# 固件获取

### 一、概述

对固件进行逆向和安全分析的前提，是需要获取到相应的固件文件。首先涉及到固件的获取，获取到的固件需要使用工具进行解析，得到相应的二进制文件或者文件系统，以便进行下一步的安全分析和漏洞挖掘。

这里列出主要的几种比较常见的途径来获取固件：

* 直接从开发团队、制造商/供应商或用户获取
* 使用制造商提供的项目从头编译
* 从供应商的support网站获取
* 从共享平台（ `Dropbox`、`box`、`Google drive`）根据二进制文件扩展名获取从用户为了解决问题而上传固件到论坛、博客，或官方评论中获取
* 设备更新进行中间人（`MITM`）获取
* 云提供商存储位置（如：`AWS`，全称`Amazon Web Services S3 buckets`）下载构建版本
* 通过 `UART`、`JTAG`、`PICit`等直接从硬件中提取
* 嗅探“硬件组件中的串行通信”中的更新服务器请求
* 通过移动应用程序中的硬编码接口
* 将固件从引导加载程序（如：U-boot ）转储到闪存或通过tftp的网络转储
* 从主板卸下闪存芯片（如：SPI ）或 MCU，以进行离线分析和数据提取需要相应的芯片编辑器来存储 flash/MCU

### 二、官网获取

对于固件获取，第一种最直接的方法就是通过官网的下载渠道，来获取相应的固件文件。首先找到官网的网址，根据官方提供的固件下载链接进行下载。

在官网的技术支持处可以下载到对应型号、对应版本的固件。如 Tenda 路由器官网：

![Tenda](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FAPrQnx68cvdpNp8riXou%2Fimage.png?alt=media\&token=2a917b12-96b1-4dd1-8b95-16cf41a28cf8)

![tplink](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FcdtiDceC7taGX6T01WoS%2Fimage.png?alt=media\&token=39e9e71c-91a9-4ef2-8695-49ec2878db34)

对于某些厂商的固件是统一放在某个服务器目录下，如 [DLINK 系列固件](ftp://ftp2.dlink.com/PRODUCTS/)。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2Ff1QwDuu4rRM0kdmNgYEa%2Fimage.png?alt=media\&token=8aa896eb-e64e-4e40-89f6-8a50d193fcce)

虽然官方提供的下载链接获取固件是一个很便捷的方式，但是大部分情况下厂商可能不提供相应固件的下载链接，这时就需要我们想一些其他的方法来获取固件。再如 draytek 厂商：

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FkyepoIvVUnE0f9WXnMDe%2Fimage.png?alt=media\&token=188fe378-5a53-4d48-bd5b-48da0bd32721)

一些国内路由器厂商的固件下载链接：

