# 静态分析

静态分析主要使用IDA Pro、Ghidra等反汇编工具分析，一般配合符号执行和污点分析提高分析规模和效率。静态分析不是指完全没有程序动态执行，而是不侧重于固件动态仿真。

### 一、分析基础

#### 1.1 反汇编引擎

* [**Capstone**](https://github.com/aquynh/capstone)

Capstone反汇编引擎可以说是如今世界上最优秀的反汇编引擎，IDA，Radare2，Qemu等著名项目都使用了Capstone Engine，支持FreeBSD, OpenBSD 和 Solaris, 可反汇编 ARM, ARM64 (ARMv8), MIPS, PPC, and x86 架构下应用。Capstone 提供丰富的反汇编指令，支持 C/Python 接口。

* [**Keystone**](https://github.com/keystone-engine/keystone)

Keystone是一个轻量级的多平台多架构的汇编框架，可以提供不少独特功能，支持多框架：Arm, Arm64 (AArch64/Armv8), Ethereum Virtual Machine, Hexagon, Mips, PowerPC, Sparc, SystemZ & X86 (包括 16/32/64bit)，同时不依赖任何架构。原生支持Windows和Mac OSX, Linux, \*BSD, Solaris，线程安全的设计，具有双重许可证，支持 C/Python 接口。

#### 1.2 常用工具(方法)

* [**IDA Pro**](https://hex-rays.com/IDA-pro/)

IDA Pro（简称IDA）是DataRescue公司出品的一款交互式反汇编工具，它功能强大、操作复杂，要完全掌握它，需要很多知识。IDA最主要的特性是交互和多处理器。操作者可以通过对IDA的交互来指导IDA更好地反汇编，IDA并不自动解决程序中的问题，但它会按用户的指令找到可疑之处，用户的工作是通知IDA怎样去做。比如人工指定编译器类型，对变量名、结构定义、数组等定义等。这样的交互能力在反汇编大型软件时显得尤为重要。多处理器特点是指IDA支持常见处理器平台上的软件产品。IDA支持的文件类型非常丰富，除了常见的PE格式，还支持Windows,DOS,UNIX,Mac,Java,.NET等平台的文件格式。

* [**Ghidra**](https://ghidra-sre.org/)

Ghidra是一个软件逆向工程（SRE）框架，包括一套功能齐全的高端软件分析工具，使用户能够在各种平台上分析编译后的代码，包括Windows、Mac OS和Linux。. 功能包括反汇编，汇编，反编译，绘图和脚本，以及数百个其他功能。. Ghidra支持各种处理器指令集和可执行格式，可以在用户交互模式和自动模式下运行。. 用户还可以使用公开的API开发自己的Ghidra插件和脚本。

* **符号执行**

**符号执行**起初应用于基于源代码的安全检测中，它通过符号表达式来模拟程序的执行，将程序的输出表示成包含这些符号的逻辑或数学表达式，从而进行语义分析。

程序中变量的取值可以被表示为符号值和常量组成的计算表达式，而一些程序漏洞可以表现为某些相关变量的取值不满足相应的约束，这时通过判断表示变量取值的表达式是否可以满足相应的约束，就可以判断程序是否存在相应的漏洞。

使用符号执行检测程序漏洞的原理如下图所示：

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FMFj3CBtrppoqkxRgW3an%2Fimage.png?alt=media\&token=68b13fe1-de3e-4e75-b35e-019adab69d2d)

* **污点分析**

污点分析就是分析程序中由污点源引入的数据是否能够不经无害处理,而直接传播到污点汇聚点。如果不能,说明系统是信息流安全的;否则,说明系统产生了隐私数据泄露或危险数据操作等安全问题。

**污点分析**是一种跟踪并分析污点信息在程序中流动的技术。在漏洞分析中，使用污点分析技术将所感兴趣的数据（通常来自程序的外部输入）标记为污点数据，然后通过跟踪和污点数据相关的信息的流向，可以知道它们是否会影响某些关键的程序操作，进而挖掘程序漏洞。即将程序是否存在某种漏洞的问题转化为污点信息是否会被 Sink 点上的操作所使用的问题。

使用污点分析检测程序漏洞的工作原理如下图所示：

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FTbOByybtEvkeCmIXbAUs%2Fimage.png?alt=media\&token=818ede09-ad13-483a-8c09-b56ec32dbe21)

### 二、实例分析

#### 2.1 IDA Pro

某路由器POC：

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/5b390e96f181b.png)

从poc中可以得知，路由器上的 web 服务器在处理 /goform/set\_manpwd 请求时出现了问题，导致在未进行用户校验的情况下，通过 routepwd 字段可以更改管理员密码，且能崩溃 web 服务器。

提取路由器中的固件，使用 binwalk 解压固件，在 /bin 目录下可以得到路由器的 web服务器的二进制文件 goahead。使用 file 命令查看 goahead 的信息如下：

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/5b390d6b2a969.png)

