Browser Extension Pentesting Methodology

Lernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Grundlegende Informationen

Browser-Erweiterungen sind in JavaScript geschrieben und werden vom Browser im Hintergrund geladen. Es hat sein DOM, kann jedoch mit DOMs anderer Websites interagieren. Dies bedeutet, dass es die Vertraulichkeit, Integrität und Verfügbarkeit (CIA) anderer Websites beeinträchtigen kann.

Hauptkomponenten

Erweiterungslayouts sehen am besten aus, wenn sie visualisiert werden und bestehen aus drei Komponenten. Schauen wir uns jede Komponente genauer an.

Inhaltsskripte

Jedes Inhaltsskript hat direkten Zugriff auf das DOM einer einzigen Webseite und ist somit potenziell bösartigen Eingaben ausgesetzt. Das Inhaltsskript enthält jedoch keine Berechtigungen außer der Fähigkeit, Nachrichten an den Erweiterungskern zu senden.

Erweiterungskern

Der Erweiterungskern enthält die meisten Erweiterungsprivilegien/-zugriffe, kann jedoch nur über XMLHttpRequest und Inhaltsskripte mit Webinhalten interagieren. Außerdem hat der Erweiterungskern keinen direkten Zugriff auf den Hostrechner.

Native Binärdatei

Die Erweiterung ermöglicht eine native Binärdatei, die mit den vollen Berechtigungen des Benutzers auf den Hostrechner zugreifen kann. Die native Binärdatei interagiert mit dem Erweiterungskern über die Standard-Netscape-Plugin-Anwendungsprogrammierschnittstelle (NPAPI), die von Flash und anderen Browser-Plug-Ins verwendet wird.

Grenzen

Um die vollen Berechtigungen des Benutzers zu erlangen, muss ein Angreifer die Erweiterung überzeugen, bösartige Eingaben vom Inhaltsskript an den Erweiterungskern und vom Erweiterungskern an die native Binärdatei weiterzuleiten.

Jede Komponente der Erweiterung ist durch starke Schutzgrenzen voneinander getrennt. Jede Komponente läuft in einem eigenen Betriebssystemprozess. Inhaltsskripte und Erweiterungskerne laufen in Sandbox-Prozessen, die für die meisten Betriebssystemdienste nicht verfügbar sind.

Darüber hinaus sind Inhaltsskripte von ihren zugehörigen Webseiten durch Ausführen in einem separaten JavaScript-Heap getrennt. Das Inhaltsskript und die Webseite haben Zugriff auf denselben zugrunde liegenden DOM, aber die beiden tauschen niemals JavaScript-Pointer aus, was das Auslaufen von JavaScript-Funktionalität verhindert.

manifest.json

Eine Chrome-Erweiterung ist nur ein ZIP-Ordner mit einer .crx-Dateierweiterung. Der Kern der Erweiterung ist die manifest.json-Datei im Stammverzeichnis des Ordners, die Layout, Berechtigungen und andere Konfigurationsoptionen angibt.

Beispiel:

{
"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

Content-Skripte werden geladen, wenn der Benutzer zu einer übereinstimmenden Seite navigiert, in unserem Fall zu einer Seite, die dem Ausdruck https://example.com/* entspricht und nicht dem Regex *://*/*/business* entspricht. Sie werden wie die eigenen Skripte der Seite ausgeführt und haben beliebigen Zugriff auf das Document Object Model (DOM).

"content_scripts": [
{
"js": [
"script.js"
],
"matches": [
"https://example.com/*",
"https://www.example.com/*"
],
"exclude_matches": ["*://*/*business*"],
}
],

Um mehr URLs einzuschließen oder auszuschließen, ist es auch möglich, include_globs und exclude_globs zu verwenden.

Dies ist ein Beispielinhaltsskript, das eine Erklärungsschaltfläche zur Seite hinzufügt, wenn die Speicher-API verwendet wird, um den Wert message aus dem Speicher der Erweiterung abzurufen.

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);
});

