hf mf restore got some textual updates in order to be easier to understand if keyB writes fails. We use a default ACL when wiping a card that doesnt allow key B to be used for writing. Restore command tries key B first, so there will be several failed key b attempts normally.

This commit is contained in:
iceman1001 2023-07-25 22:42:42 +02:00
commit e5b075ed3b
2 changed files with 28 additions and 27 deletions

View file

@ -1352,7 +1352,7 @@ static int CmdHF14AMfRestore(const char *Cmd) {
return PM3_ESOFT;
}
PrintAndLogEx(INFO, "Using key file... `" _YELLOW_("%s") "`", keyfilename);
PrintAndLogEx(INFO, "Using key file `" _YELLOW_("%s") "`", keyfilename);
// try reading card uid and create filename
if (datafnlen == 0) {
@ -1383,10 +1383,9 @@ static int CmdHF14AMfRestore(const char *Cmd) {
// default authentication key
uint8_t default_key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
PrintAndLogEx(INFO, "Restoring " _YELLOW_("%s")" to card", datafilename);
PrintAndLogEx(INFO, " blk | ");
PrintAndLogEx(INFO, "-----+------------------------------------------------------------");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, " blk | data | status");
PrintAndLogEx(INFO, "-----+-------------------------------------------------+----------------");
// main loop for restoring.
// a bit more complicated than needed
@ -1402,6 +1401,8 @@ static int CmdHF14AMfRestore(const char *Cmd) {
// if sector trailer
if (mfIsSectorTrailerBasedOnBlocks(s, b)) {
// keep the current keys on the card
if (use_keyfile_for_auth == false) {
// replace KEY A
memcpy(bldata, keyA + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE);
@ -1440,10 +1441,13 @@ static int CmdHF14AMfRestore(const char *Cmd) {
for (int8_t kt = MF_KEY_B; kt > -1; kt--) {
if (use_keyfile_for_auth) {
if (kt == MF_KEY_A)
if (kt == MF_KEY_A) {
memcpy(wdata, keyA + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE);
else
} else {
memcpy(wdata, keyB + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE);
}
} else {
// use default key to authenticate for the write command
memcpy(wdata, default_key, MIFARE_KEY_SIZE);
@ -1451,8 +1455,6 @@ static int CmdHF14AMfRestore(const char *Cmd) {
uint16_t blockno = (mfFirstBlockOfSector(s) + b);
PrintAndLogEx(INFO, " %3d | %s", blockno, sprint_hex(bldata, sizeof(bldata)));
clearCommandBuffer();
SendCommandMIX(CMD_HF_MIFARE_WRITEBL, blockno, kt, 0, wdata, sizeof(wdata));
PacketResponseNG resp;
@ -1464,22 +1466,20 @@ static int CmdHF14AMfRestore(const char *Cmd) {
int isOK = resp.oldarg[0] & 0xff;
if (isOK == 1) {
// if success, skip to next block
PrintAndLogEx(INFO, " %3d | %s| ( " _GREEN_("ok") " )", blockno, sprint_hex(bldata, sizeof(bldata)));
break;
} else if (isOK == PM3_ETEAROFF) {
}
// write somehow failed. Lets determine why.
if (isOK == PM3_ETEAROFF) {
PrintAndLogEx(INFO, "Tear off triggerd. Recommendation is not to use tear-off with restore command");
goto out;
} else {
if (b == 0) {
PrintAndLogEx(INFO, "Writing to manufacture block w key " _YELLOW_("%c") " ( " _RED_("fail") " )",
(kt == MF_KEY_A) ? 'A' : 'B'
);
} else {
PrintAndLogEx(FAILED, "Write to block " _YELLOW_("%u") " w key " _YELLOW_("%c") " ( " _RED_("fail") " ) ",
blockno,
(kt == MF_KEY_A) ? 'A' : 'B'
);
}
}
PrintAndLogEx(INFO, " %3d | %s| ( " _RED_("fail") " ) key " _YELLOW_("%c"),
blockno,
sprint_hex(bldata, sizeof(bldata)),
(kt == MF_KEY_A) ? 'A' : 'B'
);
} // end loop key types
} // end loop B
} // end loop S
@ -1488,7 +1488,7 @@ out:
free(ref_dump);
free(keyA);
free(keyB);
PrintAndLogEx(INFO, "-----+------------------------------------------------------------");
PrintAndLogEx(INFO, "-----+-------------------------------------------------+----------------");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "Done!");
return PM3_SUCCESS;

View file

@ -215,6 +215,7 @@ char *newfilenamemcopyEx(const char *preferredName, const char *suffix, savePath
if (str_endswith(preferredName, suffix)) {
p_namelen -= strlen(suffix);
}
// modify filename
snprintf(pfn, len, "%.*s%s", (int)p_namelen, preferredName, suffix);
@ -862,7 +863,7 @@ int loadFile_safeEx(const char *preferredName, const char *suffix, void **pdata,
*datalen = bytes_read;
if (verbose) {
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName);
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from binary file `" _YELLOW_("%s") "`", bytes_read, preferredName);
}
return PM3_SUCCESS;
}
@ -936,7 +937,7 @@ int loadFileEML_safe(const char *preferredName, void **pdata, size_t *datalen) {
}
}
fclose(f);
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from text file " _YELLOW_("%s"), counter, preferredName);
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from text file `" _YELLOW_("%s") "`", counter, preferredName);
uint8_t *newdump = realloc(*pdata, counter);
@ -1023,7 +1024,7 @@ int loadFileMCT_safe(const char *preferredName, void **pdata, size_t *datalen) {
}
}
fclose(f);
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from MCT file " _YELLOW_("%s"), counter, preferredName);
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from MCT file `" _YELLOW_("%s") "`", counter, preferredName);
uint8_t *newdump = realloc(*pdata, counter);
@ -1059,7 +1060,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
json_error_t error;
json_t *root = json_load_file(path, 0, &error);
if (verbose)
PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), path);
PrintAndLogEx(SUCCESS, "loaded from JSON file `" _YELLOW_("%s") "`", path);
free(path);
@ -1467,7 +1468,7 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale
}
fclose(f);
if (verbose)
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") " keys from dictionary file " _YELLOW_("%s"), vkeycnt, path);
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") " keys from dictionary file `" _YELLOW_("%s") "`", vkeycnt, path);
if (datalen)
*datalen = counter;