2026CISCN半决赛minidb详解
字数 4125
更新时间 2026-04-22 13:01:55

2026CISCN 半决赛 minidb 漏洞分析与利用教学文档

1. 概述

本教学文档基于一篇关于2026年CISCN(全国大学生信息安全竞赛)半决赛题目 minidb 的二进制安全分析文章。minidb 是一个模拟简易数据库的题目,涉及堆利用、未初始化变量、引用计数等漏洞的综合利用。文档将详细拆解题目的关键数据结构、漏洞原理及完整的利用过程。

2. 核心数据结构分析

理解程序的结构体是分析漏洞的基础。题目中定义了四个关键结构体。

2.1 DbValue 结构体

作用:存储数据库中每个键(key)对应的值(value)的实际数据。
关键成员

  • refcount:引用计数,记录有多少个 key 共享此 valueclone 操作会使其增加;setabortexec 操作会使其减少,当计数为0时会 free 该值。
  • length:记录 value 的实际长度。
  • data:指向真正的 value 内容。

2.2 DbEntry 结构体

作用:对用户暴露的、存储键值对映射的主要结构,进行了简化。
关键成员

  • key:用户通过 SET 命令设置的变量名。
  • value:指向一个 DbValue 结构体的指针。

2.3 TxContext 结构体

作用:在事务(Transaction)模式下,保存单个键修改的上下文信息,主要充当“回滚快照”。
关键成员

  • key:当前事务正在修改的键。
  • old_value:该键在事务开始前的旧值指针。
  • new_value:事务中试图写入的新值指针。
  • has_snapshot:标志位,记录是否为该键保存过快照。

2.4 全局数据库引擎结构体(文中未命名)

作用:连接并保存整个数据库的全局状态,是程序的核心全局对象。
关键成员

  • DbEntry *buckets[64]:哈希桶数组。数据库通过哈希表管理所有 DbEntry
  • TxContext *current_tx:指向当前事务上下文的指针。
  • in_tx:标志位,表示是否处于事务模式。

哈希桶机制补充说明

  • 哈希函数:对键名(key)进行哈希,并只取低6位,因此结果范围是0-63,正好对应64个桶。
  • 冲突处理:哈希到同一桶的 DbEntry 以链表形式连接。
  • 示例:假设有键 a, cat, tmp, user, flag,经过哈希后可能分布如下:
    • 3号桶: flag -> cat -> a
    • 8号桶: tmp
    • 20号桶: user
  • 查找时,先计算键的哈希值找到对应桶,再遍历链表进行精确匹配。

3. 程序主要逻辑与漏洞分析

程序支持 SETGETCLONEMULTIEXECABORT 等命令。

3.1 主逻辑与命令解析

  • main 函数读取用户输入,并根据空格进行两次切割来解析命令和参数。
  • 需要输入如 SET key value 这样的格式。

3.2 漏洞点详解

程序存在多个安全漏洞,以下是详细分析:

1. SET 命令中的释放后重用(UAF)

  • 事务模式下执行 SET 时,存在一个释放路径。
  • 漏洞代码:在释放 old_value 时,代码没有检查其 refcount(引用计数),而是直接调用 free
  • 产生条件:如果这个 old_value 被其他 DbEntry 通过 CLONE 共享(即 refcount > 1),那么直接 free 会导致其他指针变成悬垂指针(Dangling Pointer),形成UAF。
  • 核心影响:释放后,攻击者依然可以通过持有该指针的 CLONE 对象对已释放的内存进行读写操作。

2. CLONE 命令的浅拷贝

  • CLONE 操作实现的是浅拷贝
  • 它不复制实际的 DbValue 数据(data 字段),而是让新的 DbEntry 指向同一个 DbValue 结构体,并增加其 refcount
  • 这与上述SET的漏洞结合,是构造UAF利用链的关键。

3. MULTI 命令的未初始化堆漏洞

  • MULTI 命令会 malloc 一个大小为 0x38TxContext 结构体,并将其设置为当前事务上下文。
  • 漏洞malloc没有对该内存进行初始化TxContext 结构体内的字段(如 keyold_valuehas_snapshot)将包含堆上的残留数据(脏数据)。
  • 后续的 EXECABORT 命令会盲目信任这些未初始化的值。

4. EXEC 命令的任意地址释放

  • EXEC 函数完全信任从当前事务上下文(TxContext *tx)中读取的数据。
  • 它会使用 tx->key 找到记录,并根据 tx->old_value 等字段进行回滚和释放操作。
  • 漏洞利用:通过堆风水等手段,可以控制未初始化的 TxContext 结构体中的 old_value 指针,使其指向任意地址。当 EXEC 被调用时,会尝试释放该地址,造成任意地址释放(Arbitrary Address Free)

