购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.5 固件处理方式

3.5.1 固件解包

固件解包的目的是,将完整的设备固件分解成文件系统、内核、引导程序等各个功能模块,以达到有针对性地分析某个脚本或二进制程序的目的。

基于嵌入式Linux开发的设备固件的二进制可执行程序、共享库、可执行脚本等文件,一般都打包成文件系统存储在固件中。常见的文件系统有SquashFS、JFFS2等。

常用的解包工具有Binwalk、firmware-mod-kit等。

3.5.1.1 Binwalk工具

Binwalk工具是一款优秀的固件解包工具,可以解析多种固件类型。它能对绝大多数没有加密的固件进行解包,从而获取固件的文件系统或对固件进行其他分析。

1.Binwalk工具的安装

如果使用apt-get命令直接安装Binwalk工具,那么可能会由于一些依赖库的问题而造成Binwalk工具的部分功能缺失。因此,建议通过GitHub将该项目源文件克隆到本地,并按照帮助文档进行安装。

2.Binwalk工具的基本用法

Binwalk工具的常见格式为“binwalk参数 文件目录/文件名”。Binwalk工具能自动对整个固件进行分析,进而提取出相应的文件系统。其常用参数如下。

-M参数:递归扫描提取文件。

-e参数:自动提取已知的文件类型。

-A参数:使用普通可执行操作码签名扫描目标文件。

-Y参数:显示目标程序的指令集架构和指令数量。

(1)使用-A参数,可以快速扫描出固件文件中字节码对应的指令集。此参数主要用于快速确定某些RTOS、裸机固件的CPU类型。-A参数的使用过程如图3-89所示。从扫描结果中可以发现,固件为ARM指令集架构。对于一些不存在文件系统的裸机固件,可以快速判断出目标指令集。

图3-89-A参数的使用过程

(2)使用-Y参数,会显示目标程序的指令集架构和指令数量。-Y参数的使用过程如图3-90所示。

图3-90-Y参数的使用过程

3.案例:Tenda ac15路由器固件分析

(1)使用binwalk-Me命令直接进行递归解包,如图3-91所示。

图3-91 进行递归解包

(2)查看文件系统根目录,并对二进制文件进行进一步分析,如图3-92所示。

图3-92 查看文件系统根目录

3.5.1.2 firmware-mod-kit工具

firmware-mod-kit工具的功能与Binwalk工具的功能类似。它们都是用于固件解包的集成工具,并支持多种文件系统解包。另外,firmware-mod-kit工具还有重打包固件的功能。

1.firmware-mod-kit工具的安装

该项目在GitHub中开源,建议将该项目源文件从GitHub克隆到本地,依照项目帮助文档使用下载文件进行编译安装。此过程涉及的代码如下。

2.firmware-mod-kit工具的基本用法

在firmware-mod-kit工具目录下使用extract-firmware.sh脚本进行解包,命令为./extract-firmware.sh<firmware image>。

3.5.1.3 binaryanalysis-ng工具

binaryanalysis-ng工具是一个支持通用操作系统的解包工具,具有非常强大的文件解包集成能力,不仅可以解析出物联网设备的固件文件,而且支持解析一些Android固件文件。binaryanalysis-ng工具支持的文件格式如图3-93所示。

图3-93 binaryanalysis-ng工具支持的文件格式

1.binaryanalysis-ng工具的安装

从Gitee上下载binaryanalysis-ng工具,并使用apt-get、pip等命令安装相关依赖文件。

该项目在Gitee中开源,建议将该项目源文件从Gitee克隆到本地,并使用apt-get命令和pip命令安装依赖文件。此过程涉及的代码如下。

2.binaryanalysis-ng工具的基本用法

假设已经访问到src目录,此时进入src目录会看到许多Python脚本,可以使用bang-scanner工具来对固件文件进行解析。

(1)访问src目录。

(2)使用bang-scanner工具对固件文件进行解析。

(3)进入tmp目录,如图3-94所示。

图3-94 tmp目录

(4)进入unpack目录,找到需要的文件系统,如图3-95所示。

图3-95 找到需要的文件系统

(5)应用bangshell,解析解包后的结果。在运行bangshell之后,查看bangshell支持的命令有哪些,如图3-96所示。使用load命令(load/root/tmp/bang-scan-52x0_zxy)加载刚刚解析完成的目录,使用summary命令分析文件类型,如图3-97所示。

图3-96 查看bangshell支持的命令

图3-97 加载目录并分析文件类型

最终结果如下。

labels命令如图3-98所示。

图3-98 labels命令

3.5.1.4 案例:小米路由器UBI格式固件解包程序

(1)直接使用Binwalk工具解包,会显示不能解包的报错信息,代码如下。

(2)编写UBI格式固件解包程序代码,如图3-99所示。

图3-99 UBI格式固件解包程序代码