Eine Nachricht wird an die Erweiterungsseiten gesendet, wenn auf diese Schaltfläche geklickt wird, durch die Nutzung der runtime.sendMessage() API. Dies liegt an der Beschränkung des Inhaltskripts beim direkten Zugriff auf APIs, wobei storage zu den wenigen Ausnahmen gehört. Für Funktionalitäten über diese Ausnahmen hinaus werden Nachrichten an Erweiterungsseiten gesendet, mit denen Inhaltskripte kommunizieren können.

Je nach Browser können sich die Fähigkeiten des Inhaltskripts geringfügig unterscheiden. Für auf Chromium basierende Browser ist die Liste der Fähigkeiten in der Chrome-Entwicklerdokumentation verfügbar, und für Firefox dient die MDN als primäre Quelle. Es ist auch erwähnenswert, dass Inhaltskripte die Möglichkeit haben, mit Hintergrundskripten zu kommunizieren, was es ihnen ermöglicht, Aktionen auszuführen und Antworten zurückzugeben.

Um Inhaltskripte in Chrome anzuzeigen und zu debuggen, kann das Chrome-Entwicklertools-Menü über Optionen > Weitere Tools > Entwicklertools aufgerufen werden ODER durch Drücken von Strg + Umschalt + I.

Nachdem die Entwicklertools angezeigt werden, sollte auf den Quellentab geklickt werden, gefolgt vom Inhaltskripte-Tab. Dies ermöglicht die Beobachtung der ausgeführten Inhaltskripte aus verschiedenen Erweiterungen und das Setzen von Haltepunkten, um den Ausführungsfluss zu verfolgen.

Eingefügte Inhaltskripte

Beachten Sie, dass Inhaltskripte nicht zwingend erforderlich sind, da es auch möglich ist, Skripte dynamisch einzufügen und sie programmgesteuert in Webseiten über tabs.executeScript einzufügen. Dies bietet tatsächlich mehr feingranulare Kontrollen.

Für die programmgesteuerte Einschleusung eines Inhaltskripts muss die Erweiterung Hostberechtigungen für die Seite haben, in die die Skripte eingefügt werden sollen. Diese Berechtigungen können entweder durch Anforderung im Manifest der Erweiterung oder vorübergehend durch activeTab gesichert werden.

Beispiel für eine activeTab-basierte Erweiterung

manifest.json
{
"name": "My extension",
...
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Action Button"
}
}
  • Injizieren einer JS-Datei beim Klicken:

// 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"]
});
});
  • Fügen Sie eine Funktion hinzu beim Klicken:

//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

// 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 mehr URLs einzuschließen oder auszuschließen, ist es auch möglich, include_globs und exclude_globs zu verwenden.

Inhalts-Scripts run_at

Das Feld run_at steuert wann JavaScript-Dateien in die Webseite eingefügt werden. Der bevorzugte und Standardwert ist "document_idle".

Die möglichen Werte sind:

  • document_idle: Immer wenn möglich

  • document_start: Nach allen Dateien von css, aber vor dem Aufbau eines anderen DOM oder der Ausführung eines anderen Skripts.

  • document_end: Unmittelbar nachdem der DOM vollständig ist, aber bevor Subressourcen wie Bilder und Frames geladen wurden.

Über manifest.json

{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["https://*.example.com/*"],
"run_at": "document_idle",
"js": ["contentScript.js"]
}
],
...
}

Über service-worker.js

chrome.scripting.registerContentScripts([{
id : "test",
matches : [ "https://*.example.com/*" ],
runAt : "document_idle",
js : [ "contentScript.js" ],
}]);

Hintergrund

Nachrichten, die von Inhaltsskripten gesendet werden, werden von der Hintergrundseite empfangen, die eine zentrale Rolle bei der Koordination der Komponenten der Erweiterung spielt. Insbesondere 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 Zustandsverwaltung ermöglicht.

