小豚AI摄像头的完整分析
2021-04-02 18:58:00 Author: mp.weixin.qq.com(查看原文) 阅读量:136 收藏

本文为看雪论坛精华文章

看雪论坛作者ID:胡一米

一、简介

本篇中,我们打算分享一下小豚AI摄像头,这也是我们在2020年某AIoT安全峰会上的分享内容。我们在去年某日收到了一批赞助,赞助内容为华为IoT终端奖励计划列表里面的大部分设备,如下图:
图1-1 华为终端IoT奖励计划列表
小豚AI 摄像头就是表格中的一项,而且在上图的所有设备中,小豚AI 摄像头是分析难度比较小的一款设备,比较适合与大家一起分享。

二、外部分析

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

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

图2-2 摄像头和云端之间的通信内容
可以看到,摄像头与云端的绝大部分通信都是TLS加密通信。事实上,摄像头对云端的TLS证书有校验,我们无法用简单的中间人攻击拿到通信内容。
除通信监听外,我们还对摄像头开放的tcp端口进行了扫描,截图如下:
图2-3 对摄像头进行nmap扫描
结果显示该设备并没有监听任何tcp端口,是个麻烦的设备啊。

三、硬件分析

在此前的文章中,我们已经分析过不少设备固件了,这里就轻车熟路地开始吧。简单翻阅设备官网,可以确定固件并没有在官网提供下载链接。那就直接拆开设备看一看吧,如下图所示:
图3-1 摄像头电路板
可以看到,该设备使用hi3518ev300作为SoC,还有型号为winbond的16MB Flash存储器。
分析过华为设备的小伙伴肯定知道他们官网是没有公开海思芯片的相关资料,只有经过官方认证的组织才能拿到指定型号的芯片手册,显然我们并没有被认证。不过,万能的淘宝帮了我们一把,可以在淘宝上买到了hi3518ev300的芯片手册以及开发SDK,这些资料在后文中发挥了重要作用。
图3-2 淘宝购买全套资料
将Flash存储器用热风枪从板子上吹下来,放入编程器提取Flash内容,并将提取得到的文件交给binwalk分析一下,结果很让人满意,该分析的都分析出来了,如下图:
图3-3 binwalk分析结果
在IoT奖励计划的列表中,路由器、AI音箱2等设备都是无法直接用binwalk分析的,有机会再和大家分享那些设备的分析过程。
通过binwalk的分析结果,我们可以确定摄像头中运行了一个嵌入式Linux操作系统,那么,接下来的工作就是以某种方式登录到系统之中,由此观察系统中程序的运行状态并调试感兴趣的程序代码。
虽然qemu也可以用于调试工作,但在原设备上直接分析和调试肯定是更好的选择。为了登录系统,我们踩了不少坑,这些踩坑过程我们就不在文章中复述,感兴趣的读者可以找找当时会议分享的PPT,这里直接给出我们用到的3种登录方法:串口登录、telnet登录以及反向(reverse) shell 登录。

四、串口分析

借助在淘宝买到的芯片手册以及万用表,就可以确定电路板上悬空的几个过孔即为SoC的UART接口,如下图:
图4-1 电路板UART接口
仅仅接通电路板上的UART接口是无法正常使用UART串口的,开启摄像头的串口还需要两步操作:其一是调整uboot在引导linux kernel时使用的启动参数(bootargs);其二是调整linux启动脚本中对串口的各种设置。
用16进制编辑器打开固件中的uboot部分,观察这部分固件内容,并与SDK文档中描述的uboot固件结构进行对比,如下图:
图4-2 摄像头固件结构
通过对比图4-2上下两图,可以确定起始4个字节为magic word,代表着设备启动了secure boot机制。在该机制的保护下,boot rom代码会对uboot部分进行RSA签名校验,以防止uboot程序被篡改。紧接着4个字节代表uboot部分的总长度,在该设备中为0x036A58字节。
由于整个uboot部分被RSA签名校验保护,而我们又没有签名私钥以重新计算签名,所以uboot这部分是没办法改动的。但是通过深入地逆向分析uboot代码,我们发现uboot并没有对固件其他部分进行签名校验,这意味着我们可以随意调整文件系统。此外,我们又发现了linux kernel的引导参数被保存在了uboot之外的部分,如下图所示:
图4-3 摄像头Linux启动参数
上图中,kernel的引导参数保存位置为0x40000,已经超过了uboot的范围。所以我们可以调整引导参数,如下图:
图4-4 调整Linux启动参数
上图中起始的4个字节为crc32校验,我们更改了启动参数,所以需要重新计算crc32值并填回此处。
接着,查看squashfs文件系统中的启动脚本(big_run.sh和small_run.sh两个),并对比SDK文档中芯片手册内容,如下图:

