CSRF跨站请求伪造

这是一种网络攻击方式,也被称为one-click attack或者session riding

攻击原理

CSRF攻击利用网站对于用户网页浏览器的信任,挟持用户当前已登陆的Web应用程序,去执行并非用户本意的操作。

CSRF图示解析

参考如下:

https://blog.csdn.net/diu_brother/article/details/88367029

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

$GLOBALS:是引用全局变量。$GLOBALS 这种全局变量用于在 PHP 脚本中的任意位置访问全局变量(从函数或方法中均可)

在php中$GLOBALS[index]的数组储存了所有的全局变量,变量的名字就是数组的键。

从源码可以看出这里只是作一个两次输入密码是否一致的判断,如果是一致的就查看有没有设置数据库连接的全局变量和其是否为一个对象。再用mysqli_real_escape_string()函数去转义。

密码不一致就输出报错:

这里是一个get提交 我们在url中可以看得到

这里没有作其他防护措施,我们可以类似地构造这样的url通过该用户来点击,就造成攻击

http://192.168.71.128/dvwa/vulnerabilities/csrf/?password_new=hack&password_conf=hack&Change=Change#

这样的链接发给已经用户在浏览器上访问,就可以修改密码为hack,

当然这种链接直接发过去太明显了,这里我们可以构造短链接,这样的迷惑性就比较强了。

我们输入短链接后成功修改密码

Medium

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

相比与low的这里添加了一个Referer字段的验证

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

这里的$_SERVER['SERVVER_NAME']是PHP中的超全局变量,详细可参考:

https://www.cnblogs.com/rendd/p/6182918.html

HTTP_REFERER是Referer参数值,即来源地址
SERVER_NAME是host参数及主机ip名(我这里是192.168.71.128)

这两个变量进行对比HTTP_REFERER和SERVER_NAME

$_SERVER["SERVER_NAME"]  输出配置文件httpd.conf中的ServerName,一般情况下与HTTP_HOST值相同,但如果服务器端口不是默认的80端口,或者协议规范不是HTTP/1.1时,HTTP_HOST会包含这些信息,而SERVER_NAME不一定包含。(主要看配置文件的设置)

我们先直接更改密码,然后抓包看看,

可以看到成功地更改密码是在host里的值有和referer中一样的值,通过验证才可以成功修改,与我分析的一样。

那我们如何来攻击呢?我们看看直接用之前那种直接访问呢

可以看到直接报错了,这下我们用抓包来具体看一下

我们再看看之前修改成功的包是有referer的,而这里是没有的,我们可以添加referer,只需要里面包含有192.168.71.128字段就可以了

注意:

但是csrf攻击我们挂载的恶意页面一定是在外网服务器上,肯定是不能这样攻击的,referer是外网的。

我看了网上的教程是在攻击者服务器里面放一个包含更改密码的html页面文件,然后让受害者去访问。

网上看到的漏洞利用

过滤规则是http包头的Referer参数的值中必须包含主机名(这里是192.168.153.130)

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

但是我这里放好访问后,host是攻击服务器的IP了不是原服务器IP,而别人的是这样的

这里就不太搞得懂,尝试了好久,

不懂放在攻击服务器上的攻击页面,如何被用户访问,如何来实现攻击了。

我的是这样

High

还是来看一下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,要利用受害者的cookie去修改密码的页面获取关键的token。

里牵扯到了跨域问题,而现在的浏览器是不允许跨域请求的。这里简单解释下跨域,我们的框架iframe访问的地址是http://192.168.71.128/dvwa/vulnerabilities/csrf,位于服务器192.168.71.128上,而我们的攻击页面位于黑客服务器上,两者的域名不同,域名B下的所有页面都不允许主动获取域名A下的页面内容,除非域名A下的页面主动发送信息给域名B的页面,所以我们的攻击脚本是不可能取到改密界面中的user_token。

还是有很多不懂,慢慢来吧~~