Hauptpunkte:

  • Rolle der Hintergrundseite: Dient als Nervenzentrum für die Erweiterung und gewährleistet die Kommunikation und Koordination zwischen verschiedenen Teilen der Erweiterung.

  • Persistenz: Es handelt sich um eine ständig vorhandene Entität, die für den Benutzer unsichtbar ist, aber für die Funktionalität der Erweiterung unerlässlich ist.

  • Automatische Generierung: Wenn nicht explizit definiert, wird der Browser automatisch eine Hintergrundseite erstellen. Diese automatisch generierte Seite enthält alle im Manifest der Erweiterung angegebenen Hintergrundskripte und gewährleistet den nahtlosen Betrieb der Hintergrundaufgaben der Erweiterung.

Die Bequemlichkeit, die der Browser durch die automatische Generierung einer Hintergrundseite bietet (wenn nicht explizit deklariert), stellt sicher, dass alle erforderlichen Hintergrundskripte integriert und betriebsbereit sind, was den Einrichtungsprozess der Erweiterung vereinfacht.

Beispiel Hintergrundskript:

chrome.runtime.onMessage.addListener((request, sender, sendResponse) =>
{
if (request == "explain")
{
chrome.tabs.create({ url: "https://example.net/explanation" });
}
})

Es verwendet die runtime.onMessage API, um Nachrichten anzuhören. Wenn eine "erklären" Nachricht empfangen wird, verwendet es die Tabs API, um eine Seite in einem neuen Tab zu öffnen.

Um das Hintergrundskript zu debuggen, können Sie zu den Erweiterungsdetails gehen und den Service-Worker inspizieren, dies öffnet die Entwicklertools mit dem Hintergrundskript:

Optionsseiten und andere

Browser-Erweiterungen können verschiedene Arten von Seiten enthalten:

  • Aktionsseiten werden in einem Dropdown-Menü angezeigt, wenn auf das Erweiterungssymbol geklickt wird.

  • Seiten, die die Erweiterung in einem neuen Tab laden wird.

  • Optionsseiten: Diese Seite wird oben auf der Erweiterung angezeigt, wenn darauf geklickt wird. Im vorherigen Manifest konnte ich auf diese Seite zugreifen unter chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca oder durch Klicken auf:

Beachten Sie, dass diese Seiten im Gegensatz zu Hintergrundseiten nicht persistent sind, da sie dynamisch Inhalte bei Bedarf laden. Trotzdem teilen sie bestimmte Fähigkeiten mit der Hintergrundseite:

  • Kommunikation mit Inhaltskripten: Ähnlich wie die Hintergrundseite können diese Seiten Nachrichten von Inhaltskripten empfangen, um die Interaktion innerhalb der Erweiterung zu erleichtern.

  • Zugriff auf erweiterungsspezifische APIs: Diese Seiten haben umfassenden Zugriff auf erweiterungsspezifische APIs, abhängig von den 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 Browser-Erweiterungen haben (Speicher, Standort...) und auf welchen Webseiten.

Da Browser-Erweiterungen so privilegiert sein können, könnte eine bösartige oder kompromittierte Erweiterung einem Angreifer verschiedene Möglichkeiten bieten, sensible Informationen zu stehlen und den Benutzer auszuspionieren.

Überprüfen Sie, wie diese Einstellungen funktionieren und wie sie missbraucht werden können in:

pageBrowExt - permissions & host_permissions

content_security_policy

Eine Content-Security-Policy kann ebenfalls in der manifest.json deklariert werden. Wenn eine definiert ist, könnte sie anfällig sein.

Die Standardkonfiguration für Browser-Erweiterungsseiten ist eher restriktiv:

script-src 'self'; object-src 'self';

Für weitere Informationen zu CSP und möglichen Umgehungen überprüfen Sie:

pageContent Security Policy (CSP) Bypass

web_accessible_resources

