【论文阅读】HouseFuzz:面向 Linux 固件的服务感知灰盒模糊测试

HouseFuzz:面向 Linux 固件的服务感知灰盒模糊测试


一、背景与意义

背景

1.1 物联网固件安全威胁日趋严峻

  • 路由器、网关、智能家居等设备广泛运行 Linux 固件,成为重要攻击面
  • 固件中的漏洞难以人工发现,亟需自动化漏洞挖掘手段

1.2 模糊测试(Fuzzing)是主流漏洞挖掘手段

  • 通过大量自动生成的输入触发程序异常,发现潜在漏洞
  • 灰盒模糊测试(如 AFL)通过代码覆盖率反馈引导输入变异,效率较高

1.3 固件测试的核心难题:真机难以获得

  • 固件运行依赖特定硬件,无法直接 fuzzing,必须依赖仿真环境
  • 仿真准确度直接决定测试效果

目标

本文目标:设计一套专为 Linux 固件网络服务的服务感知灰盒模糊测试框架 HouseFuzz,解决以下核心问题:

  1. 更完整地识别固件中的网络服务(避免遗漏)
  2. 支持多进程协同的 fuzzing 反馈引导(而非仅监控单进程)
  3. 感知定制化服务协议语义约束,生成高质量测试用例

📌 项目地址:https://github.com/HouseFuzz/HouseFuzz

二、研究现状

2.1 已有灰盒固件模糊测试工作

方向 代表方法 核心特点
系统级仿真 Firmadyne、FirmAE 仿真整个系统,开销大
进程级仿真 FirmAFL、EQUAFL、GREENHOUSE 仅仿真单个目标进程,轻量

2.2 模糊测试阶段的现有方法

环节 现有方法
反馈引导 仅监控单进程代码覆盖率
测试用例生成 标准协议模板 + 随机变异

2.3 本文定位

本文在仿真层 基于 GREENHOUSE 扩展,重点创新在多进程模糊测试框架定制协议感知


三、存在问题 / 挑战(动机)

3.1 核心动机案例:一个典型多进程跨服务漏洞

📷 【插图位置:图1 --- 多进程协作漏洞触发示例代码】

这个缓冲区溢出漏洞需要四步触发,跨越两个进程:

步骤 进程 行为
① 服务初始化 ncc 启动 mini_http,绑定网络端口等待请求
② 请求发送 攻击者 发送恶意 HTTP 数据包
③ 请求处理 mini_http 识别 .cpp 结尾请求,经 IPC 转发给 ncc
④ 漏洞触发 ncc ipc_handler 无长度限制地读取字符串 → 缓冲区溢出

关键观察: 若只盯着 mini_http,永远触发不了 ncc 中的漏洞。


3.2 三大挑战

挑战一:服务仿真不完整
  • 基于白名单方法(如 GREENHOUSE):ncc 不在白名单 → 直接忽略
  • 基于系统仿真(如 FirmAE):遇到异常/中断就停止,服务可能没起完

HouseFuzz 见解: 观察异常流程事件(崩溃/挂起)→ 定位异常代码 → 自动打补丁 → 重新仿真,遍历更多初始化流程


挑战二:多进程反馈引导缺失
  • 现有工具仅以 mini_http 的代码覆盖率为引导
  • ncc 的执行路径完全被忽略 → 无法发现跨进程漏洞

HouseFuzz 见解: 设计用户空间多进程 fuzzing 框架,监控并合并所有服务相关进程的覆盖率,同时支持多进程漏洞检测


挑战三:定制协议语义约束被忽略
  • 触发 ncc 漏洞,输入必须同时满足:标准 HTTP 语法 + CCPact=set 这类固件私有约束
  • 现有方法随机变异,生成的输入在浅层校验即被拒绝

HouseFuzz 见解:TDG(令牌依赖图) 建模定制协议,离线+在线推理 token 约束,生成语义更合理的测试用例


