Skip to content

Commit 596dc64

Browse files
committed
To avoid infinite loops in case of huge memory devices, quit when finding a duplicated RP VMK in a FVE block > 1
1 parent 38381a2 commit 596dc64

File tree

1 file changed

+63
-46
lines changed

1 file changed

+63
-46
lines changed

src_HashExtractor/bitcracker_hash.c

+63-46
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,20 @@
3232

3333
#define INPUT_SIZE 1024
3434

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
4449

4550
#define FILE_OUT_HASH_USER "hash_user_pass.txt"
4651
#define FILE_OUT_HASH_RECV "hash_recv_pass.txt"
@@ -52,27 +57,25 @@
5257
exit(EXIT_FAILURE); \
5358
}
5459

55-
#define MAX_RP 200
5660

5761
//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];
6064

6165
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 };
6367
unsigned char key_protection_clear[2] = { 0x00, 0x00 };
6468
unsigned char key_protection_tpm[2] = { 0x00, 0x01 };
6569
unsigned char key_protection_start_key[2] = { 0x00, 0x02 };
6670
unsigned char key_protection_recovery[2] = { 0x00, 0x08 };
6771
unsigned char key_protection_password[2] = { 0x00, 0x20 };
6872
unsigned char value_type[2] = { 0x00, 0x05 };
69-
unsigned char padding[16] = {0};
7073

7174
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
7277
long int fp_before_aes=0, fp_before_salt=0;
7378
FILE *outFileUser, *outFileRecv, * encryptedImage;
74-
int salt_pos[2] = {12, 32};
75-
int aes_pos[2] = {147, 67};
7679

7780
static char finalRP[MAX_RP][210];
7881

@@ -127,7 +130,7 @@ int rp_search_salt_aes() {
127130
uint8_t a,b;
128131
int ret=0, x, y;
129132

130-
for(x=0; x < 2; x++)
133+
for(x=0; x < SALT_OFFSETS; x++)
131134
{
132135
ret=fseek(encryptedImage, salt_pos[x], SEEK_CUR);
133136
FRET_CHECK(ret)
@@ -136,23 +139,23 @@ int rp_search_salt_aes() {
136139

137140
fp_before_aes=ftell(encryptedImage);
138141
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);
140143

141-
for(y=0; y < 2; y++)
144+
for(y=0; y < AES_OFFSETS; y++)
142145
{
143146
ret=fseek(encryptedImage, aes_pos[y], SEEK_CUR);
144147
FRET_CHECK(ret)
145148

146-
fprintf(stderr, "Trying offset 0x%lx.... ", ftell(encryptedImage));
149+
fprintf(stderr, "\tOffset 0x%lx.... ", ftell(encryptedImage));
147150
a=(uint8_t)fgetc(encryptedImage);
148151
b=(uint8_t)fgetc(encryptedImage);
149152
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);
151154
found_ccm=0;
152155
}
153156
else
154157
{
155-
fprintf(stderr, "AES-CCM encryption found!!\n");
158+
fprintf(stderr, "found! :)\n");
156159
found_ccm=1;
157160
ret=fseek(encryptedImage, 3, SEEK_CUR);
158161
FRET_CHECK(ret)
@@ -194,10 +197,9 @@ int rp_search_dup() {
194197
int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRecovery)
195198
{
196199
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;
198201
unsigned char c,d;
199-
int outRP=0;
200-
202+
201203
encryptedImage = fopen(encryptedImagePath, "r");
202204

203205
if (!encryptedImage || !outHashUser || !outHashRecovery) {
@@ -210,42 +212,46 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
210212

211213
fileLen = ftell(encryptedImage);
212214
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));
214216
ret=fseek(encryptedImage, 0, SEEK_SET);
215217
FRET_CHECK(ret)
216218

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-
219219
for (j = 0; j < fileLen; j++) {
220220
c = fgetc(encryptedImage);
221-
while (i < 8 && (unsigned char)c == signature[i]) {
221+
while (i < (SIGNATURE_LEN-1) && (unsigned char)c == signature[i]) {
222222
c = fgetc(encryptedImage);
223223
i++;
224224
}
225-
if (i == 8) {
225+
226+
if (i == (SIGNATURE_LEN-1)) {
226227
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));
228230
ret=fseek(encryptedImage, 1, SEEK_CUR);
229231
version = fgetc(encryptedImage);
230-
fprintf(stderr, "Version: %d ", version);
232+
fprintf(stdout, "Version: %d ", version);
231233
if (version == 1)
232-
fprintf(stderr, "(Windows Vista)\n");
234+
fprintf(stdout, "(Windows Vista)\n");
233235
else if (version == 2)
234-
fprintf(stderr, "(Windows 7 or later)\n");
236+
fprintf(stdout, "(Windows 7 or later)\n");
235237
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");
237239
match = 0;
238240
}
239241
}
240-
if(match == 0) { i=0; continue; }
242+
243+
if(!match) {
244+
i=0;
245+
continue;
246+
}
241247

242248
i = 0;
243-
while (i < 4 && (unsigned char)c == vmk_entry[i]) {
249+
while (i < VMK_ENTRY_SIZE && (unsigned char)c == vmk_entry[i]) {
244250
c = fgetc(encryptedImage);
245251
i++;
246252
}
247253

248-
if (i == 4) {
254+
if (i == VMK_ENTRY_SIZE) {
249255
fprintf(stderr, "\n=====> VMK entry found at 0x%lx\n", (ftell(encryptedImage) - i));
250256

251257
ret=fseek(encryptedImage, 27, SEEK_CUR);
@@ -257,14 +263,14 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
257263
FRET_CHECK(fp_before_salt)
258264

259265
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);
261267
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);
263269
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);
265271
else if ((c == key_protection_recovery[0]) && (d == key_protection_recovery[1]) && RPfound < MAX_RP)
266272
{
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);
268274
rp_search_salt_aes();
269275
if (found_ccm == 0)
270276
{
@@ -279,7 +285,15 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
279285

280286
if(rp_search_dup() == 1)
281287
{
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");
283297
}
284298
else
285299
{
@@ -297,7 +311,7 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
297311
fprintf(stdout, "\nRP VMK: ");
298312
print_hex(r_vmk[RPfound], VMK_SIZE, stdout);
299313

300-
fprintf(stdout, "\n\n");
314+
fprintf(stdout, "\n");
301315
fflush(stdout);
302316

303317
RPfound++;
@@ -318,7 +332,8 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
318332
i=0;
319333
continue;
320334
}
321-
else fprintf(stderr, "VMK encrypted with AES-CCM\n");
335+
else
336+
fprintf(stderr, "VMK encrypted with AES-CCM\n");
322337

323338
ret=fseek(encryptedImage, 3, SEEK_CUR);
324339
FRET_CHECK(ret)
@@ -338,10 +353,12 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
338353
fillBuffer(encryptedImage, p_vmk, VMK_SIZE);
339354
fprintf(stdout, "\nUP VMK: ");
340355
print_hex(p_vmk, VMK_SIZE, stdout);
341-
fprintf(stdout, "\n\n");
356+
fprintf(stdout, "\n");
342357
fflush(stdout);
343358
userPasswordFound=1;
344359
}
360+
else
361+
fprintf(stdout, "Can't define a key protection method for values (%x,%x)... skipping!\n", c, d);
345362
}
346363

347364
i = 0;

0 commit comments

Comments
 (0)