可以看到目标平台是 mips32 位，LSB 字段表明是小端序，指令集为 mips32 rel2。 使用 ida 对 goahead 进行静态分析，在 strings 窗口中直接搜索 set\_manpwd ，得到两处字符串。

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/5b390e34d34ae.png)

分别查看交叉引用得到 0x46c558 处的字符串在 sub\_457ebc 中被引用两次，

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/5b39100b3120a.png)

0x46b6b4 处的字符串在 formDefineCGIjson 中被引用了一次。

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/5b3910574ca57.png)

查看 formDefineCGIjson 中的引用位置发现 websFormDefine 的第二个参数被置为 sub\_457ebc 的指针。

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/5b391068d0fae.png)

推断 sub\_457ebc 为主要处理 set\_manpwd 的函数，进入sub\_457ebc 函数发现主要有以下函数调用： 获取 routepwd 的值，该字段正是可以更改密码和命令执行的字段，

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/5b390e6acf933.png)

将传入的参数格式化成 json 对象并传入 bs\_setmanpwd 函数，同时传入的还有当前栈帧的字符串地址，对 bs\_setmanpwd 函数分析之后发现是一个来自 [libshare.so](http://libshare.so) 的库函数，且对我们的漏洞并无重大影响

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/5b390e7d89d76.png)

对 http 请求进行回复并删除 json 对象。

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/5b3910db68c51.png)

获取 password 并使用 password 格式化字符串 “[chpasswd.sh](http://chpasswd.sh) admin %s”,可以看出此条命令应该和修改管理员密码有关，继续向下发现 bl\_do\_system 函数的参数为刚才格式化好的字符串，推测此处应该是修改密码并进行命令执行的地方。

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/5b390e87c11a9.png)

#### 2.2 Ghidra

Ghidra是一个免费的开源软件，与IDA类似，有教丰富的插件，可以对包括移动应用程序在内的可执行程序（二进制）进行逆向工程分析。Ghidra支持在多个操作系统平台上安装和使用，包括Windows、Linux和MacOS。

安装依赖组件：

`sudo apt install openjdk-11-jdk`复制解压下载好的Ghidra包，打开Ghidra文件夹然后运行下列命令，此时将会打开Ghidra-GUI：`./ghidraRun`复制打开Ghidra。

下图显示的是整个反编译流程：

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FN1KMqfQG70M1YX8zXZC4%2Fimage.png?alt=media\&token=45213487-739f-4ca2-8c84-8c5c9ff623ae)

大多数编程语言都可以有解释器和编译器，比如说，Python既可以作为编译程序执行，也可以作为解释语言执行。大多数命令行工具、PowerShell和Unix Shell也是一种解释语言。高级语言翻译（解释器/编译器）通常将源代码直接翻译成机器代码。然而，翻译器和反汇编程序可以将代码生成为汇编语言。

