Skip to content

Commit 7373986

Browse files
committed
Extractor improvement: detect recovery password in case of PIN encryption
1 parent cd2c15f commit 7373986

File tree

1 file changed

+58
-26
lines changed

1 file changed

+58
-26
lines changed

src_HashExtractor/bitcracker_hash.c

+58-26
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,34 @@ static void print_hex(unsigned char *str, int len, FILE *out)
9595
fprintf(out, "%02x", str[i]);
9696
}
9797

98+
#define TEST_AES_CCM(slen) { \
99+
fprintf(stderr, "Searching AES-CCM from 0x%08lx\n", ftell(encryptedImage)); \
100+
fseek(encryptedImage, slen, SEEK_CUR); \
101+
fillBuffer(encryptedImage, r_salt, SALT_SIZE); \
102+
printf("Salt: "); \
103+
print_hex(r_salt, SALT_SIZE, stdout); \
104+
printf("\n"); \
105+
fseek(encryptedImage, 147, SEEK_CUR); \
106+
char a=(unsigned char)fgetc(encryptedImage); \
107+
char b=(unsigned char)fgetc(encryptedImage); \
108+
if (( a != value_type[0]) || (b != value_type[1])) { \
109+
fprintf(stderr, "Error: VMK not encrypted with AES-CCM (%x,%x)\n",a ,b); \
110+
found_ccm=0; \
111+
} \
112+
else \
113+
{ \
114+
fprintf(stderr, "VMK encrypted with AES-CCM (%lx)\n", (ftell(encryptedImage)-2)); \
115+
found_ccm=1; \
116+
fseek(encryptedImage, 3, SEEK_CUR); \
117+
} \
118+
}
119+
120+
int userPasswordFound=0, recoveryPasswordFound=0;
98121

