.. | ||
browext-clickjacking.md | ||
browext-permissions-and-host_permissions.md | ||
browext-xss-example.md | ||
README.md |
浏览器扩展渗透测试方法论
从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS Red Team Expert)!
支持HackTricks的其他方式:
- 如果您想看到您的公司在HackTricks中做广告或下载PDF格式的HackTricks,请查看订阅计划!
- 获取官方PEASS & HackTricks周边产品
- 探索PEASS家族,我们的独家NFTs
- 加入 💬 Discord群 或 电报群 或 关注我们的Twitter 🐦 @carlospolopm。
- 通过向HackTricks和HackTricks Cloud github仓库提交PR来分享您的黑客技巧。
基本信息
浏览器扩展是用JavaScript编写的,并由浏览器在后台加载。它有自己的DOM,但可以与其他网站的DOM进行交互。这意味着它可能会危及其他网站的机密性、完整性和可用性(CIA)。
主要组件
扩展布局在可视化时效果最佳,由三个组件组成。让我们深入了解每个组件。
内容脚本
每个内容脚本直接访问单个网页的DOM,因此容易受到潜在恶意输入的影响。但是,内容脚本除了能够向扩展核心发送消息外,不具备其他权限。
扩展核心
扩展核心包含大部分扩展权限/访问,但扩展核心只能通过XMLHttpRequest和内容脚本与Web内容进行交互。此外,扩展核心无法直接访问主机机器。
本地二进制
扩展允许本地二进制文件以用户的完整权限访问主机机器。本地二进制通过标准的Netscape插件应用程序编程接口(NPAPI)与扩展核心进行交互,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开发者文档中找到,而对于Firefox,MDN是主要来源。
值得注意的是,内容脚本可以与后台脚本通信,使其能够执行操作并传递响应。
{% endhint %}
要在Chrome中查看和调试内容脚本,可以从“选项”>“更多工具”>“开发者工具”或按Ctrl + Shift + I打开Chrome开发者工具菜单。
在显示开发者工具后,应单击源标签,然后单击内容脚本标签。这样可以观察来自各种扩展的运行内容脚本,并设置断点以跟踪执行流程。
注入的内容脚本
{% 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://*.example.com/*" ],
excludeMatches : [ "*://*/*business*" ],
js : [ "contentScript.js" ],
}]);
// Another example
chrome.tabs.executeScript(tabId, { file: "content_script.js" });
Content Scripts 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://*.example.com/*"],
"run_at": "document_idle",
"js": ["contentScript.js"]
}
],
...
}
通过 service-worker.js
chrome.scripting.registerContentScripts([{
id : "test",
matches : [ "https://*.example.com/*" ],
runAt : "document_idle",
js : [ "contentScript.js" ],
}]);
背景
内容脚本发送的消息会被背景页接收,背景页在协调扩展组件方面起着中心作用。值得注意的是,背景页在整个扩展的生命周期中持续存在,不需要直接用户交互,以隐秘方式运行。它拥有自己的文档对象模型(DOM),可以实现复杂的交互和状态管理。
关键要点:
- 背景页角色: 充当扩展的神经中枢,确保扩展各部分之间的通信和协调。
- 持久性: 它是一个始终存在的实体,对用户不可见但对扩展功能至关重要。
- 自动生成: 如果未明确定义,浏览器将自动创建一个背景页。这个自动生成的页面将包括扩展清单中指定的所有背景脚本,确保扩展的背景任务无缝运行。
{% hint style="success" %} 浏览器自动生成背景页(未明确声明时)的便利性确保了所有必要的背景脚本被集成和运行,简化了扩展的设置过程。 {% 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在新标签页中打开一个页面。
要调试后台脚本,您可以转到扩展详细信息并检查服务工作者,这将使用后台脚本打开开发者工具:
选项页面和其他
浏览器扩展可以包含各种类型的页面:
- 操作页面在单击扩展图标时显示在下拉菜单中。
- 扩展将在新标签页中加载的页面。
- 选项页面:单击时显示在扩展顶部的页面。在我的情况下,我能够在
chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca
或单击以下内容中访问此页面:
请注意,这些页面不像后台页面那样持久,因为它们根据需要动态加载内容。尽管如此,它们与后台页面共享某些功能:
- **与内容脚本通信:**与后台页面类似,这些页面可以从内容脚本接收消息,促进扩展内的交互。
- **访问扩展特定的API:**这些页面可以全面访问扩展特定的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
在公共扩展中,扩展ID是可访问的:
尽管如此,如果使用manifest.json
参数**use_dynamic_url
,这个ID可以是动态的**。
{% hint style="success" %} 请注意,即使在这里提到了一个页面,由于内容安全策略的保护,可能会防止点击劫持。因此,在确认可能存在点击劫持攻击之前,您还需要检查它(frame-ancestors部分)。 {% endhint %}
允许访问这些页面会使这些页面潜在易受点击劫持攻击:
{% content-ref url="browext-clickjacking.md" %} browext-clickjacking.md {% endcontent-ref %}
{% hint style="success" %} 只允许这些页面由扩展加载,而不是由随机URL加载,可以防止点击劫持攻击。 {% endhint %}
{% hint style="danger" %}
请注意,来自**web_accessible_resources
和扩展的其他页面也能够联系后台脚本**。因此,如果其中一个页面容易受到XSS攻击,可能会打开更大的漏洞。
此外,请注意,您只能在iframe中打开**web_accessible_resources
中指定的页面,但是从新标签页中,只要知道扩展ID,就可以访问扩展中的任何页面。因此,如果发现滥用相同参数的XSS,即使页面未配置在web_accessible_resources
**中,也可能会被滥用。
{% endhint %}
externally_connectable
根据文档,"externally_connectable"
清单属性声明了哪些扩展和网页可以通过runtime.connect和runtime.sendMessage与您的扩展连接。
- 如果在您的扩展清单中未声明**
externally_connectable
键,或者声明为"ids": ["*"]
**,所有扩展都可以连接,但没有网页可以连接。 - 如果指定了特定的ID,例如
"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
,只有这些应用程序可以连接。 - 如果指定了匹配项,这些Web应用程序将能够连接:
"matches": [
"https://*.google.com/*",
"*://*.chromium.org/*",
- 如果指定为空:
"externally_connectable": {}
,则没有应用程序或网页能够连接。
这里指定的扩展和 URL 越少,攻击面就越小。
{% hint style="danger" %}
如果一个易受 XSS 或接管攻击的网页在 externally_connectable
中被指定,攻击者将能够直接向后台脚本发送消息,完全绕过内容脚本及其 CSP。
因此,这是一个非常强大的绕过方式。
此外,如果客户端安装了一个恶意扩展,即使它不被允许与易受攻击的扩展通信,它也可以在允许的网页中注入 XSS 数据,或者滥用 WebRequest
或 DeclarativeNetRequest
API 来操纵针对特定域的请求,修改页面对 JavaScript 文件 的请求(请注意,目标页面上的 CSP 可能会阻止这些攻击)。这个想法来自这篇文章。
{% endhint %}
通信摘要
扩展 <--> Web 应用程序
为了在内容脚本和网页之间进行通信,通常会使用消息传递。因此,在 Web 应用程序中,通常会找到对函数 window.postMessage
的调用,而在内容脚本中会找到类似 window.addEventListener
的监听器。但请注意,扩展也可以与 Web 应用程序发送 Post Message 进行通信(因此 Web 应该期望这种情况发生),或者只是让 Web 加载一个新脚本。
扩展内部
通常会使用函数 chrome.runtime.sendMessage
在扩展内部发送消息(通常由 background
脚本处理),为了接收和处理消息,会声明一个监听器调用 chrome.runtime.onMessage.addListener
。
还可以使用 chrome.runtime.connect()
杻建立持久连接,而不是发送单个消息,可以使用它来发送和接收 消息,就像下面的示例一样:
chrome.runtime.connect()
示例
```javascript
var port = chrome.runtime.connect();
// Listen for messages from the web page window.addEventListener("message", (event) => { // Only accept messages from the same window if (event.source !== window) { return; }
// Check if the message type is "FROM_PAGE" if (event.data.type && (event.data.type === "FROM_PAGE")) { console.log("Content script received: " + event.data.text); // Forward the message to the background script port.postMessage({ type: 'FROM_PAGE', text: event.data.text }); } }, false);
// Listen for messages from the background script port.onMessage.addListener(function(msg) { console.log("Content script received message from background script:", msg); // Handle the response message from the background script });
</details>
还可以通过从后台脚本发送消息到特定标签中的内容脚本,调用 **`chrome.tabs.sendMessage`**,需要指定要发送消息的**标签ID**。
### 从允许的 `externally_connectable` 到扩展程序
在 `externally_connectable` 配置中允许的**Web应用程序和外部浏览器扩展程序**可以使用以下方式发送请求:
```javascript
chrome.runtime.sendMessage(extensionId, ...
需要提及扩展ID的地方。
Web ↔︎ 内容脚本通信
内容脚本运行的环境和主机页面存在的环境是相互分离的,确保隔离。尽管存在这种隔离,两者都能与页面的文档对象模型(DOM)进行交互,这是一个共享资源。为了使主机页面能够与内容脚本进行通信,或者间接地通过内容脚本与扩展进行通信,需要利用双方都可以访问的DOM作为通信渠道。
发送消息
{% code title="content-script.js" %}
// This is like "chrome.runtime.sendMessage" but to maintain the connection
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);
// Forward the message to the background script
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
这并不是“确切地”一种通信方式,但是web和内容脚本将可以访问web DOM。因此,如果内容脚本从中读取一些信息,信任web DOM,则web可能会修改这些数据(因为不应信任web,或者因为web容易受到XSS攻击),从而危及内容脚本。
您还可以在以下示例中找到一个基于DOM的XSS示例来危及浏览器扩展:
{% content-ref url="browext-xss-example.md" %} browext-xss-example.md {% endcontent-ref %}
内容脚本 ↔︎ 后台脚本通信
内容脚本可以使用函数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);
})();
从扩展程序(通常是后台脚本)发送请求。发送消息到所选标签中的内容脚本的示例:
// From https://stackoverflow.com/questions/36153999/how-to-send-a-message-between-chrome-extension-popup-and-content-script
(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 事件监听器来处理消息。无论是来自内容脚本还是扩展页面,设置方式都是一样的。
// From https://stackoverflow.com/questions/70406787/javascript-send-message-from-content-js-to-background-js
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()
以同步方式执行。要修改onMessage
事件处理程序以异步执行sendResponse()
,必须加入return true;
。
一个重要的考虑因素是,在设置多个页面接收onMessage
事件的情况下,第一个执行sendResponse()
的页面将是唯一能够有效传递响应的页面。对于同一事件的任何后续响应将不被考虑。
在编写新扩展时,应优先选择使用 promises 而不是回调。关于回调的使用,sendResponse()
函数仅在直接在同步上下文中执行,或者如果事件处理程序指示异步操作通过返回true
时才被视为有效。如果没有处理程序返回true
,或者sendResponse()
函数从内存中移除(被垃圾回收),则与sendMessage()
函数关联的回调将默认触发。
内存/代码/剪贴板中的敏感信息
如果浏览器扩展在其内存中存储敏感信息,这些信息可能会被转储(特别是在 Windows 机器上),并且可以对这些信息进行搜索。
因此,浏览器扩展的内存不应被视为安全,敏感信息(如凭据或助记词短语)不应该被存储。
当然,不要将敏感信息放在代码中,因为这将是公开的。
要从浏览器中转储内存,可以转储进程内存,或者转到浏览器扩展的设置,点击**检查弹出窗口
** -> 在**内存
部分 -> 拍摄快照
,然后使用CTRL+F
**在快照中搜索敏感信息。
此外,高度敏感信息如助记密钥或密码不应允许复制到剪贴板(或者至少在几秒钟内从剪贴板中删除),因为监视剪贴板的进程将能够获取它们。
在浏览器中加载扩展
- 下载浏览器扩展并解压缩
- 转到**
chrome://extensions/
并启用**开发者模式
- 点击**
加载已解压的扩展
**按钮
在Firefox中,您可以转到**about:debugging#/runtime/this-firefox
,然后点击加载临时附加组件
**按钮。
从商店获取扩展的源代码
可以通过各种方法获取 Chrome 扩展的源代码。以下是每个选项的详细说明和说明。
通过命令行下载扩展的 ZIP 文件
可以使用命令行将 Chrome 扩展的源代码下载为 ZIP 文件。这涉及使用curl
从特定 URL 获取 ZIP 文件,然后将 ZIP 文件的内容提取到目录中。以下是步骤:
- 将
"extension_id"
替换为扩展的实际 ID。 - 执行以下命令:
extension_id=your_extension_id # Replace with the actual extension 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"
使用 CRX Viewer 网站
使用 CRX Viewer 扩展
另一种方便的方法是使用 Chrome Extension Source Viewer,这是一个开源项目。可以从Chrome Web Store安装。查看查看器的源代码可以在其GitHub存储库中找到。
查看本地安装扩展的源代码
也可以检查本地安装的Chrome扩展。以下是方法:
- 访问Chrome本地配置文件目录,访问
chrome://version/
并找到“Profile Path”字段。 - 转到配置文件目录中的
Extensions/
子文件夹。 - 此文件夹包含所有已安装的扩展,通常以可读格式包含其源代码。
要识别扩展,可以将它们的ID映射到名称:
- 在
about:extensions
页面上启用开发者模式,以查看每个扩展的ID。 - 在每个扩展的文件夹中,
manifest.json
文件包含一个可读的name
字段,可帮助您识别扩展。
使用文件压缩工具或解包工具
前往Chrome Web Store并下载扩展。文件将具有.crx
扩展名。将文件扩展名从.crx
更改为.zip
。使用任何文件压缩工具(如WinRAR、7-Zip等)来提取ZIP文件的内容。
在Chrome中使用开发者模式
打开Chrome并转到chrome://extensions/
。在右上角启用“开发者模式”。单击“加载已解压的扩展...”。导航到扩展的目录。这不会下载源代码,但对于查看和修改已下载或开发的扩展的代码很有用。
安全审计检查清单
尽管浏览器扩展具有有限的攻击面,但其中一些可能包含漏洞或潜在的加固改进。以下是最常见的:
- 尽可能限制请求的**
权限
** - 尽可能限制
host_permissions
** - 使用强大的
content_security_policy
- 尽可能限制
externally_connectable
,如果不需要且可能,不要默认留下,指定**{}
** - 如果此处提到易受XSS攻击或接管的URL,则攻击者将能够直接向后台脚本发送消息。非常强大的绕过方式。
- 尽可能限制
web_accessible_resources
,如果可能,甚至为空。 - 如果**
web_accessible_resources
**不是空的,请检查ClickJacking - 如果从扩展到网页有任何通信,请检查由通信引起的XSS漏洞。
- 如果使用Post Messages,请检查Post Message漏洞。
- 如果内容脚本访问DOM详细信息,请检查它们是否通过网页修改而引入XSS
- 如果此通信还涉及内容脚本 -> 后台脚本通信,请特别强调
- 敏感信息不应存储在浏览器扩展代码中
- 敏感信息不应存储在浏览器扩展内存中
工具
Tarnish
- 从提供的Chrome Webstore链接中提取任何Chrome扩展。
- manifest.json 查看器:简单显示扩展清单的JSON格式化版本。
- 指纹分析:检测web_accessible_resources并自动生成Chrome扩展指纹识别JavaScript。
- 潜在的Clickjacking分析:检测具有设置web_accessible_resources指令的扩展HTML页面。根据页面用途,这些页面可能容易受到点击劫持攻击。
- 权限警告查看器:显示用户尝试安装扩展时将显示的所有Chrome权限提示警告列表。
- 危险功能:显示可能被攻击者利用的危险功能位置(例如innerHTML、chrome.tabs.executeScript等功能)。
- 入口点:显示扩展接受用户/外部输入的位置。这对于了解扩展的表面积并寻找潜在的发送恶意数据到扩展的点很有用。
- 生成的警报包括以下内容:
- 引发警报的相关代码片段和行。
- 问题描述。
- “查看文件”按钮,查看包含代码的完整源文件。
- 警报文件的路径。
- 警报文件的完整Chrome扩展URI。
- 文件类型,如后台页面脚本、内容脚本、浏览器操作等。
- 如果易受攻击的行在JavaScript文件中,则包含所有包含此行的页面的路径以及这些页面的类型和web_accessible_resource状态。
- 内容安全策略(CSP)分析器和绕过检查器:这将指出您的扩展CSP中的弱点,并且还将阐明由于白名单CDN等原因绕过CSP的潜在方法。
- 已知的易受攻击库:使用Retire.js检查已知易受攻击的JavaScript库的使用情况。
- 下载扩展和格式化版本。
- 下载原始扩展。
- 下载扩展的美化版本(自动美化的HTML和JavaScript)。
- 自动缓存扫描结果,第一次运行扩展扫描将花费大量时间。但第二次,假设扩展未更新,由于结果被缓存,几乎瞬间完成。
- 可链接的报告URL,轻松地将其他人链接到由Tarnish生成的扩展报告。
Neto
Neto项目是一个Python 3包,旨在分析和揭示浏览器插件和扩展的隐藏功能,适用于Firefox和Chrome等知名浏览器。它自动化了解压打包文件以从扩展的相关资源中提取这些功能的过程,如manifest.json
、本地化文件夹或JavaScript和HTML源文件。
参考资料
- 感谢@naivenom对本方法论的帮助
- 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/24/attack-surface-of-extension-pages/
- https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/
- 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/mv2/background-pages
- https://thehackerblog.com/kicking-the-rims-a-guide-for-securely-writing-and-auditing-chrome-extensions/
- https://gist.github.com/LongJohnCoder/9ddf5735df3a4f2e9559665fb864eac0
从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS Red Team Expert)!
支持HackTricks的其他方式:
- 如果您想看到您的公司在HackTricks中被广告或下载PDF格式的HackTricks,请查看订阅计划!
- 获取官方PEASS & HackTricks周边产品
- 发现PEASS家族,我们独家NFTs收藏品
- 加入 💬 Discord群组 或 电报群组 或在Twitter上关注我们 🐦 @carlospolopm.
- 通过向HackTricks和HackTricks Cloud github仓库提交PR来分享您的黑客技巧。