Changed : added option to skip loading the usual ~61 hardcoded keys

This commit is contained in:
Philippe Teuwen 2024-08-09 09:42:26 +02:00
commit e01ff6022a
3 changed files with 35 additions and 25 deletions

View file

@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased] ## [unreleased][unreleased]
- Changed `hf mf chk/fchk`: added option `--no-default` to skip loading the usual ~61 hardcoded keys (@doegox)
- Fixed `hf mf wipe` to detect properly write errors (@doegox) - Fixed `hf mf wipe` to detect properly write errors (@doegox)
- Fixed `hf mf fchk` which was leaving the RF field on when interrupted by keyboard (@doegox) - Fixed `hf mf fchk` which was leaving the RF field on when interrupted by keyboard (@doegox)
- Changed file saving: do not prepend with default path if given path is an absolute path (@doegox) - Changed file saving: do not prepend with default path if given path is an absolute path (@doegox)

View file

@ -151,7 +151,8 @@ for sec in range(NUM_SECTORS):
# If we have a duplicates dict # If we have a duplicates dict
if found_keys[sec][0] == "" and found_keys[sec][1] == "" and len(keys_filtered[sec][key_type]) > 0: if found_keys[sec][0] == "" and found_keys[sec][1] == "" and len(keys_filtered[sec][key_type]) > 0:
kt = ['a', 'b'][key_type] kt = ['a', 'b'][key_type]
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_duplicates.dic" dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_duplicates.dic"
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
if DEBUG: if DEBUG:
print(cmd) print(cmd)
with out: with out:
@ -176,7 +177,8 @@ for sec in range(NUM_SECTORS):
if found_keys[sec][0] == "" and found_keys[sec][1] == "" and nt[sec][0] != nt[sec][1]: if found_keys[sec][0] == "" and found_keys[sec][1] == "" and nt[sec][0] != nt[sec][1]:
# Use filtered dict # Use filtered dict
kt = ['a', 'b'][key_type] kt = ['a', 'b'][key_type]
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_filtered.dic" dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_filtered.dic"
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
if DEBUG: if DEBUG:
print(cmd) print(cmd)
with out: with out:
@ -197,7 +199,8 @@ for sec in range(NUM_SECTORS):
key_type = 0 key_type = 0
# Use regular dict # Use regular dict
kt = ['a', 'b'][key_type] kt = ['a', 'b'][key_type]
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}.dic" dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}.dic"
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
if DEBUG: if DEBUG:
print(cmd) print(cmd)
with out: with out:
@ -237,7 +240,7 @@ for sec in range(NUM_SECTORS):
keys.add(line[12:]) keys.add(line[12:])
if len(keys) > 1: if len(keys) > 1:
kt = ['a', 'b'][key_type_target] kt = ['a', 'b'][key_type_target]
cmd = f"hf mf fchk --blk {sec * 4} -{kt}" cmd = f"hf mf fchk --blk {sec * 4} -{kt} --no-default"
for k in keys: for k in keys:
cmd += f" -k {k}" cmd += f" -k {k}"
if DEBUG: if DEBUG:
@ -270,7 +273,7 @@ if FINAL_CHECK:
with (open(f"keys_{uid:08x}.dic", "w")) as f: with (open(f"keys_{uid:08x}.dic", "w")) as f:
for k in keys_set: for k in keys_set:
f.write(f"{k}\n") f.write(f"{k}\n")
cmd = f"hf mf fchk -f keys_{uid:08x}.dic --dump" cmd = f"hf mf fchk -f keys_{uid:08x}.dic --no-default --dump"
if DEBUG: if DEBUG:
print(cmd) print(cmd)
with out: with out:

View file

