def FindSasWindow(): hDesktop = win32service.OpenDesktop( "Winlogon", 0, False, win32con.DESKTOP_READOBJECTS | win32con.DESKTOP_ENUMERATE) for hWindow in hDesktop.EnumDesktopWindows(): if win32gui.GetClassName(hWindow) == "SAS window class": return hDesktop, hWindow
def run_pywin32_hidden(cmd_line, cwd=None): import win32con import pywintypes import win32service import win32process import win32event # Open Desktop. No need to close as destroyed when process ends desktop_name = "pystatacons" try: _ = win32service.OpenDesktop(desktop_name, 0, True, win32con.MAXIMUM_ALLOWED) except win32service.error: # desktop doesn't exist try: sa = pywintypes.SECURITY_ATTRIBUTES() sa.bInheritHandle = 1 _ = win32service.CreateDesktop(desktop_name, 0, win32con.MAXIMUM_ALLOWED, sa) # return if already created except win32service.error: sfi.SFIToolkit.display("Couldn't create Desktop.") sfi.SFIToolkit.pollnow() return 1337 s = win32process.STARTUPINFO() s.lpDesktop = desktop_name s.dwFlags = win32con.STARTF_USESHOWWINDOW + win32con.STARTF_FORCEOFFFEEDBACK s.wShowWindow = win32con.SW_SHOWMINNOACTIVE proc_ret = win32process.CreateProcess(None, cmd_line, None, None, False, 0, None, cwd, s) #proc_ret = win32process.CreateProcess(r"C:\Windows\System32\cmd.exe", cmd_line, None, None, False, 0, None, cwd, s) # hProcess, _, dwProcessId, _ sfi.SFIToolkit.display(cmd_line + "." + "\n" + "Starting in hidden desktop (pid=" + str(proc_ret[2]) + ").") sfi.SFIToolkit.pollnow() win32event.WaitForSingleObject(proc_ret[0], win32event.INFINITE) ret_code = win32process.GetExitCodeProcess(proc_ret[0]) return ret_code
def stopSaver(self, avatar): # First, disable the use of the screen saver so that it does not start # up again later. if self.isSaverEnabled(avatar): self.setSaverEnabled(avatar, False) # The following is adapted from the Microsoft knowledge base entry # Q140723: # # http://support.microsoft.com/kb/140723/EN-US/ # Try to open the screen saver desktop and close all the visible windows # on it. # NOTE: If the screen saver requires a password to be unlocked, then # this causes the unlock dialog to be displayed. try: desktop_flags = win32con.DESKTOP_READOBJECTS | \ win32con.DESKTOP_WRITEOBJECTS saver_desktop = win32service.OpenDesktop("Screen-saver", 0, False, desktop_flags) for w in saver_desktop.EnumDesktopWindows(): if win32gui.IsWindowVisible(w): win32api.PostMessage(w, win32con.WM_CLOSE, 0, 0) saver_desktop.CloseDesktop() # Windows 2000 and later: If there is no screen saver desktop, # then the screen saver is on the default desktop. We can close # it by sending a WM_CLOSE to the foreground window. except: win32api.PostMessage(win32gui.GetForegroundWindow(), win32con.WM_CLOSE, 0, 0)
def SetDesktop(deskname): hWinSta0 = win32service.OpenWindowStation("WinSta0", False, win32con.MAXIMUM_ALLOWED) hWinSta0.SetProcessWindowStation() hdesk = win32service.OpenDesktop(deskname, 0, False, win32con.MAXIMUM_ALLOWED) hdesk.SetThreadDesktop()
def isSaverRunning(self, avatar): # The following is adapted from the Microsoft knowledge base entry # Q150785: # # http://support.microsoft.com/kb/q150785/ # Try to open the screen saver desktop. If this succeeds, then the # screen saver has to be running. try: saver_desktop = win32service.OpenDesktop("Screen-saver", 0, False, win32con.MAXIMUM_ALLOWED) if saver_desktop is None: saver_running = False else: saver_desktop.Close() saver_running = True except Exception, ex: # This means that the screen saver is running, but we do not have # permission to open the desktop. if ex.errno == winerror.ERROR_ACCESS_DENIED: saver_running = True # This means that the screen saver is not running. elif ex.errno == winerror.ERROR_FILE_NOT_FOUND: saver_running = False # Some other unexpected error. else: print "Encountered unexpected error:", ex saver_running = False
def openWindow(): ''' Attempts to open a window on the Winlogon desktop. This can also be used to just test opening a window on the Application desktop. NOTE: The Winlogon desktop part is not currently working with this example installed as an interactive service. It may be necessary instead to set this up as something started by a Winlogon Notification Package. ''' logging.basicConfig( level=logging.DEBUG, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', datefmt='%m-%d %H:%M', filename=r'C:\temp\myapp.log', filemode='w') logging.debug("Starting") cur_winsta = win32service.GetProcessWindowStation() logging.debug("Got process window station") cur_desktop = win32service.GetThreadDesktop(win32api.GetCurrentThreadId()) logging.debug("Got current desktop") try: new_winsta = win32service.OpenWindowStation( "winsta0", False, win32con.WINSTA_ACCESSCLIPBOARD | win32con.WINSTA_ACCESSGLOBALATOMS | win32con.WINSTA_CREATEDESKTOP | win32con.WINSTA_ENUMDESKTOPS | win32con.WINSTA_ENUMERATE | win32con.WINSTA_EXITWINDOWS | win32con.WINSTA_READATTRIBUTES | win32con.WINSTA_READSCREEN | win32con.WINSTA_WRITEATTRIBUTES) new_winsta.SetProcessWindowStation() desktop = win32service.OpenDesktop( "Winlogon", 0, False, win32con.DESKTOP_CREATEMENU | win32con.DESKTOP_CREATEWINDOW | win32con.DESKTOP_ENUMERATE | win32con.DESKTOP_HOOKCONTROL | win32con.DESKTOP_JOURNALPLAYBACK | win32con.DESKTOP_JOURNALRECORD | win32con.DESKTOP_READOBJECTS | win32con.DESKTOP_SWITCHDESKTOP | win32con.DESKTOP_WRITEOBJECTS) desktop.SetThreadDesktop() logging.debug("Running calculator") os.system("calc") logging.debug("Done") except: logging.debug("Caught exception:") logging.debug(sys.exc_info()[0]) # Print the exception type logging.debug(sys.exc_info()[1]) # Print the exception info cur_winsta.SetProcessWindowStation() cur_desktop.SetThreadDesktop() cur_desktop.CloseDesktop() cur_winsta.CloseWindowStation() if new_winsta is not None: new_winsta.CloseWindowStation() if desktop is not None: desktop.CloseDesktop()
def setup_sacl(user_group_sid): """ Without this setup, the single user server will likely fail with either Error 0x0000142 or ExitCode -1073741502. This sets up access for the given user to the WinSta (Window Station) and Desktop objects. """ # Set access rights to window station h_win_sta = win32service.OpenWindowStation( "winsta0", False, win32con.READ_CONTROL | win32con.WRITE_DAC) # Get security descriptor by winsta0-handle sec_desc_win_sta = win32security.GetUserObjectSecurity( h_win_sta, win32security.OWNER_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION | win32con.GROUP_SECURITY_INFORMATION) # Get DACL from security descriptor dacl_win_sta = sec_desc_win_sta.GetSecurityDescriptorDacl() if dacl_win_sta is None: # Create DACL if not exisiting dacl_win_sta = win32security.ACL() # Add ACEs to DACL for specific user group dacl_win_sta.AddAccessAllowedAce(win32security.ACL_REVISION_DS, GENERIC_ACCESS, user_group_sid) dacl_win_sta.AddAccessAllowedAce(win32security.ACL_REVISION_DS, WINSTA_ALL, user_group_sid) # Set modified DACL for winsta0 win32security.SetSecurityInfo(h_win_sta, win32security.SE_WINDOW_OBJECT, win32security.DACL_SECURITY_INFORMATION, None, None, dacl_win_sta, None) # Set access rights to desktop h_desktop = win32service.OpenDesktop( "default", 0, False, win32con.READ_CONTROL | win32con.WRITE_DAC | win32con.DESKTOP_WRITEOBJECTS | win32con.DESKTOP_READOBJECTS) # Get security descriptor by desktop-handle sec_desc_desktop = win32security.GetUserObjectSecurity( h_desktop, win32security.OWNER_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION | win32con.GROUP_SECURITY_INFORMATION) # Get DACL from security descriptor dacl_desktop = sec_desc_desktop.GetSecurityDescriptorDacl() if dacl_desktop is None: #create DACL if not exisiting dacl_desktop = win32security.ACL() # Add ACEs to DACL for specific user group dacl_desktop.AddAccessAllowedAce(win32security.ACL_REVISION_DS, GENERIC_ACCESS, user_group_sid) dacl_desktop.AddAccessAllowedAce(win32security.ACL_REVISION_DS, DESKTOP_ALL, user_group_sid) # Set modified DACL for desktop win32security.SetSecurityInfo(h_desktop, win32security.SE_WINDOW_OBJECT, win32security.DACL_SECURITY_INFORMATION, None, None, dacl_desktop, None)
def icon_wndproc(hwnd, msg, wp, lp): """Window proc for the tray icons""" if lp == win32con.WM_LBUTTONDOWN: ## popup menu won't disappear if you don't do this win32gui.SetForegroundWindow(hwnd) curr_desktop = win32service.OpenInputDesktop(0, True, win32con.MAXIMUM_ALLOWED) curr_desktop_name = win32service.GetUserObjectInformation( curr_desktop, win32con.UOI_NAME ) winsta = win32service.GetProcessWindowStation() desktops = winsta.EnumDesktops() m = win32gui.CreatePopupMenu() desktop_cnt = len(desktops) ## *don't* create an item 0 for d in range(1, desktop_cnt + 1): mf_flags = win32con.MF_STRING ## if you switch to winlogon yourself, there's nothing there and you're stuck if desktops[d - 1].lower() in ("winlogon", "disconnect"): mf_flags = mf_flags | win32con.MF_GRAYED | win32con.MF_DISABLED if desktops[d - 1] == curr_desktop_name: mf_flags = mf_flags | win32con.MF_CHECKED win32gui.AppendMenu(m, mf_flags, d, desktops[d - 1]) win32gui.AppendMenu(m, win32con.MF_STRING, desktop_cnt + 1, "Create new ...") win32gui.AppendMenu(m, win32con.MF_STRING, desktop_cnt + 2, "Exit") x, y = win32gui.GetCursorPos() d = win32gui.TrackPopupMenu( m, win32con.TPM_LEFTBUTTON | win32con.TPM_RETURNCMD | win32con.TPM_NONOTIFY, x, y, 0, hwnd, None, ) win32gui.PumpWaitingMessages() win32gui.DestroyMenu(m) if d == desktop_cnt + 1: ## Create new get_new_desktop_name(hwnd) elif d == desktop_cnt + 2: ## Exit win32gui.PostQuitMessage(0) win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, window_info[hwnd]) del window_info[hwnd] origin_desktop.SwitchDesktop() elif d > 0: hdesk = win32service.OpenDesktop( desktops[d - 1], 0, 0, win32con.MAXIMUM_ALLOWED ) hdesk.SwitchDesktop() return 0 else: return win32gui.DefWindowProc(hwnd, msg, wp, lp)
class dump(auditbase): def __init__(self, options): self.options = options def run(self): # TODO we don't have to pass options or issues to any subs self.run_sub("dump_misc_checks", 1, self.dump_misc_checks) self.run_sub("dump_paths", self.options.do_all or self.options.do_paths, self.dump_paths ) self.run_sub("dump_all_files", self.options.do_allfiles, self.dump_all_files ) self.run_sub("dump_eventlogs", self.options.do_all or self.options.do_eventlogs, self.dump_eventlogs ) self.run_sub("dump_shares", self.options.do_all or self.options.do_shares, self.dump_shares ) self.run_sub("dump_patches", self.options.do_all or self.options.patchfile, self.dump_patches ) self.run_sub("dump_loggedin", self.options.do_all or self.options.do_loggedin, self.dump_loggedin ) self.run_sub("dump_services", self.options.do_all or self.options.do_services, self.dump_services ) self.run_sub("dump_drivers", self.options.do_all or self.options.do_drivers, self.dump_drivers ) self.run_sub("dump_drives", self.options.do_all or self.options.do_drives, self.dump_drives ) self.run_sub("dump_processes", self.options.do_all or self.options.do_processes, self.dump_processes ) self.run_sub("dump_program_files", self.options.do_all or self.options.do_program_files, self.dump_program_files) self.run_sub("dump_registry", self.options.do_all or self.options.do_registry, self.dump_registry ) self.run_sub("dump_scheduled_tasks",self.options.do_all or self.options.do_scheduled_tasks,self.dump_scheduled_tasks) self.run_sub("dump_reg_keys", self.options.do_all or self.options.do_reg_keys, self.dump_reg_keys ) self.run_sub("dump_nt_objects", self.options.do_all or self.options.do_nt_objects, self.dump_nt_objects ) self.run_sub("dump_users", self.options.do_all or self.options.do_users, self.dump_users ) self.run_sub("dump_groups", self.options.do_all or self.options.do_groups, self.dump_groups ) self.run_sub("dump_user_modals", self.options.do_all or self.options.get_modals, self.dump_user_modals) # ---------------------- Define --dump Subs --------------------------- def dump_paths(self): systempath = wpc.utils.get_system_path() print "System path: %s" % (systempath) paths = wpc.utils.get_user_paths() for path in paths: print "Path for user %s: %s" % (path[0].get_fq_name(), path[1]) def dump_scheduled_tasks(self): for task in scheduledtasks().get_all_tasks(): print task.as_text() def dump_misc_checks(self): # Check if host is in a domain in_domain = 0 dc_info = None try: dc_info = win32security.DsGetDcName(None, None, None, None, 0) in_domain = 1 except: pass if in_domain: print "[+] Host is in domain" for k in dc_info.keys(): print "[-] %s => %s" % (k, dc_info[k]) else: print "[+] Host is not in domain" def dump_eventlogs(self): # TODO print "[E] dump_eventlogs not implemented yet. Sorry." def dump_shares(self): for s in shares().get_all(): print s.as_text() def dump_reg_keys(self): for check, key in wpc.conf.reg_keys.items(): #print "Checking %s => %s" % (check, key) key_a = key.split('\\') value = key_a.pop() key_s = '\\'.join(key_a) rk = regkey(key_s) if rk.is_present: v = rk.get_value(value) # This value appears as "(Default)" in regedit print "Check: \"%s\", Key: %s, Value: %s, Data: %s" % (check, key_s, value, v) def dump_patches(self): # TODO print "[E] dump_patches not implemented yet. Sorry." def dump_loggedin(self): resume = 0 print "\n[+] Logged in users:" try: while True: users, _, resume = win32net.NetWkstaUserEnum(wpc.conf.remote_server, 1 , resume , 999999 ) for user in users: print "User logged in: Logon Server=\"%s\" Logon Domain=\"%s\" Username=\"%s\"" % (user['logon_server'], user['logon_domain'], user['username']) if resume == 0: break except: print "[E] Failed" def dump_program_files(self): # Record info about all directories include_dirs = 1 prog_dirs = [] if os.getenv('ProgramFiles'): prog_dirs.append(os.environ['ProgramFiles']) if os.getenv('ProgramFiles(x86)'): prog_dirs.append(os.environ['ProgramFiles(x86)']) for directory in prog_dirs: # Walk program files directories looking for executables for filename in wpc.utils.dirwalk(directory, wpc.conf.executable_file_extensions, include_dirs): f = File(filename) print f.as_text() def dump_services(self): for s in services().get_services(): if s: print s.as_text() else: print "[W] Failed to get info about a service. Skipping." def dump_drivers(self): for d in drivers().get_services(): print d.as_text() def dump_drives(self): for d in drives().get_fixed_drives(): print "%s: (%s)" % (d.get_name(), d.get_fs()) def dump_processes(self): for p in processes().get_all(): print p.as_text() # When listing DLLs for a process we need to see the filesystem like they do if p.is_wow64(): wpc.utils.enable_wow64() if p.get_exe(): print "Security Descriptor for Exe File %s" % p.get_exe().get_name() if p.get_exe().get_sd(): print p.get_exe().get_sd().as_text() else: print "[unknown]" for dll in p.get_dlls(): print "\nSecurity Descriptor for DLL File %s" % dll.get_name() sd = dll.get_sd() if sd: print sd.as_text() if p.is_wow64(): wpc.utils.disable_wow64() def dump_users(self, get_privs = 0): print "[+] Dumping user list:" userlist = users() for u in userlist.get_all(): print u.get_fq_name() if get_privs: print "\n\t[+] Privileges of this user:"******"\t%s" % priv print "\n\t[+] Privileges of this user + the groups it is in:" for p in u.get_effective_privileges(): print "\t%s" % p print def dump_user_modals(self): d1 = d2 = d3 = d4 = {} try: d1 = win32net.NetUserModalsGet(wpc.conf.remote_server, 0) d2 = win32net.NetUserModalsGet(wpc.conf.remote_server, 1) d3 = win32net.NetUserModalsGet(wpc.conf.remote_server, 2) d4 = win32net.NetUserModalsGet(wpc.conf.remote_server, 3) except pywintypes.error as e: print "[E] %s: %s" % (e[1], e[2]) for d in (d1, d2, d3, d4): for k in d.keys(): print "%s: %s" % (k, d[k]) def dump_groups(self, get_privs = 0): print "[+] Dumping group list:" grouplist = groups() for g in grouplist.get_all(): group_name = g.get_fq_name() for m in g.get_members(): print "%s has member: %s" % (group_name, m.get_fq_name()) if get_privs: for priv in g.get_privileges(): print "%s has privilege: %s" % (group_name, priv) # TODO # print "\n\t[+] Privileges of this group + the groups it is in:" # for p in g.get_effective_privileges(): # print "\t%s" % p def dump_registry(self): for r in regkey('HKLM').get_all_subkeys(): print r.as_text() def dump_nt_objects(self): # # Windows stations and Desktops - TODO make is more OO: objects for windowstations and desktops. # win32con.WINSTA_ALL_ACCESS = 0x0000037f print print "[-] Sessions" print for session in win32ts.WTSEnumerateSessions(win32ts.WTS_CURRENT_SERVER_HANDLE, 1, 0): print "SessionId: %s" % session['SessionId'] print "\tWinStationName: %s" % session['WinStationName'] print "\tState: %s" % session['State'] print session = win32ts.ProcessIdToSessionId(win32process.GetCurrentProcessId()) print print "[-] Winstations in session %s" % session print for w in win32service.EnumWindowStations(): print "winstation: %s" % w print for w in win32service.EnumWindowStations(): print print "[-] Session %s, Winstation '%s'" % (session, w) print # Get SD try: h = 0 h = win32service.OpenWindowStation(w, False, win32con.READ_CONTROL) s = win32security.GetKernelObjectSecurity(h, win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION) s = sd('winstation', s) print s.as_text() except pywintypes.error,details: print "[E] Can't get READ_CONTROL winstation handle: %s" % details # Get Desktops try: h = 0 h = win32service.OpenWindowStation(w, False, win32con.WINSTA_ENUMDESKTOPS) print "[-] Session %s, Winstation '%s' has these desktops:" % (session, w) for d in h.EnumDesktops(): print "\t%s" % d print except pywintypes.error,details: print "[E] Can't get WINSTA_ENUMDESKTOPS winstation handle: %s" % details if h: h.SetProcessWindowStation() for d in h.EnumDesktops(): print "[-] Session %s, Winstation '%s', Desktop '%s'" % (session, w, d) try: hd = win32service.OpenDesktop(d, 0, False, win32con.READ_CONTROL) s = win32security.GetKernelObjectSecurity(hd, win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION) s = sd('desktop', s) print s.as_text() except pywintypes.error,details: print "[E] Can't get READ_CONTROL desktop handle: %s" % details
def __init__(self, userHandle, userSID, userName, domain, forceSidAdd=False): """ Constructs a Windows-specific user perspective used to access the event manager. @pre userHandle is a valid PyHANDLE object. @param userHandle Handle to the user's authentication. @param userSID The SID for the user represented by this avatar. @param userName The name of the user represented by this avatar. @param domain The domain for the user. @param forceSidAdd Causes the given ID to be added to the window station and desktop ACLs even if it is already present. Use with caution! """ assert (userHandle is not None) UserPerspective.__init__(self) self.mUserHandle = userHandle self.mUserSID = userSID self.mWinsta = None self.mDesktop = None self.mAddedHandles = [] self.mLogger = logging.getLogger('daemon.WindowsAvatar') # Save the current window station for later. cur_winsta = win32service.GetProcessWindowStation() # Open window station winsta0 and make it the window station for this # process. winsta_flags = win32con.READ_CONTROL | win32con.WRITE_DAC new_winsta = win32service.OpenWindowStation("winsta0", False, winsta_flags) new_winsta.SetProcessWindowStation() # Get a handle to the default desktop so that we can change its access # control list. desktop_flags = win32con.READ_CONTROL | \ win32con.WRITE_DAC | \ win32con.DESKTOP_WRITEOBJECTS | \ win32con.DESKTOP_READOBJECTS desktop = win32service.OpenDesktop("default", 0, False, desktop_flags) # If user_sid is not already among the SIDs who have access to # new_winsta, then add it now. It will be removed in logout(). if forceSidAdd or not windesktop.handleHasSID(new_winsta, self.mUserSID): windesktop.addUserToWindowStation(new_winsta, self.mUserSID) self.mAddedHandles.append(new_winsta) self.mLogger.debug("Added SID to new_winsta") # If user_sid is not already among the SIDs who have access to desktop, # then add it now. It will be removed in logout(). if forceSidAdd or not windesktop.handleHasSID(desktop, self.mUserSID): windesktop.addUserToDesktop(desktop, self.mUserSID) self.mAddedHandles.append(desktop) self.mLogger.debug("Added SID to desktop") cur_winsta.SetProcessWindowStation() self.mWinsta = new_winsta self.mDesktop = desktop # (username, domain, acct_type) = \ # win32security.LookupAccountSid(dc_name, self.mUserSID) # self.mUserName = username # self.mDomain = domain self.mUserName = userName self.mDomain = domain # Get name of domain controller. try: dc_name = win32net.NetGetDCName() except: dc_name = None user_info_4 = win32net.NetUserGetInfo(dc_name, self.mUserName, 4) profilepath = user_info_4['profile'] # LoadUserProfile apparently doesn't like an empty string if not profilepath: profilepath = None try: # Leave Flags in since 2.3 still chokes on some types of optional # keyword args self.mUserProfile = win32profile.LoadUserProfile( self.mUserHandle, { 'UserName': self.mUserName, 'Flags': 0, 'ProfilePath': profilepath }) self.mLogger.debug("self.mUserProfile = %s" % str(self.mUserProfile)) self.mLogger.info("Loaded profile %s" % profilepath) except pywintypes.error, error: self.mLogger.error("Error loading profile: %s" % error)
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 dump_nt_objects(self): # # Windows stations and Desktops - TODO make is more OO: objects for windowstations and desktops. # win32con.WINSTA_ALL_ACCESS = 0x0000037f print() print("[-] Sessions") print() for session in win32ts.WTSEnumerateSessions( win32ts.WTS_CURRENT_SERVER_HANDLE, 1, 0): print("SessionId: %s" % session['SessionId']) print("\tWinStationName: %s" % session['WinStationName']) print("\tState: %s" % session['State']) print() session = win32ts.ProcessIdToSessionId( win32process.GetCurrentProcessId()) print() print("[-] Winstations in session %s" % session) print() for w in win32service.EnumWindowStations(): print("winstation: %s" % w) print() for w in win32service.EnumWindowStations(): print() print("[-] Session %s, Winstation '%s'" % (session, w)) print() # Get SD try: h = 0 h = win32service.OpenWindowStation(w, False, win32con.READ_CONTROL) s = win32security.GetKernelObjectSecurity( h, win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION) s = SD('winstation', s) print(s.as_text()) except pywintypes.error as details: print("[E] Can't get READ_CONTROL winstation handle: %s" % details) # Get Desktops h = 0 try: h = win32service.OpenWindowStation( w, False, win32con.WINSTA_ENUMDESKTOPS) print("[-] Session %s, Winstation '%s' has these desktops:" % (session, w)) for d in h.EnumDesktops(): print("\t%s" % d) print() except pywintypes.error as details: print( "[E] Can't get WINSTA_ENUMDESKTOPS winstation handle: %s" % details) if h: h.SetProcessWindowStation() for d in h.EnumDesktops(): print("[-] Session %s, Winstation '%s', Desktop '%s'" % (session, w, d)) try: hd = win32service.OpenDesktop(d, 0, False, win32con.READ_CONTROL) s = win32security.GetKernelObjectSecurity( hd, win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION) s = SD('desktop', s) print(s.as_text()) except pywintypes.error as details: print("[E] Can't get READ_CONTROL desktop handle: %s" % details) print() # # Objects # print() print("[-] Objects") print() root = NTObj("\\") for child in root.get_all_child_objects(): print(child.as_text()) if (child.get_type() == "Semaphore" or child.get_type() == "Event" or child.get_type() == "Mutant" or child.get_type() == "Timer" or child.get_type() == "Section" or child.get_type() == "Device" or child.get_type() == "SymbolicLink" or child.get_type() == "Key" or child.get_type() == "Directory") and child.get_sd(): print(child.get_sd().as_text()) else: print("Skipping unknown object type: %s" % child.get_type()) print()