[TOTOLINK](http://www.totolink.cn/index.php/Download/list/121.html)

[totolink](http://www.totolink.net/)

[极路由/hiwifi](https://app.hiwifi.com/dstore.php?m=download\&a=info)

[D-LINK](ftp://ftp2.dlink.com/PRODUCTS)

[FAST](https://service.fastcom.com.cn/download-list.html#0)

[TP-LINK](https://service.tp-link.com.cn/download?classtip=software\&p=1\&o=0)

[MERCURY](https://service.mercurycom.com.cn/download-list.html)

[Tenda](https://www.tenda.com.cn/download/cata-11.html)

[磊科](http://www.netcoretec.com/download.html)

[维盟](http://www.wayos.com/download/luyougujian.html)

[艾泰](https://www.utt.com.cn/downloadcenter.php)

[锐捷](http://www.ruijie.com.cn/fw/rj/)

[飞鱼星](http://www.adslr.com/companyfile/2/)

[newifi](http://www.newifi.com/download.shtml)

[b-link](http://www.b-link.net.cn/download.php?CateId=11)

[华硕](https://www.asus.com.cn/support/Download-Center/)

[腾达](https://www.tenda.com.cn/download/cata-11.html)

[拓实](http://www.tuoshi.cn/download.asp)

[netis](http://www.netis-systems.com/Suppory/de_details/id/1/de/50.html)

[华硕](https://www.asus.com.cn/Networking/RTAC68U/HelpDesk_BIOS/)

### 三、更新包抓取

#### 3.1 **wireshark配合热点抓设备升级的包**

工具：wireshark、ettercap

流程：中间人->开始抓包->在线升级->分析固件地址->下载

案例：华为路由WS5200 四核版这款路由器在网上找不到现有固件，我们尝试一下是否可以通过抓包在线升级过程获取固件。首先关闭防火墙，否则无法访问路由器的服务，无法做中间人攻击。使用ettercap进行arp欺骗，`sudo ettercap -Tq -i ens33 -M arp:remote /192.168.31.1// /192.168.31.134//`打开wireshark进行抓包。理论上说，点击升级固件之后，wireshark就能够记录升级固件的整个过程(HTTP),但是结果却并不理想。

还好华为路由器自带了抓包的功能（方便后期的调试和维护），所以直接使用这个功能抓取报文，比做中间人要直接了当得多。

在点击升级固件之后，我们可以看到大量发往58.49.156.104这个地址的报文，猜测极有可能是华为的服务器，过滤一下会看得更清楚可以看到在通过三次TCP握手之后，华为路由器向服务器发送了get请求，uri就是获取固件的地址：[`http://update.hicloud.com/TDS/data/files/p14/s145/G4404/g1810/v272964/f1/WS5200_10.0.2.7_main.bin`](http://update.hicloud.com/TDS/data/files/p14/s145/G4404/g1810/v272964/f1/WS5200_10.0.2.7_main.bin)

点击即可拿到最新的固件

![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1563606353/samples/1.png)

* **案例：小米智能门锁**

```
./storage/emulated/0/Android/data/com.xiaomi.smarthome/cache/ble/250cc495d7da7643680dadeab578fce0_upd_lumi.lock.mcn01.bin
```

**有些固件会上传到tmp目录下，上传完成后删除，可以使用限速大法，不断刷新目录，在删除操作前抢先转移。**

#### 3.2 **burpsuite抓APP请求设备升级的包**

略

#### 3.3 **通过putty、winscp登录通过串口/网络传输固件**

通过万用表找到uart串口上的相应引脚。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2F0jcwL2Q1S9I2vjkMg74C%2Fimage.png?alt=media\&token=a2f0396d-7761-44eb-9429-de1a220b95b7)

使用NETGEAR R7000作为演示案例。可以清楚的看到在PCBA板上，有4个已经焊接好的排针，是官方用于调试的uart串口，我们依次将4个排针从左到右排序为1-4。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FhrwfklIwt1Ff3w6qSecL%2Fimage.png?alt=media\&token=e45c6ee8-1362-4e9e-b275-040a6095d8f5)

将终端设备接通电源，并拿出万用表，调至蜂鸣档（红表笔与黑表笔接触会有蜂鸣声）。将黑表笔抵到金属散热片上（接地断路），将红表笔在1-4排针间依次接触，发现2排针发出蜂鸣声，可以判定2排针为GND引脚。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FmN0y4CPWFJKpEUSPLgXo%2Fimage.png?alt=media\&token=34829f82-2f87-4bd9-b47e-5332ccf33008)

随后使用杜邦线将其余3个排针依次与2排针进行短接，若出现终端设备重启现象，则说明与2排针短接的排针为Vcc引脚。测试过程中发现1排针为Vcc引脚。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FodyAnVKsYBLigxIc2wAr%2Fimage.png?alt=media\&token=35db89b4-6781-44a4-8be7-2e4e8eddaf1f)

将万用表调至直流电压档，将黑表笔接到GND引脚，分别测3、4排针的电压，发现均为3.3V左右。由于终端设备开机时会进行数据传输，Tx引脚电压会频繁变化，此时可以通过重启设备观察两排针电压变化。通过测试判断3排针为Tx引脚，4排针为Rx引脚。

根据uart引脚与TTL转USB模块接法，PC端接通设备uart串口。通过不停调试波特率，最终确定该终端设备uart串口波特率为115200。

在使用SSCOM确认uart串口的COM口与波特率后，我们按下PUTTY的"Open"按键，在接收完设备的初始化信息后，输入命令"id"，确认当前权限为root权限；输入"uname -a"命令，可以看到设备的相关信息。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FpBsMEXI2wpLEgIXKrcIm%2Fimage.png?alt=media\&token=3080849c-660f-407b-b0e6-3b98eb69e5d5)

终端设备的存储芯片通常挂载在文件系统上，我们通过执行命令“cat /proc/mtd”看到boot、内核、文件系统等挂载的起始地址与字节大小，其中文件系统“rootfs”挂载的位置为mtd3。

图中的proc/mtd文件保存着系统的磁盘分区信息，mtd0分区"boot"保存的是系统启动引导程序；mtd1分区"nvram"保存着系统设置的各种配置数据，诸如管理员账户密码等；mtd2分区"linux"保存着Linux内核程序；mtd3分区rootfs保存着文件系统的数据。其他分区则根据开发者设计使用。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FSIbAxb4VBBzzK2MCyfs3%2Fimage.png?alt=media\&token=d24b82b3-2316-45d7-af6e-c41c168ed596)

使用dd命令获取设备文件系统镜像：`dd if=/dev/mtd3 of=/tmp/R7000.bin`

在获取文件系统镜像后，如何使用命令将固件外传是一个问题。笔者整理了如下几种常用的固件外传方法：

* **ftp命令**

如果shell支持ftpput命令，首先需要在本机搭建一个[ftp服务器](https://blog.csdn.net/weixin_42332985/article/details/106259719)，使用命令`ftpput 10.0.0.2 R7000.bin /tmp/R7000.bin`将固件上传到本机的ftp服务器中。测试案例中本机ip为10.0.0.2，物联网终端ip为10.0.0.1。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2Fytl6MERBdlV1T55YBZZx%2Fimage.png?alt=media\&token=6452a929-c2a0-48ec-bc0d-e9aabf6edf88)

* **tftp命令**

如果shell支持tftp命令，首先在本机上下载[tftp工具](https://pjo2.github.io/tftpd64/)，开启tftp服务器。在终端设备的文件系统的/tmp目录下，使用命令`tftp -pl R7000.bin 10.0.0.2`将固件上传到本机的tftp服务器中。测试案例中本机ip为10.0.0.2，物联网终端ip为10.0.0.1。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FseoFrb12taF8LqsoQo0u%2Fimage.png?alt=media\&token=f31b919d-59cd-43c4-8ef5-c3d546204fc4)

* **nc命令**

如果shell支持nc命令，首先在本机终端shell上执行命令`nc -lp 1234 >R7000.bin`，随后在物联网设备shell终端上执行命令`nc 10.0.0.6 1234 <R7000.bin`。测试案例中，本机ip为10.0.0.6，物联网终端ip为10.0.0.1。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2Fo6nN7PJIcjMISxIcukRb%2Fimage.png?alt=media\&token=db618d6a-c275-444c-bf54-c3ec507ac861)

* **web页面获取**

如果shell支持mount、df命令，首先使用"df -h"命令查看根目录挂载名称为`ubi:rootfs_ubifs`。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2F1wJWOm45tgW841WjwToU%2Fimage.png?alt=media\&token=4cddbccd-7df9-41d2-a7a8-e9e04428393e)

常见的/www目录一般为只读权限，需要使用命令`mount -o remount,rw ubi:rootfs_ubifs`重置文件系统的读写权限。随后将/tmp目录下的AX88U.bin文件覆盖了/www目录下能够直接访问的前端页面。由于文件系统内存容量不够，所以提示空间不足。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FWEn7qRbZhrjQ75omGiqV%2Fimage.png?alt=media\&token=b752f536-2721-4ff9-bf20-19518b167443)

测试终端所覆盖的页面为`/blocking.asp`。通过访问设备前端页面，最终将固件下载到本机。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FQ0x1X1JIJsHy4QDtMZhC%2Fimage.png?alt=media\&token=e5d8e61c-a83b-48c9-8068-fbf8ce47f4ba)

### 四、硬件获取

#### 4.1 **飞线法读取**

直接将导线连接到芯片的引脚，在通过飞线连接编程器，进行在线读取固件。通过夹具夹住芯片引脚，然后连接编程器读取芯片内容，通过编程器连接芯片需要注意引脚的顺序，在 IC 芯片上都会有一个小点，大多数情况下，小点对应的引脚即为芯片的第一脚，而连接编程器的导线也需要插入编程器上相应的引脚。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2Ft1bpm2As61EcJLeuLvcy%2Fimage.png?alt=media\&token=631cd605-0014-4951-9c68-0204bbc3e7b4)

#### 4.2 **拆焊芯片读取固件**

把芯片拆焊下来，通过烧录座编程器，离线读取固件。一般情况下，对于 TSOP8 封装的闪存芯片，可以用上述方法来读取，但可能存在在线读取成功率不高或数据丢失的情况，对于更多引脚和封装格式的芯片，飞线的难度更高，有一定锡焊基础的建议采用拆焊芯片，用烧录座离线读取的方法。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2F3URi8sTSxcqA9t9iuIO2%2Fimage.png?alt=media\&token=b8222fae-45c8-4771-a7e1-1d27279ee8a5)

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FaQj0NidI03NYta427GP0%2Fimage.png?alt=media\&token=1fc65fbb-3ca5-43f6-84d3-2b904ab14f8f)

#### 4.3 J**tag提取固件**

* **拆焊芯片→烧录座连接Jlink→读取固件**

首先用热风枪拆下智能锁主控芯片；芯片第一脚对齐烧录座第一脚，然后把 Jlink 插入烧录座引出的 JTAG 接口。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FFhoTe3OZl5mqOYhV2kvr%2Fimage.png?alt=media\&token=bc380c2d-9986-4c29-9ee0-33cb83ea7308)

电脑上安装好 Jlink 驱动，打开 J-Flash 客户端，设置好参数，主要在配置栏选择正确的芯片型号，然后点击连接，在点击 Target->Read Back->Entire trip 即可读写固件。

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/872bc42054768e0f/5b3524c6c08bb.jpg)

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/872bc42054768e0f/5b3524ced11a4.jpg)

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/872bc42054768e0f/5b3524d65ced7.jpg)

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/872bc42054768e0f/5b3524db79b3c.jpg)

![](https://img-1253984064.cos.ap-guangzhou.myqcloud.com/872bc42054768e0f/5b3524f327ac3.jpg)

### 五、其他方式

针对于上面几种方法都无效的情况下，可以使用其他一些比较取巧的方法来获取固件。

#### 5.1 网上购买

一些固件爱好者可以会收集各种厂商的固件，放到网上出售。一个固件一般几元到几十元不等。

如：<https://www.qyyd5g.top/> 联系到卖家，提出想要的固件型号，可以询问到价格，付款购买即可。

![](https://1174461437-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlLEV5Rrf0TFHD0Ld3R7q%2Fuploads%2FFy9KjlsW1Rx8SmWu1hG4%2Fimage.png?alt=media\&token=2e5b0539-f3ee-4a8b-bca0-ca97c4302913)

#### 5.2 社工（向售后/客服索要固件）

在产品的官方网址中找到客服的联系方式：如QQ/微信/电话等。得到联系方式之后就可以和客服聊上，说清楚索要固件的目的。可以说自己的设备无法正常运行，需要刷最新版的固件，但是设备的在线升级功能失效了，等等。这里千万不能说要对固件进行逆向分析和漏洞挖掘之类的，这样会太过暴露了。

#### 5.3 U-BOOT

在 u-boot 的命令行中，可以使用一些命令对 flash 的内存空间进行操作，我们就可以使用一些内存分割的操作，将 flash dump 出来。

#### 5.4 故障注入

使用硬件安全/在板攻击/错误注入攻击。

来源： [***海特实验室***](https://github.com/DasSecurity-HatLab/HatLab_IOT_Wiki)&#x20;
