
Un plugin per Binary Ninja che utilizza hash XFG ottenuti tramite brute force per recuperare prototipi di funzioni precisi
Questa repository contiene script per generare e cercare hash eXtended Flow Guard.
Un articolo esteso su come funziona è disponibile nel numero 22 dell'International Journal Of Proof Of Concept || GTFO.
Il mio lavoro su questa PoC è stato notevolmente semplificato dai ragazzi di Quarkslab, che hanno svolto un ampio reverse engineering delle parti rilevanti del compilatore MS. Il loro approfondito articolo su come vengono calcolati gli hash XFG può essere letto qui: https://blog.quarkslab.com/how-the-msvc-compiler-generates-xfg-function-prototype-hashes.html
Nota: questo in nessun modo "rompe" l'XFG come mitigazione contro gli exploit; semplicemente abusa dei suoi effetti collaterali per illuminare funzioni senza simboli.
In breve, l'XFG come implementato su Windows estende e rende più rigorosa la mitigazione degli exploit Control Flow Guard, limitando le possibili destinazioni delle chiamate di funzione indirette non solo a validi punti di ingresso delle funzioni, ma a funzioni con firma corrispondente. A tale scopo, per ogni funzione viene calcolato un hash XFG e durante l'esecuzione viene effettuato un controllo contro di esso. Gli hash si basano solo sul prototipo della funzione (cioè convenzione di chiamata, argomenti e loro tipi). Come tali, possiamo precalcolarli per tipi noti e successivamente cercarli per funzioni in binari sconosciuti.
Se la ricerca ha successo, possiamo essere certi al 100% del numero esatto e dei tipi di tutti gli argomenti, nonché del valore di ritorno della funzione. Questo può essere estremamente utile per binari e funzioni senza simboli pubblici.
Ti invito a leggere l'articolo completo in PoC||GTFO, servito da un mirror vicino.
Gli script sono:
Per usare questi script, devi prima modificare gen_function_prototypes.py per aggiungere "tipi primitivi", struct o enum specifici per il target che stai esaminando. Inoltre, vorrai scegliere fino a quanti argomenti vuoi forzare con brute force. Fino a 3 richiede un minuto, fino a 4 un giorno...
Dopo che i prototipi di funzione di tutte le combinazioni sono stati generati, vorrai eseguire gen_hash_from_ast.py, che analizzerà il file precedentemente generato riga per riga e genererà il corrispondente hash XFG.
Quando ha terminato, avrai un database SQLite di prototipi di funzione con i loro hash XFG corrispondenti. Un plugin Binary Ninja molto semplice è incluso in xfg_analyzer.py. Quando viene eseguito su un binario protetto da XFG, troverà tutti gli hash XFG, li cercherà nel database e, se viene trovata una corrispondenza, applicherà il nuovo prototipo di funzione alla funzione definita.
Sappi che questa è solo una PoC. Per essere davvero utile, dovrebbe essere generato un database gigante di hash (possibilmente popolato con tutti i nomi di struct/enum dai file di intestazione di Windows) e reso disponibile per ricerche online. Inoltre, espandere questa idea agli hash XFG di C++ sarebbe un progetto molto divertente.
Sentiti libero di usare il codice in questa repository in qualsiasi modo. Se lo trovi utile, mi piacerebbe sentirti.