# 智能设备漏洞挖掘之固件提取

## 前言

&#x20;     上周六在看雪安全峰会分享了一个议题，整理了一下分享过程中的一些内容，做了一个简单记录，有些地方由于时长有限，可能过的比较快，感兴趣的朋友可以看一下文字的一些记录，议题的PPT和视频demo上传至百度云了，论坛里有需要的朋友可以下载下来，欢迎一起学习和交流。

同时也是首次公开一种本人在对智能设备进行安全测试过程中摸索和总结出来的一种uboot提取固件的方法。

链接：<https://pan.baidu.com/s/1d3zuTKPKb-hg4kM_Qxf9Hw>

密码：pf1b

下面是根据我当时演讲的发言，从速记员的记录整理的。

非常感谢看雪邀请我在这里做演讲！题目是“智能设备漏洞挖掘中的几个突破点”。

我来自绿盟科技工业物联网安全实验室，专长是硬件的固件安全。插播一条招聘广告，如果对工业物联网安全研究有兴趣的朋友，欢迎联系我们。

## 一、智能设备基础知识

这是智能设备的组成，分为几个部分，智能设备必须有这么几个东西，比如它必须有CPU、内存、相当于硬盘的flash，有网络、网口接口、串口，有时会有SD卡插座存储设备，也有的有显示界面。

![](/files/-MDSgFWcNiVd2xENMFkB)

CPU有很多架构，有X86、MIPS、ARM等；

内存分为好几种。存储也有各种，比如flash、TF卡、mmc卡、硬盘；

一般的电路板都会留串口，尤其做调试时。厂商做维护时不得不面对的问题：智能设备如果在使用中出现了问题，客户要求马上给解决，如果开发者没有维护的接口，开发人员到现场可能解决不了问题。所以这些是必备的，有时是串口，有时是网口之类的，有时候是USB口。

智能设备内运行的软件也叫固件，固件有对系统进行引导的部分，常用的是Uboot，这占很大市场份额；操作系统用Linux非常多，因为它对网络的支持非常好。

### 串口

![](/files/-MDSgSNlCrtuAM53wsKQ)

跟大家介绍一下什么是串口，串口一般分为两种类型，主要是RS232或者TTL，TTL是5V或者3.3V，相当于CPU的电压。左下角是对串口的定义，串口真正引用的是三条线，就是RXD、TXD、DCD。串口传输时，有三根线的时候，是按照一定的时序传输的，这个时序有一定的周期，这个周期是异步产生的。异步传输有一个波特率的概念: 如:9600的波特率,换算过来大概1秒钟传送1000个字节。波特率越大，传输越快。

### flash

![](/files/-MDSgYtOMddFl60O1rYe)

智能设备的组成里比较重要的还有flash，分为两种，一种是Nor falsh，它的特点是价格比较贵、容量小、地址线和数据线是分开的，好处是CPU可直接寻址，因为电路图上每一个地址线都是单个连出来的，数据线也是单独连出来的。它常用做代码存储，存储容量越大，这个地址线是越多的。

算一下上图的nor Flash的地址线的寻址范围:&#x20;

8MB = 0x800000(16进制)\
换算成二进制: 100000000000000000000000\
地址线正好是从addr0 - addr22. 最大地址是22个1

![](/files/-MDSgeWZq-UE6I0gQJ7d)

还有一种是Nand Flash，它价格便宜、容量大，主要用作数据存储，但这个东西一般是不可寻址，需要驱动程序。

### Uboot和busybox

下面讲一下软件里面的Uboot和busybox，Uboot在嵌入式里一个功能是做引导程序，启动的时候引导用，还有一个功能是做更新时用.支持CPU的种类比较多，比如ARM、Linux、MIPS、PowerPC都支持，也支持简单的网络命令之类的。Busybox集成了三百多个常用的Linux命令和工具软件，它非常小巧，编译后大概在1-2兆左右，但支持的命令非常多，而且可以根据需要做裁减。例如：有的裁剪了busybox的指令nc,dd,tar等。

![](/files/-MDSgiQRkFu-oeEarDof)

### 智能设备软件和硬件的协作关系

![](/files/-MDOEOp_Fc1mrmKDRZ_T)

这是智能设备软件和硬件的协作关系，以Linux操作系统为例，上面是内存，下面是存储flash，中间是固件，固件里面的Uboot是启动时引导用的，启动起来是kernel，后面跟着是文件系统，文件系统里面包括RAM FS和FALSH FS。

![](/files/-MDOG2eWniXAYHue3ngu)