四、核心思路

复制代码
输入:固件镜像 + 标准协议
       ↓
┌──────────────────────────────┐
│   ① 服务仿真模块(§5)        │
│   遍历初始化 → 识别网络服务   │
└──────────────┬───────────────┘
               ↓
┌──────────────────────────────┐
│   ② 多进程模糊测试框架(§6)  │
│   多进程覆盖率引导            │
│   多进程漏洞判定器            │
└──────────────┬───────────────┘
               ↓
┌──────────────────────────────┐
│   ③ 服务协议引导 Fuzzing(§7)│
│   离线+在线 TDG 推理          │
│   CFG + TDG 生成测试用例      │
└──────────────────────────────┘

两大核心亮点:

  • 多进程代码覆盖率作为引导信号
  • 令牌依赖图(TDG)感知定制协议约束

五、技术路线

本文技术贡献分为两大方向:① 服务仿真 (解决"测谁"的问题)和 ② 模糊测试(解决"怎么测"的问题)


▌贡献一:服务仿真模块(§5)

核心目标: 在 fuzzing 开始前,尽可能完整地识别并启动固件中所有相关网络服务进程

5.1.1 整体思路:分析系统初始化过程

固件启动时,init / preinit 程序会依次拉起各类进程,建立网络通道和 IPC 通道。HouseFuzz 的策略是:跑通整个初始化流程 → 从中识别哪些进程监听了网络、哪些进程存在 IPC 依赖。

5.1.2 系统初始化仿真:自动异常修复循环

复制代码
尝试运行 init → 检测异常 → 定位异常代码 → NOP 打补丁 → 重新运行

循环终止条件(满足其一即退出):

  1. 无新异常
  2. 新补丁导致识别到的通道数减少 → 判定误报,回退上一轮结果
  3. 达到最大迭代次数

异常的四种类型与检测方式:

进程类别 异常类型 检测方式
INIT 进程 中断(验证失败/内存错误) 检测 exit() 或已知错误信号
INIT 进程 挂起(如进入调试 shell) 无其他异常则积极判定为挂起
非 INIT 进程 崩溃(致命错误) 检测 SIGSEGV 等致命信号
非 INIT 进程 忙等(如死等网卡) CPU 占用 ≥ 总时间的 1/3

异常处理细节:

  • 分析异常进程的执行轨迹尾部定位异常代码(进程中止/循环处即为根源)
  • 选取满足两个条件的函数执行 NOP 替换:① 被调函数体积不超过阈值;② 位于程序自身可执行段(非外部库)

鲁棒性保障(回退机制): 打补丁后若识别到的网络/IPC 通道数量反而减少 → 视为误报 → 自动回退,避免破坏正常初始化逻辑

5.1.3 面向网络的进程识别

动态追踪策略(非静态白名单):

  • 全程记录系统调用轨迹(PID + 调用名 + 参数)
  • 检查 bind() 参数:绑定地址不是 localhost → 标记为面向网络进程
  • 对 HTTPS 等加密隧道代理进程:基于已知端口(如 80)识别内层进程,直接对内层进程 fuzzing,绕过加密开销
  • execve() 参数中提取完整命令行,用于后续独立仿真启动

5.1.4 守护进程识别

核心思路:顺藤摸瓜,通过 IPC 通道溯源

  1. 锁定通道"钥匙" :监控 open() / bind() 记录 IPC 通道路径和文件描述符
  2. 追踪数据流 :监控 send() / recv(),发现 A 进程发出的数据被 B 进程读走 → 回溯 FD → 确认通道
  3. 判定守护进程 :若某进程建立的 IPC 通道被多个网络服务进程频繁读写 → 认定为守护进程(依赖项)

🔖 示例: GREENHOUSE 白名单中没有 zebra,因此无法识别它。但 ripd 服务的正常运行强依赖 zebra 守护进程。HouseFuzz 通过动态 IPC 分析,成功发现这一隐藏依赖并将 zebra 纳入测试范围。

