hacktricks/pentesting-web/browser-extension-pentesting-methodology/README.md

746 lines
51 KiB
Markdown
Raw Normal View History

# Browser Extension Pentesting Methodology
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
{% endhint %}
## 基本情報
ブラウザ拡張機能はJavaScriptで書かれ、ブラウザによってバックグラウンドで読み込まれます。独自の[DOM](https://www.w3schools.com/js/js\_htmldom.asp)を持っていますが、他のサイトのDOMと相互作用することができます。これは、他のサイトの機密性、完全性、および可用性CIAを危険にさらす可能性があることを意味します。
## 主なコンポーネント
拡張機能のレイアウトは視覚化されると最も良く見え、3つのコンポーネントで構成されています。それぞれのコンポーネントを詳しく見ていきましょう。
<figure><img src="../../.gitbook/assets/image (16) (1) (1).png" alt=""><figcaption><p><a href="http://webblaze.cs.berkeley.edu/papers/Extensions.pdf">http://webblaze.cs.berkeley.edu/papers/Extensions.pdf</a></p></figcaption></figure>
### **コンテンツスクリプト**
各コンテンツスクリプトは**単一のウェブページ**のDOMに直接アクセスでき、**潜在的に悪意のある入力**にさらされます。しかし、コンテンツスクリプトは拡張機能のコアにメッセージを送信する能力以外の権限を持っていません。
### **拡張機能コア**
拡張機能コアは、ほとんどの拡張機能の特権/アクセスを含んでいますが、拡張機能コアは[XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)およびコンテンツスクリプトを介してのみウェブコンテンツと相互作用できます。また、拡張機能コアはホストマシンに直接アクセスすることはできません。
### **ネイティブバイナリ**
拡張機能は、**ユーザーの完全な権限でホストマシンにアクセスできるネイティブバイナリ**を許可します。ネイティブバイナリは、Flashや他のブラウザプラグインで使用される標準のNetscapeプラグインAPI[NPAPI](https://en.wikipedia.org/wiki/NPAPI))を介して拡張機能コアと相互作用します。
### 境界
{% hint style="danger" %}
ユーザーの完全な権限を取得するには、攻撃者は拡張機能にコンテンツスクリプトから拡張機能のコアへの悪意のある入力を渡すように説得し、拡張機能のコアからネイティブバイナリへの悪意のある入力を渡す必要があります。
{% endhint %}
拡張機能の各コンポーネントは、**強力な保護境界**によって互いに分離されています。各コンポーネントは**別々のオペレーティングシステムプロセス**で実行されます。コンテンツスクリプトと拡張機能コアは、ほとんどのオペレーティングシステムサービスに利用できない**サンドボックスプロセス**で実行されます。
さらに、コンテンツスクリプトは**別のJavaScriptヒープで実行されることによって、関連するウェブページから分離されています**。コンテンツスクリプトとウェブページは**同じ基盤となるDOMにアクセスできますが**、2つは**JavaScriptポインタを交換することは決してなく**、JavaScript機能の漏洩を防ぎます。
## **`manifest.json`**
Chrome拡張機能は、単に[.crxファイル拡張子](https://www.lifewire.com/crx-file-2620391)を持つZIPフォルダーです。拡張機能のコアは、フォルダーのルートにある**`manifest.json`**ファイルで、レイアウト、権限、およびその他の設定オプションを指定します。
Example:
```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*`** 正規表現に一致しないページです。これらは**ページ自身のスクリプトのように実行され**、ページの[Document Object Model (DOM)](https://developer.mozilla.org/en-US/docs/Web/API/Document\_Object\_Model)に対して任意のアクセス権を持っています。
```json
"content_scripts": [
{
"js": [
"script.js"
],
"matches": [
"https://example.com/*",
"https://www.example.com/*"
],
"exclude_matches": ["*://*/*business*"],
}
],
```
より多くのURLを含めたり除外したりするために、**`include_globs`** と **`exclude_globs`** を使用することも可能です。
2024-04-06 18:36:04 +00:00
これは、[ストレージAPI](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage)を使用して拡張機能のストレージから`message`値を取得し、ページに説明ボタンを追加する例のコンテンツスクリプトです。
```js
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);
});
```
<figure><img src="../../.gitbook/assets/image (23).png" alt=""><figcaption></figcaption></figure>
2024-04-06 18:36:04 +00:00
このボタンがクリックされると、コンテンツスクリプトによって拡張ページにメッセージが送信されます。これは、[**runtime.sendMessage() API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage)を利用するためです。コンテンツスクリプトはAPIへの直接アクセスに制限があり、`storage`が数少ない例外の一つです。これらの例外を超える機能については、コンテンツスクリプトが通信できる拡張ページにメッセージが送信されます。
{% hint style="warning" %}
ブラウザによって、コンテンツスクリプトの機能は若干異なる場合があります。Chromiumベースのブラウザの場合、機能リストは[Chrome Developers documentation](https://developer.chrome.com/docs/extensions/mv3/content\_scripts/#capabilities)で入手可能で、Firefoxの場合は[MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content\_scripts#webextension\_apis)が主な情報源となります。\
また、コンテンツスクリプトはバックグラウンドスクリプトと通信する能力があり、これによりアクションを実行し、応答を返すことができます。
{% endhint %}
Chromeでコンテンツスクリプトを表示およびデバッグするには、Options > More tools > Developer toolsからChrome開発者ツールメニューにアクセスするか、Ctrl + Shift + Iを押します。
開発者ツールが表示されたら、**Source tab**をクリックし、次に**Content Scripts**タブをクリックします。これにより、さまざまな拡張機能から実行中のコンテンツスクリプトを観察し、実行フローを追跡するためのブレークポイントを設定できます。
### 注入されたコンテンツスクリプト
{% hint style="success" %}
**コンテンツスクリプトは必須ではない**ことに注意してください。**動的に**スクリプトを**注入**したり、**プログラム的に注入**することも可能です。これは実際により**詳細な制御**を提供します。
{% endhint %}
コンテンツスクリプトをプログラム的に注入するには、拡張機能がスクリプトを注入するページに対して[ホスト権限](https://developer.chrome.com/docs/extensions/reference/permissions)を持っている必要があります。これらの権限は、拡張機能のマニフェスト内で**要求する**か、[**activeTab**](https://developer.chrome.com/docs/extensions/reference/manifest/activeTab)を通じて一時的に取得することができます。
#### activeTabベースの拡張機能の例
{% code title="manifest.json" %}
```json
{
"name": "My extension",
...
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Action Button"
}
}
```
{% endcode %}
* **クリックでJSファイルをインジェクトする:**
```javascript
// 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"]
});
});
```
* **クリック時に関数を注入する**:
```javascript
//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,
});
});
```
#### スクリプト権限の例
```javascript
// 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" });
```
より多くのURLを含めたり除外したりするために、**`include_globs`** と **`exclude_globs`** を使用することも可能です。
### コンテンツスクリプト `run_at`
`run_at` フィールドは **JavaScriptファイルがウェブページに注入されるタイミング** を制御します。推奨されるデフォルト値は `"document_idle"` です。
可能な値は次のとおりです:
* **`document_idle`**: 可能な限り
* **`document_start`**: `css` からのファイルの後、しかし他のDOMが構築される前や他のスクリプトが実行される前。
* **`document_end`**: DOMが完了した直後ですが、画像やフレームなどのサブリソースが読み込まれる前。
#### `manifest.json` を介して
```json
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["https://*.example.com/*"],
"run_at": "document_idle",
"js": ["contentScript.js"]
}
],
...
}
```
Via **`service-worker.js`**
```javascript
chrome.scripting.registerContentScripts([{
id : "test",
matches : [ "https://*.example.com/*" ],
runAt : "document_idle",
js : [ "contentScript.js" ],
}]);
```
### `background`
コンテンツスクリプトによって送信されたメッセージは、**バックグラウンドページ**によって受信され、拡張機能のコンポーネントを調整する中心的な役割を果たします。特に、バックグラウンドページは拡張機能のライフタイムを通じて持続し、ユーザーの直接的な操作なしに静かに動作します。独自のドキュメントオブジェクトモデルDOMを持ち、複雑な相互作用と状態管理を可能にします。
**重要なポイント**:
* **バックグラウンドページの役割:** 拡張機能の神経中枢として機能し、拡張機能のさまざまな部分間の通信と調整を確保します。
* **持続性:** ユーザーには見えないが、拡張機能の機能に不可欠な常に存在するエンティティです。
* **自動生成:** 明示的に定義されていない場合、ブラウザは自動的にバックグラウンドページを作成します。この自動生成されたページには、拡張機能のマニフェストに指定されたすべてのバックグラウンドスクリプトが含まれ、拡張機能のバックグラウンドタスクのシームレスな操作を確保します。
{% hint style="success" %}
明示的に宣言されていない場合にブラウザがバックグラウンドページを自動生成することによって提供される便利さは、すべての必要なバックグラウンドスクリプトが統合され、機能することを保証し、拡張機能のセットアッププロセスを簡素化します。
{% endhint %}
Example background script:
```js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) =>
{
if (request == "explain")
{
chrome.tabs.create({ url: "https://example.net/explanation" });
}
})
```
It uses [runtime.onMessage API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage) to listen to messages. When an `"explain"` message is received, it uses [tabs API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs) to open a page in a new tab.
2024-04-06 18:36:04 +00:00
To debug the background script you could go to the **extension details and inspect the service worker,** this will open the developer tools with the background script:
<figure><img src="https://github.com/carlospolop/hacktricks/blob/master/pentesting-web/browser-extension-pentesting-methodology/broken-reference" alt=""><figcaption></figcaption></figure>
### オプションページとその他
ブラウザ拡張機能にはさまざまな種類のページが含まれることがあります:
* **アクションページ**は、**拡張機能のアイコン**がクリックされたときにドロップダウンで表示されます。
* 拡張機能が**新しいタブで読み込むページ**。
* **オプションページ**:このページはクリックすると拡張機能の上に表示されます。前のマニフェストでは、私はこのページに`chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca`でアクセスできました、またはクリックすることで:
<figure><img src="../../.gitbook/assets/image (24).png" alt="" width="375"><figcaption></figcaption></figure>
これらのページは、必要に応じて動的にコンテンツを読み込むため、バックグラウンドページのように永続的ではないことに注意してください。それにもかかわらず、これらはバックグラウンドページと特定の機能を共有しています:
* **コンテンツスクリプトとの通信:** バックグラウンドページと同様に、これらのページはコンテンツスクリプトからメッセージを受信でき、拡張機能内での相互作用を促進します。
* **拡張機能固有の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](browext-permissions-and-host\_permissions.md)
{% endcontent-ref %}
### `content_security_policy`
**コンテンツセキュリティポリシー**は、`manifest.json`内にも宣言できます。定義されている場合、それは**脆弱である可能性があります**。
2024-04-06 18:36:04 +00:00
ブラウザ拡張機能ページのデフォルト設定はかなり制限されています:
```bash
script-src 'self'; object-src 'self';
```
CSPや潜在的なバイパスに関する詳細は、以下を確認してください
{% content-ref url="../content-security-policy-csp-bypass/" %}
[content-security-policy-csp-bypass](../content-security-policy-csp-bypass/)
{% endcontent-ref %}
### `web_accessible_resources`
ウェブページがブラウザ拡張のページにアクセスするためには、例えば`.html`ページ、このページは`manifest.json`の**`web_accessible_resources`**フィールドに記載されている必要があります。\
例えば:
```javascript
{
...
"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がアクセス可能**です:
2024-04-06 18:36:04 +00:00
<figure><img src="../../.gitbook/assets/image (1194).png" alt="" width="375"><figcaption></figcaption></figure>
ただし、`manifest.json`パラメータ**`use_dynamic_url`**が使用されている場合、この**idは動的**になる可能性があります。
{% hint style="success" %}
ここにページが記載されていても、**Content Security Policy**のおかげで**ClickJacking**に対して**保護されている**可能性があることに注意してください。したがって、ClickJacking攻撃が可能かどうかを確認する前に、これをチェックする必要がありますframe-ancestorsセクション
{% endhint %}
これらのページにアクセスできることは、これらのページが**潜在的に脆弱なClickJacking**であることを意味します:
{% content-ref url="browext-clickjacking.md" %}
[browext-clickjacking.md](browext-clickjacking.md)
{% endcontent-ref %}
{% hint style="success" %}
これらのページが拡張機能によってのみ読み込まれ、ランダムなURLからは読み込まれないようにすることで、ClickJacking攻撃を防ぐことができます。
{% endhint %}
{% hint style="danger" %}
**`web_accessible_resources`**からのページや拡張機能の他のページも**バックグラウンドスクリプトに連絡する**ことができることに注意してください。したがって、これらのページのいずれかが**XSS**に対して脆弱である場合、より大きな脆弱性を引き起こす可能性があります。
さらに、**`web_accessible_resources`**に示されたページはiframe内でのみ開くことができますが、新しいタブからは拡張機能IDを知っていれば拡張機能内の任意のページにアクセスすることが可能です。したがって、同じパラメータを悪用するXSSが見つかった場合、ページが**`web_accessible_resources`**に設定されていなくても悪用される可能性があります。
{% endhint %}
### `externally_connectable`
[**docs**](https://developer.chrome.com/docs/extensions/reference/manifest/externally-connectable)によると、`"externally_connectable"`マニフェストプロパティは、**どの拡張機能とウェブページがあなたの拡張機能に接続できるか**を宣言します。これは、[runtime.connect](https://developer.chrome.com/docs/extensions/reference/runtime#method-connect)および[runtime.sendMessage](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage)を介して行われます。
2024-04-06 18:36:04 +00:00
* **`externally_connectable`**キーが拡張機能のマニフェストに**宣言されていない**場合、または**`"ids": ["*"]`**として宣言されている場合、**すべての拡張機能が接続できますが、ウェブページは接続できません**。
* **特定のIDが指定されている**場合、例えば`"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]`のように、**そのアプリケーションのみ**が接続できます。
* **マッチが指定されている**場合、これらのウェブアプリは接続できるようになります:
```json
"matches": [
"https://*.google.com/*",
"*://*.chromium.org/*",
```
* 空として指定されている場合: **`"externally_connectable": {}`**、アプリやウェブは接続できません。
2024-04-06 18:36:04 +00:00
ここで示されている **拡張機能とURLが少ないほど**、**攻撃面は小さく**なります。
{% hint style="danger" %}
もしウェブページが **`externally_connectable`** に **XSSまたはテイクオーバーに脆弱** として示されている場合、攻撃者は **バックグラウンドスクリプトに直接メッセージを送信** でき、Content ScriptとそのCSPを完全にバイパスすることができます。
したがって、これは **非常に強力なバイパス** です。
さらに、クライアントが不正な拡張機能をインストールした場合、たとえそれが脆弱な拡張機能と通信することが許可されていなくても、**許可されたウェブページにXSSデータを注入** したり、**`WebRequest`** または **`DeclarativeNetRequest`** APIを悪用して、ターゲットドメインのリクエストを操作し、ページの **JavaScriptファイル** のリクエストを変更することができます。ターゲットページのCSPがこれらの攻撃を防ぐ可能性があることに注意してください。このアイデアは [**この書き込みから**](https://www.darkrelay.com/post/opera-zero-day-rce-vulnerability) 来ています。
{% endhint %}
## コミュニケーションの概要
### 拡張機能 <--> ウェブアプリ
コンテンツスクリプトとウェブページ間で通信するために、通常はポストメッセージが使用されます。したがって、ウェブアプリケーションでは通常 **`window.postMessage`** 関数への呼び出しが見られ、コンテンツスクリプトでは **`window.addEventListener`** のようなリスナーが見られます。ただし、拡張機能は **ポストメッセージを送信してウェブアプリケーションと通信** することもでき(したがってウェブはそれを期待する必要があります)、単にウェブに新しいスクリプトを読み込ませることもできます。
### 拡張機能内
通常、拡張機能内でメッセージを送信するために **`chrome.runtime.sendMessage`** 関数が使用され(通常は `background` スクリプトによって処理されます)、それを受信して処理するためにリスナーが **`chrome.runtime.onMessage.addListener`** を呼び出して宣言されます。
**`chrome.runtime.connect()`** を使用して、単一のメッセージを送信する代わりに持続的な接続を持つことも可能で、次の例のように **メッセージを送信****受信** するために使用できます。
<details>
<summary><code>chrome.runtime.connect()</code> の例</summary>
```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**を言及する必要があります。
### ネイティブメッセージング
バックグラウンドスクリプトがシステム内のバイナリと通信することが可能であり、この通信が適切に保護されていない場合、**RCEなどの重大な脆弱性にさらされる可能性があります**。[後で詳しく説明します](./#native-messaging)。
```javascript
chrome.runtime.sendNativeMessage(
'com.my_company.my_application',
{text: 'Hello'},
function (response) {
console.log('Received ' + response);
}
);
```
## Web **↔︎** コンテンツスクリプト通信
**コンテンツスクリプト**が動作する環境とホストページが存在する環境は**分離**されており、**隔離**が確保されています。この隔離にもかかわらず、両者はページの**ドキュメントオブジェクトモデル (DOM)**、つまり共有リソースと相互作用する能力を持っています。ホストページが**コンテンツスクリプト**と通信するため、またはコンテンツスクリプトを介して拡張機能と間接的に通信するためには、両者がアクセス可能な**DOM**を通信チャネルとして利用する必要があります。
### ポストメッセージ
{% code title="content-script.js" %}
```javascript
// 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" %}
```javascript
document.getElementById("theButton").addEventListener("click", () => {
window.postMessage(
{type : "FROM_PAGE", text : "Hello from the webpage!"}, "*");
}, false);
```
{% endcode %}
安全なPost Message通信は、受信したメッセージの信頼性を確認する必要があります。これは以下を確認することで行えます
* **`event.isTrusted`**: これは、イベントがユーザーのアクションによってトリガーされた場合のみTrueになります。
* コンテンツスクリプトは、ユーザーが何らかのアクションを実行した場合にのみメッセージを期待するかもしれません。
* **origin domain**: メッセージを期待する場合は、許可リストのドメインのみを許可するかもしれません。
* 正規表現が使用される場合は、非常に注意が必要です。
* **Source**: `received_message.source !== window`を使用して、メッセージが**コンテンツスクリプトがリスニングしている同じウィンドウから**のものであるかを確認できます。
前述のチェックは、実施されていても脆弱である可能性があるため、次のページで**潜在的なPost Messageバイパス**を確認してください:
{% content-ref url="../postmessage-vulnerabilities/" %}
[postmessage-vulnerabilities](../postmessage-vulnerabilities/)
{% endcontent-ref %}
### Iframe
別の通信方法として**Iframe URLs**を通じて行うことが考えられます。例は以下にあります:
{% content-ref url="browext-xss-example.md" %}
[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](browext-xss-example.md)
{% endcontent-ref %}
## コンテンツスクリプト **↔︎** バックグラウンドスクリプト通信
コンテンツスクリプトは、[**runtime.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage) **または** [**tabs.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/tabs#method-sendMessage)を使用して、**一度きりのJSONシリアライズ可能な**メッセージを送信できます。
**レスポンス**を処理するには、返された**Promise**を使用します。ただし、後方互換性のために、最後の引数として**コールバック**を渡すこともできます。
**コンテンツスクリプト**からリクエストを送信するのは次のようになります:
```javascript
(async () => {
const response = await chrome.runtime.sendMessage({greeting: "hello"});
// do something with response here, not outside the function
console.log(response);
})();
```
**拡張機能**からリクエストを送信します(通常は**バックグラウンドスクリプト**)。選択したタブのコンテンツスクリプトにメッセージを送信する方法の例:
```javascript
// 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**](https://developer.chrome.com/docs/extensions/reference/runtime#event-onMessage) **イベントリスナー**を設定する必要があります。これは、コンテンツスクリプトまたは拡張ページから見ると同じように見えます。
```javascript
// 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()`** は同期的に実行されました。`sendResponse()` の非同期実行のために `onMessage` イベントハンドラーを修正するには、`return true;` を組み込むことが不可欠です。
重要な考慮事項は、複数のページが `onMessage` イベントを受信するように設定されているシナリオでは、**特定のイベントに対して `sendResponse()`** を最初に実行したページだけが、効果的に応答を提供できるということです。同じイベントに対するその後の応答は考慮されません。
新しい拡張機能を作成する際は、コールバックよりもプロミスを優先すべきです。コールバックの使用に関しては、`sendResponse()` 関数は、同期コンテキスト内で直接実行される場合、またはイベントハンドラーが `true` を返すことによって非同期操作を示す場合にのみ有効と見なされます。どのハンドラーも `true` を返さない場合や、`sendResponse()` 関数がメモリから削除された場合(ガーベジコレクションされた場合)、`sendMessage()` 関数に関連付けられたコールバックがデフォルトでトリガーされます。
## ネイティブメッセージング
ブラウザ拡張機能は、**システム内のバイナリと stdin 経由で通信することも可能です**。アプリケーションは、次のような json を示す json をインストールする必要があります:
```json
{
"name": "com.my_company.my_application",
"description": "My Application",
"path": "C:\\Program Files\\My Application\\chrome_native_messaging_host.exe",
"type": "stdio",
"allowed_origins": ["chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"]
}
```
`name` は [`runtime.connectNative()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-connectNative) または [`runtime.sendNativeMessage()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-sendNativeMessage) に渡される文字列で、ブラウザ拡張のバックグラウンドスクリプトからアプリケーションと通信します。 `path` はバイナリへのパスで、1つの有効な `type` は stdiostdin と stdout を使用)であり、 `allowed_origins` はアクセスできる拡張機能を示します(ワイルドカードは使用できません)。
Chrome/Chromium は、この JSON をいくつかの Windows レジストリや macOS および Linux のいくつかのパスで検索します(詳細は [**docs**](https://developer.chrome.com/docs/extensions/develop/concepts/native-messaging) を参照)。
{% hint style="success" %}
ブラウザ拡張は、この通信を使用するために `nativeMessaing` 権限を宣言する必要があります。
{% endhint %}
これは、ネイティブアプリケーションにメッセージを送信するバックグラウンドスクリプトコードの例です:
```javascript
chrome.runtime.sendNativeMessage(
'com.my_company.my_application',
{text: 'Hello'},
function (response) {
console.log('Received ' + response);
}
);
```
In [**このブログ投稿**](https://spaceraccoon.dev/universal-code-execution-browser-extensions/)では、ネイティブメッセージを悪用する脆弱なパターンが提案されています:
1. ブラウザ拡張機能はコンテンツスクリプトのためのワイルドカードパターンを持っています。
2. コンテンツスクリプトは`sendMessage`を使用してバックグラウンドスクリプトに`postMessage`メッセージを渡します。
3. バックグラウンドスクリプトは`sendNativeMessage`を使用してネイティブアプリケーションにメッセージを渡します。
4. ネイティブアプリケーションはメッセージを危険に扱い、コード実行につながります。
そして、その中で**ブラウザ拡張機能を悪用して任意のページからRCEに移行する例が説明されています**。
2024-04-06 18:36:04 +00:00
## メモリ/コード/クリップボード内の機密情報
ブラウザ拡張機能が**メモリ内に機密情報を保存している場合**、これは**ダンプ**される可能性があり特にWindowsマシンで、この情報が**検索**される可能性があります。
したがって、ブラウザ拡張機能のメモリは**安全とは見なされるべきではなく**、資格情報やニーモニックフレーズなどの**機密情報は保存されるべきではありません**。
もちろん、**コード内に機密情報を置かないでください**、それは**公開されることになります**。
ブラウザからメモリをダンプするには、**プロセスメモリをダンプする**か、ブラウザ拡張機能の**設定**に行き、**`Inspect pop-up`**をクリック -> **`Memory`**セクション -> **`Take a snapshot`**を選択し、**`CTRL+F`**でスナップショット内の機密情報を検索します。
さらに、ニーモニックキーやパスワードのような非常に機密性の高い情報は、**クリップボードにコピーされることを許可すべきではありません**(または少なくとも数秒以内にクリップボードから削除するべきです)なぜなら、クリップボードを監視しているプロセスがそれらを取得できるからです。
## ブラウザに拡張機能を読み込む
1. **ブラウザ拡張機能をダウンロード**し、解凍します。
2. **`chrome://extensions/`**に移動し、`Developer Mode`を**有効にします**。
3. **`Load unpacked`**ボタンをクリックします。
**Firefox**では、**`about:debugging#/runtime/this-firefox`**に移動し、**`Load Temporary Add-on`**ボタンをクリックします。
## ストアからソースコードを取得する
Chrome拡張機能のソースコードは、さまざまな方法で取得できます。以下は各オプションの詳細な説明と手順です。
### コマンドラインを介してZIPとして拡張機能をダウンロード
Chrome拡張機能のソースコードは、コマンドラインを使用してZIPファイルとしてダウンロードできます。これは、特定のURLからZIPファイルを取得するために`curl`を使用し、その後ZIPファイルの内容をディレクトリに抽出することを含みます。手順は以下の通りです
1. `"extension_id"`を拡張機能の実際のIDに置き換えます。
2. 次のコマンドを実行します:
```bash
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ビューワーウェブサイトを使用する
[https://robwu.nl/crxviewer/](https://robwu.nl/crxviewer/)
### CRXビューワー拡張機能を使用する
もう一つの便利な方法は、オープンソースプロジェクトであるChrome拡張機能ソースビューワーを使用することです。これは[Chromeウェブストア](https://chrome.google.com/webstore/detail/chrome-extension-source-v/jifpbeccnghkjeaalbbjmodiffmgedin?hl=en)からインストールできます。ビューワーのソースコードはその[GitHubリポジトリ](https://github.com/Rob--W/crxviewer)で入手可能です。
### ローカルにインストールされた拡張機能のソースを表示する
ローカルにインストールされたChrome拡張機能も検査できます。方法は以下の通りです
1. `chrome://version/`にアクセスし、「プロファイルパス」フィールドを見つけて、Chromeのローカルプロファイルディレクトリにアクセスします。
2. プロファイルディレクトリ内の`Extensions/`サブフォルダに移動します。
3. このフォルダには、通常は読みやすい形式のソースコードを持つすべてのインストールされた拡張機能が含まれています。
拡張機能を特定するには、IDを名前にマッピングできます
* `about:extensions`ページで開発者モードを有効にして、各拡張機能のIDを表示します。
* 各拡張機能のフォルダ内の`manifest.json`ファイルには、拡張機能を特定するのに役立つ読みやすい`name`フィールドが含まれています。
### ファイルアーカイバーまたはアンパッカーを使用する
Chromeウェブストアに行き、拡張機能をダウンロードします。ファイルは`.crx`拡張子を持っています。ファイルの拡張子を`.crx`から`.zip`に変更します。任意のファイルアーカイバーWinRAR、7-Zipなどを使用してZIPファイルの内容を抽出します。
### Chromeで開発者モードを使用する
Chromeを開き、`chrome://extensions/`に移動します。右上で「開発者モード」を有効にします。「解凍された拡張機能を読み込む...」をクリックします。拡張機能のディレクトリに移動します。これはソースコードをダウンロードするものではありませんが、すでにダウンロードまたは開発された拡張機能のコードを表示および変更するのに便利です。
## Chrome拡張機能マニフェストデータセット
脆弱なブラウザ拡張機能を見つけるために、[https://github.com/palant/chrome-extension-manifests-dataset](https://github.com/palant/chrome-extension-manifests-dataset)を使用し、マニフェストファイルに潜在的な脆弱性の兆候がないか確認できます。例えば、25000人以上のユーザーを持つ拡張機能、`content_scripts`、および権限`nativeMessaging`を確認するために:
{% code overflow="wrap" %}
```bash
# Query example from https://spaceraccoon.dev/universal-code-execution-browser-extensions/
node query.js -f "metadata.user_count > 250000" "manifest.content_scripts?.length > 0 && manifest.permissions?.includes('nativeMessaging')"
```
{% endcode %}
## セキュリティ監査チェックリスト
ブラウザ拡張機能は**攻撃面が限られています**が、その中には**脆弱性**や**強化の可能性**が含まれている場合があります。以下は最も一般的なものです:
* [ ] **要求される** **`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/)**を確認する。**
* [ ] **Content ScriptがDOMの詳細にアクセス**する場合、ウェブによって**変更**されると**XSSを導入していないか**確認する
* [ ] この通信が**Content Script -> バックグラウンドスクリプト通信**にも関与している場合は特に強調する
* [ ] バックグラウンドスクリプトが**ネイティブメッセージング**を介して通信している場合、通信が安全でサニタイズされていることを確認する
* [ ] **機密情報は**ブラウザ拡張機能の**コード内に保存すべきではない**
* [ ] **機密情報は**ブラウザ拡張機能の**メモリ内に保存すべきではない**
* [ ] **機密情報は****ファイルシステムに無防備に保存すべきではない**
## ツール
### [**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ページの検出。これらはページの目的に応じてClickjackingに対して脆弱である可能性があります。
* **権限警告ビューワー**: ユーザーが拡張機能をインストールしようとしたときに表示されるすべての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
* スキャン結果の自動キャッシュ。拡張機能のスキャンを初めて実行する際にはかなりの時間がかかります。しかし、拡張機能が更新されていない限り、2回目は結果がキャッシュされているためほぼ瞬時に完了します。
* リンク可能なレポートURL。誰かにTarnishによって生成された拡張機能レポートへのリンクを簡単に提供できます。
### [Neto](https://github.com/elevenpaths/neto)
プロジェクトNetoは、FirefoxやChromeなどの有名なブラウザのブラウザプラグインや拡張機能の隠れた機能を分析し解明するために考案されたPython 3パッケージです。`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/)
* [https://gist.github.com/LongJohnCoder/9ddf5735df3a4f2e9559665fb864eac0](https://gist.github.com/LongJohnCoder/9ddf5735df3a4f2e9559665fb864eac0)
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
2024-04-06 18:36:04 +00:00
</details>
{% endhint %}