首页
社区
课程
招聘
[翻译]HiSilicon DVR(视频录像机)远程代码执行漏洞分析
发表于: 2019-4-22 20:55 19313

[翻译]HiSilicon DVR(视频录像机)远程代码执行漏洞分析

2019-4-22 20:55
19313

本篇文章主要是对使用了HiSilicon hi3520d和片上系统(SoC)构建的DVR / NVR设备的漏洞的分析,利用此漏洞会导致在Web界面未授权的远程代码执行(RCE),可以使被攻击设备被完全接管。

海思半导体是全球领先的多媒体ARM SoC解决方案供应商之一,该公司的SoC广泛应用于DVR,网络摄像机,NVR,智能手机等产品。Ambarella,海思,德州仪器是当今全球高清电视多媒体行业的三大先锋。HiSilicon DVR是海思公司生产的一种数字视频录像机。

首先应该学习一下官方的用户使用手册,然后进行深入分析,或者尝试提取固件,进行固件提取后分析会可能发现一些漏洞。

用于测试的DVR设备被称作“Seculink”




物理接口:

2个USB端口(用于控制GUI控制台的鼠标)

用于连接外接显示器的HDMI端口(VGA)(用于GUI和摄像头视图)

用于模拟闭路电视摄像机的4个BNC连接器

内部的SATA端口用于连接存储器来记录视频

用于网络访问的以太网端口

用户界面:

使用HDMI(或VGA)作为输出可以直接访问

通过HTTP进行网络访问来查看,控制摄像机

可直接访问Web界面,默认用户为“admin”,默认密码为空

在设置强密码之后,用户可能会觉得很安全了,其他人无法访问设备,但是人们经常将DVR设备的Web端口(tcp / 80)从安全的LAN(局域网)转发到WAN,以便从公网访问DVR(通过Shodan可以搜索到)。

提取固件有很多方法:

通过一些漏洞从设备获取

通过JTAG,串口控制从设备中获取

从网上查找固件包下载

虽然从官网下载固件包很简单,但我们选择最难的路,第一种方式提供了有关设备的其他信息

在DVR上进行全端口扫描,请注意,如果是root用户运行,默认情况下SYN扫描会非常慢

分析一下:

23 / tcp是telnet登录界面,需要用户名+密码验证

80 / tcp是Web登录界面

554 / tcp是rtsp服务;,它可以通过rtsp url打开:



打开rtsp界面也需要用户凭据验证

9527 / tcp似乎是一个保密的服务端口,具有一些非常有趣的功能

34567 / tcp和34599 / tcp是与DVR应用程序相关的一些数据端口

SDR设备应该是基于Linux系统的,连接到9527 / tcp(通过raw netcat)显示应用程序控制台的日志消息和登录提示,使用任何已定义的应用程序凭据登录都可以登陆,发现它为设备提供了root shell。

请注意,这显然是一个严重的安全问题,因为任何(低权限)应用用户都不应自动获取设备上的root shell。

在root shell中执行命令dmesg,可以看出DVR运行的是Linux内核(版本3.0.8),它有一个ARMv7 CPU,SoC模型是hi3520d。

从正在运行的进程列表中(ps)可以清楚地看到DVR应用程序正在监听34568 / udp,34569 / udp以及nmap()检测到的上述tcp端口。

从已装入的磁盘列表(命令)中可以清楚地看到固件映像在设备中(其中X = 0,1,2,3,4,5)。

固件文件非常小,因此如果我们想要将文件复制到设备或从设备复制文件,需要想点办法,幸运的是固件支持NFS,因此在主机上设置NFS服务器并从DVR安装固件就可以解决此问题:



获取固件:

要通过telnet接口(端口23 / tcp)访问设备,我们需要登录口令,查看可以拿到root用户的密码哈希:


假设密码是一串六个字符的小写字母,hashcat可以很快破解上面的DES hash:

因此,通过端口23 / tcp上的telnet接口登录用户root和密码xc3511是完全有可能的,在unclosable telnet界面上可访问的这个硬编码root帐户显然就是一个后门。

分析固件发现文件/var/Sofia是实现所有接口的主要应用程序,除了视频处理之外,所以这个二进制文件对我们来说似乎是最重要的。

但是加了混淆,这使得静态分析变得非常难:

因此,除静态分析(使用radare2或IDA)外,必须使用动态分析

进行动态分析,将GNU Project调试器(GDB)附加到远程 应用程序上,方法是将在远程设备上运行,并用从本地计算机上连接它。

当然,需要针对适当的ARM体系结构进行编译,为了编译它,我们可以使用 μClibc,它是嵌入式系统的C库(比如这里的DVR)。

有一个很好的编译环境叫做 Buildroot,它使编译非常简单,选择所需的应用程序(例如gdb) ,选择静态库,然后运行 。

现在固件已准备好然后开始逆向分析, 远程连接现在正在运行的进程上:



本地机器连接:

静态分析的推荐工具是Hex-Ray的 IDA Pro。

自动分析后有15.000多个函数,使用Python脚本找到auth函数。下面的 IDAPython 代码段可以找到“Users” 和 “Password” 相关的所有函数:

找到了一个函数:,对此函数快速分析后证实这就是验证函数

对硬编码字符串进行初步检查,发现一个后门密码,通用密码是:。