这是升级接口，我们对维护接口要有一定的了解，为什么？因为接口是非常重要的，一个是升级时要用，另外一个是调试时要用，还有一个是升级固件时要用。调试接口的基本就是这几个功能。

## 二、 提取固件的十种思路

&#x20;这十种思路是我所熟知的，是我经常用的十种方法，其他不讲的方法并不代表不存在。固件提取方法简单分为硬件和软件两种类型。

![](/files/-MDSgn3xftUnWJTiVpMI)

我刚才对基础知识做了大概的介绍，比如我要提取它的固件，它的固件放在flash里，我肯定要做一些了解。还有对串口和接口都要有研究。还有固件里面支持这些程序，对文件系统、基础小命令等都要有一定的了解，这些知识和技巧利用好是可以发挥很大功效的。

智能设备提取固件的十种思路：

![](/files/-MDOKCGdbjjAs0DrpVoj)

这里先讲九种固件提取方法, 最后一种方法给大家一个惊喜!

### 1、 官网或联系售后索取升级包。这点不多讲。

![](/files/-MDOLW_jTc0yDHKCyzMp)

### 2、 在线升级方式提取固件。

如果有手机应用或者电脑应用，可以点“升级”，升级固件的时候就可以通过抓包的方式，把固件给抓到。如果老版本和新版本固件的下载地址有一定的命名规律的话，新版本抓到了，老版本也可以猜出来。PPT这只是一个例子，并不针对于任何厂家。

![](/files/-MDOLbOSyeysjd81HldS)

### 3、 逆向升级软&#x4EF6;**。**

软件内置解包和通讯算法。如果它的设计是在下位机解密的话稍微安全点；在上位机解密的话是可以逆向破解的。

![](/files/-MDOLqiQiMgMe6fNg9ML)

### 4、 从调试接口：JTAG/SWD等方式获取固件。

![](/files/-MDOMc3B2j4dWbV0YtSY)

腾讯玄武实验室的小马哥去年有两次公开讲解，今天时间所限，不做描述。

![](/files/-MDOMkV-dqbWGUHFoW4L)

### 5、折flash、SD/TF卡、硬盘等，用编程器/读卡器获取固件。

常用的是焊下flash芯片,用编程器读取固件，读完后再把芯片焊回去。

![](/files/-MDOMyXFXmFeJHm-QrKz)

需要注意的是芯片是有方向的，第一脚的地方有一个圆点，焊接或用编程器读取时，弄清芯片的方向。

![](/files/-MDON6bjSd0YIWpKzViK)

### 6、从串口（UART）调试口获取固件。

![](/files/-MDONVheV4uaWrLZB5Xd)

这种方法是我在安全测试中帮客户测试产品总结出来的。厂商自己做的产品，它在安全方面有追求，但可能力不从心，就找我们做安全方面的测试。还有OEM的产品要上市了，贴大厂的牌子，大厂肯定有安全方面的要求，不希望OEM产品砸了它的招牌，这时也会找我们做一个测试。

在安全测试过程中我发现了uboot提取固件漏洞,总结出了一系列固件提取方法。

&#x20;    我最常做的是工控设备漏洞安全的研究，这个东西基本是拿不到固件，拿到的固件也是加密的，困扰了我很长时间。经过一段时间摸索之后，有了10来个成功的提取固件的案例。今年又在摄像头方面，普通物联网路由器、摄像头等类似设备，经过实践研究有二三十个成功案例后，发现通过串口提取固件的方式是最稳妥、最可靠的。为什么这么说呢？去给客户做测试时，客户说，随便你折腾，坏了也无所谓，但样品就这一个！我想焊下flash提取固件，但设备就这一个，万一焊接芯片搞坏设备了，后面就无法验证漏洞了。关键是工控设备一个就2、3万，5、6万，10几万，一旦给客户搞坏设备了，就比较尴尬了。所以我慢慢想出了一些办法，在这里与大家分享。

&#x20;    串口识别：串口有两种标准，串口识别的时候，一般是把设备拆开以后，串口一般有四个脚，第一步要找到地（GND），地是很好找的，和电源相连的那个地，或者芯片跟地相连的。地确定了以后，我们把它接到USB接口上，我先把接收的脚接上，两个脚都有可能是高电，这时把接收的脚和地接上，然后随便接上一个脚，设备一启动，如果这个时候只要有输出了，就是接对了；然后把另外一个脚一接，三个脚就接好了。我一般找串口就是上面的思路。

7、修改uboot启动脚本进入密码保护的登陆系统，这页ppt是修改uboot启动脚本进入密码保护的登陆系统思路，不展开讲了。共5条，每一条都是一个不用密码进入系统的思路。