5.1.5 进程仿真启动顺序

识别完成后,基于 GREENHOUSE 的进程仿真技术:

  1. 先启动守护进程
  2. 再启动面向网络的进程
  3. 两类进程均可按需自动拉起实用进程

所有由服务启动的子进程通过 execve() 系统调用追踪,纳入后续的覆盖率收集和漏洞检测。


▌贡献二:多进程模糊测试框架与测试用例生成(§6 + §7)

核心目标: 在正确识别服务的基础上,用多进程感知的方式进行 fuzzing,同时生成语义合理的测试用例

5.2.1 多进程覆盖率引导:TCE 检测

核心问题:多进程 fuzzing 中,何时才算"一次测试完成",可以收集覆盖率了?

单进程只需判断进程是否终止;多进程中,各进程生命周期不同,需要分别判断:

进程类型 特点 TCE 判定方式
实用进程(短生命周期) 处理单个请求即退出 进程终止
面向网络的进程(长驻) 处理请求后继续运行 检测网络套接字被释放
守护进程(IPC 模式) 处理完 IPC 后复用通道等待 检测重新调用 select/poll 等 I/O 监听调用

关键顺序约束: 先确认所有网络进程和实用进程的 TCE,再判定守护进程 TCE → 避免一次 test 中多轮 IPC 请求引发的误判

5.2.2 覆盖率记录与引导

记录机制:

  • 进程启动时分配独立共享内存覆盖位图,避免多进程数据竞争
  • 测试完成后位图归还共享内存池,供下次复用
  • 守护进程维护激活标志 :退出 accept() 后才开始记录,降低无效开销

引导机制:

  • 将全部进程位图与历史覆盖率做 diff,任一进程出现新 bit → 种子有价值 → 入队
  • 加载同一 ELF 文件的多个进程位图先合并(求和),再统一比较,保证跨 test 一致性

5.2.3 多进程漏洞检测

重点检测两类漏洞,覆盖所有服务进程(网络进程、守护进程、实用进程):

漏洞类型 检测方式 关键细节
内存损坏 检测所有进程的崩溃信号(如 SIGSEGV) 通过输入可控性分析,过滤实用进程中不可利用的崩溃
命令注入 对所有进程 execve() 系统调用插桩 先用普通字母绕过过滤器探路,确认路径可达后再替换为注入字符串

🔖 设计亮点: 命令注入检测直接插桩 execve(),而非依赖厂商 API(厂商会对 API 做特殊处理),确保检测不被绕过。

5.2.4 服务协议引导的测试用例生成:协议形式化

问题根源: 仅靠 CFG 生成的输入格式正确,但语义可能不符合固件私有约束,在浅层就被拒绝。

解决方案:CFG(语法结构)+ TDG(语义约束)双层建模

概念 类比 作用
CFG(上下文无关语法) 作文的语法模板(主谓宾结构) 保证输入格式正确(如合法的 HTTP 请求骨架)
TDG(令牌依赖图) 逻辑关系图(主语是"老师"时谓语必须是"讲课") 保证输入语义 合理(如 keyvalue 的搭配约束)

TDG 定义: 有向图 G(N, E),节点为 token(类型:Path / Key / Value),边表示两类依赖关系:

  • 控制流依赖:一个 token 决定另一个 token 是否会被访问(或走哪个分支)
  • 数据流依赖:一个 token 决定另一个 token 如何被解释

5.2.5 三类 Token 依赖场景(理解 TDG 的关键)

场景 依赖类型 具体示例
场景1(开关型) 控制流依赖 action=set 存在时 value 才会被处理;action=getvalue 根本不访问
场景2(分支型) 控制流依赖 type=network → 需要 ipmasktype=system → 需要 timezonehostname
场景3(解释型) 数据流依赖 format=hex 决定 data=FF 按十六进制解析;format=string 则按字符串解析

