研究背景
物联网设备数量众多, 其中隐藏了大量的安全漏洞。为了更多的发现漏洞, 研究者希望将一些已有的技术应用在嵌入式设备中, 但由于嵌入式设备的特性导致对其使用这些技术十分困难。
引入rehosting技术: 在高算力仿真环境中重新托管嵌入式设备的固件, 该方法存在的主要问题是:
- 每个IoT设备具有特定特征与功能, 需要高仿真度的模拟
重托管目标
物联网固件分类:
- type-I, 运行于嵌入式环境的通用操作系统(linux…)
- type-II, 专为嵌入式环境设计的操作系统.
- type-III, 整体固件, 代码直接在设备上运行, 无OS管理,使用专用接口与硬件进行交互.
Type-II与Type-III固件与硬件紧密耦合, 通用重新托管工具更难以实现.
重托管保真度
分类
-
Extraction Fidelity :静态组件保真度
- 存储在image或硬件中的文件或数据,需要从下载的固件image或物理设备中提取这些组件
-
Execution Fidelity: 动态组件保真度
- 保真度会因外围设备的存在与否而复杂
- 低执行保真度可能会导致误报或漏报
-
两者关联
- 高提取保真度才能确保高执行保真度
- 高提取保真度更容易实现, 高执行保真度更难实现
现有技术缺陷:
-
模拟外设或将通信代理到运行在真实物联网设备上的外设的技术
- 只能托管小型嵌入式软件平台/无OS
- 无法分析复杂的基于linux的固件(很大一部分物联网设备)
-
针对基于 Linux 的固件的最先进的重新托管解决方案
- 依赖于不知外设的全系统重新托管,通常是将固件样本重新打包为标准文件系统格式,将嵌入式 Linux 内核替换为特定于重新托管的版本以支持一些临时通用设备仿真,并在全系统仿真器(如 QEMU)中引导固件样本。
- 这种重新托管保真度的隐含让步(例如,通过替换嵌入式内核)会导致重新托管失败。重新托管的目标实际上没有保持足够的功能来测试面向外部的服务。
当前最先进的重新托管方法必须考虑模拟设备和物理设备之间的差异,因此通常侧重于提高仿真保真度。然而,这种对保真度的追求忽略了其他可能的解决方案。
因此, 不能盲目提升仿真度, 更应该关注于与潜在漏洞的执行直接相关的组件
专注于单个固件服务的用户模式仿真, 仅围绕固件服务重新创建必要的仿真。 目标是获得高执行保真度的优势,而无需昂贵的全系统仿真。这使我们能够显著提高重新托管服务的执行速度和可移植性。
论文提出: user-space single-service rehosting
本文提出用户空间单一服务重新托管,模拟用户空间中的单个固件服务。我们的方法回避了以前的重新托管技术遇到的许多挑战,并使我们能够将常见的漏洞发现技术应用于重新托管的映像,例如用户空间覆盖率引导的模糊测试。
- 不要求对操作系统或硬件进行高保真模拟
- 设计了一系列技术,在重新托管固件服务期间自动查找执行障碍,使用干预工具包来克服这些障碍,并验证修补的服务以检查我们的补丁是否破坏了预期的功能。
- 通过不仿真特定于操作系统或硬件的特性和功能,我们的解决方案不仅避免了全系统技术遇到的陷阱,而且作为奖励,还支持用户空间仿真,这大大降低了全系统仿真技术所表现出的执行开销。此外,用户空间仿真支持常见的漏洞发现和验证技术,例如覆盖率引导的模糊测试。
技术实现: Greenhouse
组成部件
多个部分组成
- Crawler
- Extractor 从固件镜像中提取文件系统(???)
- Runner 运行当前程序, 进行动态时间的等待, 随后调用Checker, 过程中产生运行日志.
- Checker : 根据运行日志和检查结果, 判断 rehosted 服务的保真度, 将结果传递给 Fixer
- Fixed : 根据checked结果执行”干预”措施, 提高rehosted服务保真度, 结果返回Runner.
- Exporter 将rehost后的固件导出为docker容器
不断重复循环进行迭代,直到模拟镜像被重新托管到足够的执行保真度水平(由 Checker 确定),或达到最大迭代周期数.
效果指标
分阶段
-
解包: 解压固件镜像并提取完整文件系统,
- gh仅支持type-1 固件.
- 因此需要在该阶段提取可识别的linux文件系统.
-
执行
- gh不模拟完整的环境, 而是定位到支持目标服务的特定二进制程序
- 因此, 此阶段关注于高提取保真度, 而不是高执行保真度. gh通过QEMU-user验证识别出的二进制文件是否可以在chroot下执行, 并以此判断其提取保真度.
-
连接
- 目标是实现与模拟固件服务的最低通信级别
- 要求能连接到重新托管的服务,而不会终止、超时或过早崩溃, 并能及时收到响应.
-
交互
- 在此阶段大幅提高执行保真度
rehost中的障碍
R1 初始提取会破坏完整固件中的符号链接、文件、目录和库文件, 这些文件可能对固件二进制文件的执行有至关重要的作用
- 一般的全系统rehost方法需要运行这些初始脚本作为OS boot 行为
- single-service rehost方法必须主动推断这些文件的路径
R2 运行时参数 二进制文件在命令行中运行指定参数
R3 外围设备访问 固件服务可能会尝试以多种方式与硬件外围设备进行通信. 在有限仿真中, 此类行为往往会导致奔溃或退出.
R4 NVRAM 配置 NVRAM是固件运行所需通用硬件组件, 通常包含固件映像启动与运行所需的默认配置数据.
R5 硬编码设备 嵌入式设备参数可能被硬编码.
R6 多二进制程序行为 服务程序可能需要额外的程序辅助才能运行
- Single-service rehost 要求显式运行这些辅助程序
- 全系统rehost将其作为OS启动进程的一部分
R7 运行环境监测 固件二进制程序对其运行环境进行各项检查
R8 Environment Mangling 固件程序在真实的封闭环境中往往无视其他进程的影响 但在模拟环境下存在其他进程, 固件程序的行为就可能会破坏这些程序的正常运行.
干预措施
目标:
- 满足 roadblock 的要求, 带来更高的保真度
- 或绕过 roadblock, 降低保真度, 但实现简单可拓展.
patch
Greenhouse 处理三种类型的补丁:
- Premature Exit 补丁: 解决程序过早退出的问题
- Wait Loop 补丁: 解决程序不断循环, 无法正常退出的问题
- Crashing Instruction 补丁: 将导致崩溃的执行直接替换为nop,是处理无效内存访问的有效方法, 但将导致对保真度的高度破坏性,
方案效果
- gh在特定品牌上的rehost效果好, 但在另外一些品牌上效果不佳.
- gh与 FirmAE 的有效rehost范围重叠小, 表明 Greenhouse 可以处理全系统仿真技术无法处理的rehsot障碍。
- gh方法具有可拓展性, 可用以托管其他类型的固件服务.
局限性
- 无法应对具有加密/混淆/隐藏等防护技术的固件
- gh使用QEMU-user进行用户空间仿真, 因此也具有其所有的缺陷
- gh使用angr创建CFG, 因此会受到其正确性影响
- 固件会使用自定义库函数与外围设备交互. 如果提取保真度过低而导致缺少了这些库则会影响下一步的rehost.
- 存在较低的概率误报, 需要手动分析
Reference
-
https://www.usenix.org/biblio-13740
-
https://secartifacts.github.io/usenixsec2023/appendix-files/sec23winterae-final55.pdf
-
https://zenodo.org/records/8026178