CreateProcessWithLogonW,创build进程作为另一个用户在不同的桌面上,与浏览器失败

首先很难find一个复杂的标题,因为整个情况是复杂而混乱的。

我正在尝试创build一个具有受限制权限的用户(用户是“用户”组的一部分)。 这个过程应该在另一个桌面上产生(让我们把它命名为“test”),而不是在"default" -desktop上。 使用CreateProcessWithLogonW函数的过程使用pipe理权限运行。 虽然一个正常的应用程序(记事本,VLC,WINRAR)运行没有问题,像IE浏览器,Firefox,Chrome浏览器应用程序似乎有问题。 开始,但他们即时closures没有错误代码。 如果我正在使用具有pipe理权限的用户,则每个应用程序运行时都不会出错

我正在将ACE添加到winstation和桌面的DACL中。 另外,如果我像这样启动cmd.exe并尝试运行firefox ,则会出现同样的问题。 我使用python 2.7与ctypes和win32api:

 from _ctypes import Array, POINTER, sizeof, byref from ctypes import wintypes, windll, WinError import ctypes from ctypes.wintypes import BYTE, HANDLE, DWORD, BOOL, LPCWSTR, LPWSTR, LPVOID from win32con import CREATE_NEW_CONSOLE, READ_CONTROL, WRITE_DAC, \ GROUP_SECURITY_INFORMATION, DESKTOP_WRITEOBJECTS, DESKTOP_READOBJECTS import win32con from win32security import ACL_REVISION_DS import win32security import win32service WINSTA_ALL = (win32con.WINSTA_ACCESSCLIPBOARD | win32con.WINSTA_ACCESSGLOBALATOMS | \ win32con.WINSTA_CREATEDESKTOP | win32con.WINSTA_ENUMDESKTOPS |\ win32con.WINSTA_ENUMERATE | win32con.WINSTA_EXITWINDOWS |\ win32con.WINSTA_READATTRIBUTES | win32con.WINSTA_READSCREEN |\ win32con.WINSTA_WRITEATTRIBUTES | win32con.DELETE |\ win32con.READ_CONTROL | win32con.WRITE_DAC |\ win32con.WRITE_OWNER) DESKTOP_ALL = (win32con.DESKTOP_CREATEMENU | win32con.DESKTOP_CREATEWINDOW |\ win32con.DESKTOP_ENUMERATE | win32con.DESKTOP_HOOKCONTROL |\ win32con.DESKTOP_JOURNALPLAYBACK | win32con.DESKTOP_JOURNALRECORD |\ win32con.DESKTOP_READOBJECTS | win32con.DESKTOP_SWITCHDESKTOP |\ win32con.DESKTOP_WRITEOBJECTS | win32con.DELETE |\ win32con.READ_CONTROL | win32con.WRITE_DAC |\ win32con.WRITE_OWNER) GENERIC_ACCESS = (win32con.GENERIC_READ | win32con.GENERIC_WRITE |\ win32con.GENERIC_EXECUTE | win32con.GENERIC_ALL) INVALID_HANDLE_VALUE = -1 CREATE_UNICODE_ENVIRONMENT = 0x00000400 CData = Array.__base__ LPBYTE = POINTER(BYTE) class PROCESS_INFORMATION(ctypes.Structure): _fields_ = [ ('hProcess', HANDLE), ('hThread', HANDLE), ('dwProcessId', DWORD), ('dwThreadId', DWORD), ] LPPROCESS_INFORMATION = POINTER(PROCESS_INFORMATION) class STARTUPINFOW(ctypes.Structure): _fields_ = (('cb', wintypes.DWORD), ('lpReserved', wintypes.LPWSTR), ('lpDesktop', wintypes.LPWSTR), ('lpTitle', wintypes.LPWSTR), ('dwX', wintypes.DWORD), ('dwY', wintypes.DWORD), ('dwXSize', wintypes.DWORD), ('dwYSize', wintypes.DWORD), ('dwXCountChars', wintypes.DWORD), ('dwYCountChars', wintypes.DWORD), ('dwFillAttribute', wintypes.DWORD), ('dwFlags', wintypes.DWORD), ('wShowWindow', wintypes.WORD), ('cbReserved2', wintypes.WORD), ('lpReserved2', LPBYTE), ('hStdInput', wintypes.HANDLE), ('hStdOutput', wintypes.HANDLE), ('hStdError', wintypes.HANDLE)) LPSTARTUPINFOW = POINTER(STARTUPINFOW) windll.advapi32.CreateProcessWithLogonW.restype = BOOL windll.advapi32.CreateProcessWithLogonW.argtypes = [ LPCWSTR, # lpUsername LPCWSTR, # lpDomain LPCWSTR, # lpPassword DWORD, # dwLogonFlags LPCWSTR, # lpApplicationName LPWSTR, # lpCommandLine (inout) DWORD, # dwCreationFlags LPVOID, # lpEnvironment (force Unicode) LPCWSTR, # lpCurrentDirectory LPSTARTUPINFOW, # lpStartupInfo LPPROCESS_INFORMATION, # lpProcessInfo (out) ] def CreateProcessWithLogonW( lpUsername=None, lpDomain=None, lpPassword=None, dwLogonFlags=0, lpApplicationName=0, lpCommandLine=None, dwCreationFlags=0, lpEnvironment=None, lpCurrentDirectory=None, startupInfo=None): if (lpCommandLine is not None and not isinstance(lpCommandLine, CData)): lpCommandLine = ctypes.create_unicode_buffer(lpCommandLine) dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT if startupInfo is None: startupInfo = STARTUPINFOW(sizeof(STARTUPINFOW)) processInformation = PROCESS_INFORMATION(INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE) success = windll.advapi32.CreateProcessWithLogonW( lpUsername, lpDomain, lpPassword, dwLogonFlags, lpApplicationName, lpCommandLine, dwCreationFlags, lpEnvironment, lpCurrentDirectory, byref(startupInfo), byref(processInformation)) if not success: raise WinError() return processInformation if __name__ == '__main__': user_group_sid = win32security.LookupAccountName('','Users')[0] # #Adding rights for user group "users" to winsta0 # #getting winsta0 handle hwinsta = win32service.OpenWindowStation("winsta0",False,READ_CONTROL | WRITE_DAC ) #getting security descriptor by winsta0-handle sec_desc_winsta = win32security.GetUserObjectSecurity(hwinsta,win32security.OWNER_SECURITY_INFORMATION |win32security.DACL_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION) #getting DACL from security descriptor dacl_winsta = sec_desc_winsta.GetSecurityDescriptorDacl() if dacl_winsta is None: #create DACL if not exisiting dacl_winsta=win32security.ACL() #Adding ACEs to DACL for specific user group dacl_winsta.AddAccessAllowedAce(ACL_REVISION_DS,GENERIC_ACCESS,user_group_sid) dacl_winsta.AddAccessAllowedAce(ACL_REVISION_DS,WINSTA_ALL,user_group_sid) #setting modified DACL for winsta0 win32security.SetSecurityInfo(hwinsta, win32security.SE_WINDOW_OBJECT,win32security.DACL_SECURITY_INFORMATION,None,None,dacl_winsta,None) # #Adding rights for user group "users" to desktop # #getting handle of different Desktop hdesk = win32service.OpenDesktop("test",0 ,False,READ_CONTROL | WRITE_DAC |DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS) #getting security descriptor by desktop-handle sec_desc_desk = win32security.GetUserObjectSecurity(hdesk,win32security.OWNER_SECURITY_INFORMATION |win32security.DACL_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION ) #getting DACL from security descriptor dacl_desk = sec_desc_desk.GetSecurityDescriptorDacl() if dacl_desk is None: #create DACL if not exisiting dacl_desk=win32security.ACL() #Adding ACEs to DACL for specific user group dacl_desk.AddAccessAllowedAce(ACL_REVISION_DS,GENERIC_ACCESS,user_group_sid) dacl_desk.AddAccessAllowedAce(ACL_REVISION_DS,DESKTOP_ALL,user_group_sid) #setting modified DACL for desktop win32security.SetSecurityInfo(hdesk, win32security.SE_WINDOW_OBJECT,win32security.DACL_SECURITY_INFORMATION,None,None,dacl_desk,None) firefox = "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe" notepad = "C:\\windows\\notepad.exe" si = STARTUPINFOW() si.lpDesktop = "winsta0\\test" pi = CreateProcessWithLogonW("test", ".", "password", 0x00000001, None, firefox, CREATE_NEW_CONSOLE, startupInfo=si) 

奇怪的是,如果我切换到“testing”-desktop并使用ShellRunas(Shift +右键单击 – >以不同的用户身份运行),它可以很好地工作。 所以看起来我错过了授予我的用户一些权利,但我不知道哪些权利。

所以这是我的问题:

  1. 我的目的是否正确使用CreateProccesWithLogonW
  2. CreateProccesWithLogonWShellrunas什么Shellrunas
  3. Shellrunas如何在Shellrunas工作?