def preprocess(self, **k): self.login = k.get("login", None) entrop = [0x69f31ea3, 0x1fd96207, 0x7d35e91e, 0x487dd24f] seed = 0xba0da71d maxint = 0xffffffff # Compute entropy arr = array.array('B') arr.fromstring(k["username"] + k["computername"]) for i, v in enumerate(arr): entrop[i & 3] ^= (seed * v) & maxint seed = (seed * 0xbc8f) & maxint self.entropy = "".join( map(lambda y: struct.pack("<L", y & maxint), entrop)) # Decode & extract blob v = entrop[0] | 1 arr = array.array('B') for i in range(4, len(self.raw), 2): a = (((ord(self.raw[i]) - 0x21) << 4) & 0xf0) | ( (ord(self.raw[i + 1]) - 0x21) & 0x0f) arr.append((a - (v & 0xff)) % 256) v = (v * 0x0ff5) & maxint self.dpapiblob = blob.DPAPIBlob(arr.tostring())
def parse(self, data): """Parses raw data into structured data. Automatically called by __init__. You should not call it manually. data is a DataStruct object. """ self.dpapiblob = blob.DPAPIBlob(data.remain())
def decrypt_credential_block(mkp, credential_block): """Helper to decrypt credential block.""" sblob_raw = ''.join(b.raw_data for b in credential_block.CREDENTIAL_DEC_BLOCK_ENC) sblob = blob.DPAPIBlob(sblob_raw) return decrypt_blob(mkp, sblob)
def preprocess(self, **k): self.entropy = self.APPLE_ENTROPY with open(k["aoskit"], "rb") as f: plist = CFPropertyList.CFPropertyList(f) plist.load() plist_values = CFPropertyList.native_types(plist.value) self.account = plist_values.keys()[0] plist_data_dict = plist_values[self.account] self.dpapiblob = blob.DPAPIBlob(plist_data_dict['data'])
def parse(self, data): self.crc_ok = False self.user_key = None self.dbx_key = None data.pop('B') self.crc = data.pop_string(self.V0_CRC_LEN) self.raw = data.remain() self.version, dpapi_len = data.eat('LL') self.dpapiblob = blob.DPAPIBlob(data.eat_string(dpapi_len))
def decrypt_wifi_blob(self, key_material): if self.smkp: wblob = blob.DPAPIBlob(key_material.decode('hex')) mks = self.smkp.getMasterKeys(wblob.mkguid) for mk in mks: if mk.decrypted: wblob.decrypt(mk.get_key()) if wblob.decrypted: return wblob.cleartext return '<not decrypted>'
def parse(self, data): tmp = data.read("L") d = data if tmp == 0: # Windows 7 data.read("L") self.credtype = data.eat("L") data.eat("L") else: # Windows XP d = data.eat_sub(tmp) d.eat("2L") self.credtype = d.eat("L") self.timestamp = d.eat("Q") # timestamp 64bits if self.timestamp > 0: self.timestamp /= 10000000 self.timestamp -= 11644473600 d.eat("L") self.persist = d.eat("L") d.eat("3L") # NULL self.name = d.eat_length_and_string("L").decode("UTF-16LE") self.comment = d.eat_length_and_string("L").decode("UTF-16LE") self.alias = d.eat_length_and_string("L").decode("UTF-16LE") if tmp == 0: # windows 7 d.eat_length_and_string("L") self.username = d.eat_length_and_string("L").decode("UTF-16LE") self.password = None if self.credtype == 1 or self.credtype == 4: self.dpapiblob = blob.DPAPIBlob(d.eat_length_and_string("L")) elif self.credtype == 2: # domain password self.password = d.eat_length_and_string("L") self.password = self.password.decode('UTF-16LE') self.dpapiblob = None elif self.credtype == 3: # domain certificate self.password = d.eat_length_and_string("L") self.dpapiblob = None self.entropy = self._entropy.get(self.credtype) if self.entropy is not None: s = "" for c in self.entropy: s += struct.pack("<h", ord(c) << 2) self.entropy = s
def decrypt_encrypted_blob(mkp, encrypted_password, entropy_hex=None): blob_value = blob.DPAPIBlob(encrypted_password) mks = mkp.getMasterKeys(blob_value.mkguid) if not mks: return False, 'Unable to find MK for blob {mk_guid}'.format(mk_guid=blob_value.mkguid) entropy = None if entropy_hex: entropy = entropy_hex.decode('hex') for mk in mks: if mk.decrypted: blob_value.decrypt(mk.get_key(), entropy=entropy) if blob_value.decrypted: return True, blob_value.cleartext else: return False, 'Unable to decrypt blob' else: return False, 'Unable to decrypt master key'
def preprocess(self, **k): s = [] if k.get('file'): f = open(k['file'], "r") s = f.read().split("\n") f.close() elif k.get('content'): s = k['content'].split("\n") for l in s: (n, t, v) = l.split(":", 3) v = v.rstrip() if t == 'i': v = int(v) elif t == 'b': if len(v) & 1 == 1: # if odd length, strip the last quartet which should be a # useless "0" v = v[:-1] v = v.decode('hex') self.values[n] = v if self.values['password 51']: self.dpapiblob = blob.DPAPIBlob(self.values['password 51'])
def decrypt_user_cred(umkp=None, cred_file=None): dec_cred = None res_err = None with open(cred_file, 'rb') as fin: enc_cred = vaultstruct.CREDENTIAL_FILE.parse(fin.read()) cred_blob = blob.DPAPIBlob(enc_cred.data.raw) if umkp: dec_cred, res_err = decrypt_blob(umkp, cred_blob) if not dec_cred: return False, helper_dec_err(res_err) cred_dec = vaultstruct.CREDENTIAL_DECRYPTED.parse(dec_cred) if cred_dec.header.unk_type == 3: return True, { 'File': '{file}'.format(file=cred_file), 'Domain': '{domain}'.format(domain=cred_dec.main.domain.data), 'Username': '******'.format(username=cred_dec.main.username.data), 'Password': '******'.format(password=cred_dec.main.password.data), } # system type elif cred_dec.header.unk_type == 2: return False, 'System credential type' else: return False, 'Unknown CREDENTIAL type, please report.\nCreds: {creds}'.format( creds=cred_dec)
def parse(self, data): self.login = None self.cleartext = None self.dpapiblob = blob.DPAPIBlob(data.remain()) self.entropy = None
def parse(self, data): self.dpapiblob = blob.DPAPIBlob(data.remain()) self.cleartext = None self.login = None self.password = None self.other = []
def parse(self, data): self.dpapiblob = blob.DPAPIBlob(data.remain()) self.store = None
def decrypt_vault(mkp=None, vaults_dir=None): vpol_filename = os.path.join(os.path.sep, vaults_dir, 'Policy.vpol') if not os.path.exists(vpol_filename): return False, 'Policy file not found: {file}'.format(file=vpol_filename) with open(vpol_filename, 'rb') as fin: vpol = vaultstruct.VAULT_POL.parse(fin.read()) vpol_blob = blob.DPAPIBlob(vpol.vpol_store.blob_store.raw) ok, vpol_decrypted = decrypt_blob(mkp, vpol_blob) if not ok: return False, 'Unable to decrypt blob. {message}'.format(message=vpol_decrypted) vpol_keys = vaultstruct.VAULT_POL_KEYS.parse(vpol_decrypted) key_aes128 = vpol_keys.vpol_key1.bcrypt_blob.key key_aes256 = vpol_keys.vpol_key2.bcrypt_blob.key pwdFound = [] for file in os.listdir(vaults_dir): if file.lower().endswith('.vcrd'): filepath = os.path.join(vaults_dir, file) attributes_data = {} with open(filepath, 'rb') as fin: vcrd = vaultstruct.VAULT_VCRD.parse(fin.read()) current_vault_schema = get_vault_schema( vcrd.schema_guid, vaults_dir, vaultschema.VAULT_SCHEMA_GENERIC) for attribute in vcrd.attributes: decrypted, is_attribute_ex = decrypt_vault_attribute(attribute.VAULT_ATTRIBUTE, key_aes128, key_aes256) if is_attribute_ex: schema = current_vault_schema else: schema = vaultschema.VAULT_SCHEMA_SIMPLE attributes_data[attribute.VAULT_ATTRIBUTE.id] = { 'data': decrypted, 'schema': schema } attributes_data[0xDEAD0000 + vcrd.extra_entry.id] = { 'data': str(vcrd.extra_entry.data), 'schema': vaultschema.VAULT_SCHEMA_SIMPLE } # parse value found for k, v in sorted(attributes_data.iteritems()): dataout = v['schema'].parse(v['data']) creds_tuple = [] if 'Container' in str(type(dataout)): for item in dataout['VAULT_ATTRIBUTE_ITEM']: if item['id'] != 100: creds_tuple.append((item['id'], item['item']['data'])) creds = sorted(creds_tuple, key=lambda creds: creds[0]) if creds: values = {} if len(creds) == 3: values = { 'URL' : creds[0][1], 'Login' : creds[1][1], 'Password' : creds[2][1], 'File' : filepath, } else: for cred in creds: values['Item_{id}'.format(id=cred[0])] = cred[1] values['File'] = filepath pwdFound.append(values) return True, pwdFound
def parse(self, data): self.dpapiblob = blob.DPAPIBlob(data.remain()) self.cleartext = None
def parse(self, data): l = data.eat("L") - 4 self.wifiStruct = WirelessInfo.WifiStruct(data.eat("%us" % l)) self.dpapiblob = blob.DPAPIBlob(data.remain())