Browser Extension Pentesting Methodology

Support HackTricks

Basic Information

Ekstenzije pretraživača su napisane u JavaScript-u i učitavaju se u pozadini od strane pretraživača. Ima svoj DOM ali može da interaguje sa DOM-ovima drugih sajtova. To znači da može ugroziti poverljivost, integritet i dostupnost (CIA) drugih sajtova.

Main Components

Izgledi ekstenzije izgledaju najbolje kada su vizualizovani i sastoje se od tri komponente. Pogledajmo svaku komponentu detaljno.

Content Scripts

Svaki sadržajni skript ima direktan pristup DOM-u jedne web stranice i stoga je izložen potencijalno zloćudnom unosu. Međutim, sadržajni skript ne sadrži dozvole osim sposobnosti slanja poruka jezgru ekstenzije.

Extension Core

Jezgro ekstenzije sadrži većinu privilegija/pristupa ekstenzije, ali jezgro ekstenzije može da interaguje sa web sadržajem samo putem XMLHttpRequest i sadržajnih skripti. Takođe, jezgro ekstenzije nema direktan pristup host mašini.

Native Binary

Ekstenzija omogućava nativni binarni fajl koji može pristupiti host mašini sa punim privilegijama korisnika. Nativni binarni fajl interaguje sa jezgrom ekstenzije putem standardnog Netscape Plugin Application Programming Interface (NPAPI) koji koriste Flash i drugi browser plug-in-ovi.

Boundaries

Da bi dobio pune privilegije korisnika, napadač mora ubediti ekstenziju da prenese zloćudni unos iz sadržajnog skripta u jezgro ekstenzije i iz jezgra ekstenzije u nativni binarni fajl.

Svaka komponenta ekstenzije je odvojena jedna od druge jakim zaštitnim granicama. Svaka komponenta se izvršava u odvojenom procesu operativnog sistema. Sadržajni skripti i jezgra ekstenzije se izvršavaju u sandbox procesima koji nisu dostupni većini usluga operativnog sistema.

Štaviše, sadržajni skripti su odvojeni od svojih povezanih web stranica izvršavanjem u odvojenom JavaScript heap-u. Sadržajni skript i web stranica imaju pristup istom osnovnom DOM-u, ali se njih dvoje nikada ne razmenjuju JavaScript pokazivače, sprečavajući curenje JavaScript funkcionalnosti.

manifest.json

Chrome ekstenzija je samo ZIP folder sa .crx ekstenzijom fajla. Jezgro ekstenzije je manifest.json fajl u korenu foldera, koji specificira raspored, dozvole i druge opcije konfiguracije.

Example:

{
"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) stranice.

"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 API za skladištenje preuzme message vrednost iz skladišta ekstenzije.

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

Poruka se šalje na stranice ekstenzije putem sadržajnog skripta kada se pritisne ovaj dugme, korišćenjem runtime.sendMessage() API. 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.

U zavisnosti od pregledača, mogućnosti sadržajnog skripta mogu se malo razlikovati. Za pregledače zasnovane na Chromium-u, lista mogućnosti je dostupna u Chrome Developers dokumentaciji, a za Firefox, MDN služi kao primarni izvor. Takođe je važno napomenuti da sadržajni skripti imaju sposobnost da komuniciraju sa pozadinskim skriptima, omogućavajući im da izvršavaju radnje i prenose odgovore nazad.

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

Napomena: 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 za stranicu u koju se skripte umetaju. Ove dozvole mogu se obezbediti ili zahtevom unutar manifest fajla ekstenzije ili privremeno putem activeTab.

Primer ekstenzije zasnovane na activeTab

manifest.json
{
"name": "My extension",
...
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Action Button"
}
}
  • Ubacite JS datoteku na klik:

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

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

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

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

Putem service-worker.js

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

background

Poruke koje šalju sadržajni skripti primaju se na pozadinskoj stranici, koja ima centralnu ulogu u koordinaciji komponenti ekstenzije. Važno je napomenuti da pozadinska stranica opstaje tokom celog trajanja ekstenzije, delujući diskretno bez direktne interakcije korisnika. Ima svoj vlastiti Model objekta dokumenta (DOM), što omogućava složene interakcije i upravljanje stanjem.

Ključne tačke:

  • Uloga pozadinske stranice: Deluje kao nervni centar za ekstenziju, obezbeđujući komunikaciju i koordinaciju među različitim delovima ekstenzije.

  • Postojanost: To je uvek prisutna entitet, nevidljiva korisniku, ali integralna za funkcionalnost ekstenzije.

  • Automatska generacija: Ako nije eksplicitno definisana, pretraživač će automatski kreirati pozadinsku stranicu. Ova automatski generisana stranica će uključivati sve pozadinske skripte navedene u manifestu ekstenzije, obezbeđujući nesmetano funkcionisanje pozadinskih zadataka ekstenzije.

Pogodnost koju pretraživač pruža automatskim generisanjem pozadinske stranice (kada nije eksplicitno deklarisana) osigurava da su sve potrebne pozadinske skripte integrisane i operativne, pojednostavljujući proces postavljanja ekstenzije.

Primer pozadinske skripte:

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

Koristi runtime.onMessage API za slušanje poruka. Kada se primi poruka "explain", koristi tabs API 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:

Opcione stranice i druge

