**Update [10/06/2019]: As a result of this post, some of the official Microsoft PowerShell docker images were updated to support NTLM authentication (See here for details)
TL;DR You can PS-Remote from Linux to Windows if you
Occasionally I have found it useful on my pentests to leverage PowerShell remoting as my primary means of maintaining remote code execution on a system. It’s a built-in Windows feature that is incredibly useful when living-off-the-land is a requirement due to client detection capabilities. Unfortunately, remoting from my Kali Linux box to my targets has not been an easy task due to the limited authentication mechanisms supported by the Linux branch of PowerShell Core.
PowerShell remoting requires Kerberos mutual authentication, which means that the client machine and target machine must both be connected to the domain. That can pose an issue for us testers if we don’t already have a compromised domain-connected box to perform the remoting from. Fortunately, we have the option to add ourselves as a “TrustedHost” in the target’s configuration which will permit us to perform NTLM authentication rather than Kerberos and thus removes the need to connect from a system on the domain.
Now the only catch is that PowerShell core for Linux (PowerShell 6.1.0 at the time of writing) does not come with support for NTLM authentication. This isn’t the end of the world, as we could always perform PowerShell remoting from a Windows VM. Luckily some Redditors found a way to get NTLM authentication working with PowerShell on Centos, and thus I incorporated their findings into the simple PowerShell Docker image quickbreach/powershell-ntlm.
This section will go through step-by-step how to establish a remote PowerShell session from a Linux client to a Windows target. It is assumed that you have administrative access over your target PC (RDP, payload, etc.).
Enable PowerShell remoting on the target by running the below command from an elevated PowerShell prompt
Enable-PSRemoting –Force
Get a list of the current TrustedHosts on the target system for reference
Get-Item WSMan:\localhost\Client\TrustedHosts
Next, add yourself as a TrustedHost on the target. This is required in order to use NTLM authentication during the Enter-PSSession setup phase, which is the only authentication mechanism that can be used to connect from Linux to Windows via PowerShell remoting. To accomplish this, run one of the below commands:
Use a wildcard to permit all machines to use NTLM when authenticating to this host
Set-Item WSMan:\localhost\Client\TrustedHosts -Force -Value *
Or be specific and add only your IP to the NTLM authentication permitted list
Set-Item WSMan:\localhost\Client\TrustedHosts -Force -Concatenate -Value 192.168.10.100
Setup and restart the WinRM service to reflect the changes made
Set-Service WinRM -StartMode Automatic
Restart-Service -Force WinRM
Now drop into an instance of the PowerShell-NTLM Docker image. The below sample command also mounts a local directory containing PowerShell scripts on the /mnt path inside of the docker image
docker run -it -v /pathTo/PowerShellModules:/mnt quickbreach/powershell-ntlm
Finally, the moment we’ve been waiting for: Enter into a remote PowerShell session with the below commands - note that you MUST specify the -Authentication type:
# Grab the creds we will be logging in with
$creds = Get-Credential
# Launch the session
# Important: you MUST state the authentication type as Negotiate
Enter-PSSession -ComputerName (Target-IP) -Authentication Negotiate -Credential $creds
# i.e.
Enter-PSSession -ComputerName 10.20.30.190 -Authentication Negotiate -Credential $creds
You can also use the Invoke-Command function in a similar fashion
Invoke-Command -ComputerName 10.20.30.190 -Authentication Negotiate -Credential $creds -ScriptBlock {Get-HotFix}
If there were existing TrustedHosts previous to your command to add yourself, swap out your IP and run the below:
$newvalue = ((Get-ChildItem WSMan:\localhost\Client\TrustedHosts).Value).Replace(",192.168.10.100","")
Set-Item WSMan:\localhost\Client\TrustedHosts -Force -Value $newvalue
Or, you can remove all of the TrustedHosts if you were the only one
Clear-Item WSMan:\localhost\Client\TrustedHosts
Restart the WinRM service to complete your changes (Note that this will disconnect you from Enter-PSSession)
Restart-Service WinRM
This Reddit Thread
PowerShell Remoting Cheatsheet