Simple yet elegent pwn13 min read

Ciao a tutti! È appena finito il ctf HackCon18, quindi possiamo vedere il writeup di questa interessante challenge. Il pwn è basato su due vulnerabilità: la prima è la stringa di formato e la seconda è un semplice buffer overflow, quindi bisognava fare un leak della memoria per ottenere degli indirizzi validi della libc grazie alla stringa di formato (per bypassare l’ASLR), una volta ottenuto un leak calcolare l’indirizzo della system per fare una classica ret2libc.

Il primo step fatto è stato dare un checksec del programma che ci è stato fornito:

Copy to Clipboard

Come possiamo vedere è tutto disabilitato tranne per il fatto che lo stack non è eseguibile. Proviamo ora ad eseguire il binario:

Copy to Clipboard

Ok, notiamo che il processo ritorna l’input che gli abbiamo fornito, proviamo quindi con una stringa di formato:

Copy to Clipboard

infatti ci sono degli indirizzi dello stack del processo. Proviamo ora ad inserire un input più grande:

Copy to Clipboard

Il programma è andato in segmentation fault. Esaminiamo ora con radare2 il programma per vedere cosa fa:

Copy to Clipboard

semplicemente la funzione main prende un input con la scanf, che va poi in overflow, e lo stampa con la printf così da avere la stringa di formato. Continuiamo la nostra ispezione esaminando ora il core dump creato:

Copy to Clipboard

Grazie al core dump ci siamo potuti calcolare la dimensione del buffer prima di andare in overflow. Esaminiamo ora lo stack in cerca di un indirizzo della libc da prendere con la stringa di formato. Per questo scopo facciamo partire il programma in gdb e mettiamo un breakpoint sulla printf poiché noi andremo ad ottenere la porzione dello stack utilizzata dalla printf:

Copy to Clipboard

Perfetto, c’è un indirizzo che punta alla libc_start_main, ma c’è anche un problema: se noi inseriamo un input grande (che ci servirà per sovrascrivere l’indirizzo di ritorno), andremo a sovrascrivere anche questo indirizzo! Quindi dobbiamo cercare un altro indirizzo valido da utilizzare. In particolare c’è 0x00007ffff7a6287d che è all’inizio della nostra stringa di formato, ma solo in remoto! (Non ho ancora capito perché ma inserendo %1$p in remoto otteniamo questo indirizzo, mentre in locale otteniamo un misero 0x1, probabilmente dovuta a qualche differenza nella libc utilizzata). Comunque esaminando lo stack sembra essere l’indirizzo della fflush. Calcoliamo ora la differenza tra questo valore e la libc_start_main per ottenere quest’ultima. Facciamo partire il processo in remoto per ottenere questi due valori:

Copy to Clipboard

dove %1$p è l’offset per ottenere il nostro indirizzo misterioso e %17$p è l’offset per ottenere libc_start_main. La differenza tra questi due indirizzi è:

Copy to Clipboard

Ok, ora abbiamo un indirizzo della libc valido! Ora otteniamo l’indirizzo dell’inizio della libc_start_main e poi cerchiamo l’offset della system e della stringa bin sh. Per questo scopo esaminiamo la libc che ci è stata fornita:

Copy to Clipboard

dove 0x21f45 corrisponde al leak della libc_start_main, che è a 245 byte dall’inizio della funzione. Adesso calcoliamo la base della libc e poi la system e la bin sh. Usiamo libc database per ottenere i vari offset:

Copy to Clipboard

Ora cerchiamo un gadget per inserire bin sh nel registro rdi:

Copy to Clipboard

Ed infine abbiamo tutto il necessario per la scrittura del nostro script:

Copy to Clipboard

Ora runniamo lo script:

Copy to Clipboard

Recent Tweets

For privacy reasons Twitter needs your permission to be loaded.
I Accept
2018-08-17T13:41:00+00:00

About the Author:

Dottore in Informatica. Da sempre appassionato di Linux, reti informatiche, sicurezza e, in modo amatoriale, all’elettronica. Il mio intento è quello di trasmettere le mie conoscenze ad altri appassionati.

Leave A Comment

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.