def impersonate_user(self, username, password): """Impersonate the security context of another user.""" handler = win32security.LogonUser( username, None, password, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT) win32security.ImpersonateLoggedOnUser(handler) handler.Close()
def open(self): self.handle = win32security.LogonUser( self.user, self.domain, self.password, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT) win32security.ImpersonateLoggedOnUser(self.handle) self.on = True
def setBackground(self, avatar, imgFile, imgData): ''' Changes the desktop wallpaper using the given information. The information comes in the form of a file name and the raw bytes of the wallpaper image. @param avatar The avatar representing the remote user (the client). @param imgFile The path to the new background image. In general, this will be an absolute path, though it might not be a path that is valid on the local file system. @param imgData The raw bytes of the wallpaper image as a single string. This can be written to a local file so that the new wallpaper can then be loaded and used. ''' win32security.ImpersonateLoggedOnUser(avatar.mUserHandle) dir_name = os.path.dirname(imgFile) file_name = os.path.basename(imgFile) while not os.path.exists(dir_name) or not os.path.isdir(dir_name): dir_name = os.path.dirname(dir_name) if dir_name == '': break if os.environ.has_key('HOME'): home_dir = os.environ['HOME'] elif os.environ.has_key('HOMESHARE'): home_dir = os.environ['HOMESHARE'] elif os.environ.has_key('HOMEDRIVE'): home_dir = '%s%s' % (os.environ['HOMEDRIVE'], os.environ['HOMEPATH']) else: home_dir = r'C:\temp' if dir_name == '': dir_name = home_dir # If this is a UNIX-style path, convert it to a DOS-style path just to # be safe. elif dir_name.startswith('/'): dir_name = os.path.abspath(dir_name) img_file = os.path.join(dir_name, file_name) # If dir_name should end up being one to which the authenticated user # does not have write access, this will throw an exception. try: file = open(img_file, "w+b") file.write(imgData) file.close() # If we cannot write the file to dir_name, try again in the user's home # directory--unless dir_name is already set to home_dir. In that case, # we have a big problem. except IOError, ex: if dir_name != home_dir: img_file = os.path.join(home_dir, file_name) file = open(img_file, "w+b") file.write(imgData) file.close() else: raise
def impersonate(self): if self.as_user != '@': cred = self.cred_manager.get_cred(self.as_user) self.handle = winsec.LogonUser(cred.username, cred.domain, cred.password, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT) winsec.ImpersonateLoggedOnUser(self.handle)
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 impersonate_user(self, username, password): """impersonate user when operating file system """ handler = win32security.LogonUser( username, None, password, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT) win32security.ImpersonateLoggedOnUser(handler) handler.Close()
def impersonate_user(self, username, password): if (username == "anonymous") and self.has_user('anonymous'): username = self.anon_user password = self.anon_pwd handler = win32security.LogonUser(username, None, password, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT) win32security.ImpersonateLoggedOnUser(handler) handler.Close()
def logonUser(self): try: self.handel = win32security.LogonUser( self.username, self.domain, self.password, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT) win32security.ImpersonateLoggedOnUser(self.handel) return True except Exception as error: ExceptionManager.WriteException( str(error), "logonUser", exceptionFileName) return False
def updateShares(avatar): # Get name of domain controller. try: dc_name = win32net.NetGetDCName() except: dc_name = None saved_username = avatar.mUserName # Get user sid to lookup registry values. user_sid = win32security.GetTokenInformation(avatar.mUserHandle, ntsecuritycon.TokenUser)[0] user_sid_str = win32security.ConvertSidToStringSid(user_sid) # Act as the user so that we can update session shares. win32security.ImpersonateLoggedOnUser(avatar.mUserHandle) try: # Get username user_name = win32api.GetUserName() if user_name != saved_username: raise Exception("Impersonation failed due to user name mismatch ('%s' is not '%s')" % \ (user_name, saved_username)) gLogger.debug("User: '******'" % user_name) gLogger.debug("Domain Controller: '%s'" % dc_name) gLogger.info("\n=== Disconnect from all network drives ===") # Disconnect from all network drives. drive_list_str = win32api.GetLogicalDriveStrings().rstrip('\x00') drive_list = drive_list_str.split('\x00') for drive in drive_list: if win32file.DRIVE_REMOTE == win32file.GetDriveType(drive): disconnectNetworkDrive(drive) gLogger.info("\n=== Map network drives ===") # Map the user's home directory. user_info = win32net.NetUserGetInfo(dc_name, user_name, 4) try: if user_info['home_dir_drive'] != '' and user_info[ 'home_dir'] != '': mapNetworkDrive(user_info['home_dir_drive'], user_info['home_dir']) except KeyError, ke: gLogger.error(ke) # Map the user's persistent network drives. try: user_reg = maestro.util.registry.RegistryDict( win32con.HKEY_USERS, str(user_sid_str)) for k, v in user_reg['Network'].iteritems(): drive = k + ':' mapNetworkDrive(drive, v['RemotePath']) except KeyError, ke: gLogger.warning("Unknown registry key %s" % str(ke))
def impersonate_sid(sid, session_id=None, privs=None): """ Find an existing process token for the given sid and impersonate the token. """ for tok in enumerate_tokens(sid, session_id, privs): tok = dup_token(tok) elevate_token(tok) if win32security.ImpersonateLoggedOnUser(tok) == 0: raise OSError("Impersonation failure") return tok raise OSError("Impersonation failure")
def impersonate_sid(sid, session_id=None, privs=None): ''' Find an existing process token for the given sid and impersonate the token. ''' for tok in enumerate_tokens(sid, session_id, privs): tok = dup_token(tok) elevate_token(tok) if win32security.ImpersonateLoggedOnUser(tok) == 0: raise WindowsError("Impersonation failure") # pylint: disable=undefined-variable return tok raise WindowsError("Impersonation failure") # pylint: disable=undefined-variable
def __enter__(self) -> None: try: self.handle = win32security.LogonUser( self.username, self.domain, self.password, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT, ) win32security.ImpersonateLoggedOnUser(self.handle) except pywintypes.error as exc: raise OSError(exc)
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 impersonate(username, password, domain): if username: print "Using alternative credentials:" print "Username: "******"Password: "******"Domain: " + str(domain) handle = win32security.LogonUser( username, domain, password, win32security.LOGON32_LOGON_NEW_CREDENTIALS, win32security.LOGON32_PROVIDER_WINNT50) win32security.ImpersonateLoggedOnUser(handle) else: print "[i] Running as current user. No logon creds supplied (-u, -D, -p)." print
def __init__(self, login, password, domain): # LOGON32_LOGON_NETWORK # win32con.LOGON32_LOGON_INTERACTIVE DEBUG("Impersonate login=%s domain=%s", login, domain) self.m_handle = win32security.LogonUser( login, domain, password, win32con.LOGON32_LOGON_NETWORK, win32con.LOGON32_PROVIDER_DEFAULT) DEBUG("After win32security.LogonUser handle=%s ", str(self.m_handle)) try: win32security.ImpersonateLoggedOnUser(self.m_handle) except Exception: WARNING( "win32security.ImpersonateLoggedOnUser: handle=%s Caught %s", str(self.m_handle), str(sys.exc_info())) DEBUG("Username=%s", win32api.GetUserName())
def __init__(self, login, password, domain): # LOGON32_LOGON_NETWORK # win32con.LOGON32_LOGON_INTERACTIVE logging.debug("Impersonate login=%s domain=%s", login, domain) self.m_handle = win32security.LogonUser( login, domain, password, win32con.LOGON32_LOGON_NETWORK, win32con.LOGON32_PROVIDER_DEFAULT) logging.debug("After win32security.LogonUser handle=%s ", str(self.m_handle)) try: win32security.ImpersonateLoggedOnUser(self.m_handle) except Exception as exc: logging.warning( "win32security.ImpersonateLoggedOnUser: handle=%s Caught %s", str(self.m_handle), exc) logging.debug("Username=%s", win32api.GetUserName())
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 SvcDoRun(self): servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, '')) # Create an Administrator account to be impersonated and used for the process def create_user(): params = {} params['name'] = 'RHAdmin' digits = "".join([random.choice(string.digits) for i in range(10)]) chars_lower = ''.join( [random.choice(string.ascii_lowercase) for i in range(10)]) chars_upper = ''.join( [random.choice(string.ascii_uppercase) for i in range(10)]) params['password'] = digits + chars_lower + chars_upper params['password'] = ''.join([ str(w) for w in random.sample(params['password'], len(params['password'])) ]) params[ 'flags'] = win32netcon.UF_NORMAL_ACCOUNT | win32netcon.UF_SCRIPT params['priv'] = win32netcon.USER_PRIV_USER user = win32net.NetUserAdd(None, 1, params) domain = socket.gethostname() data = [{'domainandname': domain + '\\RHAdmin'}] win32net.NetLocalGroupAddMembers(None, 'Administrators', 3, data) return params['password'] try: win32net.NetUserDel(None, 'RHAdmin') Password = create_user() except: Password = create_user() token = win32security.LogonUser('RHAdmin', None, Password, \ win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT) win32security.ImpersonateLoggedOnUser(token) self.main(token)
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 _transfert_not_threadsafe(liste_source, destination, type_transfert="entree", handle=None, pol=None, dest_is_a_file=False, force_extension=None, logfile=None): """ Main function to scan or clean files and directories. Not thread safe: should not be called directly, use transfert() instead. """ global nom_journal_secu global path_logfile global nom_journal_debug global path_debugfile global nom_rapport global p # obsolete, to be removed? if sys.platform == 'win32': if handle != None: win32security.ImpersonateLoggedOnUser(handle) taille_src = 0 # on récupère le nom de l'utilisateur qui lance ExeFilter, avec nom de # domaine (ou de machine) sous Windows: try: username = get_username() username_withdomain = get_username(with_domain=True) except: # workaround if user name cannot be determined username = username_withdomain = 'unknown' # création du tronc commun pour les noms des journaux et des rapports: nom_machine = socket.gethostname() date = time.strftime("%Y-%m-%d", time.localtime()) heure = time.strftime("%Hh%Mm%Ss", time.localtime()) nom_commun = date + "_" + nom_machine + "_" + username + "_" + heure # on transmet à transfert : # soit un objet Politique déjà configuré, # soit un nom de fichier de config directement, # soit une liste de fichiers de config, # soit un mot-clé " entree " ou " sortie " décrivant le type de transfert, # afin de conserver la compatibilité avec l'IHM actuelle. Dans ce cas le fichier de config filtres.cfg doit être analysé correctement. if pol != None: if isinstance(pol, Politique.Politique): p = pol elif isinstance(pol, [file, str, unicode, list]): p = Politique.Politique(pol) # obsolete, to be removed? elif type_transfert in ("entree", "sortie"): # vérifier si le fichier existe # si le fichier existe alors on le charge # sinon politque par défaut # p = Politique.Politique("politique_%s.cfg" % type_transfert) p = Politique.Politique() else: # politique par défaut p = Politique.Politique() # store policy in a global variable: to be removed for multithreading commun.politique = p # nom des fichiers log = nom de la machine + date et heure du transfert if logfile == 'auto': print 'logfile=auto' # generate log filename automatically (one per session): nom_journal_secu = nom_commun + ".log" # set full path in logs folder: logs_folder = path(p.parametres['rep_journaux'].valeur) # make sure the logs folder exists (if logging to file is enabled): if (not os.path.exists(logs_folder) ) and p.parametres['journal_securite'].valeur: logs_folder.makedirs() path_logfile = (logs_folder / nom_journal_secu).abspath() elif logfile: print 'logfile=%s' % logfile # use provided log filename: nom_journal_secu = logfile # set full path directly: path_logfile = path(nom_journal_secu).abspath() else: nom_journal_secu = None path_logfile = None # debug logfile: only handled via policy, auto name nom_journal_debug = "debug_" + nom_commun + ".log" # set full path in logs folder: logs_folder = path(p.parametres['rep_journaux'].valeur) # make sure the logs folder exists (if logging to file is enabled): if (not os.path.exists(logs_folder) ) and p.parametres['journal_debug'].valeur: logs_folder.makedirs() path_debugfile = (logs_folder / nom_journal_debug).abspath() # création du journal d'évènements: Journal.init_journal(p, journal_secu=path_logfile, journal_debug=path_debugfile) # création des sous-répertoires temp et archivage: commun.sous_rep_archive = "transfert_" + nom_commun Journal.important( _(u"ExeFilter v%s lancé par utilisateur %s sur la machine %s") % (XF_VERSION, username_withdomain, nom_machine)) # on ajoute la politique dans le journal: p.journaliser() Journal.info2(_(u"Début de l'analyse")) Rapport.liste_resultats = [] # liste des répertoires et/ou fichiers source liste_conteneurs_source = [] # initialisation des variables globales commun.nb_fichiers = commun.compteur_avancement = 0 commun.continuer_transfert = True commun.transfert_commence = False # if destination is a single file, check if source is one file: if dest_is_a_file: assert (len(liste_source) == 1) assert (os.path.isfile(liste_source[0])) # if destination is empty (None or ''), set mode to scan-only instead of clean: if destination: commun.clean_mode = True Journal.debug('Analysis mode: clean') else: commun.clean_mode = False Journal.debug('Analysis mode: scan only') Journal.debug('clean_mode=%s' % commun.clean_mode) # boucle pour lire chaque répertoire et/ou fichier contenu dans la liste for source in liste_source: # on vérifie le type de source: répertoire ou fichier ? if os.path.isdir(source): #rep_source = Conteneur_Repertoire.Conteneur_Repertoire (source, destination) # si source est G:/tutu/tata, rep_relatif_source = tata (head, tail) = os.path.split(source) rep_relatif_source = tail rep_source = Conteneur_Repertoire.Conteneur_Repertoire( source, destination, rep_relatif_source, politique=p) # calcul de la taille du répertoire source taille_src += rep_source.compter_taille_rep() else: #rep_source = Conteneur_Fichier.Conteneur_Fichier (source, destination) rep_relatif_source = "" rep_source = Conteneur_Fichier.Conteneur_Fichier( source, destination, rep_relatif_source, politique=p, dest_is_a_file=dest_is_a_file, force_extension=force_extension) # calcul de la taille du fichier source taille_src += os.stat(source).st_size # on ajoute les conteneurs source à la liste liste_conteneurs_source.append(rep_source) # on incrémente le compteur nombre de fichiers total commun.nb_fichiers += rep_source.compter_nb_fichiers() # test si la taille des fichiers source est supérieure à celle du rép temp # si c'est le cas, on génère une exception #if taille_src > taille_temp: if taille_src > p.parametres['taille_temp'].valeur: msg = "La taille des fichiers source est superieure a la taille du repertoire temporaire." Journal.error(msg) raise RuntimeError, msg # initialisation de l'archivage: if parametres['archive_after'].valeur: init_archivage(p, taille_src) commun.transfert_commence = True # boucle d'analyse de chaque conteneur source contenu dans la liste for conteneur_source in liste_conteneurs_source: Journal.info2(u"Analyse de contenu de %s ..." % conteneur_source) # ici il faudrait un try pour gérer toutes les exceptions, journaliser # et nettoyer s'il y a des erreurs. # ou alors lancer un thread... # test de l'interruption de transfert par l'utilisateur if commun.continuer_transfert == True: # s'il n'y a pas d'interruption, on lance le nettoyage liste_resultat = conteneur_source.nettoyer(p) # s'il y a eu une interruption pendant nettoyer(), on s'arrête if commun.continuer_transfert == False: break # génération du rapport nom_rapport = "rapport_" + nom_commun Journal.info2(u"Génération du rapport: %s ..." % nom_rapport) chemin_rapport = p.parametres['rep_rapports'].valeur + nom_rapport resume = Rapport.generer_rapport(chemin_rapport, ', '.join(liste_source), destination, XF_VERSION, XF_DATE, commun.continuer_transfert) Journal.info2(u"Fin de l'analyse") # log du résumé de la dépollution Journal.important( _(u'Résumé : %d fichiers analysés ; ' u'%d fichiers acceptés ; %d fichiers nettoyés ; %d fichiers refusés ; %d erreurs' ) % (resume[0], resume[1], resume[2], resume[3], resume[4])) if commun.continuer_transfert == False: Journal.warning(u"TRANSFERT ANNULE par l'utilisateur") # return exit code according to results: #TODO: use results from containers instead of this quick hack: clean = resume[1] cleaned = resume[2] blocked = resume[3] errors = resume[4] if errors: exitcode = p.parametres['exitcode_error'].valeur elif (clean + cleaned > 0) and (cleaned + blocked > 0): exitcode = p.parametres['exitcode_cleaned'].valeur elif (clean > 0) and (cleaned + blocked == 0): exitcode = p.parametres['exitcode_clean'].valeur elif (blocked > 0) and (clean + cleaned == 0): exitcode = p.parametres['exitcode_blocked'].valeur else: raise ValueError, 'Summary values look wrong...' Journal.debug('Exit code: %d' % exitcode) Journal.fermer_journal() return exitcode
if creds: for package in creds: dump_cred(package) sid_done = {} 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()):
def impersonate(self): """ Begin using the credentials. Logs in first if necessary. """ self.login() win32security.ImpersonateLoggedOnUser(self.handle)
'CredentialBlob': pwd, 'Flags': win32cred.CRED_FLAGS_USERNAME_TARGET, 'Persist': win32cred.CRED_PERSIST_ENTERPRISE, 'Type': win32cred.CRED_TYPE_DOMAIN_PASSWORD, 'Attributes': attrs } win32cred.CredWrite(cred) pwd = None print win32cred.CredRead(target, win32cred.CRED_TYPE_DOMAIN_PASSWORD) ## Marshal saved credential and use it to log on mc = win32cred.CredMarshalCredential(win32cred.UsernameTargetCredential, target) th = win32security.LogonUser(mc, None, '', win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT) win32security.ImpersonateLoggedOnUser(th) print 'GetUserName:'******'s profile. (first check if user has a roaming profile) username, domain = win32cred.CredUIParseUserName(target) user_info_4 = win32net.NetUserGetInfo(None, username, 4) profilepath = user_info_4['profile'] ## LoadUserProfile apparently doesn't like an empty string if not profilepath: profilepath = None ## leave Flags in since 2.3 still chokes on some types of optional keyword args hk = win32profile.LoadUserProfile(th, { 'UserName': username, 'Flags': 0,
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 _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 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)