JNDI Injection — Attack Flow

Pradeep Kumar
4 min readMay 25, 2024

--

In this blog, we will be focusing on how the JNDI attack works from behind the scene. For understanding the basics and exploitation of JNDI, you can refer to my other blog: https://medium.com/@prajeet67/jndi-injection-the-complete-story-4c5bfbb3f6e1

Exploit Flow — RMI Remote FactoryClass

  • InitialContext.lookup(URI) is is invoked within the target application, where the URI is user-controller.
  • The attacker manipulates the URI parameter to point to a malicious RMI service, using a URL such as rmi://hacker.rmi/exploit.
  • The attacker’s RMI server returns a Reference object. This Reference object includes a specifically crafted Factory class.
  • The target application dynamically loads and instantiate the Factory class, and then call factory.getObjectInstance() to obtain the object instance.
  • When the ObjectFactory class cannot be found locally, it will be obtained from the address specified by the classFactoryLocation parameter of the Reference Class and loaded accordingly.
  • The instantiation of this Factory class triggers the execution of malicious code. This code could be written within the constructor, static block, or the getObjectInstance() method of the Factory class, to achieve to Remote Code Execution (RCE).
  1. Stacktrace

2. RMI Request

3. Get Reference Object

4. Load class from codebase

  • The URLClassLoader can load classes and resources from a list of URLs, which can point to directories, JAR files, or remote locations.

Exploit Flow — LDAP Remote FactoryClass

  1. StackTrace

2. LDAP Request

3. Get Reference Object

4. Load class from codebase

EXPLOIT FLOW — LDAP javaSerializedData to trigger Local Gadget

  1. Stacktrace

2. Ldap Request

3. Deserialize the object in javaSerializedData Field

  • com.sun.jndi.ldap.object.trustSerialData property must be True for the deserialization to take place. This was set to False in very recent java versions. One of the PR can be found here: https://github.com/openjdk/jdk/pull/10228

Understanding the relation between javaClassName and javaFactory

javaClassName

  • Specifies the name of the class that has to be instantiated
public class MyClass {
private String message;

public MyClass(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}

javaFactory

  • Specifies a class that will create the instance of the above specified class.
import javax.naming.spi.ObjectFactory;
import javax.naming.*;
import java.util.Hashtable;

public class MyFactory implements ObjectFactory {
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> env){
// Logic to create an instance of MyClass
return new MyClass("Hello from MyFactory");
//For attack, we can directly add our payload in this
}
}

Connect with me on Twitter for updates: https://twitter.com/sickuritywizard

Happy Hacking…

--

--