DVWA(三)-CSRF(跨站请求伪造)

CSRF: (Cross Site Request Forgery, 跨站域请求伪造),攻击者构造网站后台某个功能接口的请求地址,诱导用户去点击或者用特殊方法让该请求地址自动加载。用户在登录状态下这个请求被服务端接收后会被误以为是用户合法的操作。说得简单点就是借刀杀人,借用被攻击者的身份,完成攻击者自己的想法。

环境:
搭建了DVWA的虚拟机(win7 x86),虚拟机IP为192.168.157.137。
admin账户登陆在物理机win10 x64
gordonb账户登录在虚拟机win7 x64

DVWA默认账户密码:
DVWA(三)-CSRF(跨站请求伪造)_第1张图片

操作界面:
DVWA(三)-CSRF(跨站请求伪造)_第2张图片
输入两次修改后的密码,就可以将admin的密码修改。

Low

Low级别源码


' . ((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); } ?>

分析: 将用户输入的新旧密码进行比较,如果相同,则将密码MD5加密,使用更新语句将数据库中的旧密码进行更新,没有任何认证过程.

攻击过程

在admin修改密码时发现使用的是GET方式发送数据包,譬如将密码修改为123456时,URL为:

http://192.168.157.137/DVWA-master/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#

在得到gordonb已经登录的情况下,诱导他点击该链接,在他不知情的情况下,修改了gordonb账户的密码.
在这里插入图片描述
DVWA(三)-CSRF(跨站请求伪造)_第3张图片
现在gordonb的密码会被修改掉了,但是这样的URL很容易被看破,所以可以使用工具将长的有规律的URL转换为短的无规律的URL。
在这里插入图片描述
可是这样还是会打开一个新的网页,并且提示密码已经更改,很容易就会暴露。所以我们创建一个攻击页面,诱导目标人物加载该页面,在目标不知情的情况下,将密码更改。

网页源码:



404

file not found.

每个人的路径是不同的,注意修改.

在目标任务加载之后,页面时404not found
DVWA(三)-CSRF(跨站请求伪造)_第4张图片
DVWA(三)-CSRF(跨站请求伪造)_第5张图片

但其实密码已经被修改

Medium

Medium源码

' . ((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); } ?>

分析: 与Low级别相比,多了一步判断,检查最后请求的页面来自何处。

// Checks to see where the request came from
if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false )

stripos函数的作用 : stripos(a,b),查找b第一次出现在a的位置,在这里就是判断SERVER_NAMES是否在HTTP_REFERER中出现。

HTTP_HOST是变化的,而SERVER_NAME只有一个。
比如,你现在机器上的一个网站http://www.a.com,这个网站也可以通过http://localhost来访问,指向同一个目录。
如果你在浏览器用http://localhost访问,则HTTP_HOST的值为localhost,而你用www.a.com访问,HTTP_HOST的值就是www.a.com,你用IP地址访问,HTTP_HOST的值就是IP,SERVER_NAME就不会变化,httpd.conf中设置为什么,显示的就是什么。

这个if语句的作用为:

HTTP_REFERER(http包头的Referer参数的值,表示来源地址)中是否包含SERVER_NAME(http包头的Host参数,及要访问的主机名)

DVWA(三)-CSRF(跨站请求伪造)_第6张图片
希望以此来预防CSRF攻击
解决思路:
按照Low级别的第一种思路,是不受影响的,因为攻击对象点击的这个链接

http://192.168.157.137/DVWA-master/vulnerabilities/csrf/?password_new=admin&password_conf=admin&Change=Change#

中含有目标IP。
DVWA(三)-CSRF(跨站请求伪造)_第7张图片

不过实战中不会使用这种方式,太容易暴露,所以主要还是使用第二种思路.

既然要求包含服务器ip,可以直接将攻击页面的文件名改为服务器的IP地址
在这里插入图片描述
DVWA(三)-CSRF(跨站请求伪造)_第8张图片
成功修改!
DVWA(三)-CSRF(跨站请求伪造)_第9张图片

High

High源码

' . ((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); } // Generate Anti-CSRF token generateSessionToken(); ?>

分析: 去掉了medium等级的验证手段,添加了对token的验证

**解决思路: ** 关键就在于获取token值,所以我们在构造的攻击页面中,首先访问修改密码的页面,得到当前token值,再将该值与其他参数发送给服务端,实现修改密码。但是跨域是不可实现的。需要与xss结合,目前水平不够,挖个坑以后解决。 ( •̥́ ˍ •̀ू )

Impossible

Impossible源码

prepare( 'SELECT password FROM users WHERE user = (:user) AND password = (:password) LIMIT 1;' ); 
    $data->bindParam( ':user', dvwaCurrentUser(), PDO::PARAM_STR ); 
    $data->bindParam( ':password', $pass_curr, PDO::PARAM_STR ); 
    $data->execute(); 

    // Do both new passwords match and does the current password match the user? 
    if( ( $pass_new == $pass_conf ) && ( $data->rowCount() == 1 ) ) { 
        // It does! 
        $pass_new = stripslashes( $pass_new ); 
        $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 database with new password 
        $data = $db->prepare( 'UPDATE users SET password = (:password) WHERE user = (:user);' ); 
        $data->bindParam( ':password', $pass_new, PDO::PARAM_STR ); 
        $data->bindParam( ':user', dvwaCurrentUser(), PDO::PARAM_STR ); 
        $data->execute(); 

        // Feedback for the user 
        echo "
Password Changed.
"; } else { // Issue with passwords matching echo "
Passwords did not match or current password incorrect.
"; } } // Generate Anti-CSRF token generateSessionToken(); ?>

检查token、修改密码需要输入以前的密码、PDO技术预防sql注入,一点机会都不给。
(ÒωÓױ)

你可能感兴趣的:(DVWA)