首页 > 其他分享 >CSRF

CSRF

时间:2024-07-12 09:53:01浏览次数:14  
标签:key exists token CSRF mysqli ___ password

Cross Site Request Forgery (CSRF)

跨站请求伪造

0x00 LOW Level

最初想直接尝试SQL注入,然后发现大部分特殊字符被转义了,原因在于函数mysqli_real_escape_string

源码:

<?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
        $current_user = dvwaCurrentUser();
        $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . $current_user . "';";
        $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);
}

?>

问题:什么是跨站

浏览器打开的一个页面其中信息被其他的网站修改(不同域之间相互请求资源,就算跨域)

比如说你现在打开了支付宝,登陆了自己的用户账号,看了一圈花呗,然后果断下线,如果此时你的Cookie等啥身份验证还没有过期,那么攻击者就可以伪造一个页面来诱惑你点击,在你神不知鬼不觉的情况下修改你的密码,让你无法再登陆自己的支付宝账号。

关于同源策略:

一个网页设置的cookie,另一个网页不能打开,除非这两个网页同源。

同源又是指:

  1. 协议相同
  2. 域名相同
  3. 端口相同

但是CSRF就是可以做到违反同源策略,仍可以依靠尚未过期的身份打开页面进行操作(就比如在接下来的操作中,我们Burpsuite生成的html文件是存放在攻击机的,因此通过file协议读取:file:///C:/Users/xxxx/Desktop/CRSF.html首先协议就不相同了)

重点

我们可以通过Burpsuite进行抓包

将HTML文件保存在本地,构造CSRF url(这个需要相同的浏览器打开,因为不同的浏览器cookie不同,没办法进行身份的盗用)

这里最开始测试的时候我们,可以在首部url中看到相关的GET方式得到的数据,

http://127.0.0.1/DVWA-master/vulnerabilities/csrf/?password_new=1&password_conf=1&Change=Change#

然后我们可以修改password的值然后再打开一个新的页面,就会发现之前的密码不管用了,这个可以作为一个初步的尝试,但是我觉得无法很好的展示其违反的同源的特性,尤其是都在同一个设备上测试的时候。

0x01 Medium_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
            $current_user = dvwaCurrentUser();
            $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . $current_user . "';";
            $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( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false )

什么是HTTP_REFERER

关于Referer:表明了请求的来源。我们学习计网的过程中了解过了,关于网络上访问浏览器的请求会传输数据包,然后在应用层采用http协议中Referer是其Header的一部分,你访问的网站也是通过它来统计网站的流量的。

目的:它存在的作用一般是为了防盗链接,就是我要访问的网站只允许自己的域名访问,不被允许就会被拦截

就比如此时我们在打开一个新的页面更改url是不被允许的,因为我们通过F12可以看到新的网页不含referer。

解决

因此,我们可以抓包后,手动加入Referer。

0x02 High_Level

源码:

<?php

$change = false;
$request_type = "html";
$return_message = "Request Failed";

if ($_SERVER['REQUEST_METHOD'] == "POST" && array_key_exists ("CONTENT_TYPE", $_SERVER) && $_SERVER['CONTENT_TYPE'] == "application/json") {
    $data = json_decode(file_get_contents('php://input'), true);
    $request_type = "json";
    if (array_key_exists("HTTP_USER_TOKEN", $_SERVER) &&
        array_key_exists("password_new", $data) &&
        array_key_exists("password_conf", $data) &&
        array_key_exists("Change", $data)) {
        $token = $_SERVER['HTTP_USER_TOKEN'];
        $pass_new = $data["password_new"];
        $pass_conf = $data["password_conf"];
        $change = true;
    }
} else {
    if (array_key_exists("user_token", $_REQUEST) &&
        array_key_exists("password_new", $_REQUEST) &&
        array_key_exists("password_conf", $_REQUEST) &&
        array_key_exists("Change", $_REQUEST)) {
        $token = $_REQUEST["user_token"];
        $pass_new = $_REQUEST["password_new"];
        $pass_conf = $_REQUEST["password_conf"];
        $change = true;
    }
}

if ($change) {
    // Check Anti-CSRF token
    checkToken( $token, $_SESSION[ 'session_token' ], 'index.php' );

    // Do the passwords match?
    if( $pass_new == $pass_conf ) {
        // They do!
        $pass_new = mysqli_real_escape_string ($GLOBALS["___mysqli_ston"], $pass_new);
        $pass_new = md5( $pass_new );

        // Update the database
        $current_user = dvwaCurrentUser();
        $insert = "UPDATE `users` SET password = '" . $pass_new . "' WHERE user = '" . $current_user . "';";
        $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert );

        // Feedback for the user
        $return_message = "Password Changed.";
    }
    else {
        // Issue with passwords matching
        $return_message = "Passwords did not match.";
    }

    mysqli_close($GLOBALS["___mysqli_ston"]);

    if ($request_type == "json") {
        generateSessionToken();
        header ("Content-Type: application/json");
        print json_encode (array("Message" =>$return_message));
        exit;
    } else {
        echo "<pre>" . $return_message . "</pre>";
    }
}

// Generate Anti-CSRF token
generateSessionToken();

?> 

发现此时多出来了许多判断,

