.. | ||
browext-clickjacking.md | ||
browext-permissions-and-host_permissions.md | ||
browext-xss-example.md | ||
README.md |
浏览器扩展渗透测试方法论
从零到英雄学习AWS黑客攻击 htARTE (HackTricks AWS Red Team Expert)!
支持HackTricks的其他方式:
- 如果您想在HackTricks中看到您的公司广告或下载HackTricks的PDF,请查看订阅计划!
- 获取官方PEASS & HackTricks商品
- 发现PEASS家族,我们独家的NFTs系列
- 加入 💬 Discord群组 或 telegram群组 或在Twitter 🐦 上关注我 @carlospolopm。
- 通过向 HackTricks 和 HackTricks Cloud github仓库提交PR来分享您的黑客技巧。**
基本信息
浏览器扩展使用JavaScript编写,并由浏览器在后台加载。它有自己的DOM,但可以与其他网站的DOM交互。这意味着它可能会危及其他网站的机密性、完整性和可用性(CIA)。
主要组件
扩展布局在可视化时看起来最佳,由三个组件组成。让我们深入了解每个组件。
内容脚本
每个内容脚本都可以直接访问单个网页的DOM,因此暴露于潜在的恶意输入。然而,内容脚本除了能够向扩展核心发送消息之外,没有其他权限。
要在Chrome中查看和调试内容脚本,您可以从选项 > 更多工具 > 开发者工具中打开Chrome开发者工具菜单,或者(按 - Ctrl + Shift + I)。
显示开发者工具后,点击源代码标签,然后点击内容脚本标签。在这里,您可以看到各种扩展的运行内容脚本,并设置断点以监控执行流程。在我们的案例中,我们通过Wappalyzer浏览器扩展展示。
扩展核心
扩展核心包含了大部分扩展权限/访问权限,但扩展核心只能通过XMLHttpRequest和内容脚本与网页内容交互。此外,扩展核心无法直接访问宿主机器。
本地二进制
扩展允许一个本地二进制文件,该文件可以**以用户的全部权限访问宿主机器。**本地二进制文件通过标准的Netscape插件应用程序编程接口(NPAPI)与扩展核心交互,该接口被Flash和其他浏览器插件使用。
边界
{% hint style="danger" %} 为了获得用户的全部权限,攻击者必须说服扩展将恶意输入从内容脚本传递到扩展的核心,再从扩展的核心传递到本地二进制文件。 {% endhint %}
扩展的每个组件都通过强大的保护边界彼此分隔。每个组件在单独的操作系统进程中运行。内容脚本和扩展核心运行在对大多数操作系统服务不可用的沙箱进程中。
此外,内容脚本通过在单独的JavaScript堆中运行与其关联的网页分离。内容脚本和网页都可以访问相同的底层DOM,但两者从不交换JavaScript指针,防止了JavaScript功能的泄露。
manifest.json
Chrome扩展只是一个带有.crx文件扩展名的ZIP文件夹。扩展的核心是文件夹根目录下的**manifest.json
**文件,它指定了布局、权限和其他配置选项。
示例:
{
"manifest_version": 2,
"name": "My extension",
"version": "1.0",
"permissions": [
"storage"
],
"content_scripts": [
{
"js": [
"script.js"
],
"matches": [
"https://example.com/*",
"https://www.example.com/*"
],
"exclude_matches": ["*://*/*business*"],
}
],
"background": {
"scripts": [
"background.js"
]
},
"options_ui": {
"page": "options.html"
}
}
content_scripts
内容脚本在用户导航到匹配的页面时加载,在我们的案例中,任何与**https://example.com/*
** 表达式匹配且不与 *://*/*/business*
正则表达式匹配的页面都会加载内容脚本。它们像页面自己的脚本一样执行,并且可以任意访问页面的文档对象模型 (DOM)。
"content_scripts": [
{
"js": [
"script.js"
],
"matches": [
"https://example.com/*",
"https://www.example.com/*"
],
"exclude_matches": ["*://*/*business*"],
}
],
为了包含或排除更多的URL,也可以使用 include_globs
和 exclude_globs
。
以下是一个示例内容脚本,当使用 存储 API 从扩展的存储中检索 message
值时,它会向页面添加一个解释按钮。
chrome.storage.local.get("message", result =>
{
let div = document.createElement("div");
div.innerHTML = result.message + " <button>Explain</button>";
div.querySelector("button").addEventListener("click", () =>
{
chrome.runtime.sendMessage("explain");
});
document.body.appendChild(div);
});
当点击这个按钮时,内容脚本使用 runtime.sendMessage() API 向扩展页面发送消息。这是因为内容脚本只能直接访问少数API,如 storage
。其他所有操作都必须通过内容脚本可以发送消息到的扩展页面来完成。
{% hint style="warning" %}
内容脚本的能力根据浏览器的不同而略有差异。对于基于Chromium的浏览器,你可以在 Chrome Developers documentation 找到列表,对于Firefox,MDN 是最终的信息来源。
记住内容脚本也可以与后台脚本通信,以便它们执行操作并发送回响应
{% endhint %}
注入内容脚本
{% hint style="success" %}
注意内容脚本不是强制性的,因为也可以通过 tabs.executeScript
动态地 注入脚本,并且可以编程式地注入到网页中。这实际上提供了更多的细粒度控制。
{% endhint %}
要以编程方式注入内容脚本,你的扩展需要对其试图注入脚本的页面拥有主机权限。主机权限可以通过作为扩展清单的一部分请求它们或通过 activeTab临时授予。
示例基于activeTab的扩展
{% code title="manifest.json" %}
{
"name": "My extension",
...
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Action Button"
}
}
{% endcode %}
- 点击时注入JS文件:
// content-script.js
document.body.style.backgroundColor = "orange";
//service-worker.js - Inject the JS file
chrome.action.onClicked.addListener((tab) => {
chrome.scripting.executeScript({
target: { tabId: tab.id },
files: ["content-script.js"]
});
});
- 在点击时注入一个函数:
//service-worker.js - Inject a function
function injectedFunction() {
document.body.style.backgroundColor = "orange";
}
chrome.action.onClicked.addListener((tab) => {
chrome.scripting.executeScript({
target : {tabId : tab.id},
func : injectedFunction,
});
});
示例包含脚本权限
// service-workser.js
chrome.scripting.registerContentScripts([{
id : "test",
matches : [ "https://*.nytimes.com/*" ],
excludeMatches : [ "*://*/*business*" ],
js : [ "contentScript.js" ],
}]);
// ANother example
chrome.tabs.executeScript(tabId, { file: "content_script.js" });
为了包含或排除更多的URL,也可以使用 include_globs
和 exclude_globs
。
内容脚本 run_at
run_at
字段控制 何时将 JavaScript 文件注入到网页中。首选且默认值是 "document_idle"
。
可能的值有:
document_idle
: 尽可能地document_start
: 在css
的任何文件之后,但在构建任何其他DOM或运行任何其他脚本之前。document_end
: 在DOM完成后立即,但在子资源如图片和框架加载之前。
通过 manifest.json
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["https://*.nytimes.com/*"],
"run_at": "document_idle",
"js": ["contentScript.js"]
}
],
...
}
通过 service-worker.js
chrome.scripting.registerContentScripts([{
id : "test",
matches : [ "https://*.nytimes.com/*" ],
runAt : "document_idle",
js : [ "contentScript.js" ],
}]);
背景
当内容脚本发送消息时,其目的地是背景页面。背景页面是一个特殊的页面,除非在扩展清单中另有指定,否则它始终存在。尽管它是一个拥有自己的DOM等的普通页面,但对用户来说是不可见的。它的功能通常是协调扩展的所有其他部分。
{% hint style="success" %} 如果没有明确声明背景页面,浏览器会很有帮助地自动生成一个,并确保所有声明的背景脚本都加载进去,就像前面的manifest.json示例中那样。 {% endhint %}
背景脚本示例:
chrome.runtime.onMessage.addListener((request, sender, sendResponse) =>
{
if (request == "explain")
{
chrome.tabs.create({ url: "https://example.net/explanation" });
}
})
它使用 runtime.onMessage API 来监听消息。当收到 "explain"
消息时,它使用 tabs API 在新标签页中打开页面。
选项页面和其他
浏览器扩展可以包含各种页面:
- 操作页面 在点击扩展图标时显示在下拉菜单中。
- 扩展将在新标签页中加载的页面。
- 选项页面:点击扩展时,此页面显示在扩展顶部。在之前的 manifest 中,在我的案例中,我可以通过
chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca
访问此页面,或点击:
与背景页面不同,这些页面不是持久的,而是在需要时加载。然而,所有这些页面都可以接收来自内容脚本的消息。并且它们都有完全访问特定于扩展的 API 的权限,只要扩展的权限允许。
总的来说,浏览器扩展的相关上下文如下所示:
permissions
和 host_permissions
permissions
和 host_permissions
是 manifest.json
中的条目,它们将指示浏览器扩展拥有哪些权限(存储、位置等)以及在哪些网页上。
由于浏览器扩展可以如此特权,一个恶意的或被泄露的扩展可能允许攻击者以不同方式窃取敏感信息和监视用户。
检查这些设置如何工作以及它们如何可能被滥用:
{% content-ref url="browext-permissions-and-host_permissions.md" %} browext-permissions-and-host_permissions.md {% endcontent-ref %}
content_security_policy
内容安全策略也可以在 manifest.json
中声明。如果定义了策略,它可能是易受攻击的。
浏览器扩展页面的默认设置相当严格:
script-src 'self'; object-src 'self';
有关CSP及其潜在绕过方法的更多信息,请查看:
{% content-ref url="../content-security-policy-csp-bypass/" %} content-security-policy-csp-bypass {% endcontent-ref %}
web_accessible_resources
为了让网页访问浏览器扩展的页面,例如.html
页面,这个页面需要在manifest.json
的**web_accessible_resources
**字段中提及。
例如:
{
...
"web_accessible_resources": [
{
"resources": [ "images/*.png" ],
"matches": [ "https://example.com/*" ]
},
{
"resources": [ "fonts/*.woff" ],
"matches": [ "https://example.com/*" ]
}
],
...
}
这些页面可以通过类似以下的URL访问:
chrome-extension://<extension-id>/message.html
在公共扩展中,extension-id 是可访问的:
然而,如果使用了 manifest.json
参数 use_dynamic_url
,这个 id 可以是动态的。
被允许访问这些页面使得这些页面 可能容易受到 ClickJacking 攻击:
{% content-ref url="browext-clickjacking.md" %} browext-clickjacking.md {% endcontent-ref %}
{% hint style="success" %} 只允许扩展加载这些页面,而不是随机 URL,可以防止 ClickJacking 攻击。 {% endhint %}
externally_connectable
根据 文档,"externally_connectable"
清单属性声明了 哪些扩展和网页可以通过 runtime.connect 和 runtime.sendMessage 连接到你的扩展。
- 如果
externally_connectable
键在你的扩展清单中 没有声明,或者声明为"ids": ["*"]
,所有扩展都可以连接,但没有网页可以连接。 - 如果声明了 特定的 ID,如
"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
,只有那些应用程序可以连接。 - 如果指定了 matches,那些网页应用将能够连接:
"matches": [
"https://*.google.com/*",
"*://*.chromium.org/*",
- 如果指定为空:
"externally_connectable": {}
,则没有任何应用程序或网页能够连接。
这里指示的扩展和URL越少,攻击面就越小。
{% hint style="danger" %}
如果在 externally_connectable
中指出了一个容易受到XSS或接管攻击的网页,攻击者将能够直接向后台脚本发送消息,完全绕过内容脚本及其CSP。
因此,这是一个非常强大的绕过。 {% endhint %}
网页 ↔︎ 内容脚本通信
尽管内容脚本和托管它们的页面的执行环境是相互隔离的,但它们共享对页面DOM的访问。如果页面希望与内容脚本通信,或通过内容脚本与扩展通信,它必须通过共享的DOM来实现。
发送消息
{% code title="content-script.js" %}
var port = chrome.runtime.connect();
window.addEventListener("message", (event) => {
// We only accept messages from ourselves
if (event.source !== window) {
return;
}
if (event.data.type && (event.data.type === "FROM_PAGE")) {
console.log("Content script received: " + event.data.text);
port.postMessage(event.data.text);
}
}, false);
{% endcode %}
{% code title="example.js" %}
document.getElementById("theButton").addEventListener("click", () => {
window.postMessage(
{type : "FROM_PAGE", text : "Hello from the webpage!"}, "*");
}, false);
{% endcode %}
安全的 Post Message 通信应该检查接收消息的真实性,这可以通过检查以下方式完成:
event.isTrusted
:如果事件是由用户操作触发的,则为 True- 内容脚本可能只在用户执行某些操作时才期望接收消息
- 原始域名:可以与允许域名列表进行对比。
- 如果使用正则表达式,要非常小心
- 来源:
received_message.source !== window
可用于检查消息是否来自同一窗口,即内容脚本正在监听的窗口。
即使执行了上述检查,也可能存在漏洞,因此请在以下页面检查潜在的 Post Message 绕过:
{% content-ref url="../postmessage-vulnerabilities/" %} postmessage-vulnerabilities {% endcontent-ref %}
Iframe
另一种可能的通信方式可能是通过 Iframe URLs,您可以在以下示例中找到:
{% content-ref url="browext-xss-example.md" %} browext-xss-example.md {% endcontent-ref %}
DOM
这不是“确切的”通信方式,但是网页和内容脚本将能够访问网页 DOM。因此,如果内容脚本从中读取一些信息,信任网页 DOM,网页可以修改这些数据(因为网页不应该被信任,或者因为网页容易受到 XSS 攻击)并且危及内容脚本。
您还可以在以下示例中找到一个基于 DOM 的 XSS 来危及浏览器扩展:
{% content-ref url="browext-xss-example.md" %} browext-xss-example.md {% endcontent-ref %}
内存/代码中的敏感信息
如果浏览器扩展在其内存中存储敏感信息,这些信息可能会被转储(特别是在 Windows 机器上)并搜索这些信息。
因此,浏览器扩展的内存不应该被认为是安全的,而且像凭据或助记词这样的敏感信息不应该被存储。
当然,不要将敏感信息放在代码中,因为它将是公开的。
内容脚本 ↔︎ 背景脚本通信
内容脚本可以使用函数 runtime.sendMessage() 或 tabs.sendMessage() 来发送一次性的 JSON-可序列化消息。
要处理响应,使用返回的Promise。尽管如此,为了向后兼容,您仍然可以将回调作为最后一个参数传递。
从内容脚本发送请求看起来像这样:
(async () => {
const response = await chrome.runtime.sendMessage({greeting: "hello"});
// do something with response here, not outside the function
console.log(response);
})();
将请求从扩展(通常是背景脚本)发送到内容脚本类似,但您需要指定发送到哪个标签页。此示例演示了向选定标签页中的内容脚本发送消息。
(async () => {
const [tab] = await chrome.tabs.query({active: true, lastFocusedWindow: true});
const response = await chrome.tabs.sendMessage(tab.id, {greeting: "hello"});
// do something with response here, not outside the function
console.log(response);
})();
在接收端,您需要设置一个 runtime.onMessage 事件监听器来处理消息。无论是在内容脚本还是扩展页面中,这看起来都是相同的。
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting === "hello")
sendResponse({farewell: "goodbye"});
}
);
在上面的例子中,sendResponse()
被同步调用。如果你想要异步使用 sendResponse()
,在 onMessage
事件处理器中添加 return true;
。
如果多个页面在监听
onMessage
事件,只有第一个调用sendResponse()
的页面会成功发送响应。对那个事件的所有其他响应都将被忽略。
对于新的扩展,你应该优先使用 promises 而不是 callbacks。如果你在使用 callbacks,sendResponse()
回调只有在同步使用,或者事件处理器返回 true
来表明它将异步响应时才有效。如果没有处理器返回 true 或者 sendResponse()
回调被垃圾回收,sendMessage()
函数的回调将会自动被调用。
在浏览器中加载扩展
- 下载 浏览器扩展并解压
- 转到
chrome://extensions/
并启用开发者模式
- 点击
加载已解压的扩展程序
按钮
在 Firefox 中,你转到 about:debugging#/runtime/this-firefox
并点击 加载临时附加组件
按钮。
从商店获取源代码
从 这里:
选项 1: 命令行下载扩展为 zip 并解压
{% code overflow="wrap" %}
extension_id=jifpbeccnghkjeaalbbjmodiffmgedin # change this ID
curl -L -o "$extension_id.zip" "https://clients2.google.com/service/update2/crx?response=redirect&os=mac&arch=x86-64&nacl_arch=x86-64&prod=chromecrx&prodchannel=stable&prodversion=44.0.2403.130&x=id%3D$extension_id%26uc"
unzip -d "$extension_id-source" "$extension_id.zip"
{% endcode %}
感谢 crxviewer 提供的[魔法下载 URL](https://github.com/Rob--W/crxviewer/blob/6113c25e3569e1ec59365ad9a177aa97e2bcda61/src/cws_pattern.js#L27-L74)。
### 选项 2:使用 CRX Viewer 网站
[https://robwu.nl/crxviewer/](https://robwu.nl/crxviewer/)
### 选项 3:使用 CRX Viewer 扩展程序
[Chrome 扩展程序源代码查看器](https://chrome.google.com/webstore/detail/chrome-extension-source-v/jifpbeccnghkjeaalbbjmodiffmgedin?hl=en) 是开源的([github 仓库](https://github.com/Rob--W/crxviewer)),使用起来非常简单。
### 选项 3:查看本地安装的扩展程序源代码
1. 找到您的 Chrome 本地配置文件目录。打开 `chrome://version/` 并找到 "Profile Path:" 字段。打开那个文件夹。
2. 打开 `Extensions/` 子文件夹
3. 这里有所有您的扩展程序,通常源代码是可读的。
#### 本地安装的扩展程序 ID 与名称之间的映射
* 在 `about:extensions` 上,打开开发者模式,您将在每个条目下看到 ID
* 在 `Extensions/` 文件夹内,manifest.json 有一个可读的 `name` 字段
## 安全审计清单
尽管浏览器扩展程序的**攻击面**有限,但其中一些可能包含**漏洞**或**潜在的加固改进**。以下是最常见的一些:
* [ ] 尽可能**限制**请求的**`permissions`**
* [ ] 尽可能**限制** **`host_permissions`**
* [ ] 使用**强大的** **`content_security_policy`**
* [ ] 尽可能**限制** **`externally_connectable`**,如果不需要且可能的话,不要默认留空,指定 **`{}`**
* [ ] 如果这里提到了**容易受到 XSS 或接管的 URL**,攻击者将能够**直接向后台脚本发送消息**。非常强大的绕过。
* [ ] 尽可能**限制** **`web_accessible_resources`**,如果可能的话甚至为空。
* [ ] 如果 **`web_accessible_resources`** 不为空,请检查 [**ClickJacking**](browext-clickjacking.md)
* [ ] 如果**扩展程序**与**网页**之间发生任何**通信**,[**检查 XSS**](browext-xss-example.md) **漏洞**是否因通信而引起。
* [ ] 如果使用了 Post Messages,请检查 [**Post Message 漏洞**](../postmessage-vulnerabilities/)。
* [ ] 如果**内容脚本访问 DOM 详情**,请检查它们是否**引入了 XSS**,如果它们被网页**修改**。
* [ ] 如果这种通信还涉及到**内容脚本 -> 后台脚本通信**,请特别强调。
* [ ] **敏感信息不应存储**在浏览器扩展程序**代码**中
* [ ] **敏感信息不应存储**在浏览器扩展程序**内存**中
## 工具
### [**Tarnish**](https://thehackerblog.com/tarnish/)
* 从提供的 Chrome 网上应用店链接中提取任何 Chrome 扩展程序。
* [**manifest.json**](https://developer.chrome.com/extensions/manifest) **查看器**:简单地显示扩展程序清单的 JSON 格式化版本。
* **指纹分析**:检测 [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources) 并自动生成 Chrome 扩展程序指纹识别 JavaScript。
* **潜在的 Clickjacking 分析**:检测设置了 [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources) 指令的扩展程序 HTML 页面。根据页面的用途,这些页面可能容易受到点击劫持。
* **权限警告查看器**:显示用户尝试安装扩展程序时将显示的所有 Chrome 权限提示警告的列表。
* **危险功能**:显示可能被攻击者利用的危险功能的位置(例如,如 innerHTML、chrome.tabs.executeScript 等功能)。
* **入口点**:显示扩展程序接收用户/外部输入的位置。这对于了解扩展程序的表面区域并寻找潜在的发送恶意制作数据到扩展程序的点很有用。
* 危险功能和入口点扫描器的生成警报都有以下内容:
* 引起警报的相关代码片段和行。
* 问题描述。
* “查看文件”按钮,以查看包含代码的完整源文件。
* 警报文件的路径。
* 警报文件的完整 Chrome 扩展程序 URI。
* 它是什么类型的文件,例如背景页面脚本、内容脚本、浏览器操作等。
* 如果易受攻击的行位于 JavaScript 文件中,则包括它被包含的所有页面的路径以及这些页面的类型和 [web_accessible_resource](https://developer.chrome.com/extensions/manifest/web_accessible_resources) 状态。
* **内容安全策略 (CSP) 分析器和绕过检查器**:这将指出扩展程序 CSP 中的弱点,并将照亮由于白名单 CDN 等原因可能绕过 CSP 的任何潜在方式。
* **已知易受攻击的库**:这使用 [Retire.js](https://retirejs.github.io/retire.js/) 检查任何已知易受攻击的 JavaScript 库的使用。
* 下载扩展程序和格式化版本。
* 下载原始扩展程序。
* 下载扩展程序的美化版本(自动美化的 HTML 和 JavaScript)。
* 扫描结果的自动缓存,第一次运行扩展程序扫描时将花费大量时间。然而,第二次,假设扩展程序没有更新,由于结果被缓存,几乎是瞬间的。
* 可链接的报告 URL,轻松将其他人链接到由 tarnish 生成的扩展程序报告。
### [Neto](https://github.com/elevenpaths/neto)
Neto 项目是一个 Python 3 包,旨在分析和揭示 Firefox 和 Chrome 等知名浏览器的浏览器插件和扩展程序的隐藏功能。它自动化了解压缩打包文件的过程,以从扩展程序中的相关资源(如 `manifest.json`、本地化文件夹或 JavaScript 和 HTML 源文件)中提取这些功能。
## 参考资料
* **感谢** [**@naivenom**](https://twitter.com/naivenom) **在这个方法论上的帮助**
* [https://www.cobalt.io/blog/introduction-to-chrome-browser-extension-security-testing](https://www.cobalt.io/blog/introduction-to-chrome-browser-extension-security-testing)
* [https://palant.info/2022/08/10/anatomy-of-a-basic-extension/](https://palant.info/2022/08/10/anatomy-of-a-basic-extension/)
* [https://palant.info/2022/08/24/attack-surface-of-extension-pages/](https://palant.info/2022/08/24/attack-surface-of-extension-pages/)
* [https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/](https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/)
* [https://help.passbolt.com/assets/files/PBL-02-report.pdf](https://help.passbolt.com/assets/files/PBL-02-report.pdf)
* [https://developer.chrome.com/docs/extensions/develop/concepts/content-scripts](https://developer.chrome.com/docs/extensions/develop/concepts/content-scripts)
* [https://developer.chrome.com/docs/extensions/mv2/background-pages](https://developer.chrome.com/docs/extensions/mv2/background-pages)
* [https://thehackerblog.com/kicking-the-rims-a-guide-for-securely-writing-and-auditing-chrome-extensions/](https://thehackerblog.com/kicking-the-rims-a-guide-for-securely-writing-and-auditing-chrome-extensions/)
<details>
<summary><strong>通过</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>从零开始学习 AWS 黑客攻击!</strong></summary>
支持 HackTricks 的其他方式:
* 如果您想在 HackTricks 中看到您的**公司广告**或**下载 HackTricks 的 PDF 版本**,请查看[**订阅计划**](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) 或 [**telegram 群组**](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>