1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Code based from these two awesome projects:
- DPAPICK : https://bitbucket.org/jmichel/dpapick
- DPAPILAB : https://github.com/dfirfpi/dpapilab
"""
from .blob import DPAPIBlob
from .eater import DataStruct
class CredentialDecryptedHeader(DataStruct):
"""
Header of the structure returned once the blob has been decrypted
Header of the CredentialDecrypted class
"""
def __init__(self, raw=None):
self.total_size = None
self.unknown1 = None
self.unknown2 = None
self.unknown3 = None
self.last_update = None
self.unknown4 = None
self.unk_type = None
self.unk_blocks = None
self.unknown5 = None
self.unknown6 = None
DataStruct.__init__(self, raw)
def parse(self, data):
self.total_size = data.eat("L")
self.unknown1 = data.eat("L")
self.unknown2 = data.eat("L")
self.unknown3 = data.eat("L")
self.last_update = data.eat("Q")
self.unknown4 = data.eat("L")
self.unk_type = data.eat("L")
self.unk_blocks = data.eat("L")
self.unknown5 = data.eat("L")
self.unknown6 = data.eat("L")
class CredentialDecrypted(DataStruct):
"""
Structure returned once the blob has been decrypted
"""
def __init__(self, raw=None):
self.header_size = None
self.header = None
self.domain = None
self.unk_string1 = None
self.unk_string2 = None
self.unk_string3 = None
self.username = None
self.password = None
DataStruct.__init__(self, raw)
def parse(self, data):
self.header_size = data.eat("L")
if self.header_size > 0:
self.header = CredentialDecryptedHeader()
self.header.parse(data.eat_sub(self.header_size - 4))
self.domain = data.eat_length_and_string("L").decode("UTF-16LE").encode("utf-8") # Unicode
self.unk_string1 = data.eat_length_and_string("L").decode("UTF-16LE").encode("utf-8") # Unicode
self.unk_string2 = data.eat_length_and_string("L").decode("UTF-16LE").encode("utf-8") # Unicode
self.unk_string3 = data.eat_length_and_string("L").decode("UTF-16LE").encode("utf-8") # Unicode
self.username = data.eat_length_and_string("L").decode("UTF-16LE").encode("utf-8") # Unicode
self.password = data.eat_length_and_string("L").decode("UTF-16LE").encode("utf-8") # Unicode
class CredFile(DataStruct):
"""
Decrypt Credentials Files stored on ...\\Microsoft\\Credentials\\...
"""
def __init__(self, raw=None):
self.unknown1 = None
self.blob_size = None
self.unknown2 = None
self.blob = None
DataStruct.__init__(self, raw)
def parse(self, data):
self.unknown1 = data.eat("L")
self.blob_size = data.eat("L")
self.unknown2 = data.eat("L")
if self.blob_size > 0:
self.blob = DPAPIBlob()
self.blob.parse(data.eat_sub(self.blob_size))
def decrypt(self, mkp, credfile):
ok, msg = self.blob.decrypt_encrypted_blob(mkp=mkp)
if ok:
cred_dec = CredentialDecrypted(msg)
if cred_dec.header.unk_type == 3:
return True, {
'File': credfile,
'Domain': cred_dec.domain,
'Username': cred_dec.username,
'Password': cred_dec.password,
}
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)
else:
return ok, msg
|