Damit eine Webseite auf eine Seite einer Browsererweiterung zugreifen kann, z. B. eine .html-Seite, muss diese Seite im Feld web_accessible_resources der manifest.json erwähnt werden. Zum Beispiel:

{
...
"web_accessible_resources": [
{
"resources": [ "images/*.png" ],
"matches": [ "https://example.com/*" ]
},
{
"resources": [ "fonts/*.woff" ],
"matches": [ "https://example.com/*" ]
}
],
...
}

Diese Seiten sind unter URLs wie folgt erreichbar:

chrome-extension://<extension-id>/message.html

In öffentlichen Erweiterungen ist die Erweiterungs-ID zugänglich:

Wenn jedoch der Parameter manifest.json use_dynamic_url verwendet wird, kann diese ID dynamisch sein.

Das Zugreifen auf diese Seiten macht sie anfällig für potenzielles Clickjacking:

pageBrowExt - ClickJacking

Indem man diese Seiten nur von der Erweiterung und nicht von zufälligen URLs laden lässt, könnten Clickjacking-Angriffe verhindert werden.

externally_connectable

Gemäß der Dokumentation gibt die Manifesteigenschaft "externally_connectable" an, welche Erweiterungen und Webseiten über runtime.connect und runtime.sendMessage mit Ihrer Erweiterung verbunden werden können.

  • Wenn der Schlüssel externally_connectable nicht in Ihrem Erweiterungsmanifest deklariert ist oder als "ids": ["*"] deklariert ist, können alle Erweiterungen eine Verbindung herstellen, aber keine Webseiten.

  • Wenn spezifische IDs angegeben sind, wie in "ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"], können nur diese Anwendungen eine Verbindung herstellen.

  • Wenn Übereinstimmungen angegeben sind, können diese Webanwendungen eine Verbindung herstellen:

