安全路透社
当前位置:安全路透社 > 安全客 > 正文

【技术分享】物联网设备安全分析之网络摄像头篇

http://p5.qhimg.com/t0145933fff567357de.jpg

翻译:shan66

预估

,或登陆网页版


传送门


【技术分享】智能家居设备安全分析手记 

前言


当前,嵌入式设备已逐渐成为私人或公司网络的攻击入口点。例如,针对HackingTeam的攻击正是沿着这条路径进行的。所以,为了安全起见,一定要保护好您的嵌入式设备。在这篇文章中,我要跟大家分享自己在分析嵌入式设备(即ADIMAX的IC-3116W网络摄像头)方面的经验。

虽然这篇文章主要介绍如何分析网络摄像头,但是涉及的技术和工具也同样适用于其他设备。特别是,我将分步进行介绍,包括1.)如何获取固件并利用它收集信息,2.)如何获得系统访问权限,和3.)如何在设备上安装gdbserver 。此外,我不会在这篇文章中披露任何“复杂”的漏洞,而是只关注有助于分析该设备的那些漏洞,例如管理界面中的远程代码执行漏洞。


一步一步分析设备


在下面,我将一步一步地讲解如何正确搭建网络摄像头的安全测试环境。就这里来说,最初的步骤与普通的Web应用程序渗透测试没有多大的区别。也就是说,第一阶段是信息收集阶段,需要从供应商的网站、谷歌等地方收集摄像头的有关信息,或通过用合适的工具(Burp Suite、nmap等)来扫描摄像头提供的各种服务(特别是管理接口)。然后是漏洞利用阶段,取得对摄像头的永久性访问权限。最后是漏洞利用的后期阶段,建立正确的调试/分析工具,并部署到摄像头上面。


第一步:搜集信息

在分析设备的过程中,关键的一步是收集尽可能多的信息。幸运的是,Edimax在其网站上提供了这款摄像头的大量信息,例如数据表、手册、固件和工具链(以及用来构建映像的文件等),但是,仍然没有我们感兴趣的那些二进制文件的源代码。

不过,固件能够为我们提供该摄像头的大量内部秘密。通过在固件上使用binwalk,我们可以提取该相机的文件系统。

$ binwalk -e IC3116W_v2.10.bin
 
DECIMAL         HEX             DESCRIPTION
-------------------------------------------------------------------------------------------------------
605             0x25D           LZMA compressed data, properties: 0x88, dictionary size: 1048576 bytes, uncompressed size: 65535 bytes
10392           0x2898          LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 3735204 bytes
1245312         0x130080        Squashfs filesystem, little endian, version 4.0, compression: lzma, size: 4072088 bytes,  907 inodes, blocksize: 131072 bytes, created: Mon Feb 22 11:50:40 2038

可以看出,开发人员使用了SquashFS文件系统。为了探索这个文件系统,我们可以使用unsquashfs(支持LZMA):

$ unsquashfs -d filesystem 130080.squashf

这样就得到了未压缩的文件系统(它被保存在filesystem文件夹中)。

$ ls -a filesystem
 
.  ..  bin  dev  etc  home  init  lib  mnt  proc  sys  test  tmp  usr  var  web  www

提取文件系统后,我们就可以探索该摄像机上的文件了。文件系统包含一些我们感兴趣的二进制文件,如telnetd,wget,ftp等等。然而,nmap的扫描(默认IP地址印在该设备的背面)结果显示,在默认情况下是不会行运telnet守护程序的。

$ nmap -sS -p0- --reason -v -T3 -Pn 192.168.2.3
 
[...]
Nmap scan report for 192.168.2.3
Host is up, received arp-response (0.00065s latency).
Not shown: 65534 closed ports
Reason: 65534 resets
PORT     STATE     SERVICE     REASON
80/tcp   open      http        syn-ack
554/tcp  open      rtsp        syn-ack
MAC Address: 74:DA:38:34:AA:75 (Unknown)
[...]

Web服务器的根目录位于www。通过考察这个文件夹,我们发现了一些无需身份验证即可访问的cgi文件,这些文件有: 

l  /www/camera-cgi/public/anonymous.cgi
l  /www/camera-cgi/public/getSysteminfo.cgi
l  /www/camera-cgi/public/supportiPhoneAppVersion.cgi

特别地,anonymous.cgi和getSysteminfo.cgi暴露了该网络摄像头的大量配置信息(例如内部IP地址,固件版本等)。

http://p6.qhimg.com/t01eb4dc0a0d3f5889d.png

通过访问文件系统,我们可以了解该摄像头上面有哪些文件,并通过这些文件来收集信息。在下一步,我们将使用自动扫描和手动测试来窥探该摄像头的内部工作机制。因此,这里不妨先熟悉一下该摄像头上所运行的应用程序。如上图所示,通过nmap扫描结果可以获悉,在端口80上运行了一个Web服务器(用于管理的Web界面)。让人高兴的是,默认登陆凭证已经打印在相机背面了,用户名是admin,密码为1234。

