
Uno scenario Proof of concept per lo sfruttamento del buffer overflow GO WASM di CVE2021-38297
WebAssembly (WASM) funge da formato di istruzioni binarie eseguibile nella maggior parte dei browser moderni. Agisce come target di compilazione per vari linguaggi ad alto livello come C, C++, Rust e GO, consentendo di scrivere codice in questi linguaggi e compilarlo in WASM.
La CVE-2021-38297 evidenzia un bug critico nella compilazione e nel caricamento da parte di GO dei binari WASM compilati con GO. La vulnerabilità risiede nel loader JS wasm (wasm_exec.js) fornito da GO, che consente il caricamento di binari WASM con dati senza restrizioni nell'argomento argv. Poiché argv è memorizzato nella memoria lineare di WASM, attori malintenzionati potrebbero sfruttare questo comportamento per sovrascrivere la memoria lineare del programma WASM compilato con GO tramite un input argv eccessivamente grande.
Questa vulnerabilità era presente nelle versioni di GO precedenti alla 1.17.2.
Questa prova di concetto presenta un'applicazione di social media, Vuln-Twitter, che consente a più utenti di pubblicare contenuti e commenti. Il server web, basato su Node.js, utilizza SQLite per memorizzare i dati di post e commenti.
Il front-end impiega semplice JavaScript insieme a un modulo GO WASM chiamato wordprocessor.wasm. Questo modulo espone metodi come toLeetSpeak, che trasforma le stringhe di input in "LeetSpeak" (ad esempio, "Hello!" diventa "h3ll0!").
I moduli GO WASM aiutano a visualizzare post e commenti in LeetSpeak.

Durante il processo di rendering del front-end, quando riceve post e commenti dal server, ogni commento viene renderizzato in "LeetSpeak" utilizzando il modulo GO WASM. Il commento di ogni post viene passato come parte della variabile argv dopo il caricamento del modulo GO WASM.
Inoltre, nel modulo GO esiste un metodo, processSharedVar(), progettato per leggere la stringa situata all'indirizzo 0x5000 e convertirla in un discorso semplificato (ad esempio, "How are you?" diventa "How r u?"). Il post originale viene esplicitamente aggiunto a 0x5000 nella memoria lineare per essere accessibile a questo metodo, modificando il contenuto del post.
Fai riferimento alla sezione di codice che fa lo stesso:

Diagramma della memoria lineare WASM durante il rendering di un commento:

In sintesi:
argv e i post all'indirizzo di memoria 0x5000.toLeetSpeak e processSharedVar vengono utilizzate rispettivamente per il contenuto dei commenti e dei post.Considerando la mancanza di controlli sulla dimensione di argv evidenziata da CVE-2021-38297, emerge una potenziale minaccia. Se un utente malintenzionato commenta con un commento eccessivamente grande su un post che non possiede, questo commento verrà passato attraverso argv durante il rendering. Non essendoci un limite di dimensione, il contenuto all'indirizzo 0x5000 (che rappresenta il post originale) diventa suscettibile di sovrascrittura.
Sfruttando questa falla, un utente malintenzionato modifica effettivamente il contenuto del post originale, in modo simile a un attacco Stored XSS. Successivamente, quando altri visualizzano la pagina, il contenuto alterato viene mostrato, perpetuato dalla logica di front-end condivisa applicata al rendering per tutti, con il risultato che il post sovrascritto è visibile a tutti.

Nota: per riprodurre questo scenario devi installare localmente la versione go1.17.1 di go, che è la versione vulnerabile utilizzata in questo scenario. Puoi fare riferimento alla documentazione ufficiale di go su come installare versioni specifiche di go.
Ora proviamo a riprodurre lo scenario sopra descritto:
git clone [email protected]:gkrishnan724/CVE-2021-38297.git && cd vuln-twitternpm install per installare tutte le dipendenzenpm run resetDB che inizializzerà il database con alcuni post e commenti.npm run dev che avvierà il server locale, apri localhost:3000 in un browser e dovresti vedere una pagina di login.Ora accediamo con un account malintenzionato usando le credenziali username: I_CANT_HACK, password: hacker; una volta effettuato l'accesso, dovresti vedere il feed con alcuni post.
Questo post sembra piuttosto interessante:
Amazon: ready 4 black friday? https://www.amazon.com/blackfriday
E se, usando la tecnica sopra descritta, riuscissimo a sovrascrivere il post di Amazon.com per farlo puntare a un link malintenzionato?
Fai riferimento al file exploit.txt: contiene il commento riempito con padding di "A" in modo da sovrascrivere tutto fino all'indirizzo 0x5000; alla fine puoi vedere il testo ready for black friday? https://evil.com/blackfriday. Se copiamo questo testo e lo commentiamo sul post precedente, dovremmo essere in grado di sovrascrivere il post originale con il testo sopra.
Provateci voi stessi e vedrete :)

In questa applicazione ho anche fornito uno script di patch, che utilizza una versione più recente di go:
npm run patchServerQuesto dovrebbe ricompilare il file go con la nuova versione e avviare il server con la versione patchata.
Ora dovresti notare che il post non viene sovrascritto e, se osservi la console, vediamo invece un errore Argument length too long.

Abbiamo dimostrato uno scenario in cui lo sfruttamento di un buffer overflow WASM sulla memoria lineare ci ha permesso di eseguire un attacco Stored XSS. Tuttavia, è essenziale notare la specificità di questo exploit: richiedeva di manipolare un testo a un indirizzo hardcoded nella memoria lineare. Nelle applicazioni web reali, scoprire vulnerabilità di questo tipo può essere estremamente difficile a causa di questo livello di specificità. Inoltre, sovrascrivere dati arbitrari nella memoria lineare senza causare un crash di sistema è complesso, soprattutto quando si ha a che fare con i moduli e i dati interni di GO, in gran parte a causa della mancanza di documentazione completa sul layout di memoria di GO.
In base alla nostra comprensione, riteniamo che il layout della memoria lineare di GO sia quello illustrato di seguito:

Sebbene questo sfruttamento introduca interessanti vettori di attacco nello sviluppo web, in particolare all'interno di WASM, introduce anche rischi di sicurezza intrinseci associati ai linguaggi di programmazione. Ad esempio, si consideri uno scenario in cui un programma C viene compilato in WASM. Se il programma C originale presenta overflow o vulnerabilità, questi rischi si trasferiscono nell'ambiente WASM, esponendolo a vulnerabilità e minacce simili.
Siamo studenti della Carnegie Mellon University e abbiamo presentato questa prova di concetto della CVE in una delle nostre classi (18-739D Hacking101). Puoi fare riferimento alla nostra presentazione qui: GOWasm.pptx