首先,很难找到一个复杂的标题,因为整个情况复杂而令人困惑。
我正在尝试以具有受限权限的用户创建进程(用户是“用户”组的一部分)。该过程应该在另一个桌面上生成(我们将其命名为“test”),而不是"default"
- 桌面上。使用CreateProcessWithLogonW
功能的进程正在使用管理员权限运行。虽然普通应用程序(记事本,vlc,winrar)运行没有问题,但IE,Firefox,Chrome等浏览器应用程序似乎有问题。它们已经启动,但它们在没有错误代码的情况下立即关闭。如果我使用具有管理权限的用户,则每个应用程序都会运行而不会出现错误。
我正在为winstation和桌面的DACL添加ACE。此外,如果我像这样开始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)
奇怪的是,如果我切换到“测试”-desktop并使用ShellRunas
(shift +右键单击 - >以不同的用户身份运行),它可以完美运行。因此,我似乎缺少授予我的用户一些权利,但我不知道哪些权利。
所以这是我的问题:
CreateProccesWithLogonW
?CreateProccesWithLogonW
和Shellrunas
之间的区别是什么?Shellrunas
如何在幕后工作?