概述:
- 供应商:COMFAST
- 产品:COMFAST CF-N1-S V2
- 固件版本:V2.6.0.1
- 漏洞类型:已认证命令注入
COMFSAT CF-N1-S V2 Router中发现了一个命令注入漏洞,攻击者可以通过发送恶意HTTP POST数据包来利用改漏洞执行任意命令。
前期准备
我们从官网上获取固件,使用binwalk -Me CF-N1-S-V2.6.0.1.bin 解压固件

进入到文件系统中,使用readelf -h busybox查看固件的架构,发现是MIPS大端。

接下来去寻找路由器的网络服务组件

固件中未发现传统的独立 Web 服务进程(如 httpd、lighttpd、boa 或 goahead)。我借鉴了bashis的漏洞报告,该固件的 Web 管理界面由 /usr/bin/webmgnt 二进制实现,其采用 FastCGI 协议处理请求。因此,单独运行 webmgnt 无法完整模拟 Web 服务环境,还需要额外启动一个支持 FastCGI 的前端 Web 服务器(如 nginx),并通过 fastcgi_pass 将请求转发给 webmgnt(通常监听 TCP 端口或 Unix socket),才能正确还原固件的 Web 交互行为。
幸运的是,我们发现固件里面好像自带nginx
用户模拟(qemu-mips-static)
笔者首先使用用户模拟试一试。

先看boot和nginx的配置文件
ROOTFS="/home/iotsec-zone/Desktop/comfast/_CF-N1-S-V2.6.0.1.bin.extracted/squashfs-root/"
# 1) 准备 qemu 到 rootfs
sudo cp /usr/bin/qemu-mips-static "$ROOTFS/usr/bin/"
# 2) 挂载运行时目录
sudo mkdir -p "$ROOTFS/proc" "$ROOTFS/sys" "$ROOTFS/dev" "$ROOTFS/var/run" "$ROOTFS/tmp"
sudo mount -t proc proc "$ROOTFS/proc"
sudo mount --rbind /sys "$ROOTFS/sys"
sudo mount --rbind /dev "$ROOTFS/dev"
# 3) 进入 chroot
sudo chroot "$ROOTFS" /bin/sh
# 4) 改 nginx 端口,避免占用宿主 80/443
cp /etc/nginx/nginx.conf /tmp/nginx-test.conf
sed -i 's/listen 80;/listen 8080;/' /tmp/nginx-test.conf
sed -i 's/listen 443 ssl;/listen 8443 ssl;/' /tmp/nginx-test.conf 2>/dev/null || true
# 5) 启动 webmgnt
/usr/bin/qemu-mips-static /usr/bin/webmgnt -d &
# 6) 启动 nginx(前台)
/usr/bin/qemu-mips-static /usr/sbin/nginx -c /tmp/nginx-test.conf -g 'daemon off;'
启动webmgnt,让它监听9002。

启动前端nginx

登录是能登陆上去,但是还是有很多启动项没有起来,而且除了主界面,其他界面都运行不起来,说明还是有其他功能没有运行。

发现三个问题点,一个是switch,设备启动时程序想要交换芯片或交换机控制任务,但当前模拟环境里没有对应硬件、驱动或者控制接口;第二个是Failed to connect to ubus,属于依赖服务缺失 Tips:ubus 是 OpenWrt 常见的消息总线;第三个是/tmp/sysinfo/board_name 和/tmp/sysinfo/mac 这两个文件一个是标识设备型号/硬件平台,另一个是设置MAC地址(通常是LAN/WAN/MAC)Tips: sysinfo目录是运行时系统信息缓存目录,它是设备启动过程中动态生成的临时信息。通常这些文件是在系统启动过程中,由 **init 脚本 + board_detect + 系统服务(ubus / nvram)**共同生成的

