Hack The Box: Forge

Prelude

Forge is an intermediate machine from Hack The Box, developed by NoobHacker9999. I really liked this machine for the initial foothold process. Forge have some internal service and an external website. The external website have an SSRF vulnerability and we can exploit it to access the internal services and eventually get the user shell. Once we are in as the user, we can find a python script that can be run as super user, with python debugger turned on. Once we are in the PDB shell, we can enter custom python script to spawn a root shell.

Let’s begin the exploitation.

Exploitation

The nmap scan showed that Forge have three ports open. Amongst them, port 21 is filtered.

nmap -sCV -v -oN tcp 10.10.11.111

Nmap scan result.

Nmap scan report for 10.10.11.111
Host is up (0.053s latency).
Not shown: 997 closed ports
PORT   STATE    SERVICE VERSION
21/tcp filtered ftp
22/tcp open     ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 4f:78:65:66:29:e4:87:6b:3c:cc:b4:3a:d2:57:20:ac (RSA)
|   256 79:df:3a:f1:fe:87:4a:57:b0:fd:4e:d0:54:c6:28:d9 (ECDSA)
|_  256 b0:58:11:40:6d:8c:bd:c5:72:aa:83:08:c5:51:fb:33 (ED25519)
80/tcp open     http    Apache httpd 2.4.41 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Did not follow redirect to http://forge.htb
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

I navigated to the web server and it redirected me to the hostname http://forge.htb.

I added the hostname to my /etc/hosts file, refreshed the page and it showed me the following gallery.

There was an Upload image button. So, I clicked it and it lead me to the following page.

I tested the Upload function to see if the upload function checks the uploaded file’s type. So, I uploaded a PHP file and it showed me the following link.

I curl-ed the shown URL and I got the contents of the PHP file I uploaded. So, there’s no checking in place for the uploaded file’s format.

There was also an Upload from URL section, where we could provide a URL and the file will be uploaded to the target. I tested that function and it was also working.

But, we can’t upload a PHP reverse shell and execute it because this was a python based web server. I found that when I began to tinker with the upload form and I got the following error.

So, I decided to try accessing the ftp via this to test if SSRF was possible.

I first tried ftp://127.0.0.1/ as the payload, but the protocol ftp was blacklisted. So, I tried http://127.0.0.2:21/ and it retrieved the FTP service banner! I used 127.0.0.2 as the target, since 127.0.0.1 and localhost was blacklisted and 127.0.0.x can be used as the loopback address.

So, SSRF is possible. But, since the ftp:// scheme is blocked, we cannot use this to access the ftp service.

I then decided to expand my recon and started sub domain enumeration using gobuster, since we already have a domain name.

And gobuster did find a new subdomain admin.forge.htb.

So, I tried to access the new subdomain, but it showed the following error.

Okay.

Time to see that SSRF in action!

I passed http://admin.forge.htb to the Upload by URL menu, but it showed an error.

So, I used URL encoding to encode the URL and send it again and this time, it worked!

Payload I used

http://%61%64%6d%69%6e%2e%66%6f%72%67%65%2e%68%74%62/

I then curl-ed the generated URL and found the contents of admin.forge.htb.

In the output, I noticed two endpoints. One for announcements and one for uploading files.

Using the technique I just did, I extracted the contents of /announcements. There was a username and password given in the announcements page.

I tried the credentials to login via SSH, but the password login was disabled.

So, I decided to take a step back and think about what to do next.

In the announcements page, I’ve found three interesting things.

  • The creds to the FTP server is user:heightofsecurity123!
  • The /upload endpoint in admin.forge.htb supports ftp
  • To upload files, we can pass the URL of the file via GET variable u.

Assembling all the information we got, the picture is clear. We have to use forge.htb‘s SSRF to access admin.forge.htb. Then, we can use admin.forge.htb‘s Upload by URL feature to retrieve contents from the FTP server.

Anatomy of the attack

Now that we know what attack to do, let’s start the exploitation.

I used the following payload in BurpSuite to login to the FTP server and list the file contents.

http://%2561%2564%256d%2569%256e%252e%2566%256f%2572%2567%2565%252e%2568%2574%2562%2Fupload%3Fu%3Dftp%3a//user:heightofsecurity123!@%2566%256f%2572%2567%2565%252e%2568%2574%2562

This translates to the following.

http://admin.forge.htb/upload?u=ftp://user:heightofsecurity123!@forge.htb/

I got a generated URL and just like we did before, I curl-ed the URL and I got the directory listing!

I could read the user.txt, but there wasn’t anything other than that.

I was stuck.

That’s when I remembered the error SSH showed when I tried to login earlier.

It required a public key to authenticate as user. So, I guessed that FTP is serving the home directory of the user and we need to export the id_rsa key from user‘s home directory to login as user.

I used the following payload to export the id_rsa key from the FTP server.

http://%2561%2564%256d%2569%256e%252e%2566%256f%2572%2567%2565%252e%2568%2574%2562%2Fupload%3Fu%3Dftp%3a//user:heightofsecurity123!@%2566%256f%2572%2567%2565%252e%2568%2574%2562/.ssh/id_rsa

And I got the SSH secret key!

I used the SSH key and I got in as user!

I'm Feeling awesome today. Have a bunch of dance gifs - Album on Imgur

Privilege Escalation

Once I was in as user, I issued sudo -l and found that user can run the python script /opt/remote-manage.py as root.

I inspected the code and found some interesting things.

Contents of remote-manage.py

The script once invoked will start listening on a random port and once we connect to that port, it will ask us for a password and the password is hardcoded as secretadminpassword.

Once we enter the password, the script will prompt a menu and using that menu, we can monitor processes, find free disk space and view listening sockets as root.

But, if the script encounters an exception, then the script will spawn python debugger (PDB).

That means, If we can create an exception to the script, then we can execute python commands as root.

So, I started the script by using the following command.

sudo /usr/bin/python3 /opt/remote-manage.py 
And the script started listening on a random port

I then used netcat to connect to the port and entered the password secretadminpassword.

I then cancelled the netcat, by pressing CTRl+C and it raised an exception in the python script and it entered PDB.

So, I used the following python code to spawn root bash shell.

import pty;pty.spawn("/bin/bash")

And we’re root!

Postlude

And that was Forge!

A great box that used a cool nested SSRF as it’s initial foothold, which I enjoyed a lot!

Kudos to NoobHacker9999 for creating such a fun machine!

Peace out! ✌️

Leave a Comment