Protostar – Heap Buffer Overflow – Heap 1

Rispetto al precedente livello, in questo caso il focus inizia ad essere sullo heap e sulla sua struttura, ed andremo quindi a comprendere meglio come è fatto e come è possibile, ovviamente, exploitarlo.

Heap 1

Codice Heap 1

Come per lo scorso esercizio, andiamo ad inserire un breakpoint alla fine del codice (riga 35) e eseguiamo dentro gdb con il comando r AA BB. Dopodiché analizziamo lo heap

Contenuto dello heap

Si può notare che al suo interno abbiamo:

  • 0x00000001: è la variabile priority dello struct internet i1, assegnata a riga 24
  • 0x0804b018: è il puntatore all’array name di i1, che vale 0x00004141 (AA)
  • 0x00000002: è la variabile priority dello struct internet i2, assegnata a riga 28
  • 0x0804b038: è il puntatore all’array name di i2, che vale 0x00004242 (BB)

Ora, osservando la riga 31 e 32 e la struttura appena analizzata, possiamo ipotizzare che l’overflow avvenga proprio durante il primo strcpy, in quanto se andiamo ad inserire più caratteri di quanti l’array name ne contenga (8), dovremmo riuscire a sovrascrivere la struct i2. Facciamo una prova con ltrace

i2.name punta a 0x41414141

Ed ecco che, come si può vedere, ora il puntatore dentro lo strcpy vale 0x41414141. Andando ad indagare con GDB e lo stesso payload

Contenuto dello heap

Non esiste più il puntatore alla variabile i2.name ed il programma è andato in crash. Ma come possiamo sfruttare questo overflow per avere un exploit funzionante?

Per prima cosa dobbiamo calcolare l’offset in modo tale da sovrascrivere l’indirizzo in maniera precisa, ed è presto detto.

Calcolo dell’offset

In questo modo, abbiamo calcolato la differenza tra la posizione del puntatore a i2.name (0x804b02c) e la posizione di i1.name (0x0804b018). Facciamo un test rapido per vedere se è giusto con il payload

gdb-peda$   r `perl -e 'print "A"x20 . "BBBB"' CC
Offset calcolato correttamente

Viene sovrascritto in maniera perfetta.

Ora che abbiamo trovato il punto da sovrascrivere, dobbiamo trovare quale indirizzo sovrascrivere. Ci potrebbero essere più vie, vediamone un paio.

Metodo 1 – GOT

Un file ELF è composto da più sezioni, ognuna delle quali composta dai propri dati e dalle proprie peculiarità. Ad esempio, se guardiamo quelle di heap1

Sezioni di heap1

ne abbiamo molteplici,come:

  • .text, che contiene la maggior parte del codice del programma
  • .rodata, che contiene le costanti
  • .data, che contiene le variabili inizializzate all’inizio
  • .plt, .got e .plt.got che si occupano del cosidetto Lazy Binding.

Il Lazy Binding si assicura sostanzialmente che un dynamic linker non perda tempo a cercare tutte le librerie necessarie ad un programma ma solo quelle che sono necessarie a runtime. Questa procedura è implementata grazie a due sezioni:

  1. Procedure Linkage Tabel (.plt): è utilizzato per chiamare procedure/funzioni esterne il cui indirizzo non è noto al momento del linking e che deve essere risolto dal linker dinamico al momento dell’esecuzione.
  2. Global Offset Table (.got):  esso mappa i simboli nel codice ai loro corrispondenti indirizzi di memoria assoluti per facilitare l’esecuzione dello stesso
GOT e PLT

[Per chi non avesse chiaro il procedimento, consiglio questo ottimo articolo]

Ma quindi, se andassimo a sovrascrivere sul puntatore a i2.name la chiamata a printf della funzione winner?

Prima di tutto, con GDB-Peda analizzo la sezione GOT dell’eseguibile

Contenuto di GOT

Una volta identificata, dovremo andare ad inserire quale indirizzo andremo a far chiamare la printf. Per ricapitolare l’idea è:

  1. Sovrascrivere l’indirizzo di memoria a cui punta i2.name con l’indirizzo della printf presente nella GOT
  2. Dentro la GOT, inserire l’indirizzo di memoria che vogliamo far stampare alla printf, quindi la funzione winner

Troviamo winner con objdump

osboxes@osboxes:~/Desktop/Protostar$   objdump -d heap1|grep winner 080484cb winner:
Esecuzione con il payload appena creato

Sembra non avere funzionato. Osservando meglio la GOT, oltre ad una printf c’è anche una puts. Proviamo con quella

Bingo!

Analizzando dentro GDB, possiamo vedere il giro completo che siamo riusciti a creare

Chain completa del payload

Metodo 2 – Return Address

Ammetto di aver lasciato il metodo due dopo GOT perché decisamente più semplice rispetto al precedente. In questo caso, possiamo semplicemente sovrascrivere il puntatore a i2.name con l’indirizzo del return address e successivamente far puntare ad esso la funzione winner. Procedendo sempre per passi, dobbiamo quindi:

  1. Trovare l’indirizzo a cui punta RET e usarlo per sovrascriverlo su *i2.name
  2. Iniettare subito dopo l’indirizzo della funzione winner

Inseriamo un breakpoint a main e troviamo EIP

Comando info frame

Ora, ci basta sostituire questo indirizzo con quello di GOT del precedente payload

Esecuzione del payload creato

Ma sembra non funzionare. Non sono riuscito a capire come mai, e ho iniziato a sparare nel mucchio trovando poi l’indirizzo di EIP corretto (0xbffff60c)

Bingo!

Cosa molto simile fuori da GDB, in quanto ho dovuto modificare l’indirizzo del return address in 0xbffff67c per ottenere un exploit funzionante

Esercizio risolto

Se sapete come mai questo comportamento di GDB commentate pure!

Conclusioni

Già con questo esercizio abbiamo approfondito molti più argomenti e l’heap inizia ad essere un pelo più chiaro. Gli approfondimenti li lasciamo per il prossimo esercizio, già in questo di cose da studiare ne sono spuntate!

Hits: 602

Facebooktwitterredditlinkedintumblrmail

L’articolo Protostar – Heap Buffer Overflow – Heap 1 proviene da HackTips.

HackTips


Stai cercando prodotti per l’hacking, la sicurezza informatica e il penetration testing? Hai bisogno di bonificare il tuo smartphone, il tuo pc o il tuo sito da virus e malware? Devi rintracciare una persona o recuperare delle informazioni urgenti? Devi riprendere possesso di un account, una mail o di una password che ti hanno sottratto? Vuoi acquistare device già configurati per sperimentare tutte le tecniche di hacking in modo facile e veloce? Hai esigenze particolari in ambito software o hardware? Possiamo aiutarti!

Contattaci subito per avere un aiuto immediato : dettagliaci tramite mail o Whatsapp che tipo di supporto ti occorre e ti invieremo un riscontro immediato!

Compila e invia il modulo qui sotto per inviarci subito una richiesta di supporto

Scrivi il tuo indirizzo email qui

Scrivi qui come possiamo aiutarti - ti supportiamo immediatamente per ogni tua esigenza!

chevron_left
chevron_right