图4-5 启动脚本中队引脚的设置
可以看到,在启动脚本中,SoC的此引脚被设置为GPIO功能。我们需要调整启动脚本,将该引脚重新设置为UART功能,如下图所示:
图4-6 调整后的启动脚本
在完成上述两个调整之后,需要将固件重新打包并烧录至Flash中。由于linux启动脚本在binwalk提取的squashfs文件系统中,所以我们需要用SDK中的mksquashfs工具,重新打包squashfs文件系统,具体方法在胖猴专题之前的关于海康萤石设备分析的文章中介绍过,这里就不再赘述。
完成以上工作后,给设备重新上电,即可使用串口登录设备,如下图:

图4-7 通过串口顺利登录设备

五、telnet分析

串口虽然可以登录摄像头设备,但毕竟还需要硬件电路连接,使用起来比较麻烦,而如果能通过telnet登录则会更加方便快捷。启动摄像头的telnetd也需要两步操作:其一是重新编译busybox,增加telnetd功能;其二是在linux启动脚本中挂载设备文件。
开始之前,先要把SDK开发环境配置好,比如说交叉编译器等。好在我们买到的SDK还不错,该有的文档、必要的脚本一个都不差,按照指示步骤逐步操作即可。在开发文档中,可以找到配置SDK相关的章节,如下图:
图5-1 配置SDK开发环境
按照上图中的SDK安装方法,逐步配置完成安装SDK。在安装过程中可能需要下载一些文件,别担心,在正常的网络环境下,都是可以顺利下载到的,不需要额外的辅助工具。
接下来,在binwalk提取的squashfs文件系统中,可以找到telnetd软链接,链接到了busybox程序。逆向分析busybox程序之后,就可以发现固件中的busybox程序并没有实现telnetd功能,如下图所示:
图5-2 busybox支持的命令列表
上图中, busybox支持的命令中没有telnetd。为解决此问题,需要重新编译SDK中的busybox程序,我们之前已经完成了开发环境的SDK部署工作。
SDK中包含了编译busybox所需要的代码以及相关的makefile文件,我们只需要调整.config文件,确定编译出的busybox程序包含telnetd、tftpd等需要的功能,然后执行make hibusybox即可,如下图所示:
图5-3 编译busybox时的.config文件
编译完成之后,用编译得到的busybox替换固件文件系统中的原有busybox程序,就可以保证摄像头有了telnetd功能。接下来还需要挂载devpts设备文件,否则telnetd在建立第一个telnet连接后就会崩溃。
将挂载devpts设备文件的两条指令放在linux的启动脚本(big_run.sh和small_run.sh)中,并加上启动telnetd的指令,就完成了对文件系统的全部调整,如下图:
图5-4 调整Linux启动脚本
最后,将文件系统重打包并烧录到Flash中,再次上电后即可通过telnet登录摄像头设备。

六、 反向shell分析

虽然通过前文的两个方法已经能够顺利登录linux操作系统了,但是Flash已经被热风枪吹下来了,就再多准备一种后备措施,这样可以避免因为前两种方法都失效而翻来覆去地吹焊Flash。
在本节中,我们准备了一个简单的反向(reverse) shell作为后备措施,反向shell代码有很多,我们随便选择一种就好,下面的代码段即为我们将要编译的reverse shell代码:
图6-1 反向shell小程序
代码比较简单,建立tcp连接之后,将输入和输出重定向到tcp连接。
用SDK中包含的交叉编译器编译该程序,然后用qemu进行本地测试,测试通过后将其放入固件的文件系统中,然后在linux启动脚本中,增加启动反向shell的指令,最后打包文件系统,烧录固件至Flash中。待摄像头正常启动之后,在主机使用nc监听设置的端口,即可通过反向shell登录设备linux系统中,如下图所示:
图6-2 通过reverse shell登录

