
Un'informazione interattiva sulla memoria per pwning / exploiting
Da appassionati di pwn, durante le CTF con exploit di heap, abbiamo sempre bisogno di un debugger (es. gdb) per tracciare il layout della memoria. Ma non serve davvero gdb se vogliamo vedere se il layout dell'heap corrisponde o meno alla nostra immaginazione. Spero che questo piccolo strumento ci aiuti a sfruttare più facilmente ;).
HeapInfo è molto utile quando il binario ha limitazioni anti-debugger, ad esempio se è sotto ptrace. HeapInfo funziona lo stesso perché non utilizza ptrace.
Implementato in Ruby perché amo Ruby :P. Ma potrebbe essere implementato in Python (se nessun altro lo farà) in futuro.
Se preferisci pwntools per gli exploit, puoi comunque usare HeapInfo in irb/pry come un piccolo debugger.
Ogni suggerimento su funzionalità o segnalazioni di bug è benvenuto.
HeapInfo è ancora in fase di sviluppo per ulteriori funzionalità, quindi la versione potrebbe cambiare frequentemente :p
$ gem install heapinfo
vittima è tracciata! cioè puoi usare ltrace/strace/gdb e HeapInfo contemporaneamente!dump - Dump della memoria a un indirizzo arbitrario.layouts - Mostra il layout corrente dei bin, molto utile per lo sfruttamento dell'heap.offset - Mostra l'offset tra un dato indirizzo e un segmento. Molto utile per calcolare offset relativi.canary - Recupera il valore dello stack guard!x - Comandi in stile GDB.s - Comandi in stile GDB.find - Comandi in stile GDB.require 'heapinfo'
# ./victim è in esecuzione
h = heapinfo('victim')
# oppure usa h = heapinfo(20568) per specificare un pid
# mostrerà informazioni semplici al caricamento:
# Program: /home/heapinfo/victim PID: 20568
# victim base @ 0x400000
# [heap] base @ 0x11cc000
# [stack] base @ 0x7fff2b244000
# libc-2.19.so base @ 0x7f892a63a000
# ld-2.19.so base @ 0x7f892bee6000
# canary value: 0x84b742f03d94c100
# query sui segmenti
"%#x" % h.libc.base
#=> "0x7f892a63a000"
h.libc.name
#=> "/lib/x86_64-linux-gnu/libc-2.19.so"
"%#x" % h.elf.base
#=> "0x400000"
"%#x" % h.heap.base
#=> "0x11cc000"
NOTA: Quando il processo non viene trovato, la maggior parte dei metodi restituirà nil. Un modo per evitare eventuali errori è racchiudere i metodi all'interno di debug; il blocco verrà ignorato durante lo sfruttamento remoto.
h = heapinfo('remote')
# Processo non trovato
h.pid # nil
# racchiudi con `debug` in modo che nessun errore venga sollevato quando si attacca un servizio remoto
h.debug { fail unless leak_libc_base == h.libc.base }
Interroga il contenuto di un indirizzo specifico.
NOTA: DEVI avere il permesso di allegare un programma, altrimenti il dump fallirà.
cioè /proc/sys/kernel/yama/ptrace_scope impostato a 0 o eseguito come root.
h.debug do
p h.dump(:libc, 8)
#=> "\x7FELF\x02\x01\x01\x00"
p h.dump(:heap, 16)
#=> "\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00"
p h.dump('heap+0x30', 16) # supporta offset!
#=> "\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x00\x00\x00\x00\x00\x00"
p h.dump('heap+0x30 * 3 + 0x8', 16) # e anche formule complesse!
#=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
p h.dump(:program, 8)
#=> "\x7FELF\x02\x01\x01\x00"
p h.dump(0x400000, 8) # o semplicemente fornisci l'indirizzo
#=> "\x7FELF\x02\x01\x01\x00"
end
# esempio non valido:
# h.dump('meow') # nessun segmento del genere
h.layouts :fast

h.layouts :unsorted, :small

h.layouts :tcache

h.offset(0x7fda86fe8670)
# 0xf6670 dopo libc
h.offset(0x1839cd0, :heap) # nome del segmento specifico
# 0x20cd0 dopo heap
h.offset(0x1839cd0)
# 0x20cd0 dopo heap

h.canary.to_s(16)
#=> '84b742f03d94c100'
h.x 8, :heap

Fornisce un cercatore di memoria, più facile da usare rispetto a (ingenuo) gdb.
Supporta la ricerca di interi, stringhe e persino espressioni regolari.
h.find(0xdeadbeef, 'heap+0x10', 0x1000)
#=> 6299664 # 0x602010
h.find(/E.F/, 0x400000, 4)
#=> 4194305 # 0x400001
h.find(/E.F/, 0x400000, 3)
#=> nil
# Ottieni l'offset relativo del risultato della ricerca
h.find('/bin/sh', :libc, rel: true)
#=> 1622391 # 0x18c177
h.offset(h.find('/bin/sh', :libc))
# 0x18c177 dopo libc
HeapInfo attualmente esegue test solo su Ubuntu. Le seguenti sono le versioni di glibc testate: