32
32
33
33
#define INPUT_SIZE 1024
34
34
35
- #define SALT_SIZE 16
36
- #define MAC_SIZE 16
37
- #define NONCE_SIZE 12
38
- #define IV_SIZE 16
39
- #define VMK_SIZE 44
40
-
41
- #define SIGNATURE_LEN 9
42
- #define VMK_SALT_JUMP 12
43
- #define VMK_AES_TYPE 0x0005
35
+ #define SALT_SIZE 16
36
+ #define MAC_SIZE 16
37
+ #define IV_SIZE 16
38
+ #define PADDING_SIZE 16
39
+ #define NONCE_SIZE 12
40
+ #define VMK_SIZE 44
41
+ #define VMK_ENTRY_SIZE 4
42
+
43
+ #define SIGNATURE_LEN 9
44
+ #define VMK_SALT_JUMP 12
45
+ #define VMK_AES_TYPE 0x0005
46
+ #define SALT_OFFSETS 2
47
+ #define AES_OFFSETS 1
48
+ #define MAX_RP 200
44
49
45
50
#define FILE_OUT_HASH_USER "hash_user_pass.txt"
46
51
#define FILE_OUT_HASH_RECV "hash_recv_pass.txt"
52
57
exit(EXIT_FAILURE); \
53
58
}
54
59
55
- #define MAX_RP 200
56
60
57
61
//Fixed
58
- static unsigned char p_salt [SALT_SIZE ], p_nonce [NONCE_SIZE ], p_mac [MAC_SIZE ], p_vmk [VMK_SIZE ];
59
- static unsigned char r_salt [MAX_RP ][SALT_SIZE ], r_nonce [MAX_RP ][NONCE_SIZE ], r_mac [MAX_RP ][MAC_SIZE ], r_vmk [MAX_RP ][VMK_SIZE ];
62
+ unsigned char p_salt [SALT_SIZE ], p_nonce [NONCE_SIZE ], p_mac [MAC_SIZE ], p_vmk [VMK_SIZE ];
63
+ unsigned char r_salt [MAX_RP ][SALT_SIZE ], r_nonce [MAX_RP ][NONCE_SIZE ], r_mac [MAX_RP ][MAC_SIZE ], r_vmk [MAX_RP ][VMK_SIZE ];
60
64
61
65
const char signature [SIGNATURE_LEN ] = "-FVE-FS-" ;
62
- unsigned char vmk_entry [4 ] = { 0x02 , 0x00 , 0x08 , 0x00 };
66
+ unsigned char vmk_entry [VMK_ENTRY_SIZE ] = { 0x02 , 0x00 , 0x08 , 0x00 };
63
67
unsigned char key_protection_clear [2 ] = { 0x00 , 0x00 };
64
68
unsigned char key_protection_tpm [2 ] = { 0x00 , 0x01 };
65
69
unsigned char key_protection_start_key [2 ] = { 0x00 , 0x02 };
66
70
unsigned char key_protection_recovery [2 ] = { 0x00 , 0x08 };
67
71
unsigned char key_protection_password [2 ] = { 0x00 , 0x20 };
68
72
unsigned char value_type [2 ] = { 0x00 , 0x05 };
69
- unsigned char padding [16 ] = {0 };
70
73
71
74
int userPasswordFound = 0 , RPfound = 0 , found_ccm = 0 ;
75
+ int salt_pos [SALT_OFFSETS ] = {12 , 32 };
76
+ int aes_pos [AES_OFFSETS ] = {147 }; //67 <-- can't prove as valid this second offset
72
77
long int fp_before_aes = 0 , fp_before_salt = 0 ;
73
78
FILE * outFileUser , * outFileRecv , * encryptedImage ;
74
- int salt_pos [2 ] = {12 , 32 };
75
- int aes_pos [2 ] = {147 , 67 };
76
79
77
80
static char finalRP [MAX_RP ][210 ];
78
81
@@ -127,7 +130,7 @@ int rp_search_salt_aes() {
127
130
uint8_t a ,b ;
128
131
int ret = 0 , x , y ;
129
132
130
- for (x = 0 ; x < 2 ; x ++ )
133
+ for (x = 0 ; x < SALT_OFFSETS ; x ++ )
131
134
{
132
135
ret = fseek (encryptedImage , salt_pos [x ], SEEK_CUR );
133
136
FRET_CHECK (ret )
@@ -136,23 +139,23 @@ int rp_search_salt_aes() {
136
139
137
140
fp_before_aes = ftell (encryptedImage );
138
141
FRET_CHECK (fp_before_aes )
139
- fprintf (stderr , "Searching AES-CCM (0x%lx)\n" , fp_before_aes );
142
+ fprintf (stderr , "Searching for AES-CCM (0x%lx)... \n" , fp_before_aes );
140
143
141
- for (y = 0 ; y < 2 ; y ++ )
144
+ for (y = 0 ; y < AES_OFFSETS ; y ++ )
142
145
{
143
146
ret = fseek (encryptedImage , aes_pos [y ], SEEK_CUR );
144
147
FRET_CHECK (ret )
145
148
146
- fprintf (stderr , "Trying offset 0x%lx.... " , ftell (encryptedImage ));
149
+ fprintf (stderr , "\tOffset 0x%lx.... " , ftell (encryptedImage ));
147
150
a = (uint8_t )fgetc (encryptedImage );
148
151
b = (uint8_t )fgetc (encryptedImage );
149
152
if (( a != value_type [0 ]) || (b != value_type [1 ])) {
150
- fprintf (stderr , "Error: VMK not encrypted with AES-CCM (0x%x,0x%x)\n" , a , b );
153
+ fprintf (stderr , "not found :( (0x%x,0x%x)\n" , a , b );
151
154
found_ccm = 0 ;
152
155
}
153
156
else
154
157
{
155
- fprintf (stderr , "AES-CCM encryption found!! \n" );
158
+ fprintf (stderr , "found! :) \n" );
156
159
found_ccm = 1 ;
157
160
ret = fseek (encryptedImage , 3 , SEEK_CUR );
158
161
FRET_CHECK (ret )
@@ -194,10 +197,9 @@ int rp_search_dup() {
194
197
int parse_image (char * encryptedImagePath , char * outHashUser , char * outHashRecovery )
195
198
{
196
199
long int fileLen = 0 , j = 0 ;
197
- int version = 0 , i = 0 , match = 0 , ret = 0 ;
200
+ int version = 0 , i = 0 , match = 0 , ret = 0 , outRP = 0 , fve_block = 0 ;
198
201
unsigned char c ,d ;
199
- int outRP = 0 ;
200
-
202
+
201
203
encryptedImage = fopen (encryptedImagePath , "r" );
202
204
203
205
if (!encryptedImage || !outHashUser || !outHashRecovery ) {
@@ -210,42 +212,46 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
210
212
211
213
fileLen = ftell (encryptedImage );
212
214
FRET_CHECK (fileLen )
213
- printf ("Encrypted device %s opened, size %ldMB \n" , encryptedImagePath , ((fileLen /1024 )/1024 ));
215
+ printf ("Encrypted device %s opened, size %7.2f MB \n" , encryptedImagePath , ( double ) ((fileLen /1024 )/1024 ));
214
216
ret = fseek (encryptedImage , 0 , SEEK_SET );
215
217
FRET_CHECK (ret )
216
218
217
- //printf("sizeof off_t=%ld, long int=%ld, ULONG_MAX=%lu LONG_MAX=%ld\n", sizeof(off_t), sizeof(long int), ULONG_MAX, LONG_MAX);
218
-
219
219
for (j = 0 ; j < fileLen ; j ++ ) {
220
220
c = fgetc (encryptedImage );
221
- while (i < 8 && (unsigned char )c == signature [i ]) {
221
+ while (i < ( SIGNATURE_LEN - 1 ) && (unsigned char )c == signature [i ]) {
222
222
c = fgetc (encryptedImage );
223
223
i ++ ;
224
224
}
225
- if (i == 8 ) {
225
+
226
+ if (i == (SIGNATURE_LEN - 1 )) {
226
227
match = 1 ;
227
- fprintf (stderr , "\nSignature found at 0x%lx\n" , (ftell (encryptedImage ) - i - 1 ));
228
+ fve_block ++ ;
229
+ fprintf (stdout , "\n************ Signature #%d found at 0x%lx ************\n" , fve_block , (ftell (encryptedImage ) - i - 1 ));
228
230
ret = fseek (encryptedImage , 1 , SEEK_CUR );
229
231
version = fgetc (encryptedImage );
230
- fprintf (stderr , "Version: %d " , version );
232
+ fprintf (stdout , "Version: %d " , version );
231
233
if (version == 1 )
232
- fprintf (stderr , "(Windows Vista)\n" );
234
+ fprintf (stdout , "(Windows Vista)\n" );
233
235
else if (version == 2 )
234
- fprintf (stderr , "(Windows 7 or later)\n" );
236
+ fprintf (stdout , "(Windows 7 or later)\n" );
235
237
else {
236
- fprintf (stderr , "\nInvalid version, looking for a signature with valid version...\n" );
238
+ fprintf (stdout , "\nInvalid version, looking for a signature with valid version...\n" );
237
239
match = 0 ;
238
240
}
239
241
}
240
- if (match == 0 ) { i = 0 ; continue ; }
242
+
243
+ if (!match ) {
244
+ i = 0 ;
245
+ continue ;
246
+ }
241
247
242
248
i = 0 ;
243
- while (i < 4 && (unsigned char )c == vmk_entry [i ]) {
249
+ while (i < VMK_ENTRY_SIZE && (unsigned char )c == vmk_entry [i ]) {
244
250
c = fgetc (encryptedImage );
245
251
i ++ ;
246
252
}
247
253
248
- if (i == 4 ) {
254
+ if (i == VMK_ENTRY_SIZE ) {
249
255
fprintf (stderr , "\n=====> VMK entry found at 0x%lx\n" , (ftell (encryptedImage ) - i ));
250
256
251
257
ret = fseek (encryptedImage , 27 , SEEK_CUR );
@@ -257,14 +263,14 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
257
263
FRET_CHECK (fp_before_salt )
258
264
259
265
if ((c == key_protection_clear [0 ]) && (d == key_protection_clear [1 ]))
260
- fprintf (stderr , "VMK not encrypted.. stored clear! (0x%lx)\n" , fp_before_salt );
266
+ fprintf (stdout , "VMK not encrypted.. stored clear! (0x%lx)\n" , fp_before_salt );
261
267
else if ((c == key_protection_tpm [0 ]) && (d == key_protection_tpm [1 ]))
262
- fprintf (stderr , "VMK encrypted with TPM...not supported! (0x%lx)\n" , fp_before_salt );
268
+ fprintf (stdout , "VMK encrypted with TPM...not supported! (0x%lx)\n" , fp_before_salt );
263
269
else if ((c == key_protection_start_key [0 ]) && (d == key_protection_start_key [1 ]))
264
- fprintf (stderr , "VMK encrypted with Startup Key...not supported! (0x%lx)\n" , fp_before_salt );
270
+ fprintf (stdout , "VMK encrypted with Startup Key...not supported! (0x%lx)\n" , fp_before_salt );
265
271
else if ((c == key_protection_recovery [0 ]) && (d == key_protection_recovery [1 ]) && RPfound < MAX_RP )
266
272
{
267
- fprintf (stderr , "Encrypted with Recovery Password (0x%lx)\n" , fp_before_salt );
273
+ fprintf (stdout , "Encrypted with Recovery Password (0x%lx)\n" , fp_before_salt );
268
274
rp_search_salt_aes ();
269
275
if (found_ccm == 0 )
270
276
{
@@ -279,7 +285,15 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
279
285
280
286
if (rp_search_dup () == 1 )
281
287
{
282
- fprintf (stdout , "This VMK has been already stored... moving forward!\n" );
288
+ fprintf (stdout , "\nThis VMK has been already stored..." );
289
+ //Avoid infinite loop n case of huge device memory
290
+ if (fve_block > 2 )
291
+ {
292
+ fprintf (stdout , "quitting to avoid infinite loop!\n" );
293
+ break ;
294
+ }
295
+ else
296
+ fprintf (stdout , "\n" );
283
297
}
284
298
else
285
299
{
@@ -297,7 +311,7 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
297
311
fprintf (stdout , "\nRP VMK: " );
298
312
print_hex (r_vmk [RPfound ], VMK_SIZE , stdout );
299
313
300
- fprintf (stdout , "\n\n " );
314
+ fprintf (stdout , "\n" );
301
315
fflush (stdout );
302
316
303
317
RPfound ++ ;
@@ -318,7 +332,8 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
318
332
i = 0 ;
319
333
continue ;
320
334
}
321
- else fprintf (stderr , "VMK encrypted with AES-CCM\n" );
335
+ else
336
+ fprintf (stderr , "VMK encrypted with AES-CCM\n" );
322
337
323
338
ret = fseek (encryptedImage , 3 , SEEK_CUR );
324
339
FRET_CHECK (ret )
@@ -338,10 +353,12 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
338
353
fillBuffer (encryptedImage , p_vmk , VMK_SIZE );
339
354
fprintf (stdout , "\nUP VMK: " );
340
355
print_hex (p_vmk , VMK_SIZE , stdout );
341
- fprintf (stdout , "\n\n " );
356
+ fprintf (stdout , "\n" );
342
357
fflush (stdout );
343
358
userPasswordFound = 1 ;
344
359
}
360
+ else
361
+ fprintf (stdout , "Can't define a key protection method for values (%x,%x)... skipping!\n" , c , d );
345
362
}
346
363
347
364
i = 0 ;
0 commit comments