"matches": [
"https://*.google.com/*",
"*://*.chromium.org/*",
  • Wenn es als leer angegeben ist: "externally_connectable": {}, wird keine App oder Website eine Verbindung herstellen können.

Je weniger Erweiterungen und URLs hier angegeben sind, desto kleiner wird die Angriffsfläche sein.

Wenn eine Webseite, die anfällig für XSS oder Übernahmen ist, in externally_connectable angegeben ist, kann ein Angreifer Nachrichten direkt an das Hintergrundskript senden, wodurch das Content-Skript und seine CSP vollständig umgangen werden.

Daher handelt es sich hierbei um einen sehr leistungsstarken Bypass.

Darüber hinaus könnte, wenn der Client eine schädliche Erweiterung installiert, selbst wenn diese nicht berechtigt ist, mit der anfälligen Erweiterung zu kommunizieren, XSS-Daten auf einer erlaubten Webseite einschleusen oder WebRequest- oder DeclarativeNetRequest-APIs missbrauchen, um Anfragen auf einer gezielten Domain zu manipulieren und eine Anfrage für eine JavaScript-Datei auf einer Seite zu ändern. (Beachten Sie, dass CSP auf der gezielten Seite diese Angriffe verhindern könnte). Diese Idee stammt aus diesem Bericht.

Web ↔︎ Content-Skript-Kommunikation

Die Umgebungen, in denen Content-Skripte arbeiten, und in denen die Host-Seiten existieren, sind voneinander getrennt, was Isolation gewährleistet. Trotz dieser Isolation haben beide die Möglichkeit, mit dem Document Object Model (DOM) der Seite zu interagieren, einem gemeinsamen Ressourcenbereich. Damit die Host-Seite mit dem Content-Skript kommunizieren kann, oder indirekt mit der Erweiterung über das Content-Skript, muss sie das DOM nutzen, das beiden Parteien als Kommunikationskanal zugänglich ist.

Post-Nachrichten

content-script.js
var port = chrome.runtime.connect();

window.addEventListener("message", (event) => {
// We only accept messages from ourselves
if (event.source !== window) {
return;
}

if (event.data.type && (event.data.type === "FROM_PAGE")) {
console.log("Content script received: " + event.data.text);
port.postMessage(event.data.text);
}
}, false);
beispiel.js
document.getElementById("theButton").addEventListener("click", () => {
window.postMessage(
{type : "FROM_PAGE", text : "Hello from the webpage!"}, "*");
}, false);

Eine sichere Post-Nachrichten-Kommunikation sollte die Echtheit der empfangenen Nachricht überprüfen, dies kann durch folgende Überprüfungen erfolgen:

  • event.isTrusted: Dies ist nur wahr, wenn das Ereignis durch eine Benutzeraktion ausgelöst wurde.

  • Das Inhalts-Skript erwartet möglicherweise eine Nachricht nur, wenn der Benutzer eine Aktion ausführt.

  • Ursprungsdomäne: Erwartet möglicherweise eine Nachricht nur von einer Whitelist von Domänen.

  • Wenn ein Regex verwendet wird, seien Sie 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 zuvor genannten Überprüfungen könnten selbst dann anfällig sein, also überprüfen Sie auf der folgenden Seite potenzielle Post-Nachrichten-Umgehungen:

pagePostMessage Vulnerabilities

Iframe

Eine weitere mögliche Kommunikationsmethode könnte über Iframe-URLs erfolgen, ein Beispiel finden Sie unter:

pageBrowExt - XSS Example

DOM

Dies ist nicht "genau" eine Kommunikationsmethode, aber das Web und das Inhalts-Skript haben Zugriff auf das Web-DOM. Wenn das Inhalts-Skript also einige Informationen daraus liest und dem Web-DOM vertraut, könnte das Web diese Daten ändern (weil dem Web nicht vertraut werden sollte oder weil das Web anfällig für XSS ist) und das Inhalts-Skript gefährden.

Ein Beispiel für eine DOM-basierte XSS zur Kompromittierung einer Browsererweiterung finden Sie auch unter:

pageBrowExt - XSS Example

Sensible Informationen im Speicher/Code

Wenn eine Browsererweiterung sensible Informationen im Speicher speichert, könnten diese ausgelesen (insbesondere auf Windows-Maschinen) und nach diesen Informationen gesucht werden.

Daher sollte der Speicher der Browsererweiterung nicht als sicher angesehen 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 zugänglich sind.

Um den Speicher des Browsers auszulesen, könnten Sie den Prozessspeicher auslesen oder in den Einstellungen der Browsererweiterung auf Inspect pop-up klicken -> Im Abschnitt Memory -> Take a snaphost und STRG+F zum Suchen sensibler Informationen im Snapshot verwenden.

Inhalts-Skript ↔︎ Hintergrundskript-Kommunikation

Ein Inhalts-Skript kann die Funktionen runtime.sendMessage() oder tabs.sendMessage() verwenden, um eine einmalige JSON-serialisierbare Nachricht zu senden.

Um die Antwort zu verarbeiten, verwenden Sie das zurückgegebene Promise. Für die Abwärtskompatibilität können Sie jedoch immer noch eine Rückruffunktion als letzten Argument übergeben.

Das Senden einer Anfrage von einem Inhalts-Skript sieht wie folgt aus:

(async () => {
const response = await chrome.runtime.sendMessage({greeting: "hello"});
// do something with response here, not outside the function
console.log(response);
})();

Senden einer Anfrage von der Erweiterung (normalerweise ein Hintergrundskript). Ein Inhalts-Skript kann die Funktionen verwenden, außer dass Sie angeben müssen, an welchen Tab sie gesendet werden soll. Beispiel, wie man eine Nachricht an das Inhalts-Skript im ausgewählten Tab sendet:

// 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);
})();

Auf der Empfängerseite müssen Sie einen runtime.onMessage Ereignislistener einrichten, um die Nachricht zu verarbeiten. Dies sieht sowohl in einem Inhaltskript als auch in einer Erweiterungsseite gleich aus.

