- Install Ansible on Windows - Thu, Jul 20 2023
- Use Azure Bastion as a jump host for RDP and SSH - Tue, Apr 18 2023
- Azure Virtual Desktop: Getting started - Fri, Apr 14 2023
Our lab scenario
Consider the following scenario: We need to run some PowerShell on the Windows Server 2012 R2 member server named mem2 from our local server named dc1. Because mem2 resides on a high-security subnet, we can’t access mem2 directly.
We’ll use adfs1 as a “jump box” because adfs1 is allowed to communicate with mem2. To start, we’ll open a remoting session from dc1 to adfs1 by using our current domain administrator credentials:
PS C:\>Enter-PSSession –ComputerName adfs1 [adfs1]: PS C:\>
Next, we’ll use Invoke-Command to initiate WS-Man PowerShell remoting and hit mem2:
[adfs1]: PS C:\>Invoke-Command –ComputerName mem2 –ScriptBlock { Get-WindowsFeature | Where-Object {$_.InstallState –eq ‘Installed’} }
Yikes! As you can see in the following screenshot, I received a heap of fatal errors.
Connecting to remote server mem2 failed with the following error message : WinRM cannot process the request. The following error with errorcode 0x800903e occurred while using Kerberos authentication . . .
This is the dreaded Kerberos “second hop” problem.
The behavior we see here is actually by design and is referred to as the Kerberos “second hop” problem. In our example, the remoting session from dc1 to adfs1 passes on my domain administrator credentials, and any remoting stuff I do on adfs1 occurs within that security context.
However, when we “reach out” from adfs1 to mem2, Kerberos assumes that it isn’t allowed to impersonate my identity for the second hop. One way to solve this problem permanently is to configure Kerberos constrained delegation in Active Directory.
Another alternative is to use the Credential Security Service Provider (CredSSP) protocol. The long story short is that CredSSP allows us to delegate user credentials manually across the network. Obviously, this is a security-sensitive operation and should be implemented judiciously.
Windows PowerShell includes only three CredSSP commands:
Get-Command -Name *credssp* | Select-Object -Property Name, Source Name Source ---- ------ Disable-WSManCredSSP Microsoft.WSMan.Management Enable-WSManCredSSP Microsoft.WSMan.Management Get-WSManCredSSP Microsoft.WSMan.Management
Let’s set up CredSSP delegation and test it out, shall we?
Enabling CredSSP
Take another look at the image I gave you at the beginning of this article. To pass my administrator credentials through adfs1 to mem2, we’ll temporarily configure dc1, my local server, as a CredSSP client, and adfs1 as a CredSSP server. We don’t have to touch the target box, mem2.
First, I’ll run Enable-WSManCredSSP on dc1:
Enable-WSManCredSSP –Role Client –DelegateComputer adfs1.company.pri -Force
Some administrators like to swing the heavy hammer by enabling delegation globally (–DelegateComputer *.company.pri), but I feel that’s a bit too permissive.
Please note that we specify the CredSSP server in our –DelegateComputer parameter, not the local box. You can verify your configuration by running Get-WSManCredSSP:
Get-WSManCredSSP The machine is configured to allow delegating fresh credentials to the following target(s): wsman/adfs1.company.pri This computer is not configured to receive credentials from a remote client computer.
Second, let’s configure adfs1 as the CredSSP server:
Enable-WSManCredSSP –Role Server -Force
You should also run Get-WSManCredSSP afterward to verify the configuration.
Okay, then. Let’s get this party started! The “secret sauce” to the delegated remoting session is specifying CredSSP as our authentication provider:
Enter-PSSession –ComputerName adfs1.company.pri –Credential company\administrator –Authentication CredSSP
“The proof is in the pudding,” my old mentor Bernie Carr used to say. Let’s see if we can complete the second-hop to mem2:
We solved the Kerberos second hop problem!
To quote Hannibal from The A-Team, “I love it when a plan comes together!”
Sweeping up the shavings
Go ahead and close your local PowerShell session. Then open a fresh one using the same credentials. I wonder if the CredSSP client settings persisted?
If you run Get-WSManCredSSP on your local and remote servers, you’ll see that we did, in fact, make a permanent change. For security’s sake, let’s reset the CredSSP environment to the way it was originally:
Disable-WSManCredSSP –Role Client Invoke-Command –ComputerName adfs1 –ScriptBlock { Disable-WSManCredSSP –Role Server }
Hi Timothy,
Thanks for the detailed explanation. I’m curios if this will also work:
(dc1 and adfs1 have different admin credentials)
1) I need to run enter-pssession from dc1 to adfs1 with -credential adfs1\administrator (or run powershell as adfs1\administrator)
2) now in pssession I need to run cmdlet to modify something on mem2 with mem2\administrator
Is is possible to pass the mem2 credentials from within the pssession?
I cannot run poweshell as mem2\administrator from dc1.
Thanks in advance
Hello Timothy,
old post but I recently used it. I had to add the wsman/hostname to Computer settings in gpedit.msc
Computer Configuration -> Administrative Templates -> System -> Credentials Delegation -> Allow Fresh Credentials with NTLM-only Server Authentication
Otherwise I got error message that the computer is not trusted.
Cheers
L