Vulnerability: Cross Site Request Forgery (CSRF)的更多相关文章

  1. WebGoat学习——跨站请求伪造(Cross Site Request Forgery (CSRF))

    跨站请求伪造(Cross Site Request Forgery (CSRF)) 跨站请求伪造(Cross Site Request Forgery (CSRF))也被称为:one click at ...

  2. Cross Site Request Forgery (CSRF)--spring security -转

    http://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/html/csrf.html 13. Cross ...

  3. 跨站请求伪造(Cross Site Request Forgery (CSRF))

    跨站请求伪造(Cross Site Request Forgery (CSRF)) 跨站请求伪造(Cross Site Request Forgery (CSRF)) 跨站请求伪造(Cross Sit ...

  4. DVWA 黑客攻防演练(十四)CSRF 攻击 Cross Site Request Forgery

    这么多攻击中,CSRF 攻击,全称是 Cross Site Request Forgery,翻译过来是跨站请求伪造可谓是最防不胜防之一.比如删除一篇文章,添加一笔钱之类,如果开发者是没有考虑到会被 C ...

  5. CSRF(Cross Site Request Forgery, 跨站域请求伪造)

    CSRF(Cross Site Request Forgery, 跨站域请求伪造) CSRF 背景与介绍 CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的 ...

  6. CSRF(Cross Site Request Forgery, 跨站请求伪造)

    一.CSRF 背景与介绍 CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一.其他安全隐患, ...

  7. 转: CSRF(Cross Site Request Forgery 跨站域请求伪造) 背景与介绍

    from:  https://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/   在 IBM Bluemix 云平台上开发并部署您的下一个应用 ...

  8. CSRF Laravel Cross Site Request Forgery protection¶

    Laravel 使得防止应用 遭到跨站请求伪造攻击变得简单. Laravel 自动为每一个被应用管理的有效用户会话生成一个 CSRF "令牌",该令牌用于验证授权用 户和发起请求者 ...

  9. Healwire Online Pharmacy 3.0 Cross Site Request Forgery / Cross Site Scripting

    Healwire Online Pharmacy version 3.0 suffers from cross site request forgery and cross site scriptin ...

随机推荐

  1. 08、元组tuple

    元组(tuple) 是一个有序且不可变的容器,在里面可以存放多个不同类型的元素 元组是在最后多一个逗号,用于表示它是一个元组 tuple = (11,22,'阿斯顿','媚媚',) #后面多加一个逗号 ...

  2. 有必要了解的大数据知识(二) Hadoop

    前言 接上文,复习整理大数据相关知识点,这章节从MapReduce开始... MapReduce介绍 MapReduce思想在生活中处处可见.或多或少都曾接触过这种思想.MapReduce的思想核心是 ...

  3. 攻防世界 reverse 流浪者

    流浪者 int __thiscall sub_401890(CWnd *this) { struct CString *v1; // ST08_4 CWnd *v2; // eax int v3; / ...

  4. 攻防世界 reverse hackme

    hackme XCTF 3rd-GCTF-2017 __int64 __fastcall sub_400F8E(__int64 a1, __int64 a2) { char input[136]; / ...

  5. Git本地操作2

    code[class*="language-"], pre[class*="language-"] { color: rgba(51, 51, 51, 1); ...

  6. K8S 上部署 Redis-cluster 三主三从 集群

    介绍 Redis代表REmote DIctionary Server是一种开源的内存中数据存储,通常用作数据库,缓存或消息代理.它可以存储和操作高级数据类型,例如列表,地图,集合和排序集合. 由于Re ...

  7. Hystrix熔断原理

    Netflix的开源组件Hystrix的流程: 图中流程的说明: 将远程服务调用逻辑封装进一个HystrixCommand. 对于每次服务调用可以使用同步或异步机制,对应执行execute()或que ...

  8. java面试-死锁产生、定位分析和修复

    死锁发生:两个或多个线程之间,互相持有对方需要的锁,而永久处于阻塞状态 一.手写死锁代码: public class DeadLockSample extends Thread { private S ...

  9. (十五)struts2的文件上传和下载

    文件上传的原理 我们以前学习上传的时候知道需要将表单的enctype属性设置为multipart/form-data. 表单的enctype属性指定的是表单数据的编码方式,有三个值: -applica ...

  10. 这可能是最容易理解的 Go Mutex 源码剖析

    Hi,大家好,我是 haohongfan. 上一篇文章<一文完全掌握 Go math/rand>,我们知道 math/rand 的 global rand 有一个全局锁,我的文章里面有一句 ...