The Log4j 2 flaw makes software running on millions of machines vulnerable to exploit. It could be attacking a server, a security door, or even a pop-up toaster connected to the internet. Here are some context on the vulnerabilities and steps to prevent its spread.
What is Log4j 2?
Almost every application keeps records, known as logs, of events including errors. These are used to understand the context of an error or event that comes under question.
Many times logs are also used for analytics and audit. Java being a cross platform common language supporting more that 3 billion devices is far more common than your toothbrush model. It might not be a surprise that your electric toothbrush runs on Java.
Rather than creating a logging system for every new Java application, software developers often adopt the open source logging library Apache Log4j 2, an upgraded version of one of the most popular logging libraries developed by Apache Software Foundation.
Log4j 2 vulnerability (CVE-2021-44228)
The critical vulnerability in Log4j was first reported to Apache on November 24 by Chen Zhaojun, an employee on Alibaba Group Holding Ltd.’s cloud-security team. The vulnerability was introduced in version 2.0-beta-9 and all versions until 2.14.1. An initial patch was released but easily bypassed. A relatively secure and stable version (2.15.0) was released on December 9 — but it was already too late.
An exploit had been publicly released on Twitter by an anonymous user. The exploit was weaponized within an hour in many forms targeting millions of systems. The vulnerability was assigned CVE-2021-44228 with the maximum possible CVSS score of 10.
The JNDI lookup feature of Log4J2 allows objects to be retrieved via JNDI – Java Naming and Directory Interface (an API that provides naming and directory functionality to Java applications). The lookup even executes the object where needed, providing a complete control on the object execution to the attacker. While there are many possible protocols with JNDI, the well known protocols with Log4J2 are LDAP (Lightweight Directory Access Protocol) and RMI (Remote Method Invocation).
In another way when a new log entry is being created, and Log4j2 encounters a JNDI reference, it actually goes to the supplied resource and collects whatever it needs to fetch in order to resolve the required variable, and in this process it might even download remote classes and execute them. To make it worse there is recursive resolution of variables that allows obfuscation and support exfiltration of data via DNS lookup.
Log4j 2 Attack Execution Flow using JNDI Vector
There were earlier warning signs that JNDI could be used for remote code execution, including this presentation at the Black Hat cybersecurity conference in 2016. Researchers identified a method to exploit a broad class of software that included JNDI.
There are extensive ways to obfuscate the payloads using different protocols such as ldap, rmi, and text processors like upper/ lower, or lookups like env/sys that an attacker can create multiple attack string combinations. I observed many obfuscation techniques already being used to avoid detection with some of them listed below:
Any string that is logged via Log4j 2 and in users control could potentially be used to exploit this vulnerability. It could even affect systems that are deep within the infrastructure, because all it requires for the exploit to work is the user string to reach the vulnerable log4j logger being used as a dependency by the application or firmware on a device.
The simplicity of this exploit has attracted even script kiddies to go on rampages running attacks across the internet.
Log4j 2 vulnerability (CVE-2021-45046)
Upgrading to 2.15.x JNDI restrictions works to prevent DNS lookups, but allows localhost lookups and is speculated to leverage limited RCE. Attackers could gain control over Thread Context Map (MDC) input data when the logging configuration uses a non-default Pattern Layout when either a Context Lookup (for example, $${ctx:loginId}) or a Thread Context Map pattern (%X, %mdc, or %MDC) us used, and craft malicious input data using a JNDI Lookup pattern resulting in an information leak and remote code execution in some environments and local code execution in all environments. This was assigned a CVE-2021-45046.
A secure and stable version of Log4j 2 2.16.0 was released that disables JNDI by default and requires property log4j2.enableJndi to be set to true to allow JNDI. It also removes support for Message Lookups that could be specified with %m format. However, that fell short of fixes when another vulnerability was discovered that allows an infinite recursion causing a DoS attack.
Log4j 2 vulnerability (CVE-2021-45105)
The DoS vulnerability in Log4j 2 is assigned CVE-2021-45105. For versions 2.14.x and below a simple pattern like ${::-$${::-k}} causes an infinite recursive resolution with the following exception being thrown by the process. Versions 2.15.x to 2.16.x require specific conditions for execution of attack like use of context lookups raising the attack complexity for a successful and disruptive crash.
The timing for DoS and effects were based on the payload. Following payload processed from a python script(2MB resultant) and sent via POST request to a tomcat server
resulted in a lag of around 18 sec with a java.lang.OutOfMemoryError
Mitigation
Exploitability depends on the Java version and how log4j 2 is used, however it should not be the way of reliance as there may be techniques to bypass the security restrictions put in place by Java security manager. There are bypasses even with using the latest Java by itself and trustURLCodebase = false.
A new stable version of Log4j 2 2.17.0 has been released that has required fixes for the three CVEs reported this month.
Earlier remediations provided by Log4j 2 in versions less than 2.17.0 only work partially as countermeasures and may still be vulnerable.
2.16.0 is still vulnerable to the DoS attack under specific conditions and may have RCE vectors unknown yet.
-Dlog4j2.formatMsgNoLookups=true or env LOG4J_FORMAT_MSG_NO_LOOKUPS=true
prevents message lookups but can still execute lookups of the form ${ctx:…}.
Removing JNDI from the classpath also helps to a certain extent but is an unstable way and may cause production problems. There are also various exploitation strategies being used by attackers to bypass this by creating deserialization payloads using existing classes from serialization gadgets such as the JNDI exploit kit.
Takeaways
Various threat actors are experimenting with this new attack vector. Hackers are using the Log4j 2 vulnerability to drop ransomwares like Khonsari, Nemesis Kitten, Cryptowares, and WebShells. It won’t take long for more advanced threat actors to use it for far more dangerous purposes. Instead of shorter monetization, they may be looking to maintain their persistence and prepare for a large-scale attack or future exploitation.
Defense in depth is an ideal way to build roadblocks to exploits by attackers. Containerization and running applications with the least privilege can prevent attackers from gaining full privilege at once.
- Strict firewall rules can contain outbound traffic generated by the log4j exploits.
- Active monitoring always needs to be in place even after all servers are patched and the dust settles.
- Identifying and investigating compromised systems should be prioritized.
Even with all the attention and sleepless nights this vulnerability brings to the security folks, so many organizations still lack the proper visibility in their portfolio. We could see a surge in demand soon around products that can help with any of the hardships the users have experienced in this race to secure lands.