@ -764,7 +764,7 @@ static int mfc_read_tag(iso14a_card_select_t *card, uint8_t *carddata, uint8_t n
return PM3_SUCCESS ; return PM3_SUCCESS ;
} }
static int mf_load_keys(uint8_t **pkeyBlock, uint32_t *pkeycnt, uint8_t *userkey, int userkeylen, const char *filename, int fnlen) { static int mf_load_keys(uint8_t **pkeyBlock, uint32_t *pkeycnt, uint8_t *userkey, int userkeylen, const char *filename, int fnlen, bool load_default) {
// Handle Keys // Handle Keys
*pkeycnt = 0; *pkeycnt = 0;
*pkeyBlock = NULL; *pkeyBlock = NULL;
@ -790,28 +790,30 @@ static int mf_load_keys(uint8_t **pkeyBlock, uint32_t *pkeycnt, uint8_t *userkey
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") " user keys", numKeys); PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") " user keys", numKeys);
} }
// Handle default keys if (load_default) {
p = realloc(*pkeyBlock, (*pkeycnt + ARRAYLEN(g_mifare_default_keys)) * MIFARE_KEY_SIZE); // Handle default keys
if (!p) { p = realloc(*pkeyBlock, (*pkeycnt + ARRAYLEN(g_mifare_default_keys)) * MIFARE_KEY_SIZE);
PrintAndLogEx(FAILED, "cannot allocate memory for Keys"); if (!p) {
free(*pkeyBlock); PrintAndLogEx(FAILED, "cannot allocate memory for Keys");
return PM3_EMALLOC; free(*pkeyBlock);
return PM3_EMALLOC;
}
*pkeyBlock = p;
// Copy default keys to list
for (int i = 0; i < ARRAYLEN(g_mifare_default_keys); i++) {
num_to_bytes(g_mifare_default_keys[i], MIFARE_KEY_SIZE, (uint8_t *)(*pkeyBlock + (*pkeycnt + i) * MIFARE_KEY_SIZE));
PrintAndLogEx(DEBUG, _YELLOW_("%2d") " - %s", *pkeycnt + i, sprint_hex(*pkeyBlock + (*pkeycnt + i) * MIFARE_KEY_SIZE, MIFARE_KEY_SIZE));
}
*pkeycnt += ARRAYLEN(g_mifare_default_keys);
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%zu") " keys from hardcoded default array", ARRAYLEN(g_mifare_default_keys));
} }
*pkeyBlock = p;
// Copy default keys to list
for (int i = 0; i < ARRAYLEN(g_mifare_default_keys); i++) {
num_to_bytes(g_mifare_default_keys[i], MIFARE_KEY_SIZE, (uint8_t *)(*pkeyBlock + (*pkeycnt + i) * MIFARE_KEY_SIZE));
PrintAndLogEx(DEBUG, _YELLOW_("%2d") " - %s", *pkeycnt + i, sprint_hex(*pkeyBlock + (*pkeycnt + i) * MIFARE_KEY_SIZE, MIFARE_KEY_SIZE));
}
*pkeycnt += ARRAYLEN(g_mifare_default_keys);
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%zu") " keys from hardcoded default array", ARRAYLEN(g_mifare_default_keys));
// Handle user supplied dictionary file // Handle user supplied dictionary file
if (fnlen > 0) { if (fnlen > 0) {
uint32_t loaded_numKeys = 0; uint32_t loaded_numKeys = 0;
uint8_t *keyBlock_tmp = NULL; uint8_t *keyBlock_tmp = NULL;
int res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock_tmp, MIFARE_KEY_SIZE, &loaded_numKeys); int res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock_tmp, MIFARE_KEY_SIZE, &loaded_numKeys);
if (res != PM3_SUCCESS || loaded_numKeys == 0 || *pkeyBlock == NULL) { if (res != PM3_SUCCESS || loaded_numKeys == 0 || keyBlock_tmp == NULL) {
PrintAndLogEx(FAILED, "An error occurred while loading the dictionary!"); PrintAndLogEx(FAILED, "An error occurred while loading the dictionary!");
free(keyBlock_tmp); free(keyBlock_tmp);
free(*pkeyBlock); free(*pkeyBlock);
@ -2761,7 +2763,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
// Start the timer // Start the timer
uint64_t t1 = msclock(); uint64_t t1 = msclock();
int ret = mf_load_keys(&keyBlock, &key_cnt, in_keys, in_keys_len, filename, fnlen); int ret = mf_load_keys(&keyBlock, &key_cnt, in_keys, in_keys_len, filename, fnlen, true);
if (ret != PM3_SUCCESS) { if (ret != PM3_SUCCESS) {
free(e_sector); free(e_sector);
return ret; return ret;
@ -3295,6 +3297,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) {
arg_int0(NULL, "blk", "<dec>", "block number (single block recovery mode)"), arg_int0(NULL, "blk", "<dec>", "block number (single block recovery mode)"),
arg_lit0("a", NULL, "single block recovery key A"), arg_lit0("a", NULL, "single block recovery key A"),
arg_lit0("b", NULL, "single block recovery key B"), arg_lit0("b", NULL, "single block recovery key B"),
arg_lit0(NULL, "no-default", "Don't add the bunch of extra default keys"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -3325,6 +3328,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) {
} else if (arg_get_lit(ctx, 12)) { } else if (arg_get_lit(ctx, 12)) {
keytype = MF_KEY_B; keytype = MF_KEY_B;
} }
bool load_default = ! arg_get_lit(ctx, 13);
CLIParserFree(ctx); CLIParserFree(ctx);
@ -3353,7 +3357,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) {
uint8_t *keyBlock = NULL; uint8_t *keyBlock = NULL;
uint32_t keycnt = 0; uint32_t keycnt = 0;
int ret = mf_load_keys(&keyBlock, &keycnt, key, keylen, filename, fnlen); int ret = mf_load_keys(&keyBlock, &keycnt, key, keylen, filename, fnlen, load_default);
if (ret != PM3_SUCCESS) { if (ret != PM3_SUCCESS) {
return ret; return ret;
} }
@ -3732,6 +3736,7 @@ static int CmdHF14AMfChk(const char *Cmd) {
arg_lit0(NULL, "emu", "Fill simulator keys from found keys"), arg_lit0(NULL, "emu", "Fill simulator keys from found keys"),
arg_lit0(NULL, "dump", "Dump found keys to binary file"), arg_lit0(NULL, "dump", "Dump found keys to binary file"),
arg_str0("f", "file", "<fn>", "Filename of dictionary"), arg_str0("f", "file", "<fn>", "Filename of dictionary"),
arg_lit0(NULL, "no-default", "Don't add the bunch of extra default keys"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -3763,6 +3768,7 @@ static int CmdHF14AMfChk(const char *Cmd) {
int fnlen = 0; int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0}; char filename[FILE_PATH_SIZE] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 12), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); CLIParamStrToBuf(arg_get_str(ctx, 12), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
bool load_default = ! arg_get_lit(ctx, 13);
CLIParserFree(ctx); CLIParserFree(ctx);
@ -3822,7 +3828,7 @@ static int CmdHF14AMfChk(const char *Cmd) {
uint8_t *keyBlock = NULL; uint8_t *keyBlock = NULL;
uint32_t keycnt = 0; uint32_t keycnt = 0;
int ret = mf_load_keys(&keyBlock, &keycnt, key, keylen, filename, fnlen); int ret = mf_load_keys(&keyBlock, &keycnt, key, keylen, filename, fnlen, load_default);
if (ret != PM3_SUCCESS) { if (ret != PM3_SUCCESS) {
return ret; return ret;
} }
@ -9494,7 +9500,7 @@ static int CmdHF14AMfInfo(const char *Cmd) {
int sectorsCnt = 2; int sectorsCnt = 2;
uint8_t *keyBlock = NULL; uint8_t *keyBlock = NULL;
uint32_t keycnt = 0; uint32_t keycnt = 0;
res = mf_load_keys(&keyBlock, &keycnt, key, MIFARE_KEY_SIZE * 2, NULL, 0); res = mf_load_keys(&keyBlock, &keycnt, key, MIFARE_KEY_SIZE * 2, NULL, 0, true);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
return res; return res;
} }