内核漏洞挖掘技术系列(2)——bochspwn
字数 2302 2025-08-05 11:39:26
内核漏洞挖掘技术:Bochspwn 深度解析
1. Bochspwn 概述
Bochspwn 是由 Google Project Zero 的 j00ru 开发的一款基于 Bochs 模拟器的内核漏洞挖掘工具,主要用于检测 double fetch 漏洞。该工具通过 Bochs 的插桩 API 监控系统范围内的内存访问模式,能够发现 Windows/Linux 等操作系统中的多种内核漏洞。
相关工具:
- bochspwn:检测 double fetch 漏洞
- bochspwn-reloaded:检测未初始化导致的内核信息泄露漏洞
2. Double Fetch 漏洞原理
2.1 基本概念
Double fetch 是一种竞争条件漏洞,其核心原理如下:
- 用户通过系统调用与内核交互
- 内核函数两次从同一用户内存地址读取同一数据:
- 第一次读取:用于验证数据或建立联系
- 第二次读取:实际使用该数据
- 用户空间的恶意线程可以在两次读取之间篡改数据
- 导致内核使用不一致的数据,可能造成:
- 缓冲区溢出
- 信息泄露
- 空指针引用
- 最终导致内核崩溃或提权攻击
2.2 Bochspwn 对 Double Fetch 的定义
在 bochspwn 论文中,double fetch 必须满足以下条件:
- 同一个虚拟地址至少有两次内存读取
- 两次读取操作发生在很短的时间内
- 读取的代码运行在内核态
- 多次读取的虚拟地址必须驻留在内存中并且用户态可写
2.3 典型示例
Windows 系统上的典型 double fetch 代码模式:
// 第一次读取:验证数据
if (user_buffer->size > MAX_SIZE) {
return STATUS_INVALID_PARAMETER;
}
// 第二次读取:使用数据
memcpy(kernel_buffer, user_buffer->data, user_buffer->size);
3. 环境搭建
3.1 系统要求
- 编译环境:Ubuntu 18.10+
- 目标系统:Windows 10 或 Linux(如 Ubuntu Server 18.04.2)
- 工具链:MinGW-w64 交叉编译工具链
3.2 详细步骤
3.2.1 安装依赖
sudo apt-get install g++-mingw-w64 g++ protobuf-compiler
3.2.2 编译 Protobuf 2.5.0
- 下载 Protobuf 2.5.0
- 编译 Windows 版本:
./configure --host=i686-w64-mingw32 --prefix=/usr/i686-w64-mingw32/
make
sudo make install
- 编译 Linux 版本:
./configure
make
sudo make install
- 解决库路径问题:
echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/libprotobuf.conf
sudo ldconfig
3.2.3 编译 Bochs 2.6.9
- 下载 Bochs 2.6.9 和 bochspwn 源代码
- 设置目录结构:
cd bochs-2.6.9/instrument/
mkdir bochspwn
cp bochspwn/instrumentation/* bochspwn/
cp bochspwn/third_party/instrumentation/* bochspwn/
-
添加 Windows 调试库(dbghelp.lib/dbghelp.dll)
-
生成协议文件:
cd bochs-2.6.9/instrument/bochspwn
protoc --cpp_out=. logging.proto
- 配置编译环境:
export MINGW=i686-w64-mingw32
export CXXFLAGS="-O2 -I/usr/${MINGW}/include/ -D_WIN32 -L/usr/${MINGW}/lib -static-libgcc -static-libstdc++ -Wno-narrowing"
export CFLAGS="-O2 -I/usr/${MINGW}/include/ -D_WIN32 -L/usr/${MINGW}/lib"
export LIBS="/usr/${MINGW}/lib/libprotobuf.a instrument/bochspwn/dbghelp.lib"
./configure \
--host=i686-w64-mingw32 \
--enable-instrumentation="instrument/bochspwn" \
--enable-x86-64 \
--enable-e1000 \
--with-win32 \
--without-x \
--without-x11 \
--enable-cpu-level=6 \
--enable-pci \
--enable-pnic \
--enable-fast-function-calls \
--enable-fpu \
--enable-cdrom \
--disable-all-optimizations
- 解决编译问题:
- 重命名
dbghelp.h为DbgHelp.h - 替换
__in和__out为___in和___out - 修改 Makefile 中的
windres为i686-w64-mingw32-windres - 添加
-lws2_32链接选项
- 重命名
3.2.4 准备目标系统
- 安装目标系统(如 Ubuntu Server)
- 更新内核并安装符号包
- 安装 Trinity 或其他覆盖率工具
- 获取内核结构信息(使用 gdb 脚本)
3.2.5 运行 Bochspwn
- 准备 bochsrc.txt 配置文件
- 转换虚拟机磁盘为 RAW 格式
- 启动 Bochs 并运行 Trinity
4. Bochspwn 原理分析
4.1 代码结构
bochspwn 主要包含三个代码目录:
- instrumentation:插桩核心代码
- third_party:第三方依赖
- tools:日志分析工具
4.2 核心工具分析
4.2.1 doubleread.cc
检测 double fetch 的核心逻辑:
- 使用
map<address, vector<log_data_st>>记录内存访问 - 对于每个地址,如果访问次数 >1 则可能为 double fetch
- 关键数据结构:
struct log_data_st {
uint32_t lin; // 线性地址
uint32_t len; // 访问长度
uint32_t repeated; // 重复访问次数
// 其他字段...
};
- 处理流程:
- 跳过 ProbeForWrite 等安全写入
- 记录所有读取操作
- 分析重复访问模式
4.2.2 unhandled_access.cc
检测未处理的内存访问(可能导致本地 DoS):
- 分析 Windows SEH(结构化异常处理)链
- 检查 TryLevel 字段是否为 0xFFFFFFFE(表示无处理)
- 典型漏洞模式:
// 无异常处理的用户内存访问
void vulnerable_function(user_struct* user_ptr) {
// 直接访问用户内存,无 try/except
kernel_buffer = user_ptr->data; // 可能导致崩溃
}
4.2.3 其他工具
- separate.cc:分割大日志文件
- win32_symbolize*:添加符号信息
- print.cc:日志打印
- no_cidll.c:过滤 CI.dll 导致的假阳性
- stat.c:统计访问信息
- count_*:统计调用栈深度和异常处理器
5. 高级技巧与注意事项
-
64位系统支持:
- 使用 x86_64-w64-mingw32 工具链
- 替换为 64 位 dbghelp 库
-
内核结构变化:
- 注意不同内核版本的结构体偏移变化
- 更新 config.txt 中的定义
-
性能优化:
- 使用无 GUI 的服务器版系统
- 调整 Bochs 内存设置
- 合理配置 bochsrc.txt
-
漏洞验证:
- 结合静态分析和动态测试
- 验证发现的潜在漏洞
6. 参考资料
- Bochspwn 漏洞挖掘技术深究(1):Double Fetches 检测
- Bochspwn: Identifying 0-days via system-wide memory access pattern analysis
- Windows Kernel Local Denial-of-Service #1
通过本文的详细指导,您可以成功搭建 bochspwn 环境并理解其工作原理,进而开展内核漏洞挖掘工作。记住在实际操作中要根据目标系统调整配置,并持续关注工具和内核的更新变化。