5. ABORT 命令的任意地址泄露

  • 类似地,ABORT 函数也信赖未初始化的 TxContext 数据。
  • 它会根据 tx->old_value 等指针进行一些操作,这可以被利用来读取特定地址的内存内容,实现信息泄露(如泄露libc地址、堆地址、栈地址)。

3.3 漏洞总结

  1. UAF漏洞SET 在事务模式中不检查引用计数直接释放 old_value,与 CLONE 的浅拷贝结合,形成释放后重用。
  2. 未初始化堆漏洞MULTI 分配的 TxContext 未初始化,其内容为堆上的残留数据。
  3. 逻辑漏洞EXECABORT 盲目信任未初始化的 TxContext,导致:
    • 通过控制脏数据,利用 EXEC 可实现任意地址释放
    • 通过控制脏数据,利用 ABORT 可实现任意地址读(信息泄露)。

4. 漏洞利用思路与步骤

利用过程需要结合堆风水(Heap Feng Shui)进行精细布局。

4.1 利用准备:理解堆布局

  • SET 命令会申请两个堆块,分别对应 DbEntryDbValue 结构体。需要先分析清楚这两个结构体在内存中的布局和大小。
  • 目标是控制这些堆块,最终劫持 TxContext 结构体。

4.2 利用步骤

第一阶段:泄露堆地址

  1. 利用 SET 的UAF和 CLONE 的浅拷贝,在释放一个 DbValue 后仍保持对其的引用。
  2. 通过 GET 命令读取悬垂指针指向的内存,可以泄露堆管理器的元数据(如 fdbk 指针),从而计算出堆的基地址。

第二阶段:泄露libc地址与栈地址

  1. 在获取堆控制能力后,下一步是劫持一个 DbEntry 结构体。
  2. 通过伪造 DbEntry 的内容,可以使其 value 指针指向全局数据库引擎结构体(g_db_engine)或其他已知结构。
  3. 利用 GET 或程序的其他输出功能,读取这些结构体中的指针。例如,g_db_engine 可能包含指向libc中全局变量的指针(用于泄露libc基址),或者包含栈地址(用于泄露栈布局)。

第三阶段:劫持控制流(以劫持栈为例)

  1. 目标:通过任意地址写,在栈上伪造返回地址或函数指针,最终劫持程序控制流。
  2. 利用任意地址释放(EXEC)和堆溢出等技术,在堆上精心布局,伪造一个 TxContext 结构体。
  3. 控制伪造的 TxContext 中的 old_value 等指针,使其指向栈上的某个关键位置(例如某个函数的返回地址)。
  4. 调用 EXEC,程序会根据伪造的 TxContext 对栈地址进行释放和写入操作,从而破坏栈数据。
  5. 结合信息泄露得到的栈地址和libc中的gadget地址(如 system 地址、one_gadget),最终实现代码执行。

4.3 利用难点

  • 题目没有提供直接的 EDIT 功能,增加了修改内存的难度,必须完全依靠 SETCLONEMULTIEXECABORT 的原生命令来构造利用链。
  • 需要对堆内存布局有非常精准的预测和控制。
  • 逆向工程是前提,必须清晰理解所有结构体关系和整个状态机。

5. 核心要点总结

  1. 逆向定基础:成功利用的前提是完整逆向出 DbValueDbEntryTxContext 及全局引擎等核心结构体,并理解其生命周期和交互逻辑。
  2. 漏洞本质
    • 主漏洞是事务模式下 SET 对引用计数的管理缺失导致的UAF。
    • 漏洞放大器是 MULTI未初始化堆分配,使得攻击者可以通过堆喷等手段控制关键数据结构。
    • 漏洞触发点是 EXEC/ABORT 对不可信输入(未初始化的 TxContext)的无校验使用
  3. 利用链条CLONE(制造多引用) -> SET in tx(触发UAF释放) -> 堆布局/风水 -> 控制未初始化的 TxContext -> 利用 EXEC 进行任意地址写或利用 ABORT 进行信息泄露 -> 最终劫持控制流。
  4. 防御思路(扩展知识):
    • 始终初始化动态分配的内存。
    • 对引用计数进行原子操作和严格检查,确保减到零才释放。
    • 对来自不可信源(如未初始化内存、用户输入)的指针进行有效性校验。
    • 使用更安全的内存分配器(如Scudo, GWP-ASan)增加利用难度。

通过本题的分析,可以深入理解现代堆漏洞利用中如何将多种低级漏洞(UAF、未初始化数据、逻辑缺陷)串联成一条完整的攻击链,这对二进制安全攻防研究具有典型意义。

相似文章
相似文章
 全屏