PowerShell Remoting for Penetration Testers

Wassup! Lately I've been on a PowerShell kick and much can be said about how useful PowerShell is for penetration testers in general (in both exploitation and utility), but today I want to highlight one specific feature which can be used for lateral movement and file-less persistence during a Windows domain penetration test. That feature is PowerShell Remoting, which is technically enabling the service WindowsRM and communicating with that using WS-Man (which is actually SOAP over HTTP(TCP:5985) and HTTPS(TCP:5986)), while reusing credentials that have access to that machine. This WS-Man communication is all taken care of using native PowerShell features (you need at least PowerShell version 2), similar to the way Deep-Panda used WMI because it was a native Windows feature. The best way to get started is just enable PowerShell Remoting via an Administrator shell on your victim machine, although you may need to bypass PowerShell execution policy.

I find it really helpful to look at security events from all sides of the coin. PowerShell Remoting is used heavily by incident responders and IT, so as a defender it's nice to know the logs PowerShell Remoting is generating (Type 3, Network Logon) and how these logs occur naturally in target environments. It's also pretty cool that you scan for PowerShell Remoting enabled machines by looking for ports 47001, 5985, and 5986.

The best part is a lot of the leg work has already been done for us as penetration testers, as we can invoke any existing PowerShell scripts easily, using PowerShell Remoting as our vector rather than WMI or psexec. There is also some great PowerShell Remoting cheatsheats out there. The following is a demo rich video where Joe not only shows the various uses of PowerShell, but really shows the effectiveness of PowerShell Remoting by running Mimikatz en mass on systems, without touching disk. Further, if you look at the source code of Invoke-Mimikatz you will see that they are using the PowerShell Remoting verb 'Invoke-Command' and native PowerShell 'ComputerName' array to invoke their code block on the remote machines: