# 华为智联旗下小豚AI摄像头的完整分析（上）

## **简介**

分享一下华为智联旗下的小豚AI摄像&#x5934;**。**

## **外部分析**

照惯例，拿到一款新设备肯定是正常使用一下，看看设备都提供什么功能、猜一猜其背后的运行逻辑。通过监听正常使用时的通信数据，可以获得手机、摄像头通信内容如下图所示：

![图2-1 摄像头和手机之间的通信内容](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsCbUBttty9tgDOCm%2F-MdLsX4ZPwRqtF0KkYiH%2Fimage.png?alt=media\&token=4ebb8370-c741-4510-b88c-b632051893de)

上图中，手机和摄像头之间存在COAP协议通信数据。此部分通信仅在给摄像头配网的过程中出现，在这之后，手机和摄像头不再直接通信，而是完全由云端转发两者的通信数据，摄像头和云端的通信内容如下图所示：

![图2-2 摄像头和云端之间的通信内容](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsCbUBttty9tgDOCm%2F-MdLs_ql7pDxS56Fkpch%2Fimage.png?alt=media\&token=dca64f97-8c0c-4d7c-bbfc-d0a12892009a)

可以看到，摄像头与云端的绝大部分通信都是TLS加密通信。事实上，摄像头对云端的TLS证书有校验，我们无法用简单的中间人攻击拿到通信内容。 除通信监听外，我们还对摄像头开放的tcp端口进行了扫描，截图如下：

![图2-3 对摄像头进行nmap扫描](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsCbUBttty9tgDOCm%2F-MdLsdcj-9nYr6IYh9SG%2Fimage.png?alt=media\&token=16f44587-8387-4687-adb9-910f965b0656)

结果显示该设备并没有监听任何tcp端口，是个麻烦的设备啊。

## **硬件分析**

在此前的文章中，我们已经分析过不少设备固件了，这里就轻车熟路地开始吧。简单翻阅设备官网，可以确定固件并没有在官网提供下载链接。那就直接拆开设备看一看吧，如下图所示：

![图3-1 摄像头电路板](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsjchEugXPyQLw3Qk%2F-MdMGyhuLNd-gwxM9Ty2%2Fimage.png?alt=media\&token=f2afa478-a708-4e8e-8ae0-55a0b1885708)

可以看到，该设备使用hi3518ev300作为SoC，还有型号为winbond的16MB Flash存储器。&#x20;

分析过华为设备的小伙伴肯定知道他们官网是没有公开海思芯片的相关资料，只有经过官方认证的组织才能拿到指定型号的芯片手册，显然我们并没有被认证。不过，万能的淘宝帮了我们一把，可以在淘宝上买到了hi3518ev300的芯片手册以及开发SDK，这些资料在后文中发挥了重要作用。

![图3-2 淘宝购买全套资料](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsjchEugXPyQLw3Qk%2F-MdMH3WV_Aou13WW-Xmc%2Fimage.png?alt=media\&token=56434dd6-8ff8-42e7-8626-562233e1178e)

将Flash存储器用热风枪从板子上吹下来，放入编程器提取Flash内容，并将提取得到的文件交给binwalk分析一下，结果很让人满意，该分析的都分析出来了，如下图：

![图3-3 binwalk分析结果](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsjchEugXPyQLw3Qk%2F-MdMH6Og6k7Et5XOZBxP%2Fimage.png?alt=media\&token=836b0aa5-b55a-4fbf-86f8-93c1462c981f)

在IoT奖励计划的列表中，路由器、AI音箱2等设备都是无法直接用binwalk分析的，有机会再和大家分享那些设备的分析过程。&#x20;

通过binwalk的分析结果，我们可以确定摄像头中运行了一个嵌入式Linux操作系统，那么，接下来的工作就是以某种方式登录到系统之中，由此观察系统中程序的运行状态并调试感兴趣的程序代码。虽然qemu也可以用于调试工作，但在原设备上直接分析和调试肯定是更好的选择。为了登录系统，我们踩了不少坑，这些踩坑过程我们就不在文章中复述，感兴趣的读者可以找找当时会议分享的PPT，这里直接给出我们用到的3种登录方法：串口登录、telnet登录以及反向(reverse) shell 登录。

## **串口分析**

借助在淘宝买到的芯片手册以及万用表，就可以确定电路板上悬空的几个过孔即为SoC的UART接口，如下图：

![图4-1 电路板UART接口](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsjchEugXPyQLw3Qk%2F-MdMHCurtQCuYVRZwPy7%2Fimage.png?alt=media\&token=0ef286c0-5091-4c5e-a6de-85f488fa4dbb)