![](/files/-MDOWmKahtCi21ojKitu)

前面说到uboot，每次启动时都有3秒时间，这个时间是可设的，一般有3秒时间在等待输入(或者其它快捷键,一般有提示)，进入uboot模式后,uboot有帮助命令，这些命令里有一条引起我的注意，就是md。md有什么作用？显示内存，能够把内存显示出来。这就有点意思了。发现只要是Nor flash，md可以把Nor flash的内容显示出来（因为nor flash可以通过CPU直接寻址），这就相当于md命令可以提取固件。但md命令是需要知道起始地址和长度的，知道起始地址和长度就可以把固件提取出来。怎么知道起始地址和命令？我查看了更多的命令的信息，结果发现bdinfo和flinfo可以查看到flash起始地址和容量。如果还是找不到的话就重启一下，重启时不要打断，看它会不会打印更多flash地址分布信息，通过这些信息基本就能找到起始地址把固件提取出来了。

![](/files/-MDOWzbmksGxOrKgFd1i)

最后把uboot提取固件的流程总结出来了：第一步，获取flash的存储信息，它这个flash有多大、什么型号的、CPU访问它的地址区间是什么？第二步，用md命令提取固件信息。第三步，记录下来。第四步，分析输出信息，获取固件。但这个方法的缺点是时间长一点，有的时候半个小时，有的时候2个小时。但这也无所谓，只要能稳定的提取固件，不要把硬件损坏，焊3条线就可以搞定了。

视频请工作人员帮我放一下。（视频播放）我用简单的命令去尝试，果然能够读到内核。下一步就全部读出来，提取固件了。把上面的信息删除掉，当时的内存地址信息和固件没关系就删掉了，右边ASCII码信息没关系也删掉了。最后把文件转成二进制，就是我要得到的固件。

![](/files/-MDOXD6P7MG_HYvK0DAM)

成功案例比较多，暂时没有失败的案例。总结为三个难度（第三个Level难度不讲），Level1最简单，用md就可以搞定了，只用Nor flash做存储。

![](/files/-MDOXIvN7rWlI28gkxyO)

Level2级别是Nand flash里有其他文件系统，这里有一个命令先把nand flash读到内存，然后用md把内存读出来，这个简单的思路就可以搞定了。

![](/files/-MDOXY2MEKchBF2fFdbz)

这是我当时调试的经验，发现用上面的这些命令可以获取信息。另外一种需要重启，重启的方式有时会打印关键地址信息。

还有读取命令，把flash里的md直接读出来，如果读不出来就用其他的思路，把SD卡或者其他文件系统的存储读到内存里，最后再从内存里读出来，基本就是这个思路。

![](/files/-MDOY-9c1u6HrL_tyd_V)

Uboot提取固件不是针对某一个厂商，几乎所有厂商都存uboot安全问题，嵌入式设备里面95%都用uboot作为它的启动，基本相当于嵌入式Linux的一个标配。在开发者大会上希望与开发者做个沟通，也希望安全研究员有新的固件提取方式或者有些漏洞利用的方式能够让开发者知道，也是为了让厂家更快修复漏洞，为安全做贡献。这个方法有可能成为未来一段时间提取固件一个比较流行的方法，我发现基本都能提取出固件来。

![](/files/-MDOXnpQkT3iFwlZxo6X)

### 7、通过利用网页和通讯漏洞获取固件的敏感信息。

这个就不做演示了，只要做安全的，这种都是小问题，通过网页能够把敏感信息提取出来，再通过字典产生密码暴力猜解passwd的破解设备口令。一般是嵌入式系统的权限配置不当。

### 8、用逻辑分析仪监听flash，ram获取信息。

它的优点是不用拆东西，只要把这个东西接上去就可以了，而且这个东西也挺好接的。但缺点是逻辑分析仪目前价格便宜的频率低，但flash一般频率比较高，都是100兆、200兆。我做了一个实验，结果发现确实是可以的。需要把这几个脚引出来，在它启动的时候抓取数据，用夹子夹在芯片上，那个标红色的脚是第一脚。抓在上面以后，通过SPI接口把传输的这个数据保存。

![](/files/-MDOQzuhTyhtqWeavJin)

前面是SPI的命令，命令里面这个是输出的数据。前面第一个是读的意思，这三个应该是地址，后面的是数据。这边是发出的命令，那边是接收的命令，结果是这个逻辑分析仪提取出的东西跟flash里的固件的二进制是一致的，说明这个思路是可行的，我当时找了一个速度稍微慢点的设备，也是可以把固件提取出来的。

