Методологија Пентестинга Додатака за Прегледаче

Reading time: 26 minutes

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)

Podržite HackTricks

Основне Информације

Додаци за прегледаче су написани у JavaScript-у и учитава их прегледач у позадини. Има свој DOM али може да интерагује са DOM-овима других сајтова. То значи да може угрожавати повјерљивост, интегритет и доступност (CIA) других сајтова.

Главне Компоненте

Изгледи додатака изгледају најбоље када су визуализовани и састоје се од три компоненте. Погледајмо сваку компоненту детаљно.

http://webblaze.cs.berkeley.edu/papers/Extensions.pdf

Скрипте Садржаја

Свака скрипта садржаја има директан приступ DOM-у једне веб странице и тиме је изложена потенцијално злонамерном улазу. Међутим, скрипта садржаја не садржи дозволе осим способности да шаље поруке основи додатка.

Основна Структура Додатка

Основна структура додатка садржи већину привилегија/приступа додатка, али основна структура додатка може да интерагује са веб садржајем само преко XMLHttpRequest и скрипти садржаја. Такође, основна структура додатка нема директан приступ хост машини.

Нативна Бинарна

Додаци омогућавају нативну бинарну датотеку која може приступити хост машини са пуном привилегијом корисника. Нативна бинарна интерагује са основном структуром додатка преко стандардног Netscape Plugin Application Programming Interface (NPAPI) који користе Flash и други додаци за прегледаче.

Границе

caution

Да би добио пуне привилегије корисника, нападач мора убедити додатак да проследи злонамерни улаз из скрипте садржаја у основну структуру додатка и из основне структуре додатка у нативну бинарну.

Свака компонента додатка је одвојена од других јаким заштитним границама. Свака компонента ради у одвојеном процесу оперативног система. Скрипте садржаја и основне структуре додатка раде у sandbox процесима недоступним већини услуга оперативног система.

Штавише, скрипте садржаја су одвојене од својих повезаних веб страница извођењем у одвојеном JavaScript хипу. Скрипта садржаја и веб страница имају приступ истом основном DOM-u, али се двоје никада не размењују JavaScript показиваче, спречавајући цурење JavaScript функционалности.

manifest.json

Chrome додатак је само ZIP фасцикла са .crx екстензијом датотеке. Основна структура додатка је 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).

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

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.

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, a za Firefox, MDN 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 za stranicu u koju se skripte umetnu. Ove dozvole mogu se obezbediti ili zahtevom unutar manifest-a 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"
}
}
  • 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 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 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:

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:

BrowExt - permissions & host_permissions

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:

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:

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:

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:

BrowExt - ClickJacking

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

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

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.

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

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:

PostMessage Vulnerabilities

Iframe

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

BrowExt - XSS Example

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:

BrowExt - XSS Example

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:

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 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() ili runtime.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).

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

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. 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 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 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
  • Ako se bilo koja komunikacija dešava od ekstenzije do web stranice, proverite za XSS ranjivosti uzrokovane u komunikaciji.
  • Ako se koriste Post Messages, proverite za Post Message ranjivosti.
  • 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/ 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

  • 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 ekstenzija.
  • 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, 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 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 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

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

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)

Podržite HackTricks