使用[VxHunter](https://github.com/PAGalaxyLab/vxhunter) 插件分析vxworks固件起始地址和符号：

* 加载 VXworks固件

![](https://github.com/PAGalaxyLab/vxhunter/raw/master/docs/images/Load_vxworks_image_to_ghidra_01.png)

![](https://github.com/PAGalaxyLab/vxhunter/raw/master/docs/images/not_analyze_now.png)

* 加载 **VxHunter firmware init script**

![](https://github.com/PAGalaxyLab/vxhunter/raw/master/docs/images/VxHunter_ghidra_firmware_init_720.gif)

* 利用脚本分析

![](https://github.com/PAGalaxyLab/vxhunter/raw/master/docs/images/VxHunter_ghidra_analysis_720.gif)

#### 2.3 符号执行

angr是一个基于Python的二进制符号执行框架。支持大多数架构，包括MIPS和ARM架构。

为了生成程序跟踪信息，angr通过模拟每条指令来模拟每个函数，并使用符号执行来决定是否跟随一条分支指令。作为一个符号执行框架，angr使用也可能存在路径爆炸问题。

在某系列路由器漏洞分析中，使用了angr的[Reaching Definition](https://degrigis.github.io/posts/angr_rd/)分析技术，生成一个由路由器固件中的函数的组成的**use-def关系图**。然后，对该图进行相应的分析，以检测可能的安全漏洞，比如（来自source点）用户输入到达一个危险的函数（即sink点），如system函数，就认为发现了一个潜在的安全漏洞。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2Fdf04CbU5DLpx7hU7JQ62%2Fimage.png?alt=media\&token=402a78de-3c2a-47bf-b24e-a4a93b197b11)

在上面的函数中，存在一个明显的命令注入漏洞：含有漏洞的代码为system(command)，其中注入的命令来自querystring的参数name。在这个函数中，querystring和其他原子之间的use-def关系如下所示：

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FXPEswASpxglKo6xXmvrI%2Fimage.png?alt=media\&token=a308d69a-d68a-457b-b7b5-01df69d640d4)

querystring被定义为函数vuln的参数，并被get\_querystring\_value函数作为参数querystring使用。除此之外，函数get\_querystring\_value还定义了一个参数name，get\_querystring\_value函数定义了一个返回值，并用到了上面定义的两个参数。

在调用sprintf函数时，还用到了name变量（函数get\_querystring\_value的返回值）和一个字符串echo %s >> /tmp/log。因为sprintf函数的第一个参数是目标，所以，对command进行适当的定义，从而让它全面使用提供给spritnf函数的2个参数，而不是仅使用返回值。生成的use-def关系如下所示：

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FrwDgsfqrEQaKkjt8mSwt%2Fimage.png?alt=media\&token=b59a783b-2788-42dc-9ed9-ffe8dffa8ed2)

使用相同的概念，通过这种分析方法可以为函数中的所有原子生成相应的use-def关系。正如我们在上面看到的，这种关系可以被建模为一个图：“使用”用边表示，“定义”用节点表示。 因此可以将其转换为图分析问题。

#### 2.4 污点分析

现在，现成的污点分析工具已经有很多了。比如[Triton](https://triton.quarkslab.com/)和[bincat](https://github.com/airbus-seclab/bincat)，但两者支持的架构有限。下以[SaTC](https://github.com/NSSL-SJTU/SaTC)为例简介污点分析过程 。

SaTC研究人员发现，现有嵌入式系统中的许多流行漏洞都位于其脆弱的web服务中，寻找这些漏洞的关键：如何定位后端程序中用于处理与用户输入数据相关的代码，而Web前端文件（html、js、xml等）中存在的一些关键字符串通常与后端二进制文件之间是共享的，也就是说承载用户输入数据的某个参数名称在前端文件与后端文件中都会存在。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FPk0ls2EOnD9RhNT7MA1A%2Fimage.png?alt=media\&token=ad9bfbc1-083d-4169-9b1a-02cc6a6551a3)

基于此，SaTC主要针对**web服务**，将解压后的固件系统目录路径作为输入给到工具，然后工具就可以全程自动化完成提取关键字符串、定位后端程序中关键字符串的引用位置、以引用点为起始位置进行污点分析，最终输出了所有可能存在漏洞的指令位置，同时还给出了从输入点到漏洞指令位置的函数调用链条。比如如下示例：

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FtlLBj7vaR9Ytkvq2wWIl%2Fimage.png?alt=media\&token=5d35bdad-3a07-45db-97b3-1cab3c0b7518)

Front-End为该路由器的USB管理功能界面，用户通过浏览器可以访问该页面进行USB管理。

Back-end为该路由器的后端接口服务函数调用图，用于接收前端发起的http请求并进行业务处理。

通过查看前端js代码可以发现Unmount功能的接口请求地址为goform/setUsbUnload，接口请求参数为deviceName。查看后端程序可以找到对Unmount功能接口的处理函数formsetUsbUnload，同时可以发现deviceName参数值被接收后未做任何校验，直接被用于字符串拼接，拼接后的字符串被作为doSystemCmd（可用于执行系统命令，如通过执行nc命令实现shell反弹）函数的参数进行使用。这是典型的命令注入漏洞，产生该漏洞的根因是程序未对用户可控的输入进行有效净化校验就被拼接成字符串用于命令执行。攻击者可以通过发送恶意构造的deviceName参数值，注入恶意命令并获取设备权限。

### 三、**专用工具**

* **PATCHECKO \[20]**

PATCHECKO是一个针对可执行文件漏洞和补丁存在性检测的框架PATCHECKO。它混合了静态检测和动态检测方法，能够对X86和arm架构的二进制代码进行漏洞检测。

* **KARONTE \[21]** [**Github**](https://github.com/ucsb-seclab/karonte)

KARONTE是一种静态分析方法，能够通过建模和跟踪多二进制交互来分析嵌入式设备固件，该方法基于污点信息分析，以检测不安全的交互并识别漏洞。

* **SaTC \[22]** [**Github**](https://github.com/NSSL-SJTU/SaTC)

SaTC 通过利用前后端共享关键字作为污点分析输入，从而能够聚焦在后端执行体中与前端输入强相关的数据引入点，将其作为污点分析的开始位置，降低符号执行复杂度，同时能够更加精准、高效地发现多种类型的安全漏洞。

* **Firmalice \[23]**

Firmalice是一个二进制静态分析框架，能够自动化的检测固件程序中的认证旁路漏洞，Firmalice构建在符号化执行引擎上，结合了程序切片的相关技术来提高其扩展性。

* **FIE \[24]**

对于某些固件，完整的分析是难以处理的，分析中的各种不精确来源可能会导致误报或漏报。FIE使用符号执行描述外设，改进符号执行技术来适应固件特定的功能，并致力于发现固件中的内存错误。

* **PASAN \[25]**

PASAN是第一个用于检测嵌入式系统并发外设访问内在问题的静态分析工具。PASAn使用解析器准备的内存布局自动查找每个外设的MMIO地址范围，使用对应的设备驱动提取外设的内部状态机，自动检测外设访问的并发Bug。

* **Basespec \[26]** [**Github**](https://github.com/SysSec-KAIST/BaseSpec)

BaseSpec是对基带固件中软件和设置做比较性分析的戏方法，通过利用标准的消息结构，BaseSpec能够系统地检查基带软件中的信息结构。

* **LightBlue \[27]** [**Github**](https://github.com/purseclab/lightblue)

LightBlue是一个BLE固件分析剪裁工具，可以自动感知蓝牙栈的配置文件的框架，允许用户通过删除不需要的蓝牙特性来自动减少他们的蓝牙攻击面。

* **FirmXRay \[28]** [**Github**](https://github.com/OSUSecLab/FirmXRay)

FirmXRay是Ghidra BLE 固件静态反汇编插件，直接从固件分析link layer漏洞。