使用此密码,我们可以以任何用户(例如管理员)访问应用程序中的任何内容。例如,获取视频流:



或者在应用程序控制台(9527 / tcp)上获得root shell:

对auth函数深入分析发现:密码hash函数是sub_3DD5E4。它是一串MD5,有一些奇怪的转换,用Python逆向算法:

使用上面的哈希算法,可以设置任意密码

Sofia文件可以处理80 / tcp端口上的HTTP请求,可以对其进行fuzz测试。可以使用gdb附加调试,先杀死Sofia进程,然后使用gdbserver重新启动进程:



本地连接:


GET请求:


正常响应:


使用looong请求测试是否可以溢出:

响应是200,带有“404 File Not Found”消息,但我们可以在gdb中看到进程崩溃了

分析一下崩溃原因,远程进程Sofia得到了SIGSEGV(分段错误),堆栈中填充了输入的“a”字符,$ pc(程序计数器)寄存器中出现了输入的值(“aaaa” - 1) ,这是典型的堆栈溢出,这意味着我们有机会控制程序流程

测试:

这也可以导致SIGSEGV,并且$ pc寄存器是 ,我们的payload在$ sp + 0x14(堆栈基址+ 0x14)上开始执行

利用这种溢出的最方式是通过将一些shellcode注入到堆栈,然后将程序流重定向到shellcode,这样我们就可以在目标机器上远程任意代码执行。由于设备操作系统上没有权限分离,这意味着完全控制设备(root shell)。

设备上也有可能启用了一些漏洞利用缓解技术,这会使漏洞利用变得更难。

防止栈溢出的shellcode的最基本方法是No-eXecute(NX)技术,这可以防止在特定的内存页面上执行代码(通常是具有写入权限的页面,如堆栈)。

但是这个设备有些地方没有NX位设置(查看STACK,rwx):

或者在gdb gef中使用checksec。gef输出发现也没有其他的缓解措施,例如堆栈canary(因为如果存在堆栈canary,我们无法控制带有堆栈溢出的$ pc)。

在进行RCE之前,我们唯一应该知道的是堆栈地址。我们应该在paylaod的适当位置(上面的“wxyz”)写入地址$ sp + 0x14,以便将程序流重定向到shellcode。

还有一种缓解技术也可以使漏洞利用变得更难:地址空间布局随机化(ASLR),ASLR随机化存储段的基址(例如,堆栈的基址)。

发现确实启用了ASLR(“2”表示完全随机化,“0”禁用):

让我们首先尝试利用溢出来关闭ASLR。

按照上面的过程,我们得到SIGSEGV崩溃时堆栈地址($ sp)是0x5a26f3d8

所以payload应该是:

shellcode应该是我们想要执行的东西,最好是一个connectback shellcode。注意,必须避免一些“badchars”,:0x00,0x0d('\ n'),0x20(''),0x26('&'),0x3f('?'),此外,还有299字节的大小限制。

这里的shellcode使用socket,connect,dup2和execve系统调用写出了一个连接shell

发送payload进行漏洞利用,就可以拿到shell

首先要启动一个监听器:


然后发送shellcode:

使用 netcat 监听发送RCE命令

现在可以在远程系统上以root身份执行任意命令

但是还不能稳定漏洞利用,因为ASLR没有关闭,因此我们不知道shellcode起始地址

关闭ASLR并非易事,通常有两种方法可以做到:

在随机发生器中发现一些信息通过泄漏/覆盖来攻击它

泄漏远程二进制文件的随机内存地址。

经过一段时间的研究,发现无法泄漏,但后来想到了一个办法,Web服务器中存在一个漏洞:目录遍历漏洞。

目录遍历漏洞可以拿到root用户的hash密码:

此漏洞非常严重,因为攻击者可以读取任何文件,包括录制的视频(如果设备有一些HDD存储)。

此外,该漏洞可以帮助我们关闭ASLR。

该/proc文件系统包含了很多正在运行的进程信息,也就是/proc/[pid]目录。/proc可以获得列表GET ../../proc,这样我们就可以得到所有的PID。如果 /proc/[pid]/cmdline是/var/Sofia,就可以找到应用程序的PID。

关闭ASLR最重要的信息是 /proc/[pid]/smaps。此文件包含内存页统计信息,包含页面地址和其他信息(例如rss)。

例如:

这只是其中一页,该列表包含约150页。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 2
支持
分享
最新回复 (7)
雪    币: 744
活跃值: (1404)
能力值: ( LV9,RANK:150 )
在线值:
发帖
回帖
粉丝
2
鹏哥真是个人才
2019-4-22 21:00
0
雪    币: 3051
活跃值: (1392)
能力值: ( LV13,RANK:480 )
在线值:
发帖
回帖
粉丝
3
VicZ 鹏哥真是个人才
超哥才是大佬
2019-4-22 21:05
0
雪    币: 47147
活跃值: (20450)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
4
论坛MD缓存有bug,导致重复的发帖已删除了。
再次感谢分享!
2019-4-23 07:45
0
雪    币: 3051
活跃值: (1392)
能力值: ( LV13,RANK:480 )
在线值:
发帖
回帖
粉丝
5
谢谢老师  md一直提交不上去
2019-4-23 08:52
0
雪    币: 1101
活跃值: (51)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
一个字,牛
2019-7-2 16:11
0
游客
登录 | 注册 方可回帖
返回
//