The Powershell Double Hop
This post details overcoming the infamous double hop problem that exists in powershell. Once you have established a powershell remoting session on one computer, you are mostly limited to activity on that computer. From that session, you cannot create additional sessions and if you try to access a resource outside that computer, you may run into an Access Denied error message.
Suppose you are able to get a PS session on a jump server accessible from an external network and are trying to access an internal resource. You might receive error messages like these if you try to create nested sessions or try to access a third resource:
This example isn’t working because PowerShell is not passing the credentials we authenticated with to the remote resource. This isn’t a bug but a security feature.
You can solve this problem with credssp but that requires additional configuration which you might not be able to do. Remember, posts in this blog are written from an adversarial perspective.
The Solution
This double hop problem can be solved without credssp; the only catch is that you need to have cleartext credentials. A pass the hash attack using a NTLM hash will not work. This method allows you to tie a credential to a PowerShell session configuration and reuse this configuration for all future connections.
Method 1
Register the credentials first:
$cred = Get-Credential usfun\pastudent47
Then you can use nested Invoke-Command to access the third resource with the registered credentials.
Invoke-Command -ComputerName ufc-jumpsrv -Credential $cred -ScriptBlock {
Invoke-Command -ComputerName ufc-webprod -Credential $Using:cred -ScriptBlock {whoami}
}
Method 2
Another way to do this is to register a session configuration with the jump server using a domain account and specify that configuration name when connecting to the third resource. This ensures that when we connect using this session configuration, it will always authenticate with this user.
Create the configuration:
Invoke-Command -ComputerName ufc-jumpsrv -ScriptBlock { Register-PSSessionConfiguration -Name Offsecure -RunAsCredential 'usfun\pastudent47' -Force }
Once we have the session configuration created, we can then just specify that session configuration using the ConfigurationName parameter when connecting to the third resource. This will ensure your credentials are passed on and you can then get access, as depicted below.
Invoke-Command -ComputerName 'ufc-jumpsrv' -ScriptBlock { Get-ChildItem -Path \\ufc-webprod\c$ } -ConfigurationName Offsecure