This page looks best with JavaScript enabled

Hack The Box :: ForwardSlash

 ·  ☕ 8 min read  ·  🧔🏻 noobintheshell

ForwardSlash is a Hard Linux box created by InfoSecJack and chivato. It was released on April 4th, 2020 and retired on July 4th, 2020. The users rated the difficulty 6.3/10 and gave an appreciation score of 3.8/5.

ForwardSlash Info Card
ForwardSlash Info Card


We access a website defaced by a hacker group. Checking for VHOSTs, we find a backup website with a login page. We can register and log in. The vulnerable feature has been poorly disabled as we can still call it to access a developer page that is protected by IP filtering. The feature is vulnerable to LFI and we can retrieve the pages source code with a PHP wrapper. The user chiv password is hardcoded in one of them. Once connected through SSH, we find multiples notes left by chiv that lead us to a backup config file that should contain the old database credentials. We exploit a SUID binary backup (owned by pain) to read that config file and retrieve pain password and therefore, the user flag. In pain home folder we find an encrypted file and the script used to encrypt it. We retrieve the encryption key with a dictionary attack. It message leaks the password of a LUKS image. pain is a sudoer and can run the commands to decrypt the image and mount it as root. The image contains root SSH private key that we use to get the root flag.

Reconnaissance & Enumeration

Open Ports

An NMAP scan shows the following (partial) output:

$ sudo nmap -sS -sV -p-

22/tcp  open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))

We discover the usual SSH server and HTTP ports opened.

Web discovery

Browsing the IP address redirects to http://forwardslash.htb. We add the domain to the /etc/hosts file. We then access a website defaced by a hacker group called The Backslash Gang:

website landing page
website landing page

They give some hints on the vulnerabilities they exploited:

This was ridiculous, who even uses XML and Automatic FTP Logins

A file/folder discovery does not show much. We continue with a VHOST scan:

gobuster vhost -u http://forwardslash.htb/ -w ../../wordlists/big.txt | grep -E "Status: (2|3)"
gobuster vhost -u http://forwardslash.htb/ -w ../../wordlists/big.txt | grep -E "Status: (2|3)"

We discover backup.forwardslash.htb that we add as well to the hosts file. The backup page shows a login page:

backup landing page
backup landing page

We can sign up to access a dashboard:


There is a nice Quick Message from Chivato:

quick message
quick message

The Change Your Profile Picture feature shows a disabled input:


The vulnerability should be there and we can easily modify the HTTP code to enable the input and the button.

A new file/folder discovery shows:

$ gobuster dir -u http://backup.forwardslash.htb -w ../../wordlists/big.txt -x php
/api.php (Status: 200)
/config.php (Status: 200)
/dev (Status: 301)
/environment.php (Status: 302)
/index.php (Status: 302)
/login.php (Status: 200)
/logout.php (Status: 302)
/register.php (Status: 200)
/welcome.php (Status: 302)

The /dev folder shows the following message:

403 Access Denied
Access Denied From

It is probably only accessible from the localhost. We tried some well-known HTTP headers to bypass this kind of filter, but no success.

Gaining Access

We can easily edit the input and the button HTML code to remove the disabled attribute and then try to call /dev/index.php that will bypass the filter. This will include the /dev/index.php page:

include /dev/index.php
include /dev/index.php

We access an XML API Test feature which is probably what the hacker group was referring to in its message. Let’s see what else we can do through this Local File Inclusion (LFI) vulnerability. We can read local system files:

$ curl http://backup.forwardslash.htb/profilepicture.php -H “Cookie: PHPSESSID=2jlmsmrq9r8vabqs1s1j1qqq0p” -d “url=/etc/passwd
mysql:x:111:113:MySQL Server,,,:/nonexistent:/bin/false

And we can even read a page source code with PHP wrappers as follows:

$ curl http://backup.forwardslash.htb/profilepicture.php -H “Cookie: PHPSESSID=2jlmsmrq9r8vabqs1s1j1qqq0p” -d “url=php://filter/convert.base64-encode/resource=dev/index.php

We get the source code encoded in base64. Once decoded, we can read the user chiv FTP password:

/dev/index.php snippet — credentials leak + XXE
/dev/index.php snippet — credentials leak + XXE

On top of that, we see as well that XML External Entities (XXE) can be processed, which is another vulnerability that can be used to read local files or, in certain cases (not here), get Remote Code Execution (RCE).

