template for obsidian
马上年末了,最近导师让学习下SFuzz++这个项目,然后后续根据这个思想来申请专利。记录下SFuzz++的论文笔记
主要关注的内容为Design部分。
Approach Overview
在这篇论文中,设计了工具SFuzz++来解决以下问题:
- 如何定位外部输入点(尤其是隐式输入)
- 如何确定代码和上下文的范围
- 如何有效的进行基于切片的模糊测试
- 如何验证代码片段中检测到的漏洞
提出了基于切片的模糊测试方法来检测基于RTOS的嵌入式设备的代码片段。
整体流程
![[2024-12-30-SFuzz++论文笔记/file-20241230184218016.png]]
步骤
- 使用大模型和启发式方法来定位RTOS固件的外部输入点
- 使用范围提取器来提取与外部输入相关的代码片段并提取相关内存约束来恢复上下文环境
- 初始化运行环境并使用基于切片的模糊测试引擎来探索代码片段的执行树,同时使用控制流节点处理器来增强模糊测试的效率。
- 基于漏洞验证器来构建漏洞POC
A. 外部输入识别
将外部输入点分为两类:
- 显式输入点:根据明确的输入函数来确定
由于程序符号会被stripped掉,并且所有函数功能都被封装到一个二进制程序中。通过启发式方法来恢复函数语义(符号表文件和日志函数、web服务语义,与SaTC类似、开源固件 - 隐式输入点:硬编码的全局地址,根据全局地址的交叉引用来确定
给个例子:
![[2024-12-30-SFuzz++论文笔记/file-20241230192808606.png]]
可以看到0x8004000地址作为了函数wifiRecvData的输入,然后在wifi_config_set函数中被引用,这一个pattern无法通过定位recv等输入函数的方式来匹配到。
由于这种隐式输入通常与显式输入函数关联,因此可以通过分析与显示输入函数的关系来判断;同时可以利用大模型来推断候选函数是否展现出了解析数据的语义。
首先分析出所有显示输入点,因为全局变量通常与这些相关。通过跟踪跨procedure的参数和返回值数据流,我们生成了候选全局地址集合。
对于每一个引用全局地址的函数,我们使用Ghidra逆向工具来提取反汇编代码,然后将其整合到大模型的Prompt提示词中,让大模型来分析目标函数代码,基于分析,大模型会给出该函数是否为解析函数。然后通过污点分析来评估目标全局地址是否可以传播到sink点。
![[2024-12-30-SFuzz++论文笔记/file-20241230194716250.png]]
B. Code Snippet Scope Extractor
使用识别的外部输入点作为根节点,应用前向切片策略来构造执行树,代表一个相对独立的测试单元。然后再继续进行改进代码片段和上下文信息。
- Sensitive Call Graph Construction: 调用图构造器识别所有包含外部输入点的。为保证模糊测试效率,只保留能够到达sink点的分支。
- Call Graph Pruning: 使用粗粒度的污点分析技术。分析调用图的每一个路径,识别潜在的外部输入和全局数据,然后除去与此无关的路径
- Call Graph Stitching: 为了实现一种更好的数据流跟踪,SFuzz++会恢复由于缺少关联而缺失的边以及不同调用图的连接。与KARONTE和SaTC相似,通过数据共享范式来解决外界输入流的中断问题(set_env和get_env)
使用动态分析+静态分析的方法来完成这一工作:- 对于标记为常量字符串的数据共享范式,根据常量值来匹配。然后连接相应的call路径,组成一个两元元组(<nvram_set, nvram_get>)
- 对于存在动态创建的变量,如下图:
![[2024-12-30-SFuzz++论文笔记/file-20241230202342623.png]]
然后使用近似字符串匹配来检测。在模拟中需要确定变量的真实值- 当set点对应于多个get点时,SFuzz++构建一个条件节点来管理关系。(通过概率随机选取路径)
- Context Information Restoration: 提取两类关键上下文信息(本地和全局上下文)。
- 本地上下文:栈帧信息,寄存器值,变量约束
使用轻量级的符号执行从代码片段的根节点来执行。在这一过程中,记录栈帧信息。同时获取寄存器值和上游的约束。FN:buf长度定义 - 全局上下文:RTOS启动过程中全局内存空间区域。
SFuzz++使用大模型来检测全局变量初始化器。而且,通过建立每个函数和其修改的全局地址的映射(优先写入操作),候选函数被大模型分析来决定是否进行了全局空间的初始化。如果被确认为是,则使用符号执行来提取关联到全局变量的约束。另外,大模型可以用于识别被调用的可能干扰符号执行的函数。
- 本地上下文:栈帧信息,寄存器值,变量约束
Micro Fuzzer
为了有效地对提取的代码片段进行模糊测试,SFuzz++首先执行各类影响路径可达性和测试效率的指令(call,条件分支);然后恢复上下文信息来为模糊测试做准备;最终,测试所有的代码片段来检测可能的issue。
Control Flow Nodes Handler
由于缺失RTOS固件完整的上下文和运行时状态,我们需要一种方法来决定如何解决代码片段中的函数调用以及选择应该跳入哪一个条件语句。
- Call Instruction:跳过无关的call函数;对于有关系的函数,要完整探索。
- Conditional Branch: 条件分支
- Single reachable branch:
- Both branches reachable:
- No reachable branches:
Runtime State Initialization
使用提取到的上下文信息来精确地初始化运行时环境。
Fuzzing Engine
基于代码切片的模糊测试方法
Enhanced Memory Safety Policies
SFuzz++添加了内存检查机制
Vulnerability Validator
恢复真实环境进行确认是否crash能够真正触发。
- 前向基于切片的混合测试
- 后向基于切片的条件验证
基于大模型辅助的模糊测试种子生成:让大模型根据结构化数据来确定数据结构,从而能够更方便的通过代码片段中可能出现的check情况,从而7提高模糊测试效率。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Small Utopia!
评论