mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
708 lines
43 KiB
Markdown
708 lines
43 KiB
Markdown
# Browser Extension Pentesting Methodology
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
## Grundinformationen
|
|
|
|
Browsererweiterungen sind in JavaScript geschrieben und werden vom Browser im Hintergrund geladen. Sie haben ihr eigenes [DOM](https://www.w3schools.com/js/js_htmldom.asp), können jedoch mit den DOMs anderer Seiten interagieren. Das bedeutet, dass sie die Vertraulichkeit, Integrität und Verfügbarkeit (CIA) anderer Seiten gefährden können.
|
|
|
|
## Hauptkomponenten
|
|
|
|
Die Layouts von Erweiterungen sehen am besten aus, wenn sie visualisiert werden, und bestehen aus drei Komponenten. Lassen Sie uns jede Komponente im Detail betrachten.
|
|
|
|
<figure><img src="../../images/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>
|
|
|
|
### **Inhalts-Skripte**
|
|
|
|
Jedes Inhalts-Skript hat direkten Zugriff auf das DOM einer **einzelnen Webseite** und ist damit potenziell schädlichem Input ausgesetzt. Das Inhalts-Skript enthält jedoch keine Berechtigungen, außer der Fähigkeit, Nachrichten an den Erweiterungskern zu senden.
|
|
|
|
### **Erweiterungskern**
|
|
|
|
Der Erweiterungskern enthält die meisten Berechtigungen/Zugriffe der Erweiterung, kann jedoch nur über [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) und Inhalts-Skripte mit Webinhalten interagieren. Außerdem hat der Erweiterungskern keinen direkten Zugriff auf die Hostmaschine.
|
|
|
|
### **Native Binärdatei**
|
|
|
|
Die Erweiterung erlaubt eine native Binärdatei, die **auf die Hostmaschine mit den vollständigen Berechtigungen des Benutzers zugreifen kann.** Die native Binärdatei interagiert über die standardmäßige Netscape Plugin Application Programming Interface ([NPAPI](https://en.wikipedia.org/wiki/NPAPI)) mit dem Erweiterungskern, die von Flash und anderen Browser-Plugins verwendet wird.
|
|
|
|
### Grenzen
|
|
|
|
> [!CAUTION]
|
|
> Um die vollständigen Berechtigungen des Benutzers zu erhalten, muss ein Angreifer die Erweiterung überzeugen, schädlichen Input vom Inhalts-Skript an den Kern der Erweiterung und vom Kern der Erweiterung an die native Binärdatei weiterzugeben.
|
|
|
|
Jede Komponente der Erweiterung ist durch **starke Schutzgrenzen** voneinander getrennt. Jede Komponente läuft in einem **separaten Betriebssystemprozess**. Inhalts-Skripte und Erweiterungskerne laufen in **Sandbox-Prozessen**, die für die meisten Betriebssystemdienste nicht verfügbar sind.
|
|
|
|
Darüber hinaus sind Inhalts-Skripte von ihren zugehörigen Webseiten getrennt, indem sie **in einem separaten JavaScript-Heap** ausgeführt werden. Das Inhalts-Skript und die Webseite haben **Zugriff auf dasselbe zugrunde liegende DOM**, aber die beiden **tauschen niemals JavaScript-Zeiger aus**, was das Leaken von JavaScript-Funktionalität verhindert.
|
|
|
|
## **`manifest.json`**
|
|
|
|
Eine Chrome-Erweiterung ist einfach ein ZIP-Ordner mit einer [.crx-Dateiendung](https://www.lifewire.com/crx-file-2620391). Der Kern der Erweiterung ist die **`manifest.json`**-Datei im Stammordner, die Layout, Berechtigungen und andere Konfigurationsoptionen angibt.
|
|
|
|
Beispiel:
|
|
```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`
|
|
|
|
Inhalts-Skripte werden **geladen**, wann immer der Benutzer zu einer übereinstimmenden Seite **navigiert**, in unserem Fall zu jeder Seite, die dem **`https://example.com/*`** Ausdruck entspricht und nicht dem **`*://*/*/business*`** Regex entspricht. Sie werden **wie die eigenen Skripte der Seite** ausgeführt und haben beliebigen Zugriff auf das [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*"],
|
|
}
|
|
],
|
|
```
|
|
Um weitere URLs einzuschließen oder auszuschließen, ist es auch möglich, **`include_globs`** und **`exclude_globs`** zu verwenden.
|
|
|
|
Dies ist ein Beispiel für ein Inhalts-Skript, das einen Erklär-Button zur Seite hinzufügt, wenn [die Storage-API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage) verwendet wird, um den `message`-Wert aus dem Speicher der Erweiterung abzurufen.
|
|
```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="../../images/image (23).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
Eine Nachricht wird an die Erweiterungsseiten vom Inhalts-Skript gesendet, wenn dieser Button geklickt wird, durch die Nutzung der [**runtime.sendMessage() API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage). Dies liegt an der Einschränkung des Inhalts-Skripts im direkten Zugriff auf APIs, wobei `storage` eine der wenigen Ausnahmen ist. Für Funktionalitäten über diese Ausnahmen hinaus werden Nachrichten an Erweiterungsseiten gesendet, mit denen Inhalts-Skripte kommunizieren können.
|
|
|
|
> [!WARNING]
|
|
> Je nach Browser können die Fähigkeiten des Inhalts-Skripts leicht variieren. Für Chromium-basierte Browser ist die Liste der Fähigkeiten in der [Chrome Developers documentation](https://developer.chrome.com/docs/extensions/mv3/content_scripts/#capabilities) verfügbar, und für Firefox dient die [MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#webextension_apis) als primäre Quelle.\
|
|
> Es ist auch bemerkenswert, dass Inhalts-Skripte die Fähigkeit haben, mit Hintergrund-Skripten zu kommunizieren, was es ihnen ermöglicht, Aktionen auszuführen und Antworten zurückzugeben.
|
|
|
|
Um Inhalts-Skripte in Chrome anzuzeigen und zu debuggen, kann das Menü der Chrome-Entwicklertools über Optionen > Weitere Tools > Entwicklertools oder durch Drücken von Ctrl + Shift + I aufgerufen werden.
|
|
|
|
Sobald die Entwicklertools angezeigt werden, ist der **Quell-Tab** anzuklicken, gefolgt vom **Inhalts-Skripte**-Tab. Dies ermöglicht die Beobachtung von laufenden Inhalts-Skripten aus verschiedenen Erweiterungen und das Setzen von Haltepunkten, um den Ausführungsfluss zu verfolgen.
|
|
|
|
### Eingespritzte Inhalts-Skripte
|
|
|
|
> [!TIP]
|
|
> Beachten Sie, dass **Inhalts-Skripte nicht zwingend erforderlich sind**, da es auch möglich ist, Skripte **dynamisch** zu **injizieren** und sie **programmgesteuert** in Webseiten über **`tabs.executeScript`** zu injizieren. Dies bietet tatsächlich mehr **granulare Kontrollen**.
|
|
|
|
Für die programmgesteuerte Injektion eines Inhalts-Skripts muss die Erweiterung [Host-Berechtigungen](https://developer.chrome.com/docs/extensions/reference/permissions) für die Seite haben, in die die Skripte injiziert werden sollen. Diese Berechtigungen können entweder durch **Anfordern** innerhalb des Manifests der Erweiterung oder vorübergehend über [**activeTab**](https://developer.chrome.com/docs/extensions/reference/manifest/activeTab) gesichert werden.
|
|
|
|
#### Beispiel für eine activeTab-basierte Erweiterung
|
|
```json:manifest.json
|
|
{
|
|
"name": "My extension",
|
|
...
|
|
"permissions": [
|
|
"activeTab",
|
|
"scripting"
|
|
],
|
|
"background": {
|
|
"service_worker": "background.js"
|
|
},
|
|
"action": {
|
|
"default_title": "Action Button"
|
|
}
|
|
}
|
|
```
|
|
- **Injiziere eine JS-Datei beim Klicken:**
|
|
```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"],
|
|
})
|
|
})
|
|
```
|
|
- **Funktion beim Klicken injizieren:**
|
|
```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,
|
|
})
|
|
})
|
|
```
|
|
#### Beispiel mit Skriptberechtigungen
|
|
```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" })
|
|
```
|
|
Um weitere URLs einzuschließen oder auszuschließen, ist es auch möglich, **`include_globs`** und **`exclude_globs`** zu verwenden.
|
|
|
|
### Content Scripts `run_at`
|
|
|
|
Das Feld `run_at` steuert **wann JavaScript-Dateien in die Webseite injiziert werden**. Der bevorzugte und Standardwert ist `"document_idle"`.
|
|
|
|
Die möglichen Werte sind:
|
|
|
|
- **`document_idle`**: Wann immer möglich
|
|
- **`document_start`**: Nach allen Dateien von `css`, aber bevor andere DOM-Elemente erstellt oder andere Skripte ausgeführt werden.
|
|
- **`document_end`**: Unmittelbar nachdem das DOM vollständig ist, aber bevor Unterressourcen wie Bilder und Frames geladen wurden.
|
|
|
|
#### Via `manifest.json`
|
|
```json
|
|
{
|
|
"name": "My extension",
|
|
...
|
|
"content_scripts": [
|
|
{
|
|
"matches": ["https://*.example.com/*"],
|
|
"run_at": "document_idle",
|
|
"js": ["contentScript.js"]
|
|
}
|
|
],
|
|
...
|
|
}
|
|
|
|
```
|
|
Über **`service-worker.js`**
|
|
```javascript
|
|
chrome.scripting.registerContentScripts([
|
|
{
|
|
id: "test",
|
|
matches: ["https://*.example.com/*"],
|
|
runAt: "document_idle",
|
|
js: ["contentScript.js"],
|
|
},
|
|
])
|
|
```
|
|
### `background`
|
|
|
|
Nachrichten, die von Inhalts-Skripten gesendet werden, werden von der **Hintergrundseite** empfangen, die eine zentrale Rolle bei der Koordination der Komponenten der Erweiterung spielt. Bemerkenswerterweise bleibt die Hintergrundseite während der gesamten Lebensdauer der Erweiterung bestehen und arbeitet diskret ohne direkte Benutzerinteraktion. Sie verfügt über ihr eigenes Document Object Model (DOM), das komplexe Interaktionen und Zustandsmanagement ermöglicht.
|
|
|
|
**Wichtige Punkte**:
|
|
|
|
- **Rolle der Hintergrundseite:** Dient als Nervenzentrum für die Erweiterung und gewährleistet die Kommunikation und Koordination zwischen den verschiedenen Teilen der Erweiterung.
|
|
- **Persistenz:** Es ist eine ständig präsente Entität, die für den Benutzer unsichtbar, aber für die Funktionalität der Erweiterung unerlässlich ist.
|
|
- **Automatische Generierung:** Wenn nicht ausdrücklich definiert, wird der Browser automatisch eine Hintergrundseite erstellen. Diese automatisch generierte Seite enthält alle Hintergrundskripte, die im Manifest der Erweiterung angegeben sind, und gewährleistet den nahtlosen Betrieb der Hintergrundaufgaben der Erweiterung.
|
|
|
|
> [!TIP]
|
|
> Der Komfort, den der Browser bei der automatischen Generierung einer Hintergrundseite (wenn nicht ausdrücklich deklariert) bietet, stellt sicher, dass alle notwendigen Hintergrundskripte integriert und betriebsbereit sind, was den Einrichtungsprozess der Erweiterung vereinfacht.
|
|
|
|
Beispiel für ein Hintergrundskript:
|
|
```js
|
|
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
if (request == "explain") {
|
|
chrome.tabs.create({ url: "https://example.net/explanation" })
|
|
}
|
|
})
|
|
```
|
|
Es verwendet die [runtime.onMessage API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage), um Nachrichten zu empfangen. Wenn eine `"explain"`-Nachricht empfangen wird, verwendet es die [tabs API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs), um eine Seite in einem neuen Tab zu öffnen.
|
|
|
|
Um das Hintergrundskript zu debuggen, könnten Sie zu den **Erweiterungsdetails gehen und den Dienstarbeiter inspizieren,** dies öffnet die Entwicklertools mit dem Hintergrundskript:
|
|
|
|
<figure><img src="https://github.com/carlospolop/hacktricks/blob/master/pentesting-web/browser-extension-pentesting-methodology/broken-reference" alt=""><figcaption></figcaption></figure>
|
|
|
|
### Optionsseiten und andere
|
|
|
|
Browsererweiterungen können verschiedene Arten von Seiten enthalten:
|
|
|
|
- **Aktionsseiten** werden in einem **Dropdown angezeigt, wenn das Erweiterungssymbol** angeklickt wird.
|
|
- Seiten, die die Erweiterung **in einem neuen Tab lädt**.
|
|
- **Optionsseiten**: Diese Seite wird oben auf der Erweiterung angezeigt, wenn sie angeklickt wird. Im vorherigen Manifest konnte ich auf diese Seite zugreifen unter `chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca` oder durch Klicken:
|
|
|
|
<figure><img src="../../images/image (24).png" alt="" width="375"><figcaption></figcaption></figure>
|
|
|
|
Beachten Sie, dass diese Seiten nicht persistent sind wie Hintergrundseiten, da sie dynamisch Inhalte nach Bedarf laden. Trotz dessen teilen sie bestimmte Fähigkeiten mit der Hintergrundseite:
|
|
|
|
- **Kommunikation mit Inhalts-Skripten:** Ähnlich wie die Hintergrundseite können diese Seiten Nachrichten von Inhalts-Skripten empfangen, was die Interaktion innerhalb der Erweiterung erleichtert.
|
|
- **Zugriff auf erweiterungsspezifische APIs:** Diese Seiten haben umfassenden Zugriff auf erweiterungsspezifische APIs, vorbehaltlich der für die Erweiterung definierten Berechtigungen.
|
|
|
|
### `permissions` & `host_permissions`
|
|
|
|
**`permissions`** und **`host_permissions`** sind Einträge aus der `manifest.json`, die anzeigen, **welche Berechtigungen** die Browsererweiterung hat (Speicher, Standort...) und in **welchen Webseiten**.
|
|
|
|
Da Browsererweiterungen so **privilegiert** sein können, könnte eine bösartige oder kompromittierte Erweiterung dem Angreifer **verschiedene Mittel ermöglichen, um sensible Informationen zu stehlen und den Benutzer auszuspionieren**.
|
|
|
|
Überprüfen Sie, wie diese Einstellungen funktionieren und wie sie missbraucht werden könnten in:
|
|
|
|
{{#ref}}
|
|
browext-permissions-and-host_permissions.md
|
|
{{#endref}}
|
|
|
|
### `content_security_policy`
|
|
|
|
Eine **Content-Sicherheitsrichtlinie** kann auch innerhalb der `manifest.json` deklariert werden. Wenn eine definiert ist, könnte sie **anfällig** sein.
|
|
|
|
Die Standardeinstellung für Seiten von Browsererweiterungen ist eher restriktiv:
|
|
```bash
|
|
script-src 'self'; object-src 'self';
|
|
```
|
|
Für weitere Informationen zu CSP und potenziellen Bypässen siehe:
|
|
|
|
{{#ref}}
|
|
../content-security-policy-csp-bypass/
|
|
{{#endref}}
|
|
|
|
### `web_accessible_resources`
|
|
|
|
Damit eine Webseite auf eine Seite einer Browsererweiterung zugreifen kann, beispielsweise eine `.html`-Seite, muss diese Seite im **`web_accessible_resources`**-Feld der `manifest.json` erwähnt werden.\
|
|
Zum Beispiel:
|
|
```javascript
|
|
{
|
|
...
|
|
"web_accessible_resources": [
|
|
{
|
|
"resources": [ "images/*.png" ],
|
|
"matches": [ "https://example.com/*" ]
|
|
},
|
|
{
|
|
"resources": [ "fonts/*.woff" ],
|
|
"matches": [ "https://example.com/*" ]
|
|
}
|
|
],
|
|
...
|
|
}
|
|
```
|
|
Diese Seiten sind über URLs wie zugänglich:
|
|
```
|
|
chrome-extension://<extension-id>/message.html
|
|
```
|
|
In öffentlichen Erweiterungen ist die **extension-id zugänglich**:
|
|
|
|
<figure><img src="../../images/image (1194).png" alt="" width="375"><figcaption></figcaption></figure>
|
|
|
|
Wenn jedoch der `manifest.json` Parameter **`use_dynamic_url`** verwendet wird, kann diese **id dynamisch** sein.
|
|
|
|
> [!TIP]
|
|
> Beachten Sie, dass selbst wenn eine Seite hier erwähnt wird, sie möglicherweise **gegen ClickJacking geschützt** ist, dank der **Content Security Policy**. Daher müssen Sie dies auch überprüfen (frame-ancestors Abschnitt), bevor Sie bestätigen, dass ein ClickJacking-Angriff möglich ist.
|
|
|
|
Der Zugriff auf diese Seiten macht diese Seiten **potenziell anfällig für ClickJacking**:
|
|
|
|
{{#ref}}
|
|
browext-clickjacking.md
|
|
{{#endref}}
|
|
|
|
> [!TIP]
|
|
> Wenn diese Seiten nur von der Erweiterung und nicht von zufälligen URLs geladen werden dürfen, könnte dies ClickJacking-Angriffe verhindern.
|
|
|
|
> [!CAUTION]
|
|
> Beachten Sie, dass die Seiten aus **`web_accessible_resources`** und andere Seiten der Erweiterung ebenfalls in der Lage sind, **Hintergrundskripte zu kontaktieren**. Wenn eine dieser Seiten also anfällig für **XSS** ist, könnte dies eine größere Verwundbarkeit eröffnen.
|
|
>
|
|
> Darüber hinaus beachten Sie, dass Sie nur Seiten, die in **`web_accessible_resources`** angegeben sind, innerhalb von iframes öffnen können, aber von einem neuen Tab aus ist es möglich, auf jede Seite in der Erweiterung zuzugreifen, wenn Sie die Erweiterungs-ID kennen. Daher könnte, wenn ein XSS gefunden wird, das dieselben Parameter ausnutzt, dies auch ausgenutzt werden, selbst wenn die Seite nicht in **`web_accessible_resources`** konfiguriert ist.
|
|
|
|
### `externally_connectable`
|
|
|
|
Laut den [**docs**](https://developer.chrome.com/docs/extensions/reference/manifest/externally-connectable) erklärt die `"externally_connectable"` Manifest-Eigenschaft, **welche Erweiterungen und Webseiten sich mit Ihrer Erweiterung verbinden können** über [runtime.connect](https://developer.chrome.com/docs/extensions/reference/runtime#method-connect) und [runtime.sendMessage](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage).
|
|
|
|
- Wenn der **`externally_connectable`** Schlüssel **nicht** im Manifest Ihrer Erweiterung deklariert ist oder als **`"ids": ["*"]`** deklariert ist, **können alle Erweiterungen sich verbinden, aber keine Webseiten können sich verbinden**.
|
|
- Wenn **spezifische IDs angegeben sind**, wie in `"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]`, **können nur diese Anwendungen** sich verbinden.
|
|
- Wenn **Übereinstimmungen** angegeben sind, können diese Webanwendungen sich verbinden:
|
|
```json
|
|
"matches": [
|
|
"https://*.google.com/*",
|
|
"*://*.chromium.org/*",
|
|
```
|
|
- Wenn es als leer angegeben ist: **`"externally_connectable": {}`**, kann keine App oder Webseite eine Verbindung herstellen.
|
|
|
|
Je **weniger Erweiterungen und URLs** hier angegeben sind, desto **kleiner wird die Angriffsfläche** sein.
|
|
|
|
> [!CAUTION]
|
|
> Wenn eine Webseite **anfällig für XSS oder Übernahme** in **`externally_connectable`** angegeben ist, kann ein Angreifer **Nachrichten direkt an das Hintergrundskript senden**, wodurch das Content-Skript und dessen CSP vollständig umgangen werden.
|
|
>
|
|
> Daher ist dies ein **sehr mächtiger Bypass**.
|
|
>
|
|
> Darüber hinaus, wenn der Client eine bösartige Erweiterung installiert, selbst wenn sie nicht berechtigt ist, mit der anfälligen Erweiterung zu kommunizieren, könnte sie **XSS-Daten in eine erlaubte Webseite injizieren** oder die **`WebRequest`** oder **`DeclarativeNetRequest`** APIs missbrauchen, um Anfragen auf einer gezielten Domain zu manipulieren und eine Anfrage für eine **JavaScript-Datei** zu ändern. (Beachten Sie, dass CSP auf der gezielten Seite diese Angriffe verhindern könnte). Diese Idee stammt [**aus diesem Bericht**](https://www.darkrelay.com/post/opera-zero-day-rce-vulnerability).
|
|
|
|
## Kommunikationsübersicht
|
|
|
|
### Erweiterung <--> WebApp
|
|
|
|
Um zwischen dem Content-Skript und der Webseite zu kommunizieren, werden normalerweise Post-Nachrichten verwendet. Daher finden Sie in der Webanwendung normalerweise Aufrufe der Funktion **`window.postMessage`** und im Content-Skript Listener wie **`window.addEventListener`**. Beachten Sie jedoch, dass die Erweiterung auch **mit der Webanwendung kommunizieren könnte, indem sie eine Post-Nachricht sendet** (und daher sollte die Webseite dies erwarten) oder einfach die Webseite dazu bringt, ein neues Skript zu laden.
|
|
|
|
### Innerhalb der Erweiterung
|
|
|
|
Normalerweise wird die Funktion **`chrome.runtime.sendMessage`** verwendet, um eine Nachricht innerhalb der Erweiterung zu senden (normalerweise vom `background`-Skript verarbeitet) und um sie zu empfangen und zu verarbeiten, wird ein Listener deklariert, der **`chrome.runtime.onMessage.addListener`** aufruft.
|
|
|
|
Es ist auch möglich, **`chrome.runtime.connect()`** zu verwenden, um eine persistente Verbindung anstelle von einzelnen Nachrichten zu haben. Es ist möglich, es zu verwenden, um **Nachrichten** zu **senden** und **zu empfangen**, wie im folgenden Beispiel:
|
|
|
|
<details>
|
|
|
|
<summary><code>chrome.runtime.connect()</code> Beispiel</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>
|
|
|
|
Es ist auch möglich, Nachrichten von einem Hintergrundskript an ein Inhaltskript zu senden, das sich in einem bestimmten Tab befindet, indem man **`chrome.tabs.sendMessage`** aufruft, wobei man die **ID des Tabs** angeben muss, an den die Nachricht gesendet werden soll.
|
|
|
|
### Von erlaubtem `externally_connectable` zur Erweiterung
|
|
|
|
**Webanwendungen und externe Browsererweiterungen, die in der `externally_connectable`-Konfiguration erlaubt sind**, können Anfragen senden mit:
|
|
```javascript
|
|
chrome.runtime.sendMessage(extensionId, ...
|
|
```
|
|
Wo es notwendig ist, die **Erweiterungs-ID** zu erwähnen.
|
|
|
|
### Native Messaging
|
|
|
|
Es ist möglich, dass die Hintergrundskripte mit Binärdateien im System kommunizieren, die **anfällig für kritische Sicherheitsanfälligkeiten wie RCEs** sein könnten, wenn diese Kommunikation nicht ordnungsgemäß gesichert ist. [More on this later](#native-messaging).
|
|
```javascript
|
|
chrome.runtime.sendNativeMessage(
|
|
"com.my_company.my_application",
|
|
{ text: "Hello" },
|
|
function (response) {
|
|
console.log("Received " + response)
|
|
}
|
|
)
|
|
```
|
|
## Web **↔︎** Content Script Kommunikation
|
|
|
|
Die Umgebungen, in denen **Content-Skripte** arbeiten und wo die Host-Seiten existieren, sind **getrennt** voneinander, was **Isolation** gewährleistet. Trotz dieser Isolation haben beide die Möglichkeit, mit dem **Document Object Model (DOM)** der Seite zu interagieren, einer gemeinsamen Ressource. Damit die Host-Seite mit dem **Content-Skript** oder indirekt mit der Erweiterung über das Content-Skript kommunizieren kann, ist es erforderlich, das von beiden Parteien zugängliche **DOM** als Kommunikationskanal zu nutzen.
|
|
|
|
### Post-Nachrichten
|
|
```javascript: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
|
|
)
|
|
```
|
|
|
|
```javascript:example.js
|
|
document.getElementById("theButton").addEventListener(
|
|
"click",
|
|
() => {
|
|
window.postMessage(
|
|
{ type: "FROM_PAGE", text: "Hello from the webpage!" },
|
|
"*"
|
|
)
|
|
},
|
|
false
|
|
)
|
|
```
|
|
Eine sichere Post Message-Kommunikation sollte die Authentizität der empfangenen Nachricht überprüfen, dies kann durch folgende Punkte geschehen:
|
|
|
|
- **`event.isTrusted`**: Dies ist nur dann True, wenn das Ereignis durch eine Benutzeraktion ausgelöst wurde.
|
|
- Das Inhalts-Skript könnte eine Nachricht nur erwarten, wenn der Benutzer eine Aktion ausführt.
|
|
- **Ursprungsdomäne**: könnte eine Nachricht nur von einer erlaubten Liste von Domänen erwarten.
|
|
- Wenn ein Regex verwendet wird, sei sehr vorsichtig.
|
|
- **Quelle**: `received_message.source !== window` kann verwendet werden, um zu überprüfen, ob die Nachricht **aus demselben Fenster** stammt, in dem das Inhalts-Skript lauscht.
|
|
|
|
Die vorherigen Überprüfungen könnten, selbst wenn sie durchgeführt werden, anfällig sein, also überprüfe auf der folgenden Seite **potenzielle Post Message-Bypässe**:
|
|
|
|
{{#ref}}
|
|
../postmessage-vulnerabilities/
|
|
{{#endref}}
|
|
|
|
### Iframe
|
|
|
|
Ein weiterer möglicher Kommunikationsweg könnte über **Iframe-URLs** erfolgen, ein Beispiel findest du in:
|
|
|
|
{{#ref}}
|
|
browext-xss-example.md
|
|
{{#endref}}
|
|
|
|
### DOM
|
|
|
|
Dies ist nicht "genau" ein Kommunikationsweg, aber das **Web und das Inhalts-Skript haben Zugriff auf das Web-DOM**. Wenn das **Inhalts-Skript** also Informationen daraus liest und das **Web-DOM** vertraut, könnte das Web **diese Daten ändern** (weil das Web nicht vertraut werden sollte oder weil das Web anfällig für XSS ist) und das **Inhalts-Skript kompromittieren**.
|
|
|
|
Ein Beispiel für einen **DOM-basierten XSS-Angriff zur Kompromittierung einer Browsererweiterung** findest du in:
|
|
|
|
{{#ref}}
|
|
browext-xss-example.md
|
|
{{#endref}}
|
|
|
|
## Kommunikation zwischen Inhalts-Skript **↔︎** Hintergrund-Skript
|
|
|
|
Ein Inhalts-Skript kann die Funktionen [**runtime.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage) **oder** [**tabs.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/tabs#method-sendMessage) verwenden, um eine **einmalige JSON-serialisierbare** Nachricht zu senden.
|
|
|
|
Um die **Antwort** zu verarbeiten, verwende das zurückgegebene **Promise**. Obwohl du zur Rückwärtskompatibilität weiterhin einen **Callback** als letzten Parameter übergeben kannst.
|
|
|
|
Das Senden einer Anfrage von einem **Inhalts-Skript** sieht so aus:
|
|
```javascript
|
|
;(async () => {
|
|
const response = await chrome.runtime.sendMessage({ greeting: "hello" })
|
|
// do something with response here, not outside the function
|
|
console.log(response)
|
|
})()
|
|
```
|
|
Eine Anfrage von der **Erweiterung** (normalerweise ein **Hintergrundskript**) senden. Beispiel, wie man eine Nachricht an das Inhaltskript im ausgewählten Tab sendet:
|
|
```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)
|
|
})()
|
|
```
|
|
Am **Empfangsende** müssen Sie einen [**runtime.onMessage**](https://developer.chrome.com/docs/extensions/reference/runtime#event-onMessage) **Ereignis-Listener** einrichten, um die Nachricht zu verarbeiten. Dies sieht sowohl aus einem Inhalts-Skript als auch von einer Erweiterungsseite gleich aus.
|
|
```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" })
|
|
})
|
|
```
|
|
Im hervorgehobenen Beispiel wurde **`sendResponse()`** synchron ausgeführt. Um den `onMessage`-Ereignis-Handler für die asynchrone Ausführung von `sendResponse()` zu modifizieren, ist es unerlässlich, `return true;` einzufügen.
|
|
|
|
Eine wichtige Überlegung ist, dass in Szenarien, in denen mehrere Seiten `onMessage`-Ereignisse empfangen sollen, **die erste Seite, die `sendResponse()`** für ein bestimmtes Ereignis ausführt, die einzige sein wird, die die Antwort effektiv liefern kann. Alle nachfolgenden Antworten auf dasselbe Ereignis werden nicht berücksichtigt.
|
|
|
|
Beim Erstellen neuer Erweiterungen sollte die Präferenz auf Promises anstelle von Callbacks liegen. In Bezug auf die Verwendung von Callbacks wird die Funktion `sendResponse()` nur dann als gültig angesehen, wenn sie direkt im synchronen Kontext ausgeführt wird oder wenn der Ereignis-Handler eine asynchrone Operation anzeigt, indem er `true` zurückgibt. Sollten keine der Handler `true` zurückgeben oder wenn die Funktion `sendResponse()` aus dem Speicher entfernt wird (garbage-collected), wird der mit der Funktion `sendMessage()` verbundene Callback standardmäßig ausgelöst.
|
|
|
|
## Native Messaging
|
|
|
|
Browsererweiterungen ermöglichen auch die Kommunikation mit **Binaries im System über stdin**. Die Anwendung muss eine JSON installieren, die dies in einer JSON wie folgt angibt:
|
|
```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/"]
|
|
}
|
|
```
|
|
Wo der `name` der String ist, der an [`runtime.connectNative()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-connectNative) oder [`runtime.sendNativeMessage()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-sendNativeMessage) übergeben wird, um mit der Anwendung von den Hintergrundskripten der Browsererweiterung zu kommunizieren. Der `path` ist der Pfad zur Binärdatei, es gibt nur 1 gültigen `type`, der stdio ist (verwende stdin und stdout) und die `allowed_origins` geben die Erweiterungen an, die darauf zugreifen können (und dürfen kein Wildcard haben).
|
|
|
|
Chrome/Chromium wird in einigen Windows-Registrierungen und einigen Pfaden in macOS und Linux nach diesem JSON suchen (weitere Informationen in den [**docs**](https://developer.chrome.com/docs/extensions/develop/concepts/native-messaging)).
|
|
|
|
> [!TIP]
|
|
> Die Browsererweiterung benötigt auch die `nativeMessaing`-Berechtigung, um diese Kommunikation nutzen zu können.
|
|
|
|
So sieht ein Hintergrundskriptcode aus, der Nachrichten an eine native Anwendung sendet:
|
|
```javascript
|
|
chrome.runtime.sendNativeMessage(
|
|
"com.my_company.my_application",
|
|
{ text: "Hello" },
|
|
function (response) {
|
|
console.log("Received " + response)
|
|
}
|
|
)
|
|
```
|
|
In [**diesem Blogbeitrag**](https://spaceraccoon.dev/universal-code-execution-browser-extensions/) wird ein verwundbares Muster vorgeschlagen, das native Nachrichten missbraucht:
|
|
|
|
1. Die Browsererweiterung hat ein Wildcard-Muster für das Inhalts-Skript.
|
|
2. Das Inhalts-Skript überträgt `postMessage`-Nachrichten an das Hintergrund-Skript mit `sendMessage`.
|
|
3. Das Hintergrund-Skript überträgt die Nachricht an die native Anwendung mit `sendNativeMessage`.
|
|
4. Die native Anwendung verarbeitet die Nachricht gefährlich, was zu einer Codeausführung führt.
|
|
|
|
Und darin wird ein Beispiel für **den Übergang von jeder Seite zu RCE unter Ausnutzung einer Browsererweiterung erklärt**.
|
|
|
|
## Sensible Informationen im Speicher/Code/Clipboard
|
|
|
|
Wenn eine Browsererweiterung **sensible Informationen im Speicher speichert**, könnten diese **ausgelesen** werden (insbesondere auf Windows-Maschinen) und nach diesen Informationen **gesucht** werden.
|
|
|
|
Daher sollte der Speicher der Browsererweiterung **nicht als sicher betrachtet werden** und **sensible Informationen** wie Anmeldeinformationen oder mnemonische Phrasen **sollten nicht gespeichert** werden.
|
|
|
|
Natürlich sollten **keine sensiblen Informationen im Code** platziert werden, da sie **öffentlich** sein werden.
|
|
|
|
Um den Speicher des Browsers auszulesen, könnten Sie **den Prozessspeicher dumpen** oder zu den **Einstellungen** der Browsererweiterung gehen, auf **`Pop-up inspizieren`** klicken -> Im **`Speicher`**-Bereich -> **`Snapshot erstellen`** und **`STRG+F`** verwenden, um im Snapshot nach sensiblen Informationen zu suchen.
|
|
|
|
Darüber hinaus sollten hochsensible Informationen wie mnemonische Schlüssel oder Passwörter **nicht in die Zwischenablage kopiert werden dürfen** (oder zumindest innerhalb weniger Sekunden von der Zwischenablage entfernt werden), da Prozesse, die die Zwischenablage überwachen, sie dann erhalten können.
|
|
|
|
## Laden einer Erweiterung im Browser
|
|
|
|
1. **Laden** Sie die Browsererweiterung herunter und entpacken Sie sie.
|
|
2. Gehen Sie zu **`chrome://extensions/`** und **aktivieren** Sie den `Entwicklermodus`.
|
|
3. Klicken Sie auf die Schaltfläche **`Entpackte Erweiterung laden`**.
|
|
|
|
In **Firefox** gehen Sie zu **`about:debugging#/runtime/this-firefox`** und klicken auf die Schaltfläche **`Temporäre Erweiterung laden`**.
|
|
|
|
## Den Quellcode aus dem Store abrufen
|
|
|
|
Der Quellcode einer Chrome-Erweiterung kann auf verschiedene Weise abgerufen werden. Nachfolgend sind detaillierte Erklärungen und Anweisungen für jede Option aufgeführt.
|
|
|
|
### Erweiterung als ZIP über die Befehlszeile herunterladen
|
|
|
|
Der Quellcode einer Chrome-Erweiterung kann über die Befehlszeile als ZIP-Datei heruntergeladen werden. Dies beinhaltet die Verwendung von `curl`, um die ZIP-Datei von einer bestimmten URL abzurufen und dann den Inhalt der ZIP-Datei in ein Verzeichnis zu extrahieren. Hier sind die Schritte:
|
|
|
|
1. Ersetzen Sie `"extension_id"` durch die tatsächliche ID der Erweiterung.
|
|
2. Führen Sie die folgenden Befehle aus:
|
|
```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"
|
|
```
|
|
### Verwenden Sie die CRX Viewer-Website
|
|
|
|
[https://robwu.nl/crxviewer/](https://robwu.nl/crxviewer/)
|
|
|
|
### Verwenden Sie die CRX Viewer-Erweiterung
|
|
|
|
Eine weitere praktische Methode ist die Verwendung des Chrome Extension Source Viewer, einem Open-Source-Projekt. Es kann aus dem [Chrome Web Store](https://chrome.google.com/webstore/detail/chrome-extension-source-v/jifpbeccnghkjeaalbbjmodiffmgedin?hl=en) installiert werden. Der Quellcode des Viewers ist in seinem [GitHub-Repository](https://github.com/Rob--W/crxviewer) verfügbar.
|
|
|
|
### Quellcode der lokal installierten Erweiterung anzeigen
|
|
|
|
Chrome-Erweiterungen, die lokal installiert sind, können ebenfalls inspiziert werden. So geht's:
|
|
|
|
1. Greifen Sie auf Ihr lokales Chrome-Profilverzeichnis zu, indem Sie `chrome://version/` besuchen und das Feld "Profilpfad" suchen.
|
|
2. Navigieren Sie zum Unterordner `Extensions/` innerhalb des Profilverzeichnisses.
|
|
3. Dieser Ordner enthält alle installierten Erweiterungen, typischerweise mit ihrem Quellcode in einem lesbaren Format.
|
|
|
|
Um Erweiterungen zu identifizieren, können Sie deren IDs den Namen zuordnen:
|
|
|
|
- Aktivieren Sie den Entwicklermodus auf der Seite `about:extensions`, um die IDs jeder Erweiterung zu sehen.
|
|
- Innerhalb des Ordners jeder Erweiterung enthält die Datei `manifest.json` ein lesbares `name`-Feld, das Ihnen hilft, die Erweiterung zu identifizieren.
|
|
|
|
### Verwenden Sie einen Dateiarchivier oder -depacker
|
|
|
|
Gehen Sie zum Chrome Web Store und laden Sie die Erweiterung herunter. Die Datei hat die Erweiterung `.crx`. Ändern Sie die Dateierweiterung von `.crx` in `.zip`. Verwenden Sie einen beliebigen Dateiarchivier (wie WinRAR, 7-Zip usw.), um den Inhalt der ZIP-Datei zu extrahieren.
|
|
|
|
### Verwenden Sie den Entwicklermodus in Chrome
|
|
|
|
Öffnen Sie Chrome und gehen Sie zu `chrome://extensions/`. Aktivieren Sie "Entwicklermodus" oben rechts. Klicken Sie auf "Entpackte Erweiterung laden...". Navigieren Sie zum Verzeichnis Ihrer Erweiterung. Dies lädt den Quellcode nicht herunter, ist jedoch nützlich, um den Code einer bereits heruntergeladenen oder entwickelten Erweiterung anzuzeigen und zu ändern.
|
|
|
|
## Chrome-Erweiterungsmanifest-Datensatz
|
|
|
|
Um anfällige Browsererweiterungen zu erkennen, könnten Sie das [https://github.com/palant/chrome-extension-manifests-dataset](https://github.com/palant/chrome-extension-manifests-dataset) verwenden und deren Manifestdateien auf potenziell anfällige Hinweise überprüfen. Zum Beispiel, um nach Erweiterungen mit mehr als 25000 Benutzern, `content_scripts` und der Berechtigung `nativeMessaging` zu suchen:
|
|
```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')"
|
|
```
|
|
## Sicherheitsprüfliste
|
|
|
|
Obwohl Browsererweiterungen eine **begrenzte Angriffsfläche** haben, können einige von ihnen **Schwachstellen** oder **potenzielle Verbesserungen der Sicherheit** enthalten. Die folgenden sind die häufigsten:
|
|
|
|
- [ ] **Berechtigungen** so weit wie möglich **`permissions`** einschränken
|
|
- [ ] **Host-Berechtigungen** so weit wie möglich **`host_permissions`** einschränken
|
|
- [ ] Eine **starke** **`content_security_policy`** verwenden
|
|
- [ ] **Extern zugängliche** **`externally_connectable`** so weit wie möglich einschränken, wenn keine benötigt wird und möglich ist, lassen Sie es nicht standardmäßig, geben Sie **`{}`** an
|
|
- [ ] Wenn hier eine **URL, die anfällig für XSS oder Übernahme ist**, erwähnt wird, kann ein Angreifer **Nachrichten direkt an die Hintergrundskripte senden**. Sehr mächtiger Umgehung.
|
|
- [ ] **Web zugängliche Ressourcen** so weit wie möglich **`web_accessible_resources`** einschränken, sogar leer, wenn möglich.
|
|
- [ ] Wenn **`web_accessible_resources`** nicht leer ist, überprüfen Sie [**ClickJacking**](browext-clickjacking.md)
|
|
- [ ] Wenn eine **Kommunikation** von der **Erweiterung** zur **Webseite** erfolgt, [**überprüfen Sie auf XSS**](browext-xss-example.md) **Schwachstellen**, die in der Kommunikation verursacht werden.
|
|
- [ ] Wenn Post-Nachrichten verwendet werden, überprüfen Sie auf [**Post-Nachrichten-Schwachstellen**](../postmessage-vulnerabilities/index.html)**.**
|
|
- [ ] Wenn das **Inhalts-Skript auf DOM-Details zugreift**, überprüfen Sie, ob sie **kein XSS einführen**, wenn sie von der Webseite **modifiziert** werden
|
|
- [ ] Besondere Betonung, wenn diese Kommunikation auch an der **Kommunikation zwischen Inhalts-Skript und Hintergrundskript** beteiligt ist
|
|
- [ ] Wenn das Hintergrundskript über **native Messaging** kommuniziert, überprüfen Sie, ob die Kommunikation sicher und bereinigt ist
|
|
- [ ] **Sensible Informationen sollten nicht** im Code der Browsererweiterung **gespeichert** werden
|
|
- [ ] **Sensible Informationen sollten nicht** im Speicher der Browsererweiterung **gespeichert** werden
|
|
- [ ] **Sensible Informationen sollten nicht** im **Dateisystem ungeschützt** **gespeichert** werden
|
|
|
|
## Risiken von Browsererweiterungen
|
|
|
|
- Die App [https://crxaminer.tech/](https://crxaminer.tech/) analysiert einige Daten wie die Berechtigungen, die die Browsererweiterung anfordert, um ein Risikoniveau für die Verwendung der Browsererweiterung anzugeben.
|
|
|
|
## Werkzeuge
|
|
|
|
### [**Tarnish**](https://thehackerblog.com/tarnish/)
|
|
|
|
- Zieht jede Chrome-Erweiterung von einem bereitgestellten Chrome Webstore-Link.
|
|
- [**manifest.json**](https://developer.chrome.com/extensions/manifest) **Viewer**: zeigt einfach eine JSON-hübsch formatierte Version des Manifests der Erweiterung an.
|
|
- **Fingerprint-Analyse**: Erkennung von [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources) und automatische Generierung von JavaScript zur Fingerabdruckerkennung von Chrome-Erweiterungen.
|
|
- **Potenzielle Clickjacking-Analyse**: Erkennung von HTML-Seiten der Erweiterung mit der **web_accessible_resources**-Richtlinie. Diese sind potenziell anfällig für Clickjacking, abhängig vom Zweck der Seiten.
|
|
- **Berechtigungswarnungen Viewer**: zeigt eine Liste aller Chrome-Berechtigungsaufforderungswarnungen, die angezeigt werden, wenn ein Benutzer versucht, die Erweiterung zu installieren.
|
|
- **Gefährliche Funktion(en)**: zeigt den Standort gefährlicher Funktionen, die potenziell von einem Angreifer ausgenutzt werden könnten (z. B. Funktionen wie innerHTML, chrome.tabs.executeScript).
|
|
- **Einstiegspunkt(e)**: zeigt, wo die Erweiterung Benutzereingaben oder externe Eingaben entgegennimmt. Dies ist nützlich, um die Angriffsfläche einer Erweiterung zu verstehen und nach potenziellen Punkten zu suchen, um bösartig gestaltete Daten an die Erweiterung zu senden.
|
|
- Sowohl die Scanner für gefährliche Funktionen als auch die für Einstiegspunkte haben Folgendes für ihre generierten Warnungen:
|
|
- Relevanter Codeausschnitt und Zeile, die die Warnung verursacht hat.
|
|
- Beschreibung des Problems.
|
|
- Eine „Datei anzeigen“-Schaltfläche, um die vollständige Quelldatei mit dem Code anzuzeigen.
|
|
- Der Pfad der alarmierten Datei.
|
|
- Die vollständige Chrome-Erweiterungs-URI der alarmierten Datei.
|
|
- Der Typ der Datei, z. B. ein Hintergrundseiten-Skript, Inhalts-Skript, Browser-Aktion usw.
|
|
- Wenn die anfällige Zeile in einer JavaScript-Datei ist, die Pfade aller Seiten, auf denen sie enthalten ist, sowie den Typ dieser Seiten und den Status der [web_accessible_resource](https://developer.chrome.com/extensions/manifest/web_accessible_resources).
|
|
- **Content Security Policy (CSP) Analyzer und Umgehungsprüfer**: Dies wird Schwächen in der CSP Ihrer Erweiterung aufzeigen und auch potenzielle Möglichkeiten zur Umgehung Ihrer CSP aufgrund von aufgelisteten CDNs usw. aufzeigen.
|
|
- **Bekannte anfällige Bibliotheken**: Dies verwendet [Retire.js](https://retirejs.github.io/retire.js/), um die Verwendung bekannter anfälliger JavaScript-Bibliotheken zu überprüfen.
|
|
- Erweiterung und formatierte Versionen herunterladen.
|
|
- Die ursprüngliche Erweiterung herunterladen.
|
|
- Eine verschönerte Version der Erweiterung herunterladen (automatisch hübsch formatierte HTML- und JavaScript-Dateien).
|
|
- Automatische Zwischenspeicherung der Scanergebnisse, das Ausführen eines Erweiterungsscans dauert beim ersten Mal eine gute Zeit. Beim zweiten Mal, vorausgesetzt, die Erweiterung wurde nicht aktualisiert, wird es aufgrund der zwischengespeicherten Ergebnisse fast sofort sein.
|
|
- Verlinkbare Bericht-URLs, um jemand anderem leicht einen von Tarnish generierten Erweiterungsbericht zu verlinken.
|
|
|
|
### [Neto](https://github.com/elevenpaths/neto)
|
|
|
|
Projekt Neto ist ein Python 3-Paket, das entwickelt wurde, um versteckte Funktionen von Browser-Plugins und -Erweiterungen für bekannte Browser wie Firefox und Chrome zu analysieren und aufzudecken. Es automatisiert den Prozess des Entpackens der gepackten Dateien, um diese Funktionen aus relevanten Ressourcen in einer Erweiterung wie `manifest.json`, Lokalisierungsordnern oder JavaScript- und HTML-Quelldateien zu extrahieren.
|
|
|
|
## Referenzen
|
|
|
|
- **Danke an** [**@naivenom**](https://twitter.com/naivenom) **für die Hilfe mit dieser Methodik**
|
|
- [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)
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|