1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 """
22 @author: Brendan Dolan-Gavitt
23 @license: GNU General Public License 2.0 or later
24 @contact: bdolangavitt@wesleyan.edu
25
26 http://moyix.blogspot.com/2008/02/decrypting-lsa-secrets.html
27
28 Code seems to be inspired by eyas_at_xfocus.org
29 http://www.xfocus.net/articles/200411/749.html
30 """
31 import struct
32
33 from rekall import obj
34 from Crypto.Hash import MD5
35 from Crypto.Hash import MD4
36 from Crypto.Cipher import DES
37 from Crypto.Cipher import ARC4
38
39
40 odd_parity = [
41 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
42 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
43 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
44 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
45 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
46 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
47 97, 97, 98, 98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110, 110,
48 112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127, 127,
49 128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140, 143, 143,
50 145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157, 157, 158, 158,
51 161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171, 173, 173, 174, 174,
52 176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191, 191,
53 193, 193, 194, 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206, 206,
54 208, 208, 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223, 223,
55 224, 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239, 239,
56 241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254, 254
57 ]
58
59
60 p = [ 0x8, 0x5, 0x4, 0x2, 0xb, 0x9, 0xd, 0x3,
61 0x0, 0x6, 0x1, 0xc, 0xe, 0xa, 0xf, 0x7 ]
62
63
64 aqwerty = "!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%\0"
65 anum = "0123456789012345678901234567890123456789\0"
66 antpassword = "NTPASSWORD\0"
67 almpassword = "LMPASSWORD\0"
68 lmkey = "KGS!@#$%"
69
70 empty_lm = "aad3b435b51404eeaad3b435b51404ee".decode('hex')
71 empty_nt = "31d6cfe0d16ae931b73c59d7e0c089c0".decode('hex')
72
74 key = []
75 key.append(ord(s[0]) >> 1)
76 key.append(((ord(s[0]) & 0x01) << 6) | (ord(s[1]) >> 2))
77 key.append(((ord(s[1]) & 0x03) << 5) | (ord(s[2]) >> 3))
78 key.append(((ord(s[2]) & 0x07) << 4) | (ord(s[3]) >> 4))
79 key.append(((ord(s[3]) & 0x0F) << 3) | (ord(s[4]) >> 5))
80 key.append(((ord(s[4]) & 0x1F) << 2) | (ord(s[5]) >> 6))
81 key.append(((ord(s[5]) & 0x3F) << 1) | (ord(s[6]) >> 7))
82 key.append(ord(s[6]) & 0x7F)
83 for i in range(8):
84 key[i] = (key[i] << 1)
85 key[i] = odd_parity[key[i]]
86 return "".join(chr(k) for k in key)
87
89 s1 = ""
90 s1 += chr(sid & 0xFF)
91 s1 += chr((sid >> 8) & 0xFF)
92 s1 += chr((sid >> 16) & 0xFF)
93 s1 += chr((sid >> 24) & 0xFF)
94 s1 += s1[0]
95 s1 += s1[1]
96 s1 += s1[2]
97 s2 = s1[3] + s1[0] + s1[1] + s1[2]
98 s2 += s2[0] + s2[1] + s2[2]
99
100 return str_to_key(s1), str_to_key(s2)
101
103 pw = pw[:14].upper()
104 pw = pw + ('\0' * (14 - len(pw)))
105 d1 = DES.new(str_to_key(pw[:7]), DES.MODE_ECB)
106 d2 = DES.new(str_to_key(pw[7:]), DES.MODE_ECB)
107 return d1.encrypt(lmkey) + d2.encrypt(lmkey)
108
110 return MD4.new(pw.encode('utf-16-le')).digest()
111
113 """Determine which control set we are currently running with."""
114 csselect = sys_registry.open_key("Select")
115 if not csselect:
116 return 1
117
118 value = csselect.open_value("Current")
119 return value.DecodedData
120
122 """Derive the boot key by unscrambling the LSA."""
123 cs = find_control_set(sys_registry)
124 bootkey = ""
125 lsa_base = ["ControlSet{0:03}".format(cs), "Control", "Lsa"]
126 lsa_keys = ["JD", "Skew1", "GBG", "Data"]
127
128 lsa = sys_registry.open_key(lsa_base)
129
130 for lk in lsa_keys:
131 subkey = lsa.open_subkey(lk)
132 bootkey_data = subkey.Class.dereference_as("UnicodeString",
133 length=subkey.ClassLength)
134
135 bootkey += bootkey_data.v().decode('hex')
136
137 bootkey_scrambled = ""
138 for i in range(len(bootkey)):
139 bootkey_scrambled += bootkey[p[i]]
140
141 return bootkey_scrambled
142
144 sam_account_path = ["SAM", "Domains", "Account"]
145
146 sam_account_key = sam_registry.open_key(sam_account_path)
147
148
149 F = sam_account_key.open_value("F").DecodedData
150 if not F:
151 return F
152
153 md5 = MD5.new()
154 md5.update(F[0x70:0x80] + aqwerty + bootkey + anum)
155 rc4_key = md5.digest()
156
157 rc4 = ARC4.new(rc4_key)
158 hbootkey = rc4.encrypt(F[0x80:0xA0])
159
160 return hbootkey
161
163 user_key_path = ["SAM", "Domains", "Account", "Users"]
164
165 user_key = sam_registry.open_key(user_key_path)
166
167 for k in user_key.subkeys():
168 if k.Name != "Names":
169 yield k
170
172 (des_k1, des_k2) = sid_to_key(rid)
173 d1 = DES.new(des_k1, DES.MODE_ECB)
174 d2 = DES.new(des_k2, DES.MODE_ECB)
175
176 md5 = MD5.new()
177 md5.update(hbootkey[:0x10] + struct.pack("<L", rid) + lmntstr)
178 rc4_key = md5.digest()
179 rc4 = ARC4.new(rc4_key)
180 obfkey = rc4.encrypt(enc_hash)
181 hash = d1.decrypt(obfkey[:8]) + d2.decrypt(obfkey[8:])
182
183 return hash
184
199
201 (des_k1, des_k2) = sid_to_key(rid)
202 d1 = DES.new(des_k1, DES.MODE_ECB)
203 d2 = DES.new(des_k2, DES.MODE_ECB)
204
205 enc_hash = d1.encrypt(hash[:8]) + d2.encrypt(hash[8:])
206
207 md5 = MD5.new()
208 md5.update(hbootkey[:0x10] + struct.pack("<L", rid) + lmntstr)
209 rc4_key = md5.digest()
210 rc4 = ARC4.new(rc4_key)
211 obfkey = rc4.encrypt(enc_hash)
212
213 return obfkey
214
229
231 rid = int(str(user_key.Name), 16)
232
233 V = user_key.open_value("V").DecodedData
234
235 lm_offset = struct.unpack("<L", V[0x9c:0xa0])[0] + 0xCC + 4
236 lm_len = struct.unpack("<L", V[0xa0:0xa4])[0] - 4
237 nt_offset = struct.unpack("<L", V[0xa8:0xac])[0] + 0xCC + 4
238 nt_len = struct.unpack("<L", V[0xac:0xb0])[0] - 4
239
240 if lm_len:
241 enc_lm_hash = V[lm_offset:lm_offset + 0x10]
242 else:
243 enc_lm_hash = ""
244
245 if nt_len:
246 enc_nt_hash = V[nt_offset:nt_offset + 0x10]
247 else:
248 enc_nt_hash = ""
249
250 return decrypt_hashes(rid, enc_lm_hash, enc_nt_hash, hbootkey)
251
253 V = user_key.open_value("V").DecodedData
254
255 name_offset = struct.unpack("<L", V[0x0c:0x10])[0] + 0xCC
256 name_length = struct.unpack("<L", V[0x10:0x14])[0]
257
258 username = V[name_offset:name_offset + name_length].decode('utf-16-le')
259
260 return username
261
263 V = user_key.open_value("V").DecodedData
264
265 desc_offset = struct.unpack("<L", V[0x24:0x28])[0] + 0xCC
266 desc_length = struct.unpack("<L", V[0x28:0x2c])[0]
267
268 desc = V[desc_offset:desc_offset + desc_length].decode('utf-16-le')
269
270 return desc
271
287