1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 '''Windows NT 5.1 and 5.2 LsaEncryptMemory decryption algorithm.'''
21
22 import struct
23
24
26 '''NT 5.1 and NT 5.2 lsasrv.dll DES decryption 32 bits implementation.'''
27
28 sboxul = [
29 [0x02080800, 0x00080000, 0x02000002, 0x02080802,
30 0x02000000, 0x00080802, 0x00080002, 0x02000002,
31 0x00080802, 0x02080800, 0x02080000, 0x00000802,
32 0x02000802, 0x02000000, 0x00000000, 0x00080002,
33 0x00080000, 0x00000002, 0x02000800, 0x00080800,
34 0x02080802, 0x02080000, 0x00000802, 0x02000800,
35 0x00000002, 0x00000800, 0x00080800, 0x02080002,
36 0x00000800, 0x02000802, 0x02080002, 0x00000000,
37 0x00000000, 0x02080802, 0x02000800, 0x00080002,
38 0x02080800, 0x00080000, 0x00000802, 0x02000800,
39 0x02080002, 0x00000800, 0x00080800, 0x02000002,
40 0x00080802, 0x00000002, 0x02000002, 0x02080000,
41 0x02080802, 0x00080800, 0x02080000, 0x02000802,
42 0x02000000, 0x00000802, 0x00080002, 0x00000000,
43 0x00080000, 0x02000000, 0x02000802, 0x02080800,
44 0x00000002, 0x02080002, 0x00000800, 0x00080802],
45
46 [0x40108010, 0x00000000, 0x00108000, 0x40100000,
47 0x40000010, 0x00008010, 0x40008000, 0x00108000,
48 0x00008000, 0x40100010, 0x00000010, 0x40008000,
49 0x00100010, 0x40108000, 0x40100000, 0x00000010,
50 0x00100000, 0x40008010, 0x40100010, 0x00008000,
51 0x00108010, 0x40000000, 0x00000000, 0x00100010,
52 0x40008010, 0x00108010, 0x40108000, 0x40000010,
53 0x40000000, 0x00100000, 0x00008010, 0x40108010,
54 0x00100010, 0x40108000, 0x40008000, 0x00108010,
55 0x40108010, 0x00100010, 0x40000010, 0x00000000,
56 0x40000000, 0x00008010, 0x00100000, 0x40100010,
57 0x00008000, 0x40000000, 0x00108010, 0x40008010,
58 0x40108000, 0x00008000, 0x00000000, 0x40000010,
59 0x00000010, 0x40108010, 0x00108000, 0x40100000,
60 0x40100010, 0x00100000, 0x00008010, 0x40008000,
61 0x40008010, 0x00000010, 0x40100000, 0x00108000],
62
63 [0x04000001, 0x04040100, 0x00000100, 0x04000101,
64 0x00040001, 0x04000000, 0x04000101, 0x00040100,
65 0x04000100, 0x00040000, 0x04040000, 0x00000001,
66 0x04040101, 0x00000101, 0x00000001, 0x04040001,
67 0x00000000, 0x00040001, 0x04040100, 0x00000100,
68 0x00000101, 0x04040101, 0x00040000, 0x04000001,
69 0x04040001, 0x04000100, 0x00040101, 0x04040000,
70 0x00040100, 0x00000000, 0x04000000, 0x00040101,
71 0x04040100, 0x00000100, 0x00000001, 0x00040000,
72 0x00000101, 0x00040001, 0x04040000, 0x04000101,
73 0x00000000, 0x04040100, 0x00040100, 0x04040001,
74 0x00040001, 0x04000000, 0x04040101, 0x00000001,
75 0x00040101, 0x04000001, 0x04000000, 0x04040101,
76 0x00040000, 0x04000100, 0x04000101, 0x00040100,
77 0x04000100, 0x00000000, 0x04040001, 0x00000101,
78 0x04000001, 0x00040101, 0x00000100, 0x04040000],
79
80 [0x00401008, 0x10001000, 0x00000008, 0x10401008,
81 0x00000000, 0x10400000, 0x10001008, 0x00400008,
82 0x10401000, 0x10000008, 0x10000000, 0x00001008,
83 0x10000008, 0x00401008, 0x00400000, 0x10000000,
84 0x10400008, 0x00401000, 0x00001000, 0x00000008,
85 0x00401000, 0x10001008, 0x10400000, 0x00001000,
86 0x00001008, 0x00000000, 0x00400008, 0x10401000,
87 0x10001000, 0x10400008, 0x10401008, 0x00400000,
88 0x10400008, 0x00001008, 0x00400000, 0x10000008,
89 0x00401000, 0x10001000, 0x00000008, 0x10400000,
90 0x10001008, 0x00000000, 0x00001000, 0x00400008,
91 0x00000000, 0x10400008, 0x10401000, 0x00001000,
92 0x10000000, 0x10401008, 0x00401008, 0x00400000,
93 0x10401008, 0x00000008, 0x10001000, 0x00401008,
94 0x00400008, 0x00401000, 0x10400000, 0x10001008,
95 0x00001008, 0x10000000, 0x10000008, 0x10401000],
96
97 [0x08000000, 0x00010000, 0x00000400, 0x08010420,
98 0x08010020, 0x08000400, 0x00010420, 0x08010000,
99 0x00010000, 0x00000020, 0x08000020, 0x00010400,
100 0x08000420, 0x08010020, 0x08010400, 0x00000000,
101 0x00010400, 0x08000000, 0x00010020, 0x00000420,
102 0x08000400, 0x00010420, 0x00000000, 0x08000020,
103 0x00000020, 0x08000420, 0x08010420, 0x00010020,
104 0x08010000, 0x00000400, 0x00000420, 0x08010400,
105 0x08010400, 0x08000420, 0x00010020, 0x08010000,
106 0x00010000, 0x00000020, 0x08000020, 0x08000400,
107 0x08000000, 0x00010400, 0x08010420, 0x00000000,
108 0x00010420, 0x08000000, 0x00000400, 0x00010020,
109 0x08000420, 0x00000400, 0x00000000, 0x08010420,
110 0x08010020, 0x08010400, 0x00000420, 0x00010000,
111 0x00010400, 0x08010020, 0x08000400, 0x00000420,
112 0x00000020, 0x00010420, 0x08010000, 0x08000020],
113
114 [0x80000040, 0x00200040, 0x00000000, 0x80202000,
115 0x00200040, 0x00002000, 0x80002040, 0x00200000,
116 0x00002040, 0x80202040, 0x00202000, 0x80000000,
117 0x80002000, 0x80000040, 0x80200000, 0x00202040,
118 0x00200000, 0x80002040, 0x80200040, 0x00000000,
119 0x00002000, 0x00000040, 0x80202000, 0x80200040,
120 0x80202040, 0x80200000, 0x80000000, 0x00002040,
121 0x00000040, 0x00202000, 0x00202040, 0x80002000,
122 0x00002040, 0x80000000, 0x80002000, 0x00202040,
123 0x80202000, 0x00200040, 0x00000000, 0x80002000,
124 0x80000000, 0x00002000, 0x80200040, 0x00200000,
125 0x00200040, 0x80202040, 0x00202000, 0x00000040,
126 0x80202040, 0x00202000, 0x00200000, 0x80002040,
127 0x80000040, 0x80200000, 0x00202040, 0x00000000,
128 0x00002000, 0x80000040, 0x80002040, 0x80202000,
129 0x80200000, 0x00002040, 0x00000040, 0x80200040],
130
131 [0x00004000, 0x00000200, 0x01000200, 0x01000004,
132 0x01004204, 0x00004004, 0x00004200, 0x00000000,
133 0x01000000, 0x01000204, 0x00000204, 0x01004000,
134 0x00000004, 0x01004200, 0x01004000, 0x00000204,
135 0x01000204, 0x00004000, 0x00004004, 0x01004204,
136 0x00000000, 0x01000200, 0x01000004, 0x00004200,
137 0x01004004, 0x00004204, 0x01004200, 0x00000004,
138 0x00004204, 0x01004004, 0x00000200, 0x01000000,
139 0x00004204, 0x01004000, 0x01004004, 0x00000204,
140 0x00004000, 0x00000200, 0x01000000, 0x01004004,
141 0x01000204, 0x00004204, 0x00004200, 0x00000000,
142 0x00000200, 0x01000004, 0x00000004, 0x01000200,
143 0x00000000, 0x01000204, 0x01000200, 0x00004200,
144 0x00000204, 0x00004000, 0x01004204, 0x01000000,
145 0x01004200, 0x00000004, 0x00004004, 0x01004204,
146 0x01000004, 0x01004200, 0x01004000, 0x00004004],
147
148 [0x20800080, 0x20820000, 0x00020080, 0x00000000,
149 0x20020000, 0x00800080, 0x20800000, 0x20820080,
150 0x00000080, 0x20000000, 0x00820000, 0x00020080,
151 0x00820080, 0x20020080, 0x20000080, 0x20800000,
152 0x00020000, 0x00820080, 0x00800080, 0x20020000,
153 0x20820080, 0x20000080, 0x00000000, 0x00820000,
154 0x20000000, 0x00800000, 0x20020080, 0x20800080,
155 0x00800000, 0x00020000, 0x20820000, 0x00000080,
156 0x00800000, 0x00020000, 0x20000080, 0x20820080,
157 0x00020080, 0x20000000, 0x00000000, 0x00820000,
158 0x20800080, 0x20020080, 0x20020000, 0x00800080,
159 0x20820000, 0x00000080, 0x00800080, 0x20020000,
160 0x20820080, 0x00800000, 0x20800000, 0x20000080,
161 0x00820000, 0x00020080, 0x20020080, 0x20800000,
162 0x00000080, 0x20820000, 0x00820080, 0x00000000,
163 0x20000000, 0x20800080, 0x00020000, 0x00820080]
164 ]
165
167
168 if len(des_key) != 128:
169 raise ValueError("DES KEY must be 128 bytes long!")
170
171 self.des_key = des_key
172
173
174 self.max_bits = 32
175 self.max_bits_mask = (2**self.max_bits - 1)
176
177 - def rol(self, value, r_bits):
178 r_bits %= self.max_bits
179
180 return ((value << r_bits | (value >> (self.max_bits - r_bits))) &
181 self.max_bits_mask)
182
183 - def ror(self, value, r_bits):
184 r_bits %= self.max_bits
185
186 return ((value << (self.max_bits - r_bits) | (value >> r_bits)) &
187 self.max_bits_mask)
188
190
191 eax, edx = struct.unpack('<LL', self.des_key[round * 8:round * 8 + 8])
192 ebx = 0
193 eax ^= src
194 edx ^= src
195 eax &= 0x0FCFCFCFC
196 edx &= 0x0CFCFCFCF
197 ebx = (ebx & 0xFFFFFF00) | (eax & 0x000000FF)
198 ecx = (ecx & 0xFFFFFF00) | ((eax & 0x0000FF00) >> 8)
199 edx = self.ror(edx, 4)
200 ebp = self.sboxul[0][ebx >> 2]
201 ebx = (ebx & 0xFFFFFF00) | (edx & 0x000000FF)
202 dst ^= ebp
203 ebp = self.sboxul[2][ecx >> 2]
204 dst ^= ebp
205 ecx = (ecx & 0xFFFFFF00) | ((edx & 0x0000FF00) >> 8)
206 eax >>= 0x10
207 ebp = self.sboxul[1][ebx >> 2]
208 dst ^= ebp
209 ebx = (ebx & 0xFFFFFF00) | ((eax & 0x0000FF00) >> 8)
210 edx >>= 0x10
211 ebp = self.sboxul[3][ecx >> 2]
212 dst ^= ebp
213 ecx = (ecx & 0xFFFFFF00) | ((edx & 0x0000FF00) >> 8)
214 eax &= 0xFF
215 edx &= 0xFF
216 ebx = self.sboxul[6][ebx >> 2]
217 dst ^= ebx
218 ebx = self.sboxul[7][ecx >> 2]
219 dst ^= ebx
220 ebx = self.sboxul[4][eax >> 2]
221 dst ^= ebx
222 ebx = self.sboxul[5][edx >> 2]
223 dst ^= ebx
224 return dst, ecx
225
227
228 esi = encrypted
229 eax = struct.unpack('<L', esi[:4])[0]
230 edi = struct.unpack('<L', esi[4:])[0]
231 eax = self.rol(eax, 4)
232 esi = eax
233 eax = eax ^ edi
234 eax = eax & 0x0F0F0F0F0
235 esi = esi ^ eax
236 edi = edi ^ eax
237 edi = self.rol(edi, 0x14)
238 eax = edi
239 edi = edi ^ esi
240 edi = edi & 0x0FFF0000F
241 eax = eax ^ edi
242 esi = esi ^ edi
243 eax = self.rol(eax, 0x0e)
244 edi = eax
245 eax = eax ^ esi
246 eax = eax & 0x33333333
247 edi = edi ^ eax
248 esi = esi ^ eax
249 esi = self.rol(esi, 0x16)
250 eax = esi
251 esi = esi ^ edi
252 esi = esi & 0x3FC03FC
253 eax = eax ^ esi
254 edi = edi ^ esi
255 eax = self.rol(eax, 0x9)
256 esi = eax
257 eax = eax ^ edi
258 eax = eax & 0x0AAAAAAAA
259 esi = esi ^ eax
260 edi = edi ^ eax
261 edi = self.rol(edi, 0x1)
262
263 ecx = 0
264 for round in range(15, 0, -2):
265 edi, ecx = self._decrypt_loop(edi, esi, ecx, round)
266 esi, ecx = self._decrypt_loop(esi, edi, ecx, round-1)
267
268 esi = self.ror(esi, 1)
269 eax = edi
270 edi ^= esi
271 edi &= 0x0AAAAAAAA
272 eax ^= edi
273 esi ^= edi
274 eax = self.rol(eax, 0x17)
275 edi = eax
276 eax ^= esi
277 eax &= 0x3FC03FC
278 edi ^= eax
279 esi ^= eax
280 edi = self.rol(edi, 0x0A)
281 eax = edi
282 edi ^= esi
283 edi &= 0x33333333
284 eax ^= edi
285 esi ^= edi
286 esi = self.rol(esi, 0x12)
287 edi = esi
288 esi ^= eax
289 esi &= 0x0FFF0000F
290 edi ^= esi
291 eax ^= esi
292 edi = self.rol(edi, 0x0C)
293 esi = edi
294 edi ^= eax
295 edi &= 0x0F0F0F0F0
296 esi ^= edi
297 eax ^= edi
298 eax = self.ror(eax, 4)
299
300 return struct.pack('<L', eax) + struct.pack('<L', esi)
301
302
304 '''NT 5.1 and NT 5.2 lsasrv.dll DESX implementation.'''
305
307
308 if len(desx_key) != 144:
309 raise ValueError("DESX KEY must be 144 bytes long!")
310
311 self.desx_key = desx_key
312 self.DES = XP_DES(desx_key[16:])
313
315
316 if len(encrypted) != 8:
317 raise ValueError("Encrypted data length must be 8 bytes!")
318
319 eax, esi = struct.unpack('<LL', encrypted)
320 ecx, edx = struct.unpack('<LL', self.desx_key[8:16])
321 ecx ^= eax
322 edx ^= esi
323 enc_64 = struct.pack('<L', ecx) + struct.pack('<L', edx)
324
325 decrypted = self.DES.decrypt(enc_64)
326
327 ecx, ebx = struct.unpack('<LL', self.desx_key[:8])
328 edx, eax = struct.unpack('<LL', decrypted)
329 edx ^= ecx
330 eax ^= ebx
331
332 return struct.pack('<L', edx) + struct.pack('<L', eax)
333
334
336 '''NT 5.1 and NT 5.2 lsasrv.dll CBC with DESX partial implementation.'''
337
339
340 if len(desx_key) != 144:
341 raise ValueError("DESX KEY must be 144 bytes long!")
342
343 self.desx_key = desx_key
344 self.DESX = XP_DESX(desx_key)
345
346 - def decrypt(self, encrypted, feedback):
347
348 if len(encrypted) % 8:
349 raise ValueError("Encrypted length is not multiple of 8 bytes")
350
351 decrypted = self.DESX.decrypt(encrypted)
352
353 decrypted_temp = struct.unpack('<Q', decrypted)[0]
354 decrypted_temp ^= struct.unpack('<Q', feedback)[0]
355 decrypted = struct.pack('<Q', decrypted_temp)
356
357 feedback = encrypted
358
359 return decrypted, feedback
360
361
363
364 - def __init__(self, desx_key, feedback):
365
366 if len(desx_key) != 144:
367 raise ValueError("DESX KEY must be 144 bytes long!")
368
369 if len(feedback) != 8:
370 raise ValueError("feedback must be 8 bytes long!")
371
372 self.desx_key = desx_key
373 self.feedback = feedback
374 self.CBC_DESX = XP_CBC_DESX(desx_key)
375
377 if len(encrypted) % 8:
378 raise ValueError("Encrypted length is not multiple of 8 bytes.")
379
380 decrypted = ''
381 feedback = self.feedback
382
383 for i in range(0, len(encrypted) >> 3, 1):
384 decrypted8, feedback = self.CBC_DESX.decrypt(
385 encrypted[i*8:i*8+8], feedback)
386 decrypted += decrypted8
387
388 return decrypted
389