change hf legic dump, restore, to abort if xoring of data failed

This commit is contained in:
iceman1001 2021-04-26 14:29:28 +02:00
commit 792b59997e

View file

@ -42,11 +42,10 @@ static bool legic_xor(uint8_t *data, uint16_t cardsize) {
return false; return false;
} }
for (uint16_t i = 22; i < cardsize; i++) { for (uint16_t i = 22; i < cardsize; i++) {
data[i] ^= crc; data[i] ^= crc;
} }
PrintAndLogEx(SUCCESS, "(De)Obsfuscation done"); PrintAndLogEx(SUCCESS, "applying xoring of data done!");
return true; return true;
} }
@ -509,10 +508,9 @@ static int CmdLegicWrbl(const char *Cmd) {
int offset = arg_get_int_def(ctx, 1, 0); int offset = arg_get_int_def(ctx, 1, 0);
int data_len = 0; int dlen = 0;
uint8_t data[MAX_LENGTH] = {0}; uint8_t data[MAX_LENGTH] = {0};
CLIGetHexWithReturn(ctx, 2, data, &dlen);
CLIGetHexWithReturn(ctx, 2, data, &data_len);
bool autoconfirm = arg_get_lit(ctx, 3); bool autoconfirm = arg_get_lit(ctx, 3);
@ -536,15 +534,15 @@ static int CmdLegicWrbl(const char *Cmd) {
legic_print_type(card.cardsize, 0); legic_print_type(card.cardsize, 0);
if (data_len + offset > card.cardsize) { if (dlen + offset > card.cardsize) {
PrintAndLogEx(WARNING, "Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, data_len + offset); PrintAndLogEx(WARNING, "Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, dlen + offset);
return PM3_EOUTOFBOUND; return PM3_EOUTOFBOUND;
} }
if ((offset == 5 || offset == 6) && (! autoconfirm)) { if ((offset == 5 || offset == 6) && (! autoconfirm)) {
PrintAndLogEx(NORMAL, "############# DANGER ################"); PrintAndLogEx(INFO, "############# DANGER ################");
PrintAndLogEx(NORMAL, "# changing the DCF is irreversible #"); PrintAndLogEx(WARNING, "# changing the DCF is irreversible #");
PrintAndLogEx(NORMAL, "#####################################"); PrintAndLogEx(INFO, "#####################################");
const char *confirm = "Do you really want to continue? y(es)/n(o) : "; const char *confirm = "Do you really want to continue? y(es)/n(o) : ";
bool overwrite = false; bool overwrite = false;
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
@ -572,7 +570,7 @@ static int CmdLegicWrbl(const char *Cmd) {
PacketResponseNG resp; PacketResponseNG resp;
clearCommandBuffer(); clearCommandBuffer();
SendCommandOLD(CMD_HF_LEGIC_WRITER, offset, data_len, IV, data, data_len); SendCommandOLD(CMD_HF_LEGIC_WRITER, offset, dlen, IV, data, dlen);
uint8_t timeout = 0; uint8_t timeout = 0;
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
@ -758,14 +756,14 @@ static int CmdLegicDump(const char *Cmd) {
CLIParserInit(&ctx, "hf legic dump", CLIParserInit(&ctx, "hf legic dump",
"Read all memory from LEGIC Prime MIM22, MIM256, MIM1024 and saves bin/eml/json dump file\n" "Read all memory from LEGIC Prime MIM22, MIM256, MIM1024 and saves bin/eml/json dump file\n"
"It autodetects card type.", "It autodetects card type.",
"hf legic dump --> use UID as filename\n" "hf legic dump --> use UID as filename\n"
"hf legic dump -f myfile --> use user specified filename\n" "hf legic dump -f myfile --> use user specified filename\n"
"hf legic dump --deobfuscate --> use UID as filename and deobfuscate data"); "hf legic dump --de --> use UID as filename and deobfuscate data");
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_str0("f", "file", "<filename>", "specify a filename for dump file"), arg_str0("f", "file", "<filename>", "specify a filename for dump file"),
arg_lit0(NULL, "deobfuscate", "deobfuscate dump data (xor with MCC)"), arg_lit0(NULL, "de", "deobfuscate dump data (xor with MCC)"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -775,7 +773,6 @@ static int CmdLegicDump(const char *Cmd) {
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
bool shall_deobsfuscate = arg_get_lit(ctx, 2); bool shall_deobsfuscate = arg_get_lit(ctx, 2);
CLIParserFree(ctx); CLIParserFree(ctx);
// tagtype // tagtype
@ -827,6 +824,17 @@ static int CmdLegicDump(const char *Cmd) {
return PM3_ETIMEOUT; return PM3_ETIMEOUT;
} }
if (shall_deobsfuscate) {
// Deobfuscate the whole dump. Unused data (after the last sector) will be MCC since
// 0x00 ^ MCC = MCC. Finding the end of used data is not part of this function.
if (legic_xor(data, dumplen) == false) {
PrintAndLogEx(FAILED, "Deobsfuscate failed, exiting...");
PrintAndLogEx(HINT, "Try running command without `--de` parameter");
free(data);
return PM3_EFAILED;
}
}
// user supplied filename? // user supplied filename?
if (fnlen < 1) { if (fnlen < 1) {
PrintAndLogEx(INFO, "Using UID as filename"); PrintAndLogEx(INFO, "Using UID as filename");
@ -834,12 +842,6 @@ static int CmdLegicDump(const char *Cmd) {
FillFileNameByUID(filename, data, "-dump", 4); FillFileNameByUID(filename, data, "-dump", 4);
} }
if (shall_deobsfuscate) {
// Deobfuscate the whole dump. Unused data (after the last sector) will be MCC since
// 0x00 ^ MCC = MCC. Finding the end of used data is not part of this function.
legic_xor(data, dumplen);
}
saveFile(filename, ".bin", data, readlen); saveFile(filename, ".bin", data, readlen);
saveFileEML(filename, data, readlen, 8); saveFileEML(filename, data, readlen, 8);
saveFileJSON(filename, jsfLegic, data, readlen, NULL); saveFileJSON(filename, jsfLegic, data, readlen, NULL);
@ -852,13 +854,13 @@ static int CmdLegicRestore(const char *Cmd) {
CLIParserInit(&ctx, "hf legic restore", CLIParserInit(&ctx, "hf legic restore",
"Reads binary file and it autodetects card type and verifies that the file has the same size\n" "Reads binary file and it autodetects card type and verifies that the file has the same size\n"
"Then write the data back to card. All bytes except the first 7bytes [UID(4) MCC(1) DCF(2)]", "Then write the data back to card. All bytes except the first 7bytes [UID(4) MCC(1) DCF(2)]",
"hf legic restore -f myfile --> use user specified filename\n" "hf legic restore -f myfile --> use user specified filename\n"
"hf legic restore -f myfile --obfuscate --> use UID as filename and deobfuscate data"); "hf legic restore -f myfile --ob --> use UID as filename and obfuscate data");
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_str1("f", "file", "<filename>", "specify a filename to restore"), arg_str1("f", "file", "<filename>", "specify a filename to restore"),
arg_lit0(NULL, "obfuscate", "obfuscate dump data (xor with MCC)"), arg_lit0(NULL, "ob", "obfuscate dump data (xor with MCC)"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, false); CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -868,7 +870,6 @@ static int CmdLegicRestore(const char *Cmd) {
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
bool shall_obsfuscate = arg_get_lit(ctx, 2); bool shall_obsfuscate = arg_get_lit(ctx, 2);
CLIParserFree(ctx); CLIParserFree(ctx);
// tagtype // tagtype
@ -901,7 +902,12 @@ static int CmdLegicRestore(const char *Cmd) {
} }
if (shall_obsfuscate) { if (shall_obsfuscate) {
legic_xor(data, card.cardsize); if (legic_xor(data, card.cardsize) == false){
PrintAndLogEx(FAILED, "Obsfuscate failed, exiting...");
PrintAndLogEx(HINT, "Try running command without `--ob` parameter");
free(data);
return PM3_EFAILED;
}
} }
PrintAndLogEx(SUCCESS, "Restoring to card"); PrintAndLogEx(SUCCESS, "Restoring to card");
@ -943,7 +949,7 @@ static int CmdLegicRestore(const char *Cmd) {
} }
free(data); free(data);
PrintAndLogEx(SUCCESS, "Done"); PrintAndLogEx(SUCCESS, "Done!");
return PM3_SUCCESS; return PM3_SUCCESS;
} }