核心启示: 不满足依赖关系的 token 组合,即使格式合法也会在浅层被拒绝,无法触达深层漏洞代码。

5.2.6 在线 TDG 推理(动态,边 fuzzing 边更新)

ccp_act=AAA 的 HTTP 请求为例:

复制代码
输入:POST /get_set.cpp HTTP/1.1
      ccp_act=AAA&...
步骤 操作 结果
Step 1:收集 token HTTP 解析器解析测试用例 AAA→Value,ccp_act→Key,/get_set.cpp→Path
Step 2:推断新 token 插桩 strcmp() 发现 strcmp("AAA","set") 推断期望 token "set",类型同为 Value
Step 3:建立依赖 Value 依赖同参数的 Key TDG 新增边:"set""ccp_act"

后续 fuzzing 若包含 Key ccp_act,就会优先尝试 Value "set",大幅提高通过浅层校验的概率。

5.2.7 离线 TDG 推理(静态,启动时预生成初始 TDG)

不依赖运行时数据,通过静态分析提前建图:

  1. 调用静态分析工具(IDA Pro)提取 URL 路径、参数键 → Path / Key token
  2. 基于控制流 / 数据流分析,识别图4中的三类代码模式 → 推断 token 依赖关系
  3. 在推断依赖过程中,顺带发现与常量字符串比较处的 Value token
  4. 整合为初始 TDG,弥补 fuzzing 早期缺乏种子覆盖的不足

在线 vs 离线互补:

离线组件 在线组件
时机 fuzzing 开始前 fuzzing 过程中持续更新
优势 启动快,提供初始 TDG 随探索深入不断完善
局限 只能识别标准字符串比较函数 还能识别定制化字符串比较逻辑

5.2.8 测试用例生成:CFG 骨架 + TDG 填充

