型号:X5000R(http://www.totolink.cn/home/menu/newstpl.html?menu_newstpl=products&id=65)
AX1800 无线双频千兆路由器(http://www.totolink.cn/home/menu/newstpl.html?menu_newstpl=products&id=65)
下面有分析思路,设备模拟过程比较靠近新手,师傅们可以直接跳到后面分析过程。
一
漏洞
![](https://img.nsg.cn/xxl/2022/04/f01235e3-bd6c-4a88-b5e7-00413083d693.jpeg)
登陆页面构造参数,无需密码。
formLoginAuth.htm?authCode=1&action=login(http://192.168.0.1/formLoginAuth.htm?authCode=1&userName=admin&goURL=home.html&action=login)
可直接绕过登陆,进入后台。
![](https://img.nsg.cn/xxl/2022/04/eab9f54e-196f-4895-bc40-91440fc4cb6a.jpeg)
![](https://img.nsg.cn/xxl/2022/04/5d7daf58-9b55-42d0-9162-58e826a70396.jpeg)
产生原因在lighttpd wen服务文件from_login函数中。
![](https://img.nsg.cn/xxl/2022/04/85e301ab-9d7e-4142-b38d-f0eacb1bc979.jpeg)
if (iVar2 == 0) { iVar1 = strcmp((char *)&sa58,"ie8"); if (iVar1 == 0) { pcVar1 = "/login_ie.html"; } else { iVar1 = atoi((char *)&sa58); if (iVar1 == 1) { pcVar2 = "/login.html"; pcVar1 = "http://%s%s%s"; pcVar3 = "/phone"; LAB_409114: sprintf(param_2,pcVar1,acStack1860,pcVar3,pcVar2); return 1; } pcVar1 = "/login.html"; } sprintf(param_2,"http://%s%s",acStack1860,pcVar1); return 1; }
上面代码是登陆检查,当iVar2=1的时候,直接跳过检查,不需要登陆。
iVar2的值是autoCode参数的值,所以构造autoCode=1即可绕过。
二
模拟
下面是详细分析思路。
今天偶然发现这款非常小众的路由器,至于多小众,我分析这款官方月销15台。
我分析的这款是 AX1800,官方可以直接下载固件。
这款固件超级适合新手第一次分析使用。
binwalk分析:
binwalk TOTOLINK_C8343R-1C_X5000R_IP04433_MT7621A_SPI_16M256M_V9.1.0u.6118_B20201102_ALL.web
![](https://img.nsg.cn/xxl/2022/04/6c75116e-fa3a-4d5d-9a2c-f53dd662931c.png)
squashfs文件系统,uImage,LZMA压缩文件中应该也是个比较大的内容,直接使用-Me参数递归提取。
binwalk -Me TOTOLINK_C8343R-1C_X5000R_IP04433_MT7621A_SPI_16M256M_V9.1.0u.6118_B20201102_ALL.web
![](https://img.nsg.cn/xxl/2022/04/eeddcaa3-8176-48ad-812f-3a78e1548d7c.png)
里面有标准的文件系统。
查看架构:
binwalk ./bin/busybox
![](https://img.nsg.cn/xxl/2022/04/ae5b4f2e-3765-4c21-b78d-92e6714fe8f7.png)
mips小端序,查看其文件系统瞅瞅有没有什么东西。
有个工具叫firmwalker,可以自动分析文件系统,提取重要文件,我个人觉得不是特别好用。
我比较推荐使用vscode来做分析。
下面是要关注的一些地方:
etc/ #这里会存放系统启动文件如openwrt的rcS文件sbin/ #这里一般会存放厂商制作的功能性文件和提供web服务的文件www/ #这里会存放一些web静态页面和后台服务文件文件
其他地方也尽量看一下,经验多了就容易清楚哪些文件是做什么的了,没经验就慢慢来。
这里发现了这几个文件:
![](https://img.nsg.cn/xxl/2022/04/8d18a169-df92-44c6-9e0d-89b2fb2b13a9.png)
![](https://img.nsg.cn/xxl/2022/04/20af4568-2d64-4c26-8cdb-44f75fce9b37.png)
![](https://img.nsg.cn/xxl/2022/04/633b87e7-d708-4e4d-8229-9c8c354840ec.png)
可以看到他使用了lighttpd 的web服务文件。
一般固件大概会有这几个轻量级httpd文件:lighttpd,httpd,uhppd。
其他的还有很多。
尝试使用qemu-user模拟http服务。
cp (which qemu-mipsel-static) ./sudo chroot . ./qemu-mipsel-static ./usr/sbin/lighttpd
![](https://img.nsg.cn/xxl/2022/04/bdabb96a-0fd1-458e-b11d-ccd58f2432aa.png)
这里的报错是需要用-f参数指定配置文件,上面已经发现了lighttpd.conf文件。
sudo chroot . ./qemu-mipsel-static ./usr/sbin/lighttpd -f ./lighttp/lighttpd.conf
![](https://img.nsg.cn/xxl/2022/04/777667aa-1b9d-4c10-a294-5a87c91a3c77.png)
没有这个文件,这里我们先去把这个路径改一下,在lighttpd.conf中。
![](https://img.nsg.cn/xxl/2022/04/7f2f4494-d885-4760-a342-f11e1a655614.png)
把它改到固件的系统文件中./var/run/lighttpd.pid,并且去创建这个文件。
运行:
![](https://img.nsg.cn/xxl/2022/04/6c408405-2120-4f75-b49e-e066816ed579.png)
这里虽然正常启动,但是如果不挂载文件夹,还是挺多问题的,所以我更倾向使用系统模式。
这里系统模式不做赘述,我写了个脚本,可以很方便启动。
核心文件比较大,大家按文件自行下载:
https://people.debian.org/~aurel32/qemu/mips/
我把脚本放链接放这里:
https://gitee.com/p1piyang/backward-analysis/tree/master/
qemu启动:
sudo ./start-mipsel.sh
sudo 启动:
ifconfig eth0 192.168.5.12 up #qemu中设置ip,qemu里边
将文件系统上传:
scp -r squashfs-root/ root@192.168.5.12:/root/ #在主机
挂载:
chroot ./squashfs-root/ /bin/sh
启动:
./user/sbin/lighttpd -f ./lighttp/lighttpd.conf
![](https://img.nsg.cn/xxl/2022/04/0d5f85ac-f48a-4b6b-9709-16febe5923f1.jpeg)
三
分析
刚开始是想直接去分析lighttpd的。随手登陆了一下,看了下包。
我个人浅薄的经验,不要单纯去无目的的分析某个应用,我之前犯过这种错误,太容易对着一个程序漫无目的的乱逛,希望你没有这种情况。
这里明显可以看到调用了cgi文件,之前看文件的时候看到了这个东西的。
![](https://img.nsg.cn/xxl/2022/04/2e7658c7-ccf9-4843-b826-2b1ae25faa3b.png)
可以去分析下这个文件。
ghidra open!!! Link 死大头!!! search "action"!!!
![](https://img.nsg.cn/xxl/2022/04/8b9c25e9-15ce-4275-b166-d915765866ce.jpeg)
action=login,交叉引用,看一下。
![](https://img.nsg.cn/xxl/2022/04/eafdf94d-755e-438e-9ede-24794e297085.jpeg)
说实话,ghidra的这个伪代码看着老奇怪了,这里是判断了登陆还是升级。
![](https://img.nsg.cn/xxl/2022/04/ace78adf-2b32-4f6c-9eaf-841c493be194.jpeg)
if下面,这里判断flag=1,最后的逻辑是将字符串格式化到acStack4456中。
![](https://img.nsg.cn/xxl/2022/04/75e89c32-2514-47c2-8fae-e2297387f0b6.jpeg)
再往下这个地方我刚开始比较懵了,因为websGetVar程序查找表变量var,相当于获取参数。所以这里并没有往下看,而是换了个思路点。
这里知道了他是对登陆做了个判断。
去查找登陆的请求参数。
![](https://img.nsg.cn/xxl/2022/04/f75a874b-d280-42cd-819e-de7dc8f350f1.png)
![](https://img.nsg.cn/xxl/2022/04/d9f95a7b-a27b-4c05-8596-3b3e4bfd0d8b.jpeg)
发现了这么个地方,根据登陆的包。
![](https://img.nsg.cn/xxl/2022/04/0b74cb3d-e137-439c-af20-941ba0a5e8e3.png)
发现他返回了一串地址。并且主动访问了这串地址。
![](https://img.nsg.cn/xxl/2022/04/111a60e8-dc4c-4160-86bc-dd7aae06ef3c.png)
所以这个地方是判断密码的地方。本来想试试正确密码,来分析下,结果密码怎么都不对。
这里解释下,因为我没有设备,是直接在官网下载的固件,所以这个密码怎么都不对,我怀疑是固件模拟的问题,就没有往下追究。
他主动访问了formloginAuth.htm,在www/文件夹下并没有这个文件,所以去找下lighttpd文件分析下。
ghidra open!!! Link 死大头!!! search "formLoginAuth"!!!
![](https://img.nsg.cn/xxl/2022/04/bd1a5036-de80-491b-b85e-8173f83b863e.jpeg)
跟进from_Login函数:
![](https://img.nsg.cn/xxl/2022/04/c5596eda-0dec-45ea-807a-cb0e9df6c456.jpeg)
这里就发现了参数处理。
![](https://img.nsg.cn/xxl/2022/04/7530ab41-518c-4d1e-b471-e96ade8dd135.png)
判断几个参数做了什么,userName是空的先不看,goURL是某个html文件,盲猜他是的从哪来的,action是要做什么。
所以现在要看一下authCode。
如果authCode不等于0,iVar2就等于整形的authCode的值。
往下分析:
![](https://img.nsg.cn/xxl/2022/04/c656b37f-2105-47d6-a78f-83dc2bdaef81.jpeg)
这里改成1之后直接,跳过了这个判断。
但是只吧这个改为1之后还是返回到登陆界面。
![](https://img.nsg.cn/xxl/2022/04/24c0f305-f5a6-4b00-80d2-aea380272efd.jpeg)
这里pcVar2=1,导致跳过了设置pcVar2 = home.html。
所以我猜测goUrl参数不是从哪来,而是从哪去。
最后发现果然是哦。
其实在ghidra反编译的时候,好多地方不太习惯,很多地方靠函数名和字符串硬猜。