> For the complete documentation index, see [llms.txt](https://wokough.gitbook.io/iot-firmware-aio/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wokough.gitbook.io/iot-firmware-aio/wiki/gu-jian-huo-qu.md).

# 固件获取

### 一、概述

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

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

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

### 二、官网获取

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

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

![Tenda](/files/nAP9IuHpTN3JWKXH5Ltq)

![tplink](/files/gDtqVl90xhVWrglJGxOY)

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

![](/files/g1OWzo1WvwAITP1o3T7F)

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

![](/files/iAtgIZbIBhA0aBiBrXLD)

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

[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串口上的相应引脚。

![](/files/pfmVOn59Cj9rTF1WEmNU)

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

![](/files/tkIAlHlEJtinMRVLEvRn)

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

![](/files/M33jDATqaPDMATkhIc9C)

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

![](/files/tkbLM2NOgYkIOi3lR3Q6)

将万用表调至直流电压档，将黑表笔接到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"命令，可以看到设备的相关信息。

![](/files/Js6eWt60YSzEfRnVrKv1)

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

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

![](/files/j1mPqN0prcHnltBykkVo)

使用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。

![](/files/7AgMRTmevY3K9VVXOsdQ)

* **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。

![](/files/qYofwI4hZaa2QiSAVhts)

* **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。

![](/files/nTaQGG7Ldn6g2hlBPtgR)

* **web页面获取**

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

![](/files/fnzvsZU0WyklCwu45ymI)

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

![](/files/LJgMMCZ0tpA1HRD2Tr1I)

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

![](/files/irJ8wnOWhZSrLMNu85nK)

### 四、硬件获取

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

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

![](/files/muGaw1j98a3kh5MPASZH)

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

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

![](/files/VoVpaEqYkM0rbBbSDe2t)

![](/files/OuHdhyMabNPETXq0cfxJ)

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

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

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

![](/files/9bxJL8Vg06fI7jIk9zRE)

电脑上安装好 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/> 联系到卖家，提出想要的固件型号，可以询问到价格，付款购买即可。

![](/files/O9YFMU9zumkw2NEAqTDH)

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

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

#### 5.3 U-BOOT

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

#### 5.4 故障注入

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

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