Monday, May 18, 2015

Writeup: Coding 1 @ DEFCON CTF Quals 2015

This was the task. Connect to remote host, receive initial register state and instructions in binary. 


Not pretty, but I solved this using python, c and gdb.

coding1sc.c code, compile: gcc -fno-stack-protector -z execstack coding1sc.c -o coding1sc
#include
int main(int argc, char **argv)
{
    int fp;
    char buffer[512];
    fp = fopen(argv[1], "rb");
    fread(buffer, sizeof(buffer), 1, fp);
    fclose(fp);
    int (*func)();
    func = (int (*)()) buffer;
    (int)(*func)();
    return 0;
}
coding1.gdb script
break *0x400649
commands
    print $rax
    print $rbx
    print $rcx
    print $rdx
    print $rsi
    print $rdi
    print $r8
    print $r9
    print $r10
    print $r11
    print $r12
    print $r13
    print $r14
    print $r15
    c
end 
r coding1.bin
coding1.py
import commands
import socket
import re
import os 
def rv(reg, line):
    return re.search('%s=0x([0-9a-f]+)' % reg, line).group(1).zfill(16) 
def rv2(reg, line):
    return re.search('\$%s = (0x[0-9a-f]+)' % reg, line).group(1) 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('catwestern_631d7907670909fc4df2defc13f2057c.quals.shallweplayaga.me', 9999)) 
data = s.recv(1024)
rax = rv('rax', data)
rbx = rv('rbx', data)
rcx = rv('rcx', data)
rdx = rv('rdx', data)
rsi = rv('rsi', data)
rdi = rv('rdi', data)
r8 = rv('r8', data)
r9 = rv('r9', data)
r10 = rv('r10', data)
r11 = rv('r11', data)
r12 = rv('r12', data)
r13 = rv('r13', data)
r14 = rv('r14', data)
r15 = rv('r15', data) 
inst = '\x48\xb8' + rax.decode('hex')[::-1]
inst += '\x48\xbb' + rbx.decode('hex')[::-1]
inst += '\x48\xb9' + rcx.decode('hex')[::-1]
inst += '\x48\xba' + rdx.decode('hex')[::-1]
inst += '\x48\xbe' + rsi.decode('hex')[::-1]
inst += '\x48\xbf' + rdi.decode('hex')[::-1]
inst += '\x49\xb8' + r8.decode('hex')[::-1]
inst += '\x49\xb9' + r9.decode('hex')[::-1]
inst += '\x49\xba' + r10.decode('hex')[::-1]
inst += '\x49\xbb' + r11.decode('hex')[::-1]
inst += '\x49\xbc' + r12.decode('hex')[::-1]
inst += '\x49\xbd' + r13.decode('hex')[::-1]
inst += '\x49\xbe' + r14.decode('hex')[::-1]
inst += '\x49\xbf' + r15.decode('hex')[::-1] 
data = s.recv(1024)
bytes = int(re.search('About to send (\d+) bytes', data).group(1))
inst += data[-bytes:]
f = open('coding1.bin', 'wb')
f.write(inst)
f.close() 
o = commands.getoutput('gdb ./coding1sc < coding1.gdb') 
final = 'rax=%s\r\n' % rv2('1', o)
final += 'rbx=%s\r\n' % rv2('2', o)
final += 'rcx=%s\r\n' % rv2('3', o)
final += 'rdx=%s\r\n'  % rv2('4', o)
final += 'rsi=%s\r\n' % rv2('5', o)
final += 'rdi=%s\r\n' % rv2('6', o)
final += 'r8=%s\r\n' % rv2('7', o)
final += 'r9=%s\r\n' % rv2('8', o)
final += 'r10=%s\r\n' % rv2('9', o)
final += 'r11=%s\r\n' % rv2('10', o)
final += 'r12=%s\r\n' % rv2('11', o)
final += 'r13=%s\r\n' % rv2('12', o)
final += 'r14=%s\r\n' % rv2('13', o)
final += 'r15=%s\r\n' % rv2('14', o) 
print 'Sending', final
s.sendall(final) 
print s.recv(1024) 
s.close()
Let's use all this.

No comments:

Post a Comment