diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index eba190b5e..2ea197cf7 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -507,7 +507,10 @@ static int CmdHF14AMfWrBl(const char *Cmd) { "Sector 0 / Block 0 - Manufacturer block\n" "When writing to block 0 you must use a VALID block 0 data (UID, BCC, SAK, ATQA)\n" "Writing an invalid block 0 means rendering your Magic GEN2 card undetectable. \n" - "Look in the magic_cards_notes.md file for help to resolve it.", + "Look in the magic_cards_notes.md file for help to resolve it.\n" + " \n" + "`--force` param is used to override warnings like bad ACL and BLOCK 0 writes.\n" + " if not specified, it will exit if detected", "hf mf wrbl --blk 1 -k FFFFFFFFFFFF -d 000102030405060708090a0b0c0d0e0f" ); void *argtable[] = { @@ -515,7 +518,7 @@ static int CmdHF14AMfWrBl(const char *Cmd) { arg_int1(NULL, "blk", "", "block number"), arg_lit0("a", NULL, "input key type is key A (def)"), arg_lit0("b", NULL, "input key type is key B"), - arg_lit0(NULL, "force", "enforce block0 writes"), + arg_lit0(NULL, "force", "override warnings"), arg_str0("k", "key", "", "key, 6 hex bytes"), arg_str0("d", "data", "", "bytes to write, 16 hex bytes"), @@ -553,6 +556,8 @@ static int CmdHF14AMfWrBl(const char *Cmd) { if (b > 255) { return PM3_EINVARG; } + + // BLOCK 0 detection if (b == 0 && force == false) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "Targeting Sector 0 / Block 0 - Manufacturer block"); @@ -564,13 +569,14 @@ static int CmdHF14AMfWrBl(const char *Cmd) { uint8_t blockno = (uint8_t)b; - // Warn if ACL is strict read-only + // Sector trailer sanity checks. + // Warn if ACL is strict read-only, or invalid ACL. if (mfIsSectorTrailer(blockno)) { PrintAndLogEx(INFO, "Sector trailer (ST) write detected"); // ensure access right isn't messed up. if (mfValidateAccessConditions(&block[6]) == false) { - PrintAndLogEx(WARNING, "Invalid Access Conditions detected, replacing by default values"); + PrintAndLogEx(WARNING, "Invalid Access Conditions detected, replacing with default values"); memcpy(block + 6, "\xFF\x07\x80\x69", 4); } @@ -583,8 +589,13 @@ static int CmdHF14AMfWrBl(const char *Cmd) { } } if (ro_detected) { - PrintAndLogEx(INFO, "Exiting, please run `" _YELLOW_("hf mf acl -d %s") "` to understand", sprint_hex_inrow(&block[6], 3)); - return PM3_EINVARG; + if (force) { + PrintAndLogEx(WARNING, " --force override, continuing..."); + } else { + PrintAndLogEx(INFO, "Exiting, please run `" _YELLOW_("hf mf acl -d %s") "` to understand", sprint_hex_inrow(&block[6], 3)); + PrintAndLogEx(INFO, "Use `" _YELLOW_("--force") "` to override and write this data"); + return PM3_EINVARG; + } } else { PrintAndLogEx(SUCCESS, "ST passed checks, continuing..."); } @@ -1079,9 +1090,11 @@ static int CmdHF14AMfRestore(const char *Cmd) { "If access rights in dump file is all zeros, it will be replaced with default values\n" "\n" "`--uid` param is used for filename templates `hf-mf--dump.bin` and `hf-mf--key.bin.\n" - " If not specified, it will read the card uid instead.\n" + " if not specified, it will read the card uid instead.\n" " `--ka` param you can indicate that the key file should be used for authentication instead.\n" - " if so we also try both B/A keys", + " if so we also try both B/A keys\n" + "`--force` param is used to override warnings and allow bad ACL block writes.\n" + " if not specified, it will skip blocks with bad ACL.\n", "hf mf restore\n" "hf mf restore --1k --uid 04010203\n" "hf mf restore --1k --uid 04010203 -k hf-mf-AABBCCDD-key.bin\n" @@ -1098,6 +1111,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { arg_str0("f", "file", "", "specify dump filename (bin/eml/json)"), arg_str0("k", "kfn", "", "key filename"), arg_lit0(NULL, "ka", "use specified keyfile to authenticate"), + arg_lit0(NULL, "force", "override warnings"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1120,6 +1134,8 @@ static int CmdHF14AMfRestore(const char *Cmd) { CLIParamStrToBuf(arg_get_str(ctx, 7), (uint8_t *)keyfilename, FILE_PATH_SIZE, &keyfnlen); bool use_keyfile_for_auth = arg_get_lit(ctx, 8); + bool force = arg_get_lit(ctx, 9); + CLIParserFree(ctx); // validations @@ -1256,7 +1272,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { // ensure access right isn't messed up. if (mfValidateAccessConditions(&bldata[6]) == false) { - PrintAndLogEx(WARNING, "Invalid Access Conditions on sector %i, replacing by default values", s); + PrintAndLogEx(WARNING, "Invalid Access Conditions on sector %i, replacing with default values", s); memcpy(bldata + 6, "\xFF\x07\x80\x69", 4); } @@ -1264,6 +1280,12 @@ static int CmdHF14AMfRestore(const char *Cmd) { for (uint8_t foo = 0; foo < mfNumBlocksPerSector(s); foo++) { if (mfReadOnlyAccessConditions(foo, &bldata[6])) { PrintAndLogEx(WARNING, "Strict ReadOnly Access Conditions on block " _YELLOW_("%u") " detected", foo); + + // if --force isn't used, skip writing this block + if (force == false) { + PrintAndLogEx(INFO, "Skipping, use `" _YELLOW_("--force") "` to override and write this data"); + continue; + } } } }