首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

DVWA笔记系列-CSRF

0x01 CSRF 简介

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

跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

0x02 CSRF 原理

CSRF攻击原理如下:

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

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

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

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

CSRF攻击原理图:

0x03 DVWA-CSRF-LOW

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

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('

'. ((is_object($GLOBALS["___mysqli_ston"])) ?mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res=mysqli_connect_error()) ?$___mysqli_res:false)) .'');

// Feedback for the user

echo"

Password Changed.";

}

else {

// Issue with passwords matching

echo"

Passwords did not match.";

}

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

}

?>

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

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

0x04 DVWA-CSRF-Medium

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('

'. ((is_object($GLOBALS["___mysqli_ston"])) ?mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res=mysqli_connect_error()) ?$___mysqli_res:false)) .'');

// Feedback for the user

echo"

Password Changed.";

}

else {

// Issue with passwords matching

echo"

Passwords did not match.";

}

}

else {

// Didn't come from a trusted source

echo"

That request didn't look correct.";

}

((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截取的数据包:

红线部分即为后端加的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

发现可以,成功绕过

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

诱使用户点击:

攻击成功。

0x05 结束语

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

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180422G0CQGE00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券