Ret2csu
https://www.scs.stanford.edu/brop/bittau-brop.pdfInformazioni di Base
ret2csu è una tecnica di hacking utilizzata quando si cerca di prendere il controllo di un programma ma non si riescono a trovare i gadget soliti per manipolare il comportamento del programma.
Quando un programma utilizza determinate librerie (come libc), ha alcune funzioni integrate per gestire come diverse parti del programma comunicano tra loro. Tra queste funzioni ci sono alcune gemme nascoste che possono agire come i nostri gadget mancanti, in particolare una chiamata __libc_csu_init
.
I Gadget Magici in __libc_csu_init
In __libc_csu_init
, ci sono due sequenze di istruzioni (gadget) da evidenziare:
La prima sequenza ci permette di impostare valori in diversi registri (rbx, rbp, r12, r13, r14, r15). Questi sono come slot in cui possiamo memorizzare numeri o indirizzi che vogliamo utilizzare successivamente.
Questo gadget ci permette di controllare questi registri facendo uscire i valori dallo stack e inserendoli al loro interno.
La seconda sequenza utilizza i valori che abbiamo impostato per fare un paio di cose:
Spostare valori specifici in altri registri, preparandoli per essere utilizzati come parametri nelle funzioni.
Effettuare una chiamata a una posizione determinata sommando i valori in r15 e rbx, e moltiplicando rbx per 8.
Forse non conosci nessun indirizzo da scrivere lì e hai bisogno di un'istruzione
ret
. Nota che il secondo gadget finirà anche con unret
, ma dovrai soddisfare alcune condizioni per raggiungerlo:
Le condizioni saranno:
[r12 + rbx*8]
deve puntare a un indirizzo che memorizza una funzione invocabile (se non si ha idea e non si ha pie, è possibile utilizzare la funzione_init
):Se _init si trova a
0x400560
, utilizzare GEF per cercare un puntatore in memoria ad esso e fare in modo che[r12 + rbx*8]
sia l'indirizzo con il puntatore a _init:
rbp
erbx
devono avere lo stesso valore per evitare il saltoCi sono alcuni pop omessi che devi tenere in considerazione
RDI e RSI
Un altro modo per controllare rdi
e rsi
dal gadget ret2csu è accedendo a offset specifici:
Controlla questa pagina per ulteriori informazioni:
pageBROP - Blind Return Oriented ProgrammingEsempio
Utilizzando la chiamata
Immagina di voler fare una syscall o chiamare una funzione come write()
ma hai bisogno di valori specifici nei registri rdx
e rsi
come parametri. Normalmente, cercheresti gadget che impostano direttamente questi registri, ma non ne trovi.
Ecco dove entra in gioco ret2csu:
Imposta i Registri: Usa il primo gadget magico per estrarre i valori dallo stack e inserirli in rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx) e r15.
Usa il Secondo Gadget: Con questi registri impostati, utilizzi il secondo gadget. Questo ti permette di spostare i valori scelti in
rdx
ersi
(da r14 e r13, rispettivamente), preparando i parametri per una chiamata di funzione. Inoltre, controllandor15
erbx
, puoi far sì che il programma chiami una funzione situata all'indirizzo che calcoli e inserisci in[r15 + rbx*8]
.
Hai un esempio che utilizza questa tecnica e la spiega qui, e questo è l'exploit finale che è stato utilizzato:
Si noti che l'exploit precedente non è destinato a fare un RCE
, ma è destinato solo a chiamare una funzione chiamata win
(prendendo l'indirizzo di win
da stdin chiamando gets nella catena ROP e memorizzandolo in r15) con un terzo argomento con il valore 0xdeadbeefcafed00d
.
Bypassare la chiamata e raggiungere ret
L'exploit seguente è stato estratto da questa pagina dove viene utilizzato il ret2csu ma anziché utilizzare la chiamata, sta bypassando i confronti e raggiungendo il ret
dopo la chiamata:
Perché non utilizzare direttamente libc?
Di solito questi casi sono vulnerabili anche a ret2plt + ret2lib, ma a volte è necessario controllare più parametri di quelli facilmente controllabili con i gadget che si trovano direttamente in libc. Ad esempio, la funzione write()
richiede tre parametri e potrebbe non essere possibile trovare gadget per impostare tutti questi direttamente.
Last updated