DC-2 (VulnHub) — black-box penetration test, recon to root
My second VulnHub box, and a completely different lesson from the first. DC-1 fell because its software was ancient. DC-2 had nothing old to exploit — every step was just a weak password or a lazy config, and it only fell because all of them happened to line up. Two things stuck with me. The way in was an SSH server hiding on a strange high port that a normal scan skips straight past. And the “restricted” shell that was supposed to trap the first user let me open a text editor, which is all you need to climb right back out of it. The full engagement report is below; if you only want the highlights, they’re in the executive summary.
Engagement type: Network penetration test (black-box, single host) Tester: Self-study lab (solo) Date: 2026-08-27 Target: 192.168.56.104 (VulnHub DC-2), isolated host-only network 192.168.56.0/24 Attacker host: Kali Linux, same isolated 192.168.56.0/24 segment (DHCP-assigned) Authorization: Self-owned lab VMs on an isolated, internet-less network. No third-party systems in scope.
1. Executive summary
A single web-server host on the internal lab network was assessed with no prior knowledge and no credentials (black-box). The host was fully compromised: starting from nothing but network access, the tester recovered login credentials, used them to obtain a remote shell, and then escalated to complete administrative (root) control of the machine.
Unlike a typical “old software” compromise, no single software vulnerability was exploited here. Every step abused a weak password or a misconfiguration:
- Two accounts used passwords that were ordinary words taken from the website’s own content, making them guessable in seconds once a wordlist was built from the site.
- The remote-access service (SSH) was reachable with those passwords, on a non-standard port that a routine scan would miss.
- One account was fenced into a “restricted shell” that was trivial to escape, so the fence gave a false sense of security while providing none.
- A second account was allowed to run a common developer tool (
git) as the administrator without a password, and that tool can be trivially made to launch an administrator shell.
In business terms: an anonymous attacker on this network could guess their way in and become full administrator of the server and all its data, using only free tools and no exploit code. Each individual weakness looks minor; chained together they produce total compromise.
The root cause is not obsolete software but a systemic failure of credential hygiene and least privilege — weak passwords, an ineffective shell restriction, and an over-broad sudo grant. Remediation is a set of configuration and policy fixes, not a patch cycle.
Overall risk rating: CRITICAL (full administrative compromise was achieved end-to-end).
| Severity | Count |
|---|---|
| Critical | 0 |
| High | 2 |
| Medium | 2 |
| Low | 0 |
No finding is individually Critical, yet the host was fully rooted. That gap is the lesson of this engagement: defence that relies on each weakness being “only High/Medium” fails when the weaknesses chain.
2. Scope & rules of engagement
- In scope: the single host
192.168.56.104on the isolated192.168.56.0/24network. - Out of scope: any other host; the internet (the lab has no route out by design).
- Window: single session, 2026-08-27.
- Methods allowed: full active scanning, credential brute-forcing, and exploitation (owned lab).
- Knowledge level: black-box — the tester began with only an IP range, no credentials and no documentation.
- Constraint honoured: all activity confined to the authorized, isolated lab; no real or third-party systems touched. Root was proven by reading the target’s marker file, not by installing any persistent backdoor. The VM can be restored from snapshot.
3. Methodology
Standard penetration-test lifecycle:
- Reconnaissance / host discovery —
nmap -snto locate the live host (DHCP-assigned). - Scanning & enumeration —
nmap -sV -sCfor services; then a full-rangenmap -p-after the default scan proved incomplete;wpscanto enumerate the web application. - Vulnerability analysis — assessed the WordPress install for a software exploit, then pivoted (as the target’s own hints suggested) to credential attack plus local misconfiguration.
- Credential access — built a target-specific wordlist with
cewland brute-forced WordPress logins withwpscan. - Exploitation / foothold — reused recovered credentials against SSH on the non-standard port.
- Post-exploitation / privilege escalation — escaped a restricted shell, moved laterally to a second local account, and abused a
sudomisconfiguration to reach root. - Reporting — this document.
Tools: nmap, wpscan, cewl, OpenSSH client, vi (restricted-shell escape), su, sudo, GTFOBins (technique reference), standard Linux shell utilities.
4. Findings
Severities use CVSS v3.1 base-metric reasoning. These findings are configuration and credential weaknesses, not catalogued CVEs, so every score is marked assessed — the vector is the tester’s judgement for this specific environment.
F-01 — Privilege escalation to root via misconfigured sudo (git) (HIGH)
- CVSS: 7.8 assessed —
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Affected: user
jerry’ssudopolicy —(root) NOPASSWD: /usr/bin/git. - Description:
jerrymay rungitas root without a password.gitis not a self-contained command: for long output it invokes a pager (less/more), and that pager — becausegitwas launched viasudo— runs with root privileges. Most pagers can execute an arbitrary shell command from within themselves, so the attacker escapes the pager into a root shell. This is a classic “living-off-the-land”sudoabuse (GTFOBinsgit). - Evidence:
sudo -lasjerryreturned(root) NOPASSWD: /usr/bin/git.sudo git -p help configopened the pager as root;!/bin/bashfrom the pager prompt spawned a shell whereidreturneduid=0(root) gid=0(root) groups=0(root)./root/final-flag.txtwas then read (captured in the figure in §5). - Remediation: Remove the
gitentry fromjerry’ssudorules. Grantsudoonly to specific, non-shell-spawning commands under least privilege; neverNOPASSWDon tools that can execute sub-processes (git,vi,find,less,awk,tar, …). Audit/etc/sudoersand/etc/sudoers.d/*against a known-good baseline.
F-02 — Weak, guessable credentials permitting SSH foothold (HIGH)
- CVSS: 7.3 assessed —
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L - Affected: WordPress / system accounts
tomandjerry; SSH service on tcp/7744. - Description: Both accounts used passwords that were plain words present in the website’s own page content (
tom:parturient,jerry:adipiscing). A wordlist generated directly from the site withcewlrecovered them almost immediately — standard wordlists (rockyou) would not have, but the site handed the attacker its own dictionary.tom’s password was additionally valid for SSH, converting a web-app credential into an interactive remote shell. - Evidence:
cewl http://dc-2/ -w cewl.txtbuilt the wordlist;wpscan --url http://dc-2/ -U users.txt -P cewl.txtreturned valid credentials fortomandjerry;ssh tom@192.168.56.104 -p 7744authenticated withparturient. (jerrywas not permitted to log in over SSH — see the narrative.) - Remediation: Enforce a strong-password policy and screen against site-derived and breached wordlists. Prefer SSH key authentication and disable password authentication (
PasswordAuthentication no). Add rate-limiting / lockout (fail2ban) to blunt brute-forcing. Do not reuse web-application passwords for system/SSH accounts.
F-03 — Ineffective restricted shell (rbash trivially escaped) (MEDIUM)
- CVSS: 5.3 assessed —
AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L - Affected:
tom’s login shell —rbash(restricted bash). - Description:
tomis confined torbash, which blockscd, commands containing/,PATHchanges and redirection, exposing only a handful of binaries (ls,less,pwd,vi). The restriction is cosmetic: an allowed program that can spawn a sub-shell defeats it. Fromvi, setting the shell and invoking it drops the user into an unrestricted bash; repairingPATHthen restoressu,sudo, and everything else. The control provides a false sense of containment. - Evidence: as
tom,cat/nano/vim/su/sudo/cdwere blocked whilels/less/pwd/viworked. Escape:vi→:set shell=/bin/bash→:shell, thenexport PATH=/usr/bin:/bin:$PATH— after which arbitrary commands ran normally. - Remediation: Do not rely on
rbashas a security boundary. If a user must be confined, remove shell-spawning binaries from their allowed set, or use a proper mechanism (ForceCommand, a locked-downchroot/jail, or no interactive shell at all). Treat any restricted shell that exposes an editor or pager as already broken.
F-04 — WordPress username enumeration (MEDIUM)
- CVSS: 5.3 assessed —
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N - Affected: WordPress 4.7.10 on Apache httpd 2.4.10 (tcp/80) — author archives / REST author listing.
- Description: The site freely disclosed valid usernames (
admin,jerry,tom) through author enumeration. This is not itself a breach, but it converts the login page from an unknown-username guessing problem into a known-username password-only problem, directly enabling F-02. (One account,tom, did not surface in the same author listing but was still discoverable, showing that partial hardening does not close the gap.) - Evidence:
wpscan --url http://dc-2/ --enumerate u,p,tlisted the users and surfacedxmlrpc.phpandwp-cron.php; the author-archive search independently confirmed a username. - Remediation: Suppress author enumeration (block
?author=redirects and the REST/wp-json/wp/v2/userslisting), avoid using login names as public display names, and consider a security plugin that hides user enumeration and rate-limitsxmlrpc.php.
5. Attack narrative (the chain)
- Discovery —
nmap -sn 192.168.56.0/24located the target at192.168.56.104. - Enumeration (initial) —
nmap -sV -sC 192.168.56.104showed a single open port, tcp/80: Apache httpd 2.4.10 (Debian) serving WordPress 4.7.10. The site redirected to the hostnamedc-2, so192.168.56.104 dc-2was added to/etc/hoststo reach it. - Web enumeration — the site content carried a hint (Flag 1) that a standard wordlist would fail and pointed at
cewl.wpscan --url http://dc-2/ --enumerate u,p,tenumerated the usersadmin,jerry,tom(withtombehaving differently from the other two) and the endpointsxmlrpc.php/wp-cron.php. A second hint (Flag 2) advised abandoning a WordPress exploit — “take a shortcut … another entry point” — steering the engagement toward credentials and a service not yet found. - Credential access —
cewl http://dc-2/ -w cewl.txtscraped a target-specific wordlist from the site’s own words.wpscan --url http://dc-2/ -U users.txt -P cewl.txtrecoveredjerry:adipiscingandtom:parturient. - Finding the real door — the default scan’s “only port 80” was treated with suspicion given Flag 2’s “another entry point.” A full-range scan,
nmap -p- 192.168.56.104, revealed SSH on tcp/7744 (OpenSSH 6.7p1) — hidden on a high, non-standard port that the top-1000 default scan never touched. - Foothold —
ssh tom@192.168.56.104 -p 7744authenticated withparturient.jerry’s credentials did not grant SSH access; onlytomcould log in. - Restricted-shell escape —
tomlanded inrbash:cd,cat,su,sudoand any/-path command were blocked; onlyls,less,pwd,viworked. A home-directory flag (Flag 3) hinted that the path forward was tosutojerry. Using the allowed editor,vi→:set shell=/bin/bash→:shellproduced an unrestricted shell;export PATH=/usr/bin:/bin:$PATHrestored normal command resolution. - Lateral movement —
su jerrywithadipiscingsucceeded.jerry’s home flag (Flag 4) pointed atsudo. - Privilege escalation —
sudo -lshowed(root) NOPASSWD: /usr/bin/git. Per GTFOBins,sudo git -p help configopened the pager as root and!/bin/bashbroke out into a root shell:id→uid=0(root). - Loot — read
/root/final-flag.txt(a congratulatory completion banner), confirming full administrative control.
No software exploit was used at any point. Entry was achieved by guessing site-derived passwords; root was reached by chaining a broken shell restriction, a reused/adjacent account, and an over-broad sudo grant.
6. Conclusion & prioritized remediation
DC-2 fell without a single CVE. It fell to weak credentials and least-privilege failures — the kind of findings a scanner rarely flags and a patch cycle never fixes. Each weakness, taken alone, is a High or Medium; taken together they are a straight line from anonymous network access to root.
Priority order:
- Immediate: remove
gitfromjerry’ssudorules (F-01) — this alone breaks the escalation to root. Force password resets fortom/jerryto strong, non-site-derived values (F-02). - Short term: switch SSH to key-based auth, disable password login, and add
fail2ban(F-02); stop relying onrbashas a boundary and confinetomproperly or not at all (F-03). - Ongoing: suppress WordPress user enumeration and rate-limit
xmlrpc.php(F-04); audit allsudogrants against a least-privilege baseline; adopt a password policy that screens against site-derived and breached wordlists.
Defence-in-depth note: any one control done properly would have broken the chain — a strong password (no foothold), a real shell restriction (no escape), or a scoped sudo grant (no root). The compromise required all of them to be weak at once, which is exactly why layered controls matter: no single lapse should be game-over.
Appendix A — Host service inventory
| Port | Service | Version |
|---|---|---|
| 80/tcp | http | Apache httpd 2.4.10 (Debian) — hosting WordPress 4.7.10 |
| 7744/tcp | ssh | OpenSSH 6.7p1 Debian (protocol 2.0); host keys: RSA, DSA, ECDSA, ED25519 |
Note the non-standard SSH port (7744) — invisible to a default top-1000
nmapscan and only found vianmap -p-.
Appendix B — MITRE ATT&CK mapping
| Step | Tactic | Technique |
|---|---|---|
nmap -sn, -sV -sC, -p- | Reconnaissance / Discovery | T1595 Active Scanning · T1046 Network Service Discovery |
wpscan --enumerate u | Discovery | T1087 Account Discovery · T1589 Gather Victim Identity Information |
cewl + wpscan -P brute force | Credential Access | T1110.001 Password Guessing · T1110 Brute Force |
SSH login as tom on 7744 | Initial Access / Lateral Movement | T1078 Valid Accounts · T1021.004 Remote Services: SSH |
vi → :shell rbash escape | Execution | T1059.004 Command and Scripting Interpreter: Unix Shell |
su jerry | Privilege Escalation | T1078 Valid Accounts |
sudo git → root shell | Privilege Escalation | T1548.003 Abuse Elevation Control Mechanism: Sudo and Sudo Caching |
read /root/final-flag.txt | Collection | T1005 Data from Local System |
