Saturday, June 17, 2017

Powershell Direct (few internals). Part 2

According https://docs.microsoft.com/en-us/windows-server/virtualization/hyper-v/manage/manage-windows-virtual-machines-with-powershell-direct Powershell Direct session needs Hyper-V administrator privilege for user, which start that session. Yes, it is true, if you use Enter-PSSession cmdlet, but if you will be use Hyper-V sockets natively you don’t need any privileges for it.











Log on in Hyper-V host as user without special privileges (that user is member local Users group only). Run application, that make CONNECT call to any guest VM which run on that host (you can use ClientExample app, which was described in this blog early - https://github.com/gerhart01/HyperV-sockets).
You need change HV_PARENT_GUID to GUID of guest OS
WSADATA wsaData;
        SOCKADDR_HV clientService;
        CLSID VmID, ServiceID;

        // Initialize GUIDs
        //wchar_t* clsid_str = L"{a42e7cda-d03f-480c-9cc2-a4de20abb878}"; // HV_PARENT_GUID
        wchar_t* clsid_str = L"{6a964317-1d87-4a74-abf9-46a69b048900}";
    CLSIDFromString(clsid_str, &VmID);
clsid_str = L"{999e53d4-3d5c-4c3e-8779-bed06ec056e1}";
CLSIDFromString(clsid_str, &ServiceID); //GUID of Powershell Direct Service

When you run it you get message from guest OS:
It begins of PoSh Direct communication protocol. We can see details in OutOfProcTransportManager.cs and RemoteSessionHyperVSocket.cs files of Powershell source code and icsvc.dll library (guest OS module, which handle communication on start):
     if ( recv(i, (char *)&v23, 520, 0) == 0xFFFFFFFF
       || send(i, "PASS", 4, 0) == 0xFFFFFFFF
       || recv(i, (char *)&v22, 520, 0) == 0xFFFFFFFF
       || send(i, "PASS", 4, 0) == 0xFFFFFFFF
       || recv(i, (char *)&v20, 260, 0) == 0xFFFFFFFF
       || strcmp_0((const char *)&v20, "EMPTYPW")
       && (send(i, "PASS", 4, 0) == 0xFFFFFFFF || recv(i, (char *)&v21, 520, 0) == 0xFFFFFFFF) )

    If we get that part of protocol from powershell source and compile it in standalone module, we can communicate with guest OS and execute command as user which credential we send for LogonUserExExW (icsvc start Powershell process with this credentials).
    Of course, it not vulnerability in Hyper-V sockets mechanism (it was designed as usual TCP sockets which don’t need any special permission for working), but it looks like that it may be described more correctly in Microsoft docs.