def enumerate_tokens(sid=None, session_id=None, privs=None): """ Enumerate tokens from any existing processes that can be accessed. Optionally filter by sid. """ for p in psutil.process_iter(): if p.pid == 0: continue try: ph = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, 0, p.pid) except win32api.error as exc: if exc.winerror == 5: log.debug("Unable to OpenProcess pid=%d name=%s", p.pid, p.name()) continue raise exc try: access = (win32security.TOKEN_DUPLICATE | win32security.TOKEN_QUERY | win32security.TOKEN_IMPERSONATE | win32security.TOKEN_ASSIGN_PRIMARY) th = win32security.OpenProcessToken(ph, access) except Exception as exc: # pylint: disable=broad-except log.debug( "OpenProcessToken failed pid=%d name=%s user%s", p.pid, p.name(), p.username(), ) continue try: process_sid = win32security.GetTokenInformation( th, win32security.TokenUser)[0] except Exception as exc: # pylint: disable=broad-except log.exception( "GetTokenInformation pid=%d name=%s user%s", p.pid, p.name(), p.username(), ) continue proc_sid = win32security.ConvertSidToStringSid(process_sid) if sid and sid != proc_sid: log.debug("Token for pid does not match user sid: %s", sid) continue if (session_id and win32security.GetTokenInformation( th, win32security.TokenSessionId) != session_id): continue def has_priv(tok, priv): luid = win32security.LookupPrivilegeValue(None, priv) for priv_luid, flags in win32security.GetTokenInformation( tok, win32security.TokenPrivileges): if priv_luid == luid: return True return False if privs: has_all = True for name in privs: if not has_priv(th, name): has_all = False if not has_all: continue yield dup_token(th)
def get_token_origin(self): if not self.token_origin and self.get_th(): self.token_origin = win32security.GetTokenInformation( self.get_th(), ntsecuritycon.TokenOrigin) return self.token_origin
def dump_token(th): token_type = win32security.GetTokenInformation(th, win32security.TokenType) print('TokenType:', token_type, TOKEN_TYPE.lookup_name(token_type)) if token_type == win32security.TokenImpersonation: imp_lvl = win32security.GetTokenInformation( th, win32security.TokenImpersonationLevel) print('TokenImpersonationLevel:', imp_lvl, SECURITY_IMPERSONATION_LEVEL.lookup_name(imp_lvl)) print('TokenSessionId:', win32security.GetTokenInformation(th, win32security.TokenSessionId)) privs = win32security.GetTokenInformation(th, win32security.TokenPrivileges) print('TokenPrivileges:') for priv_luid, priv_flags in privs: flag_names, unk = TOKEN_PRIVILEGE_ATTRIBUTES.lookup_flags(priv_flags) flag_desc = ' '.join(flag_names) if (unk): flag_desc += '(' + str(unk) + ')' priv_name = win32security.LookupPrivilegeName('', priv_luid) priv_desc = win32security.LookupPrivilegeDisplayName('', priv_name) print('\t', priv_name, priv_desc, priv_flags, flag_desc) print('TokenGroups:') groups = win32security.GetTokenInformation(th, win32security.TokenGroups) for group_sid, group_attr in groups: flag_names, unk = TOKEN_GROUP_ATTRIBUTES.lookup_flags(group_attr) flag_desc = ' '.join(flag_names) if (unk): flag_desc += '(' + str(unk) + ')' if group_attr & TOKEN_GROUP_ATTRIBUTES.SE_GROUP_LOGON_ID: sid_desc = 'Logon sid' else: sid_desc = win32security.LookupAccountSid('', group_sid) print('\t', group_sid, sid_desc, group_attr, flag_desc) ## Vista token information types, will throw (87, 'GetTokenInformation', 'The parameter is incorrect.') on earier OS try: is_elevated = win32security.GetTokenInformation( th, win32security.TokenElevation) print('TokenElevation:', is_elevated) except pywintypes.error as details: if details.winerror != winerror.ERROR_INVALID_PARAMETER: raise return None print( 'TokenHasRestrictions:', win32security.GetTokenInformation(th, win32security.TokenHasRestrictions)) print( 'TokenMandatoryPolicy', win32security.GetTokenInformation(th, win32security.TokenMandatoryPolicy)) print( 'TokenVirtualizationAllowed:', win32security.GetTokenInformation( th, win32security.TokenVirtualizationAllowed)) print( 'TokenVirtualizationEnabled:', win32security.GetTokenInformation( th, win32security.TokenVirtualizationEnabled)) elevation_type = win32security.GetTokenInformation( th, win32security.TokenElevationType) print('TokenElevationType:', elevation_type, TOKEN_ELEVATION_TYPE.lookup_name(elevation_type)) if elevation_type != win32security.TokenElevationTypeDefault: lt = win32security.GetTokenInformation(th, win32security.TokenLinkedToken) print('TokenLinkedToken:', lt) else: lt = None return lt
## Vista token information types, will throw (87, 'GetTokenInformation', 'The parameter is incorrect.') on earier OS try: is_elevated = win32security.GetTokenInformation( th, win32security.TokenElevation) token_info.append(( 'TokenElevation:', is_elevated, )) except pywintypes.error, details: if details.winerror != winerror.ERROR_INVALID_PARAMETER: raise return None token_info.append(( 'TokenHasRestrictions:', win32security.GetTokenInformation(th, win32security.TokenHasRestrictions), )) token_info.append(( 'TokenMandatoryPolicy', win32security.GetTokenInformation(th, win32security.TokenMandatoryPolicy), )) #print 'TokenIntegrityLevel', win32security.GetTokenInformation(th, win32security.TokenIntegrityLevel) token_info.append(( 'TokenVirtualizationAllowed:', win32security.GetTokenInformation( th, win32security.TokenVirtualizationAllowed), )) token_info.append(( 'TokenVirtualizationEnabled:', win32security.GetTokenInformation(
win32security.SE_LOCK_MEMORY_NAME), win32con.SE_PRIVILEGE_ENABLED, ), ) all_info = (win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION | win32security.SACL_SECURITY_INFORMATION) pid = win32api.GetCurrentProcessId() ph = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, 0, pid) ## PROCESS_ALL_ACCESS does not contain ACCESS_SYSTEM_SECURITY (neccessy to do SACLs) th = win32security.OpenProcessToken( ph, win32security.TOKEN_ALL_ACCESS) ##win32con.TOKEN_ADJUST_PRIVILEGES) old_privs = win32security.GetTokenInformation(th, win32security.TokenPrivileges) desired_privs = tuple((e[0], win32con.SE_PRIVILEGE_ENABLED) for e in old_privs) modified_privs = win32security.AdjustTokenPrivileges( th, 0, desired_privs ) # Will (partially) fail for new_privs (unless they are a subset of current ones) gle = win32api.GetLastError() if gle != 0: print("AdjustTokenPrivileges error:", gle) # print(modified_privs) my_sid = win32security.GetTokenInformation(th, win32security.TokenUser)[0] pwr_sid = win32security.LookupAccountName("", "Power Users")[0] ## reopen process with ACCESS_SYSTEM_SECURITY now that sufficent privs are enabled ph = win32api.OpenProcess( win32con.PROCESS_ALL_ACCESS | win32con.ACCESS_SYSTEM_SECURITY, 0, pid) sd = win32security.GetKernelObjectSecurity(ph, all_info)
def test_token_default(self): assert _tokens.token().Statistics['AuthenticationId'] == win32security.GetTokenInformation(self.token0, win32security.TokenStatistics)['AuthenticationId'] assert _tokens.token().Origin == win32security.GetTokenInformation(self.token0, win32security.TokenOrigin)
win32security.LookupPrivilegeValue("", win32security.SE_LOCK_MEMORY_NAME), win32con.SE_PRIVILEGE_ENABLED, ), ) all_info = (win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION | win32security.SACL_SECURITY_INFORMATION) ph = win32process.GetCurrentProcess() th = win32security.OpenProcessToken( ph, win32security.TOKEN_ALL_ACCESS) ##win32con.TOKEN_ADJUST_PRIVILEGES) win32security.AdjustTokenPrivileges(th, 0, new_privs) my_sid = win32security.GetTokenInformation(th, win32security.TokenUser)[0] pwr_sid = win32security.LookupAccountName("", "Power Users")[0] sd = win32security.GetNamedSecurityInfo(fname, win32security.SE_FILE_OBJECT, all_info) dacl = sd.GetSecurityDescriptorDacl() if dacl is None: dacl = win32security.ACL() sacl = sd.GetSecurityDescriptorSacl() if sacl is None: sacl = win32security.ACL() dacl_ace_cnt = dacl.GetAceCount() sacl_ace_cnt = sacl.GetAceCount() dacl.AddAccessAllowedAce(dacl.GetAclRevision(),
from ntsecuritycon import * import win32api, win32security, winerror # This is a Python implementation of win32api.GetDomainName() def GetDomainName(): try: tok = win32security.OpenThreadToken(win32api.GetCurrentThread(), TOKEN_QUERY, 1) except win32api.error, details: if details[0] != winerror.ERROR_NO_TOKEN: raise # attempt to open the process token, since no thread token # exists tok = win32security.OpenProcessToken(win32api.GetCurrentProcess(), TOKEN_QUERY) sid, attr = win32security.GetTokenInformation(tok, TokenUser) win32api.CloseHandle(tok) name, dom, typ = win32security.LookupAccountSid(None, sid) return dom if __name__=='__main__': print "Domain name is", GetDomainName()
flag_desc += '(' + str(unk) + ')' if group_attr & TOKEN_GROUP_ATTRIBUTES.SE_GROUP_LOGON_ID: sid_desc = 'Logon sid' else: sid_desc=win32security.LookupAccountSid('',group_sid) print '\t',group_sid, sid_desc, group_attr, flag_desc ## Vista token information types, will throw (87, 'GetTokenInformation', 'The parameter is incorrect.') on earier OS try: is_elevated=win32security.GetTokenInformation(th, win32security.TokenElevation) print 'TokenElevation:', is_elevated except pywintypes.error, details: if details.winerror != winerror.ERROR_INVALID_PARAMETER: raise return None print 'TokenHasRestrictions:', win32security.GetTokenInformation(th, win32security.TokenHasRestrictions) print 'TokenMandatoryPolicy', win32security.GetTokenInformation(th, win32security.TokenMandatoryPolicy) print 'TokenVirtualizationAllowed:', win32security.GetTokenInformation(th, win32security.TokenVirtualizationAllowed) print 'TokenVirtualizationEnabled:', win32security.GetTokenInformation(th, win32security.TokenVirtualizationEnabled) elevation_type = win32security.GetTokenInformation(th, win32security.TokenElevationType) print 'TokenElevationType:', elevation_type, TOKEN_ELEVATION_TYPE.lookup_name(elevation_type) if elevation_type!=win32security.TokenElevationTypeDefault: lt=win32security.GetTokenInformation(th, win32security.TokenLinkedToken) print 'TokenLinkedToken:', lt else: lt=None return lt ph = win32api.GetCurrentProcess()
def run_as_system(command): # pylint: disable=too-many-locals currentProcess = win32api.OpenProcess(win32con.MAXIMUM_ALLOWED, False, os.getpid()) currentProcessToken = win32security.OpenProcessToken(currentProcess, win32con.MAXIMUM_ALLOWED) duplicatedCurrentProcessToken = win32security.DuplicateTokenEx( ExistingToken=currentProcessToken, DesiredAccess=win32con.MAXIMUM_ALLOWED, ImpersonationLevel=win32security.SecurityImpersonation, TokenType=ntsecuritycon.TokenImpersonation, TokenAttributes=None ) _id = win32security.LookupPrivilegeValue(None, win32security.SE_DEBUG_NAME) newprivs = [(_id, win32security.SE_PRIVILEGE_ENABLED)] win32security.AdjustTokenPrivileges(duplicatedCurrentProcessToken, False, newprivs) win32security.SetThreadToken(win32api.GetCurrentThread(), duplicatedCurrentProcessToken) currentProcessToken = win32security.OpenThreadToken(win32api.GetCurrentThread(), win32con.MAXIMUM_ALLOWED, False) sessionId = win32security.GetTokenInformation(currentProcessToken, ntsecuritycon.TokenSessionId) pid = None for proc in psutil.process_iter(): try: if proc.name() == "lsass.exe": pid = proc.pid break except psutil.AccessDenied: pass if not pid: raise RuntimeError("Failed to get pid of lsass.exe") lsassProcess = win32api.OpenProcess(win32con.MAXIMUM_ALLOWED, False, pid) lsassProcessToken = win32security.OpenProcessToken( lsassProcess, win32con.MAXIMUM_ALLOWED ) systemToken = win32security.DuplicateTokenEx( ExistingToken=lsassProcessToken, DesiredAccess=win32con.MAXIMUM_ALLOWED, ImpersonationLevel=win32security.SecurityImpersonation, TokenType=ntsecuritycon.TokenImpersonation, TokenAttributes=None ) privs = win32security.GetTokenInformation(systemToken, ntsecuritycon.TokenPrivileges) newprivs = [] # enable all privileges for privtuple in privs: newprivs.append((privtuple[0], win32security.SE_PRIVILEGE_ENABLED)) privs = tuple(newprivs) win32security.AdjustTokenPrivileges(systemToken, False, newprivs) win32security.SetThreadToken(win32api.GetCurrentThread(), systemToken) hToken = win32security.DuplicateTokenEx( ExistingToken=lsassProcessToken, DesiredAccess=win32con.MAXIMUM_ALLOWED, ImpersonationLevel=win32security.SecurityImpersonation, TokenType=ntsecuritycon.TokenPrimary, TokenAttributes=None ) win32security.SetTokenInformation(hToken, ntsecuritycon.TokenSessionId, sessionId) privs = win32security.GetTokenInformation(hToken, ntsecuritycon.TokenPrivileges) newprivs = [] # enable all privileges for privtuple in privs: newprivs.append((privtuple[0], win32security.SE_PRIVILEGE_ENABLED)) privs = tuple(newprivs) win32security.AdjustTokenPrivileges(hToken, False, newprivs) si = win32process.STARTUPINFO() dwCreationFlags = win32con.CREATE_NEW_CONSOLE win32process.CreateProcessAsUser(hToken, None, command, None, None, 1, dwCreationFlags, None, None, si)
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)
def get_integrity_level(): currentProcess = win32api.OpenProcess(win32con.MAXIMUM_ALLOWED, False, os.getpid()) currentProcessToken = win32security.OpenProcessToken(currentProcess, win32con.MAXIMUM_ALLOWED) sid, _unused = win32security.GetTokenInformation(currentProcessToken, ntsecuritycon.TokenIntegrityLevel) return win32security.ConvertSidToStringSid(sid)
def remote_authorize(self, data): err, sec_buffer = self.mServer.authorize(data) if err == 0: # Get the handle for the authenticated user such that we can pass it # to win32security.DuplicateTokenEx() and get back a handle that # allows us to spawn interactive processes as the authenticated user. self.mServer.ctxt.ImpersonateSecurityContext() flags = win32security.TOKEN_DUPLICATE | win32security.TOKEN_QUERY handle = win32security.OpenThreadToken(win32api.GetCurrentThread(), flags, False) self.mServer.ctxt.RevertSecurityContext() # Using handle, reate a primary handle suitable for passing to # CreateProcessAsUser(). sec_attr = None # sec_attr = pywintypes.SECURITY_ATTRIBUTES() # sec_attr.Initialize() # sec_attr.bInheritHandle = True # Try different impersonation levels for DuplicateTokenEx(). These # should be in order of decreasing utility (most useful to least). # See the SECURITY_IMPERSONATION_LEVEL documentation for more # details. levels = [win32security.SecurityDelegation, win32security.SecurityImpersonation] primary_handle = None #access = win32security.TOKEN_ALL_ACCESS #access = win32con.MAXIMUM_ALLOWED access = win32security.TOKEN_IMPERSONATE | \ win32security.TOKEN_QUERY | \ win32security.TOKEN_ASSIGN_PRIMARY | \ win32security.TOKEN_DUPLICATE for l in levels: try: primary_handle = \ win32security.DuplicateTokenEx( ExistingToken = handle, DesiredAccess = access, ImpersonationLevel = l, TokenType = ntsecuritycon.TokenPrimary, TokenAttributes = sec_attr ) break except Exception, ex: self.mLogger.error("Failed to create primary token with impersonation level %s:" % str(l)) self.mLogger.error(str(ex)) # If the above failed to create a primary token, then we throw an # exception. It is important that we do not return None from this # method. if primary_handle is None: msg = 'Failed to create primary token for user!' self.mLogger.error(msg) raise failure.Failure(error.UnauthorizedLogin(msg)) # acct_info[0] has the SID for the user. acct_info = win32security.GetTokenInformation(primary_handle, win32security.TokenUser) user_sid = acct_info[0] # This returns a tuple containing the user name, the domain (if # applicable), and the accouunt type. # NOTE: The returned strings may be Unicode strings. user_info = win32security.LookupAccountSid(None, user_sid) # Close the handle returned by win32security.OpenThreadToken() since # it is a duplicate. handle.Close() # NOTE: We are forcing the addition of user_sid to the window station # and desktop ACLs. This seems to be the only way for the user # authenticated through SSPI to be able to open interactive windows. return self.prepareAvatar(avatar.WindowsAvatar(primary_handle, user_sid, str(user_info[0]), str(user_info[1]), True))
wmi_obj = wmi.WMI(privileges=["Security"]) #creating the process watcher process_watcher = wmi_obj.Win32_Process.watch_for("creation") #creating a loop that keeps printing details for each process launched while True: new_process = process_watcher() print "The Process name is:", new_process.Caption print "The CommandLine:", new_process.CommandLine print "The Executable path:", new_process.ExecutablePath print "The Date of creation:", new_process.CreationDate print "Thread count:", new_process.ThreadCount print "Process Owner:", new_process.GetOwner() print "The ProcessID:", new_process.ProcessID print "The Parent PID:", new_process.ParentProcessID #assigning required variables for the privileges process = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION, False, new_process.ProcessID) token = win32security.OpenProcessToken(process, win32con.TOKEN_QUERY) privileges = win32security.GetTokenInformation( token, win32security.TokenPrivileges) for TokenPrivileges in privileges: if TokenPrivileges[1] == 3: win32security.LookupPrivilegeName(None, TokenPrivileges[0]) print TokenPrivileges
def _change_privilege_state(privilege_name, enable): ''' Change the state, either enable or disable, of the named privilege for this process. If the change fails, an exception will be raised. If successful, it returns True. ''' log.debug( '{0} the privilege {1} for this process.'.format( 'Enabling' if enable else 'Disabling', privilege_name ) ) # this is a pseudo-handle that doesn't need to be closed hProc = win32api.GetCurrentProcess() hToken = None try: hToken = win32security.OpenProcessToken( hProc, win32security.TOKEN_QUERY | win32security.TOKEN_ADJUST_PRIVILEGES ) privilege = win32security.LookupPrivilegeValue(None, privilege_name) if enable: privilege_attrs = win32security.SE_PRIVILEGE_ENABLED else: # a value of 0 disables a privilege (there's no constant for it) privilege_attrs = 0 # check that the handle has the requested privilege token_privileges = dict(win32security.GetTokenInformation( hToken, win32security.TokenPrivileges)) if privilege not in token_privileges: if enable: raise SaltInvocationError( 'The requested privilege {0} is not available for this ' 'process (check Salt user privileges).'.format(privilege_name)) else: # disable a privilege this process does not have log.debug( 'Cannot disable privilege {0} because this process ' 'does not have that privilege.'.format(privilege_name) ) return True else: # check if the privilege is already in the requested state if token_privileges[privilege] == privilege_attrs: log.debug( 'The requested privilege {0} is already in the ' 'requested state.'.format(privilege_name) ) return True changes = win32security.AdjustTokenPrivileges( hToken, False, [(privilege, privilege_attrs)] ) finally: if hToken: win32api.CloseHandle(hToken) if not bool(changes): raise SaltInvocationError( 'Could not {0} the {1} privilege for this process'.format( 'enable' if enable else 'remove', privilege_name ) ) else: return True
def is_elevated(): import win32security import win32api hToken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), win32security.TOKEN_QUERY) return win32security.GetTokenInformation(hToken, win32security.TokenElevation) != 0
def test(): # check if running on Windows NT, if not, display notice and terminate if win32api.GetVersion() & 0x80000000: print("This sample only runs on NT") return import sys, getopt opts, args = getopt.getopt(sys.argv[1:], "rwh?c:t:v") computer = None do_read = do_write = 1 logType = "Application" verbose = 0 if len(args) > 0: print("Invalid args") usage() return 1 for opt, val in opts: if opt == '-t': logType = val if opt == '-c': computer = val if opt in ['-h', '-?']: usage() return if opt == '-r': do_read = 0 if opt == '-w': do_write = 0 if opt == '-v': verbose = verbose + 1 if do_write: ph = win32api.GetCurrentProcess() th = win32security.OpenProcessToken(ph, win32con.TOKEN_READ) my_sid = win32security.GetTokenInformation(th, win32security.TokenUser)[0] win32evtlogutil.ReportEvent( logType, 2, strings=["The message text for event 2", "Another insert"], data="Raw\0Data".encode("ascii"), sid=my_sid) win32evtlogutil.ReportEvent( logType, 1, eventType=win32evtlog.EVENTLOG_WARNING_TYPE, strings=["A warning", "An even more dire warning"], data="Raw\0Data".encode("ascii"), sid=my_sid) win32evtlogutil.ReportEvent( logType, 1, eventType=win32evtlog.EVENTLOG_INFORMATION_TYPE, strings=["An info", "Too much info"], data="Raw\0Data".encode("ascii"), sid=my_sid) print("Successfully wrote 3 records to the log") if do_read: ReadLog(computer, logType, verbose > 0)
def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, unused_restore_signals, unused_start_new_session): """Execute program""" assert not pass_fds, "pass_fds not supported on Windows." if not isinstance(args, str): args = list2cmdline(args) # Process startup details if startupinfo is None: startupinfo = win32process.STARTUPINFO() if -1 not in (p2cread, c2pwrite, errwrite): startupinfo.dwFlags |= win32process.STARTF_USESTDHANDLES startupinfo.hStdInput = p2cread startupinfo.hStdOutput = c2pwrite startupinfo.hStdError = errwrite if shell: startupinfo.dwFlags |= win32process.STARTF_USESHOWWINDOW startupinfo.wShowWindow = win32process.SW_HIDE comspec = os.environ.get("COMSPEC", "cmd.exe") args = '{} /c "{}"'.format(comspec, args) if self._token: sid, _ = win32security.GetTokenInformation(self._token, win32security.TokenUser) setup_sacl(sid) # Start the process try: hp, ht, pid, tid = win32process.CreateProcessAsUser( self._token, executable, args, # no special security None, None, int(not close_fds), creationflags, env, os.fspath(cwd) if cwd is not None else None, startupinfo) err = win32api.GetLastError() if err: logger.error( "Error %r when calling CreateProcessAsUser executable %s args %s with the \ token %r ", err, executable, args, self._token) else: win32event.WaitForSingleObject( hp, 1000) # Wait at least one second before checking exit code logger.error( "ExitCode %r when calling CreateProcessAsUser executable %s args %s with the \ token %r ", win32process.GetExitCodeProcess(hp), executable, args, self._token) finally: # Child is launched. Close the parent's copy of those pipe # handles that only the child should have open. You need # to make sure that no handles to the write end of the # output pipe are maintained in this process or else the # pipe will not close when the child process exits and the # ReadFile will hang. if p2cread != -1: p2cread.Close() if c2pwrite != -1: c2pwrite.Close() if errwrite != -1: errwrite.Close() if hasattr(self, '_devnull'): os.close(self._devnull) try: # Retain the process handle, but close the thread handle self._child_created = True # Popen stores the win handle as an int, not as a PyHandle self._handle = Handle(hp.Detach()) self.pid = pid finally: CLOSEHANDLE(ht)
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 WindowsError: # 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 _token_privs(): token = _privileges._get_token() return dict( win32security.GetTokenInformation(token, win32security.TokenPrivileges))
def runas_system(cmd, username, password): # This only works as system, when salt is running as a service for example # Check for a domain domain = '.' if '@' in username: username, domain = username.split('@') if '\\' in username: domain, username = username.split('\\') # Load User and Get Token token = win32security.LogonUser(username, domain, password, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT) # Load the User Profile handle_reg = win32profile.LoadUserProfile(token, {'UserName': username}) try: # Get Unrestricted Token (UAC) if this is an Admin Account elevated_token = win32security.GetTokenInformation( token, win32security.TokenLinkedToken) # Get list of privileges this token contains privileges = win32security.GetTokenInformation( elevated_token, win32security.TokenPrivileges) # Create a set of all privileges to be enabled enable_privs = set() for luid, flags in privileges: enable_privs.add((luid, win32con.SE_PRIVILEGE_ENABLED)) # Enable the privileges win32security.AdjustTokenPrivileges(elevated_token, 0, enable_privs) except win32security.error as exc: # User doesn't have admin, use existing token if exc[0] == winerror.ERROR_NO_SUCH_LOGON_SESSION \ or exc[0] == winerror.ERROR_PRIVILEGE_NOT_HELD: elevated_token = token else: raise # Get Security Attributes security_attributes = win32security.SECURITY_ATTRIBUTES() security_attributes.bInheritHandle = 1 # Create a pipe to set as stdout in the child. The write handle needs to be # inheritable. stdin_read, stdin_write = win32pipe.CreatePipe(security_attributes, 0) stdin_read = make_inheritable(stdin_read) stdout_read, stdout_write = win32pipe.CreatePipe(security_attributes, 0) stdout_write = make_inheritable(stdout_write) stderr_read, stderr_write = win32pipe.CreatePipe(security_attributes, 0) stderr_write = make_inheritable(stderr_write) # Get startup info structure startup_info = win32process.STARTUPINFO() startup_info.dwFlags = win32con.STARTF_USESTDHANDLES startup_info.hStdInput = stdin_read startup_info.hStdOutput = stdout_write startup_info.hStdError = stderr_write # Get User Environment user_environment = win32profile.CreateEnvironmentBlock(token, False) # Build command cmd = 'cmd /c {0}'.format(cmd) # Run command and return process info structure procArgs = (None, cmd, security_attributes, security_attributes, 1, 0, user_environment, None, startup_info) hProcess, hThread, PId, TId = \ win32process.CreateProcessAsUser(elevated_token, *procArgs) if stdin_read is not None: stdin_read.Close() if stdout_write is not None: stdout_write.Close() if stderr_write is not None: stderr_write.Close() hThread.Close() # Initialize ret and set first element ret = {'pid': PId} # Get Standard Out fd_out = msvcrt.open_osfhandle(stdout_read, os.O_RDONLY | os.O_TEXT) with os.fdopen(fd_out, 'r') as f_out: ret['stdout'] = f_out.read() # Get Standard Error fd_err = msvcrt.open_osfhandle(stderr_read, os.O_RDONLY | os.O_TEXT) with os.fdopen(fd_err, 'r') as f_err: ret['stderr'] = f_err.read() # Get Return Code if win32event.WaitForSingleObject(hProcess, win32event.INFINITE) == win32con.WAIT_OBJECT_0: exitcode = win32process.GetExitCodeProcess(hProcess) ret['retcode'] = exitcode # Close handle to process win32api.CloseHandle(hProcess) # Unload the User Profile win32profile.UnloadUserProfile(token, handle_reg) return ret
def take_screenshot(): ret = False ScreenShot.init_globals() if ScreenShot.DISABLE_SSHOT: p("}}ybSkipping screen shot - disabled by .disable_sshot file}}xx", log_level=2) return # Find the logged in user and run the sshot.exe app cmd = os.path.join(util.BINARIES_FOLDER, "sshot\\sshot.exe") p("}}gnTrying to run " + cmd + "}}xx", log_level=4) user_token = UserAccounts.get_active_user_token() if user_token is None: p("}}ynUnable to get user token - screen locked?}}xx", log_level=2) return ret sidObj, intVal = win32security.GetTokenInformation( user_token, win32security.TokenUser) #source = win32security.GetTokenInformation(tokenh, TokenSource) if sidObj: accountName, domainName, accountTypeInt = \ win32security.LookupAccountSid(".", sidObj) else: p("}}rnUnable to get User Token! }}xx", log_level=1) return None #p("}}gnFound User Token: " + str(user_token) + "}}xx", log_level=5) # If user is in the administrators group, skip taking the sshot if UserAccounts.is_in_admin_group(accountName): p("}}mbUser (" + accountName + ") is in admin group, skipping screen shot...}}xx") return True p("}}gnRunning As: " + accountName + "}}xx", log_level=2) # Put this token in the logged in session #win32security.SetTokenInformation(user_token_copy, win32security.TokenSessionId, session_id) # Use win create process function si = win32process.STARTUPINFO() si.dwFlags = win32process.STARTF_USESHOWWINDOW si.wShowWindow = win32con.SW_NORMAL # si.lpDesktop = "WinSta0\Default" si.lpDesktop = "WinSta0\\Default" # Setup envinroment for the user environment = win32profile.CreateEnvironmentBlock(user_token, False) try: ( hProcess, hThread, dwProcessId, dwThreadId ) = win32process.CreateProcessAsUser( user_token, 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 p("Process Started: " + str(dwProcessId), log_level=5) p(hProcess, log_level=5) ret = True except Exception as e: p("}}rnError launching process:}}xx\n" + str(e), log_level=1) # Cleanup user_token.close() # else: # # Not logged in as system user, run as current user # try: # timeout = 10 # 10 seconds? # # Log an error if the process doesn't return 0 # # stdout=PIPE and stderr=STDOUT instead of capture_output=True # p("}}gnRunning as current user " + user_name + "}}xx") # proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,timeout=timeout, check=False) # if (proc.returncode == 0): # p("Command Results: " + cmd + "\n" + proc.stdout.decode()) # ret = True # else: # p("*** Command Failed!: " + cmd + "(" + str(proc.returncode) + ") \n" + proc.stdout.decode()) # except Exception as ex: # p("*** Command Exception! " + cmd + " \n" + \ # str(ex)) if ret is True: p("}}gnSnapped.}}xx", log_level=3) return ret
def token_info(th): token_info = [] token_type = win32security.GetTokenInformation(th, win32security.TokenType) token_info.append( ('TokenType:', token_type, TOKEN_TYPE.lookup_name(token_type))) if token_type == win32security.TokenImpersonation: imp_lvl = win32security.GetTokenInformation( th, win32security.TokenImpersonationLevel) token_info.append(('TokenImpersonationLevel:', imp_lvl, SECURITY_IMPERSONATION_LEVEL.lookup_name(imp_lvl))) token_info.append( token_info.append( ('TokenSessionId:', win32security.GetTokenInformation(th, win32security.TokenSessionId)))) privs = win32security.GetTokenInformation(th, win32security.TokenPrivileges) token_info.append(('TokenPrivileges:', )) for priv_luid, priv_flags in privs: flag_names, unk = TOKEN_PRIVILEGE_ATTRIBUTES.lookup_flags(priv_flags) flag_desc = ' '.join(flag_names) if (unk): flag_desc += '(' + str(unk) + ')' priv_name = win32security.LookupPrivilegeName('', priv_luid) priv_desc = win32security.LookupPrivilegeDisplayName('', priv_name) token_info.append(( '\t', priv_name, priv_desc, priv_flags, flag_desc, )) token_info.append(('TokenGroups:', )) groups = win32security.GetTokenInformation(th, win32security.TokenGroups) for group_sid, group_attr in groups: flag_names, unk = TOKEN_GROUP_ATTRIBUTES.lookup_flags(group_attr) flag_desc = ' '.join(flag_names) if (unk): flag_desc += '(' + str(unk) + ')' if group_attr & TOKEN_GROUP_ATTRIBUTES.SE_GROUP_LOGON_ID: sid_desc = 'Logon sid' else: sid_desc = win32security.LookupAccountSid('', group_sid) token_info.append(( '\t', group_sid, sid_desc, group_attr, flag_desc, )) ## Vista token information types, will throw (87, 'GetTokenInformation', 'The parameter is incorrect.') on earier OS try: is_elevated = win32security.GetTokenInformation( th, win32security.TokenElevation) token_info.append(( 'TokenElevation:', is_elevated, )) except pywintypes.error, details: if details.winerror != winerror.ERROR_INVALID_PARAMETER: raise return None
def isProcessOwnerSID(pid, sid): try: phandle = win32api.OpenProcess( win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, False, pid) except pywintypes.error, err: return False try: hProcessToken = win32security.OpenProcessToken(phandle, win32con.TOKEN_READ) except pywintypes.error, err: win32api.CloseHandle(phandle) return False p_sid = win32security.GetTokenInformation(hProcessToken, win32security.TokenOwner) ret = (p_sid == sid) win32api.CloseHandle(hProcessToken) win32api.CloseHandle(phandle) return ret def existProcess(pid): try: hProcess = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION, False, pid) except pywintypes.error, err: return False