Esempio n. 1
0
    def get_bootkey(cls, syshive: registry.RegistryHive) -> Optional[bytes]:
        cs = 1
        lsa_base = "ControlSet{0:03}".format(cs) + "\\Control\\Lsa"
        lsa_keys = ["JD", "Skew1", "GBG", "Data"]

        lsa = syshive.get_key(lsa_base)

        if not lsa:
            return None

        bootkey = ''

        for lk in lsa_keys:
            key = syshive.get_key(lsa_base + '\\' + lk)

            class_data = syshive.read(key.Class + 4, key.ClassLength)

            if class_data is None:
                return None
            bootkey += class_data.decode('utf-16-le')

        bootkey_str = binascii.unhexlify(bootkey)
        bootkey_scrambled = bytes([
            bootkey_str[cls.bootkey_perm_table[i]]
            for i in range(len(bootkey_str))
        ])
        return bootkey_scrambled
Esempio n. 2
0
    def get_hbootkey(cls, samhive: registry.RegistryHive, bootkey: bytes) -> Optional[bytes]:
        sam_account_path = "SAM\\Domains\\Account"

        if not bootkey:
            return None

        sam_account_key = cls.get_hive_key(samhive, sam_account_path)
        if not sam_account_key:
            return None

        sam_data = None
        for v in sam_account_key.get_values():
            if v.get_name() == 'F':
                sam_data = samhive.read(v.Data + 4, v.DataLength)
        if not sam_data:
            return None

        revision = sam_data[0x00]
        if revision == 2:
            md5 = hashlib.md5()

            md5.update(sam_data[0x70:0x80] + cls.aqwerty + bootkey + cls.anum)
            rc4_key = md5.digest()

            rc4 = ARC4.new(rc4_key)
            hbootkey = rc4.encrypt(sam_data[0x80:0xA0])
            return hbootkey
        elif revision == 3:
            # AES encrypted
            iv = sam_data[0x78:0x88]
            encryptedHBootKey = sam_data[0x88:0xA8]
            cipher = AES.new(bootkey, AES.MODE_CBC, iv)
            hbootkey = cipher.decrypt(encryptedHBootKey)
            return hbootkey[:16]
        return None
Esempio n. 3
0
 def get_hive_key(cls, hive: registry.RegistryHive, key: str):
     result = None
     try:
         result = hive.get_key(key)
     except KeyError:
         vollog.info(
             "Unable to load the required registry key {}\\{} from this memory image".format(hive.get_name(), key))
     return result
Esempio n. 4
0
    def get_user_keys(
        cls, samhive: registry.RegistryHive
    ) -> List[interfaces.objects.ObjectInterface]:
        user_key_path = "SAM\\Domains\\Account\\Users"

        user_key = samhive.get_key(user_key_path)
        if not user_key:
            return []
        return [k for k in user_key.get_subkeys() if k.Name != "Names"]
Esempio n. 5
0
    def get_user_hashes(cls, user: registry.CM_KEY_NODE,
                        samhive: registry.RegistryHive,
                        hbootkey: bytes) -> Optional[Tuple[bytes, bytes]]:
        ## Will sometimes find extra user with rid = NAMES, returns empty strings right now
        try:
            rid = int(str(user.get_name()), 16)
        except ValueError:
            return None
        sam_data = None
        for v in user.get_values():
            if v.get_name() == 'V':
                sam_data = samhive.read(v.Data + 4, v.DataLength)
        if not sam_data:
            return None

        lm_offset = unpack("<L", sam_data[0x9c:0xa0])[0] + 0xCC
        lm_len = unpack("<L", sam_data[0xa0:0xa4])[0]
        nt_offset = unpack("<L", sam_data[0xa8:0xac])[0] + 0xCC
        nt_len = unpack("<L", sam_data[0xac:0xb0])[0]

        lm_revision = sam_data[lm_offset + 2:lm_offset + 3]
        lmhash = None
        if lm_revision == b'\x01':
            if lm_len == 20:
                enc_lm_hash = sam_data[lm_offset + 0x04:lm_offset + 0x14]
                lmhash = cls.decrypt_single_hash(rid, hbootkey, enc_lm_hash,
                                                 cls.almpassword)
        elif lm_revision == b'\x02':
            if lm_len == 56:
                lm_salt = sam_data[lm_offset + 4:lm_offset + 20]
                enc_lm_hash = sam_data[lm_offset + 20:lm_offset + 52]
                lmhash = cls.decrypt_single_salted_hash(
                    rid, hbootkey, enc_lm_hash, cls.almpassword, lm_salt)

        # NT hash decryption
        nthash = None
        nt_revision = sam_data[nt_offset + 2:nt_offset + 3]
        if nt_revision == b'\x01':
            if nt_len == 20:
                enc_nt_hash = sam_data[nt_offset + 4:nt_offset + 20]
                nthash = cls.decrypt_single_hash(rid, hbootkey, enc_nt_hash,
                                                 cls.antpassword)
        elif nt_revision == b'\x02':
            if nt_len == 56:
                nt_salt = sam_data[nt_offset + 8:nt_offset + 24]
                enc_nt_hash = sam_data[nt_offset + 24:nt_offset + 56]
                nthash = cls.decrypt_single_salted_hash(
                    rid, hbootkey, enc_nt_hash, cls.antpassword, nt_salt)
        return lmhash, nthash
Esempio n. 6
0
    def get_user_name(cls, user: registry.CM_KEY_NODE, samhive: registry.RegistryHive) -> Optional[bytes]:
        value = None
        for v in user.get_values():
            if v.get_name() == 'V':
                value = samhive.read(v.Data + 4, v.DataLength)
        if not value:
            return None

        name_offset = unpack("<L", value[0x0c:0x10])[0] + 0xCC
        name_length = unpack("<L", value[0x10:0x14])[0]
        if name_length > len(value):
            return None

        username = value[name_offset:name_offset + name_length]
        return username
Esempio n. 7
0
    def get_user_name(cls, user: interfaces.objects.ObjectInterface,
                      samhive: registry.RegistryHive) -> Optional[bytes]:
        V = None
        for v in user.get_values():
            if v.get_name() == 'V':
                V = samhive.read(v.Data + 4, v.DataLength)
        if not V:
            return None

        name_offset = unpack("<L", V[0x0c:0x10])[0] + 0xCC
        name_length = unpack("<L", V[0x10:0x14])[0]
        if name_length > len(V):
            return None

        username = V[name_offset:name_offset + name_length]
        return username