Ekstenzije pretraživača mogu sadržati razne 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 u chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca ili klikom:

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-jevima specifičnim za ekstenziju: Ove stranice uživaju sveobuhvatan pristup API-jevima 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 (skladištenje, lokacija...) i u koje web stranice.

Kako ekstenzije pretraživača mogu biti tako privilegovane, zlonamerna ili kompromitovana ekstenzija mogla bi omogućiti napadaču različite načine da ukrade osetljive informacije i špijunira korisnika.

Proverite kako ove postavke funkcionišu i kako bi mogle biti zloupotrebljene u:

BrowExt - permissions & host_permissions

content_security_policy

Politika bezbednosti sadržaja može biti deklarisana i unutar manifest.json. Ako je jedna definisana, mogla bi biti ranjiva.

Podrazumevana postavka za stranice ekstenzije pretraživača je prilično restriktivna:

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

Za više informacija o CSP-u i potencijalnim zaobilaženjima, proverite:

Content Security Policy (CSP) Bypass

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:

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

Međutim, ako se koristi parametar manifest.json use_dynamic_url, ovaj id može biti dinamičan.

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ć.

Mogućnost pristupa ovim stranicama čini ih potencijalno ranjivim na ClickJacking:

BrowExt - ClickJacking

Dozvoljavanje da se ove stranice učitavaju samo putem ekstenzije, a ne putem nasumičnih URL-ova, moglo bi sprečiti ClickJacking napade.

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, manifest svojstvo "externally_connectable" deklarira koje ekstenzije i web stranice mogu da se povežu sa vašom ekstenzijom putem runtime.connect i runtime.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 match-ovi navedeni, te web aplikacije će moći da se povežu:

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

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.

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:

chrome.runtime.connect() primer

```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 obezbeđena. Više o tome kasnije.

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 Document Object Model (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

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

Iframe

Još jedan mogući način komunikacije može biti kroz Iframe URL-ove, možete pronaći primer u:

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:

Komunikacija Sadržajnog Skripta ↔︎ Pozadinskog Skripta

Sadržajni Skript može koristiti funkcije runtime.sendMessage() ili tabs.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:

(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:

// 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 slušač događaja da bi se obradila poruka. Ovo izgleda isto iz skripte sadržaja ili stranice ekstenzije.

// 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 događaj 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 bi trebala biti na promenama umesto na 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 događaj handler označava asinhronu operaciju vraćanjem true. Ako nijedan od handlera ne vrati true ili ako je funkcija sendResponse() 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:

{
"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 koji se prosleđuje runtime.connectNative() ili runtime.sendNativeMessage() za komunikaciju sa aplikacijom iz pozadinskih skripti ekstenzije pregledač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).

Ekstenzija pregledač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:

chrome.runtime.sendNativeMessage(
'com.my_company.my_application',
{text: 'Hello'},
function (response) {
console.log('Received ' + response);
}
);

U ovom blog postu, 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 prosleđuje 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šenja 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 na podešavanja ekstenzije pretraživača klikom na Inspect pop-up -> U Memory sekciji -> 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 fajl koristeći komandnu liniju. To uključuje korišćenje curl za preuzimanje ZIP fajla sa specifične URL adrese i zatim ekstrakciju sadržaja ZIP fajla u direktorijum. Evo koraka:

  1. Zamenite "extension_id" sa stvarnim ID-jem ekstenzije.

  2. Izvršite sledeće komande:

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/

Koristite CRX Viewer ekstenziju

Još jedna pogodna metoda je korišćenje Chrome Extension Source Viewer, koji je open-source projekat. Može se instalirati iz Chrome Web Store. Izvorni kod pregledača je dostupan u njegovom GitHub repozitorijumu.

Pregledajte izvor lokalno instalirane ekstenzije

Chrome ekstenzije instalirane lokalno takođe se mogu pregledati. Evo kako:

  1. Pristupite svom lokalnom Chrome profilu tako što ćete posetiti chrome://version/ i pronaći polje "Profile Path".

  2. Idite u podfolder Extensions/ unutar direktorijuma profila.

  3. Ovaj folder 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 foldera svake ekstenzije, datoteka manifest.json sadrži čitljivo polje name, što pomaže u identifikaciji ekstenzije.

Koristite arhivator ili raspakivač datoteka

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

# 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 za bezbednosnu reviziju

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:

Alati

  • Preuzima bilo koju Chrome ekstenziju sa datog linka Chrome web prodavnice.

  • manifest.json pregledač: jednostavno prikazuje JSON-formatiranu verziju manifest datoteke ekstenzije.

  • Analiza otiska: Detekcija web_accessible_resources i automatska generacija JavaScript-a za otiskivanje Chrome ekstenzije.

  • Potencijalna analiza Clickjacking-a: Detekcija HTML stranica ekstenzije sa postavljenom direktivom 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, sadržajna skripta, 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 status web_accessible_resource.

  • Analizator Content Security Policy (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 da proveri bilo kakvu upotrebu poznatih ranjivih JavaScript biblioteka.

  • Preuzmite ekstenziju i formatirane verzije.

  • Preuzmite originalnu ekstenziju.

  • Preuzmite ulepšanu verziju ekstenzije (automatski formatiran HTML i JavaScript).

  • Automatsko keširanje rezultata skeniranja, pokretanje skeniranja ekstenzije će potrajati neko vreme 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.

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

Last updated