// 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-Ereignisbehandler für die asynchrone Ausführung von sendResponse() zu ändern, ist es unerlässlich, return true; einzubeziehen.

Eine wichtige Überlegung ist, dass in Szenarien, in denen mehrere Seiten so eingestellt sind, dass sie onMessage-Ereignisse empfangen, die erste Seite, die sendResponse() für ein bestimmtes Ereignis ausführt, die einzige sein wird, die die Antwort effektiv übermitteln kann. Alle nachfolgenden Antworten auf dasselbe Ereignis werden nicht berücksichtigt.

Bei der Erstellung neuer Erweiterungen sollte der Vorzug Promises gegenüber Callbacks gelten. In Bezug auf die Verwendung von Callbacks wird die sendResponse()-Funktion nur dann als gültig betrachtet, wenn sie direkt im synchronen Kontext ausgeführt wird oder wenn der Ereignisbehandler eine asynchrone Operation anzeigt, indem er true zurückgibt. Sollten keine der Handler true zurückgeben oder wenn die sendResponse()-Funktion aus dem Speicher entfernt wird (garbage-collected), wird das mit der sendMessage()-Funktion verknüpfte Callback standardmäßig ausgelöst.

Laden einer Erweiterung im Browser

  1. Browser-Erweiterung herunterladen & entpacken

  2. Gehe zu chrome://extensions/ und aktiviere den Entwicklermodus

  3. Klicke auf die Schaltfläche Entpackte Erweiterung laden

In Firefox gehst du zu about:debugging#/runtime/this-firefox und klickst auf die Schaltfläche Temporäre Add-on laden.

Abrufen des Quellcodes aus dem Store

Der Quellcode einer Chrome-Erweiterung kann auf verschiedene Arten erhalten werden. Im Folgenden 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 als ZIP-Datei über die Befehlszeile heruntergeladen werden. Dies beinhaltet die Verwendung von curl, um die ZIP-Datei von einer bestimmten URL abzurufen und dann die Inhalte der ZIP-Datei in ein Verzeichnis zu extrahieren. Hier sind die Schritte:

  1. Ersetze "extension_id" durch die tatsächliche ID der Erweiterung.

  2. Führe die folgenden Befehle aus:

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/

Verwenden Sie die CRX Viewer-Erweiterung

Eine weitere praktische Methode ist die Verwendung des Chrome Extension Source Viewer, der ein Open-Source-Projekt ist. Es kann aus dem Chrome Web Store installiert werden. Der Quellcode des Viewers ist in seinem GitHub-Repository verfügbar.

Quellcode einer lokal installierten Erweiterung anzeigen

Lokal installierte Chrome-Erweiterungen 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 Extensions/-Unterordner innerhalb des Profilverzeichnisses.

  3. Dieser Ordner enthält alle installierten Erweiterungen, normalerweise mit ihrem Quellcode in einem lesbaren Format.

Um Erweiterungen zu identifizieren, können Sie ihre IDs den Namen zuordnen:

  • Aktivieren Sie den Entwicklermodus auf der Seite about:extensions, um die IDs jeder Erweiterung zu sehen.

  • Im Ordner jeder Erweiterung enthält die Datei manifest.json ein lesbares name-Feld, das Ihnen hilft, die Erweiterung zu identifizieren.

Verwenden Sie einen Dateiarchivierer oder -entpacker

