gpt4 book ai didi

python - 在 Python 脚本中以 Windows 上的不同用户身份(非管理员)运行程序

转载 作者:可可西里 更新时间:2023-11-01 11:46:03 27 4
gpt4 key购买 nike

使用以下代码:

class ImpersonateWin32Sec(object):

def __init__(self, domain, username, password):
self.username = username
self.password = password
self.domain = domain
self.handle = None

def __enter__(self):
self.handle = win32security.LogonUser(self.username, self.domain, self.password, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT)
win32security.ImpersonateLoggedOnUser(self.handle)

def __exit__(self, *args):
win32security.RevertToSelf()
self.handle.Close()

with ImpersonateWin32Sec("domain", "altuser", "password"):
prc = subprocess.Popen(cmdLine, cwd = "C:\\Temp", stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, env = env, shell = shell, creationflags = CREATE_NO_WINDOW)
stdOut, stdErr = prc.communicate(timeout = 60)

我正在尝试以不同的用户身份运行程序。它似乎只能部分起作用,因为某些命令会失败。以下 3 个命令显示环境的某些部分仍然适用于原始用户:

os.getlogin() # altuser
getpass.getuser() # origuser --> WRONG!!!
win32api.GetUserName() # altuser

我的代码有什么遗漏/错误?我发现一些信息表明 ImpersonateLoggedOnUser 为用户创建了一个模拟 token ,而不是主 token ?这可能是问题所在吗?如果是,我怎样才能获得主要 token ?非常感谢代码示例。

问候,马丁

最佳答案

我终于找到了如何做到这一点。它相当复杂,我不得不合并几个示例中的代码(其中一些是 C 语言)。以下示例在作为 Network ServiceSystem 用户执行时有效。在用户 session 或 session 0 中执行都没有关系。

代码如下:

import os
import msvcrt
import win32security
import win32con
import win32pipe
import win32process
import win32api
import win32net
import win32file
import win32event
import win32profile
import win32service


GENERIC_ACCESS = win32con.GENERIC_READ | win32con.GENERIC_WRITE | win32con.GENERIC_EXECUTE | win32con.GENERIC_ALL

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)


def runAsDomainUser(domainName, userName, password, cmdLine, maxWait):
# maxWait = Maximum execution time in ms
userGroupSid = win32security.LookupAccountName(domainName, userName)[0]
# Login as domain user and create new session
userToken = win32security.LogonUser(userName, domainName, password,
win32con.LOGON32_LOGON_INTERACTIVE,
win32con.LOGON32_PROVIDER_DEFAULT)
rc = win32api.GetLastError()
if userToken is None or (rc != 0):
return -1, "", "LogonUser failed with RC=%d!" % rc
profileDir = win32profile.GetUserProfileDirectory(userToken)
tokenUser = win32security.GetTokenInformation(userToken, win32security.TokenUser)

# Set access rights to window station
hWinSta = win32service.OpenWindowStation("winsta0", False, win32con.READ_CONTROL | win32con.WRITE_DAC )
# Get security descriptor by winsta0-handle
secDescWinSta = win32security.GetUserObjectSecurity(hWinSta, win32security.OWNER_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32con.GROUP_SECURITY_INFORMATION)
# Get DACL from security descriptor
daclWinSta = secDescWinSta.GetSecurityDescriptorDacl()
if daclWinSta is None:
# Create DACL if not exisiting
daclWinSta = win32security.ACL()
# Add ACEs to DACL for specific user group
daclWinSta.AddAccessAllowedAce(win32security.ACL_REVISION_DS, GENERIC_ACCESS, userGroupSid)
daclWinSta.AddAccessAllowedAce(win32security.ACL_REVISION_DS, WINSTA_ALL, userGroupSid)
# Set modified DACL for winsta0
win32security.SetSecurityInfo(hWinSta, win32security.SE_WINDOW_OBJECT, win32security.DACL_SECURITY_INFORMATION,
None, None, daclWinSta, None)

# Set access rights to desktop
hDesktop = win32service.OpenDesktop("default", 0, False, win32con.READ_CONTROL
| win32con.WRITE_DAC
| win32con.DESKTOP_WRITEOBJECTS
| win32con.DESKTOP_READOBJECTS)
# Get security descriptor by desktop-handle
secDescDesktop = win32security.GetUserObjectSecurity(hDesktop, win32security.OWNER_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32con.GROUP_SECURITY_INFORMATION )
# Get DACL from security descriptor
daclDesktop = secDescDesktop.GetSecurityDescriptorDacl()
if daclDesktop is None:
#create DACL if not exisiting
daclDesktop = win32security.ACL()
# Add ACEs to DACL for specific user group
daclDesktop.AddAccessAllowedAce(win32security.ACL_REVISION_DS, GENERIC_ACCESS, userGroupSid)
daclDesktop.AddAccessAllowedAce(win32security.ACL_REVISION_DS, DESKTOP_ALL, userGroupSid)
# Set modified DACL for desktop
win32security.SetSecurityInfo(hDesktop, win32security.SE_WINDOW_OBJECT, win32security.DACL_SECURITY_INFORMATION,
None, None, daclDesktop, None)

# Setup stdin, stdOut and stderr
secAttrs = win32security.SECURITY_ATTRIBUTES()
secAttrs.bInheritHandle = 1
stdOutRd, stdOutWr = win32pipe.CreatePipe(secAttrs, 0)
stdErrRd, stdErrWr = win32pipe.CreatePipe(secAttrs, 0)

ppid = win32api.GetCurrentProcess()
tmp = win32api.DuplicateHandle(ppid, stdOutRd, ppid, 0, 0, win32con.DUPLICATE_SAME_ACCESS)
win32file.CloseHandle(stdOutRd)
stdOutRd = tmp

environment = win32profile.CreateEnvironmentBlock(userToken, False)

startupInfo = win32process.STARTUPINFO()
startupInfo.dwFlags = win32con.STARTF_USESTDHANDLES
startupInfo.hStdOutput = stdOutWr
startupInfo.hStdError = stdErrWr

hPrc = win32process.CreateProcessAsUser(
userToken,
None, # appName
cmdLine, # commandLine
None, # processAttributes
None, # threadAttributes
1, # bInheritHandles
win32process.CREATE_NEW_CONSOLE, # dwCreationFlags
environment, # newEnvironment
profileDir, # currentDirectory
startupInfo)[0]

win32file.CloseHandle(stdErrWr)
win32file.CloseHandle(stdOutWr)
win32security.RevertToSelf()

# Wait for process to complete
stdOutBuf = os.fdopen(msvcrt.open_osfhandle(stdOutRd, 0), "rb")
stdErrBuf = os.fdopen(msvcrt.open_osfhandle(stdErrRd, 0), "rb")
win32event.WaitForSingleObject(hPrc, maxWait)
stdOut = stdOutBuf.read()
stdErr = stdErrBuf.read()
rc = win32process.GetExitCodeProcess(hPrc)
return rc, str(stdOut, "utf-8"), str(stdErr, "utf-8")


if __name__ == "__main__":
cmdLine = "C:/Windows/System32/cmd.exe"
domainName = input("Domain: ")
userName = input("User: ")
password = input("Password: ")
print(runAsDomainUser(domainName, userName, password, cmdLine, 60000))

关于python - 在 Python 脚本中以 Windows 上的不同用户身份(非管理员)运行程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44675464/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com