在开始分析之前,我们先从供应商[1]的网站下载这个固件更新,然后使用一个固件工具binwalk[2]将更新文件解包。
$ binwalk -Me F9K1111_WW_1.04.10_upg.bin
下面的图片中显示了得到的结果,这个结果看起来是一个相当标准的SquashFS文件系统,代表着该设备的root目录。
现在,为了执行bindiff,我们将需要与硬件进行一些交互,以得到里面事先打补丁状态的文件。
为了分析基础固件,我们需要利用一些方法转储物理设备中的数据。要做到这一点,必须先移除设备的外壳。
上图中红色和蓝色方框部分可能是检索固件、SPI flash芯片和UART接口的地方。尽管我们已经看到一些UART级别的活动,但是我们仍将继续通过分析SPI flash芯片上的基础图像进行处理。我们正在处理的芯片引脚MX25L 1606e可以从Macronix获得。
在获取到这个表并移除芯片后,我们就准备好了将GoodFET[3]与上述通用的8脚引脚连接。
在引脚7和引脚8桥接之后,我们使用下面代码确保所有hook都正确执行:
$ python goodfet.spiflash info
接下来,我们运行goodfet.spiflash dump<outfile>来获取芯片中的内容。
$ python goodfet.spiflash dump s
最后,我们对结果文件进行快速字符串搜索,以确保dump看起来合法(至少包含一些可读的字符串)。
跟之前类似,生成的二进制文件可以通过binwalk进行解包。
将前面两次解包的文件系统移动到一个Windows box,然后将它们拖进WinMerge[4],可以看到实际上并没有太大的改变。
文件compiler_data、version和FUNCTION_SCRIPT中没有包含任何有趣的变化(除了可能对某些指纹有用的数据),util_system.asp的变化也没有多少有趣的地方。所以,我们将大多精力花在查看Belkin对webs GoAhead Webserver的修改上。
惠普的Zero Day Initiative已经利用可能受影响的函数名字或输入对这些漏洞进行了命名,分别如下:
1、formWpsStart pinCode远程代码漏洞 2、formWlanSetupWPS wps_enrolee_pin远程代码执行漏洞 3、formWlanMP远程代码执行漏洞 4、formBSSetSitesurvey远程代码执行漏洞 5、formHwSet远程代码执行漏洞 6、formConnectionSetting远程代码执行漏洞 7、formAccept远程代码执行漏洞 8、formiNICWpsStart远程代码执行漏洞 9、formUSBStorage远程代码执行漏洞
所以,在将webs的补丁版本加载到IDA之后,我们在函数列表中搜索formHwSet,然而什么也没找到,实际上这些函数中的很多都没有发现。将其拖进Bindiff中,我们可以看到在更新中移除了7个函数,如下表所示。
这些很好地对应了ZDI报告中的数据。事实上,ZDI报告中列举的每个函数都已被删除,除了formWlanSetupWPS和formBSSetSitesurvey。接下来,我们就花点时间详细查看下这些被删除的函数。
我们首先分析的是formUsbStorage函数。在快速阅读该函数后,很明显地发现这里存在一些问题。首先,通过GoAhead webs API函数websGetVar访问POST变量sub_dir,然后该变量用于对system的调用中,这里允许命令注入。
这段代码可以通过以下指令触发:
wget --post-data="sub_dir=vectra;reboot" http://belkin.range/goform/formUSBStorage
同样地,可以在formWIanMP中发现类似的错误,通过追踪对websGetVar的调用,我们看到一些可能存在漏洞的地方。
继续往下看,我们发现这几个可能之处都可以作为注入到系统调用的入口点,这里我们分析一下ateFunc。
这段代码可以通过以下指令触发:
wget --post-data="ateFunc=;reboot;" http://belkin.range/goform/formWlanMP
这里存在更多的命令注入漏洞,这次我们使用变量[sic]Anntena。
这段代码可以通过以下指令触发:
wget --post-data="Anntena=;reboot;" http://belkin.range/goform/formHwSet
这里,我们在函数formConnectionSetting的参数timeOut中发现了命令注入漏洞。
这段代码可以通过以下指令触发:
wget --post-data="timeOut=1;reboot;" http://belkin.range/goform/formConnectionSetting
此时,我们已经彻底分析了被删除的函数。接下来,我们看一下更重要的函数,即Belkin没有删除的函数 formBSSetSitesurvey,下图是它的总体结构图:
回退之后,我们放大并发现最大变化之处在于,Belkin增加了一个函数strcat_escape,在整个函数中都使用了strcat_escape。
这个strcat_escape函数需要3个缓冲器:dst、src和tokens。如果发现tokens在被复制到dst之前被转义,那么该函数将使用嵌套循环在src字符串中搜索任何转义的tokens。在图中所示的情况中,token_of_none_quotation作为令牌被传递,该令牌定义为" /// "’$()<>`# &* |;”。利用webs二进制文件,我们用C语言重新实现这个函数,然后就可以看到预期的输出:
然后,将这个(大概正确)转义字符串通过sprintf正常传递到system中。
这个补丁的有效性依赖于几个因素:
1、strcat_escape函数完全按预期工作 2、strcat_escape不会无意中导致缓冲区溢出 3、strcat_escape,用于所有用户的输入,在system中结束
我们都已意识到,嵌入式设备代码的安全成熟度仍旧是一个问题。在本篇文章中我们看到,即使是2014年发布的设备,这仍然是一个问题。
[1] http://cache-www.belkin.com/support/dl/F9K1111_WW_1.04.10_upg.bin
[2] http://binwalk.org
[3] http://goodfet.sourceforge.net/apps/spi
[4] http://winmerge.org
*参考来源: blog.vectranetworks.com ,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)