仅仅接通电路板上的UART接口是无法正常使用UART串口的，开启摄像头的串口还需要两步操作：其一是调整uboot在引导linux kernel时使用的启动参数(bootargs)；其二是调整linux启动脚本中对串口的各种设置。 用16进制编辑器打开固件中的uboot部分，观察这部分固件内容，并与SDK文档中描述的uboot固件结构进行对比，如下图：

![](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsjchEugXPyQLw3Qk%2F-MdMHGIYqpItk-DBQkOo%2Fimage.png?alt=media\&token=1e5fa228-ddac-4534-a6f5-f75e48a07cb8)

![图4-2 摄像头固件结构](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsjchEugXPyQLw3Qk%2F-MdMHIn03pOZSJrmcq58%2Fimage.png?alt=media\&token=0f104ec8-753d-46a8-a85d-521d1cec2f61)

通过对比图4-2上下两图，可以确定起始4个字节为magic word，代表着设备启动了secure boot机制。在该机制的保护下，boot rom代码会对uboot部分进行RSA签名校验，以防止uboot程序被篡改。紧接着4个字节代表uboot部分的总长度，在该设备中为0x036A58字节。&#x20;

由于整个uboot部分被RSA签名校验保护，而我们又没有签名私钥以重新计算签名，所以uboot这部分是没办法改动的。但是通过深入地逆向分析uboot代码，我们发现uboot并没有对固件其他部分进行签名校验，这意味着我们可以随意调整文件系统。此外，我们又发现了linux kernel的引导参数被保存在了uboot之外的部分，如下图所示：

![图4-3 摄像头Linux启动参数](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsjchEugXPyQLw3Qk%2F-MdMHNiymLrrVpYV3zLl%2Fimage.png?alt=media\&token=a439afb8-36c1-466b-8d7f-69a8f0a8d0d6)

上图中，kernel的引导参数保存位置为0x40000，已经超过了uboot的范围。所以我们可以调整引导参数，如下图：

![图4-4 调整Linux启动参数](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsjchEugXPyQLw3Qk%2F-MdMHRGePOODxLQwiV7S%2Fimage.png?alt=media\&token=f8501071-0d23-47a5-a712-ae17c681783f)

上图中起始的4个字节为crc32校验，我们更改了启动参数，所以需要重新计算crc32值并填回此处。 接着，查看squashfs文件系统中的启动脚本(big\_run.sh和small\_run.sh两个)，并对比SDK文档中芯片手册内容，如下图：

![](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsjchEugXPyQLw3Qk%2F-MdMHUaD_8Vmp1ax6bKo%2Fimage.png?alt=media\&token=324d5c40-1602-4c91-b93a-cf9e131e035e)

![图4-5 启动脚本中队引脚的设置](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsjchEugXPyQLw3Qk%2F-MdMHW8MHLE_Ep9IbUGT%2Fimage.png?alt=media\&token=358a21f5-d990-48f6-818d-2abeebc6f17e)

可以看到，在启动脚本中，SoC的此引脚被设置为GPIO功能。我们需要调整启动脚本，将该引脚重新设置为UART功能，如下图所示：

![图4-6 调整后的启动脚本](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsjchEugXPyQLw3Qk%2F-MdMHZ8TF_kgk7CyZlAh%2Fimage.png?alt=media\&token=b9969000-d751-48b2-a321-f4f070fcbe8f)

在完成上述两个调整之后，需要将固件重新打包并烧录至Flash中。由于linux启动脚本在binwalk提取的squashfs文件系统中，所以我们需要用SDK中的mksquashfs工具，重新打包squashfs文件系统，具体方法在胖猴专题之前的关于海康萤石设备分析的文章中介绍过，这里就不再赘述。&#x20;

完成以上工作后，给设备重新上电，即可使用串口登录设备，如下图：

![图4-7 通过串口顺利登录设备](https://3519990514-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mc9RUlvJLCDxdpf1zh2%2F-MdLsjchEugXPyQLw3Qk%2F-MdMHbUIyaToyn9K8Hzu%2Fimage.png?alt=media\&token=858696ba-6666-49c1-a069-1b5eb5a0ab35)

到此即是我们对小豚AI摄像头的第一篇，在本文中，我们对此设备进行了简单的外部分析，并顺利的开启了设备的串口功能。但事实上，我们分析的很多设备是无法启用串口的，所以在下一篇文章中，我们会继续分享其他的系统登录方法。在登录系统之后，我们还会分析其中的一个关键程序，就是产生TLS加密通信的关键程序。最后，还希望各位读者能够从中有所收获。
