[原创][writeup]CTFHUB-FastBin Attack
3小时前 209
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
根据IDA静态分析已知存在堆溢出漏洞,且申请的堆大小固定,释放后会进入fastbins,所以考虑通过篡改fastbin->fd来申请fakeChunk,现查找可利用的fd
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
其中0x6020c0
是全局变量heapList
的地址,其中存着每一个heap的指针,如果可以将该指针修改就可以达到任意读/写,并且在heapList
上方存在可利用的内容,通过字节错位将fd
指针定于0x60209d
,内存如下
1 2 3 4 5 6 7 8 9 10 11 12 |
|
可以看到若chunk->fd=0x60209d
时,size
字段为0x7f
即0111 1111
,而其中末4位为标志位高到低分别是PREV_INUSE IS_MMAPPED NON_MAIN_ARENA SIZE_BITS
,既实际大小为0111 0000
即0x70
,由于我们申请的heap大小固定为0x60
,加上字段大小后即0x70
,最终的fastbins
大小分类一致,可用作构造FakeChunk
根据分析可以总结出一下三点:
0x60
,释放后进入fastbins
均属于大小分类0x70
heapList
上方存在可用于构造FakeChunk
的内存区根据分析已知
heap
最终都将进入fastbins->0x70
分类链表中heapList
上方存在可利用内存区用以构造FakeChunk
根据上述条件准备进行以下攻击
edit()
函数溢出并篡改heap#1的fd指针指向0x60209d
fakeChunk->0x60209d
edit()
修改heap#2填充13字节的payload到达0x6020C0
既heapList[0]
并向其中填入[email protected]
show()
函数打印出*heapList[0]
即puts
函数地址并计算出libcBase
edit()
再次修改heap#2以篡改heapList[0]
值为&__malloc_hook
或&__free_hook
edit()
修改heap#0以篡改__malloc_hook
或__free_hook
以执行oneGadget对于glibc堆管理的各类bins详细请参见
CTF竞赛权威指南(Pwn篇)->11.1.3章
以下为简述:
程序中申请的大小为0x60的heap释放后均会进入fastbins->0x70
分类中(由于glibc版本问题所以并不会进入tcache
,调试时请注意使用的glibc版本);
fastbins
是一个后进先出的单链表,除分类中第一个进入的chunk
外的每一个chunk->fd
字段都指向上一个进入fastbins
的chunk
,也即当前chunk#1
被弹出后下一个应该被弹出的chunk#0
,既然这样我们就可以通过申请连续的chunk#0 chunk#1 chunk2
并按顺序释放#chunk2、#chunk1
,此时的chunk1->fd
为#chunk2
,意为当我们再次申请大小为0x60
时会弹出chunk1
并将chunk->fd
作为下一个预备弹出的chunk
此时我们通过edit()
编辑chunk#0
并且使用堆溢出篡改chunk1->fd
使其指向一个fakeChunk
,以达到读写fakeChunk
的目的;注意:该FakeChunk->size需要符合fastbins的大小分类即0x70
,根据上述分析已知在全局变量heapList
上方存在符合条件的FakeChunk
内存区,所以我们将chunk#1->fd
指向该内存区,将其申请到手后可即可结合show() edit()
进行任意读写
可以任意读后即可泄露LibcBase
,将函数got
地址填入heapList[0]
后使用show()
函数即可达到泄露,而将&__malloc_hook
或&__free_hook
填入即可篡改此两个hook的指向,此两个hook的指向在分别在malloc()
和free()
函数调用时被调用,所以我们可以向其中填入oneGadget并再次调用add()
或者delete()
使其执行并且getShell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
|