def get_token_groups(self): if self.token_groups == []: try: for tup in win32security.GetTokenInformation( self.get_th(), ntsecuritycon.TokenGroups): sid = tup[0] attr = tup[1] if attr < 0: attr = 2**32 + attr attr_str_a = [] if attr & 1: attr_str_a.append("MANDATORY") if attr & 2: attr_str_a.append("ENABLED_BY_DEFAULT") if attr & 4: attr_str_a.append("ENABLED") if attr & 8: attr_str_a.append("OWNER") if attr & 16: attr_str_a.append("USE_FOR_DENY_ONLY") if attr & 0x00000020: attr_str_a.append("INTEGRITY") if attr & 0x00000040: attr_str_a.append("INTEGRITY_ENABLED") if attr & 0x20000000: attr_str_a.append("RESOURCE") if attr & 0xC0000000: attr_str_a.append("LOGON_ID") self.token_groups.append((Principal(sid), attr_str_a)) except: pass return self.token_groups
def get_token_owner(self): if not self.token_owner and self.get_th(): sidObj = win32security.GetTokenInformation( self.get_th(), ntsecuritycon.TokenOwner) if sidObj: self.token_owner = Principal(sidObj) return self.token_owner
def get_token_primary_group(self): if not self.token_primary_group and self.get_th(): sidObj = win32security.GetTokenInformation( self.get_th(), ntsecuritycon.TokenPrimaryGroup) if sidObj: self.token_primary_group = Principal(sidObj) return self.token_primary_group
def get_owner(self): if not self.owner: owner_sid = self.get_owner_sid() if owner_sid: self.owner = Principal(self.get_owner_sid()) else: self.owner = None return self.owner
def get_group(self): if not self.group: group_sid = self.get_group_sid() if group_sid: self.group = Principal(self.get_group_sid()) else: self.group = None return self.group
def get_token_integrity_level(self): if not self.token_integrity_level and self.get_th(): try: sid, i = win32security.GetTokenInformation( self.get_th(), ntsecuritycon.TokenIntegrityLevel) self.token_integrity_level = Principal(sid) except: pass return self.token_integrity_level
def get_token_restricted_sids(self): if self.token_restricted_sids == [] and self.get_th(): try: tups = win32security.GetTokenInformation( self.get_th(), ntsecuritycon.TokenRestrictedSids) for sid, i in tups: self.token_restricted_sids.append(Principal(sid)) except: pass return self.token_restricted_sids
def get_all(self): if not self.processes: pids = win32process.EnumProcesses() try: proc_infos = win32ts.WTSEnumerateProcesses( wpc.conf.remote_server, 1, 0) except: proc_infos = [] pass for pid in pids: p = Process(pid) self.add(p) for proc_info in proc_infos: pid = proc_info[1] p = self.find_by_pid(pid) if p: # might fail to find process - race condition p.set_wts_session_id(proc_info[0]) p.set_wts_name(proc_info[2]) if proc_info[3]: # sometimes None p.set_wts_sid(Principal(proc_info[3])) TH32CS_SNAPPROCESS = 0x00000002 # See http://msdn2.microsoft.com/en-us/library/ms686701.aspx CreateToolhelp32Snapshot = ctypes.windll.kernel32.CreateToolhelp32Snapshot Process32First = ctypes.windll.kernel32.Process32First Process32Next = ctypes.windll.kernel32.Process32Next Thread32First = ctypes.windll.kernel32.Thread32First Thread32Next = ctypes.windll.kernel32.Thread32Next CloseHandle = ctypes.windll.kernel32.CloseHandle hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) pe32 = PROCESSENTRY32() pe32.dwSize = ctypes.sizeof(PROCESSENTRY32) if Process32First(hProcessSnap, ctypes.byref(pe32)) == win32con.FALSE: pass #print >> sys.stderr, "Failed getting first process." #return else: while True: p = self.find_by_pid(pe32.th32ProcessID) if p: # might fail to find process - race condition p.set_short_name(pe32.szExeFile) if Process32Next(hProcessSnap, ctypes.byref(pe32)) == win32con.FALSE: break CloseHandle(hProcessSnap) return self.processes
def __init__(self, *args, **kwargs): Principal.__init__(self, *args, **kwargs) self.member_of = [] self.effective_privileges = []
def define_trusted_principals(options): exploitable_by_fq = [] ignore_principals = [] if options.exploitable_by_list: exploitable_by_fq = options.exploitable_by_list if options.exploitable_by_file: try: exploitable_by_fq = exploitable_by_fq + [ line.strip() for line in open(options.exploitable_by_file) ] except: print("[E] Error reading from file %s" % options.exploitablebyfile) sys.exit() if options.ignore_principal_list: ignore_principals = options.ignore_principal_list if options.ignore_principal_file: try: ignore_principals = ignore_principals + [ line.strip() for line in open(options.ignoreprincipalfile) ] except: print("[E] Error reading from file %s" % options.ignoreprincipalfile) sys.exit() # examine token, populate exploitable_by if options.exploitable_by_me: try: p = Process(os.getpid()) wpc.conf.exploitable_by.append(p.get_token().get_token_owner()) for g in p.get_token().get_token_groups(): if "|".join(g[1]).find("USE_FOR_DENY_ONLY") == -1: wpc.conf.exploitable_by.append(g[0]) except: print("[E] Problem examining access token of current process") sys.exit() # check each of the supplied users in exploitable_by and exploitable_by resolve if exploitable_by_fq or wpc.conf.exploitable_by: wpc.conf.privesc_mode = "exploitable_by" for t in exploitable_by_fq: try: sid, _, _ = win32security.LookupAccountName( wpc.conf.remote_server, t) if sid: p = Principal(sid) # print "Trusted: %s (%s) [%s]" % (p.get_fq_name(), p.get_type_string(), p.is_group_type()) # print "[D] Added trusted principal %s. is group? %s" % (p.get_fq_name(), p.is_group_type()) if p.is_group_type(): p = Group(p.get_sid()) # for m in p.get_members(): # print "Member: %s" % m.get_fq_name() else: p = User(p.get_sid()) # print p.get_groups() wpc.conf.exploitable_by.append(p) else: print("[E] can't look up sid for " + t) except: pass print("Only reporting privesc issues for these users/groups:") for p in wpc.conf.exploitable_by: print("* " + p.get_fq_name()) return else: wpc.conf.privesc_mode = "report_untrusted" # if user has specified list of trusted users, use only their list if ignore_principals: if options.ignorenoone: wpc.conf.trusted_principals_fq = [] wpc.conf.trusted_principals_fq = wpc.conf.trusted_principals_fq + ignore_principals else: # otherwise the user has not specified a list of trusted users. we intelligently tweak the list. # Ignore "NT AUTHORITY\TERMINAL SERVER USER" if HKLM\System\CurrentControlSet\Control\Terminal Server\TSUserEnabled = 0 or doesn't exist # See http://support.microsoft.com/kb/238965 for details r = RegKey( r"HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server" ) if r.is_present(): v = r.get_value("TSUserEnabled") if v is None: print( "[i] TSUserEnabled registry value is absent. Excluding TERMINAL SERVER USER" ) elif v != 0: print( "[i] TSUserEnabled registry value is %s. Including TERMINAL SERVER USER" % v) wpc.conf.trusted_principals_fq.append( "NT AUTHORITY\TERMINAL SERVER USER") else: print( "[i] TSUserEnabled registry value is 0. Excluding TERMINAL SERVER USER" ) else: print( "[i] TSUserEnabled registry key is absent. Excluding TERMINAL SERVER USER" ) print() # TODO we only want to ignore this if it doesn't resolve try: # Server Operators group # print "[D] converting string sid" # print "%s" % win32security.ConvertStringSidToSid("S-1-5-32-549") p = Group(win32security.ConvertStringSidToSid("S-1-5-32-549")) except: wpc.conf.trusted_principals.append(p) # TODO this always ignored power users. not what we want. # only want to ignore when group doesn't exist. try: p = Group(win32security.ConvertStringSidToSid("S-1-5-32-547")) wpc.conf.trusted_principals.append(p) except: pass # populate wpc.conf.trusted_principals with the objects corresponding to trusted_principals_fq for t in wpc.conf.trusted_principals_fq: try: sid, _, _ = win32security.LookupAccountName( wpc.conf.remote_server, t) if sid: p = Principal(sid) # print "Trusted: %s (%s) [%s]" % (p.get_fq_name(), p.get_type_string(), p.is_group_type()) # print "[D] Added trusted principal %s. is group? %s" % (p.get_fq_name(), p.is_group_type()) if p.is_group_type(): p = Group(p.get_sid()) # for m in p.get_members(): # print "Member: %s" % m.get_fq_name() else: p = User(p.get_sid()) # print p.get_groups() wpc.conf.trusted_principals.append(p) else: print("[E] can't look up sid for " + t) except: pass print("Considering these users to be trusted:") for p in wpc.conf.trusted_principals: print("* " + p.get_fq_name()) print()