Пример #1
0
    def run(self, profile):
        path = os.path.join(profile['APPDATA'], 'Skype')
        if not os.path.exists(path):
            return

        pwd_found = set()
        # retrieve the key used to build the salt
        key = self.get_regkey(profile)
        if not key:
            log.error('Skype: The salt has not been retrieved')
            return

        username = self.get_username(path)
        d = os.path.join(path, username)
        if username and os.path.exists(d):
            info = self.get_info(key, username, d)
            if info:
                pwd_found.add(info)

        if not pwd_found:
            for d in os.listdir(path):
                info = self.get_info(key, d, os.path.join(path, d))
                if info:
                    pwd_found.add(info)

        return list(pwd_found)
Пример #2
0
    def parse_json(self, connection_file_path):
        repos_creds = []
        if not os.path.exists(connection_file_path):
            return repos_creds
        with open(connection_file_path) as connection_file:
            try:
                connections_infos = json.load(connection_file)
            except Exception:
                return repos_creds
            for connection in connections_infos.get("connections", []):
                try:
                    creds = {
                        "Name": connection["connectionName"],
                        "Host": connection["serverHost"],
                        "Port": connection["serverPort"]
                    }
                    crd = connection["credentials"][0]
                    if crd.get("enabled"):
                        creds.update({
                            "AuthMode": "CREDENTIALS",
                            "DatabaseName": crd["databaseName"],
                            "AuthMechanism": crd["mechanism"],
                            "Login": crd["userName"],
                            "Password": crd["userPassword"]
                        })
                    else:
                        creds.update({
                            "Host": connection["ssh"]["host"],
                            "Port": connection["ssh"]["port"],
                            "Login": connection["ssh"]["userName"]
                        })
                        if connection["ssh"]["enabled"] and connection["ssh"][
                                "method"] == "password":
                            creds.update({
                                "AuthMode":
                                "SSH_CREDENTIALS",
                                "Password":
                                connection["ssh"]["userPassword"]
                            })
                        else:
                            creds.update({
                                "AuthMode":
                                "SSH_PRIVATE_KEY",
                                "Passphrase":
                                connection["ssh"]["passphrase"],
                                "PrivateKey":
                                self.read_file_content(
                                    connection["ssh"]["privateKeyFile"]),
                                "PublicKey":
                                self.read_file_content(
                                    connection["ssh"]["publicKeyFile"])
                            })
                    repos_creds.append(creds)
                except Exception as e:
                    log.error(f"Cannot retrieve connections credentials '{e}'")

        return repos_creds
Пример #3
0
    def run(self, profile):
        interfaces_dir = os.path.join('C:\\ProgramData\\Microsoft\\Wlansvc\\Profiles\\Interfaces')

        # # for windows Vista or higher

        if not os.path.isdir(interfaces_dir):
            return

        pwd_found = []

        for wifi_dir in os.listdir(interfaces_dir):
            repository = os.path.join(interfaces_dir, wifi_dir)
            if not os.path.isdir(repository):
                continue

            for file in os.listdir(repository):
                f = os.path.join(repository, file)
                if not os.path.isfile(f):
                    continue
                values = {}
                tree = ElementTree(file=f)
                root = tree.getroot()
                xmlns = root.tag.split("}")[0] + '}'

                for elem in tree.iter():
                    if elem.tag.endswith('SSID'):
                        for w in elem:
                            if w.tag == xmlns + 'name':
                                values['SSID'] = w.text

                    if elem.tag.endswith('authentication'):
                        values['Authentication'] = elem.text

                    if elem.tag.endswith('protected'):
                        values['Protected'] = elem.text

                    if elem.tag.endswith('keyMaterial'):
                        try:
                            password = self.decrypt_using_lsa_secret(elem.text, profile)
                            if not password:
                                password = self.decrypt_using_netsh(ssid=values['SSID'])
                            if password:
                                values['Password'] = password
                            else:
                                values['INFO'] = '[!] Password not found.'
                        except Exception:
                            log.error(traceback.format_exc())
                            values['INFO'] = '[!] Password not found.'

                if values:
                    pwd_found.append(values)

        return pwd_found
