# CSRF(跨站请求伪造)
从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS红队专家)!
支持HackTricks的其他方式:
* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们独家的[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
加入[**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy)服务器,与经验丰富的黑客和赏金猎人交流!
**黑客见解**\
参与深入探讨黑客的刺激和挑战的内容
**实时黑客新闻**\
通过实时新闻和见解及时了解快节奏的黑客世界
**最新公告**\
随时了解最新的赏金任务发布和重要平台更新
**加入我们的** [**Discord**](https://discord.com/invite/N3FrSbmwdy) 并开始与顶尖黑客合作!
## 解释跨站请求伪造(CSRF)
**跨站请求伪造(CSRF)**是一种在Web应用程序中发现的安全漏洞类型。它使攻击者能够利用受害者的已验证会话,代表毫不知情的用户执行操作。当已登录受害者平台的用户访问恶意站点时,攻击就会执行。该站点随后通过执行JavaScript、提交表单或获取图像等方法触发对受害者帐户的请求。
### CSRF攻击的先决条件
要利用CSRF漏洞,必须满足几个条件:
1. **识别有价值的操作**:攻击者需要找到值得利用的操作,例如更改用户的密码、电子邮件或提升权限。
2. **会话管理**:用户的会话应仅通过Cookie或HTTP基本身份验证标头管理,因为其他标头无法用于此目的进行操作。
3. **无法预测的参数**:请求不应包含无法预测的参数,因为这些参数可能会阻止攻击。
### 快速检查
您可以**在Burp中捕获请求**并检查CSRF保护,并且可以单击**复制为fetch**以从浏览器中进行测试请求:
### 防御CSRF攻击
可以实施多种对策来防范CSRF攻击:
* [**SameSite cookies**](hacking-with-cookies/#samesite):此属性可防止浏览器随跨站请求发送Cookie。[了解更多关于SameSite cookies的信息](hacking-with-cookies/#samesite)。
* [**跨域资源共享**](cors-bypass.md):受害站点的CORS策略可能影响攻击的可行性,特别是如果攻击需要读取受害站点的响应。[了解有关CORS绕过的信息](cors-bypass.md)。
* **用户验证**:提示用户输入密码或解决验证码可以确认用户的意图。
* **检查引用者或来源标头**:验证这些标头可以帮助确保请求来自受信任的来源。但是,精心构造的URL可能会绕过实施不良的检查,例如:
* 使用`http://mal.net?orig=http://example.com`(URL以受信任的URL结尾)
* 使用`http://example.com.mal.net`(URL以受信任的URL开头)
* **修改参数名称**:更改POST或GET请求中的参数名称可以帮助防止自动化攻击。
* **CSRF令牌**:在每个会话中加入唯一的CSRF令牌,并要求在后续请求中使用此令牌,可以显著减轻CSRF的风险。通过强制执行CORS可以增强令牌的有效性。
理解并实施这些防御措施对于维护Web应用程序的安全性和完整性至关重要。
## 防御绕过
### 从POST到GET
也许您想要滥用的表单准备发送**带有CSRF令牌的POST请求**,但是,您应该**检查**是否**GET**也是**有效的**,以及当您发送GET请求时**CSRF令牌是否仍在验证**。
### 缺少令牌
应用程序可能会实施一种机制,在出现令牌时**验证令牌**。但是,如果在令牌缺失时完全跳过验证,则会出现漏洞。攻击者可以通过**删除携带令牌的参数**(而不仅仅是其值)来利用这一点。这使他们可以规避验证过程并有效地执行跨站请求伪造(CSRF)攻击。
### CSRF令牌未绑定到用户会话
未将CSRF令牌绑定到用户会话的应用程序存在重大**安全风险**。这些系统会对全局池中的令牌进行验证,而不是确保每个令牌都绑定到发起会话。
以下是攻击者如何利用这一点的方法:
1. 使用自己的帐户进行**身份验证**。
2. 从全局池中**获取有效的CSRF令牌**。
3. 使用此令牌对受害者进行CSRF攻击。
此漏洞允许攻击者代表受害者进行未经授权的请求,利用应用程序的**不足的令牌验证机制**。
### 方法绕过
如果请求使用了“**奇怪**”的**方法**,请检查**方法****覆盖功能**是否有效。例如,如果**使用PUT**方法,您可以尝试**使用POST**方法并**发送**:_https://example.com/my/dear/api/val/num?**\_method=PUT**_
这也可以通过在POST请求中发送**\_method参数**或使用以下**标头**来实现:
* _X-HTTP-Method_
* _X-HTTP-Method-Override_
* _X-Method-Override_
### 自定义标头令牌绕过
如果请求在请求中添加了一个带有**令牌**的**自定义标头**作为**CSRF保护方法**,那么:
* 在没有**自定义令牌和标头**的情况下测试请求。
* 使用**完全相同长度但不同令牌**测试请求。
### 通过Cookie验证CSRF令牌
应用程序可能通过在Cookie和请求参数中复制令牌或通过设置CSRF Cookie并验证后端发送的令牌来实现CSRF保护。应用程序通过检查请求参数中的令牌是否与Cookie中的值对齐来验证请求。
但是,如果网站存在漏洞,允许攻击者在受害者的浏览器中设置CSRF Cookie,例如CRLF漏洞,那么此方法容易受到CSRF攻击。攻击者可以通过加载设置Cookie的欺骗性图像,然后发起CSRF攻击来利用这一点。
以下是攻击可能构建的示例:
```html
```
{% hint style="info" %}
请注意,如果 **csrf token 与会话 cookie 相关联**,则此攻击将无效,因为您将需要向受害者设置您的会话,因此您将攻击自己。
{% endhint %}
### Content-Type 更改
根据[**此链接**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple\_requests),为了**避免预检请求**使用 **POST** 方法,这些是允许的 Content-Type 值:
- **`application/x-www-form-urlencoded`**
- **`multipart/form-data`**
- **`text/plain`**
但是,请注意,**服务器逻辑可能会有所不同**取决于使用的 **Content-Type**,因此您应该尝试提到的值和其他值,如 **`application/json`**,**`text/xml`**,**`application/xml`**。
示例(来自[此处](https://brycec.me/posts/corctf\_2021\_challenges))将 JSON 数据发送为 text/plain:
```html
```
### 绕过预检请求以获取JSON数据
在尝试通过POST请求发送JSON数据时,在HTML表单中使用 `Content-Type: application/json` 是不直接可能的。同样,利用 `XMLHttpRequest` 发送此内容类型会启动一个预检请求。尽管如此,仍然有策略可以潜在地绕过这种限制,并检查服务器是否处理JSON数据,而不考虑Content-Type:
1. **使用替代内容类型**:通过在表单中设置 `enctype="text/plain"`,使用 `Content-Type: text/plain` 或 `Content-Type: application/x-www-form-urlencoded`。这种方法测试后端是否使用数据,而不考虑Content-Type。
2. **修改内容类型**:为了避免预检请求,同时确保服务器将内容识别为JSON,您可以使用 `Content-Type: text/plain; application/json` 发送数据。这不会触发预检请求,但如果服务器配置为接受 `application/json`,则可能会被正确处理。
3. **SWF Flash文件利用**:一种较不常见但可行的方法涉及使用SWF Flash文件来绕过此类限制。要深入了解此技术,请参考[此文章](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937)。
### 绕过引用者/来源检查
**避免引用者标头**
应用程序可能仅在存在时验证 'Referer' 标头。为了防止浏览器发送此标头,可以使用以下HTML meta标记:
```xml
```
这会确保省略“Referer”标头,可能绕过某些应用程序中的验证检查。
**正则表达式绕过**
{% content-ref url="ssrf-server-side-request-forgery/url-format-bypass.md" %}
[url-format-bypass.md](ssrf-server-side-request-forgery/url-format-bypass.md)
{% endcontent-ref %}
要在URL中设置服务器的域名,以便Referrer将其发送到参数中,您可以执行:
```html
```
### **HEAD方法绕过**
[**这篇CTF解密**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution)的第一部分解释了[Oak的源代码](https://github.com/oakserver/oak/blob/main/router.ts#L281),一个路由器被设置为**将HEAD请求处理为GET请求**,且不返回响应主体 - 这是一个常见的解决方法,不仅仅适用于Oak。与处理HEAD请求的特定处理程序不同,它们**只是交给GET处理程序,但应用程序会删除响应主体**。
因此,如果GET请求受限,您可以**发送一个将被处理为GET请求的HEAD请求**。
## **利用示例**
### **窃取CSRF令牌**
如果正在使用**CSRF令牌**作为**防御**,您可以尝试通过[XSS](xss-cross-site-scripting/#xss-stealing-csrf-tokens)漏洞或[悬挂标记](dangling-markup-html-scriptless-injection/)漏洞**窃取它**。
### **使用HTML标签进行GET**
```xml
404 - Page not found
The URL you are requesting is no longer available
```
其他可以用来自动发送GET请求的HTML5标签有:
```html