def LockWorkStation(self): try: logging.debug("LockWorkStation was called.") sessionId = GetActiveSessionId() if sessionId != 0xffffffff: logging.debug("Locking workstation (session %d)", sessionId) dupToken = None userToken = win32ts.WTSQueryUserToken(sessionId) if userToken is not None: logging.debug("Got the active user token.") # The following access rights are required for # CreateProcessAsUser. access = win32security.TOKEN_QUERY access |= win32security.TOKEN_DUPLICATE access |= win32security.TOKEN_ASSIGN_PRIMARY dupToken = win32security.DuplicateTokenEx( userToken, win32security.SecurityImpersonation, access, win32security.TokenPrimary, None) userToken.Close() if dupToken is not None: logging.debug("Duplicated the active user token.") lockCmd = os.path.join(os.environ['WINDIR'], "system32\\rundll32.exe") lockCmd += " user32.dll,LockWorkStation" logging.debug("Executing \"%s\".", lockCmd) win32process.CreateProcessAsUser( dupToken, None, lockCmd, None, None, 0, 0, None, None, win32process.STARTUPINFO()) dupToken.Close() else: logging.debug("No active session. Ignoring lock workstation " "command.") except: logging.exception("LockWorkStation exception")
def create_print_process(self): session_id = win32ts.WTSGetActiveConsoleSessionId() user_token = win32ts.WTSQueryUserToken(session_id) startup_info = win32process.STARTUPINFO() cmdline = "E:\\python_project\\happyWorkAutoPrint\\dist\\autoPrint\\autoPrint.exe" win32process.CreateProcessAsUser(user_token, None, cmdline, None, None, False, win32con.NORMAL_PRIORITY_CLASS, None, None, startup_info)
def run_as_cur_user(process, args): session_id = windll.kernel32.WTSGetActiveConsoleSessionId() token = win32ts.WTSQueryUserToken(session_id) win32process.CreateProcessAsUser( token, process, args, None, None, True, win32con.NORMAL_PRIORITY_CLASS, None, None, win32process.STARTUPINFO())
def runScreenShotApp2_old(self): console_id = win32ts.WTSGetActiveConsoleSessionId() if console_id == 0xffffffff: # User not logged in right now? logging.info("No console user") return None dc = None logging.info("Got console: " + str(console_id)) # Get processes running on this console svr = win32ts.WTSOpenServer(".") user_token = win32ts.WTSQueryUserToken(console_id) logging.info("User Token " + str(user_token)) # hwnd = win32gui.GetDC(win32con.HWND_DESKTOP) # win32gui.GetDesktopWindow() # dc = ctypes.windll.user32.GetDC(win32con.HWND_DESKTOP) # logging.info("DC before impersonation " + str(dc)) # win32gui.ReleaseDC(win32con.HWND_DESKTOP, dc) # Switch to the user win32security.ImpersonateLoggedOnUser(user_token) logging.info("Impersonating " + win32api.GetUserName()) app_path = os.path.dirname( os.path.dirname( os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) cmd = os.path.join(app_path, "sshot\\dist\\sshot.exe") logging.info("Running sshot app " + cmd) logging.info(os.system(cmd)) # hwnd = ctypes.windll.user32.GetDC(win32con.HWND_DESKTOP) # logging.info("HWND after impersonation " + str(hwnd)) # ps_list = win32ts.WTSEnumerateProcesses(svr, 1, 0) # for ps in ps_list: # logging.info("PS " + str(ps)) win32ts.WTSCloseServer(svr) # Revert back to normal user win32security.RevertToSelf() user_token.close() return
def RunAsStandardUser(command_line, env, cwd, timeout): """Runs a command as non-elevated logged-on user. Args: command_line: The command line string, including arguments, to run. env: Environment variables for child process, None to inherit. cwd: Working directory for child process, None to inherit from parent. timeout: How long in seconds should wait for child process. Returns: (pid, exit_code, sdtout, stderr) tuple. Raises: ImpersonationError: when impersonation failed. """ logging.info('Running "%s" as the logon user.', command_line) # Adjust current process to be part of the trusted computer base. current_process_token = win32security.OpenProcessToken( win32api.GetCurrentProcess(), win32security.TOKEN_ALL_ACCESS) tcb_privilege_flag = win32security.LookupPrivilegeValue( None, win32security.SE_TCB_NAME) se_enable = win32security.SE_PRIVILEGE_ENABLED win32security.AdjustTokenPrivileges(current_process_token, 0, [(tcb_privilege_flag, se_enable)]) active_session_id = proc_util.GetActiveSessionID() if not active_session_id: raise ImpersonationError('Cannot find active logon session.') try: logon_user_token = win32ts.WTSQueryUserToken(active_session_id) except pywintypes.error as err: if err.winerror == winerror.ERROR_NO_TOKEN: raise ImpersonationError('No user is logged on.') else: raise ImpersonationError('Failed to get user token: %s' % err) return _RunAsOnWindowStationDesktop(command_line, logon_user_token, 'WinSta0', 'default', env, cwd, timeout)
def runas_session_user(cmd, executable=None, creationflags=0, cwd=None, startupinfo=None, return_handles=False): if not creationflags & win32con.DETACHED_PROCESS: creationflags |= win32con.CREATE_NEW_CONSOLE if cwd is None: cwd = os.getcwd() si = win32process.STARTUPINFO() if startupinfo: startupinfo_update(startupinfo, si) with impersonate_system(): htoken_user = win32ts.WTSQueryUserToken(win32ts.WTS_CURRENT_SESSION) hProcess, hThread, dwProcessId, dwThreadId = ( win32process.CreateProcessAsUser(htoken_user, executable, cmd, None, None, False, creationflags, None, cwd, si)) if return_handles: return hProcess, hThread return dwProcessId, dwThreadId
def _create_process_as_active_user(self, process_args, parent=None, hide=True, output=False): WTS_CURRENT_SERVER_HANDLE = 0 sessions = win32ts.WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE) log.debug('{}'.format(sessions)) active_session = None for session in sessions: if session['State'] == utils.WTS_CONNECTSTATE_CLASS.WTSActive: active_session = session break if active_session is None: raise Exception("Could not find an active session") # active_session = win32ts.WTSGetActiveConsoleSessionId() log.debug("Active Session is: {}".format(active_session)) hUser = win32ts.WTSQueryUserToken(active_session['SessionId']) return self._create_process(process_args, user_handle=hUser.handle, parent=parent, hide=hide, output=output)
def __init__ (self, cmd): self.cmd = cmd self.handle = None self.thread_id = None self.pid = None self.tid = None self.returncode = None process = win32api.GetCurrentProcess() token = win32security.OpenProcessToken(process, win32security.TOKEN_ALL_ACCESS) tcb_privilege_flag = win32security.\ LookupPrivilegeValue(None, win32security.SE_TCB_NAME) se_enable = win32security.SE_PRIVILEGE_ENABLED old_privilege_data = win32security.\ AdjustTokenPrivileges(token, 0, [(tcb_privilege_flag, se_enable)]) console_session_id = ctypes.windll.kernel32.WTSGetActiveConsoleSessionId() console_user_token = win32ts.WTSQueryUserToken(console_session_id) startupinfo = win32process.STARTUPINFO() startupinfo.dwFlags = win32process.STARTF_USESHOWWINDOW startupinfo.wShowWindow = win32con.SW_SHOW startupinfo.lpDesktop = 'winsta0\default' process_arguments = (console_user_token, None, self.cmd, None, None, 0, 0,None, None, startupinfo) self.handle, self.thread_id , self.pid, self.tid = win32process.\ CreateProcessAsUser(*process_arguments)
def runScreenShotApp(self): global DISABLE_SSHOT if DISABLE_SSHOT is True: return # Get the session id for the console session_id = win32ts.WTSGetActiveConsoleSessionId() if session_id == 0xffffffff: # User not logged in right now? logging.info("No console user") return None # logging.info("Got Console: " + str(session_id)) # Login to the terminal service to get the user token for the console id svr = win32ts.WTSOpenServer(".") user_token = win32ts.WTSQueryUserToken(session_id) # logging.info("User Token " + str(user_token)) # Copy the token user_token_copy = win32security.DuplicateTokenEx( user_token, win32security.SecurityImpersonation, win32security.TOKEN_ALL_ACCESS, win32security.TokenPrimary) # Put this token in the logged in session win32security.SetTokenInformation(user_token_copy, win32security.TokenSessionId, session_id) # Switch to the user # win32security.ImpersonateLoggedOnUser(user_token) # logging.info("Impersonating " + win32api.GetUserName()) # Run the screen shot app # app_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) # cmd = os.path.join(app_path, "sshot\\dist\\sshot.exe") cmd = os.path.join(ROOT_FOLDER, "ope_laptop_binaries\\sshot\\sshot.exe" ) # "c:\\programdata\\ope\\bin\\sshot.exe" # cmd = "cmd.exe" logging.info("Running sshot app " + cmd) # Use win create process function si = win32process.STARTUPINFO() si.dwFlags = win32process.STARTF_USESHOWWINDOW si.wShowWindow = win32con.SW_NORMAL # si.lpDesktop = "WinSta0\Default" si.lpDesktop = "" # Setup envinroment for the user environment = win32profile.CreateEnvironmentBlock(user_token, False) try: ( hProcess, hThread, dwProcessId, dwThreadId ) = win32process.CreateProcessAsUser( user_token_copy, None, # AppName (really command line, blank if cmd line supplied) "\"" + cmd + "\"", # Command Line (blank if app supplied) None, # Process Attributes None, # Thread Attributes 0, # Inherits Handles win32con. NORMAL_PRIORITY_CLASS, # or win32con.CREATE_NEW_CONSOLE, environment, # Environment os.path.dirname(cmd), # Curr directory si) # Startup info # logging.info("Process Started: " + str(dwProcessId)) # logging.info(hProcess) except Exception as e: logging.info("Error launching process: " + str(e)) # logging.info(os.system(cmd)) # Return us to normal security # win32security.RevertToSelf() # Cleanup win32ts.WTSCloseServer(svr) user_token.close() user_token_copy.close() return
def CreateProc(appname, cmdline=None): global cfg #找到winlogon.exe的进程信息,然后复制它的token,再赋权新的token,用新token创建的新进程,就有前台交互权限了 p = getProcess(caption='winlogon.exe')[0] pid = p['pid'] if cfg['debug']: mylog("pid=%d,type=%s" % (pid, type(pid))) #通过winlogon.exe的pid打开进程,获得它的句柄 handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid) #通过winlogon.exe的句柄,获得它的令牌(经测试,admin权限运行的程序,只能用TOKEN_QUERY方式打开,service方式运行的程序,有全部权限) token_handle = win32security.OpenProcessToken( handle, win32con.TOKEN_ADJUST_PRIVILEGES | win32con.TOKEN_QUERY | win32con.TOKEN_DUPLICATE) if cfg['debug']: print("winlogon.exe's handle=%s,token=%s" % (handle, token_handle)) res = None #通过winlogon.exe的令牌,复制一个新令牌(经测试,admin权限运行的程序,权限不足,service方式运行的程序,有全部权限) dup_th = win32security.DuplicateTokenEx( token_handle, win32security.SecurityImpersonation, win32security.TOKEN_ALL_ACCESS, win32security.TokenPrimary, ) #通过winlogon.exe的pid,获得它的session id(经测试,admin权限运行的程序,没TCB权限,需要service方式运行的程序,有全部权限) curr_session_id = win32ts.ProcessIdToSessionId(pid) if cfg['debug']: print("dup_th=%s" % dup_th) #获得系统默认的程序启动信息(初始化程序所需的,标准输出、桌面选择等信息) startup = win32process.STARTUPINFO() if cfg['debug']: print(startup) #下面的这个win32con.CREATE_NEW_CONSOLE权限必须给,要不后面CreateProcessAsUser时看到执行了,然后程序就没了 priority = win32con.NORMAL_PRIORITY_CLASS | win32con.CREATE_NEW_CONSOLE if cfg['debug']: mylog("in CreateProc(),appname=%s,cmdline=%s" % (appname, cmdline)) (hProcess, hThread, dwProcessId, dwThreadId) = (None, None, None, None) #通过winlogon.exe的session id获得它的console令牌 console_user_token = win32ts.WTSQueryUserToken(curr_session_id) #通过winlogon.exe的console令牌,获得它的环境profile设置信息 environment = win32profile.CreateEnvironmentBlock(console_user_token, False) #给复制出来的token,绑定对应的session id,使之基于和winlogon.exe一样的会话 win32security.SetTokenInformation(dup_th, win32security.TokenSessionId, curr_session_id) #设置调整权限的flag权限 flags = win32con.TOKEN_ADJUST_PRIVILEGES | win32con.TOKEN_QUERY #设置权限1:找到SE_DEBUG_NAME的权限的id,给p1 p1 = win32security.LookupPrivilegeValue(None, win32con.SE_DEBUG_NAME) newPrivileges = [(p1, win32con.SE_PRIVILEGE_ENABLED)] #把复制出来的winlogon.exe的token,增加新权限(也即是SE_DEBUG_NAME权限) win32security.AdjustTokenPrivileges(dup_th, False, newPrivileges) if cfg['debug']: privs = getPrivs(dup_th) mylog("privs=%s" % "\n".join(privs)) #下面准备启动程序需要的重定向的标准输出和标准错误输出的文件句柄,但目前似乎没有重定向成功:( fh_stdout = win32file.CreateFile( os.path.join(app_path, "watchdog.stdout"), win32file.GENERIC_WRITE, win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE, None, win32file.OPEN_ALWAYS, win32file.FILE_FLAG_SEQUENTIAL_SCAN, 0) fh_stderr = win32file.CreateFile( os.path.join(app_path, "watchdog.stderr"), win32file.GENERIC_WRITE, win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE, None, win32file.OPEN_ALWAYS, win32file.FILE_FLAG_SEQUENTIAL_SCAN, 0) startup.hStdOutput = fh_stdout startup.hStdError = fh_stderr #下面开始尝试用复制好的token:dup_th,并也给了足够的权限的token,然后来启动指定程序 try: (hProcess, hThread, dwProcessId, dwThreadId) = win32process.CreateProcessAsUser( dup_th, appname, cmdline, None, None, True, priority, None, None, startup) except Exception as e: mylog("in CreateProc(),return False,ERROR:%s" % str(e)) return False mylog("%s,%s,%s,%s" % (hProcess, hThread, dwProcessId, dwThreadId)) if dwProcessId == None: #创建进程失败 mylog( "Can not get dwProcessId from win32process.CreateProcessAsUser()") return False try: time.sleep(2) mylog("dwProcessId=%s" % dwProcessId) process = psutil.Process(dwProcessId) except Exception as e: mylog("CreateProc(),try to psutil.Process(),ERROR:%s" % str(e)) mylog("process:%s" % process) return_code = None try: return_code = process.wait(10) except Exception as e: mylog("CreateProc(),try to process.wait(),ERROR:%s" % str(e)) mylog("Maybe Child process Running already , but not quit") mylog("CreateProc return code=%s" % str(return_code))
def get_active_user_token(): # Figure out the active user token we need to use to run the app as ret = None # Get the current user name user_name = win32api.GetUserName() if user_name != "SYSTEM": # Running as a logged in user, get the current users token current_process = win32process.GetCurrentProcess() token = win32security.OpenProcessToken(current_process, win32con.MAXIMUM_ALLOWED) # win32con.TOKEN_ADJUST_PRIVILEGES | win32con.TOKEN_QUERY) # ret = token return ret #if user_name == "SYSTEM": # p("}}gnStarted by SYSTEM user (OPEService) - trying to switch user identity}}xx") # Get a list of Terminal Service sessions and see which one is active active_session = UserAccounts.WTS_INVALID_SESSION_ID station_name = "" sessions = win32ts.WTSEnumerateSessions(None, 1, 0) for session in sessions: if session['State'] == UserAccounts.WTSActive: # Found the active session active_session = session['SessionId'] station_name = session["WinStationName"] # If we didn't find one, try this way if active_session == UserAccounts.WTS_INVALID_SESSION_ID: active_session = win32ts.WTSGetActiveConsoleSessionId() if active_session == UserAccounts.WTS_INVALID_SESSION_ID: # User not logged in right now? or lock screen up? p("}}gnNo console user or desktop locked}}xx", log_level=1) return ret # Get the current console session #p("Got Console: " + str(active_session), debug_level=5) # Login to the terminal service to get the user token for the console id so we can impersonate it try: #svr = win32ts.WTSOpenServer(".") #win32ts.WTSCloseServer(svr) user_token = win32ts.WTSQueryUserToken(active_session) # Copy the token so we can modify it user_token_copy = win32security.DuplicateTokenEx( user_token, win32security.SecurityImpersonation, win32security.TOKEN_ALL_ACCESS, win32security.TokenPrimary) ret = user_token_copy user_token.close() except Exception as ex: p("}}rnUnknown Error - trying to get WTS UserToken\n" + str(ex) + "}}xx", debug_level=1) return ret #p("User Token Found " + str(user_token_copy), debug_level=5) return ret