Пример #4
0
    def run(self, profile):
        pwd_found = []

        creds_directory = os.path.join(profile['LOCALAPPDATA'], 'Microsoft',
                                       'Credentials')
        creds_directory2 = os.path.join(profile['APPDATA'], 'Microsoft',
                                        'Credentials')
        if not profile.get('mkfiles'):
            return
        for folder in [creds_directory, creds_directory2]:
            if not os.path.isdir(creds_directory):
                continue
            for cred_file in os.listdir(folder):
                try:
                    data = open(os.path.join(folder, cred_file), 'rb').read()
                    cred = CredentialFile(data)
                    blob = DPAPI_BLOB(cred['Data'])

                    masterkey = profile['mkfiles'].get(
                        bin_to_string(blob['GuidMasterKey']).lower())

                    if masterkey:
                        decrypted = blob.decrypt(masterkey)
                        if decrypted is not None:
                            blob = CREDENTIAL_BLOB(decrypted)
                            pwd = blob['Unknown3']
                            try:
                                pwd = pwd.decode('utf-16-le').rstrip('\0')
                            except:
                                pass
                            pwd_found.append({
                                'Target':
                                blob['Target'].decode('utf-16-le').rstrip(
                                    '\0'),
                                'Username':
                                blob['Username'].decode('utf-16-le').rstrip(
                                    '\0'),
                                'Password':
                                pwd,
                                'LastWritten':
                                datetime.utcfromtimestamp(
                                    getUnixTime(blob['LastWritten']))
                            })
                except Exception:
                    log.error(traceback.format_exc())

            return pwd_found
Пример #5
0
    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)
Пример #6
0
    def get_firefox_profiles(self, directory):
        """
        List all profiles
        """
        cp = RawConfigParser()
        profile_list = []

        if os.path.isfile(os.path.join(directory, 'profiles.ini')):
            try:
                cp.read(os.path.join(directory, 'profiles.ini'))
                for section in cp.sections():
                    if section.startswith('Profile') and cp.has_option(
                            section, 'Path'):
                        profile_path = None

                        if cp.has_option(section, 'IsRelative'):
                            if cp.get(section, 'IsRelative') == '1':
                                profile_path = os.path.join(
                                    directory,
                                    cp.get(section, 'Path').strip())
                            elif cp.get(section, 'IsRelative') == '0':
                                profile_path = cp.get(section, 'Path').strip()

                        else:  # No "IsRelative" in profiles.ini
                            profile_path = os.path.join(
                                directory,
                                cp.get(section, 'Path').strip())

                        if profile_path:
                            profile_list.append(profile_path.replace(
                                '/', '\\'))

            except Exception as e:
                log.error(f'An error occurred while reading profiles.ini: {e}')

        else:
            for i in os.listdir(directory):
                i = os.path.join(directory, i, 'cookies.sqlite')
                if os.path.isfile(i):
                    profile_list.append(i)

        return list(set(profile_list))
Пример #7
0
    def run(self):
        creds = []
        results = None

        # Find the location of steam - to make it easier we're going to use a try block
        # 'cos I'm lazy
        try:
            with OpenKey(winreg.HKEY_CURRENT_USER,
                         'Software\\Valve\\Steam') as key:
                results = winreg.QueryValueEx(key, 'SteamPath')
        except Exception:
            pass

        if not results:
            return

        steampath = results[0]
        userdata = os.path.join(steampath, 'userdata')

        # Check that we have a userdata directory
        if not os.path.exists(userdata):
            log.error('Steam doesn\'t have a userdata directory.')
            return

        # Now look for Galcon Fusion in every user
        for f in os.listdir(userdata):
            filepath = os.path.join(userdata, f, '44200\\remote\\galcon.cfg')
            if not os.path.exists(filepath):
                continue

            # If we're here we should have a Galcon Fusion file
            with open(filepath, mode='rb') as cfgfile:
                # We've found a config file, now extract the creds
                data = cfgfile.read()
                creds.append({
                    'Login': data[4:0x23],
                    'Password': data[0x24:0x43]
                })

        return creds