if ($_SERVER['REQUEST_METHOD'] == "POST" && array_key_exists ("CONTENT_TYPE", $_SERVER) && $_SERVER['CONTENT_TYPE'] == "application/json") {
    $data = json_decode(file_get_contents('php://input'), true);
    $request_type = "json";
    if (array_key_exists("HTTP_USER_TOKEN", $_SERVER) &&
        array_key_exists("password_new", $data) &&
        array_key_exists("password_conf", $data) &&
        array_key_exists("Change", $data)) {
        $token = $_SERVER['HTTP_USER_TOKEN'];
        $pass_new = $data["password_new"];
        $pass_conf = $data["password_conf"];
        $change = true;
    }
} else {
    if (array_key_exists("user_token", $_REQUEST) &&
        array_key_exists("password_new", $_REQUEST) &&
        array_key_exists("password_conf", $_REQUEST) &&
        array_key_exists("Change", $_REQUEST)) {
        $token = $_REQUEST["user_token"];
        $pass_new = $_REQUEST["password_new"];
        $pass_conf = $_REQUEST["password_conf"];
        $change = true;
    }
}

多出来了一个token,

http://127.0.0.1/DVWA-master/vulnerabilities/csrf/?password_new=1&password_conf=1&Change=Change&user_token=2361956e672e361c3a9a3436a47105d1#

什么是token

:Anti-CSRF token机制,用户每次访问修改密码的页面时,服务器都会返回一个随机的token,当浏览器向服务器发起请求,需要提交token参数,而服务器在收到请求时,会优先检查token,只有token正确,才会处理客户端的请求。

因此它比referer更安全

这里Burpsuite可以帮我们直接完成token的获取

安装好插件后修改,就可以进行修改密码。

重点

  1. 什么是跨站(不同域的资源请求)| 什么是同源(三个特性相同即为同源)
  2. Referer的作用:用于指出域名来源
  3. token作用:安全性更近一步

标签:key,exists,token,CSRF,mysqli,___,password
From: https://www.cnblogs.com/XXS-uic9/p/18297494

相关文章

  • 23、Django-CSRF跨站伪造请求攻击
     配置:1、在settings.py中确认MIDDLEWARE中确保--django.middleware.csrf.CsrfViewMiddleware打开2、在模板中、form标签下添加如下标签:--{%csrf_token%}#这个就是页面中的暗号 案例views.py-------------------------------------------------......
  • 生产实习--启明星辰 第四天(Web网络安全基础知识,sql注入,xss攻击,csrf与ssrf,xxe攻击,未授
    web安全的基础知识基本定义Web安全,也称为网络安全或在线安全,是指保护网站、网页和Web服务免受各种威胁和攻击的技术和实践。这些威胁可能来自恶意软件、网络攻击、数据泄露、身份盗窃、服务中断等。Web安全的目标是确保Web应用程序和用户数据的安全、完整和可用性。一般流程......
  • 跨站请求伪造(CSRF)攻击原理及预防手段
    1、什么是跨站请求伪造?CSRF(Cross-siteRequestForgery,跨站请求伪造)攻击是一种常见的Web攻击,它利用用户在登录某个网站后的有效session来发送恶意请求。攻击者通过引导用户访问恶意网站,将用户的数据提交到目标网站,欺骗目标网站相信该请求是用户发送的。CSRF攻击的关键是攻击者可......
  • 白帽工具箱:DVWA中CSRF攻击与防御的入门指南
    ......
  • DRF 前后端分离项目如何解决CSRF 数据交互
    ★背景说明在DjangoRESTframework(DRF)前后端分离项目中,解决CSRF问题通常有以下几种方法:1.禁用CSRF验证,但这会降低安全性。(不推荐)2.使用csrftokencookie3.在前端每次POST、PUT或DELETE请求前先发起一个GET请求(GET请求不需要经过CSRF检查)获取CSRFToken并将响......
  • CSRF攻击与修复
    基本原理受害者登录a.com,并保留了登录凭证(Cookie)。攻击者引诱受害者访问了b.com。b.com向a.com发送了一个请求:a.com/act=xx。浏览器会默认携带a.com的Cookie。a.com接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求。a.com以受害者的名义执......
  • csrf跨站请求,钓鱼网站实现示例,CSRF校验,CSRF相关装饰器,Auth模块,扩展Auth表
    ⅠDjango框架之csrf跨站请求【一】跨站请求伪造介绍【1】引入CSRF(Cross-SiteRequestForgery)跨站请求伪造是一种常见的网络攻击方式。攻击者通过诱导受害者访问恶意网站或点击恶意链接将恶意请求发送到目标网站上利用受害者在目标网站中已登录的身份来执行某些操作从而......
  • 网络安全筑基篇——CSRF、SSRF
    前言本篇文章相对于来说比较水,大家看不懂的话,多去百度,去了解相关的知识大家一定要多去理解这个原理,理解的同时去打打靶场,就能很快上手啦什么是CSRF?CSRF(即跨站请求伪造)是指利用受害者尚未失效的身份认证信息、(cookie、会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面......
  • CSRF漏洞复现及测试工具讲解
    一、Python编写一个存在CSRF漏洞①编写html网页<!DOCTYPEhtml><html><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>转账</title......
  • 关于CSRF
    CrossSiteRequestForgery跨站请求伪造当用户访问恶意网站时,恶意网站可以通过链接跳转的方式,引导用户访问被攻击网站,因为用户可能最近刚刚访问过被攻击网站,浏览器携带其缓存的合法cookie让用户访问,cookie中保存了客户的认证信息,用户从而不需要重新认证。此过程实际上是恶意......