Metodologija pentestinga browser ekstenzija
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Osnovne informacije
Browser ekstenzije su napisane u JavaScriptu i učitavaju se u pozadini od strane browsera. Imaju sopstveni DOM ali mogu da interaguju sa DOM-ovima drugih sajtova. To znači da mogu ugroziti poverljivost, integritet i dostupnost drugih sajtova (CIA).
Glavne komponente
Raspored ekstenzija najbolje je prikazan vizuelno i sastoji se iz tri komponente. Pogledajmo svaku komponentu detaljno.
 (1) (1).png)
Content Scripts
Svaki content script ima direktan pristup DOM-u jedne web stranice i samim tim je izložen potencijalno malicioznom inputu. Međutim, content script nema druge dozvole osim mogućnosti slanja poruka extension core-u.
Extension Core
Extension core sadrži većinu privilegija/pristupa ekstenzije, ali extension core može da interaguje sa web sadržajem samo putem XMLHttpRequest i content scripts. Takođe, extension core nema direktan pristup host mašini.
Native Binary
Ekstenzija dozvoljava native binary koji može da pristupi host mašini sa punim privilegijama korisnika. Native binary komunicira sa extension core-om preko standardnog Netscape Plugin Application Programming Interface (NPAPI) koji koriste Flash i drugi browser plug-inovi.
Boundaries
Caution
Da bi stekao pune privilegije korisnika, napadač mora da ubedi ekstenziju da prosledi maliciozni input iz content scripta u extension core i iz extension core-a u native binary.
Svaka komponenta ekstenzije odvojena je od drugih snažnim zaštitnim granicama. Svaka komponenta radi u zasebnom procesu operativnog sistema. Content scripts i extension cores rade u sandbox procesima koji nisu dostupni većini servisa operativnog sistema.
Pored toga, content scripts su odvojeni od pripadajućih web stranica tako što se izvršavaju u zasebnom JavaScript heap-u. Content script i web stranica imaju pristup istom osnovnom DOM-u, ali ta dva nikada ne razmenjuju JavaScript pointers, sprečavajući leaking JavaScript funkcionalnosti.
manifest.json
Chrome ekstenzija je zapravo ZIP folder sa .crx file extension. Core ekstenzije je fajl manifest.json u korenu foldera, koji specificira raspored, dozvole i druge konfiguracione opcije.
Primer:
{
"manifest_version": 2,
"name": "My extension",
"version": "1.0",
"permissions": ["storage"],
"content_scripts": [
{
"js": ["script.js"],
"matches": ["https://example.com/*", "https://www.example.com/*"],
"exclude_matches": ["*://*/*business*"]
}
],
"background": {
"scripts": ["background.js"]
},
"options_ui": {
"page": "options.html"
}
}
content_scripts
Content scripts se učitavaju kad god korisnik navigira na odgovarajuću stranicu, u našem slučaju bilo koja stranica koja odgovara izrazu https://example.com/* i ne odgovara regexu *://*/*/business*. Izvršavaju se kao skripte same stranice i imaju proizvoljan pristup stranici Document Object Model (DOM).
"content_scripts": [
{
"js": [
"script.js"
],
"matches": [
"https://example.com/*",
"https://www.example.com/*"
],
"exclude_matches": ["*://*/*business*"],
}
],
Da biste uključili ili isključili više URL-ova, moguće je koristiti include_globs i exclude_globs.
Ovo je primer content script-a koji će dodati explain button na stranicu kada se the storage API koristi za dohvat vrednosti message iz extension’s storage.
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)
})
.png)
Poruka se šalje stranicama ekstenzije od strane skripte sadržaja kada se ovaj dugme klikne, putem korišćenja runtime.sendMessage() API. To je zbog ograničenja skripte sadržaja u direktnom pristupu API-jima, pri čemu je storage jedan od retkih izuzetaka. Za funkcionalnosti van tih izuzetaka, poruke se šalju stranicama ekstenzije sa kojima skripte sadržaja mogu komunicirati.
Warning
U zavisnosti od pregledača, mogućnosti skripte sadržaja mogu se malo razlikovati. Za Chromium-based browsers, lista mogućnosti je dostupna u Chrome Developers documentation, a za Firefox, MDN služi kao primarni izvor.
Takođe je važno napomenuti da skripte sadržaja mogu komunicirati sa skriptama u pozadini, omogućavajući im da izvrše akcije i proslede odgovore nazad.
Za pregled i debugovanje skripti sadržaja u Chrome-u, meni Chrome developer tools može se otvoriti preko Options > More tools > Developer tools ILI pritiskom Ctrl + Shift + I.
Kada se prikažu developer tools, kliknite na Source tab, zatim na Content Scripts tab. Ovo omogućava posmatranje pokrenutih skripti sadržaja iz različitih ekstenzija i postavljanje breakpoint-ova za praćenje toka izvršavanja.
Injected content scripts
Tip
Imajte na umu da Content Scripts nisu obavezne jer je takođe moguće dinamički injektovati skripte i programski ih ubaciti u web stranice putem
tabs.executeScript. To zapravo pruža više granularnih kontrola.
Za programsko injektovanje skripte sadržaja, ekstenzija mora imati host permissions za stranicu u koju će skripte biti injektovane. Ove dozvole se mogu obezbediti ili tako što će se tražiti unutar manifesta ekstenzije ili privremeno putem activeTab.
Example activeTab-based extension
{
"name": "My extension",
...
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Action Button"
}
}
- Injektuj JS fajl pri kliku:
// 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"],
})
})
- Inject a function pri kliku:
//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 scripting permissions
// 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 biste uključili ili isključili više URL-ova, moguće je koristiti include_globs i exclude_globs.
Content skripte run_at
Polje run_at kontroliše kada se JavaScript fajlovi ubacuju u web stranicu. Poželjna i podrazumevana vrednost je “document_idle”.
Moguće vrednosti su:
document_idle: Kad god je mogućedocument_start: Nakon bilo kojih fajlova izcss, ali pre nego što se bilo koji drugi DOM izgradi ili se pokrene bilo koja druga skripta.document_end: Odmah nakon što je DOM kompletan, ali pre nego što se podresursi kao slike i frame-ovi učitaju.
Putem 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 content scripts primaju pozadinska stranica, koja ima centralnu ulogu u koordinaciji komponenti ekstenzije. Važno je da pozadinska stranica opstaje tokom trajanja ekstenzije, radeći diskretno bez direktne interakcije sa korisnikom. Ima sopstveni Document Object Model (DOM), omogućavajući kompleksne interakcije i upravljanje stanjima.
Ključne napomene:
- Uloga pozadinske stranice: Služi kao centralno čvorište za ekstenziju, obezbeđujući komunikaciju i koordinaciju među različitim delovima ekstenzije.
- Postojanost: To je stalno prisutna komponenta, nevidljiva korisniku ali ključna za funkcionalnost ekstenzije.
- Automatsko generisanje: Ako nije eksplicitno definisana, pregledač će automatski kreirati pozadinsku stranicu. Ova automatski generisana stranica će uključiti sve background scripts navedene u manifestu ekstenzije, osiguravajući neometan rad pozadinskih zadataka ekstenzije.
Tip
Pogodnost koju pruža pregledač prilikom automatskog generisanja pozadinske stranice (kada nije eksplicitno deklarisana) osigurava da su sve neophodne background scripts integrisane i operativne, pojednostavljujući proces podešavanja ekstenzije.
Example background script:
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request == "explain") {
chrome.tabs.create({ url: "https://example.net/explanation" })
}
})
It uses runtime.onMessage API to listen to messages. When an "explain" message is received, it uses tabs API to open a page in a new tab.
Za debugovanje background skripta možete otići na detalje ekstenzije i inspektovati service worker, ovo će otvoriti developer tools sa background skriptom:
Options pages and other
Browser extensions mogu sadržati različite vrste stranica:
- Action pages se prikazuju u drop-down kada se klikne na ikonu ekstenzije.
- Stranice koje će ekstenzija učitati u novom tabu.
- Option Pages: Ova stranica se prikazuje preko ekstenzije kada se klikne. U prethodnom manifestu, u mom slučaju mogao sam pristupiti ovoj stranici preko
chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjcaili klikom:
.png)
Imajte na umu da ove stranice nisu persistentne kao background pages jer dinamički učitavaju sadržaj po potrebi. Uprkos tome, dele određene mogućnosti sa background page:
- Communication with Content Scripts: Slično background page-u, ove stranice mogu primati poruke od content scripts, olakšavajući interakciju unutar ekstenzije.
- Access to Extension-Specific APIs: Ove stranice imaju širok pristup extension-specific APIs, u skladu sa permisijama definisanim za ekstenziju.
permissions & host_permissions
permissions i host_permissions su unosi iz manifest.json koji će indicirati koje permisije ekstenzija ima (storage, location…) i na kojim web stranicama.
Pošto browser extensions mogu biti veoma privileged, zlonamerna ili kompromitovana ekstenzija može napadaču omogućiti različite načine da ukrade osetljive informacije i špijunira korisnika.
Proverite kako ova podešavanja funkcionišu i kako se mogu zloupotrebiti u:
BrowExt - permissions & host_permissions
content_security_policy
A content security policy se takođe može deklarisati unutar manifest.json. Ako je definisana, može biti vulnerable.
Podrazumevana podešavanja za stranice browser ekstenzija su prilično restriktivna:
script-src 'self'; object-src 'self';
Za više informacija o CSP i potencijalnim bypasses pogledajte:
Content Security Policy (CSP) Bypass
web_accessible_resources
Da bi web stranica mogla da pristupi stranici proširenja pregledača, na primer .html stranici, ta stranica mora biti navedena u polju web_accessible_resources u 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-ovima kao:
chrome-extension://<extension-id>/message.html
In public extensions the extension-id is accesible:
.png)
Although, if the manifest.json parameter use_dynamic_url is used, this id can be dynamic.
Tip
Note that even if a page is mentioned here, it might be protected against ClickJacking thanks to the Content Security Policy. So you also need to check it (frame-ancestors section) before confirming a ClickJacking attack is possible.
Being allowed to access these pages make these pages potentially vulnerable ClickJacking:
Tip
Allowing these pages to be loaded only by the extension and not by random URLs could prevent ClickJacking attacks.
Caution
Note that the pages from
web_accessible_resourcesand other pages of the extension are also capable of contacting background scripts. So if one of these pages is vulnerable to XSS it could open a bigger vulnerability.Moreover, note that you can only open pages indicated in
web_accessible_resourcesinside iframes, but from a new tab it’s possible to access any page in the extension knowing the extension ID. Therefore, if an XSS is found abusing same parameters, it could be abused even if the page isn’t configured inweb_accessible_resources.
externally_connectable
A per the docs, The "externally_connectable" manifest property declares which extensions and web pages can connect to your extension via runtime.connect and runtime.sendMessage.
- If the
externally_connectablekey is not declared in your extension’s manifest or it’s declared as"ids": ["*"], all extensions can connect, but no web pages can connect. - If specific IDs are specified, like in
"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"], only those applications can connect. - If matches are specified, those web apps will be able to connect:
"matches": [
"https://*.google.com/*",
"*://*.chromium.org/*",
- If it’s specified as empty:
"externally_connectable": {}, nijedna aplikacija ili web neće moći da se poveže.
The manje ekstenzija i URL-ova ovde navedeno, to će biti manja površina napada.
Caution
Ako je web stranica vulnerable to XSS or takeover navedena u
externally_connectable, napadač će moći da pošalje poruke direktno background script-u, potpuno zaobilazeći Content Script i njegov CSP.Dakle, ovo je veoma moćan bypass.
Štaviše, ako klijent instalira rouge extension, čak i ako nije dozvoljeno da komunicira sa ranjivom ekstenzijom, mogao bi da ubaci XSS data u dozvoljenu web stranicu ili zloupotrebi
WebRequestiliDeclarativeNetRequestAPI-je da manipuliše zahtevima na ciljanoj domeni menjajući zahtev stranice za JavaScript file. (Napomena: CSP na ciljanoj stranici može sprečiti ove napade). Ova ideja potiče from this writeup.
Communication summary
Extension <–> WebApp
Za komunikaciju između content script-a i web stranice obično se koriste post messages. Dakle, u web aplikaciji ćete obično naći pozive funkciji window.postMessage i u content script-u slušače kao window.addEventListener. Napomena, međutim, da ekstenzija takođe može komunicirati sa web aplikacijom slanjem Post Message (i stoga web treba da to očekuje) ili jednostavno naterati web da učita novi skript.
Inside the extension
Obično se funkcija chrome.runtime.sendMessage koristi za slanje poruke unutar ekstenzije (obično obrađuje background script) i da bi se primila i obradila, deklarisan je slušač pozivanjem chrome.runtime.onMessage.addListener.
Takođe je moguće koristiti chrome.runtime.connect() da se uspostavi perzistentna konekcija umesto slanja pojedinačnih poruka, može se koristiti za slanje i primanje messages 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>
Moguće je takođe slati poruke iz background skripte ka content skripti lociranoj u specifičnom tabu pozivom **`chrome.tabs.sendMessage`** gde ćete morati da navedete **ID taba** kome šaljete poruku.
### Od dozvoljenih `externally_connectable` ka ekstenziji
**Web aplikacije i eksterni dodaci za pregledač koji su dozvoljeni** u `externally_connectable` konfiguraciji mogu slati zahteve koristeći :
```javascript
chrome.runtime.sendMessage(extensionId, ...
Gde god je potrebno pomenuti extension ID.
Native Messaging
Moguće je da pozadinske skripte komuniciraju sa binarnim fajlovima unutar sistema, što može biti podložno kritičnim ranjivostima kao što su RCEs ako ta komunikacija nije pravilno osigurana. More on this later.
chrome.runtime.sendNativeMessage(
"com.my_company.my_application",
{ text: "Hello" },
function (response) {
console.log("Received " + response)
}
)
Web ↔︎ Content Script Komunikacija
Okruženja u kojima rade content scripts i u kojima postoje host stranice su međusobno odvojena, obezbeđujući izolaciju. Uprkos toj izolaciji, oba mogu da interaguju sa Document Object Model (DOM) stranice, koji je zajednički resurs. Da bi host stranica ostvarila komunikaciju sa content script, ili indirektno sa ekstenzijom preko content script, potrebno je koristiti DOM koji je dostupan obema stranama kao kanal komunikacije.
Post Messages
// 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
)
document.getElementById("theButton").addEventListener(
"click",
() => {
window.postMessage(
{ type: "FROM_PAGE", text: "Hello from the webpage!" },
"*"
)
},
false
)
A secure Post Message communication should check the authenticity of the received message, this can be done checking:
event.isTrusted: Ovo je True samo ako je događaj pokrenut radnjom korisnika- The content script može očekivati poruku samo ako korisnik izvrši neku radnju
- origin domain: može očekivati poruku samo od allowlist domena.
- If a regex is used, be very careful
- Source:
received_message.source !== windowmože se koristiti da proveri da li je poruka iz istog prozora gde Content Script sluša.
The previous checks, even if performed, could be vulnerable, so check in the following page potential Post Message bypasses:
Iframe
Još jedan mogući način komunikacije može biti preko Iframe URLs, primer možete naći u:
DOM
Ovo nije “tačno” način komunikacije, ali web and the content script will have access to the web DOM. Dakle, ako content script čita neke informacije iz njega, trusting the web DOM, web može modify this data (jer webu se ne bi trebalo verovati, ili zato što je web ranjiv na XSS) i može compromise the Content Script.
Takođe možete naći primer DOM based XSS to compromise a browser extension u:
Content Script ↔︎ Background Script Komunikacija
Content Script može koristiti funkcije runtime.sendMessage() or tabs.sendMessage() da pošalje one-time JSON-serializable poruku.
Za obradu response, koristite vraćeni Promise. Ipak, radi kompatibilnosti unazad, i dalje možete proslediti callback kao poslednji argument.
Slanje zahteva iz content script 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 extension (obično background script). Primer kako poslati poruku content script-u u selected tab:
// 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, morate podesiti runtime.onMessage event listener da obradi poruku. Ovo izgleda isto iz content script-a ili extension page-a.
// 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 sinhrono. Da bi se onMessage event handler prilagodio za asinhrono izvršavanje sendResponse(), neophodno je ubaciti return true;.
Važna napomena je da u scenarijima gde više stranica prima onMessage događaje, prva stranica koja pozove sendResponse() za određeni događaj biće jedina koja može uspešno isporučiti odgovor. Svi naknadni odgovori na isti događaj neće biti uzeti u obzir.
Pri kreiranju novih ekstenzija, trebalo bi preferirati promises umesto callbacks. Kada se koriste callbacks, funkcija sendResponse() važi samo ako je pozvana direktno u sinhronom kontekstu, ili ako event handler označi asinhronu operaciju vraćanjem true. Ako nijedan handler ne vrati true ili ako je sendResponse() uklonjen iz memorije (garbage-collected), callback povezan sa sendMessage() će biti pozvan podrazumevano.
Native Messaging
Ekstenzije pregledača takođe omogućavaju komunikaciju sa binaries in the system via stdin. Aplikacija mora instalirati json koji to navodi u json-u poput:
{
"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 ka runtime.connectNative() ili runtime.sendNativeMessage() da bi se komuniciralo sa aplikacijom iz pozadinskih skripti ekstenzije pregledača. path je putanja do binarne datoteke, postoji samo 1 važeći type koji je stdio (koristi stdin i stdout) a allowed_origins označava ekstenzije koje mu mogu pristupiti (i ne može sadržati wildcard).
Chrome/Chromium će tražiti ovaj json u nekim Windows registry i na nekim putanjama na macOS i Linuxu (više informacija u docs).
Tip
Ekstenzija pregledača takođe treba da ima deklarisanu
nativeMessaingdozvolu kako bi mogla da koristi ovu komunikaciju.
Ovako izgleda kod pozadinske skripte koja šalje poruke native aplikaciji:
chrome.runtime.sendNativeMessage(
"com.my_company.my_application",
{ text: "Hello" },
function (response) {
console.log("Received " + response)
}
)
In this blog post, predložen je ranjiv obrazac koji zloupotrebljava native messages:
- Browser extension ima wildcard pattern za content script.
- Content script prosleđuje
postMessageporuke background script-u koristećisendMessage. - Background script prosleđuje poruku native application koristeći
sendNativeMessage. - Native application rukuje porukom na opasan način, što vodi do code execution.
I u okviru toga je dat primer kako se sa bilo koje stranice dođe do RCE zloupotrebom ekstenzije pretraživača.
Osetljive informacije u memoriji/Code/Clipboard
Ako Browser Extension čuva sensitive information inside it’s memory, to može biti dumped (posebno na Windows mašinama) i searched za te informacije.
Stoga se memorija Browser Extension-a ne sme smatrati sigurnom i sensitive information kao što su kredencijali ili mnemonic phrases ne bi trebalo čuvati.
Naravno, ne stavljajte sensitive information in the code, jer će biti public.
Za dump-ovanje memorije iz browser-a možete dump the process memory ili otići u settings ekstenzije i kliknuti na Inspect pop-up -> u sekciji Memory -> Take a snaphost i koristiti CTRL+F da pretražite snapshot za osetljive informacije.
Štaviše, veoma osetljive informacije kao što su mnemonic keys ili lozinke ne bi trebalo da dozvole da budu kopirane u clipboard (ili bar ukloniti ih iz clipboard-a nakon nekoliko sekundi), jer tada procesi koji nadgledaju clipboard mogu da ih dohvate.
Loading an Extension in the Browser
- Download ekstenziju pretraživača & unzip-ujte
- Idite na
chrome://extensions/i enableDeveloper Mode - Kliknite na
Load unpackeddugme
U Firefox idite na about:debugging#/runtime/this-firefox i kliknite na Load Temporary Add-on dugme.
Getting the source code from the store
Izvorni kod Chrome ekstenzije može se dobiti na nekoliko načina. Ispod su detaljna objašnjenja i instrukcije za svaku opciju.
Download Extension as ZIP via Command Line
Izvorni kod Chrome ekstenzije može se preuzeti kao ZIP fajl koristeći command line. Ovo podrazumeva korišćenje curl da se preuzme ZIP fajl sa specifičnog URL-a i zatim ekstraktovanje sadržaja ZIP fajla u direktorijum. Evo koraka:
- Zamenite
"extension_id"stvarnim ID-em ekstenzije. - Execute the following commands:
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 website
Koristite CRX Viewer ekstenziju
Još jedan praktičan metod je korišćenje Chrome Extension Source Viewer, koji je open-source projekat. Može se instalirati iz Chrome Web Store. Izvorni kod viewer-a je dostupan u njegovom GitHub repository.
Pregledajte izvor lokalno instalirane ekstenzije
Chrome ekstenzije instalirane lokalno takođe se mogu pregledati. Evo kako:
- Pristupite Chrome lokalnom profilu tako što ćete otići na
chrome://version/i pronaći polje “Profile Path”. - Idite u podfolder
Extensions/unutar direktorijuma profila. - Ovaj folder sadrži sve instalirane ekstenzije, obično sa njihovim izvornih kodom u čitljivom formatu.
Da biste identifikovali ekstenzije, možete mapirati njihove ID-jeve na imena:
- Omogućite Developer Mode na stranici
about:extensionsda vidite ID-jeve svake ekstenzije. - U okviru foldera svake ekstenzije, fajl
manifest.jsonsadrži čitljivo poljename, što vam pomaže da identifikujete ekstenziju.
Koristite fajl arhiver ili unpacker
Idite na Chrome Web Store i preuzmite ekstenziju. Fajl će imati .crx ekstenziju. Promenite ekstenziju fajla sa .crx na .zip. Koristite bilo koji fajl arhiver (kao WinRAR, 7-Zip, itd.) da ekstrahujete sadržaj ZIP fajla.
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…”. Navigirajte do direktorijuma vaše ekstenzije. Ovo ne preuzima izvorni kod, ali je korisno za pregled i modifikaciju koda već preuzete ili razvijene ekstenzije.
Chrome extension manifest dataset
Da biste pokušali da pronađete ranjive browser ekstenzije možete koristiti https://github.com/palant/chrome-extension-manifests-dataset i proveriti njihove manifest fajlove za potencijalne znake ranjivosti. Na primer, da biste proverili ekstenzije sa više od 25000 korisnika, content_scripts i dozvolom nativeMessaing:
# 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')"
Post-exploitation: Forced extension load & persistence (Windows)
Stealthy tehnika za backdoor-ovanje Chromium tako što se direktno edituju per-user Preferences i falsifikuju validni HMACs, zbog čega browser prihvata i aktivira arbitrarni unpacked extension bez promptova ili flagova.
Forced Extension Load Preferences Mac Forgery Windows
Detecting Malicious Extension Updates (Static Version Diffing)
Supply-chain kompromisi često dolaze kao malicious updates prethodno benignih ekstenzija. Praktičan, low-noise pristup je da uporedite novi extension package sa poslednjom known-good verzijom koristeći static analysis (na primer, Assemblyline). Cilj je da se alarmira na high-signal delte umesto na bilo koju promenu.
Workflow
- Submit both versions (old + new) to the same static-analysis profile.
- Flag new or updated background/service worker scripts (persistence + privileged logic).
- Flag new or updated content scripts (DOM access and data collection).
- Flag new permissions/host_permissions added in
manifest.json. - Flag new domains extracted from code (potential C2/exfil endpoints).
- Flag new static-analysis detections (npr. base64 decode, cookie harvesting, network-request builders, obfuscation patterns).
- Flag statistical anomalies kao što su oštri skokovi entropije ili outlier z-scores u izmenjenim skriptama.
Detecting script changes accurately
- New script added → detektovati preko
manifest.jsondiff. - Existing script modified (manifest unchanged) → uporediti per-file hashes iz extracted file tree (npr. Assemblyline
Extractoutput). Ovo detektuje stealthy izmene postojećih workers ili content skripti.
Pre-disclosure detections
Da bi se izbegle “easy mode” detekcije zasnovane na već-known IOCs, onemogućite threat-intel-fed servise i oslonite se na intrinzične signale (domains, heuristic signatures, script deltas, entropy anomalies). Ovo povećava šanse da se otkriju malicious updates pre javnog izveštavanja.
Example high-confidence alert logic
- Low-noise combo: new domains + new static-analysis detections + updated background/service worker + updated or added content scripts.
- Broader catch: new domain + new or updated background/service worker (veći recall, više noise).
Key Assemblyline services for this workflow:
- Extract: raspakuje extension i daje per-file hashes.
- Characterize: računa karakteristike fajlova (npr. entropy).
- JsJAWS / FrankenStrings / URLCreator: izvlače JS heuristike, stringove i domene za diff između verzija.
Security Audit Checklist
Iako Browser Extensions imaju limited attack surface, neke od njih mogu sadržati vulnerabilities ili potencijalna poboljšanja za hardening. Sledeći su najčešći:
- Ograničiti koliko god je moguće tražene
permissions - Ograničiti koliko god je moguće
host_permissions - Koristiti snažan
content_security_policy - Ograničiti koliko god je moguće
externally_connectable; ako nije potrebno, ne ostavljati podrazumevano, navesti{} - Ako je ovde pomenut URL vulnerable to XSS or to takeover, napadač će moći da šalje poruke background scriptovima direktno. Veoma moćan bypass.
- Ograničiti koliko god je moguće
web_accessible_resources, čak i na prazno ako je moguće. - Ako
web_accessible_resourcesnije none, proveriti za ClickJacking - Ako bilo koja komunikacija ide iz extension ka web page, proveriti XSS ranjivosti koje nastaju u toj komunikaciji.
- Ako se koriste Post Messages, proveriti za Post Message vulnerabilities.
- Ako Content Script pristupa DOM detaljima, proveriti da li ne uvodi XSS ako budu izmenjeni od strane web-a
- Obratiti posebnu pažnju ako je ova komunikacija uključena i u Content Script -> Background script communication
- Ako background script komunicira preko native messaging, proveriti da li je komunikacija secure i da li se sanitizuju podaci
- Senzitivne informacije ne bi trebalo da se čuvaju unutar koda Browser Extension-a
- Senzitivne informacije ne bi trebalo da se čuvaju u memoriji Browser Extension-a
- Senzitivne informacije ne bi trebalo da se čuvaju nezaštićeno u file system-u
Browser Extension Risks
- Aplikacija https://crxaminer.tech/ analizira neke podatke kao što su permissions koje browser extension zahteva kako bi dala nivo rizika korišćenja ekstenzije.
Tools
Tarnish
- Skida bilo koji Chrome extension sa datog Chrome webstore linka.
- manifest.json viewer: jednostavno prikazuje JSON-prettified verziju manifest-a extension-a.
- Fingerprint Analysis: detekcija web_accessible_resources i automatska generacija Chrome extension fingerprinting JavaScript-a.
- Potential Clickjacking Analysis: detekcija HTML stranica extension-a sa web_accessible_resources directive. One su potencijalno ranjive na clickjacking u zavisnosti od svrhe stranica.
- Permission Warning(s) viewer: prikazuje listu svih Chrome permission prompt upozorenja koja će se pojaviti pri pokušaju korisnika da instalira extension.
- Dangerous Function(s): prikazuje lokaciju opasnih funkcija koje bi napadač mogao eksploatisati (npr. innerHTML, chrome.tabs.executeScript).
- Entry Point(s): pokazuje gde extension prima user/external input. Korisno za razumevanje surface area i traženje potencijalnih tačaka za slanje maliciously-crafted podataka extension-u.
- I Dangerous Function(s) i Entry Point(s) skeneri za generisane alarme prikazuju:
- Relevantni kod snippeta i liniju koja je izazvala alert.
- Opis problema.
- Dugme “View File” za pregled celog izvornog fajla koji sadrži kod.
- Putanju alertovanog fajla.
- Pun Chrome extension URI alertovanog fajla.
- Tip fajla, poput Background Page script, Content Script, Browser Action, itd.
- Ako je ranjiva linija u JavaScript fajlu, putanje svih stranica gde je uključen kao i tip tih stranica i web_accessible_resource status.
- Content Security Policy (CSP) analyzer and bypass checker: ukazuje na slabosti u CSP-u vaše ekstenzije i takođe osvetljava potencijalne načine za bypass zbog whitelisted CDN-ova, itd.
- Known Vulnerable Libraries: koristi Retire.js za proveru korišćenja poznato-ranjivih JavaScript biblioteka.
- Preuzimanje extension-a i formatiranih verzija.
- Preuzimanje originalnog extension-a.
- Preuzimanje beautified verzije extension-a (auto prettified HTML i JavaScript).
- Automatsko keširanje rezultata skeniranja; prvo pokretanje traje duže, ali pri ponovnom pokretanju (ako extension nije ažuriran) biće skoro instant zbog cache-a.
- Linkable Report URLs, lako podeliti izveštaj o extension-u generisan od tarnish-a.
Neto
Project Neto je Python 3 paket osmišljen da analizira i otkrije skrivene osobine browser plugins i extension-a za poznate browsere kao što su Firefox i Chrome. Automatizuje proces unzip-ovanja pakovanih fajlova kako bi izvukao te osobine iz relevantnih resursa u extension-u kao što su manifest.json, localization folders ili Javascript i HTML source fajlovi.
References
- Thanks to @naivenom for the help with this methodology
- 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/24/attack-surface-of-extension-pages/
- https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/
- 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/mv2/background-pages
- https://thehackerblog.com/kicking-the-rims-a-guide-for-securely-writing-and-auditing-chrome-extensions/
- https://gist.github.com/LongJohnCoder/9ddf5735df3a4f2e9559665fb864eac0
- https://redcanary.com/blog/threat-detection/assemblyline-browser-extensions/
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.


