漏洞概要
受影响版本
- 固件版本 ≤ 1.0.168
漏洞类型
- 授权后命令注入漏洞
风险等级
- CVSS 3.1评分:8.8(High)
- 影响范围:机密性/完整性/可用性全破坏
漏洞机理
小米AX9000
路由器在1.0.168
版本及之前存在二进制漏洞(命令注入),该漏洞由于未对非法的appid
做出有效限制而引起。已授权登录的攻击者在成功利用此漏洞后,可在远程目标设备上执行任意命令,并获得设备的最高控制权,造成权限提升。
环境搭建
固件下载地址:固件下载
小米AX9000
路由器固件是AArch64el
架构的,我这里因为使用的mac的m芯片,就是arm64的,加上提前安装了ubuntu、arm的虚拟机,我这里 就直接在虚拟机中模拟起手,
解压后,直接文件夹内进行挂载,
mount --bind /proc proc
mount --bind /dev dev
chroot . /bin/sh
启动httpd服务
这里有三个http程序,uhttpd,mihttpd,sysapihttpd。查看/etc/sysapihttpd/sysapihttpd.conf
发现就是nginx,并且监听了80端口,
根据openwrt
的内核初始化流程,按理说应该先启动/etc/preinit
,其中会执行/sbin/init
进行初始化,但是在这套固件仿真的时候,这样会导致qemu
重启,所以我们首先先执行/sbin/init
中最重要的/sbin/procd &
,启动进程管理器即可。
这里我们直接启动sysapihttpd
即可,/etc/init.d/sysapihttpd start
Failed to connect to ubus
这里有报错这里是用到了ubus
总线通信,我们需要启动/sbin/ubusd &
再去start http程序,启动成功,且netstat
查看web
端口也正常对外开放,这里的nvram我们暂时用不到,就先不管,
访问一下,成功模拟,
因为我这里前面已经设置过密码了,所有让我们直接密码登录,
由于该漏洞是需要登录授权的,所以我们得看一下后端的密码校验是怎么写的,这里需要分析一下
身份校验的过程在/usr/lib/lua/luci/dispatcher.lua
的jsonauth
函数中,其中调用了checkUser
函数根据从POST
报文中获取的username
,password
和nonce
(现时)字段进行身份验证。
在/usr/lib/lua/xiaoqiang/util/XQSecureUtil.lua
的checkUser
函数中,首先获取了系统uci
配置项中存储的密码,这里的XQPreference.get
函数在本文的上一节中已经给出,可分析出此处的配置项为account.common.(用户名)
。接着,需要POST
报文中传入的现时字段nonce
与系统中uci
存储的password
的值拼接后进行sha1
哈希的结果等于POST
报文中传入的密码字段。
到这里我们清楚了后端的鉴权方式,我们去前端js里看一下是怎么构建登录的用户名和密码的,
这里可以看到固定的用户名就是admin,
而密码字段是通过oldPwd()
函数加密后的结果。这里的oldPwd()
函数将用户提交的密码明文与一个固定的key
值(a2ffa5c9be07488bbb04a3a47d3c5f6a
)拼接后,进行sha1
哈希,再将结果继续与现时nonce
拼接后,再sha1
哈希一次,作为POST
请求报文中的密码字段
结合上述分