七、hilink程序分析

在正常登录设备Linux系统之后,我们就开始分析和调试设备中运行的程序,在前文提到的3种登录方式之中,telnet是最简单易用的,所以我们在后文中统一使用telnet作为登录方式。
首先使用ps指令查看系统中正在运行的关键进程,如下图所示:
图7-1 摄像头设备中正在运行的程序
上图中,有三个关键进程:hilink是负责关键模块、ipc是负责摄像头主要逻辑功能的模块而monitor看起来是负责监控设备运行状态的模块。我们在上一篇中提到摄像头和云端的TLS通信就是由hilink程序产生的,接下来我们就分析分析这个hilink程序。
照惯例,先开启该程序的运行日志。通过逆向分析该程序,可以找到用于判断是否打印日志的函数,如下图所示:
图7-2 打印日志前的判断
上图中,logLevel函数即为判断当前等级(R0=3)的日志是否需要打印,我们只需要修改logLevel函数的返回值永远为1,即可打印出所有日志。
通过运行日志可以大体上掌握程序的执行流程。在程序启动后,首先会在云端注册登录,由关键字符串“LoginToCloud”找到关键代码段,如下图:
图7-3 hilink登录到云端
根据上图中的内容,推测其通信内容除了TLS加密外,还有一次应用层加密。此时,仅仅做静态分析有些困难,我们编译一份gdbserver传到设备上调试一下。在SDK中,包含了gdb项目,只要正常编译出来就可以直接使用。

我们编译的busybox包含了tftp功能,可以用来传输文件。关于gdbserver调试相关的内容,可以参考海康萤石的那篇分析文章,这里不再复述。调试截图如下:

图7-4 调试hilink程序
通过调试可以确定,有很大一部分请求并没有执行hilink_encrypt_coap_buf函数,这意味着并没有进行应用层加密。
接下来,我们试着给程序打个补丁,修正一下其TLS证书,然后做一个中间人攻击,看看是否能够拿到通信数据,用于打补丁的脚本如下:
图7-5 给hilink程序打补丁
这个脚本功能也很简单,只是把程序中的TLS证书更改为我们自己生成的TLS证书。
最后再写一个实施中间人攻击的脚本,将通信内容进行简单的整理,即可获得下图中的内容:
图7-6 获取hilink程序通信内容
上图中的这些通信内容,可以帮助我们继续深入分析,但这里就不做过多的陈述,感兴趣的读者可以自行尝试。

八、小结

关于小豚AI摄像头的分析文章到此就结束了,在这篇分析中,我们介绍了3种登录linux操作系统的常用方式,分别是串口、telnet和reverse shell,各位读者在分析其他设备时可以根据实际情况选择其中一种合适的方法。
此外,经由这篇对这个摄像头进行的各种尝试,设备已经处于一个可调试的状态,文章中我们只对摄像头中运行的hilink程序进行了初步分析,感兴趣的读者完全可以在此基础上继续探索,挖掘潜在的漏洞。
最后,希望本篇文章能给各位读者带来一些收获,如若有什么想商量或者讨论的,可以随时联系我们胖猴微信:PwnMonkey。在后续文章中,我们还会继续分享其他的研究案例,敬请期待。

- End -

看雪ID:胡一米 

https://bbs.pediy.com/user-home-613694.htm

  *本文由看雪论坛 胡一米  原创,转载请注明来自看雪社区。

# 往期推荐

公众号ID:ikanxue
官方微博:看雪安全
商务合作:[email protected]

球分享

球点赞

球在看

点击“阅读原文”,了解更多!


文章来源: http://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458383269&idx=1&sn=2c5ef24d9990e98bfb155fcb72728d14&chksm=b180c32f86f74a39f33993cd024a0bc3de7d2987378c46694887d5428ec385092f96048467f5#rd
如有侵权请联系:admin#unsafe.sh