http://p6.qhimg.com/t011cd10c98e6a7b00b.png

有了这些,我们就获得了系统的部分访问权限。


第二步:获得系统访问权限

通过对Web界面的自动扫描和手动测试,我们发现系统日志允许远程代码执行。借助于telnetd的路径,我们可以通过以下方式启动telnet服务:

http://p6.qhimg.com/t01d5f3bd6edc6f4c62.png

现在可以通过telnet连接到摄像机: 

$ telnet 192.168.2.3
Trying 192.168.2.3...
Connected to 192.168.2.3.
Escape character is '^]'.
 
IC-34AA75 login: admin
Password: 
RLX Linux version 2.0
         _           _  _
        | |         | ||_|                 
   _  _ | | _  _    | | _ ____  _   _  _  _ 
  | |/ || |\ \/ /   | || |  _ \| | | |\ \/ /
  | |_/ | |/    \   | || | | | | |_| |/    \
  |_|   |_|\_/\_/   |_||_|_| |_|\____|\_/\_/
 
For further information check:
http://processor.realtek.com/
 
BusyBox v1.13.4 (2015-02-25 18:14:22 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
 
# cat /etc/passwd
admin:$1$yAn92Ld/$u5nHFH9nLds0naDaLuK1d/:0:0:System Administrator,,,:/:/bin/sh

telnet登录的凭证与Web界面(用户名:admin,密码:1234)的凭证是相同的。从/ etc / passwd可以看出,该系统上面只有一个用户,即admin(权限为uid 0和gid 0)。因此,我们已经直接拥有了root访问权限。

需要注意的是,我们也可以通过UART端口获得该系统的shell。这个端口可以在下图中看到(引脚已被去掉,并直接焊接到了电路板上)。

http://p7.qhimg.com/t013d913be48c329507.png

为了与UART端口通信,我们可以使用诸如JTAGulator之类的独立设备。在获取了系统访问权限之后,现在可以部署相应的工具来分析相机了。


第三步:搭建安全测试环境

实际上,这个摄像头上已经提供了一些可以帮助分析运行的进程的工具了。但遗憾的是,它并没有提供调试器或编译器。而我们的目标(至少对于这篇博客文章来说)正是在这个设备上面运行调试器。更具体地说,我想在一台x86机器上本地运行gdb,而在这台摄像头设备上面运行gdbserver。

 在这台摄像头设备上运行gdbserver(而不是gdb本身)具有多个优点。首先,gdbserve的二进制文件的大小远小于完整的gdb二进制文件。由于磁盘空间可能是嵌入式设备上的稀缺资源,所以gdbserver通常是唯一的选择。其次,gdbserver比gdb本身具有更少的依赖项,因此更容易交叉编译。当然,使用这个方法也是有缺点的。例如,如果主机系统(即运行gdb的系统)和目标系统(即运行gdbserver的系统)的寄存器大小不同,那么就可能发生问题。这也是我让gdb在x86机器上运行的原因。

 要想将二进制文件安装到该摄像头上,自然需要能够在该摄像头上轻松写入和读出文件了。为了给这个摄像头写入文件,我们可以使用wget(虽然squashfs文件系统是只读的,但是,已经有一个闪存挂载到/var下面,因此我们可以对它执行写入操作)。要从这个摄像头中读出文件,可以使用lighttpd(该摄像头的Web服务器)。通过启动该服务器的另一个实例(并且把它的根目录设置为“/”),我们就可以从相机下载所有文件了。

 在建立了摄像头和主机系统之间的文件传输通道之后,我们就可以开始交叉编译gdbserver了。为此,我们首先需要了解该摄像头使用的是哪种处理器。

# cat /proc/cpuinfo
system type             : RTL819xD
processor               : 0
cpu model               : 56322
BogoMIPS                : 658.63
tlb_entries             : 32
mips16 implemented      : yes

从上面的输出可以看出,它使用的是RTL819xD,这是一种基于MIPS的处理器。因此,我首先尝试使用标准的MIPS交叉编译器。为了获得交叉编译器,我们可以到Aboriginal Linux网站上面下载。这个网站不仅提供了大量的交叉编译器,而且还提供了许多的shell脚本,可用来为特定的架构(基于qemu)搭建一个完整的构建环境。

 然而,底层的Realtek CPU使用的是修改版的指令集,所以普通的MIPS二进制文件通常无法在该摄像头上运行(只有非常简单的二进制文件可以运行)。但正如我前面提到的,Edimax也为其设备提供了一个工具链。借助于CentOS 7.3和厂商提供的工具链,我就可以为该摄像头建立一个构建环境了。建立这个构建环境的具体步骤,可以参见该工具链自身提供的pdf帮助文件,其基本步骤为:

第一步 : cd TARGET_DIR

第二步 : bzip2 -cd rsdk-{VERSION}-{LIBRARY}-{PLATFORM}.tar.bz2 | tar xvf –

第三步 : ln -s rsdk-{VERSION}/{PLATFORM}/{LIBRARY} rsdk

第四步 : export PATH=TARGET_DIR/rsdk/bin:$PATH

使用CentOS系统后,我们就可以交叉编译该摄像头的二进制文件了。例如,为了交叉编译gdbserver,我们可以使用如下所示的命令:

$ cd gdbserver_src
$ ./configure  --host=mips-linux CC=rsdk-linux-gcc
$ ./make CC=rsdk-linux-gcc AS=rsdk-linux-as LD=rsdk-linux-ld

通过环境变量CC、AS和LD,可以为编译和加载过程指定编译器、汇编器和加载器。最后,我们得到了一个能够在网络摄像头上运行的gdbserver二进制文件。

我们也可以以类似的方式获得相应的gdb二进制文件。然而,幸运的是,在构建链中已经提供了用于x86系统(与MIPS系统上的gdbserver交互)的预编译好的二进制文件了。不过,如果你想从头开始创建这个二进制文件的话,那么必须为编译过程指定不同的参数 

$ cd gdb_src
$ ./configure  --target=mips-linux
$ ./make

 在这个构建过程中,我们必须指定目标系统(即将来运行gdbserver的系统)。此外,我还测试了不同的gdb / gdbserver版本,最后发现gdb-6.8能够用于该摄像头。

最后,我将介绍如何利用上面配置的gdb / gdbserver来分析该摄像头上运行的二进制文件。所以,我们首先将gdbserver二进制文件复制到该设备的/ var目录,并通过chmod命令使其变为可执行文件。为了让gdbserver连接到进程上面,必须执行以下命令: 

# /var/gdbserver ip:port --attach pid

这里的IP是运行gdb的主机系统的地址。命令中指定的端口将在目标系统上打开。此外,其中的pid是我们想要连接的进程的进程ID。当然,我们也可以通过提供到可执行文件的路径而非-attach参数,在这个摄像头设备上启动一个新的进程(不连接到现有的进程上)。

作为一个例子,我们将连接到正在摄像头上运行的/ bin / ipcam二进制代码上面:

# /var/gdbserver 192.168.2.10:1234 --attach 9266
Attached; pid = 9266
Listening on port 1234

在执行该命令后,gdbserver就会在规定的1234端口上等待传入连接。在x86主机上,我们启动相应的gdb可执行文件,并通过下列方式连接到目标系统: 

$ rsdk-mips-gdb -q
(gdb) target remote 192.168.2.3:1234 
 
Remote debugging using 192.168.2.3:1234
[New Thread 9266]
0x2ab6b89c in ?? ()
 
(gdb)

然而,我们可以看到,gdb并没有函数上下文,也就是说它不知道自己当前在哪里。这是因为gdb必须为将在目标服务器上调试的二进制文件加载符号表才行。因此,我们必须在本地对这个二进制文件执行file命令(在gdb中)来加载符号表。此外,为了调试库调用,必须在本地保存一份该摄像头设备的文件系统的副本,同时,还应该从根目录中运行gdb(这样做能够确保可以在主机x86系统上找到相应的程序库)。 

$ cd cam_root_dir
$ rsdk-mips-gdb -q
(gdb) file cam_root_dir/bin/ipcam
Reading symbols from cam_root_dir/bin/ipcam...(no debugging symbols found)...done.
(gdb) target remote 192.168.2.3:1234 
Remote debugging using 192.168.2.3:1234
[New Thread 9266]
0x2aaa8a40 in _start() from cam_root_dir/lib/ld-uClibc.so.0
(gdb)

现在,你可以使用gdb了,仿佛它就在该摄像头上本地运行一样(即设置断点、分析寄存器等)。因此,我们现在已经拥有了一个通用的环境,可以对该摄像头设备上运行的各种服务进行分析处理了。

正如我在帖子开头提到的,这里发现的这个漏洞已经报告给供应商了。但是,截至今天,相应固件的仍然没有得到更新。所以,我们必须采取其他措施防止潜在的攻击。例如,为了防止anonymous.cgi,getSysteminfo.cgi和supportiPhoneAppVersion.cgi泄露信息,应该通过其他方式限制对它们的访问,比如可以使用单独的防火墙。当然,人们可以通过如上所述的方法获得系统访问,然后根据需要重新配置该摄像头设备。

 对于web接口的认证区域的远程代码执行问题,必须确保对该区域的访问进行限制。首先,该摄像头的默认凭证应该进行修改。此外,根据相机的使用情况,如果不需要经由因特网访问web界面的话,就应该禁用这项功能。


传送门


【技术分享】智能家居设备安全分析手记 


原文链接:https://insinuator.net/2016/10/setting-up-a-research-environment-for-ip-cameras/

未经允许不得转载:安全路透社 » 【技术分享】物联网设备安全分析之网络摄像头篇

赞 (0)
分享到:更多 ()

评论 0

评论前必须登录!

登陆 注册