(3)编译、运行,并处理UBI文件,代码如下。

(4)使用ubireader_extract_images命令解压UBI文件,代码如下。

(5)使用unsquashfs命令解压rootfs.ubifs文件,代码如下。

(6)解压之后,成功得到文件系统,代码如下。

3.5.2 固件加/解密

为了防止恶意分析人员或者攻击者对物联网设备固件进行解包分析,一些厂商会对发布的设备固件进行加密。面对这种情况,用户无法直接使用Binwalk工具对设备固件进行解包,需要通过手动分析逆向程序中的加密过程来解密,从而进行设备固件解包。

1.场景一:设备固件在出厂时未加密

在此种加密场景中,解密程序与较新版本程序中的未加密固件一起被提供,以便将来进行加密固件程序的更新,此后发布的固件为加密固件。固件加密场景如图3-100所示。

图3-100 固件加密场景1

2.场景二:设备固件在原始版本中已加密

(1)虽然设备固件在原始版本中已加密,但是厂商决定更改加密方案,并发布一个未加密的转换版本v1.2,其中包含了新的解密程序。固件加密场景如图3-101所示。

图3-101 固件加密场景2

(2)虽然设备固件在原始版本中已加密,但是厂商决定更改加密方案,并发布一个包含新版本解密程序的未加密转换版本。固件加密场景如图3-102所示。

图3-102 固件加密场景3

3.案例:D-Link DIR-878路由器解密

(1)获取DIR-878路由器固件的过程代码如图3-103所示。从结果中可知,该路由器固件的版本号为v1.04。

图3-103 获取DIR-878路由器固件的过程代码

(2)使用binwalk-Me命令将固件解包,之后进入固件文件系统根目录,代码如下。

(3)找到bin/imgdecrypt二进制文件,并使用以下代码解密高版本加密固件。

(4)解密后的固件存放在/tmp/.firmware.orig目录下,使用如图3-104所示的Binwalk工具正常解包即可。

图3-104 使用Binwalk工具正常解包解密后的固件

3.5.3 固件重打包

固件重打包是在对设备原有固件进行解包之后,先在固件中加入自定义的功能,再对其进行重打包并将重打包的固件刷回设备。固件重打包经常用于种植后门木马或者获取调试设备权限。

根据3.3.3节中内容可知,物联网设备固件一般由头部分和数据部分组成。由于在进行逆向分析时,通常关注的是如何使用Binwalk工具提取文件系统,因此在对设备固件进行修改时,必须了解以下内容。

1.uImage header简介及实例

uImage是U-boot专用的镜像文件,是在zImage(经过gzip命令压缩的vmlinux内核镜像)之前加上一个长度为64字节的文件头,是存储整个镜像概括信息的区域。

1)uImage header简介

uImage header一般放在固件的头部位置,也可以放在固件的中间位置。uImage header中一般存储的信息有uImage header大小(默认为64字节)、uImage header的CRC32的值、固件总大小,以及除了uImage header的data区域CRC32的值及固件镜像的一些基本属性,如设备的CPU类型、镜像压缩算法、镜像名等。

2)uImage header实例

使用Binwalk工具分析得到某个固件uImage header的代码如下。

从以上代码中可以获取如下具体信息。

(1)header size:64 bytes.

(2)header CRC:0xCFAB1B51.

(3)image size:3755611 bytes(整个固件减去uImage header的大小)。

(4)data CRC:0x1352BC1D.

(5)固件的指令集架构为MIPS架构。

(6)数据压缩算法是lzma。

(7)固件名称为B-LINK Linux Image。

2.uImage header的十六进制的表示方法

uImage header在hexdump命令下的信息如图3-105所示。

图3-105 uImage header在hexdump命令下的信息

其中,左上方框中的内容表示的是uImage header的CRC32的值(也就是从0x00到0x40的数据的CRC32的值);右上方框中的内容表示的是固件data段数据的总大小(0x394e5b,即date段数据的总大小为3755611字节);中间方框中的内容表示的是data段数据的CRC32的值。

3.uImage header的CRC32的值的计算方法

在对固件进行修改之后,需要重新计算uImage header的CRC32的值并替换,计算过程如下。

(1)使用dd命令单独对uImage header进行提取。

(2)将原uImage header CRC位置的值覆盖成00 00 00 00。

(3)使用010 Editor工具或者其他可以计算CRC32的值的工具计算uImage header的CRC32的值。

如图3-106所示,使用010 Editor工具计算uImage header的CRC32的值为CFAB1B51,对应了上面的数值。

图3-106 计算uImage header的CRC32的值 rydIRPgr1DjSdyOmi4nc11bftIiBEAM4JnY1+nYSIKlcfX2VSGLs6Yf+m8zEWS3z

点击中间区域
呼出菜单
上一章
目录
下一章
×