导航菜单

t01c2034d4092d1cc7d

 

作者:H4lo@海特实验室

前言

2020年2月4日,有外国研究人员发表了一篇文章:基于Xiongmai的DVR,NVR和IP摄像机的固件后门漏洞。最新的固件版本虽然默认禁用了Telnet访问和调试端口(9527/tcp),但打开了9530/tcp端口,攻击者可以利用这个端口发送一个特殊的命令来启动Telnet守护进程,并使用固定密码访问shell。参考文章见文末链接一。

其实这个漏洞疑似是一个海思摄像头组件的历史漏洞,关于详细的漏洞分析可以查看文末参考链接二。

安恒信息「物联网安全监测平台」已集成相关漏洞探测规则。

 

漏洞测试环境

设备:XMJP IPC 摄像头

型号:XM530

官网固件下载:https://download.xm030.cn/d/MDAwMDAwNjM=

设备图片:

t013b80dfbd80e2139c

t01cbd1ac59431c4545

 

漏洞分析

从官网获取固件的下载链接,下载固件文件到本地,使用 binwalk 进行解压:

binwalk -Me XMJP_IPC_XM510_RA50X10_WIFIXM712.bin

根据漏洞信息,找到 OpenTelnet:OpenOnce 字符串所在的位置:

$ grep -rnl "OpenTelnet:OpenOnce"*
grep: etc/localtime:No such file or directory
grep: etc/resolv.conf:No such file or directory
grep: lib/firmware:No such file or directory
grep: mnt/web:No such file or directory
usr/bin/dvrHelper
usr/bin/netinit
grep: usr/bin/ProductDefinition:No such file or directory
grep: usr/share/music/customAlarmVoice.pcm:No such file or directory

在 usr/bin 目录下找到 dvrHelper 这个可执行程序,使用 file 命令查看文件信息:

$ file usr/bin/dvrHelper
usr/bin/dvrHelper: ELF 32-bit LSB executable, ARM, EABI5 version 1(SYSV), dynamically linked, interpreter /lib/ld-, stripped

将usr/bin/dvrHelper 这个二进制程序,使用 IDA 进行加载:

t01dcce63255dfd4c44

搜索 OpenTelnet:OpenOnce 字符串的位置,双击跟进:

t01d896dfce28bd7b4f

在这个函数流程中,可以看到经过了几个判断之后,会执行 system(“telnetd”) 命令,从而开启一个 telnetd 端口,我们的目的就是需要让程序执行到这个流程分支。

流程分析

首先程序会根据 socket 套接字中 recv 函数接收的内容,判断前几个字节内容是否为 OpenTelnet:OpenOnce 开头:

strncmp(v32,"OpenTelnet:OpenOnce",0x13u)

如果是的话在下面的 else 判断中就会通过 get_random_code 函数中的 rand 函数随机返回 8 位数字:

t01f81b6401801394a9

get_random_code 函数

t012f9f91ea2f6ab910

接着再次判断通过 recv 函数接收的内容是否为 randNum 字符串开头,是的话就跳转到 else 分支:

t0119b1856a83b42e51

这里的 get_key 函数的作用是返回一个 key 字符串,这里的逻辑为判断 /mnt/custom/TelnetOEMPasswd 文件是否存在,存在的话返回文件的内容(也就是密钥),不存在就返回 2wj9fsa2 字符串。

t0162e76fc3e205471e

接着在 126 行,将上一步程序返回的 randNum 随机数字和 key 进行拼接,得到 challengeStr 字符串传入到 encrypt 函数中进行加密,这里就 key 就相当于一个固化在程序中的 PSK 预认证后门密钥。

跟进到 encrypt 函数中,函数中的逻辑较为复杂,根据参考文章 2 中代码的分析可知这里是一个 3DES 加密算法。

t014d484f44b85dbf1a

或者这里使用 Ghidra 工具的 FindCrypt 脚本,可以发现几个目标地址都是 DES 加密所需的 sbox 参数等等。

t016d572da8328f9b98

逆向加密算法,根据参考文章 2 中的代码写出具体的解密算法之后,将这个加密结果拼接在 randNum:字符串之后:

t01db65d64f8f3c1e4d

经过程序比较就会输出 “verify:OK” 字符串,这里就通过了这一步的判读。

接着会再次比较接收到的字符串开头是否为 CMD:,是的话就会进入下面的 if 判断:

t01cc56fca598d3b52a

这里的解密算法对应的上面的加密算法,判断解密后的字符串是否为 “Telnet:OpenOnce” 字符串,那么这里只需要将 “Telnet:OpenOnce” 字符串经过相同的加密算法加密即可,就可以通过 strncmp(&key, “Telnet:OpenOnce”, 0xFu) 这个判断。从而执行 system(“telnetd”) 函数,开启后门。

实际调试

当我们向 9530 端口发送一个 OpenTelnet:OpenOnce 字符串时,端口会回应一个 randNum,如下图:

t012c8c3ac99d171bfb

注意这里需要使用 socket 编程来进行实现:

...
connect(sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr);
recv(sockfd, netbuf, BUFSIZE -1,0);
...

接着我们需要将拼接得到的 challengeStr ,也就是 175727002wj9fsa2 进行加密函数的加密。加密完成之后传送 randNum:加密后的内容 到远程 9530 端口服务。

这里的远程服务就会返回 “verify:OK” 字符串,如下图:

t01eb31aafc109b046c

之后将 “Telnet:OpenOnce” 字符串进行同样加密算法的加密,将这个加密的内容拼接到 “CMD:” 字符串后面得到 CMD:加密后的内容,并将其发送到远程服务,设备就会执行 system(“telnetd”) 语句,并返回 “Open:OK” 字符串,至此 telnet 服务就被打开了。

设备密码爆破

在成功打开了 telnetd 端口之后,需要使用 root 用户的密码进行登陆。在解压后的固件文件系统的 etc 目录下,查看 passwd 文件的内容:

$ cat passwd
root:$1$RYIwEiRA$d5iRRVQ5ZeRTrJwGjRy.B0:0:0:root:/:/bin/sh

因为密码采用 des 加密,猜测密码位数较短,可以使用 hackcat 进行暴力破解:

hashcat64.bin -a3 -m1500 $1$RYIwEiRA$d5iRRVQ5ZeRTrJwGjRy.B0 -1?l?d ?1?1?1?1?1?1

最后可以得到密码为:xmhdipc。雄迈摄像头的几种默认密码的组合已经有人爆破出了一个列表,见下文的图片。

 

漏洞证明

t019cbcd2a96b008a3d

 

参考文章

  1. Full disclosure: 0day vulnerability (backdoor) in firmware for Xiaongmai-based DVRs, NVRs and IP
  2. pwn-hisilicon-dvr

本文由安全客原创发布转载,请参考转载声明,注明出处: https://www.anquanke.com/post/id/206004

相关推荐

CVE-2020-5764:安卓MX Player播放器路径穿越和代码执行漏洞

译文声明 本文是翻译文章,文章原作者David Wells,文章来源:medium.com 原文地址:https://medium.com...

WAF Bypass之xerces解析

  JAVA的XML解析,底层用的是xerces,而xml本身的特性及xerces的一些特性,可以用来造成WAF与后台...