-
Notifications
You must be signed in to change notification settings - Fork 2
/
parse_master_key_file.go
180 lines (149 loc) · 4.69 KB
/
parse_master_key_file.go
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package masterkey
import (
"bytes"
"encoding/binary"
)
type MasterKeyFile struct {
Header Header
MasterKey MasterKey
BackupKey BackupKey
CredHist CredHist
DomainKey DomainKey
Decrypted bool
Guid []byte
Key []byte
}
type Header struct {
Version uint32
Guid []byte
Policy uint32
MasterKeyLen uint64
BackupKeyLen uint64
CredHistLen uint64
DomainKeyLen uint64
}
type MasterKey struct {
Version uint32
Salt [16]byte
Rounds uint32
AlgHash uint32
AlgCrypt uint32
PbKey []byte
// Store result data
Decrypted bool
Key []byte
KeyHash []byte
HmacSalt []byte
Hmac []byte
HmacComputed []byte
}
type BackupKey MasterKey
type CredHist struct {
Version uint32
Guid [16]byte
}
type DomainKey struct {
Version uint32
SecretLen uint32
AccessCheckLen uint32
GuidKey []byte
EncryptedSecret []byte
AccessCheck []byte
// Store result data
Decrypted bool
Key []byte
}
// Read DPAPI master key file into structure.
func parseMasterKeyFileData(blobData []byte) MasterKeyFile {
var skip = 0
var masterKeyFile MasterKeyFile
// Parse header
masterKeyFile.Header = readHeader(blobData)
skip += 128
// Parse masterKey
masterKeyLen := int(masterKeyFile.Header.MasterKeyLen)
if masterKeyLen > 0 {
masterKeyFile.MasterKey = readMasterKey(blobData[skip:], masterKeyLen)
skip += masterKeyLen
}
// Parse masterKey
backupKeyLen := int(masterKeyFile.Header.BackupKeyLen)
if backupKeyLen > 0 {
masterKeyFile.BackupKey = readBackupKey(blobData[skip:], backupKeyLen)
skip += backupKeyLen
}
// Parse credHistLen
credHistLen := int(masterKeyFile.Header.CredHistLen)
if credHistLen > 0 {
masterKeyFile.CredHist = readCredHist(blobData[skip:], credHistLen)
skip += credHistLen
}
// Parse domainKey
domainKeyLen := int(masterKeyFile.Header.DomainKeyLen)
if domainKeyLen > 0 {
masterKeyFile.DomainKey = readDomainKey(blobData[skip:], domainKeyLen)
skip += domainKeyLen
}
return masterKeyFile
}
func readHeader(data []byte) Header {
var header Header
reader := bytes.NewReader(data)
var Q uint64
binary.Read(reader, binary.LittleEndian, &header.Version)
binary.Read(reader, binary.LittleEndian, &Q)
header.Guid = make([]byte, 72)
binary.Read(reader, binary.LittleEndian, &header.Guid)
binary.Read(reader, binary.LittleEndian, &Q)
binary.Read(reader, binary.LittleEndian, &header.Policy)
binary.Read(reader, binary.LittleEndian, &header.MasterKeyLen)
binary.Read(reader, binary.LittleEndian, &header.BackupKeyLen)
binary.Read(reader, binary.LittleEndian, &header.CredHistLen)
binary.Read(reader, binary.LittleEndian, &header.DomainKeyLen)
return header
}
func readMasterKey(data []byte, masterKeyLen int) MasterKey {
var masterKey MasterKey
reader := bytes.NewReader(data)
binary.Read(reader, binary.LittleEndian, &masterKey.Version)
binary.Read(reader, binary.LittleEndian, &masterKey.Salt)
binary.Read(reader, binary.LittleEndian, &masterKey.Rounds)
binary.Read(reader, binary.LittleEndian, &masterKey.AlgHash)
binary.Read(reader, binary.LittleEndian, &masterKey.AlgCrypt)
masterKey.PbKey = make([]byte, masterKeyLen-32)
binary.Read(reader, binary.LittleEndian, &masterKey.PbKey)
return masterKey
}
func readBackupKey(data []byte, backupKeyLen int) BackupKey {
var backupKey BackupKey
reader := bytes.NewReader(data)
binary.Read(reader, binary.LittleEndian, &backupKey.Version)
binary.Read(reader, binary.LittleEndian, &backupKey.Salt)
binary.Read(reader, binary.LittleEndian, &backupKey.Rounds)
binary.Read(reader, binary.LittleEndian, &backupKey.AlgHash)
binary.Read(reader, binary.LittleEndian, &backupKey.AlgCrypt)
backupKey.PbKey = make([]byte, backupKeyLen-32)
binary.Read(reader, binary.LittleEndian, &backupKey.PbKey)
return backupKey
}
func readCredHist(data []byte, backupKeyLen int) CredHist {
var credHist CredHist
reader := bytes.NewReader(data)
binary.Read(reader, binary.LittleEndian, &credHist.Version)
binary.Read(reader, binary.LittleEndian, &credHist.Guid)
return credHist
}
func readDomainKey(data []byte, domainKeyLen int) DomainKey {
var domainKey DomainKey
reader := bytes.NewReader(data)
binary.Read(reader, binary.LittleEndian, &domainKey.Version)
binary.Read(reader, binary.LittleEndian, &domainKey.SecretLen)
binary.Read(reader, binary.LittleEndian, &domainKey.AccessCheckLen)
domainKey.GuidKey = make([]byte, 16)
binary.Read(reader, binary.LittleEndian, &domainKey.GuidKey)
domainKey.EncryptedSecret = make([]byte, domainKey.SecretLen)
binary.Read(reader, binary.LittleEndian, &domainKey.EncryptedSecret)
domainKey.AccessCheck = make([]byte, domainKey.AccessCheckLen)
binary.Read(reader, binary.LittleEndian, &domainKey.AccessCheck)
return domainKey
}