If we have a look at the test done to filter access to /dev, we see that the IP filtering can be bypassed if we use the admin account:

/dev/index.php snippet — IP filtering
/dev/index.php snippet — IP filtering

Strangely, the admin account does not exist. We can create it and access the/dev/index.php page without bypass. From there, we can exploit the XXE to read files as well with this payload:

<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM “file:///etc/passwd” >]>

The FTP code leads to an RFI that we can use to trig XSS. We can query a remote FTP server for a file called debug.txt. If we start an FTP server on our box, configure the chiv user/password and serve a debug.txt file containing some Javascript code, we can then execute it with:

The " is important here to pass the regex filter.

Anyway…the FTP credentials are re-used for the system user. We can log in through SSH.

Local Reconnaissance & Enumeration

Now that we have a shell as chiv we can explore the box. The user flag is in pain home directory. We can read some more files in there. First, a note.txt from chiv that contains:

Pain, even though they got into our server, I made sure to encrypt any important files and then did some crypto magic on the key… I gave you the key in person the other day, so unless these hackers are some crypto experts we should be good to go.


Then there is a encryptorinator folder that contains an encrypted file ciphertext as well as the Python script used to encrypt it:

chiv mentions that he encrypted some ‘important’ files. By looking around we find another message in the backup config file /var/www/backup.forwardslash.htb/config.php:

//credentials for the temp db while we recover, had to backup old config, didn't want it getting compromised -pain

The backup config file is found in /var/backup/config.php.bak and can only be read by pain. We find another note.txt along with it:

Chiv, this is the backup of the old config, the one with the password we need to actually keep safe. Please DO NOT TOUCH.


By checking for SUID binaries, we find /usr/bin/backup owned by pain. This looks like the way to pivot. We can execute it:


This is a backup viewer so we can probably read the config.php.bak file with it. It seems to check for a file that does not exist and that seems to be an MD5 hash. The filename changes each time we launch the tool. Actually, it changes every second.

We find yet another note.txt that we missed during the enumeration phase at the root of http://forwardslash.htb:

Pain, we were hacked by some skids that call themselves the “Backslash Gang”… I know… That name…
Anyway I am just leaving this note here to say that we still have that backup site so we should be fine.


Privilege Escalation

User pivoting

We can copy the backup binary locally with scp and open it with Ghidra. The main function is quite self-explanatory:

main function snippet
main function snippet

The filename is the MD5 hash of the local time with format HH:MM:SS. That’s why it changes each second. What we can do here is to create a symlink to /var/backup/config.php.bak with the name being the MD5 hash of the current time. We need to do that in less than a second. The following one-liner is all we need:

$ ln -s /var/backups/config.php.bak $(export t=$(date +%H:%M:%S);echo -n $t | md5sum | awk '{ print $1 }') && backup

And we get pain password (it is not a hash) that he re-used as well for his system account:

pain credentials leak
pain credentials leak

We log in through SSH and get the user flag.

Root escalation

Once logged in with pain, we see that he can run some commands as root:

sudo -l
sudo -l

LUKS is a disk encryption tool, so the first guess is that there is an encrypted drive/image somewhere that we can decrypt and mount. To do that we would need a password that we don’t have yet.

We found previously an encrypted file with the script used to encrypt it. Let’s analyze the script:

Quite a basic encryption. We can easily re-use the decrypt function to perform a dictionary attack:

We output the decryption string once we find the word the. The output is:

decrypted message
decrypted message

We have the location of the encrypted image and the password to decrypt it. With that, we execute the following commands to decrypt and mount the image encrypted_backup.img (pain is member of the group backupoperator so he can read the image):

$ cd /var/backups/recovery
$ mkdir mnt
$ sudo /sbin/cryptsetup luksOpen encrypted_backup.img backup
Enter passphrase for encrypted_backup.img: cB!6%sdH8Lj^@Y*$C2cf
$ sudo /bin/mount /dev/mapper/backup ./mnt/
$ cd mnt

The image contains root SSH private key id_rsa. We retrieve it, log in through SSH and get the root flag!


This was quite a straightforward box, more on the Medium difficulty I would say. No insane enumeration to do so I completed it quite easily :) Except for the LUKS part, the concepts seen can be found in many other boxes.


[1] XML External Entity (XXE) Processing

[2] LUKS`

Share on

AppSec Engineer and CTFer