Thursday, May 11, 2017

PowerShell Direct (few internals)

Some thoughts about new Windows Server 2016 and Windows 10 Hyper-V feature – PowerShell Direct. This feature is used for sending commands from host OS to guest OS without network communication. You can read about it on
In host OS you can enter
Enter-PSSession -VMName VMName
Invoke-Command -VMName VMName -ScriptBlock { Commands }

And then you can execute commands in guest OS. Before you can run command, you need enter guest OS credentials with local admin privileges.
After you enter it, PowerShell process in host OS send data to guest OS using Hyper-V sockets.
Byte[] domain = Encoding.Unicode.GetBytes(networkCredential.Domain);
Byte[] userName = Encoding.Unicode.GetBytes(networkCredential.UserName);
Byte[] password = Encoding.Unicode.GetBytes(networkCredential.Password);




In guest OS it handles by icsvc.dll (virtual machine integration component services), which runs as a service.
Guest OS administrator can attach WinDBG to this instance of svchost.exe and make command bp sspicli!LogonUserExExW, then g (yes, before it he can enter .logopen and then go to sleep). After host OS administrator enters guest OS credentials, WinDBG stops on sspicli!LogonUserExExW and you can see clear text login and password.
These credentials are needed for starting powershell.exe process (using CreateProcessAsUserW function).
It is not a bug, but, it seems, creates short nuance for enterprise environment - you can’t use PowerShell Direct if guest OS have more than one administrator and that administrator is not Hyper-V admin. He can catch you credentials very easy without needs to brute force it.
So, it not bad scenario attack continuation in VDI and Terminal Services virtual machines environment, where simple user can increase privileges to local admin. You can mitigate risks if you use unique local credentials for every virtual machine. Yes, if you use domain account for PowerShell Direct , don’t forget limit logon machines in account properties.