mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-26 22:52:06 +00:00
603 lines
36 KiB
Markdown
603 lines
36 KiB
Markdown
# Metodologia di pentesting delle estensioni del browser
|
|
|
|
<details>
|
|
|
|
<summary><strong>Impara l'hacking di AWS da zero a eroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Altri modi per supportare HackTricks:
|
|
|
|
* Se vuoi vedere la tua **azienda pubblicizzata su HackTricks** o **scaricare HackTricks in PDF** Controlla i [**PACCHETTI DI ABBONAMENTO**](https://github.com/sponsors/carlospolop)!
|
|
* Ottieni il [**merchandising ufficiale di PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Scopri [**The PEASS Family**](https://opensea.io/collection/the-peass-family), la nostra collezione di [**NFT**](https://opensea.io/collection/the-peass-family) esclusivi
|
|
* **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo Telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
* **Condividi i tuoi trucchi di hacking inviando PR a** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|
|
|
|
## Informazioni di base
|
|
|
|
Le estensioni del browser sono scritte in JavaScript e vengono caricate dal browser in background. Hanno il loro [DOM](https://www.w3schools.com/js/js\_htmldom.asp) ma possono interagire con i DOM di altri siti. Ciò significa che possono compromettere la confidenzialità, l'integrità e la disponibilità (CIA) di altri siti.
|
|
|
|
## Componenti principali
|
|
|
|
I layout delle estensioni appaiono al meglio quando visualizzati e sono composti da tre componenti. Vediamo ogni componente nel dettaglio.
|
|
|
|
<figure><img src="../../.gitbook/assets/image (4).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>
|
|
|
|
### **Script di contenuto**
|
|
|
|
Ogni script di contenuto ha accesso diretto al DOM di una **singola pagina web** ed è quindi esposto a **input potenzialmente dannosi**. Tuttavia, lo script di contenuto non ha altre autorizzazioni oltre alla capacità di inviare messaggi al core dell'estensione.
|
|
|
|
### **Core dell'estensione**
|
|
|
|
Il core dell'estensione contiene la maggior parte dei privilegi/accessi dell'estensione, ma può interagire solo con il contenuto web tramite [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) e script di contenuto. Inoltre, il core dell'estensione non ha accesso diretto alla macchina host.
|
|
|
|
### **Binario nativo**
|
|
|
|
L'estensione consente un binario nativo che può **accedere alla macchina host con i privilegi completi dell'utente**. Il binario nativo interagisce con il core dell'estensione tramite l'interfaccia di programmazione delle applicazioni del plugin Netscape standard ([NPAPI](https://en.wikipedia.org/wiki/NPAPI)) utilizzata da Flash e altri plugin del browser.
|
|
|
|
### Limiti
|
|
|
|
{% hint style="danger" %}
|
|
Per ottenere i privilegi completi dell'utente, un attaccante deve convincere l'estensione a passare input dannosi dallo script di contenuto al core dell'estensione e dal core dell'estensione al binario nativo.
|
|
{% endhint %}
|
|
|
|
Ogni componente dell'estensione è separato dagli altri da **forti limiti di protezione**. Ogni componente viene eseguito in un **processo separato del sistema operativo**. Gli script di contenuto e i core dell'estensione vengono eseguiti in **processi sandbox** non disponibili per la maggior parte dei servizi del sistema operativo.
|
|
|
|
Inoltre, gli script di contenuto sono separati dalle loro pagine web associate **eseguendosi in un heap JavaScript separato**. Lo script di contenuto e la pagina web hanno **accesso allo stesso DOM sottostante**, ma i due **non scambiano mai puntatori JavaScript**, impedendo la divulgazione della funzionalità JavaScript.
|
|
|
|
## **`manifest.json`**
|
|
|
|
Un'estensione di Chrome è semplicemente una cartella ZIP con un'estensione di file [.crx](https://www.lifewire.com/crx-file-2620391). Il core dell'estensione è il file **`manifest.json`** nella radice della cartella, che specifica il layout, le autorizzazioni e altre opzioni di configurazione.
|
|
|
|
Esempio:
|
|
```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`
|
|
|
|
I content scripts vengono **caricati** ogni volta che l'utente **naviga su una pagina corrispondente**, nel nostro caso qualsiasi pagina che corrisponda all'espressione **`https://example.com/*`** e non corrisponda alla regex **`*://*/*/business*`**. Essi vengono eseguiti **come gli script della pagina stessa** e hanno accesso arbitrario al [Document Object Model (DOM)](https://developer.mozilla.org/en-US/docs/Web/API/Document\_Object\_Model) della pagina.
|
|
```json
|
|
"content_scripts": [
|
|
{
|
|
"js": [
|
|
"script.js"
|
|
],
|
|
"matches": [
|
|
"https://example.com/*",
|
|
"https://www.example.com/*"
|
|
],
|
|
"exclude_matches": ["*://*/*business*"],
|
|
}
|
|
],
|
|
```
|
|
Per includere o escludere ulteriori URL, è possibile utilizzare anche **`include_globs`** e **`exclude_globs`**.
|
|
|
|
Questo è un esempio di script di contenuto che aggiungerà un pulsante di spiegazione alla pagina quando [l'API di archiviazione](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage) viene utilizzata per recuperare il valore `message` dalla memoria dell'estensione.
|
|
```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 (7).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
Quando viene cliccato questo pulsante, viene inviato un messaggio alle pagine dell'estensione tramite l'utilizzo dell'API [**runtime.sendMessage()**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage). Ciò è dovuto alla limitazione dello script di contenuto nell'accesso diretto alle API, con `storage` tra le poche eccezioni. Per funzionalità al di là di queste eccezioni, vengono inviati messaggi alle pagine dell'estensione con cui gli script di contenuto possono comunicare.
|
|
|
|
{% hint style="warning" %}
|
|
A seconda del browser, le capacità dello script di contenuto possono variare leggermente. Per i browser basati su Chromium, l'elenco delle capacità è disponibile nella documentazione degli [sviluppatori di Chrome](https://developer.chrome.com/docs/extensions/mv3/content_scripts/#capabilities), e per Firefox, [MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#webextension_apis) è la fonte primaria.\
|
|
È anche importante notare che gli script di contenuto hanno la capacità di comunicare con gli script di background, consentendo loro di eseguire azioni e trasmettere risposte.
|
|
{% endhint %}
|
|
|
|
Per visualizzare e debuggare gli script di contenuto in Chrome, è possibile accedere al menu degli strumenti per sviluppatori di Chrome da Opzioni > Altri strumenti > Strumenti per sviluppatori O premendo Ctrl + Shift + I.
|
|
|
|
Una volta visualizzati gli strumenti per sviluppatori, fare clic sulla scheda **Sorgente**, seguita dalla scheda **Script di contenuto**. Ciò consente di osservare gli script di contenuto in esecuzione da varie estensioni e impostare punti di interruzione per tracciare il flusso di esecuzione.
|
|
|
|
### Script di contenuto iniettati
|
|
|
|
{% hint style="success" %}
|
|
Si noti che **gli script di contenuto non sono obbligatori** poiché è anche possibile **iniettare script in modo dinamico** e **iniettarli programmaticamente** nelle pagine web tramite **`tabs.executeScript`**. Ciò fornisce effettivamente un controllo più **granulare**.
|
|
{% endhint %}
|
|
|
|
Per l'iniezione programmatica di uno script di contenuto, è necessario che l'estensione abbia [permessi di host](https://developer.chrome.com/docs/extensions/reference/permissions) per la pagina in cui gli script devono essere iniettati. Questi permessi possono essere ottenuti sia **richiedendoli** all'interno del manifesto dell'estensione che su base temporanea tramite [**activeTab**](https://developer.chrome.com/docs/extensions/reference/manifest/activeTab).
|
|
|
|
#### Esempio di estensione basata su activeTab
|
|
|
|
{% code title="manifest.json" %}
|
|
```json
|
|
{
|
|
"name": "My extension",
|
|
...
|
|
"permissions": [
|
|
"activeTab",
|
|
"scripting"
|
|
],
|
|
"background": {
|
|
"service_worker": "background.js"
|
|
},
|
|
"action": {
|
|
"default_title": "Action Button"
|
|
}
|
|
}
|
|
```
|
|
{% endcode %}
|
|
|
|
* **Iniettare un file JS al clic:**
|
|
```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"]
|
|
});
|
|
});
|
|
```
|
|
* **Iniettare una funzione** al click:
|
|
```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,
|
|
});
|
|
});
|
|
```
|
|
#### Esempio con le autorizzazioni di scripting
|
|
|
|
In questo esempio, esploreremo come sfruttare le autorizzazioni di scripting di un'estensione del browser per eseguire codice malevolo sul sistema target.
|
|
|
|
1. **Analisi dell'estensione**: Iniziamo analizzando l'estensione del browser per identificare le autorizzazioni di scripting che sono state concesse. Possiamo farlo esaminando il file `manifest.json` dell'estensione. Cerchiamo le chiavi come `content_scripts` o `background_scripts` per determinare quali script possono essere eseguiti.
|
|
|
|
2. **Identificazione delle vulnerabilità**: Una volta identificate le autorizzazioni di scripting, dobbiamo cercare vulnerabilità che potrebbero consentirci di eseguire codice malevolo. Possibili vulnerabilità includono l'iniezione di script, la mancanza di validazione degli input o la presenza di funzioni pericolose.
|
|
|
|
3. **Sfruttamento delle vulnerabilità**: Una volta identificata una vulnerabilità, sfruttiamola per eseguire il nostro codice malevolo. Possiamo farlo iniettando script dannosi in pagine web specifiche o sfruttando funzioni vulnerabili per ottenere l'esecuzione del nostro codice.
|
|
|
|
4. **Esecuzione del codice malevolo**: Una volta che siamo riusciti a eseguire il nostro codice malevolo, possiamo sfruttarlo per compiere azioni dannose sul sistema target. Questo potrebbe includere il furto di dati sensibili, l'installazione di malware aggiuntivo o il controllo remoto del sistema.
|
|
|
|
È importante notare che l'esecuzione di codice malevolo tramite le autorizzazioni di scripting di un'estensione del browser è un'attività illegale e non autorizzata. Questo esempio è fornito solo a scopo educativo per comprendere le potenziali vulnerabilità e le misure di sicurezza necessarie per proteggere le estensioni del browser.
|
|
```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" });
|
|
```
|
|
Per includere o escludere ulteriori URL è possibile utilizzare anche **`include_globs`** e **`exclude_globs`**.
|
|
|
|
### Script di contenuto `run_at`
|
|
|
|
Il campo `run_at` controlla **quando i file JavaScript vengono iniettati nella pagina web**. Il valore preferito e predefinito è `"document_idle"`.
|
|
|
|
I possibili valori sono:
|
|
|
|
* **`document_idle`**: Quando possibile
|
|
* **`document_start`**: Dopo eventuali file da `css`, ma prima che venga costruito qualsiasi altro DOM o eseguito qualsiasi altro script.
|
|
* **`document_end`**: Immediatamente dopo il completamento del DOM, ma prima che vengano caricati i sottorisorse come immagini e frame.
|
|
|
|
#### Attraverso `manifest.json`
|
|
```json
|
|
{
|
|
"name": "My extension",
|
|
...
|
|
"content_scripts": [
|
|
{
|
|
"matches": ["https://*.example.com/*"],
|
|
"run_at": "document_idle",
|
|
"js": ["contentScript.js"]
|
|
}
|
|
],
|
|
...
|
|
}
|
|
|
|
```
|
|
Attraverso **`service-worker.js`**
|
|
```javascript
|
|
chrome.scripting.registerContentScripts([{
|
|
id : "test",
|
|
matches : [ "https://*.example.com/*" ],
|
|
runAt : "document_idle",
|
|
js : [ "contentScript.js" ],
|
|
}]);
|
|
```
|
|
### `background`
|
|
|
|
I messaggi inviati dagli script di contenuto vengono ricevuti dalla **pagina di background**, che svolge un ruolo centrale nel coordinare i componenti dell'estensione. In particolare, la pagina di background persiste durante l'intera durata dell'estensione, operando in modo discreto senza interazione diretta dell'utente. Possiede il proprio Document Object Model (DOM), che consente interazioni complesse e gestione dello stato.
|
|
|
|
**Punti chiave**:
|
|
|
|
- **Ruolo della pagina di background:** Agisce come centro nervoso dell'estensione, garantendo la comunicazione e il coordinamento tra le varie parti dell'estensione.
|
|
- **Persistenza:** È un'entità sempre presente, invisibile all'utente ma fondamentale per la funzionalità dell'estensione.
|
|
- **Generazione automatica:** Se non viene esplicitamente definita, il browser creerà automaticamente una pagina di background. Questa pagina generata automaticamente includerà tutti gli script di background specificati nel manifesto dell'estensione, garantendo il corretto funzionamento dei compiti di background dell'estensione.
|
|
|
|
{% hint style="success" %}
|
|
La comodità fornita dal browser nella generazione automatica di una pagina di background (quando non dichiarata esplicitamente) garantisce l'integrazione e il funzionamento di tutti gli script di background necessari, semplificando il processo di configurazione dell'estensione.
|
|
{% endhint %}
|
|
|
|
Esempio di script di background:
|
|
```js
|
|
chrome.runtime.onMessage.addListener((request, sender, sendResponse) =>
|
|
{
|
|
if (request == "explain")
|
|
{
|
|
chrome.tabs.create({ url: "https://example.net/explanation" });
|
|
}
|
|
})
|
|
```
|
|
Utilizza l'API [runtime.onMessage](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage) per ascoltare i messaggi. Quando viene ricevuto un messaggio "explain", utilizza l'API [tabs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs) per aprire una pagina in una nuova scheda.
|
|
|
|
Per eseguire il debug dello script di background, è possibile andare ai **dettagli dell'estensione e ispezionare il service worker**, ciò aprirà gli strumenti per sviluppatori con lo script di background:
|
|
|
|
<figure><img src="broken-reference" alt=""><figcaption></figcaption></figure>
|
|
|
|
### Pagine delle opzioni e altre
|
|
|
|
Le estensioni del browser possono contenere vari tipi di pagine:
|
|
|
|
* **Pagine di azione** vengono visualizzate in un **menu a discesa quando si fa clic sull'icona** dell'estensione.
|
|
* Pagine che l'estensione **caricherà in una nuova scheda**.
|
|
* **Pagine delle opzioni**: questa pagina viene visualizzata sopra l'estensione quando viene cliccata. Nel manifesto precedente, sono riuscito ad accedere a questa pagina in `chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca` o facendo clic su:
|
|
|
|
<figure><img src="../../.gitbook/assets/image (8).png" alt="" width="375"><figcaption></figcaption></figure>
|
|
|
|
Si noti che queste pagine non sono persistenti come le pagine di background in quanto caricano dinamicamente il contenuto solo quando necessario. Nonostante ciò, condividono alcune funzionalità con la pagina di background:
|
|
|
|
- **Comunicazione con gli script di contenuto:** Similmente alla pagina di background, queste pagine possono ricevere messaggi dagli script di contenuto, facilitando l'interazione all'interno dell'estensione.
|
|
- **Accesso alle API specifiche dell'estensione:** Queste pagine hanno un accesso completo alle API specifiche dell'estensione, soggette alle autorizzazioni definite per l'estensione.
|
|
|
|
### `permissions` e `host_permissions`
|
|
|
|
**`permissions`** e **`host_permissions`** sono voci presenti nel file `manifest.json` che indicano **quali autorizzazioni** ha l'estensione del browser (archiviazione, posizione...) e in **quali pagine web**.
|
|
|
|
Poiché le estensioni del browser possono essere così **privilegiate**, una estensione maligna o compromessa potrebbe consentire all'attaccante **diversi mezzi per rubare informazioni sensibili e spiare l'utente**.
|
|
|
|
Verifica come funzionano queste impostazioni e come potrebbero essere sfruttate in:
|
|
|
|
{% 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`
|
|
|
|
Una **content security policy** può essere dichiarata anche all'interno del file `manifest.json`. Se ne è definita una, potrebbe essere **vulnerabile**.
|
|
|
|
L'impostazione predefinita per le pagine delle estensioni del browser è piuttosto restrittiva:
|
|
```bash
|
|
script-src 'self'; object-src 'self';
|
|
```
|
|
Per ulteriori informazioni su CSP e potenziali bypass, controlla:
|
|
|
|
{% content-ref url="../content-security-policy-csp-bypass/" %}
|
|
[content-security-policy-csp-bypass](../content-security-policy-csp-bypass/)
|
|
{% endcontent-ref %}
|
|
|
|
### `web_accessible_resources`
|
|
|
|
affinché una pagina web possa accedere a una pagina di un'estensione del browser, ad esempio un file `.html`, questa pagina deve essere menzionata nel campo **`web_accessible_resources`** del file `manifest.json`.\
|
|
Ad esempio:
|
|
```javascript
|
|
{
|
|
...
|
|
"web_accessible_resources": [
|
|
{
|
|
"resources": [ "images/*.png" ],
|
|
"matches": [ "https://example.com/*" ]
|
|
},
|
|
{
|
|
"resources": [ "fonts/*.woff" ],
|
|
"matches": [ "https://example.com/*" ]
|
|
}
|
|
],
|
|
...
|
|
}
|
|
```
|
|
Queste pagine sono accessibili tramite URL come:
|
|
```
|
|
chrome-extension://<extension-id>/message.html
|
|
```
|
|
Nelle estensioni pubbliche l'**ID dell'estensione è accessibile**:
|
|
|
|
<figure><img src="../../.gitbook/assets/image (722).png" alt="" width="375"><figcaption></figcaption></figure>
|
|
|
|
Tuttavia, se viene utilizzato il parametro `use_dynamic_url` nel file `manifest.json`, questo **ID può essere dinamico**.
|
|
|
|
Avere accesso a queste pagine rende queste pagine **potenzialmente vulnerabili al ClickJacking**:
|
|
|
|
{% content-ref url="browext-clickjacking.md" %}
|
|
[browext-clickjacking.md](browext-clickjacking.md)
|
|
{% endcontent-ref %}
|
|
|
|
{% hint style="success" %}
|
|
Consentire il caricamento di queste pagine solo dall'estensione e non da URL casuali potrebbe prevenire attacchi di ClickJacking.
|
|
{% endhint %}
|
|
|
|
### `externally_connectable`
|
|
|
|
Secondo la [**documentazione**](https://developer.chrome.com/docs/extensions/reference/manifest/externally-connectable), la proprietà del manifesto `"externally_connectable"` dichiara **quali estensioni e pagine web possono connettersi** alla tua estensione tramite [runtime.connect](https://developer.chrome.com/docs/extensions/reference/runtime#method-connect) e [runtime.sendMessage](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage).
|
|
|
|
* Se la chiave **`externally_connectable`** non è dichiarata nel manifesto dell'estensione o è dichiarata come **`"ids": ["*"]`**, **tutte le estensioni possono connettersi, ma nessuna pagina web può connettersi**.
|
|
* Se vengono specificati **ID specifici**, come in `"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]`, **solo quelle applicazioni** possono connettersi.
|
|
* Se vengono specificati **corrispondenze**, quelle web app saranno in grado di connettersi:
|
|
```json
|
|
"matches": [
|
|
"https://*.google.com/*",
|
|
"*://*.chromium.org/*",
|
|
```
|
|
* Se viene specificato come vuoto: **`"externally_connectable": {}`**, nessuna app o web sarà in grado di connettersi.
|
|
|
|
Più estensioni e URL vengono indicati qui, più piccola sarà la superficie di attacco.
|
|
|
|
{% hint style="danger" %}
|
|
Se una pagina web vulnerabile a XSS o takeover viene indicata in **`externally_connectable`**, un attaccante sarà in grado di inviare messaggi direttamente allo script di background, bypassando completamente lo script di contenuto e la sua CSP.
|
|
|
|
Pertanto, questo è un bypass molto potente.
|
|
{% endhint %}
|
|
|
|
## Comunicazione Web **↔︎** Content Script
|
|
|
|
Gli ambienti in cui operano gli **script di contenuto** e in cui esistono le pagine ospitanti sono **separati** l'uno dall'altro, garantendo **isolamento**. Nonostante questo isolamento, entrambi hanno la capacità di interagire con il **Document Object Model (DOM)** della pagina, una risorsa condivisa. Per consentire alla pagina ospitante di comunicare con lo **script di contenuto**, o indirettamente con l'estensione tramite lo script di contenuto, è necessario utilizzare il **DOM** accessibile da entrambe le parti come canale di comunicazione.
|
|
|
|
### Messaggi Post
|
|
```javascript
|
|
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);
|
|
```
|
|
{% code title="esempio.js" %}
|
|
```javascript
|
|
document.getElementById("theButton").addEventListener("click", () => {
|
|
window.postMessage(
|
|
{type : "FROM_PAGE", text : "Hello from the webpage!"}, "*");
|
|
}, false);
|
|
```
|
|
{% endcode %}
|
|
|
|
Una comunicazione sicura tramite Post Message dovrebbe verificare l'autenticità del messaggio ricevuto, ciò può essere fatto controllando:
|
|
|
|
* **`event.isTrusted`**: Questo è vero solo se l'evento è stato scatenato da un'azione dell'utente
|
|
* Lo script di contenuto potrebbe aspettarsi un messaggio solo se l'utente compie qualche azione
|
|
* **Dominio di origine**: potrebbe aspettarsi un messaggio solo da una lista di domini consentiti.
|
|
* Se viene utilizzata una regex, fare molta attenzione
|
|
* **Sorgente**: `received_message.source !== window` può essere utilizzato per verificare se il messaggio proveniva dalla **stessa finestra** in cui lo script di contenuto sta ascoltando.
|
|
|
|
I controlli precedenti, anche se eseguiti, potrebbero essere vulnerabili, quindi controllare nella pagina seguente **possibili bypass di Post Message**:
|
|
|
|
{% content-ref url="../postmessage-vulnerabilities/" %}
|
|
[postmessage-vulnerabilities](../postmessage-vulnerabilities/)
|
|
{% endcontent-ref %}
|
|
|
|
### Iframe
|
|
|
|
Un altro possibile modo di comunicazione potrebbe essere tramite **URL Iframe**, puoi trovare un esempio in:
|
|
|
|
{% content-ref url="browext-xss-example.md" %}
|
|
[browext-xss-example.md](browext-xss-example.md)
|
|
{% endcontent-ref %}
|
|
|
|
### DOM
|
|
|
|
Questo non è "esattamente" un modo di comunicazione, ma il **web e lo script di contenuto avranno accesso al DOM web**. Quindi, se lo **script di contenuto** sta leggendo alcune informazioni da esso, **fidandosi del DOM web**, il web potrebbe **modificare questi dati** (perché il web non dovrebbe essere fidato, o perché il web è vulnerabile a XSS) e **compromettere lo script di contenuto**.
|
|
|
|
Puoi trovare anche un esempio di **DOM based XSS per compromettere un'estensione del browser** in:
|
|
|
|
{% content-ref url="browext-xss-example.md" %}
|
|
[browext-xss-example.md](browext-xss-example.md)
|
|
{% endcontent-ref %}
|
|
|
|
## Informazioni Sensibili in Memoria/Codice
|
|
|
|
Se un'estensione del browser memorizza **informazioni sensibili nella sua memoria**, queste potrebbero essere **estratte** (soprattutto su macchine Windows) e **ricercate** per queste informazioni.
|
|
|
|
Pertanto, la memoria dell'estensione del browser **non dovrebbe essere considerata sicura** e **informazioni sensibili** come credenziali o frasi mnemoniche **non dovrebbero essere memorizzate**.
|
|
|
|
Naturalmente, **non inserire informazioni sensibili nel codice**, poiché saranno **pubbliche**.
|
|
|
|
## Comunicazione tra Content Script **↔︎** Background Script
|
|
|
|
Uno script di contenuto può utilizzare le funzioni [**runtime.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage) **o** [**tabs.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/tabs#method-sendMessage) per inviare un messaggio **serializzabile in JSON** una sola volta.
|
|
|
|
Per gestire la **risposta**, utilizzare la **Promise** restituita. Tuttavia, per la compatibilità all'indietro, è ancora possibile passare una **callback** come ultimo argomento.
|
|
|
|
L'invio di una richiesta da uno **script di contenuto** appare così:
|
|
```javascript
|
|
(async () => {
|
|
const response = await chrome.runtime.sendMessage({greeting: "hello"});
|
|
// do something with response here, not outside the function
|
|
console.log(response);
|
|
})();
|
|
```
|
|
Inviare una richiesta dall'**estensione** (di solito uno **script di background**). Uno script di contenuto può utilizzare le funzioni, tranne che è necessario specificare a quale scheda inviarlo. Esempio di come inviare un messaggio allo script di contenuto nella scheda selezionata:
|
|
```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);
|
|
})();
|
|
```
|
|
Sul **lato ricevente**, è necessario configurare un [**runtime.onMessage**](https://developer.chrome.com/docs/extensions/reference/runtime#event-onMessage) **ascoltatore di eventi** per gestire il messaggio. Questo aspetto è identico sia per uno script di contenuto che per una pagina di estensione.
|
|
```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"});
|
|
}
|
|
);
|
|
```
|
|
Nell'esempio evidenziato, **`sendResponse()`** è stato eseguito in modo sincrono. Per modificare l'handler dell'evento `onMessage` in modo asincrono per l'esecuzione di `sendResponse()`, è imperativo incorporare `return true;`.
|
|
|
|
Una considerazione importante è che in scenari in cui più pagine sono impostate per ricevere eventi `onMessage`, **la prima pagina a eseguire `sendResponse()`** per un evento specifico sarà l'unica in grado di consegnare efficacemente la risposta. Eventuali risposte successive allo stesso evento non verranno prese in considerazione.
|
|
|
|
Nella creazione di nuove estensioni, la preferenza dovrebbe essere data alle promesse anziché ai callback. Per quanto riguarda l'uso dei callback, la funzione `sendResponse()` è considerata valida solo se viene eseguita direttamente nel contesto sincrono, o se l'handler dell'evento indica un'operazione asincrona restituendo `true`. Se nessuno degli handler restituisce `true` o se la funzione `sendResponse()` viene rimossa dalla memoria (garbage-collected), il callback associato alla funzione `sendMessage()` verrà attivato per impostazione predefinita.
|
|
|
|
|
|
## Caricamento di un'estensione nel browser
|
|
|
|
1. **Scarica** l'estensione del browser e scompattala
|
|
2. Vai a **`chrome://extensions/`** e **abilita** la modalità sviluppatore
|
|
3. Fai clic sul pulsante **`Carica estensione non pacchettizzata`**
|
|
|
|
In **Firefox** vai a **`about:debugging#/runtime/this-firefox`** e fai clic sul pulsante **`Carica estensione temporanea`**.
|
|
|
|
## Ottenere il codice sorgente dallo store
|
|
|
|
Il codice sorgente di un'estensione Chrome può essere ottenuto tramite vari metodi. Di seguito sono fornite spiegazioni dettagliate e istruzioni per ciascuna opzione.
|
|
|
|
### Scarica l'estensione come file ZIP tramite la riga di comando
|
|
|
|
Il codice sorgente di un'estensione Chrome può essere scaricato come file ZIP utilizzando la riga di comando. Ciò comporta l'utilizzo di `curl` per recuperare il file ZIP da un URL specifico e quindi estrarre i contenuti del file ZIP in una directory. Ecco i passaggi da seguire:
|
|
|
|
1. Sostituisci `"extension_id"` con l'effettivo ID dell'estensione.
|
|
2. Esegui i seguenti comandi:
|
|
```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"
|
|
```
|
|
### Utilizzare il sito web CRX Viewer
|
|
|
|
[https://robwu.nl/crxviewer/](https://robwu.nl/crxviewer/)
|
|
|
|
### Utilizzare l'estensione CRX Viewer
|
|
|
|
Un altro metodo conveniente è utilizzare l'estensione Chrome Extension Source Viewer, che è un progetto open-source. Può essere installato dal [Chrome Web Store](https://chrome.google.com/webstore/detail/chrome-extension-source-v/jifpbeccnghkjeaalbbjmodiffmgedin?hl=en). Il codice sorgente del visualizzatore è disponibile nel suo [repository GitHub](https://github.com/Rob--W/crxviewer).
|
|
|
|
### Visualizzare il codice sorgente dell'estensione installata localmente
|
|
|
|
Le estensioni di Chrome installate localmente possono anche essere ispezionate. Ecco come:
|
|
|
|
1. Accedi alla directory del profilo locale di Chrome visitando `chrome://version/` e individuando il campo "Percorso del profilo".
|
|
2. Naviga nella sottocartella `Extensions/` all'interno della directory del profilo.
|
|
3. Questa cartella contiene tutte le estensioni installate, di solito con il loro codice sorgente in un formato leggibile.
|
|
|
|
Per identificare le estensioni, puoi mappare i loro ID ai nomi:
|
|
|
|
- Abilita la modalità sviluppatore nella pagina `about:extensions` per vedere gli ID di ogni estensione.
|
|
- All'interno della cartella di ogni estensione, il file `manifest.json` contiene un campo `name` leggibile, che ti aiuta a identificare l'estensione.
|
|
|
|
### Utilizzare un archiviatore o un decompressore di file
|
|
Vai al Chrome Web Store e scarica l'estensione. Il file avrà l'estensione `.crx`.
|
|
Cambia l'estensione del file da `.crx` a `.zip`.
|
|
Utilizza qualsiasi archiviatore di file (come WinRAR, 7-Zip, ecc.) per estrarre i contenuti del file ZIP.
|
|
|
|
### Utilizzare la modalità sviluppatore in Chrome
|
|
Apri Chrome e vai a `chrome://extensions/`.
|
|
Abilita la "Modalità sviluppatore" in alto a destra.
|
|
Fai clic su "Carica estensione non pacchettizzata...".
|
|
Passa alla directory della tua estensione.
|
|
Questo non scarica il codice sorgente, ma è utile per visualizzare e modificare il codice di un'estensione già scaricata o sviluppata.
|
|
|
|
## Checklist di audit di sicurezza
|
|
|
|
Anche se le estensioni del browser hanno una **superficie di attacco limitata**, alcune di esse potrebbero contenere **vulnerabilità** o **miglioramenti potenziali della sicurezza**. Ecco le più comuni:
|
|
|
|
* [ ] **Limitare** il più possibile le **`permissions`** richieste
|
|
* [ ] **Limitare** il più possibile le **`host_permissions`**
|
|
* [ ] Utilizzare una **`content_security_policy`** **forte**
|
|
* [ ] **Limitare** il più possibile le **`externally_connectable`**, se non è necessario e possibile, non lasciarle per impostazione predefinita, specificare **`{}`**
|
|
* [ ] Se viene menzionato un URL vulnerabile a XSS o a takeover, un attaccante sarà in grado di **inviare messaggi direttamente agli script di background**. Un bypass molto potente.
|
|
* [ ] **Limitare** il più possibile le **`web_accessible_resources`**, anche vuote se possibile.
|
|
* [ ] Se **`web_accessible_resources`** non è nullo, controllare [**ClickJacking**](browext-clickjacking.md)
|
|
* [ ] Se avviene una **comunicazione** dall'**estensione** alla **pagina web**, [**controllare le vulnerabilità XSS**](browext-xss-example.md) causate dalla comunicazione.
|
|
* [ ] Se vengono utilizzati i messaggi di posta, controllare le [**vulnerabilità dei messaggi di posta**](../postmessage-vulnerabilities/)**.**
|
|
* [ ] Se lo **Script di contenuto accede ai dettagli del DOM**, controllare che non stiano introducendo un XSS se vengono **modificati** dalla pagina web
|
|
* [ ] Fare particolare attenzione se questa comunicazione è coinvolta anche nella **comunicazione dello Script di contenuto -> Script di background**
|
|
* [ ] Le **informazioni sensibili non dovrebbero essere memorizzate** all'interno del codice dell'estensione del browser
|
|
* [ ] Le **informazioni sensibili non dovrebbero essere memorizzate** nella memoria dell'estensione del browser
|
|
|
|
## Strumenti
|
|
|
|
### [**Tarnish**](https://thehackerblog.com/tarnish/)
|
|
|
|
* Estrae qualsiasi estensione Chrome da un link fornito dal Chrome Web Store.
|
|
* Visualizzatore di [**manifest.json**](https://developer.chrome.com/extensions/manifest): visualizza semplicemente una versione JSON formattata del manifesto dell'estensione.
|
|
* Analisi delle impronte digitali: rilevamento delle [web\_accessible\_resources](https://developer.chrome.com/extensions/manifest/web\_accessible\_resources) e generazione automatica di JavaScript per l'impronta digitale dell'estensione Chrome.
|
|
* Analisi potenziale del Clickjacking: rilevamento delle pagine HTML dell'estensione con la direttiva [web\_accessible\_resources](https://developer.chrome.com/extensions/manifest/web\_accessible\_resources) impostata. Queste sono potenzialmente vulnerabili al clickjacking a seconda dello scopo delle pagine.
|
|
* Visualizzatore di avvisi di autorizzazioni: mostra un elenco di tutti gli avvisi di autorizzazione di Chrome che verranno visualizzati quando un utente tenta di installare l'estensione.
|
|
* Funzioni pericolose: mostra la posizione delle funzioni pericolose che potrebbero essere sfruttate da un attaccante (ad esempio, funzioni come innerHTML, chrome.tabs.executeScript).
|
|
* Punti di ingresso: mostra dove l'estensione accetta input dall'utente/esterno. Questo è utile per comprendere l'area di superficie di un'estensione e cercare potenziali punti per inviare dati malevoli all'estensione.
|
|
* Sia gli scanner di Funzioni pericolose che di Punti di ingresso hanno quanto segue per gli avvisi generati:
|
|
* Frammento di codice rilevante e riga che ha causato l'avviso.
|
|
* Descrizione del problema.
|
|
* Un pulsante "Visualizza file" per visualizzare il file sorgente completo contenente il codice.
|
|
* Il percorso del file segnalato.
|
|
* L'URI completo dell'estensione Chrome del file segnalato.
|
|
* Il tipo di file, ad esempio uno script di pagina di background, uno script di contenuto, un'azione del browser, ecc.
|
|
* Se la riga vulnerabile si trova in un file JavaScript, i percorsi di tutte le pagine in cui è inclusa, nonché il tipo di queste pagine e lo stato di [web\_accessible\_resource](https://developer.chrome.com/extensions/manifest/web\_accessible\_resources).
|
|
* Analizzatore e verificatore di Content Security Policy (CSP): evidenzia le debolezze del CSP dell'estensione e illumina anche eventuali modi per eludere il CSP a causa di CDN in whitelist, ecc.
|
|
* Librerie vulnerabili conosciute: utilizza [Retire.js](https://retirejs.github.io/retire.js/) per verificare l'uso di librerie JavaScript conosciute come vulnerabili.
|
|
* Scarica l'estensione e le versioni formattate.
|
|
* Scarica l'estensione originale.
|
|
* Scarica una versione formattata dell'estensione (HTML e JavaScript automaticamente formattati).
|
|
* Caching automatico dei risultati della scansione, eseguire una scansione dell'estensione richiederà molto tempo la prima volta che viene eseguita. Tuttavia, la seconda volta, a meno che l'estensione non sia stata aggiornata, sarà quasi istantanea grazie ai risultati memorizzati nella cache.
|
|
* URL di report collegabili, è possibile collegare facilmente a qualcun altro un report sull'estensione generato da tarnish.
|
|
|
|
### [Neto](https://github.com/elevenpaths/neto)
|
|
|
|
Il progetto Neto è un pacchetto Python 3 concepito per analizzare e svelare funzionalità nascoste di plugin ed estensioni del browser
|
|
* Se vuoi vedere la tua **azienda pubblicizzata in HackTricks** o **scaricare HackTricks in PDF** Controlla i [**PIANI DI ABBONAMENTO**](https://github.com/sponsors/carlospolop)!
|
|
* Ottieni il [**merchandising ufficiale di PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Scopri [**La Famiglia PEASS**](https://opensea.io/collection/the-peass-family), la nostra collezione di [**NFT esclusivi**](https://opensea.io/collection/the-peass-family)
|
|
* **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
* **Condividi i tuoi trucchi di hacking inviando PR ai repository di** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) su github.
|
|
|
|
</details>
|