原文作者:Juan Carlos Jiménez

翻译者:光棍节

原文地址:http://jcjc-dev.com/2016/12/14/reversing-huawei-5-reversing-firmware/

在第四部分我们得到了完整的固件,并成功解压得到其中的所有内容。本节主要是挖掘固件中有趣的代码,通用的漏洞等。

在翻译的过程中,我们跳过了一些关于Linux系统、二进制反编译以及其他一些相关概念的介绍。

一、收集和分析开源组件

华为根据GPL的要求,HG533路由器开源了相关的源代码:下载地址,源代码目录结构如图一所示。

图一 华为HG533开源代码

Bootloader源代码 本路由器的bootloader就是uboot。根据GPL授权要求,华为应该将uboot的源代码开源在官方网站上。本文中没有对其进一步分析。 内核源代码 首先我们看看源代码是否给我们的分析带来帮助,恢复出厂设置按钮是用户用来强制设置路由器的配置恢复成出厂设置,在之前的分析中,已有按下出厂设置按钮后UART打印的信息,如图二所示。

图二 出厂设置UART打印信息

用简单的grep命令,我们可以看到不同该组件(内核、二进制和共享库)的协同工作,如图三所示。

图三 源码中查找部分字符串

有了内核代码能够帮助我们发现安全相关的弱算法以及其他被厂商任何事可以接受的偏弱的实现方法。更重要的是,我们可以编译内核代码,从而实现自己想要的

用户空间源代码

在源代码中,其中部分的组件如busybox、iptables等也已经开源,如果其中的版本偏旧,这些组件本身就可能带有已公开的漏洞。

如果是奔着去找0day漏洞或者后门以及敏感数据的话,你的目标就不是这些开源的组件了,厂商或者某提供商开发的面向设备的非开源的代码一般不会进行详细的安全测试,可能含有较多的bug。这些代码会编译成二进制文件存放在用户空间中,我们有所有的文件系统,当然就有这些文件了。但是因为没有源代码,所以需要逆向分析这些二进制文件。

二、反编译器

市场上针对MIPS流行的反编译器如IDA Pro、Radare2和Binary Ninja等,(此处不做具体介绍翻译)。 收集文件系统中的二进制文件的信息,如:

$ file bin/busybox
bin/busybox: ELF 32-bit LSB executable, MIPS, MIPS-II version 1 (SYSV), dynamically linked (uses shared libs), corrupted section header size

就知道了此路由器采用的是32位小端MIPS指令框架,使用了共享库等信息。当然也可以通过datasheet获取,如图四所示。

图四 RT3352datasheet

再找MIPS24KEc能支持的框架。 接下来举例分析用户空间下的二进制文件的反编译。 还是分析上面的回复出厂设置的,打印出来的部分字符串没有在文件中找到,如“button has been pressed”,我们搜索这个打印的下一个字符串,如下:

~/Tech/Reversing/Huawei-HG533_TalkTalk/router_filesystem
$ grep -i -r "restore default success" .
Binary file ./bin/cli matches
Binary file ./bin/equipcmd matches
Binary file ./lib/libcfmapi.so matches

三个文件中包含了这个字符串,有两个在/bin/目录下,另外一个在/lib/下,用IDA Pro看看/bin/equipcmd,字符串所在的位置如图五所示。

图五 equipcmd反编译

仔细分析后发现,源代码中的c文件被编译成这些指令。如“clear configuration file”对应之前分析的通信中的ERASE命令。基于这个结果,我们发现了“restore default success”或者“restore default fail”,如果成功了,就另外打印一些东西,清空缓冲区,然后重启,这与我们之前研究的恢复出厂设置完全吻合。

在上面的图片中,可以看到IDA解析了所有的函数名称,其他的文件并不一定能这样。这是因为符号表的缘故。

三、查找默认WIFI密码生成算法

在前面的分析中,我们已经知道了路由器默认的证书信息,如图六所示。

图六 路由器默认证书信息

并且我们知道:

1、每一路由器设备都预置了一个不同的WIFI证书。 2、证书是在生产的时候硬编码在设备中或者由设备生成,而且,我们知道SSID和密码存放在flash的保护区中,进而有如下两种情况:

l 如果硬编码,那么路由器只需要从一个已知的存储区域读取即可 l 如果是由设备生成然后保存到flash中的话,那么一定会有一个算法存在设备中,如果输入的是公开的,比如MAC地址,那么我们应该可以找到、反编译并重新实现这个算法,从而计算出默认的WIFI密码。

查找硬编码字符串,除了username和password外,在这个设备中,TALKTALK-可能更合适。这个字符串是MAC地址后六位的前缀。如果是上述的后者,那么这个一定是硬编码在某个文件中。查找结果如下:

$ grep -r 'TALKTALK-' .
Binary file ./bin/cms matches
Binary file ./bin/nmbd matches
Binary file ./bin/smbd matches

其中nmbd和smbd是samba的两个文件,用来支持U盘设备的,所以我们分析另外一个cms文件。如图七所示。

图七 cms文件逆向分析

这与我们猜测的SSID生成算法很像。实现的代码位于ATP_WLAN_Init函数中,而这个函数有如下的操作:

