@@ -142,7 +142,6 @@ int dump_users_keys(FILE* sam_hive, named_key_t** users_keys_array, size_t* user
142142 return 0 ;
143143}
144144
145- // TODO(Complete the function)
146145int dump_v_value (FILE * sam_hive , named_key_t * user_key_ptr , ntlm_user_t * user_info_ptr )
147146{
148147 // Validating parameters
@@ -207,10 +206,12 @@ int dump_user_ntlm(ntlm_user_t* user_info_ptr, const uint8_t* hashed_bootkey)
207206 return -1 ;
208207 }
209208
209+ // Decrypt LM hash
210210 int result = decrypt_ntlm_hash (user_info_ptr , hashed_bootkey , hash_lm );
211211 if (result != 0 )
212212 return -2 ;
213213
214+ // Decrypt NT hash
214215 result = decrypt_ntlm_hash (user_info_ptr , hashed_bootkey , hash_nt );
215216 if (result != 0 )
216217 return -3 ;
@@ -245,74 +246,58 @@ int decrypt_ntlm_hash(ntlm_user_t* user_info_ptr, const uint8_t* hashed_bootkey,
245246 }
246247
247248 // Preparing arrays for encrypted hash and salt
249+ uint8_t salt [16 ];
248250 uint8_t encrypted_hash [32 ];
249- uint8_t encrypted_hash_salt [16 ];
250- memset (encrypted_hash , 0 , 32 );
251- memset (encrypted_hash_salt , 0 , 16 );
251+ memcpy (salt , hash_type ? NTPASSWORD : LMPASSWORD , 16 );
252+ memcpy (encrypted_hash , ((uint8_t * )user_info_ptr -> v_value ) + hash_offset + 4 , 16 );
252253
253254 // Setting proper pointer to hash
254255 uint8_t * hash_pointer = hash_type ? user_info_ptr -> nthash : user_info_ptr -> lmhash ;
255- switch (revision )
256- {
257- case 1 :
258- if (hash_exists != 0x14 )
259- {
260- //hash_pointer = hash_nt ? EMPTY_NT_HASH : EMPTY_LM_HASH;
261- memcpy (hash_pointer , hash_type ? EMPTY_NT_HASH : EMPTY_LM_HASH , 16 );
262- return 0 ;
263- }
264256
265- memcpy (encrypted_hash , ((uint8_t * )user_info_ptr -> v_value ) + hash_offset + 4 , 16 );
266- // Decrypt NTLMv1 Hash (without a salt)
267- if (decrypt_hash (
268- encrypted_hash ,
269- hashed_bootkey ,
270- hash_type ? NTPASSWORD : LMPASSWORD ,
271- user_info_ptr ,
272- hash_pointer
273- ) != 0 )
274- return -3 ;
275- break ;
276- case 2 :
277- if (hash_exists != 0x38 )
278- {
279- memcpy (hash_pointer , hash_type ? EMPTY_NT_HASH : EMPTY_LM_HASH , 16 );
280- return 0 ;
281- }
282-
283- // Reading salt and encrypted hash (offset +4 if hash type is NT)
284- memcpy (encrypted_hash_salt , (uint8_t * )user_info_ptr -> v_value + hash_offset + 4 + (hash_type * 4 ), 16 );
257+ uint32_t exists_cmp = 0x14 ;
258+ decrypt_callback_t decrypt_callback = & decrypt_ntlmv1_callback ;
259+ if (revision == 2 )
260+ {
261+ exists_cmp = 0x38 ;
262+ decrypt_callback = & decrypt_ntlmv2_callback ;
263+ memcpy (salt , (uint8_t * )user_info_ptr -> v_value + hash_offset + 4 + (hash_type * 4 ), 16 );
285264 memcpy (encrypted_hash , (uint8_t * )user_info_ptr -> v_value + hash_offset + 20 + (hash_type * 4 ), 32 );
265+ }
286266
287- // Decrypt NTLMv2 Hash (with a salt)
288- if (decrypt_salted_hash (
289- encrypted_hash ,
290- hashed_bootkey ,
291- encrypted_hash_salt ,
292- user_info_ptr ,
293- hash_pointer
294- ) != 0 )
295- return -4 ;
296-
297- break ;
267+ if (hash_exists != exists_cmp )
268+ {
269+ memcpy (hash_pointer , hash_type ? EMPTY_NT_HASH : EMPTY_LM_HASH , 16 );
270+ return 0 ;
271+ }
298272
299- default :
273+ if (decrypt_ntlm_hash_wrapper (
274+ encrypted_hash ,
275+ hashed_bootkey ,
276+ salt ,
277+ user_info_ptr ,
278+ decrypt_callback ,
279+ hash_pointer
280+ ) != 0 )
300281 return -2 ;
301- }
302282
303283 return 0 ;
304284}
305285
306- int decrypt_hash (
286+ int decrypt_ntlm_hash_wrapper (
307287 const uint8_t * enc_hash ,
308288 const uint8_t * hashed_bootkey ,
309- const uint8_t * ntlmphrase ,
289+ const uint8_t * salt ,
310290 ntlm_user_t * user_info_ptr ,
291+ decrypt_callback_t ntlm_version ,
311292 uint8_t * decrypted_hash
312293)
313294{
314295 // Validating parameters
315- if (enc_hash == NULL || hashed_bootkey == NULL || ntlmphrase == NULL || user_info_ptr == NULL || decrypted_hash == NULL )
296+ if (enc_hash == NULL || hashed_bootkey == NULL ||
297+ salt == NULL || user_info_ptr == NULL ||
298+ decrypted_hash == NULL || ntlm_version == NULL ||
299+ user_info_ptr == NULL
300+ )
316301 {
317302 errno = EINVAL ;
318303 return -1 ;
@@ -326,12 +311,51 @@ int decrypt_hash(
326311 des_key1 = BYTE_SWAP64 (des_key1 );
327312 des_key2 = BYTE_SWAP64 (des_key2 );
328313
314+ uint8_t * staged_hash = malloc_check (staged_hash , 32 , -3 );
315+ {
316+ int result = (* ntlm_version )(enc_hash , hashed_bootkey , salt , user_info_ptr , staged_hash );
317+ if (result != 0 )
318+ {
319+ errno = EBADF ;
320+ free (staged_hash );
321+ return result ;
322+ }
323+ }
324+
325+ uint8_t * des_key = & des_key1 ;
326+ for (size_t i = 0 ; i < 16 ; i += sizeof (uint64_t ), des_key = & des_key2 )
327+ {
328+ if (des_ecb_decrypt (staged_hash + i , sizeof (uint64_t ), des_key , decrypted_hash + i ) == 0 )
329+ {
330+ free (staged_hash );
331+ return -6 ;
332+ }
333+ }
334+
335+ return 0 ;
336+ }
337+
338+ int decrypt_ntlmv1_callback (
339+ const uint8_t * encrypted_hash ,
340+ const uint8_t * hashed_bootkey ,
341+ const uint8_t * salt ,
342+ const ntlm_user_t * user_info_ptr ,
343+ uint8_t * output
344+ )
345+ {
346+ // Validating parameters
347+ if (encrypted_hash == NULL || hashed_bootkey == NULL || salt == NULL || output == NULL || user_info_ptr == NULL )
348+ {
349+ errno = EINVAL ;
350+ return -1 ;
351+ }
352+
329353 // Constructing full data for RC4 key
330- size_t ntlmphrase_len = strlen (ntlmphrase ) + 1 ;
354+ size_t ntlmphrase_len = strlen (salt ) + 1 ;
331355 uint8_t * full_data = malloc_check (full_data , 16 + sizeof (uint32_t ) + ntlmphrase_len , -3 );
332356 memcpy (full_data , hashed_bootkey , 16 );
333357 memcpy (full_data + 16 , & user_info_ptr -> sid , sizeof (uint32_t ));
334- memcpy (full_data + 16 + sizeof (uint32_t ), ntlmphrase , ntlmphrase_len );
358+ memcpy (full_data + 16 + sizeof (uint32_t ), output , ntlmphrase_len );
335359
336360 // MD5 of the data will be RC4 key
337361 uint8_t * md5_hash = get_md5 (full_data , 16 + sizeof (uint32_t ) + ntlmphrase_len );
@@ -341,66 +365,33 @@ int decrypt_hash(
341365 return -4 ;
342366 }
343367
344- uint8_t pre_des_hash [32 ];
345- if (rc4_encrypt (enc_hash , 16 , md5_hash , pre_des_hash ) == 0 )
368+ if (rc4_encrypt (encrypted_hash , 16 , md5_hash , output ) == 0 )
346369 {
347370 cleanup_pointers (2 , full_data , md5_hash );
348371 return -5 ;
349372 }
350373
351- uint8_t * des_key = & des_key1 ;
352- for (size_t i = 0 ; i < 16 ; i += sizeof (uint64_t ), des_key = & des_key2 )
353- {
354- if (des_ecb_decrypt (pre_des_hash + i , sizeof (uint64_t ), des_key , decrypted_hash + i ) == 0 )
355- {
356- free (pre_des_hash );
357- return -6 ;
358- }
359- }
360-
361374 return 0 ;
362375}
363376
364- int decrypt_salted_hash (
365- const uint8_t * enc_hash ,
377+ int decrypt_ntlmv2_callback (
378+ const uint8_t * encrypted_hash ,
366379 const uint8_t * hashed_bootkey ,
367380 const uint8_t * salt ,
368- ntlm_user_t * user_info_ptr ,
369- uint8_t * decrypted_hash
381+ const ntlm_user_t * user_info_ptr ,
382+ uint8_t * output
370383)
371384{
372385 // Validating parameters
373- if (enc_hash == NULL || hashed_bootkey == NULL || salt == NULL || user_info_ptr == NULL || decrypted_hash == NULL )
386+ if (encrypted_hash == NULL || hashed_bootkey == NULL || salt == NULL || output == NULL || user_info_ptr == NULL )
374387 {
375388 errno = EINVAL ;
376389 return -1 ;
377390 }
378391
379- uint64_t des_key1 = 0 ;
380- uint64_t des_key2 = 0 ;
381- if (sid_to_des_keys (user_info_ptr -> sid , & des_key1 , & des_key2 ) != 0 )
392+ if (aes_128_cbc_decrypt (encrypted_hash , 32 , hashed_bootkey , salt , output ) == 0 )
382393 return -2 ;
383394
384- des_key1 = BYTE_SWAP64 (des_key1 );
385- des_key2 = BYTE_SWAP64 (des_key2 );
386-
387- uint8_t * pre_des_hash = malloc_check (pre_des_hash , 32 , -3 );
388- if (aes_128_cbc_decrypt (enc_hash , 32 , hashed_bootkey , salt , pre_des_hash ) == 0 )
389- {
390- free (pre_des_hash );
391- return -4 ;
392- }
393-
394- uint8_t * des_key = & des_key1 ;
395- for (size_t i = 0 ; i < 16 ; i += sizeof (uint64_t ), des_key = & des_key2 )
396- {
397- if (des_ecb_decrypt (pre_des_hash + i , sizeof (uint64_t ), des_key , decrypted_hash + i ) == 0 )
398- {
399- free (pre_des_hash );
400- return -6 ;
401- }
402- }
403-
404395 return 0 ;
405396}
406397
0 commit comments