Пример #8
0
    def run(self, profile):
        """
        Extract all connection's credentials.

        :return: List of dict in which one dict contains all information for a connection.
        """
        repos_creds = []
        connection_file_location = os.path.join(
            profile["USERPROFILE"],
            '.ApacheDirectoryStudio\\.metadata\\.plugins\\org.apache.directory.studio.connection.core\\connections.xml'
        )
        if os.path.isfile(connection_file_location):
            try:
                connections = parse(connection_file_location).getroot()
                connection_nodes = connections.findall(".//connection")
                for connection_node in connection_nodes:
                    creds = {}
                    for connection_attr_name in connection_node.attrib:
                        # Interesting XML attributes in ADS connection configuration
                        if connection_attr_name in ["host", "port", "bindPrincipal", "bindPassword", "authMethod"]:
                            creds[connection_attr_name] = connection_node.attrib[connection_attr_name].strip()
                    if creds:
                        repos_creds.append(creds)
            except Exception as e:
                log.error("Cannot retrieve connections credentials '%s'" % e)

        # Parse and process the list of connections credentials
        pwd_found = []
        for creds in repos_creds:
            pwd_found.append({
                "Host"                  : creds["host"],
                "Port"                  : creds["port"],
                "Login"                 : creds["bindPrincipal"],
                "Password"              : creds["bindPassword"],
                "AuthenticationMethod"  : creds["authMethod"]
            })

        return pwd_found
Пример #9
0
    def run(self):
        creds = []
        results = None

        # Find the location of steam - to make it easier we're going to use a try block
        # 'cos I'm lazy
        try:
            with OpenKey(winreg.HKEY_CURRENT_USER,
                         'Software\Valve\Steam') as key:
                results = winreg.QueryValueEx(key, 'SteamPath')
        except Exception:
            pass

        if not results:
            return

        steampath = results[0]
        steamapps = os.path.join(steampath, 'SteamApps\common')

        # Check that we have a SteamApps directory
        if not os.path.exists(steamapps):
            log.error('Steam doesn\'t have a SteamApps directory.')
            return

        filepath = os.path.join(steamapps, 'Turba\\Assets\\Settings.bin')

        if not os.path.exists(filepath):
            log.debug('Turba doesn\'t appear to be installed.')
            return

        # If we're here we should have a valid config file file
        with open(filepath, mode='rb') as filepath:
            # We've found a config file, now extract the creds
            data = filepath.read()
            chunk = data[0x1b:].split(b'\x0a')
            creds.append({'Login': chunk[0], 'Password': chunk[1]})
        return creds
Пример #10
0
    def extract_private_keys_unprotected(self):
        """
        Extract all DSA/RSA private keys that are not protected with a passphrase.

        :return: List of encoded key (key file content)
        """
        keys = []
        if os.path.isdir(self.key_files_location):
            for (dirpath, dirnames,
                 filenames) in os.walk(self.key_files_location,
                                       followlinks=True):
                for f in filenames:
                    key_file_path = os.path.join(dirpath, f)
                    if os.path.isfile(key_file_path):
                        try:
                            # Read encoded content of the key
                            with open(key_file_path, "r") as key_file:
                                key_content_encoded = key_file.read()
                            # Determine the type of the key (public/private) and what is it algorithm
                            if "DSA PRIVATE KEY" in key_content_encoded:
                                key_algorithm = "DSA"
                            elif "RSA PRIVATE KEY" in key_content_encoded or "OPENSSH PRIVATE KEY" in key_content_encoded:
                                key_algorithm = "RSA"
                            else:
                                key_algorithm = None
                            # Check if the key can be loaded (used) without passphrase
                            # if key_algorithm is not None and self.is_private_key_unprotected(key_content_encoded,
                            #                                                                    key_algorithm):
                            if key_algorithm:
                                keys.append(key_content_encoded)
                        except Exception as e:
                            log.error("Cannot load key file '%s' '%s'" %
                                      (key_file_path, e))
                            pass

        return keys
