def revert(self): """ Stop using the credentials. The user is left logged in, which can speed up later impersonations with the same credentials. """ if self.handle is not None: win32security.RevertToSelf()
def test_Token_unimpersonate(): hToken = win32security.LogonUser("alice", "", "Passw0rd", win32security.LOGON32_LOGON_NETWORK, win32security.LOGON32_PROVIDER_DEFAULT) win32security.ImpersonateLoggedOnUser(_tokens.Token(hToken).pyobject()) assert _tokens.token().Owner.pyobject() == alice win32security.RevertToSelf() assert _tokens.token().Owner.pyobject() == me
def logoffUser(self): try: win32security.RevertToSelf() self.handel.Close() return True except Exception as error: ExceptionManager.WriteException( str(error), "logoffUser", exceptionFileName) return False
def logout(self): """ Log out of the user's account. If currently impersonating the user, impersonation is also ended. """ if self.handle is not None: win32security.RevertToSelf() self.handle.Close() self.handle = None
def test_Token_impersonate(): alice, system, type = win32security.LookupAccountName(None, "alice") hToken = win32security.LogonUser("alice", "", "Passw0rd", win32security.LOGON32_LOGON_NETWORK, win32security.LOGON32_PROVIDER_DEFAULT) token = _tokens.Token(hToken) try: token.impersonate() assert token.Owner.pyobject() == alice finally: win32security.RevertToSelf()
def test_Token_unimpersonate(self): hToken = win32security.LogonUser( "alice", "", "Passw0rd", win32security.LOGON32_LOGON_NETWORK, win32security.LOGON32_PROVIDER_DEFAULT ) me = _tokens.token().Owner.pyobject() win32security.ImpersonateLoggedOnUser(_tokens.Token(hToken).pyobject()) self.assertEquals(_tokens.token().Owner.pyobject(), self.alice) win32security.RevertToSelf() self.assertEquals(_tokens.token().Owner.pyobject(), me)
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 getBackgroundImageFile(self, avatar): ''' Determines the absolute path to the current desktop wallpaper image file. The path will be a local path that may not be valid for the client, but it will be valid for the purposes of reading the image file in the service so that the data can be sent to the client. @param avatar The avatar representing the remote user (the client). @return A string naming the full path to the local file that is used for the desktop wallpaper image is returned. ''' # This returns an empty string if no desktop background image is # currently set. win32security.ImpersonateLoggedOnUser(avatar.mUserHandle) file = win32gui.SystemParametersInfo(win32con.SPI_GETDESKWALLPAPER) win32security.RevertToSelf() return file
def setSaverEnabled(self, avatar, enabled): win32security.ImpersonateLoggedOnUser(avatar.mUserHandle) update = win32con.SPIF_UPDATEINIFILE | win32con.SPIF_SENDCHANGE win32gui.SystemParametersInfo(win32con.SPI_SETSCREENSAVEACTIVE, enabled, update) # If we are re-enabling the use of the screen saver, then we have to # take an extra step to make sure that the screen saver can actually # kick back in after the desired timeout period. if enabled: # Simulator user input to reinitialize the timeout period. For more # information on why this is necessary, see the Microsoft knowledge # base entry Q140723: # # http://support.microsoft.com/kb/140723/EN-US/ win32api.SetCursorPos(win32api.GetCursorPos()) #(x, y) = win32api.GetCursorPos() #win32api.SetCursorPos((x + 1, y + 1)) win32security.RevertToSelf()
def printStatus(): ''' Impersonates a user (as determined by the global variables USERNAME, DOMAIN, and PASSWORD) and lists the contents of TEST_DIR. For this to be a useful test, TEST_DIR should be a directory that is only readablye by DOMAIN\USERNAME. ''' handle = win32security.LogonUser(USERNAME, DOMAIN, PASSWORD, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT) win32security.ImpersonateLoggedOnUser(handle) logging.basicConfig( level=logging.DEBUG, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', datefmt='%m-%d %H:%M', filename=LOG_FILE, filemode='w') logging.debug(win32api.GetUserName()) for d in dircache.listdir(TEST_DIR): logging.debug(d) win32security.RevertToSelf() handle.Close()
def _safeCreateProcess(avatar, appName, cmd, processSA, threadSA, inheritHandles, creationFlags, env, cwd, si): new_env = {} if env is not None: for key, value in env.iteritems(): new_env[unicode(key)] = unicode(value) env = new_env log.debug( """\ _SaferCreateProcess(appName=%r, cmd=%r, env=%r, cwd=%r) os.getcwd(): %r """, appName, cmd, env, cwd, os.getcwd()) si.lpDesktop = r"winsta0\default" params = (appName, cmd, processSA, threadSA, inheritHandles, creationFlags, env, cwd, si) # If we have been given an avatar with credentials, create the # process as the identified user. if avatar is not None and avatar.mUserHandle is not None: # Run the command ase the authenticated user. user = avatar.mUserHandle win32security.ImpersonateLoggedOnUser(user) process, thread, process_id, thread_id\ = win32process.CreateProcessAsUser(user, *params) win32security.RevertToSelf() else: process, thread, process_id, thread_id\ = win32process.CreateProcess(*params) return process, thread, process_id, thread_id
def __del__(self): win32security.RevertToSelf() self.m_handle.Close()
def __init__(self, cmd, login=None, hStdin=None, hStdout=None, hStderr=None, show=1, xy=None, xySize=None, desktop=None): """ Create a Windows process. cmd: command to run login: run as user 'Domain\nUser\nPassword' hStdin, hStdout, hStderr: handles for process I/O; default is caller's stdin, stdout & stderr show: wShowWindow (0=SW_HIDE, 1=SW_NORMAL, ...) xy: window offset (x, y) of upper left corner in pixels xySize: window size (width, height) in pixels desktop: lpDesktop - name of desktop e.g. 'winsta0\\default' None = inherit current desktop '' = create new desktop if necessary User calling login requires additional privileges: Act as part of the operating system [not needed on Windows XP] Increase quotas Replace a process level token Login string must EITHER be an administrator's account (ordinary user can't access current desktop - see Microsoft Q165194) OR use desktop='' to run another desktop invisibly (may be very slow to startup & finalize). """ si = win32process.STARTUPINFO() si.dwFlags = (win32con.STARTF_USESTDHANDLES ^ win32con.STARTF_USESHOWWINDOW) if hStdin is None: si.hStdInput = win32api.GetStdHandle(win32api.STD_INPUT_HANDLE) else: si.hStdInput = hStdin if hStdout is None: si.hStdOutput = win32api.GetStdHandle(win32api.STD_OUTPUT_HANDLE) else: si.hStdOutput = hStdout if hStderr is None: si.hStdError = win32api.GetStdHandle(win32api.STD_ERROR_HANDLE) else: si.hStdError = hStderr si.wShowWindow = show if xy is not None: si.dwX, si.dwY = xy si.dwFlags ^= win32con.STARTF_USEPOSITION if xySize is not None: si.dwXSize, si.dwYSize = xySize si.dwFlags ^= win32con.STARTF_USESIZE if desktop is not None: si.lpDesktop = desktop procArgs = ( None, # appName cmd, # commandLine None, # processAttributes None, # threadAttributes 1, # bInheritHandles win32process.CREATE_NEW_CONSOLE, # dwCreationFlags None, # newEnvironment None, # currentDirectory si) # startupinfo if login is not None: hUser = logonUser(login) win32security.ImpersonateLoggedOnUser(hUser) procHandles = win32process.CreateProcessAsUser(hUser, *procArgs) win32security.RevertToSelf() else: procHandles = win32process.CreateProcess(*procArgs) self.hProcess, self.hThread, self.PId, self.TId = procHandles
def runas(cmdLine, username, password=None, cwd=None): """ Run a command as another user. If the process is running as an admin or system account this method does not require a password. Other non privileged accounts need to provide a password for the user to runas. Commands are run in with the highest level privileges possible for the account provided. """ # Validate the domain and sid exist for the username username, domain = split_username(username) try: _, domain, _ = win32security.LookupAccountName(domain, username) except pywintypes.error as exc: message = win32api.FormatMessage(exc.winerror).rstrip("\n") raise CommandExecutionError(message) # Elevate the token from the current process access = win32security.TOKEN_QUERY | win32security.TOKEN_ADJUST_PRIVILEGES th = win32security.OpenProcessToken(win32api.GetCurrentProcess(), access) salt.platform.win.elevate_token(th) # Try to impersonate the SYSTEM user. This process needs to be running as a # user who as been granted the SeImpersonatePrivilege, Administrator # accounts have this permission by default. try: impersonation_token = salt.platform.win.impersonate_sid( salt.platform.win.SYSTEM_SID, session_id=0, privs=["SeTcbPrivilege"], ) except OSError: # pylint: disable=undefined-variable log.debug("Unable to impersonate SYSTEM user") impersonation_token = None win32api.CloseHandle(th) # Impersonation of the SYSTEM user failed. Fallback to an un-privileged # runas. if not impersonation_token: log.debug("No impersonation token, using unprivileged runas") return runas_unpriv(cmdLine, username, password, cwd) if domain == "NT AUTHORITY": # Logon as a system level account, SYSTEM, LOCAL SERVICE, or NETWORK # SERVICE. user_token = win32security.LogonUser( username, domain, "", win32con.LOGON32_LOGON_SERVICE, win32con.LOGON32_PROVIDER_DEFAULT, ) elif password: # Login with a password. user_token = win32security.LogonUser( username, domain, password, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT, ) else: # Login without a password. This always returns an elevated token. user_token = salt.platform.win.logon_msv1_s4u(username).Token # Get a linked user token to elevate if needed elevation_type = win32security.GetTokenInformation( user_token, win32security.TokenElevationType) if elevation_type > 1: user_token = win32security.GetTokenInformation( user_token, win32security.TokenLinkedToken) # Elevate the user token salt.platform.win.elevate_token(user_token) # Make sure the user's token has access to a windows station and desktop salt.platform.win.grant_winsta_and_desktop(user_token) # Create pipes for standard in, out and error streams security_attributes = win32security.SECURITY_ATTRIBUTES() security_attributes.bInheritHandle = 1 stdin_read, stdin_write = win32pipe.CreatePipe(security_attributes, 0) stdin_read = salt.platform.win.make_inheritable(stdin_read) stdout_read, stdout_write = win32pipe.CreatePipe(security_attributes, 0) stdout_write = salt.platform.win.make_inheritable(stdout_write) stderr_read, stderr_write = win32pipe.CreatePipe(security_attributes, 0) stderr_write = salt.platform.win.make_inheritable(stderr_write) # Run the process without showing a window. creationflags = (win32process.CREATE_NO_WINDOW | win32process.CREATE_NEW_CONSOLE | win32process.CREATE_SUSPENDED) startup_info = salt.platform.win.STARTUPINFO( dwFlags=win32con.STARTF_USESTDHANDLES, hStdInput=stdin_read.handle, hStdOutput=stdout_write.handle, hStdError=stderr_write.handle, ) # Create the environment for the user env = create_env(user_token, False) hProcess = None try: # Start the process in a suspended state. process_info = salt.platform.win.CreateProcessWithTokenW( int(user_token), logonflags=1, applicationname=None, commandline=cmdLine, currentdirectory=cwd, creationflags=creationflags, startupinfo=startup_info, environment=env, ) hProcess = process_info.hProcess hThread = process_info.hThread dwProcessId = process_info.dwProcessId dwThreadId = process_info.dwThreadId # We don't use these so let's close the handle salt.platform.win.kernel32.CloseHandle(stdin_write.handle) salt.platform.win.kernel32.CloseHandle(stdout_write.handle) salt.platform.win.kernel32.CloseHandle(stderr_write.handle) ret = {"pid": dwProcessId} # Resume the process psutil.Process(dwProcessId).resume() # Wait for the process to exit and get its return code. if (win32event.WaitForSingleObject( hProcess, win32event.INFINITE) == win32con.WAIT_OBJECT_0): exitcode = win32process.GetExitCodeProcess(hProcess) ret["retcode"] = exitcode # Read standard out fd_out = msvcrt.open_osfhandle(stdout_read.handle, os.O_RDONLY | os.O_TEXT) with os.fdopen(fd_out, "r") as f_out: stdout = f_out.read() ret["stdout"] = stdout # Read standard error fd_err = msvcrt.open_osfhandle(stderr_read.handle, os.O_RDONLY | os.O_TEXT) with os.fdopen(fd_err, "r") as f_err: stderr = f_err.read() ret["stderr"] = stderr finally: if hProcess is not None: salt.platform.win.kernel32.CloseHandle(hProcess) win32api.CloseHandle(th) win32api.CloseHandle(user_token) if impersonation_token: win32security.RevertToSelf() win32api.CloseHandle(impersonation_token) return ret
def terminate_impersonation(self, username): """Terminate the impersonation of another user.""" win32security.RevertToSelf()
def revert(self): if self.as_user != '@': winsec.RevertToSelf() # terminates impersonation self.handle.Close() # guarantees cleanup
def logoff(self): win32security.RevertToSelf() # Terminates impersonation self.handle.Close() # Guarantees cleanup
def terminate_impersonation(self, username): """undo user from impersonation """ win32security.RevertToSelf()
def _getBackgroundImageData(self, avatar): bytes = '' file_name = self._getBackgroundFileName(avatar) if file_name != '': if sys.platform.startswith('win'): import win32security win32security.ImpersonateLoggedOnUser(avatar.mUserHandle) try: file_obj = open(file_name, 'r+b') bytes = file_obj.read() file_obj.close() except Exception, ex: self.mLogger.debug("Failed to read '%s': %s" % \ (file_name, str(ex))) win32security.RevertToSelf() # On non-Windows platforms, we have to jump through some extra # hoops to increase the likelihood of being able to read the # background image file. That is, we have to fork off a child # process and then read the file contents as the authenticated # user. else: import select child_pipe_rd, child_pipe_wr = os.pipe() pid = os.fork() if pid == 0: os.close(child_pipe_rd) maestro.util.changeToUserName(avatar.mUserName) exit_status = 0 try: file_obj = open(file_name, 'r+b') bytes = file_obj.read() file_obj.close() os.write(child_pipe_wr, bytes) except Exception, ex: self.mLogger.debug("Failed to read '%s': %s" % \ (file_name, str(ex))) exit_status = -1 os._exit(exit_status) os.close(child_pipe_wr) read, write, ex = select.select([child_pipe_rd], [], []) if child_pipe_rd in read: done = False while not done: try: cur_data = os.read(child_pipe_rd, 8192) read, write, ex = select.select([child_pipe_rd], [], [], 0.1) if cur_data == '': done = True else: bytes = bytes + cur_data if child_pipe_rd not in read: done = True except IOError, ex: if ex.errno == errno.EINTR: continue else: raise except OSError, ex: if ex.errno == errno.EINTR: continue else: raise
def logoff(self): if (self.is_impersonating) : win32security.RevertToSelf() #terminates impersonation self.handle.Close() #guarantees cleanup
def __exit__(self, *args) -> None: try: win32security.RevertToSelf() self.handle.Close() except AttributeError: pass
def terminate_impersonation(self): win32security.RevertToSelf()
for p in processes().get_all(): for t in p.get_tokens(): x = t.get_token_user().get_fq_name().encode("utf8") if t.get_token_user().get_fq_name().encode( "utf8") in sid_done.keys(): pass else: sid_done[t.get_token_user().get_fq_name().encode("utf8")] = 1 section("Dumping Credentials from Credential Manager for: %s" % t.get_token_user().get_fq_name()) win32security.ImpersonateLoggedOnUser(t.get_th()) creds = get_credman_creds() if creds: for package in creds: dump_cred(package) win32security.RevertToSelf() # lsadump if options.do_all or options.do_lsasecrets: section("Dumping LSA Secrets") secrets = get_live_secrets() if not secrets: print "[E] Unable to read LSA secrets. Perhaps you are not SYTEM?" sys.exit(1) for k in sorted(secrets.keys()): print k print dump(secrets[k], length=16) # shell with privileges of another process if options.pid:
def close(self): if not self.on: return win32security.RevertToSelf() # terminates impersonation self.handle.Close() # guarantees cleanup
def terminate_impersonation(self, username): """undo user from impersonation """ if self.file_access_user: win32security.RevertToSelf()
def runCommandAsOtherUser(): ''' Runs a command (C:\Python24\python.exe C:\read_files.py) as another user (as determined by the global variables USERNAME, DOMAIN, and PASSWORD). The python.exe process will be owned by USERNAME and have access to that user's files. Hence, for this test to be useful, the value in LOG_FILE should be a file to which only DOMAIN\USERNAME has write access, and TEST_DIR should be a directory from which only DOMAIN\USERNAME can read. ''' logging.basicConfig( level=logging.DEBUG, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', datefmt='%m-%d %H:%M', filename=r'C:\temp\myapp2.log', filemode='w') logging.debug("Starting") try: cur_winsta = win32service.GetProcessWindowStation() logging.debug("Got process window station") new_winsta = win32service.OpenWindowStation( "winsta0", False, win32con.READ_CONTROL | win32con.WRITE_DAC) new_winsta.SetProcessWindowStation() desktop = win32service.OpenDesktop( "default", 0, False, win32con.READ_CONTROL | win32con.WRITE_DAC | win32con.DESKTOP_WRITEOBJECTS | win32con.DESKTOP_READOBJECTS) handle = win32security.LogonUser(USERNAME, DOMAIN, PASSWORD, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT) tic = win32security.GetTokenInformation(handle, ntsecuritycon.TokenGroups) user_sid = None for sid, flags in tic: if flags & win32con.SE_GROUP_LOGON_ID: user_sid = sid break if user_sid is None: raise Exception('Failed to determine logon ID') winsta_ace_indices = addUserToWindowStation(new_winsta, user_sid) desktop_ace_indices = addUserToDesktop(desktop, user_sid) si = win32process.STARTUPINFO() # Copied from process.py. I don't know what these should be in general. si.dwFlags = win32process.STARTF_USESHOWWINDOW ^ win32con.STARTF_USESTDHANDLES si.wShowWindow = win32con.SW_NORMAL si.lpDesktop = r"winsta0\default" create_flags = win32process.CREATE_NEW_CONSOLE win32security.ImpersonateLoggedOnUser(handle) # Hard-coded paths are bad except that this is just a proof-of-concept # service. # This command validates that the process has the access rights of the # logged on (impersonated) user. # logging.debug('LOG_FILE = ' + LOG_FILE) # logging.debug('TEST_DIR = ' + TEST_DIR) # (process, thread, proc_id, thread_id) = \ # win32process.CreateProcessAsUser(handle, None, # r"C:\Python24\python.exe C:\read_files.py %s %s" % (LOG_FILE, TEST_DIR), # None, None, 1, create_flags, None, # None, si) # This command validates that the process is allowed to open a window # on the current desktop. (process, thread, proc_id, thread_id) = \ win32process.CreateProcessAsUser(handle, None, r"C:\windows\system32\calc.exe", None, None, 1, create_flags, None, None, si) cur_winsta.SetProcessWindowStation() win32security.RevertToSelf() handle.Close() logging.debug("Waiting for completion") win32event.WaitForSingleObject(process, win32event.INFINITE) logging.debug("Done!") logging.debug("Removing added ACEs from new_winsta") removeACEs(new_winsta, winsta_ace_indices) logging.debug("Removing added ACEs from desktop") removeACEs(desktop, desktop_ace_indices) new_winsta.CloseWindowStation() desktop.CloseDesktop() except TypeError, ex: logging.debug(ex)