![](/files/-MDORMUJH4k6_AjzzBNZ)

### 9、用tar/dd、nc提取固件。

利用原来的硬件接口，再用它原来的软件，可能会达到事半功倍的效果，不用焊板子。这里先是用串口，通过串口得到系统权限，用nc从网络传输固件出去。

![](/files/-MDOTI1Syg3qHzhf29p9)

### 10、综合应用

第十种固件提取方法是，前面几种方法的融会贯通，综合应用。它相当于“降龙十八掌”的最后一掌。

通过串口获取权限的话，如果运气好，它也没有设登陆密码，如果能够进入系统，就用这种方法：通过USB或者SD卡，执行拷贝命令、打包命令，把这个打包到U盘里或者大的内存文件系统里，然后再拷贝到外置文件系统里(U盘或TF卡)。

第二种是发现echo命令可以通过二进制方式写入“1234567”，用输入命令的方式发送二进制文件，通过命令的方式传输木马，这个木马把固件输出来，通过串口记录输出,这也是一个思路。

![](/files/-MDOVCR8joUuVmxrV0p0)

总结固件提取方法：智能设备普遍存在uboot，如果没有把md类似的命令屏蔽掉，是可以轻易提取固件的。智能设备固件存在flash里，flash没有保护固件被非法读取的措施。如果FLASH和RAM集成在CPU上，并且开启了加密的话是比较难提取固件的。但如果它用另外一种方式：（FLASH和RAM、CPU分别独立）,是特别容易被提取固件的，原因是拆下FLASH用编程器直接能读到flash里面的内容了。

硬件调试接口方法方便了维护客户，但有时也方便了不速之客，软件如果留一个后门是便于维护，但密码太简单的话容易被破解或者猜测，或者容易让别人从固件里分析出来。结论是目前部分智能设备的架构存在一定安全隐患。

![](/files/-MDOVZ3mMLiPr0T0ue_k)

## 三、 从固件发掘漏洞的思路

### 智能设备固件拆解

用binwalk进行固件拆解，有些同事用binwalk解不出来，但我能够解出来，为什么？因为它是没有掌握binwalk的安装方法，binwalk有些依赖的软件，这些依赖的东西都要装全。有一个命令（./deps.sh）是需要执行的，会把所有相关的依赖的软件安装，安装以后就比较好提取了。我常用的-Me的方式提取固件。

![](/files/-MDOYR8xU6IwCKCBJ0km)

这里举了一个例子，可以通过密码字典暴力破解的方式破解linux登陆密码，如果它的密码比较简单，很快就破解出来了。

![](/files/-MDOYbe5EekCH6W65Fe5)

### 从固件挖掘漏洞的思路

我以前做过开发，所有的问题如果没有思路时，就想一下开发人员会怎么做？他会留下什么调试后门？有什么接口？如果你提取固件以后。能不能查固件里系统的敏感信息？看一下厂家有没有留下维护的后门密码？如果有后门密码就简单了。这些看完了以后，看总共有多少网络服务、网络端口，网络服务运行的二进制有没有溢出点，把web调用接口调试调试，看看有没有问题。基本就是这些思路，非常简单。时间有限，只能点一下。

![](/files/-MDOYwTdCVaBv_6GrBmQ)

## 四、 智能设备的加固建议

### 信息隐藏

信息隐藏非常重要，比如uboot把固件提取出来就是因为知道它是什么芯片，如果芯片是打磨的可能好一点，或者把封装改了也好一点，这些重要信息要注意隐藏。

![](/files/-MDOZ2Um6a3qTvB2b1pS)

### 安全的开发、维护和调试接口

调试接口能不能屏蔽掉，比如软件的、硬件的屏蔽掉，或者busybox不用的功能能不能去掉和裁剪掉。比如，智能设备进入系统都是root权限，权限太大，可以干的事情太多了，这些是可以避免的，不一定要给root权限。

![](/files/-MDOZE_uPSY6ae13WVzt)

### 其他加固建议如PPT。

![](/files/-MDOZP8j3pAHOoL0kjBo)

议题的PPT和视频demo上传至百度云了，那几个活跃气氛的gif图片也在里边，有需要的朋友下载看看，欢迎一起学习和交流。

链接：<https://pan.baidu.com/s/1d3zuTKPKb-hg4kM_Qxf9Hw>

密码：pf1b


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://functfan.gitbook.io/gewuzz/lou-dong-wa-jue-1/lou-dong-wa-jue/wu-lian-wang-lou-dong-wa-jue-ji-shu/zhi-neng-she-bei-lou-dong-wa-jue-zhi-gu-jian-ti-qu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
