708 lines
41 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Методологија Пентестинга Додатака за Прегледаче
{{#include ../../banners/hacktricks-training.md}}
## Основне Информације
Додаци за прегледаче су написани у JavaScript-у и учитава их прегледач у позадини. Има свој [DOM](https://www.w3schools.com/js/js_htmldom.asp) али може да интерагује са DOM-овима других сајтова. То значи да може угрожавати повјерљивост, интегритет и доступност (CIA) других сајтова.
## Главне Компоненте
Изгледи додатака изгледају најбоље када су визуализовани и састоје се од три компоненте. Погледајмо сваку компоненту детаљно.
<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>
### **Скрипте Садржаја**
Свака скрипта садржаја има директан приступ DOM-у **једне веб странице** и тиме је изложена **потенцијално злонамерном улазу**. Међутим, скрипта садржаја не садржи дозволе осим способности да шаље поруке основи додатка.
### **Основна Структура Додатка**
Основна структура додатка садржи већину привилегија/приступа додатка, али основна структура додатка може да интерагује са веб садржајем само преко [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) и скрипти садржаја. Такође, основна структура додатка нема директан приступ хост машини.
### **Нативна Бинарна**
Додаци омогућавају нативну бинарну датотеку која може **приступити хост машини са пуном привилегијом корисника.** Нативна бинарна интерагује са основном структуром додатка преко стандардног Netscape Plugin Application Programming Interface ([NPAPI](https://en.wikipedia.org/wiki/NPAPI)) који користе Flash и други додаци за прегледаче.
### Границе
> [!CAUTION]
> Да би добио пуне привилегије корисника, нападач мора убедити додатак да проследи злонамерни улаз из скрипте садржаја у основну структуру додатка и из основне структуре додатка у нативну бинарну.
Свака компонента додатка је одвојена од других **јаким заштитним границама**. Свака компонента ради у **одвојеном процесу оперативног система**. Скрипте садржаја и основне структуре додатка раде у **sandbox процесима** недоступним већини услуга оперативног система.
Штавише, скрипте садржаја су одвојене од својих повезаних веб страница **извођењем у одвојеном JavaScript хипу**. Скрипта садржаја и веб страница имају **приступ истом основном DOM-u**, али се двоје **никада не размењују JavaScript показиваче**, спречавајући цурење JavaScript функционалности.
## **`manifest.json`**
Chrome додатак је само ZIP фасцикла са [.crx екстензијом датотеке](https://www.lifewire.com/crx-file-2620391). Основна структура додатка је **`manifest.json`** датотека у корену фасцикле, која спецификује изглед, дозволе и друге опције конфигурације.
Пример:
```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`
Skripte sadržaja se **učitavaju** svaki put kada korisnik **navigira na odgovarajuću stranicu**, u našem slučaju bilo koja stranica koja odgovara **`https://example.com/*`** izrazu i ne odgovara **`*://*/*/business*`** regex-u. Izvršavaju se **poput skripti same stranice** i imaju proizvoljan pristup [Modelu objekta dokumenta (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*"],
}
],
```
Da bi se uključilo ili isključilo više URL-ova, takođe je moguće koristiti **`include_globs`** i **`exclude_globs`**.
Ovo je primer sadržajnog skripta koji će dodati dugme za objašnjenje na stranicu kada [storage API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage) preuzme `message` vrednost iz skladišta ekstenzije.
```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>
Poruka se šalje na stranice ekstenzije putem sadržajnog skripta kada se pritisne ovaj dugme, korišćenjem [**runtime.sendMessage() API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage). To je zbog ograničenja sadržajnog skripta u direktnom pristupu API-ima, pri čemu je `storage` jedan od retkih izuzetaka. Za funkcionalnosti izvan ovih izuzetaka, poruke se šalju na stranice ekstenzije sa kojima sadržajni skripti mogu komunicirati.
> [!WARNING]
> U zavisnosti od pretraživača, mogućnosti sadržajnog skripta mogu se malo razlikovati. Za pretraživače zasnovane na Chromium-u, lista mogućnosti je dostupna u [Chrome Developers dokumentaciji](https://developer.chrome.com/docs/extensions/mv3/content_scripts/#capabilities), a za Firefox, [MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#webextension_apis) služi kao primarni izvor.\
> Takođe je važno napomenuti da sadržajni skripti imaju mogućnost komunikacije sa pozadinskim skriptima, omogućavajući im da izvršavaju radnje i vraćaju odgovore.
Za pregledanje i debagovanje sadržajnih skripti u Chrome-u, meni alata za programere može se pristupiti iz Opcije > Više alata > Alati za programere ili pritiskom na Ctrl + Shift + I.
Kada se prikažu alati za programere, treba kliknuti na **Source tab**, a zatim na **Content Scripts** tab. Ovo omogućava posmatranje aktivnih sadržajnih skripti iz različitih ekstenzija i postavljanje tačaka prekida za praćenje toka izvršenja.
### Umetnuti sadržajni skripti
> [!TIP]
> Imajte na umu da **Sadržajni skripti nisu obavezni** jer je takođe moguće **dinamički** **umetati** skripte i **programatski ih umetati** na web stranice putem **`tabs.executeScript`**. Ovo zapravo pruža više **granularnih kontrola**.
Za programatsko umetanje sadržajnog skripta, ekstenzija mora imati [host permissions](https://developer.chrome.com/docs/extensions/reference/permissions) za stranicu u koju se skripte umetnu. Ove dozvole mogu se obezbediti ili **zahtevom** unutar manifest-a ekstenzije ili privremeno putem [**activeTab**](https://developer.chrome.com/docs/extensions/reference/manifest/activeTab).
#### Primer ekstenzije zasnovane na activeTab
```json:manifest.json
{
"name": "My extension",
...
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Action Button"
}
}
```
- **Umetnite JS datoteku na klik:**
```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"],
})
})
```
- **Umetnite funkciju** na klik:
```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,
})
})
```
#### Primer sa dozvolama za skripting
```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" })
```
Da bi se uključilo ili isključilo više URL-ova, takođe je moguće koristiti **`include_globs`** i **`exclude_globs`**.
### Content Scripts `run_at`
Polje `run_at` kontroliše **kada se JavaScript datoteke ubacuju u veb stranicu**. Preferirana i podrazumevana vrednost je `"document_idle"`.
Moguće vrednosti su:
- **`document_idle`**: Kada god je to moguće
- **`document_start`**: Nakon bilo kojih datoteka iz `css`, ali pre nego što se konstruira bilo koji drugi DOM ili se pokrene bilo koji drugi skript.
- **`document_end`**: Odmah nakon što je DOM završen, ali pre nego što se učitaju podresursi poput slika i okvira.
#### Via `manifest.json`
```json
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["https://*.example.com/*"],
"run_at": "document_idle",
"js": ["contentScript.js"]
}
],
...
}
```
Putem **`service-worker.js`**
```javascript
chrome.scripting.registerContentScripts([
{
id: "test",
matches: ["https://*.example.com/*"],
runAt: "document_idle",
js: ["contentScript.js"],
},
])
```
### `background`
Poruke koje šalju sadržajni skripti primaju **background page**, koja ima centralnu ulogu u koordinaciji komponenti ekstenzije. Imajte na umu da background page opstaje tokom celog trajanja ekstenzije, delujući diskretno bez direktne interakcije korisnika. Ima svoj vlastiti Document Object Model (DOM), što omogućava složene interakcije i upravljanje stanjem.
**Ključne tačke**:
- **Uloga Background Page:** Deluje kao nervni centar za ekstenziju, obezbeđujući komunikaciju i koordinaciju među različitim delovima ekstenzije.
- **Persistencija:** To je uvek prisutna entitet, nevidljiva korisniku, ali integralna za funkcionalnost ekstenzije.
- **Automatska Generacija:** Ako nije eksplicitno definisana, pretraživač će automatski kreirati background page. Ova automatski generisana stranica će uključivati sve background skripte navedene u manifestu ekstenzije, obezbeđujući nesmetano funkcionisanje pozadinskih zadataka ekstenzije.
> [!TIP]
> Povoljnost koju pretraživač pruža automatskim generisanjem background page (kada nije eksplicitno deklarisana) osigurava da su sve potrebne background skripte integrisane i operativne, pojednostavljujući proces postavljanja ekstenzije.
Primer background skripte:
```js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request == "explain") {
chrome.tabs.create({ url: "https://example.net/explanation" })
}
})
```
Koristi [runtime.onMessage API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage) za slušanje poruka. Kada se primi poruka `"explain"`, koristi [tabs API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs) da otvori stranicu u novoj kartici.
Da biste debagovali pozadinski skript, možete otići na **detalje ekstenzije i inspektovati servisnog radnika,** što će otvoriti alate za programere sa pozadinskim skriptom:
<figure><img src="https://github.com/carlospolop/hacktricks/blob/master/pentesting-web/browser-extension-pentesting-methodology/broken-reference" alt=""><figcaption></figcaption></figure>
### Opcione stranice i druge
Ekstenzije pretraživača mogu sadržati različite vrste stranica:
- **Akcione stranice** se prikazuju u **ispod kada se klikne na ikonu ekstenzije**.
- Stranice koje će ekstenzija **učitati u novoj kartici**.
- **Opcione stranice**: Ova stranica se prikazuje na vrhu ekstenzije kada se klikne. U prethodnom manifestu, u mom slučaju, mogao sam da pristupim ovoj stranici na `chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca` ili klikom:
<figure><img src="../../images/image (24).png" alt="" width="375"><figcaption></figcaption></figure>
Napomena da ove stranice nisu trajne kao pozadinske stranice, jer dinamički učitavaju sadržaj po potrebi. I pored toga, dele određene mogućnosti sa pozadinskom stranicom:
- **Komunikacija sa sadržajnim skriptama:** Slično pozadinskoj stranici, ove stranice mogu primati poruke od sadržajnih skripti, olakšavajući interakciju unutar ekstenzije.
- **Pristup API-ima specifičnim za ekstenziju:** Ove stranice uživaju sveobuhvatan pristup API-ima specifičnim za ekstenziju, podložnim dozvolama definisanim za ekstenziju.
### `permissions` & `host_permissions`
**`permissions`** i **`host_permissions`** su unosi iz `manifest.json` koji će označiti **koje dozvole** ekstenzija pretraživača ima (storage, location...) i **na kojim web stranicama**.
Kako ekstenzije pretraživača mogu biti tako **privilegovane**, zlonamerna ili kompromitovana ekstenzija mogla bi omogućiti napadaču **različite načine za krađu osetljivih informacija i špijuniranje korisnika**.
Proverite kako ove postavke funkcionišu i kako bi mogle biti zloupotrebljene u:
{{#ref}}
browext-permissions-and-host_permissions.md
{{#endref}}
### `content_security_policy`
**Politika bezbednosti sadržaja** može se takođe deklarisati unutar `manifest.json`. Ako je jedna definisana, mogla bi biti **ranjiva**.
Podrazumevana postavka za stranice ekstenzija pretraživača je prilično restriktivna:
```bash
script-src 'self'; object-src 'self';
```
Za više informacija o CSP-u i potencijalnim zaobilaženjima pogledajte:
{{#ref}}
../content-security-policy-csp-bypass/
{{#endref}}
### `web_accessible_resources`
da bi veb stranica imala pristup stranici ekstenzije pregledača, na primer, `.html` stranici, ova stranica mora biti pomenuta u **`web_accessible_resources`** polju `manifest.json`.\
Na primer:
```javascript
{
...
"web_accessible_resources": [
{
"resources": [ "images/*.png" ],
"matches": [ "https://example.com/*" ]
},
{
"resources": [ "fonts/*.woff" ],
"matches": [ "https://example.com/*" ]
}
],
...
}
```
Ove stranice su dostupne na URL-u kao:
```
chrome-extension://<extension-id>/message.html
```
U javnim ekstenzijama **extension-id je dostupan**:
<figure><img src="../../images/image (1194).png" alt="" width="375"><figcaption></figcaption></figure>
Međutim, ako se koristi parametar `manifest.json` **`use_dynamic_url`**, ovaj **id može biti dinamičan**.
> [!TIP]
> Imajte na umu da čak i ako je stranica ovde pomenuta, može biti **zaštićena od ClickJacking** zahvaljujući **Content Security Policy**. Takođe treba da proverite (odeljak frame-ancestors) pre nego što potvrdite da je ClickJacking napad moguć.
Dozvola pristupa ovim stranicama čini ih **potencijalno ranjivim na ClickJacking**:
{{#ref}}
browext-clickjacking.md
{{#endref}}
> [!TIP]
> Dozvoljavanje da se ove stranice učitavaju samo putem ekstenzije, a ne putem nasumičnih URL-ova moglo bi sprečiti ClickJacking napade.
> [!CAUTION]
> Imajte na umu da stranice iz **`web_accessible_resources`** i druge stranice ekstenzije takođe mogu **kontaktirati pozadinske skripte**. Dakle, ako je jedna od ovih stranica ranjiva na **XSS**, to bi moglo otvoriti veću ranjivost.
>
> Pored toga, imajte na umu da možete otvoriti samo stranice navedene u **`web_accessible_resources`** unutar iframe-ova, ali iz nove kartice je moguće pristupiti bilo kojoj stranici u ekstenziji poznavajući ID ekstenzije. Stoga, ako se pronađe XSS koji zloupotrebljava iste parametre, može se zloupotrebiti čak i ako stranica nije konfigurisana u **`web_accessible_resources`**.
### `externally_connectable`
Prema [**docs**](https://developer.chrome.com/docs/extensions/reference/manifest/externally-connectable), manifest svojstvo `"externally_connectable"` deklarira **koje ekstenzije i web stranice mogu da se povežu** sa vašom ekstenzijom putem [runtime.connect](https://developer.chrome.com/docs/extensions/reference/runtime#method-connect) i [runtime.sendMessage](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage).
- Ako ključ **`externally_connectable`** **nije** deklarisan u manifestu vaše ekstenzije ili je deklarisan kao **`"ids": ["*"]`**, **sve ekstenzije mogu da se povežu, ali nijedna web stranica ne može da se poveže**.
- Ako su **specifični ID-ovi navedeni**, kao u `"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]`, **samo te aplikacije** mogu da se povežu.
- Ako su **matches** navedeni, te web aplikacije će moći da se povežu:
```json
"matches": [
"https://*.google.com/*",
"*://*.chromium.org/*",
```
- Ako je navedeno kao prazno: **`"externally_connectable": {}`**, nijedna aplikacija ili veb neće moći da se poveže.
Što je **manje ekstenzija i URL-ova** ovde navedeno, to će biti **manja površina napada**.
> [!CAUTION]
> Ako je veb stranica **ranjiva na XSS ili preuzimanje** navedena u **`externally_connectable`**, napadač će moći da **pošalje poruke direktno u pozadinski skript**, potpuno zaobilazeći Content Script i njegov CSP.
>
> Stoga, ovo je **veoma moćan zaobilazni način**.
>
> Štaviše, ako klijent instalira lažnu ekstenziju, čak i ako nije dozvoljeno da komunicira sa ranjivom ekstenzijom, mogla bi da ubrizga **XSS podatke u dozvoljenu veb stranicu** ili zloupotrebi **`WebRequest`** ili **`DeclarativeNetRequest`** API-je da manipuliše zahtevima na ciljanom domenu menjajući zahtev stranice za **JavaScript datoteku**. (Imajte na umu da CSP na ciljnoj stranici može sprečiti ove napade). Ova ideja dolazi [**iz ovog izveštaja**](https://www.darkrelay.com/post/opera-zero-day-rce-vulnerability).
## Sažetak komunikacije
### Ekstenzija <--> WebApp
Za komunikaciju između sadržajnog skripta i veb stranice obično se koriste post poruke. Stoga, u veb aplikaciji obično ćete pronaći pozive funkciji **`window.postMessage`** i u sadržajnom skriptu slušaoce poput **`window.addEventListener`**. Imajte na umu, međutim, da ekstenzija takođe može **komunicirati sa veb aplikacijom slanjem Post Poruke** (i stoga bi veb trebao to očekivati) ili jednostavno učiniti da veb učita novi skript.
### Unutar ekstenzije
Obično se funkcija **`chrome.runtime.sendMessage`** koristi za slanje poruke unutar ekstenzije (obično obrađuje `background` skript) i da bi je primila i obradila, deklarisan je slušalac koji poziva **`chrome.runtime.onMessage.addListener`**.
Takođe je moguće koristiti **`chrome.runtime.connect()`** da se uspostavi postojana veza umesto slanja pojedinačnih poruka, moguće je koristiti je za **slanje** i **prijem** **poruka** kao u sledećem primeru:
<details>
<summary><code>chrome.runtime.connect()</code> primer</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>
Takođe je moguće slati poruke iz pozadinskog skripta u sadržajni skript smešten u određenoj kartici pozivajući **`chrome.tabs.sendMessage`** gde ćete morati da navedete **ID kartice** kojoj šaljete poruku.
### Od dozvoljenog `externally_connectable` do ekstenzije
**Web aplikacije i eksternalni pregledački dodaci koji su dozvoljeni** u `externally_connectable` konfiguraciji mogu slati zahteve koristeći :
```javascript
chrome.runtime.sendMessage(extensionId, ...
```
Gde je potrebno pomenuti **ID ekstenzije**.
### Native Messaging
Moguće je da skripte u pozadini komuniciraju sa binarnim datotekama unutar sistema, koje mogu biti **podložne kritičnim ranjivostima kao što su RCE** ako ova komunikacija nije pravilno zaštićena. [Više o tome kasnije](#native-messaging).
```javascript
chrome.runtime.sendNativeMessage(
"com.my_company.my_application",
{ text: "Hello" },
function (response) {
console.log("Received " + response)
}
)
```
## Web **↔︎** Komunikacija između sadržajnih skripti
Okruženja u kojima **sadržajne skripte** funkcionišu i gde postoje host stranice su **odvojena** jedno od drugog, obezbeđujući **izolaciju**. I pored ove izolacije, oba imaju sposobnost da interaguju sa **Modelom objekta dokumenta (DOM)** stranice, zajedničkim resursom. Da bi host stranica mogla da komunicira sa **sadržajnom skriptom**, ili indirektno sa ekstenzijom putem sadržajne skripte, potrebno je koristiti **DOM** koji je dostupan obe strane kao komunikacioni kanal.
### Post poruke
```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
)
```
Sigurna Post Message komunikacija treba da proveri autentičnost primljene poruke, što se može uraditi proverom:
- **`event.isTrusted`**: Ovo je Tačno samo ako je događaj pokrenut akcijom korisnika
- Sadržajni skript može očekivati poruku samo ako korisnik izvrši neku akciju
- **izvorna domena**: može očekivati poruku samo sa dozvoljene liste domena.
- Ako se koristi regex, budite veoma oprezni
- **Izvor**: `received_message.source !== window` može se koristiti za proveru da li je poruka **iz iste prozora** gde Sadržajni Skript sluša.
Prethodne provere, čak i ako su izvršene, mogu biti ranjive, pa proverite na sledećoj stranici **potencijalne Post Message zaobilaženja**:
{{#ref}}
../postmessage-vulnerabilities/
{{#endref}}
### Iframe
Još jedan mogući način komunikacije može biti kroz **Iframe URL-ove**, možete pronaći primer u:
{{#ref}}
browext-xss-example.md
{{#endref}}
### DOM
Ovo nije "tačno" način komunikacije, ali **web i sadržajni skript će imati pristup web DOM-u**. Dakle, ako **sadržajni skript** čita neke informacije iz njega, **verujući web DOM-u**, web bi mogao **modifikovati ove podatke** (jer web ne bi trebao biti poverljiv, ili zato što je web ranjiv na XSS) i **kompromitovati Sadržajni Skript**.
Takođe možete pronaći primer **DOM baziranog XSS-a za kompromitovanje ekstenzije pretraživača** u:
{{#ref}}
browext-xss-example.md
{{#endref}}
## Komunikacija Sadržajnog Skripta **↔︎** Pozadinskog Skripta
Sadržajni Skript može koristiti funkcije [**runtime.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage) **ili** [**tabs.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/tabs#method-sendMessage) za slanje **jednokratne JSON-serializovane** poruke.
Da biste obradili **odgovor**, koristite vraćeni **Promise**. Iako, za unazadnu kompatibilnost, još uvek možete proslediti **callback** kao poslednji argument.
Slanje zahteva iz **sadržajnog skripta** izgleda ovako:
```javascript
;(async () => {
const response = await chrome.runtime.sendMessage({ greeting: "hello" })
// do something with response here, not outside the function
console.log(response)
})()
```
Slanje zahteva iz **ekstenzije** (obično **pozadinskog skripta**). Primer kako poslati poruku sadržajnom skriptu u odabranom tabu:
```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)
})()
```
Na **prijemnoj strani**, potrebno je postaviti [**runtime.onMessage**](https://developer.chrome.com/docs/extensions/reference/runtime#event-onMessage) **slušač događaja** da bi se obradila poruka. Ovo izgleda isto iz skripte sadržaja ili stranice ekstenzije.
```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" })
})
```
U istaknutom primeru, **`sendResponse()`** je izvršen na sinhroni način. Da bi se modifikovao `onMessage` handler za asinhrono izvršavanje `sendResponse()`, neophodno je uključiti `return true;`.
Važna stvar koju treba uzeti u obzir je da u scenarijima gde više stranica treba da prime `onMessage` događaje, **prva stranica koja izvrši `sendResponse()`** za određeni događaj će biti jedina koja može efikasno dostaviti odgovor. Svi naredni odgovori na isti događaj neće biti uzeti u obzir.
Kada se kreiraju nove ekstenzije, prednost treba dati promenama umesto povratnim pozivima. Što se tiče korišćenja povratnih poziva, `sendResponse()` funkcija se smatra validnom samo ako se izvršava direktno unutar sinhronog konteksta, ili ako handler označava asinhronu operaciju vraćanjem `true`. Ako nijedan od handlera ne vrati `true` ili ako je `sendResponse()` funkcija uklonjena iz memorije (sakupljena smeća), povratni poziv povezan sa `sendMessage()` funkcijom će se podrazumevano aktivirati.
## Native Messaging
Ekstenzije pretraživača takođe omogućavaju komunikaciju sa **binarima u sistemu putem stdin**. Aplikacija mora instalirati json koji to označava u json formatu:
```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/"]
}
```
Gde je `name` string prosleđen u [`runtime.connectNative()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-connectNative) ili [`runtime.sendNativeMessage()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-sendNativeMessage) za komunikaciju sa aplikacijom iz pozadinskih skripti ekstenzije pretraživača. `path` je putanja do binarnog fajla, postoji samo 1 važeći `type` koji je stdio (koristi stdin i stdout) i `allowed_origins` označava ekstenzije koje mogu da mu pristupe (i ne mogu imati wildcard).
Chrome/Chromium će tražiti ovaj json u nekim registrima sistema i nekim putanjama u macOS i Linux (više informacija u [**docs**](https://developer.chrome.com/docs/extensions/develop/concepts/native-messaging)).
> [!TIP]
> Ekstenzija pretraživača takođe treba da ima dozvolu `nativeMessaing` deklarisanu kako bi mogla da koristi ovu komunikaciju.
Ovako izgleda neki kod pozadinske skripte koji šalje poruke native aplikaciji:
```javascript
chrome.runtime.sendNativeMessage(
"com.my_company.my_application",
{ text: "Hello" },
function (response) {
console.log("Received " + response)
}
)
```
U [**ovom blog postu**](https://spaceraccoon.dev/universal-code-execution-browser-extensions/), predložen je ranjiv obrazac koji zloupotrebljava native poruke:
1. Ekstenzija pretraživača ima obrazac sa wildcard za sadržaj skripte.
2. Sadržaj skripte šalje `postMessage` poruke pozadinskoj skripti koristeći `sendMessage`.
3. Pozadinska skripta prosleđuje poruku native aplikaciji koristeći `sendNativeMessage`.
4. Native aplikacija opasno obrađuje poruku, što dovodi do izvršavanja koda.
I unutar njega objašnjen je primer **prelaska sa bilo koje stranice na RCE zloupotrebom ekstenzije pretraživača**.
## Osetljive informacije u memoriji/kodu/clipboard-u
Ako ekstenzija pretraživača čuva **osetljive informacije unutar svoje memorije**, to može biti **izvučeno** (posebno na Windows mašinama) i **pretraženo** za te informacije.
Stoga, memorija ekstenzije pretraživača **ne bi trebala biti smatrana sigurnom** i **osetljive informacije** kao što su akreditivi ili mnemoničke fraze **ne bi trebale biti čuvane**.
Naravno, **ne stavljajte osetljive informacije u kod**, jer će to biti **javno**.
Da biste izvadili memoriju iz pretraživača, možete **izvući memoriju procesa** ili da odete u **podešavanja** ekstenzije pretraživača klikom na **`Inspect pop-up`** -> U sekciji **`Memory`** -> **`Take a snapshot`** i **`CTRL+F`** da pretražujete unutar snimka za osetljive informacije.
Štaviše, veoma osetljive informacije kao što su mnemoničke ključeve ili lozinke **ne bi trebale biti dozvoljene da se kopiraju u clipboard** (ili barem ih uklonite iz clipboard-a u nekoliko sekundi) jer će tada procesi koji prate clipboard moći da ih dobiju.
## Učitavanje ekstenzije u pretraživaču
1. **Preuzmite** ekstenziju pretraživača & raspakujte je
2. Idite na **`chrome://extensions/`** i **omogućite** `Developer Mode`
3. Kliknite na dugme **`Load unpacked`**
U **Firefox-u** idete na **`about:debugging#/runtime/this-firefox`** i kliknite na dugme **`Load Temporary Add-on`**.
## Dobijanje izvornog koda iz prodavnice
Izvorni kod Chrome ekstenzije može se dobiti kroz različite metode. Ispod su detaljna objašnjenja i uputstva za svaku opciju.
### Preuzimanje ekstenzije kao ZIP putem komandne linije
Izvorni kod Chrome ekstenzije može se preuzeti kao ZIP datoteka koristeći komandnu liniju. To uključuje korišćenje `curl` za preuzimanje ZIP datoteke sa specifične URL adrese i zatim ekstrakciju sadržaja ZIP datoteke u direktorijum. Evo koraka:
1. Zamenite `"extension_id"` sa stvarnim ID-jem ekstenzije.
2. Izvršite sledeće komande:
```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"
```
### Koristite CRX Viewer veb sajt
[https://robwu.nl/crxviewer/](https://robwu.nl/crxviewer/)
### Koristite CRX Viewer ekstenziju
Još jedna pogodna metoda je korišćenje Chrome Extension Source Viewer, koji je projekat otvorenog koda. Može se instalirati iz [Chrome Web Store](https://chrome.google.com/webstore/detail/chrome-extension-source-v/jifpbeccnghkjeaalbbjmodiffmgedin?hl=en). Izvorni kod pregledača je dostupan u njegovom [GitHub repozitorijumu](https://github.com/Rob--W/crxviewer).
### Pregledajte izvor lokalno instalirane ekstenzije
Chrome ekstenzije instalirane lokalno takođe se mogu pregledati. Evo kako:
1. Pristupite svom lokalnom profilu Chrome-a tako što ćete posetiti `chrome://version/` i pronaći polje "Profile Path".
2. Idite u podfolder `Extensions/` unutar direktorijuma profila.
3. Ova fascikla sadrži sve instalirane ekstenzije, obično sa njihovim izvorom u čitljivom formatu.
Da biste identifikovali ekstenzije, možete mapirati njihove ID-eve na imena:
- Omogućite Developer Mode na stranici `about:extensions` da biste videli ID-eve svake ekstenzije.
- Unutar fascikle svake ekstenzije, datoteka `manifest.json` sadrži čitljivo polje `name`, što pomaže u identifikaciji ekstenzije.
### Koristite arhivator ili raspakivač
Idite na Chrome Web Store i preuzmite ekstenziju. Datoteka će imati ekstenziju `.crx`. Promenite ekstenziju datoteke sa `.crx` na `.zip`. Koristite bilo koji arhivator (kao što su WinRAR, 7-Zip, itd.) da biste raspakovali sadržaj ZIP datoteke.
### Koristite Developer Mode u Chrome-u
Otvorite Chrome i idite na `chrome://extensions/`. Omogućite "Developer mode" u gornjem desnom uglu. Kliknite na "Load unpacked extension...". Idite do direktorijuma vaše ekstenzije. Ovo ne preuzima izvorni kod, ali je korisno za pregledanje i modifikovanje koda već preuzete ili razvijene ekstenzije.
## Skup podataka manifest ekstenzija za Chrome
Da biste pokušali da pronađete ranjive ekstenzije za pretraživač, možete koristiti [https://github.com/palant/chrome-extension-manifests-dataset](https://github.com/palant/chrome-extension-manifests-dataset) i proveriti njihove manifest datoteke na potencijalno ranjive znakove. Na primer, da biste proverili ekstenzije sa više od 25000 korisnika, `content_scripts` i dozvolu `nativeMessaging`:
```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')"
```
## Lista provere bezbednosti
Iako ekstenzije za pretraživače imaju **ograničenu površinu napada**, neke od njih mogu sadržati **ranjivosti** ili **potencijalna poboljšanja sigurnosti**. Sledeće su najčešće:
- [ ] **Ograničite** koliko god je moguće tražene **`permissions`**
- [ ] **Ograničite** koliko god je moguće **`host_permissions`**
- [ ] Koristite **jaku** **`content_security_policy`**
- [ ] **Ograničite** koliko god je moguće **`externally_connectable`**, ako nije potrebno i moguće, ne ostavljajte ga podrazumevano, navedite **`{}`**
- [ ] Ako je ovde pomenut **URL ranjiv na XSS ili preuzimanje**, napadač će moći da **šalje poruke pozadinskim skriptama direktno**. Veoma moćan zaobilaženje.
- [ ] **Ograničite** koliko god je moguće **`web_accessible_resources`**, čak i prazne ako je moguće.
- [ ] Ako **`web_accessible_resources`** nije nijedna, proverite za [**ClickJacking**](browext-clickjacking.md)
- [ ] Ako se bilo koja **komunikacija** dešava od **ekstenzije** do **web stranice**, [**proverite za XSS**](browext-xss-example.md) **ranjivosti** uzrokovane u komunikaciji.
- [ ] Ako se koriste Post Messages, proverite za [**Post Message ranjivosti**](../postmessage-vulnerabilities/index.html)**.**
- [ ] Ako **Content Script pristupa DOM detaljima**, proverite da li **ne uvode XSS** ako ih **modifikuje** web
- [ ] Posebno naglasite ako je ova komunikacija takođe uključena u **komunikaciju Content Script -> pozadinska skripta**
- [ ] Ako pozadinska skripta komunicira putem **native messaging**, proverite da li je komunikacija sigurna i sanirana
- [ ] **Osetljive informacije ne bi trebalo da budu pohranjene** unutar koda ekstenzije za pretraživač
- [ ] **Osetljive informacije ne bi trebalo da budu pohranjene** unutar memorije ekstenzije za pretraživač
- [ ] **Osetljive informacije ne bi trebalo da budu pohranjene** unutar **datotečnog sistema nezaštićeno**
## Rizici ekstenzije za pretraživač
- Aplikacija [https://crxaminer.tech/](https://crxaminer.tech/) analizira neke podatke kao što su dozvole koje ekstenzija za pretraživač zahteva kako bi dala nivo rizika korišćenja ekstenzije za pretraživač.
## Alati
### [**Tarnish**](https://thehackerblog.com/tarnish/)
- Preuzima bilo koju Chrome ekstenziju sa datog linka Chrome web prodavnice.
- [**manifest.json**](https://developer.chrome.com/extensions/manifest) **pregledač**: jednostavno prikazuje JSON-formatiranu verziju manifest datoteke ekstenzije.
- **Analiza otiska**: Detekcija [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources) i automatska generacija JavaScript-a za otiskivanje Chrome ekstenzija.
- **Potencijalna analiza Clickjacking-a**: Detekcija HTML stranica ekstenzije sa postavljenom direktivom [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources). Ove su potencijalno ranjive na clickjacking u zavisnosti od svrhe stranica.
- **Pregledač upozorenja o dozvolama**: koji prikazuje listu svih upozorenja o dozvolama Chrome-a koja će biti prikazana kada korisnik pokuša da instalira ekstenziju.
- **Opasne funkcije**: prikazuje lokaciju opasnih funkcija koje bi potencijalno mogle biti iskorišćene od strane napadača (npr. funkcije kao što su innerHTML, chrome.tabs.executeScript).
- **Ulazne tačke**: prikazuje gde ekstenzija prima korisnički/eksterni ulaz. Ovo je korisno za razumevanje površine ekstenzije i traženje potencijalnih tačaka za slanje zlonamerno oblikovanih podataka ekstenziji.
- I skeneri Opasnih funkcija i Ulaznih tačaka imaju sledeće za svoje generisane alarme:
- Relevantni deo koda i linija koja je izazvala alarm.
- Opis problema.
- Dugme "Pogledaj datoteku" za pregled celokupne izvorne datoteke koja sadrži kod.
- Putanja alarmirane datoteke.
- Potpuni URI Chrome ekstenzije alarmirane datoteke.
- Tip datoteke, kao što su skripta pozadinske stranice, skripta sadržaja, akcija pretraživača, itd.
- Ako je ranjiva linija u JavaScript datoteci, putanje svih stranica gde je uključena kao i tip ovih stranica, i [web_accessible_resource](https://developer.chrome.com/extensions/manifest/web_accessible_resources) status.
- **Analizator politike sigurnosti sadržaja (CSP) i proveravač zaobilaženja**: Ovo će ukazati na slabosti u CSP-u vaše ekstenzije i takođe će osvetliti sve potencijalne načine zaobilaženja vašeg CSP-a zbog belih lista CDN-ova itd.
- **Poznate ranjive biblioteke**: Ovo koristi [Retire.js](https://retirejs.github.io/retire.js/) da proveri za bilo kakvu upotrebu poznatih ranjivih JavaScript biblioteka.
- Preuzmite ekstenziju i formatirane verzije.
- Preuzmite originalnu ekstenziju.
- Preuzmite ulepšanu verziju ekstenzije (automatski formatirani HTML i JavaScript).
- Automatsko keširanje rezultata skeniranja, pokretanje skeniranja ekstenzije će potrajati dobar deo vremena prvi put kada ga pokrenete. Međutim, drugi put, pod pretpostavkom da ekstenzija nije ažurirana, biće gotovo instant zbog keširanih rezultata.
- Linkabilni URL-ovi izveštaja, lako povežite nekoga sa izveštajem o ekstenziji generisanim od strane tarnish.
### [Neto](https://github.com/elevenpaths/neto)
Projekat Neto je Python 3 paket osmišljen za analizu i otkrivanje skrivenih funkcija ekstenzija i dodataka za pretraživače kao što su Firefox i Chrome. Automatizuje proces raspakivanja pakovanih datoteka kako bi izvukao ove funkcije iz relevantnih resursa u ekstenziji kao što su `manifest.json`, folderi za lokalizaciju ili JavaScript i HTML izvorne datoteke.
## Reference
- **Zahvaljujući** [**@naivenom**](https://twitter.com/naivenom) **za pomoć sa ovom metodologijom**
- [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}}