Пример #11
0
    def run(self, profile, system=None):
        if profile.get('mkfiles'):
            return profile['mkfiles']
        dpapi = DPAPI()
        if profile.get('sys32'):
            dpapi.masterkeys = {
                **profile['sys32'].get('machine', {}),
                **profile['sys32'].get('user', {})
            }
        if system:
            files = system
        else:
            files = os.path.join(profile['APPDATA'], 'Microsoft', 'Protect',
                                 profile['SID'])
        if not os.path.isdir(files):
            return

        for pwd in profile.get('passwords',
                               []) + [profile.get('password', '')]:
            dpapi.get_prekeys_from_password(profile['SID'],
                                            password=pwd,
                                            nt_hash=None)

        lsa = LsaSecrets().run(profile)
        for x in lsa['logon_sessions']:
            x = lsa['logon_sessions'][x]
            sid = x['sid']
            for dc in x['kerberos_creds']:
                if dc['password'] is not None:
                    dpapi.get_prekeys_from_password(sid,
                                                    password=dc['password'],
                                                    nt_hash=None)
                if dc['pin'] is not None:
                    dpapi.get_prekeys_from_password(sid,
                                                    password='******' %
                                                    dc['pin'],
                                                    nt_hash=None)
            for dc in x['msv_creds']:
                if dc['NThash'] is not None and len(dc['NThash']) == 16:
                    dpapi.get_prekeys_from_password(sid,
                                                    password=None,
                                                    nt_hash=dc['NThash'])
                if dc['SHAHash'] is not None and len(dc['SHAHash']) == 20:
                    dpapi.prekeys[dc['SHAHash']] = 1
            for dc in x['dpapi_creds']:
                dpapi.masterkeys[dc['key_guid']] = dc['masterkey']
            for i in [
                    'wdigest_creds', 'ssp_creds', 'livessp_creds',
                    'credman_creds', 'tspkg_creds'
            ]:
                for dc in x[i]:
                    if dc['password'] is not None:
                        dpapi.get_prekeys_from_password(
                            sid, password=dc['password'], nt_hash=None)
            for dc in x['cloudap_creds']:
                dpapi.masterkeys[dc['key_guid']] = dc['dpapi_key']

        reg = RegistrySecrets().run(profile)
        if reg['SECURITY']:
            for secret in reg['SECURITY']['cached_secrets']:
                if secret['type'] == 'LSASecretDPAPI':
                    dpapi.prekeys[secret['user_key']] = 1
                    dpapi.prekeys[secret['machine_key']] = 1

        if reg['SAM']:
            for secret in reg['SAM']['local_users']:
                if secret['nt_hash']:
                    sid = '%s-%s' % (reg['SAM']['machine_sid'], secret['rid'])
                    dpapi.get_prekeys_from_password(sid,
                                                    nt_hash=secret['nt_hash'])

        list_files = os.listdir(files)
        preferred_guid = None
        if 'Preferred' in list_files:
            list_files.remove('Preferred')
            with open(os.path.join(files, 'Preferred'), 'rb') as pfile:
                GUID1 = pfile.read(8)
                GUID2 = pfile.read(8)

            GUID = struct.unpack("<LHH", GUID1)
            GUID2 = struct.unpack(">HLH", GUID2)
            preferred_guid = f"{GUID[0]:08x}-{GUID[1]:04x}-{GUID[2]:04x}-{GUID2[0]:04x}-{GUID2[1]:08x}{GUID2[2]:04x}"
            if preferred_guid in list_files:
                with open(os.path.join(files, preferred_guid), 'rb') as pfile:
                    profile['extra']['PreferredRaw'] = pfile.read()

        for file in list_files:
            if file.lower() in dpapi.masterkeys or not os.path.isfile(
                    os.path.join(files, file)):
                continue
            try:
                dpapi.decrypt_masterkey_file(os.path.join(files, file))
            except Exception:
                log.error(traceback.format_exc())
        return dpapi.masterkeys