1、 找到设备的MAC地址: mac = BSP_NET_GetBaseMacAddress()

2、 创建SSID字符串: snprintf(SSID, "TALKTALK-%02x%02x%02x", mac[3], mac[4], mac[5])

3、 保存字符串到某个位置: ATP_DBSetPara(SavedRegister3, 0xE8801E09, SSID)

但是不幸的是,在这个分支运行之后,执行了ATP_DBSave函数,接着执行其他的命令了,如图八所示。

图八 cms文件逆向分析

但是对这个函数以及后续的分析并没有找到我们想要的。 经过分析其他的潜在相关的代码段,我们没有发现密码生成相关算法,这将证实厂商使用相对安全地方法,将每一台设备的默认密码存放在flash保护区中。

在未来,我将接着分析其他的设备或者接着更详细的分析这个设备,因为真的有太多的设备都是使用着算法去生成密码的。 接下来看看还能干点其他的什么事情。

四、查找命令行注入漏洞

通常最危险的漏洞就是命令行注入,方法很简单,就是找一个输入的字符串,这个字符串是被用来作为shell命令的参数,我们试图添加自己的命令,绕过设备中的过滤器,在嵌入式设备中,这种漏洞经常会导致设备被完全的控制。

在嵌入式设备中,由于受到存储的限制,这种漏洞经常出现,比如你正在开发供用户配置设备的web接口,你希望添加网络测试功能的ping命令,你就需要给用户定义ping的目标的选项,然后返回结果。如图九所示。

图九 ping功能界面

当你受到用户提供的地址等信息时,你的处理可能是找到一个提供了ICMP协议的库文件,然后直接后台调用;或者是使用标准的系统调用,调用路由器支持的ping命令实现。当然后者比较容易实现,当然把用户的输入作为一个参数直接交给系统调用,是比较危险的,在这个路由器中的处理如图十所示。

图十 /bin/web的反编译

一个系统的system()调用是最简单的执行命令方法,有时候开发者会包装system()函数来过滤所有的输入,但是这种包装的难度比较大,总有一些会漏掉。

在二进制中查找可能调用system()是很有可能找到命令行注入的,调查一个很有可能没有过滤输入的,图十一是/bin/web中所有的调用了system()的。

图十一 web中调用了system()结果

函数的名字能够帮助我们了解这次调用是否会接收用户的输入,我们也看到了与PIN、PUK、SIMs等相关的调用,这是不是说这个应用于手机产品也有关系。

我尝试去分析atp_gethostbyname,但是目前没有找到可以注入的地方,如图十二所示,当不是一个域名的时候就返回错误。

图十二 非域名时返回错误

如果对其他的函数也进行详细的分析,可能会存在着命令行注入漏洞,另外一个很有可能存在注入漏洞的是“LAN-Side DSL CPE Configuration”协议或者是TR-064协议,尽管这个协议只能用于内部网络的,被用来通过互联网来配置路由器,如果存在注入漏洞,可能就可以靠发送几个数据包从而获取如wifi密码等信息。

/bin/tr064的逆向如图十三所示。

图十三 tr064文件反编译

从上图中可以看到在第二节中的SSL认证证书文件,利用这个证书,我们可以伪装成路由器与服务器等进行通信,进而挖掘其中存在的漏洞等。

五、查找其他类型的漏洞

当然,我们也可以去查找如缓冲区溢出等漏洞,通过控制用户端的输入,查找缓冲区溢出漏洞,从而完全的控制路由器。 缓冲区漏洞挖掘的思路很简单,如图十四所示。

图十四 登录时的缓冲区溢出测试示意图

但是这类漏洞的利用方法相对会比较麻烦,针对不同的场景需要有不同的应对方法,甚至需要使用如ROP等复杂的技术。当然,嵌入式设备的安全相对PC机要落后很多,如ASLR等基本上不会采用。

你可以通过发现潜在的输入,查找管理这些输入的函数名,进而分析并构造特殊的意想不到的输入,这样很有可能找到某个漏洞。

我们也可以关心如strcpy,strcat,sprintf等函数,这些函数很有可能存在缓冲区溢出漏洞,当然也包括strncpy,strncat等,只是利用方法会更复杂。如图十五所示。

图十五 strcpy等函数搜索结果

尽管上面的strcpy等函数是否是处理用户的输入的,但是类似这种的代码是很危险的,一旦你发现潜在的不安全字符串操作,很有可能就找到了一个可以利用的漏洞。

尝试发送意外的长输入使之崩溃,然后分析崩溃的原因,这是挖掘此类漏洞的通用作法,你也不应该设置所有的输入都是常规的输入,因为可能会被过滤,可以基于工具实现缓冲区漏洞的挖掘。

Web漏洞中的csrf漏洞同样经常出现在嵌入式设备中,利用他们可以试下文件的读写或者绕过认证进而控制系统,结合命令行注入和csrf漏洞,路由器很有可能会被远程的攻击。

当然RetDec是可以将MIPS指令反编译成伪C代码。如图十六所示。

图十六 RetDec反编译成伪C代码

六、后记

后续的研究是关于动态调试二进制文件的


Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:http://paper.seebug.org/167/