Log4j Patching Guide - richnadeau/Secure-Web-Application-CTF-Nadeau-Notter GitHub Wiki
Vulnerability Information
What is Log4j?
Apache’s Log4j software library used to log security and performance information.
What is the Exploit?
Exploitation of Remote Code Execution (RCE) in versions 2.0-beta9 to 2.14.1. CVE-2021-44228 "JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled." (JNDI = Java Naming and Directory Interface)
This exploit is a lack of Input Validation and pertains the OWSAP Top 10 #6 - Vulnerable and Outdated Components and # 3 - Injection
Proposed Solution
Input Validation
The username and password fields have no input validation. This is the main point of failure with this exploitation. We were able to input anything we wanted including the malicious code. This is very easily mitigated by using the built in HTML attributes: required and pattern.
Navigate to the log4-shell-poc repository and enter the target folder:
cd /root/log4-shell-poc/target
You will see a .war files, log4shell-1.0-SNAPSHOT.war and a .jar file marshalsec-0.0.3-SNAPSHOT-all.jar. .war files are used for running Java Web Applications and always contain at least three things: an index.jsp, a WEB-INF folder, and META-INF folder. WEB-INF is where all the functions and libraries of a web application are stored. Unpack log4shell-1.0-SNAPSHOT.war. This is the vulnerable web application.
unzip log4shell-1.0-SNAPSHOT.war
You will notice that this unzips two folders and an index.jsp. We want to edit index.jsp.
For example, I patched the index.jsp like this:
When we try to use the payload the characters are rejected and the character limit stops at 15.
Here is my patched version of Index.jsp which you can use as a reference or download and implement into the .war file.
When you're to pack everything up and rerun the docker file, move the marshalsec-0.0.3-SNAPSHOT-all.jar into log4j-shell-poc parent folder temporarily and remove any other file/folder that isn't index.jsp or contained within WEB-INF/ or META-INF/. We are now going to zip these files as a .war with this command:
jar -cvf log4shell-1.0-SNAPSHOT.war *
Next, remove the surplus the left over index.jsp, WEB-INF/, and META-INF/ and return marshalsec-0.0.3-SNAPSHOT-all.war to this directory.
Now, return to the log4j-shell-poc parent folder and rebuild and rerun the docker file:

Though this does resolve the issue of Input Validation, I encourage you to update the Log4j files as well.
Understanding the Scans
The scanner we ran post exploitation reveals and locates the log4j files that are affected by this vulnerability. For me this was:
[WARNING] [32 - vulnerable binary classes] /var/lib/docker/overlay2/ae495803dba5b7c8f1a79ceb06e221cee7745928c3d6cc7afa47b331c6e2d5f5/merged/usr/local/tomcat/webapps/ROOT/WEB-INF/lib/log41-core
-2.14.1.jar
[WARNING] [81= vulnerable binary elasses]/var/lib/docker/overlay2/ae495803dba5b7c8f1a79ceb06e221cee7745928c3d6cc7afa47b331c6e2d5f5/diff/usr/local/tomcat/webapps/ROOT/WEB-INF/lib/log4j-core-2.14-1.jar
- Notice:
/tomcat/webapps/
In a default Tomcat configuration, /tomcat/webapps/ is the DocumentRoot directory, similar to /var/www/html in Apache.
Since we are using a sever inside of a Docker container, the information the scanner provides is useful only to tell us what code we would need to edit to fix the exploit: /WEB-INF/lib/log4j-core-2.
Updating the Vulnerable Log4j Files
Open an SSH connection to the Ubuntu box and elevate to root. We'll need to download the updated versions of the log4j vulnerabilities from Apache's website:
cd /tmp
wget https://dlcdn.apache.org/logging/log4j/2.17.1/apache-log4j-2.17.1-bin.tar.gz
Now, unzip the file and enter the directory:
tar -xf apache-log4j-2.17.1-bin.tar.gz
cd apache-log4j-2.17.1-bin
ls
This directory contains all the update-to-date versions of every log4j jar file.

The only files interest for this fix are: log4j-core-2.17.1.jar and log4j-api-2.17.1.jar. Though only the core file is vulnerable to CVE-2021-44228, it's a good idea to update BOTH of these files.
Next, we need to install java in order to pack up a .war file, which is a type of zip that is used by java based web applications.
sudo apt install default-jdk
Navigate to the log4-shell-poc repository and enter the target folder.
cd /root/log4-shell-poc/target
Unpack log4shell-1.0-SNAPSHOT.war.
unzip log4shell-1.0-SNAPSHOT.war
The folder of interest here is WEB-INF/. Open this folder, then the subfolder lib/.
Now copy the log4j-core-2.17.1.jar and log4j-api-2.17.1.jar files from /tmp/apache-log4j-2.17.1-bin/ to here and delete the 2.14.1 files:
cp /tmp/apache-log4j-2.17.1-bin/log4j-core-2.17.1.jar .
cp /tmp/apache-log4j-2.17.1-bin/log4j-api-2.17.1.jar .
rm log4j-core-2.14.1.jar
rm log4j-api-2.14.1.jar
Now return to the target folder and move marshalsec-0.0.3-SNAPSHOT-all.jar into log4j-shell-poc parent folder temporarily. At this point the only thing in target/ should be: Index.jsp, WEB-INF, and META-INF. We are now going to zip these files as a .war with this command:
jar -cvf log4shell-1.0-SNAPSHOT.war *
Move marshalsec-0.0.3-SNAPSHOT-all.jar file we moved earlier back into target/.
Now, rebuild and rerun the docker file

Reopen the Web Application and enter the payload command:

You will now notice that the exploit is no longer working and are instead redirected to the login invalid page:
Go ahead and log in as the admin user to make sure the website still functions properly:
- username: admin
- password: password

Finally, rerun the scanner as a final confirmation:
wget https://raw.githubusercontent.com/rubo77/log4j_checker_beta/main/log4j_checker_beta.sh -q -O - | bash
- Keep in mind that the previous docker file may appear here as well. Pay attention to the file path and the log4j file version for this reason. The scanner is built to detect any log4j files so you will see the
2.17.1files but they will not be marked as vulnerable.
In the screenshot of the scanner output below, I've highlighted in orange the exploitable version of the Web Application and highlighted the update-to-date version in purple. Notice that the log4j file versions are different. I've also highlighted the file path as proof that these were different sessions.

Reference: https://logging.apache.org/log4j/2.x/security.html
Bonus: Detecting Log4j on Elastic
If you are running an Elastic stack with Elastic Security configured, you can use this alert rule to detect when Vulnerable Log4j is exploited:
sequence by host.id with maxspan=1m
[network where event.action == "connection_attempted" and
process.name : "java" and
/*
outbound connection attempt to
LDAP, RMI or DNS standard ports
by JAVA process
*/
destination.port in (1389, 389, 1099, 53, 5353)] by process.pid
[process where event.type == "start" and /* Suspicious JAVA child process */
process.parent.name : "java" and
process.name : ("sh",
"bash",
"dash",
"ksh",
"tcsh",
"zsh",
"curl",
"perl*",
"python*",
"ruby*",
"php*",
"wget")] by process.parent.pid