CSRF漏洞详解:原理、测试与防御绕过技术
CSRF漏洞详解:原理、测试与防御绕过技术
CSRF(跨站请求伪造)是一种常见的Web安全漏洞,攻击者可以利用这种漏洞在用户不知情的情况下,以用户的身份执行恶意操作。本文将详细介绍CSRF的概念、原理、产生条件、测试方法以及防御绕过技术。
CSRF
概念:跨站请求伪造
两个条件:
- a 用户访问站点A并产生了cookie
- b 用户没有退出A同时访问了B
本质:利用cookie伪造用户身份,发起恶意代码
原理
跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。
开发需求:用户可以修改自己的邮箱地址
实现结果:用户在修改信息页面填写邮箱地址后提交,可修改邮箱信息,实际对应请求地址为www.test.com/info.php?email=xxx@x.com&type=edit
实现方式(关键步骤):
- 获取用户传递的email、type参数值
- 根据type的参数值edit进入编辑信息逻辑
- 修改邮箱地址为xxx@x.com
- 向客户端返回操作结果
CSRF产生关键点
- 对资源的写操作(增删改)
- 发送的请求内容可被推理
eg
假设A站点开展投票评选活动,为id为18的用户投票的接口地址为
www.test.com/vote.php?vote_userid=18
此时攻击者在某大型论坛发表帖子,其中插入远程图片,对应html代码为
<img src="www.test.com\vote.php?vote_userid=18">
那么所有登录过A站点且未退出的账户,均会在用户无感知的情况下实现为id=18的账户投票
GET CSRF测试
最常见为寻找富文本编辑框,插入img标签,地址设置为csrf请求地址
<img src="www.test.com/vote.php?vote_userid=18">
CSRF生成POC
burp中请求右键-Engagement tools-Generate CSRF POC
yakit中也可以一键生成CSRF POC
此外,post csrf可尝试将post参数修改为get方式提交,有些服务端会正常接收,这种情况下可使用get csrf利用方式
CSRF绕过
CSRF漏洞很容易就可以被发现并利用。一眼看去很多站点好像在这方面都做得不错:当你检查针对敏感操作的请求时,他们往往会实施CSRF保护。有时候可能是一个在请求主体中的CSRF token,也有可能是一个referer字段检测,或者有时是一个特殊的HTTP头字段或者cookie字段。
我们遇到的最常见的防御措施有这些:
- CSRF token - CSRF token是由服务器端应用生成并与客户端共享的唯一不可预测的值。当尝试执行敏感操作(例如提交表单)时,客户端必须在请求中包含正确的CSRF token。这就让用户的每一次操作后不能单纯通过重放数据包的方式重复该操作,接收到CSRF利用页面的受害者也是如此。
- SameSite cookie - SameSite是一种浏览器安全机制,用于确定何时将网站的cookie包含在来自其他网站的请求中。由于执行敏感操作的请求通常携带经过身份验证的会话cookie,因此适当的SameSite限制可能会阻止攻击者跨站触发这些操作。自2021年起,Chrome默认实施Lax的SameSite限制。但是目前不是所有的浏览器都采用这一策略,但后续可能会逐步跟进。
- 基于Referer验证 - 有的网站会验证Referer头,判断请求是否是从当前域发出的,但是这种防御措施没有CSRF token有效。
但是CSRF的防御不代表它就不可以被绕过。今天我们讨论一些我如何绕过CSRF防御措施的技术。
不管哪种CSRF防御措施部署,你都可以先尝试如下两件事:点击劫持和更改请求方法。
点击劫持
在同一个功能端点利用点击劫持会绕过所有CSRF防御。因为从技术上讲,请求确实来自合法站点,如果易受攻击的端点所在页面容易遭受点击劫持攻击,那么所有的CSRF保护将变得没有效果,攻击者可以任意执行CSRF攻击。
更改请求方法
另外值得一试的方法就是更改请求的方法。如果要伪造的敏感请求是通过POST方法发送的,那么尝试将其转换为GET请求。如果操作时通过GET方法发送的,那么尝试转换为POST方法。应用程序可能仍然执行操作,且通常没有任何保护机制。
例如,如下请求:
POST /change_password
POST body:
new_password=qwerty
可以被改写成
GET /change_password?new_password=qwerty
CSRF Token下的爆破
- [序列场景案例:csrf token保护下的爆破 | Yak Program Language](https://www.yaklang.com/products/Web Fuzzer/fuzz-sequence-example3/)
- [热加载场景案例:csrf token保护下的爆破 | Yak Program Language](https://www.yaklang.com/products/Web Fuzzer/fuzz-hotpatch-example1/)
[!NOTE]
当我们可以获取到Token时,可以采用以上方式进行爆破账密
绕过Referer字段
如果attack.com是一个可控的域名,bank.com是一个要攻击的域名。这个站点没有使用CSRF token但是检查了referer字段。你应该怎么做?
移除referer字段
和发送一个空token值相同,有时候你只需简单地移除referer字段就可以绕过CSRF防御。你可以添加如下meta标签到存在漏洞的页面。
<meta name =“referrer”content =“no-referrer”>
应用程序可能只是在发送后才会验证,这种情况下你可以绕过其CSRF防御。
绕过正则表达式
如果referer检查是基于白名单的,你可以尝试绕过验证URL的正则表达式。例如,你可以尝试在referer的URL中将受害者域名置于二级域名区域或者URL目录区域。
如果一个站点在referer字段检查“bank.com”字段,那么“bank.com.attacker.com"或”attakcer.com/bank.com"可能可以绕过这种检测。
更多参考
- 客户端漏洞篇之客户端请求伪造(CSRF)专题 - FreeBuf网络安全行业门户
- 文章 - 绕过CSRF防御 - 先知社区