Since news of the Log4Shell vulnerability (CVE-2021-44228/CVE-2021-45046) broke last month, infosec teams have been scrambling to find instances of the vulnerability in their environments and remediate them. It’s been a challenge because of the breadth of impact: any Java application that uses the popular Apache log4j2 logging library is potentially vulnerable. Some vendors, like VMware and Cisco, have had to issue advisories for dozens of affected products. In the meantime, attackers have been taking full advantage.

A variety of security tools have come up in the last few weeks to assist companies in remediating Log4Shell. Most of these tools stop at the point of detecting Log4Shell, with varying degrees of accuracy. As an autonomous pentesting solution, NodeZero’s approach is to act like an attacker: NodeZero not only detects where Log4Shell is present, but it also attempts to fully exploit it just like an attacker would.

The value of exploitation is that it allows security practitioners to understand the true impact of a vulnerability. In the case of Log4Shell, the true impact of exploiting it is one of the following:

  • Moderate Impact: Information disclosure of application and host configuration
  • High Impact: In addition to above, disclosure of sensitive credentials such as AWS access keys or database passwords
  • Critical Impact: Remote code execution leading to host compromise

Also important is knowing the type of host that can be compromised – the impact of compromising a VMware vCenter Server is much more severe than a one-off application in a lab subnet. Understanding the true impact of Log4Shell enables security teams to take a disciplined, risk-based approach to fixing it. We describe here how NodeZero detects and exploits Log4Shell and surfaces its impact.

Background: How Attackers Exploit Log4Shell

Remote Code Execution Flow

Log4Shell affects any Java application using a vulnerable version of the Apache log4j2 library. Attackers exploit a vulnerable application by passing crafted user input to it, hoping that the application will log that input. The crafted user input contains a special string of the form “${jndi:…}”. JNDI stands for Java Naming and Directory Interface. It’s a Java-specific abstraction used to query “naming” services on the network for resources like configuration.

When the application receives and logs malicious input from an attacker, the vulnerable log4j2 component of the application is induced to perform a JNDI lookup. The application connects over the network to attacker-controlled servers. These attacker-controlled servers return malicious commands to the vulnerable application in the form of serialized Java objects. When these objects are deserialized by the vulnerable application, the attacker-provided commands are executed, leading to remote code execution and giving the attacker access to the application host.

The above flow is a worst-case outcome with Log4Shell and has been proven publicly for a number of prominent Java applications such as VMware vCenter Server, Unifi Controller, and Apache Solr.

Information Disclosure Flow

In a lot of cases, based on the type of application that’s vulnerable and the version of Java running, attackers won’t be able to get to remote code execution. However, attackers can still disclose system-level information from the host of the vulnerable application. If an attacker is lucky, this information can include sensitive secrets such as AWS access keys and database passwords.

Information disclosure is possible because of a handy feature supported by the log4j2 library: the ability to lookup and fill in or “interpolate” the value of substitution variables. Substitution variables use the syntax “${variable_name},” and log4j2 supports pulling in arbitrary environment variables using the “env” prefix. This means that if an application is running in an environment containing sensitive information, an attacker can leak that information. An attacker simply includes the substitution variable to be leaked in the crafted JNDI payload that is logged by the vulnerable application. The vulnerable application looks up and substitutes that variable with its actual value and sends it back to the attacker, as depicted in the flow below.

How NodeZero Exploits Log4Shell

NodeZero uses a variety of techniques for detecting and exploiting Log4Shell.

Detection Phase

Initially, to identify which applications are potentially vulnerable to Log4Shell, NodeZero scans the network using the open source nuclei tool. Scanning takes on two forms:

  • Application fuzzing: NodeZero sends crafted network requests with JNDI payloads in places that are commonly logged by applications like certain HTTP headers and URL paths.
  • Application-specific detection: NodeZero sends tailored requests targeted to specific applications, based on known proof of concepts for exploiting Log4Shell against those applications.

In practice, we’ve seen success using both forms of scanning to detect Log4Shell.

NodeZero detects if an application is vulnerable by checking for DNS requests originating from the application. How does this work? In place of the attacker host, the JNDI payloads sent by NodeZero contain a randomly generated subdomain based off a Horizon3-owned domain. The DNS name server for this domain is a custom Horizon3-managed DNS server. When an application vulnerable to Log4Shell attempts to make the network connection to perform a JNDI lookup, it must first resolve the subdomain using DNS. That DNS request is sent to the Horizon3 DNS server and captured as proof of the Log4Shell vulnerability. For example, here’s an example of inducing a DNS request from a vulnerable VMware vRealize Operations Manager application:

Exploit Phase

After an application is found to be vulnerable, NodeZero attempts to exploit the application, as described in the “How Attackers Exploit Log4Shell” above. NodeZero starts up custom attack servers, re-verifies the vulnerability, and then carries out the Information Disclosure and Remote Code Execution flows.

NodeZero captures as proof all information it was able to leak via Log4Shell. Here’s an example of leaking an AWS access key from the environment of a running Apache Solr application:

NodeZero attempts remote code execution by running network commands like “curl,” “wget,” and “powershell” on the target host to initiate HTTP connections back to NodeZero. NodeZero attempts a variety of Java serialization payloads that work across Linux and Windows and different versions of Java. As proof, NodeZero captures the HTTP request from the vulnerable host. Here’s an example of proof from exploiting the Unifi Controller application, getting it to connect back to NodeZero using curl.

How NodeZero Surfaces the Impact of Log4Shell

NodeZero uses the results of its exploitation attempts to surface the impact of Log4Shell in a few different ways.

First, as shown above, NodeZero captures detailed proof of exploitation. This includes all the information that could be leaked as a result of exploiting Log4Shell and proof of remote code execution.

Second, NodeZero scores all weaknesses based on the outcome of exploitation. The CVSSv3 score for Log4Shell is 10.0 (Critical). However that score assumes a worst case scenario. NodeZero starts with a base score to 7.5 (High), which is consistent with just an information disclosure impact. If NodeZero is able to achieve remote code execution, the score is bumped up to Critical.

To illustrate, here are two Apache Solr servers, one running version 7.4 on port 8983 and another running version 8.11.0 on port 8984. NodeZero was able to get remote code execution on the 7.4 Solr instance but not on the 8.11.0 instance. The score of each weakness reflect its true impact.

Third, if remote code execution is possible, NodeZero specifically raises that up as a “Host Compromise” impact, making it easy to identify instances where Log4Shell can be exploited to achieve the worst-case outcome. Here’s an example of a “Host Compromise” impact generated from getting remote code execution against a vulnerable Apache Struts application.

Fourth, NodeZero understands that some applications are more critical to the business than others. Based on NodeZero’s understanding of the type of application that could be compromised, NodeZero generates a “Critical Infrastructure” impact accordingly. Here’s an example of a “Critical Infrastructure” impact for VMware vCenter.

Conclusion

Log4Shell is a “once-in-a-decade” type of vulnerability that will linger in environments for years to come. For a vulnerability with such a broad, lasting impact, it’s important to establish a principled and disciplined approach for discovering and remediating it. NodeZero both detects and exploits Log4Shell, surfacing a wealth of information that can be used to understand its real impact and prioritize its remediation.

Run an autonomous pentest on your environment today, and ensure your limited resources are spent fixing problems that can actually be exploited.