当前设备可能的完整生成链路
内核启动
↓
/sbin/init
↓
/etc/init.d/rcS
↓
执行一堆启动脚本
↓
board_detect / system.sh
↓
读取硬件信息(flash / nvram / 驱动)
↓
写入 /tmp/sysinfo/*
所以原因是没有真实的硬件板子,导致sysinfo文件里缺少board_name和mac数据,现在的思路就是去到系统里去寻找有没有可能对这个sysinfo文件输入数据的程序,如果有的话,我们启动这个程序,如果没有的话,我们伪造这个数据。


我们看到有两个文件可能和sysinfo有关/lib/ar71xx.sh和10_sysinfo我们分别看一下它们的代码。
/lib/ar71xx.sh:dd if=$dev bs=1 skip=0 count=6 2>/dev/null | hexdump -v -e '1/1 "%02x:"' | sed '$s/.$//' > /tmp/sysinfo/mac这表示从某个设备/分区$dev读取前6个字节,格式化成MAC地址,写入/tmp/sysinfo/mac。
/lib/ar71xx.sh就是主要往sysinfo文件里面写入数据的脚本,运行这个脚本试一下。

运行失败,开始伪造!
wifi_info_init() {
local board=$(ar71xx_board_name)
local def_txpower_2g
local def_txpower_5g
local no_ht80_with_11a
local wifi_user_led
local button_wps
case "$board" in
ap121)
def_txpower_2g="25"
;;
cf-wa300 |\
cf-wa300v2 |\
cf-wa700 |\
cf-wr600n |\
cf-wr605n |\
cf-n1s |\
ws-gr402 |\
ws-gr405 |\
cf-wr615n)
def_txpower_2g="25"
;;
cf-a4 |\
cf-e113a |\
cf-e120a |\
cf-e120av2 |\
cf-e120av3 |\
cf-e211a |\
cf-e305a |\
cf-e312a |\
cf-e315a |\
cf-e6100)
def_txpower_5g="21"
no_ht80_with_11a="1"
;;
cf-e317a)
def_txpower_5g="28"
no_ht80_with_11a="1"
;;
cf-e356a |\
cf-wa750)
def_txpower_2g="21"
def_txpower_5g="21"
no_ht80_with_11a="1"
;;
cf-e4)
def_txpower_2g="20"
def_txpower_5g="17"
no_ht80_with_11a="0"
;;
esac
[ -n "$def_txpower_2g" ] && echo "$def_txpower_2g" > /tmp/sysinfo/txpower
[ -n "$def_txpower_5g" ] && echo "$def_txpower_5g" > /tmp/sysinfo/txpower_5g
[ -n "$no_ht80_with_11a" ] && echo "$no_ht80_with_11a" > /tmp/sysinfo/no_ht80_with_11a
case "$board" in
cf-wr615n |\
cf-wr630ac |\
cf-wr635ac |\
cf-wr650ac)
wifi_user_led="1"
button_wps="1"
;;
cf-e3 | \
cf-e4 | \
ws-r642-overseas |\
cf-wr752ac |\
cf-n1s |\
ws-gr402 |\
ws-gr405 |\
ws-r650)
button_wps="1"
;;
esac
[ -n "$wifi_user_led" ] && echo "$wifi_user_led" > /tmp/sysinfo/wifi_user_led
[ -n "$button_wps" ] && touch /tmp/sysinfo/button_wps
# TODO if anyone do not need admin wifi, disable here
case "$board" in
cf-rf105)
echo "do generate any files about wifi"
;;
*)
echo "1" > /tmp/sysinfo/admin_wifi_exist
;;
esac
}
我们的设备是CF-N1-S,写出对应伪造脚本
mkdir -p /tmp/sysinfo
echo "cf-n1s" > /tmp/sysinfo/board_name
echo "CF-N1-S" > /tmp/sysinfo/model
echo "00:11:22:33:44:55" > /tmp/sysinfo/mac
echo "25" > /tmp/sysinfo/txpower
touch /tmp/sysinfo/button_wps
echo "1" > /tmp/sysinfo/admin_wifi_exist
echo "00:11:22:33:44:55" > /tmp/sysinfo/wifidog_mac

我们发现,之前的sysinfo问题以及Segmentation fault问题不见了,我们在squashfs-root里面找到ubusd二进制文件,我们模拟运行它。


模拟成功!
Access denied的根因是登录后的会话被固件自己删掉,首次登录/引导分支导致的 Access denied。
我们再回看启动项,发现在/etc/rc.local下

这段配置文件主要作用一是修网络,二是跳过首次引导/协议页,所以它是解决Access denied的主要原因。查找可能的使用rc.local配置文件的文件,/etc/init.d/done脚本就是运行这个文件的,我们只要运行后一部分就可以了。

系统模拟(qemu-system-mips)
我们再用系统模拟玩一下,系统模拟我们需要搭建一个MIPS系统虚拟机,配置内外网卡,将文件系统打包进入到虚拟机内。
配置主机网络:
sudo tunctl