99122
int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRecovery)
100123
{
101-
int version = 0, i = 0, match = 0;
124+
int version = 0, i = 0, match = 0, found_ccm=0;
102125
long int fileLen = 0, j=0;
103-
int vmkFound=0, recoveryFound=0;
104-
105126
const char signature[SIGNATURE_LEN] = "-FVE-FS-";
106127
unsigned char vmk_entry[4] = { 0x02, 0x00, 0x08, 0x00 };
107128
unsigned char key_protection_clear[2] = { 0x00, 0x00 };
@@ -162,35 +183,43 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
162183
d = (unsigned char)fgetc(encryptedImage);
163184

164185
if ((c == key_protection_clear[0]) && (d == key_protection_clear[1]))
165-
fprintf(stderr, "VMK not encrypted.. stored clear!\n");
186+
fprintf(stderr, "VMK not encrypted.. stored clear! (0x%08lx)\n", ftell(encryptedImage));
166187
else if ((c == key_protection_tpm[0]) && (d == key_protection_tpm[1]))
167-
fprintf(stderr, "VMK encrypted with TPM...not supported!\n");
188+
fprintf(stderr, "VMK encrypted with TPM...not supported! (0x%08lx)\n", ftell(encryptedImage));
168189
else if ((c == key_protection_start_key[0]) && (d == key_protection_start_key[1]))
169-
fprintf(stderr, "VMK encrypted with Startup Key...not supported!\n");
170-
else if ((c == key_protection_recovery[0]) && (d == key_protection_recovery[1]) && recoveryFound == 0)
190+
fprintf(stderr, "VMK encrypted with Startup Key...not supported! (0x%08lx)\n", ftell(encryptedImage));
191+
else if ((c == key_protection_recovery[0]) && (d == key_protection_recovery[1]) && recoveryPasswordFound == 0)
171192
{
172193
curr_fp = ftell(encryptedImage);
173-
fprintf(stderr, "VMK encrypted with Recovery Password found at %lx\n", curr_fp);
174-
fseek(encryptedImage, 12, SEEK_CUR);
175-
fillBuffer(encryptedImage, r_salt, SALT_SIZE);
176-
fseek(encryptedImage, 147, SEEK_CUR);
177-
char a=(unsigned char)fgetc(encryptedImage);
178-
char b=(unsigned char)fgetc(encryptedImage);
179-
if (( a != value_type[0]) || (b != value_type[1])) {
180-
fprintf(stderr, "Error: VMK not encrypted with AES-CCM, a: %02x, b: %02x\n",a ,b);
194+
fprintf(stderr, "VMK encrypted with Recovery Password found at 0x%08lx\n", curr_fp);
195+
196+
TEST_AES_CCM(12)
197+
if (found_ccm == 0)
198+
{
199+
fseek(encryptedImage, curr_fp, SEEK_SET);
200+
TEST_AES_CCM(12+20)
201+
}
202+
if (found_ccm == 0)
203+
{
181204
match=0;
182205
i=0;
183206
continue;
184207
}
185-
else fprintf(stderr, "VMK encrypted with AES-CCM\n");
186-
187-
fseek(encryptedImage, 3, SEEK_CUR);
208+
188209
fillBuffer(encryptedImage, r_nonce, NONCE_SIZE);
210+
printf("\nNonce: ");
211+
print_hex(r_nonce, NONCE_SIZE, stdout);
212+
189213
fillBuffer(encryptedImage, r_mac, MAC_SIZE);
214+
printf("\nMAC: ");
215+
print_hex(r_mac, MAC_SIZE, stdout);
216+
190217
fillBuffer(encryptedImage, r_vmk, VMK_SIZE);
191-
recoveryFound=1;
218+
printf("\nVMK: ");
219+
print_hex(r_vmk, VMK_SIZE, stdout);
220+
recoveryPasswordFound=1;
192221
}
193-
else if ((c == key_protection_password[0]) && (d == key_protection_password[1]) && vmkFound == 0)
222+
else if ((c == key_protection_password[0]) && (d == key_protection_password[1]) && userPasswordFound == 0)
194223
{
195224
curr_fp = ftell(encryptedImage);
196225
fprintf(stderr, "VMK encrypted with User Password found at %lx\n", curr_fp);
@@ -209,21 +238,21 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
209238
fillBuffer(encryptedImage, p_nonce, NONCE_SIZE);
210239
fillBuffer(encryptedImage, p_mac, MAC_SIZE);
211240
fillBuffer(encryptedImage, p_vmk, VMK_SIZE);
212-
vmkFound=1;
241+
userPasswordFound=1;
213242
}
214243
}
215244

216245
i = 0;
217-
//if(vmkFound == 1 || recoveryFound == 1) break;
246+
//if(userPasswordFound == 1 || recoveryPasswordFound == 1) break;
218247
}
219248

220249
fclose(encryptedImage);
221250

222-
if (vmkFound == 0 && recoveryFound == 0) {
251+
if (userPasswordFound == 0 && recoveryPasswordFound == 0) {
223252
fprintf(stderr, "Error while extracting data: No signature found!\n");
224253
return 1;
225254
} else {
226-
if(vmkFound == 1)
255+
if(userPasswordFound == 1)
227256
{
228257
printf("\nUser Password hash:\n$bitlocker$0$%d$", SALT_SIZE);
229258
print_hex(p_salt, SALT_SIZE, stdout);
@@ -252,7 +281,7 @@ int parse_image(char * encryptedImagePath, char * outHashUser, char * outHashRec
252281
fclose(outFileUser);
253282
}
254283

255-
if(recoveryFound == 1)
284+
if(recoveryPasswordFound == 1)
256285
{
257286
printf("\nRecovery Key hash:\n$bitlocker$2$%d$", SALT_SIZE);
258287
print_hex(r_salt, SALT_SIZE, stdout);
@@ -360,7 +389,10 @@ int main(int argc, char **argv)
360389
if(parse_image(imagePath, outHashUser, outHashRecovery))
361390
fprintf(stderr, "\nError while parsing input device image\n");
362391
else
363-
printf("\nOutput files: \"%s\" and \"%s\"\n", outHashUser, outHashRecovery);
392+
{
393+
if(userPasswordFound) printf("\nOutput file for user password attack: \"%s\"\n", outHashUser);
394+
if(recoveryPasswordFound) printf("\nOutput file for recovery password attack: \"%s\"\n", outHashRecovery);
395+
}
364396

365397
free(outHashUser);
366398
free(outHashRecovery);

0 commit comments

Comments
 (0)