Пример #12
0
    def run(self, profile):
        """
        Main function:

        - For encrypted password, provides the encrypted version of the password with the master password in order
        to allow "LaZagne run initiator" the use the encryption parameter associated with the version of Maven because
        encryption parameters can change between version of Maven.

        - "LaZagne run initiator" can also use the encrypted password and the master password "AS IS"
        in a Maven distribution to access repositories.
        See:
        github.com/jelmerk/maven-settings-decoder
        github.com/sonatype/plexus-cipher/blob/master/src/main/java/org/sonatype/plexus/components/cipher/PBECipher.java
        """

        # Extract the master password
        master_password = None
        master_password_file_location = profile["USERPROFILE"] + u'\\.m2\\settings-security.xml'
        if os.path.isfile(master_password_file_location):
            try:
                config = ElementTree.parse(master_password_file_location).getroot()
                master_password_node = config.find(".//master")
                if master_password_node is not None:
                    master_password = master_password_node.text
            except Exception as e:
                log.error("Cannot retrieve master password '%s'" % e)
                master_password = None

        # Extract all available repositories credentials
        repos_creds = []
        maven_settings_file_location = profile["USERPROFILE"] + '\\.m2\\settings.xml'
        if os.path.isfile(maven_settings_file_location):
            try:
                settings = ElementTree.parse(maven_settings_file_location).getroot()
                server_nodes = settings.findall(".//%sserver" % "{http://maven.apache.org/SETTINGS/1.0.0}")
                for server_node in server_nodes:
                    creds = {}
                    for child_node in server_node:
                        tag_name = child_node.tag.replace("{http://maven.apache.org/SETTINGS/1.0.0}", "")
                        if tag_name in ["id", "username", "password", "privateKey", "passphrase"]:
                            creds[tag_name] = child_node.text.strip()
                    if len(creds) > 0:
                        repos_creds.append(creds)
            except Exception as e:
                log.error("Cannot retrieve repositories credentials '%s'" % e)

        # Parse and process the list of repositories's credentials
        # 3 cases are handled:
        # => Authentication using password protected with the master password (encrypted)
        # => Authentication using password not protected with the master password (plain text)
        # => Authentication using private key
        pwd_found = []
        for creds in repos_creds:
            values = {"Id": creds["id"], "Login": creds["username"]}
            if "privateKey" in creds:
                pk_file_location = creds["privateKey"]
                pk_file_location = pk_file_location.replace("${user.home}", profile["USERPROFILE"])
                if not os.path.isfile(pk_file_location):
                    pwd = creds["password"].strip()
                    # Case for authentication using password protected with the master password
                    if pwd.startswith("{") and pwd.endswith("}"):
                        values["SymetricEncryptionKey"] = master_password
                        values["PasswordEncrypted"] = pwd
                    else:
                        values["Password"] = pwd
                else:
                    # Case for authentication using private key
                    pk_file_location = creds["privateKey"]
                    pk_file_location = pk_file_location.replace("${user.home}", profile["USERPROFILE"])
                    with open(pk_file_location, "r") as pk_file:
                        values["PrivateKey"] = pk_file.read()
                    if "passphrase" in creds:
                        values["Passphrase"] = creds["passphrase"]
            pwd_found.append(values)

        return pwd_found