两步生成流程:

  1. CFG 展开 :按语法规则生成合法请求骨架(如 ⟨KV⟩ → ⟨Key⟩=⟨Value⟩
  2. TDG 填充:查询 TDG,按依赖关系插入语义合理的 token 值

🔖 示例对比:

  • 传统方法(随机变异):{"deviceType": "abc", "operation": "xyz"} → 浅层拒绝
  • HouseFuzz(TDG 引导):查询 TDG → deviceType=lightoperation 限定为 toggle/dim{"deviceType": "light", "operation": "toggle"} → 通过校验,进入深层代码

六、实验评估

实验设置

  • 工具链:Binwalk(固件提取)+ QEMU(仿真)+ Radare2(轨迹分析)+ IDA Pro(离线 TDG)+ AFL++(fuzzing)
  • 数据集:60 个可用固件(3 个厂商,70 个原始镜像,10 个提取失败)
  • 环境:Ubuntu 22.04,Intel Xeon Gold 5218,64 核,245 GB 内存

RQ1:整体性能对比(vs. GREENHOUSE)

指标 GREENHOUSE HouseFuzz 提升
代码覆盖率(边覆盖) 基线 +24.8% p < 0.01
发现漏洞数 46 个 128 个 +178%
其中 0-day 数 40 个 110 个 +175%
覆盖服务数 18 个 25 个 ---

最新固件验证 :在 2020 年后新固件数据集(12 个固件)中,额外发现 21 个 0-day,均已获 CVE/CNVD 编号

总漏洞披露: 共上报 156 个 0-day(58 个缓冲区溢出 + 15 个命令注入 + 83 个拒绝服务)


RQ2:服务识别效果

工具 识别面向网络进程数 召回率
GREENHOUSE 44 18.1%
FirmAE 128 33.1%
HouseFuzz 311 80.4%
  • 精确率均为 100%(人工确认)
  • HouseFuzz 在 23 个额外固件上识别了 119 个(+37%)网络服务(来自异常修复)
  • 发现 85 个仿真异常,8 个被回退机制正确识别为误报

RQ3:多进程框架消融实验

  • HOUSEMP(多进程)在 16 个目标服务上代码覆盖率明显高于 GREENHOUSE(单进程)
  • 多进程框架额外检测出 14 个 GREENHOUSE 无法发现的漏洞
  • 共识别 24 个多进程漏洞 ,其中 17 个获 CVE/CNVD 编号(占全部编号漏洞的 38%)
  • 53.7% 的目标服务存在 IPC 行为

TCE 稳定性: 8,746 个种子中,排除非确定性控制流(NCL)后,TCE 检测达到 100% 一致覆盖率


RQ4:协议引导消融实验

方案 发现漏洞数
HOUSECFG(仅 CFG) 36
HOUSETDGOL(CFG + 在线 TDG) +94% vs HOUSECFG
HOUSEFUZZ(CFG + 在线 + 离线 TDG) 比 HOUSETDGOL 再多 55 个

TDG 推理质量:

  • 平均每个 TDG 含 734 个节点、2610 条依赖边
  • Token 推理精确率:HouseFuzz 62% vs GREENHOUSE 15%
  • 依赖关系推理精确率:44%(即使不完全准确,fuzzing 试错机制可自动筛选)

七、总结与体会

7.1 论文贡献总结

模块 核心创新 效果
服务仿真 异常自动检测与修复循环 网络服务识别提升 76%+
多进程 Fuzzing 全进程 TCE 检测 + 多进程覆盖率合并 发现 24 个跨进程漏洞(38% CVE)
协议引导 离线+在线 TDG 推理 0-day 发现提升 175%

7.2 主要局限

  1. 仿真保真度:仍基于进程仿真,非真实设备,存在覆盖盲区
  2. 认证后逻辑:缺少 session 维护,难测试需登录后才可访问的功能
  3. 未知协议:约 32.4% 服务使用非标准协议,协议引导能力有限
  4. TDG 精度:Token 和依赖推断仍有噪声(精确率 44%~62%)
  5. 适用范围:专为 Linux 固件网络服务设计,非通用嵌入式 fuzzing 框架

7.3 个人体会

  • 项目提供了 Docker 镜像,本地(Win11 + Docker + QEMU)进行了简单复现尝试
  • 虚拟机嵌套导致仿真较慢,资源消耗较高
  • 模糊测试阶段需要提前通过 IDA 准备种子集,上手门槛相对较高
  • 整体来看,多进程 fuzzing 框架是本文最有价值的创新点,弥补了现有工具对多进程协作漏洞检测的系统性缺失

📌 参考资料

相关推荐
GG-_-Bond1 分钟前
基于dpdk实现udp接收数据
linux·网络·udp
平凡シンプル5 分钟前
TCP UDP 网络通信插件 SL-Uniplugin-Tcp-Udp
网络·学习·uniapp·记录
小程序设计7 分钟前
Easy-Shop商城小程序漏洞挖掘与防护研究
网络·安全
万联WANFLOW26 分钟前
TikTok Shop上线“Sell Across EU”,欧洲社交电商迎来生态重构
网络·业界资讯
liulilittle1 小时前
为什么采用全局管理缓存及状态:麻将客户端状态管理
服务器·网络·游戏·客户端·异步·mahjong·麻将
酣大智2 小时前
OSPF引入的直连路由在 ospf 路由表中看不到
网络·ospf
2601_966377132 小时前
等保2.0最新标准新增安全数据处理要求后怎么办?等保一体机数据安全模块来助力
运维·网络·安全·等保一体机
BullSmall2 小时前
window系统上报Cannot assign requested address
网络·功能测试
杨云龙UP2 小时前
MySQL Host is blocked because of many connection errors 导致 JDBC 连接失败排查与解决
linux·运维·网络·数据库·sql·mysql·登录失败
执念WRD2 小时前
Fastjson 1.2.83 RCE 漏洞利用
网络·安全·网络安全