Gehen Sie zum Chrome Web Store und laden Sie die Erweiterung herunter. Die Datei wird die Erweiterung .crx haben. Ändern Sie die Dateierweiterung von .crx in .zip. Verwenden Sie einen Dateiarchivierer (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 oben rechts den "Entwicklermodus". Klicken Sie auf "Entpackte Erweiterung laden...". Navigieren Sie zum Verzeichnis Ihrer Erweiterung. Dies lädt nicht den Quellcode herunter, ist aber nützlich, um den Code einer bereits heruntergeladenen oder entwickelten Erweiterung anzuzeigen und zu ändern.

Sicherheitsprüfungs-Checkliste

Obwohl Browser-Erweiterungen eine begrenzte Angriffsfläche haben, können einige von ihnen Schwachstellen oder potenzielle Verbesserungen der Absicherung enthalten. Die folgenden sind die häufigsten:

Werkzeuge

  • Holt jede Chrome-Erweiterung von einem bereitgestellten Chrome-Webstore-Link.

  • manifest.json Viewer: zeigt einfach eine JSON-formatierte Version des Manifests der Erweiterung an.

  • Fingerprint-Analyse: Erkennung von web_accessible_resources und automatische Generierung von JavaScript zur Erstellung von Chrome-Erweiterungs-Fingerabdrücken.

  • Potenzielle Clickjacking-Analyse: Erkennung von Erweiterungs-HTML-Seiten mit der Direktive web_accessible_resources. Diese sind je nach Zweck der Seiten potenziell anfällig für Clickjacking.

  • Berechtigungswarnungs-Viewer: zeigt eine Liste aller Chrome-Berechtigungswarnungen an, die angezeigt werden, wenn ein Benutzer versucht, die Erweiterung zu installieren.

  • Gefährliche Funktionen: zeigt den Ort gefährlicher Funktionen an, die potenziell von einem Angreifer ausgenutzt werden könnten (z. B. Funktionen wie innerHTML, chrome.tabs.executeScript).

  • Einstiegspunkte: zeigt, wo die Erweiterung Benutzer-/externe Eingaben entgegennimmt. Dies ist nützlich, um den Oberflächenbereich einer Erweiterung zu verstehen und nach potenziellen Punkten zu suchen, an die bösartig gestaltete Daten gesendet werden können.

  • Sowohl die Scanner für Gefährliche Funktionen als auch Einstiegspunkte haben folgendes für ihre generierten Warnungen:

  • Relevanten Code-Schnipsel und Zeile, die die Warnung verursacht hat.

  • Beschreibung des Problems.

  • Eine Schaltfläche "Datei anzeigen", um die vollständige Quelldatei mit dem Code anzuzeigen.

  • Der Pfad der alarmierten Datei.

  • Die vollständige Chrome-Erweiterungs-URI der alarmierten Datei.

  • Der Dateityp, z. B. ein Hintergrundseiten-Skript, ein Inhalts-Skript, eine Browseraktion usw.

  • Wenn die anfällige Zeile in einer JavaScript-Datei ist, die Pfade aller Seiten, auf denen sie enthalten ist, sowie der Status dieser Seiten als web_accessible_resource.

  • Content Security Policy (CSP)-Analysator und Bypass-Prüfer: Dies zeigt Schwächen in der CSP Ihrer Erweiterung auf und beleuchtet auch mögliche Umgehungsmöglichkeiten Ihrer CSP aufgrund von whitelisteten CDNs usw.

  • Bekannte verwundbare Bibliotheken: Verwendet Retire.js, um auf die Verwendung von bekannten verwundbaren JavaScript-Bibliotheken zu prüfen.

  • Erweiterung und formatierte Versionen herunterladen.

  • Die originale Erweiterung herunterladen.

  • Eine verschönerte Version der Erweiterung herunterladen (automatisch formatiertes HTML und JavaScript).

  • Automatisches Zwischenspeichern von Scanergebnissen, das Ausführen eines Erweiterungsscans dauert beim ersten Mal eine gute Zeit. Beim zweiten Mal, vorausgesetzt die Erweiterung wurde nicht aktualisiert, erfolgt die Ausführung fast sofort aufgrund der zwischengespeicherten Ergebnisse.

  • Verlinkbare Berichts-URLs, um jemand anderen leicht zu einem von Tarnish generierten Erweiterungsbericht zu verlinken.

Das 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

Erlernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Last updated