mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 10:37:23 -07:00
style and text. unify some parameter names
This commit is contained in:
parent
add2eb8e9d
commit
ec26b6d84f
5 changed files with 196 additions and 92 deletions
|
@ -1187,8 +1187,8 @@ static int CmdHF14aDesChk(const char *Cmd) {
|
|||
CLIParserInit(&ctx, "hf mfdes chk",
|
||||
"Checks keys with MIFARE DESFire card.",
|
||||
"hf mfdes chk --aid 123456 -k 000102030405060708090a0b0c0d0e0f -> check key on aid 0x123456\n"
|
||||
"hf mfdes chk -d mfdes_default_keys -> check keys against all existing aid on card\n"
|
||||
"hf mfdes chk -d mfdes_default_keys --aid 123456 -> check keys against aid 0x123456\n"
|
||||
"hf mfdes chk -f mfdes_default_keys -> check keys against all existing aid on card\n"
|
||||
"hf mfdes chk -f mfdes_default_keys --aid 123456 -> check keys against aid 0x123456\n"
|
||||
"hf mfdes chk --aid 123456 --pattern1b -j keys -> check all 1-byte keys pattern on aid 0x123456 and save found keys to `keys.json`\n"
|
||||
"hf mfdes chk --aid 123456 --pattern2b --startp2b FA00 -> check all 2-byte keys pattern on aid 0x123456. Start from key FA00FA00...FA00");
|
||||
|
||||
|
@ -1196,7 +1196,7 @@ static int CmdHF14aDesChk(const char *Cmd) {
|
|||
arg_param_begin,
|
||||
arg_str0(NULL, "aid", "<hex>", "Use specific AID (3 hex bytes, big endian)"),
|
||||
arg_str0("k", "key", "<hex>", "Key for checking (HEX 16 bytes)"),
|
||||
arg_str0("d", "dict", "<fn>", "Dictionary file with keys"),
|
||||
arg_str0("f", "file", "<fn>", "Filename of dictionary"),
|
||||
arg_lit0(NULL, "pattern1b", "Check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)"),
|
||||
arg_lit0(NULL, "pattern2b", "Check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"),
|
||||
arg_str0(NULL, "startp2b", "<pattern>", "Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)"),
|
||||
|
@ -1209,12 +1209,12 @@ static int CmdHF14aDesChk(const char *Cmd) {
|
|||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
bool APDULogging = arg_get_lit(ctx, 11);
|
||||
|
||||
int aidlength = 0;
|
||||
uint8_t aid[3] = {0};
|
||||
CLIGetHexWithReturn(ctx, 1, aid, &aidlength);
|
||||
|
||||
swap24(aid);
|
||||
|
||||
uint8_t vkey[16] = {0};
|
||||
int vkeylen = 0;
|
||||
CLIGetHexWithReturn(ctx, 2, vkey, &vkeylen);
|
||||
|
@ -1293,17 +1293,26 @@ static int CmdHF14aDesChk(const char *Cmd) {
|
|||
int kdfInputLen = 0;
|
||||
CLIGetHexWithReturn(ctx, 10, kdfInput, &kdfInputLen);
|
||||
|
||||
bool APDULogging = arg_get_lit(ctx, 11);
|
||||
|
||||
CLIParserFree(ctx);
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
// 1-byte pattern search mode
|
||||
if (pattern1b) {
|
||||
for (uint32_t i = 0; i < 0x100; i++)
|
||||
|
||||
for (uint32_t i = 0; i < 0x100; i++) {
|
||||
memset(aeskeyList[i], i, 16);
|
||||
for (uint32_t i = 0; i < 0x100; i++)
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < 0x100; i++) {
|
||||
memset(deskeyList[i], i, 8);
|
||||
for (uint32_t i = 0; i < 0x100; i++)
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < 0x100; i++) {
|
||||
memset(k3kkeyList[i], i, 24);
|
||||
}
|
||||
|
||||
aeskeyListLen = 0x100;
|
||||
deskeyListLen = 0x100;
|
||||
k3kkeyListLen = 0x100;
|
||||
|
@ -1319,18 +1328,21 @@ static int CmdHF14aDesChk(const char *Cmd) {
|
|||
if (dict_filenamelen) {
|
||||
|
||||
res = loadFileDICTIONARYEx((char *)dict_filename, deskeyList, sizeof(deskeyList), NULL, 8, &deskeyListLen, 0, &endFilePosition, true);
|
||||
if (res == PM3_SUCCESS && endFilePosition)
|
||||
if (res == PM3_SUCCESS && endFilePosition) {
|
||||
PrintAndLogEx(SUCCESS, "First part of des dictionary successfully loaded.");
|
||||
}
|
||||
|
||||
endFilePosition = 0;
|
||||
res = loadFileDICTIONARYEx((char *)dict_filename, aeskeyList, sizeof(aeskeyList), NULL, 16, &aeskeyListLen, 0, &endFilePosition, true);
|
||||
if (res == PM3_SUCCESS && endFilePosition)
|
||||
if (res == PM3_SUCCESS && endFilePosition) {
|
||||
PrintAndLogEx(SUCCESS, "First part of aes dictionary successfully loaded.");
|
||||
}
|
||||
|
||||
endFilePosition = 0;
|
||||
res = loadFileDICTIONARYEx((char *)dict_filename, k3kkeyList, sizeof(k3kkeyList), NULL, 24, &k3kkeyListLen, 0, &endFilePosition, true);
|
||||
if (res == PM3_SUCCESS && endFilePosition)
|
||||
if (res == PM3_SUCCESS && endFilePosition) {
|
||||
PrintAndLogEx(SUCCESS, "First part of k3kdes dictionary successfully loaded.");
|
||||
}
|
||||
|
||||
endFilePosition = 0;
|
||||
}
|
||||
|
@ -1352,8 +1364,9 @@ static int CmdHF14aDesChk(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, "Loaded " _YELLOW_("%"PRIu32) " k3kdes keys", k3kkeyListLen);
|
||||
}
|
||||
|
||||
if (verbose == false)
|
||||
if (verbose == false) {
|
||||
PrintAndLogEx(INFO, "Search keys:");
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
uint8_t app_ids[78] = {0};
|
||||
|
@ -1508,7 +1521,7 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
"Detect key type and tries to find one from the list.",
|
||||
"hf mfdes detect -> detect key 0 from PICC level\n"
|
||||
"hf mfdes detect --schann d40 -> detect key 0 from PICC level via secure channel D40\n"
|
||||
"hf mfdes detect --dict mfdes_default_keys -> detect key 0 from PICC level with help of the standard dictionary\n"
|
||||
"hf mfdes detect -f mfdes_default_keys -> detect key 0 from PICC level with help of the standard dictionary\n"
|
||||
"hf mfdes detect --aid 123456 -n 2 --save -> detect key 2 from app 123456 and if succeed - save params to defaults (`default` command)\n"
|
||||
"hf mfdes detect --isoid df01 --save -> detect key 0 and save to defaults with card in the LRP mode");
|
||||
|
||||
|
@ -1526,7 +1539,7 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
|
||||
arg_str0(NULL, "dict", "<fn>", "Dictionary file name with keys"),
|
||||
arg_str0("f", "file", "<fn>", "Filename of dictionary"),
|
||||
arg_lit0(NULL, "save", "Save found key and parameters to defaults"),
|
||||
arg_param_end
|
||||
};
|
||||
|
@ -1571,28 +1584,38 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
|
||||
uint8_t data[250] = {0};
|
||||
size_t datalen = 0;
|
||||
|
||||
res = DesfireGetKeySettings(&dctx, data, &datalen);
|
||||
if (res == PM3_SUCCESS && datalen >= 2) {
|
||||
|
||||
uint8_t num_keys = data[1];
|
||||
|
||||
switch (num_keys >> 6) {
|
||||
case 0:
|
||||
case 0: {
|
||||
keytypes[T_DES] = true;
|
||||
keytypes[T_3DES] = true;
|
||||
break;
|
||||
case 1:
|
||||
}
|
||||
case 1: {
|
||||
keytypes[T_3K3DES] = true;
|
||||
break;
|
||||
case 2:
|
||||
}
|
||||
case 2: {
|
||||
keytypes[T_AES] = true;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// if fail - check auth commands
|
||||
AuthCommandsChk_t authCmdCheck = {0};
|
||||
DesfireCheckAuthCommands(selectway, id, NULL, 0, &authCmdCheck);
|
||||
|
||||
if (authCmdCheck.checked) {
|
||||
|
||||
if (authCmdCheck.auth) {
|
||||
keytypes[T_DES] = true;
|
||||
keytypes[T_3DES] = true;
|
||||
|
@ -1601,14 +1624,17 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
keytypes[T_3K3DES] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (authCmdCheck.authAES || authCmdCheck.authEV2) {
|
||||
keytypes[T_AES] = true;
|
||||
}
|
||||
|
||||
if (authCmdCheck.authLRP) {
|
||||
keytypes[T_AES] = true;
|
||||
uselrp = true;
|
||||
securechann = DACLRP;
|
||||
}
|
||||
|
||||
} else {
|
||||
// if nothing helps - we check DES only
|
||||
keytypes[T_DES] = true;
|
||||
|
@ -1623,10 +1649,13 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
}
|
||||
|
||||
if (verbose) {
|
||||
if (DesfireMFSelected(selectway, id))
|
||||
|
||||
if (DesfireMFSelected(selectway, id)) {
|
||||
PrintAndLogEx(INFO, "Check PICC key num: %d (0x%02x)", dctx.keyNum, dctx.keyNum);
|
||||
else
|
||||
} else {
|
||||
PrintAndLogEx(INFO, "Check: %s key num: %d (0x%02x)", DesfireWayIDStr(selectway, id), dctx.keyNum, dctx.keyNum);
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "keys: DES: %s 2TDEA: %s 3TDEA: %s AES: %s LRP: %s",
|
||||
keytypes[T_DES] ? _GREEN_("YES") : _RED_("NO"),
|
||||
keytypes[T_3DES] ? _GREEN_("YES") : _RED_("NO"),
|
||||
|
@ -1640,43 +1669,61 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
bool found = false;
|
||||
size_t errcount = 0;
|
||||
for (uint8_t ktype = T_DES; ktype <= T_AES; ktype++) {
|
||||
if (!keytypes[ktype])
|
||||
|
||||
if (keytypes[ktype] == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dctx.keyType = ktype;
|
||||
if (verbose)
|
||||
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, "Scan key type: %s", CLIGetOptionListStr(DesfireAlgoOpts, dctx.keyType));
|
||||
}
|
||||
|
||||
if (dict_filenamelen == 0) {
|
||||
// keys from mifaredefault.h
|
||||
for (int i = 0; i < g_mifare_plus_default_keys_len; i++) {
|
||||
|
||||
uint8_t key[DESFIRE_MAX_KEY_SIZE] = {0};
|
||||
if (hex_to_bytes(g_mifare_plus_default_keys[i], key, 16) != 16)
|
||||
if (hex_to_bytes(g_mifare_plus_default_keys[i], key, 16) != 16) {
|
||||
continue;
|
||||
if (ktype == T_3K3DES)
|
||||
}
|
||||
|
||||
if (ktype == T_3K3DES) {
|
||||
memcpy(&key[16], key, 8);
|
||||
}
|
||||
|
||||
res = DesfireAuthCheck(&dctx, selectway, id, securechann, key);
|
||||
if (res == PM3_SUCCESS) {
|
||||
found = true;
|
||||
break; // all the params already in the dctx
|
||||
}
|
||||
|
||||
if (res == -10) {
|
||||
if (verbose)
|
||||
|
||||
if (verbose) {
|
||||
PrintAndLogEx(ERR, "Can't select AID. There is no connection with card.");
|
||||
}
|
||||
|
||||
found = false;
|
||||
break; // we can't select app after invalid 1st auth stages
|
||||
}
|
||||
|
||||
if (res == -11) {
|
||||
|
||||
if (errcount > 10) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
PrintAndLogEx(ERR, "Too much errors (%zu) from card", errcount);
|
||||
}
|
||||
break;
|
||||
}
|
||||
errcount++;
|
||||
} else
|
||||
|
||||
} else {
|
||||
errcount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// keys from file
|
||||
uint8_t keyList[MAX_KEYS_LIST_LEN * MAX_KEY_LEN] = {0};
|
||||
|
@ -1684,49 +1731,65 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
size_t keylen = desfire_get_key_length(dctx.keyType);
|
||||
size_t endFilePosition = 0;
|
||||
|
||||
while (!found) {
|
||||
while (found == false) {
|
||||
|
||||
res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), NULL, keylen, &keyListLen, endFilePosition, &endFilePosition, verbose);
|
||||
if (res != 1 && res != PM3_SUCCESS)
|
||||
if (res != 1 && res != PM3_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < keyListLen; i++) {
|
||||
|
||||
res = DesfireAuthCheck(&dctx, selectway, id, securechann, &keyList[i * keylen]);
|
||||
if (res == PM3_SUCCESS) {
|
||||
found = true;
|
||||
break; // all the params already in the dctx
|
||||
}
|
||||
|
||||
if (res == -10) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
PrintAndLogEx(ERR, "Can't select AID. There is no connection with card.");
|
||||
}
|
||||
|
||||
found = false;
|
||||
break; // we can't select app after invalid 1st auth stages
|
||||
}
|
||||
|
||||
if (res == -11) {
|
||||
|
||||
if (errcount > 10) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
PrintAndLogEx(ERR, "Too much errors (%zu) from card", errcount);
|
||||
}
|
||||
break;
|
||||
}
|
||||
errcount++;
|
||||
} else
|
||||
|
||||
} else {
|
||||
errcount = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (endFilePosition == 0)
|
||||
if (endFilePosition == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (found)
|
||||
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
if (DesfireMFSelected(selectway, id))
|
||||
|
||||
if (DesfireMFSelected(selectway, id)) {
|
||||
PrintAndLogEx(INFO, _GREEN_("Found") " key num: %d (0x%02x)", dctx.keyNum, dctx.keyNum);
|
||||
else
|
||||
} else {
|
||||
PrintAndLogEx(INFO, "Found key for: %s key num: %d (0x%02x)", DesfireWayIDStr(selectway, id), dctx.keyNum, dctx.keyNum);
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "channel " _GREEN_("%s") " key " _GREEN_("%s") " [%d]: " _GREEN_("%s"),
|
||||
CLIGetOptionListStr(DesfireSecureChannelOpts, securechann),
|
||||
|
@ -1741,6 +1804,7 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
DropField();
|
||||
|
||||
if (found && save) {
|
||||
|
||||
defaultKeyNum = dctx.keyNum;
|
||||
defaultAlgoId = dctx.keyType;
|
||||
memcpy(defaultKey, dctx.key, DESFIRE_MAX_KEY_SIZE);
|
||||
|
@ -1751,17 +1815,16 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
defaultCommSet = dctx.cmdSet;
|
||||
|
||||
PrintAndLogEx(INFO, "-----------" _CYAN_("Default parameters") "---------------------------------");
|
||||
|
||||
PrintAndLogEx(INFO, "Key Num : %d", defaultKeyNum);
|
||||
PrintAndLogEx(INFO, "Algo : %s", CLIGetOptionListStr(DesfireAlgoOpts, defaultAlgoId));
|
||||
PrintAndLogEx(INFO, "Key : %s", sprint_hex(defaultKey, desfire_get_key_length(defaultAlgoId)));
|
||||
PrintAndLogEx(INFO, "KDF algo : %s", CLIGetOptionListStr(DesfireKDFAlgoOpts, defaultKdfAlgo));
|
||||
PrintAndLogEx(INFO, "KDF input : [%d] %s", defaultKdfInputLen, sprint_hex(defaultKdfInput, defaultKdfInputLen));
|
||||
PrintAndLogEx(INFO, "Secure chan : %s", CLIGetOptionListStr(DesfireSecureChannelOpts, defaultSecureChannel));
|
||||
PrintAndLogEx(INFO, "Command set : %s", CLIGetOptionListStr(DesfireCommandSetOpts, defaultCommSet));
|
||||
PrintAndLogEx(INFO, _GREEN_("Saved"));
|
||||
PrintAndLogEx(INFO, "Key Num....... %d", defaultKeyNum);
|
||||
PrintAndLogEx(INFO, "Algo.......... %s", CLIGetOptionListStr(DesfireAlgoOpts, defaultAlgoId));
|
||||
PrintAndLogEx(INFO, "Key........... %s", sprint_hex(defaultKey, desfire_get_key_length(defaultAlgoId)));
|
||||
PrintAndLogEx(INFO, "KDF algo...... %s", CLIGetOptionListStr(DesfireKDFAlgoOpts, defaultKdfAlgo));
|
||||
PrintAndLogEx(INFO, "KDF input..... [%d] %s", defaultKdfInputLen, sprint_hex(defaultKdfInput, defaultKdfInputLen));
|
||||
PrintAndLogEx(INFO, "Secure chan... %s", CLIGetOptionListStr(DesfireSecureChannelOpts, defaultSecureChannel));
|
||||
PrintAndLogEx(INFO, "Command set... %s", CLIGetOptionListStr(DesfireCommandSetOpts, defaultCommSet));
|
||||
PrintAndLogEx(INFO, "Parameters saved to in-memory ( %s )", _GREEN_("ok"));
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -575,7 +575,8 @@ static int CmdHFMFPInitPerso(const char *Cmd) {
|
|||
CLIParserInit(&ctx, "hf mfp initp",
|
||||
"Executes Write Perso command for all card's keys. Can be used in SL0 mode only.",
|
||||
"hf mfp initp --key 000102030405060708090a0b0c0d0e0f -> fill all the keys with key (00..0f)\n"
|
||||
"hf mfp initp -vv -> fill all the keys with default key(0xff..0xff) and show all the data exchange");
|
||||
"hf mfp initp -vv -> fill all the keys with default key(0xff..0xff) and show all the data exchange"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
@ -700,13 +701,14 @@ static int CmdHFMFPAuth(const char *Cmd) {
|
|||
CLIParserInit(&ctx, "hf mfp auth",
|
||||
"Executes AES authentication command for MIFARE Plus card",
|
||||
"hf mfp auth --ki 4000 --key 000102030405060708090a0b0c0d0e0f -> executes authentication\n"
|
||||
"hf mfp auth --ki 9003 --key FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -v -> executes authentication and shows all the system data");
|
||||
"hf mfp auth --ki 9003 --key FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -v -> executes authentication and shows all the system data"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("v", "verbose", "Verbose output"),
|
||||
arg_str1(NULL, "ki", "<hex>", "Key number, 2 hex bytes"),
|
||||
arg_str1(NULL, "key", "<hex>", "Key, 16 hex bytes"),
|
||||
arg_str1("k", "key", "<hex>", "Key, 16 hex bytes"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
@ -756,7 +758,8 @@ static int CmdHFMFPRdbl(const char *Cmd) {
|
|||
CLIParserInit(&ctx, "hf mfp rdbl",
|
||||
"Reads blocks from MIFARE Plus card",
|
||||
"hf mfp rdbl --blk 0 --key 000102030405060708090a0b0c0d0e0f -> executes authentication and read block 0 data\n"
|
||||
"hf mfp rdbl --blk 1 -v -> executes authentication and shows sector 1 data with default key 0xFF..0xFF");
|
||||
"hf mfp rdbl --blk 1 -v -> executes authentication and shows sector 1 data with default key 0xFF..0xFF"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
@ -874,7 +877,8 @@ static int CmdHFMFPRdsc(const char *Cmd) {
|
|||
CLIParserInit(&ctx, "hf mfp rdsc",
|
||||
"Reads one sector from MIFARE Plus card",
|
||||
"hf mfp rdsc -s 0 --key 000102030405060708090a0b0c0d0e0f -> executes authentication and read sector 0 data\n"
|
||||
"hf mfp rdsc -s 1 -v -> executes authentication and shows sector 1 data with default key");
|
||||
"hf mfp rdsc -s 1 -v -> executes authentication and shows sector 1 data with default key"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
@ -1418,9 +1422,10 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
"Checks keys on MIFARE Plus card",
|
||||
"hf mfp chk -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B\n"
|
||||
"hf mfp chk -s 2 -a -> check default key list on sector 2, only key A\n"
|
||||
"hf mfp chk -d mfp_default_keys -s0 -e6 -> check keys from dictionary against sectors 0-6\n"
|
||||
"hf mfp chk -f mfp_default_keys -s0 -e6 -> check keys from dictionary against sectors 0-6\n"
|
||||
"hf mfp chk --pattern1b --dump -> check all 1-byte keys pattern and save found keys to file\n"
|
||||
"hf mfp chk --pattern2b --startp2b FA00 -> check all 2-byte keys pattern. Start from key FA00FA00...FA00");
|
||||
"hf mfp chk --pattern2b --startp2b FA00 -> check all 2-byte keys pattern. Start from key FA00FA00...FA00"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
@ -1429,7 +1434,7 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
arg_int0("s", "startsec", "<0..255>", "Start sector number"),
|
||||
arg_int0("e", "endsec", "<0..255>", "End sector number"),
|
||||
arg_str0("k", "key", "<hex>", "Key for checking (HEX 16 bytes)"),
|
||||
arg_str0("d", "dict", "<fn>", "Dictionary file with keys"),
|
||||
arg_str0("f", "file", "<fn>", "Dictionary file with default keys"),
|
||||
arg_lit0(NULL, "pattern1b", "Check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)"),
|
||||
arg_lit0(NULL, "pattern2b", "Check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"),
|
||||
arg_str0(NULL, "startp2b", "<pattern>", "Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)"),
|
||||
|
@ -1507,17 +1512,21 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
|
||||
uint8_t startKeyAB = 0;
|
||||
uint8_t endKeyAB = 1;
|
||||
if (keyA && (keyB == false))
|
||||
if (keyA && (keyB == false)) {
|
||||
endKeyAB = 0;
|
||||
}
|
||||
|
||||
if ((keyA == false) && keyB)
|
||||
if ((keyA == false) && keyB) {
|
||||
startKeyAB = 1;
|
||||
}
|
||||
|
||||
if (endSector < startSector)
|
||||
if (endSector < startSector) {
|
||||
endSector = startSector;
|
||||
}
|
||||
|
||||
// 1-byte pattern search mode
|
||||
if (pattern1b) {
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
memset(keyList[i], i, 16);
|
||||
}
|
||||
|
@ -1535,9 +1544,10 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
// dictionary mode
|
||||
size_t endFilePosition = 0;
|
||||
if (dict_filenamelen) {
|
||||
uint32_t keycnt = 0;
|
||||
res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), NULL, 16, &keycnt, 0, &endFilePosition, true);
|
||||
|
||||
uint32_t keycnt = 0;
|
||||
|
||||
res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), NULL, 16, &keycnt, 0, &endFilePosition, true);
|
||||
if (res == PM3_SUCCESS && endFilePosition) {
|
||||
keyListLen = keycnt;
|
||||
PrintAndLogEx(SUCCESS, "First part of dictionary successfully loaded.");
|
||||
|
@ -1604,13 +1614,13 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
char strA[46 + 1] = {0};
|
||||
char strB[46 + 1] = {0};
|
||||
|
||||
uint8_t ndef_key[] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7};
|
||||
|
||||
bool has_ndef_key = false;
|
||||
bool printedHeader = false;
|
||||
for (uint8_t s = startSector; s <= endSector; s++) {
|
||||
|
||||
if ((memcmp(&foundKeys[0][s][1], ndef_key, AES_KEY_LEN) == 0) ||
|
||||
(memcmp(&foundKeys[1][s][1], ndef_key, AES_KEY_LEN) == 0)) {
|
||||
if ((memcmp(&foundKeys[0][s][1], g_mifarep_ndef_key, AES_KEY_LEN) == 0) ||
|
||||
(memcmp(&foundKeys[1][s][1], g_mifarep_ndef_key, AES_KEY_LEN) == 0)) {
|
||||
has_ndef_key = true;
|
||||
}
|
||||
|
||||
|
@ -1637,10 +1647,12 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, " " _YELLOW_("%03d") " | %s | %s", s, strA, strB);
|
||||
}
|
||||
|
||||
if (printedHeader == false)
|
||||
PrintAndLogEx(INFO, "No keys found(");
|
||||
else
|
||||
PrintAndLogEx(INFO, "-----+----------------------------------+----------------------------------\n");
|
||||
if (printedHeader == false) {
|
||||
PrintAndLogEx(INFO, "No keys found");
|
||||
} else {
|
||||
PrintAndLogEx(INFO, "-----+----------------------------------+----------------------------------");
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
||||
// save keys to json
|
||||
if (create_dumpfile && printedHeader) {
|
||||
|
@ -1691,7 +1703,7 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
}
|
||||
|
||||
// MAD detection
|
||||
if ((memcmp(&foundKeys[0][0][1], "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7", AES_KEY_LEN) == 0)) {
|
||||
if ((memcmp(&foundKeys[0][0][1], g_mifarep_mad_key, AES_KEY_LEN) == 0)) {
|
||||
PrintAndLogEx(HINT, "Hint: MAD key detected. Try " _YELLOW_("`hf mfp mad`") " for more details");
|
||||
}
|
||||
|
||||
|
@ -1784,7 +1796,8 @@ static int CmdHFMFPMAD(const char *Cmd) {
|
|||
CLIParserInit(&ctx, "hf mfp mad",
|
||||
"Checks and prints MIFARE Application Directory (MAD)",
|
||||
"hf mfp mad\n"
|
||||
"hf mfp mad --aid e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> read and print NDEF data from MAD aid");
|
||||
"hf mfp mad --aid e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> read and print NDEF data from MAD aid"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
|
|
@ -210,15 +210,18 @@ int MifareAuth4(mf4Session_t *mf4session, const uint8_t *keyn, uint8_t *key, boo
|
|||
uint8_t RndA[17] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00};
|
||||
uint8_t RndB[17] = {0};
|
||||
|
||||
if (silentMode)
|
||||
if (silentMode) {
|
||||
verbose = false;
|
||||
}
|
||||
|
||||
if (mf4session)
|
||||
if (mf4session) {
|
||||
mf4session->Authenticated = false;
|
||||
}
|
||||
|
||||
uint8_t cmd1[] = {0x70, keyn[1], keyn[0], 0x00};
|
||||
int res = ExchangeRAW14a(cmd1, sizeof(cmd1), activateField, true, data, sizeof(data), &datalen, silentMode);
|
||||
if (res != PM3_SUCCESS) {
|
||||
|
||||
if (silentMode == false) {
|
||||
PrintAndLogEx(ERR, "Exchange raw error: %d", res);
|
||||
}
|
||||
|
@ -234,20 +237,35 @@ int MifareAuth4(mf4Session_t *mf4session, const uint8_t *keyn, uint8_t *key, boo
|
|||
}
|
||||
|
||||
if (datalen < 1) {
|
||||
if (!silentMode) PrintAndLogEx(ERR, "Card response wrong length: %d", datalen);
|
||||
if (dropFieldIfError) DropField();
|
||||
if (silentMode == false) {
|
||||
PrintAndLogEx(ERR, "Card response wrong length: %d", datalen);
|
||||
}
|
||||
|
||||
if (dropFieldIfError) {
|
||||
DropField();
|
||||
}
|
||||
return PM3_EWRONGANSWER;
|
||||
}
|
||||
|
||||
if (data[0] != 0x90) {
|
||||
if (!silentMode) PrintAndLogEx(ERR, "Card response error: %02x %s", data[0], mfpGetErrorDescription(data[0]));
|
||||
if (dropFieldIfError) DropField();
|
||||
if (silentMode == false) {
|
||||
PrintAndLogEx(ERR, "Card response error: %02x %s", data[0], mfpGetErrorDescription(data[0]));
|
||||
}
|
||||
|
||||
if (dropFieldIfError) {
|
||||
DropField();
|
||||
}
|
||||
return PM3_EWRONGANSWER;
|
||||
}
|
||||
|
||||
if (datalen != 19) { // code 1b + 16b + crc 2b
|
||||
if (!silentMode) PrintAndLogEx(ERR, "Card response must be 19 bytes long instead of: %d", datalen);
|
||||
if (dropFieldIfError) DropField();
|
||||
if (silentMode == false) {
|
||||
PrintAndLogEx(ERR, "Card response must be 19 bytes long instead of: %d", datalen);
|
||||
}
|
||||
|
||||
if (dropFieldIfError) {
|
||||
DropField();
|
||||
}
|
||||
return PM3_EWRONGANSWER;
|
||||
}
|
||||
|
||||
|
@ -268,11 +286,13 @@ int MifareAuth4(mf4Session_t *mf4session, const uint8_t *keyn, uint8_t *key, boo
|
|||
if (verbose) {
|
||||
PrintAndLogEx(INFO, ">phase2: %s", sprint_hex(cmd2, 33));
|
||||
}
|
||||
|
||||
res = ExchangeRAW14a(cmd2, sizeof(cmd2), false, true, data, sizeof(data), &datalen, silentMode);
|
||||
if (res != PM3_SUCCESS) {
|
||||
if (silentMode == false) {
|
||||
PrintAndLogEx(ERR, "Exchange raw error: %d", res);
|
||||
}
|
||||
|
||||
if (dropFieldIfError) {
|
||||
DropField();
|
||||
}
|
||||
|
@ -291,12 +311,18 @@ int MifareAuth4(mf4Session_t *mf4session, const uint8_t *keyn, uint8_t *key, boo
|
|||
}
|
||||
|
||||
if (memcmp(&raw[4], &RndA[1], 16)) {
|
||||
if (!silentMode) PrintAndLogEx(ERR, "\nAuthentication FAILED. rnd is not equal");
|
||||
if (silentMode == false) {
|
||||
PrintAndLogEx(ERR, "\nAuthentication FAILED. rnd is not equal");
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
PrintAndLogEx(ERR, "RndA reader: %s", sprint_hex(&RndA[1], 16));
|
||||
PrintAndLogEx(ERR, "RndA card: %s", sprint_hex(&raw[4], 16));
|
||||
}
|
||||
if (dropFieldIfError) DropField();
|
||||
|
||||
if (dropFieldIfError) {
|
||||
DropField();
|
||||
}
|
||||
return PM3_EWRONGANSWER;
|
||||
}
|
||||
|
||||
|
@ -309,6 +335,7 @@ int MifareAuth4(mf4Session_t *mf4session, const uint8_t *keyn, uint8_t *key, boo
|
|||
uint8_t kenc[16] = {0};
|
||||
memcpy(&kenc[0], &RndA[11], 5);
|
||||
memcpy(&kenc[5], &RndB[11], 5);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
kenc[10 + i] = RndA[4 + i] ^ RndB[4 + i];
|
||||
}
|
||||
|
@ -322,6 +349,7 @@ int MifareAuth4(mf4Session_t *mf4session, const uint8_t *keyn, uint8_t *key, boo
|
|||
uint8_t kmac[16] = {0};
|
||||
memcpy(&kmac[0], &RndA[7], 5);
|
||||
memcpy(&kmac[5], &RndB[7], 5);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
kmac[10 + i] = RndA[0 + i] ^ RndB[0 + i];
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "mifaredefault.h" // consts
|
||||
#include "protocol_vigik.h"
|
||||
|
||||
#define MIFARE_SECTOR_RETRY 10
|
||||
#define MIFARE_SECTOR_RETRY 6
|
||||
|
||||
// mifare tracer flags
|
||||
#define TRACE_IDLE 0x00
|
||||
|
|
|
@ -5755,8 +5755,8 @@
|
|||
"description": "Checks keys with MIFARE DESFire card.",
|
||||
"notes": [
|
||||
"hf mfdes chk --aid 123456 -k 000102030405060708090a0b0c0d0e0f -> check key on aid 0x123456",
|
||||
"hf mfdes chk -d mfdes_default_keys -> check keys against all existing aid on card",
|
||||
"hf mfdes chk -d mfdes_default_keys --aid 123456 -> check keys against aid 0x123456",
|
||||
"hf mfdes chk -f mfdes_default_keys -> check keys against all existing aid on card",
|
||||
"hf mfdes chk -f mfdes_default_keys --aid 123456 -> check keys against aid 0x123456",
|
||||
"hf mfdes chk --aid 123456 --pattern1b -j keys -> check all 1-byte keys pattern on aid 0x123456 and save found keys to `keys.json`",
|
||||
"hf mfdes chk --aid 123456 --pattern2b --startp2b FA00 -> check all 2-byte keys pattern on aid 0x123456. Start from key FA00FA00...FA00"
|
||||
],
|
||||
|
@ -5765,7 +5765,7 @@
|
|||
"-h, --help This help",
|
||||
"--aid <hex> Use specific AID (3 hex bytes, big endian)",
|
||||
"-k, --key <hex> Key for checking (HEX 16 bytes)",
|
||||
"-d, --dict <fn> Dictionary file with keys",
|
||||
"-f, --file <fn> Filename of dictionary",
|
||||
"--pattern1b Check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)",
|
||||
"--pattern2b Check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)",
|
||||
"--startp2b <pattern> Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)",
|
||||
|
@ -5775,7 +5775,7 @@
|
|||
"-i, --kdfi <hex> KDF input (1-31 hex bytes)",
|
||||
"-a, --apdu Show APDU requests and responses"
|
||||
],
|
||||
"usage": "hf mfdes chk [-hva] [--aid <hex>] [-k <hex>] [-d <fn>] [--pattern1b] [--pattern2b] [--startp2b <pattern>] [-j <fn>] [--kdf <0|1|2>] [-i <hex>]"
|
||||
"usage": "hf mfdes chk [-hva] [--aid <hex>] [-k <hex>] [-f <fn>] [--pattern1b] [--pattern2b] [--startp2b <pattern>] [-j <fn>] [--kdf <0|1|2>] [-i <hex>]"
|
||||
},
|
||||
"hf mfdes chkeysettings": {
|
||||
"command": "hf mfdes chkeysettings",
|
||||
|
@ -6130,7 +6130,7 @@
|
|||
"notes": [
|
||||
"hf mfdes detect -> detect key 0 from PICC level",
|
||||
"hf mfdes detect --schann d40 -> detect key 0 from PICC level via secure channel D40",
|
||||
"hf mfdes detect --dict mfdes_default_keys -> detect key 0 from PICC level with help of the standard dictionary",
|
||||
"hf mfdes detect -f mfdes_default_keys -> detect key 0 from PICC level with help of the standard dictionary",
|
||||
"hf mfdes detect --aid 123456 -n 2 --save -> detect key 2 from app 123456 and if succeed - save params to defaults (`default` command)",
|
||||
"hf mfdes detect --isoid df01 --save -> detect key 0 and save to defaults with card in the LRP mode"
|
||||
],
|
||||
|
@ -6149,10 +6149,10 @@
|
|||
"--schann <d40|ev1|ev2|lrp> Secure channel",
|
||||
"--aid <hex> Application ID (3 hex bytes, big endian)",
|
||||
"--isoid <hex> Application ISO ID (ISO DF ID) (2 hex bytes, big endian).",
|
||||
"--dict <fn> Dictionary file name with keys",
|
||||
"-f, --file <fn> Filename of dictionary",
|
||||
"--save Save found key and parameters to defaults"
|
||||
],
|
||||
"usage": "hf mfdes detect [-hav] [-n <dec>] [-t <DES|2TDEA|3TDEA|AES>] [-k <hex>] [--kdf <none|AN10922|gallagher>] [-i <hex>] [-m <plain|mac|encrypt>] [-c <native|niso|iso>] [--schann <d40|ev1|ev2|lrp>] [--aid <hex>] [--isoid <hex>] [--dict <fn>] [--save]"
|
||||
"usage": "hf mfdes detect [-hav] [-n <dec>] [-t <DES|2TDEA|3TDEA|AES>] [-k <hex>] [--kdf <none|AN10922|gallagher>] [-i <hex>] [-m <plain|mac|encrypt>] [-c <native|niso|iso>] [--schann <d40|ev1|ev2|lrp>] [--aid <hex>] [--isoid <hex>] [-f <fn>] [--save]"
|
||||
},
|
||||
"hf mfdes dump": {
|
||||
"command": "hf mfdes dump",
|
||||
|
@ -6770,9 +6770,9 @@
|
|||
"-h, --help This help",
|
||||
"-v, --verbose Verbose output",
|
||||
"--ki <hex> Key number, 2 hex bytes",
|
||||
"--key <hex> Key, 16 hex bytes"
|
||||
"-k, --key <hex> Key, 16 hex bytes"
|
||||
],
|
||||
"usage": "hf mfp auth [-hv] --ki <hex> --key <hex>"
|
||||
"usage": "hf mfp auth [-hv] --ki <hex> -k <hex>"
|
||||
},
|
||||
"hf mfp chconf": {
|
||||
"command": "hf mfp chconf",
|
||||
|
@ -6806,7 +6806,7 @@
|
|||
"notes": [
|
||||
"hf mfp chk -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B",
|
||||
"hf mfp chk -s 2 -a -> check default key list on sector 2, only key A",
|
||||
"hf mfp chk -d mfp_default_keys -s0 -e6 -> check keys from dictionary against sectors 0-6",
|
||||
"hf mfp chk -f mfp_default_keys -s0 -e6 -> check keys from dictionary against sectors 0-6",
|
||||
"hf mfp chk --pattern1b --dump -> check all 1-byte keys pattern and save found keys to file",
|
||||
"hf mfp chk --pattern2b --startp2b FA00 -> check all 2-byte keys pattern. Start from key FA00FA00...FA00"
|
||||
],
|
||||
|
@ -6818,14 +6818,14 @@
|
|||
"-s, --startsec <0..255> Start sector number",
|
||||
"-e, --endsec <0..255> End sector number",
|
||||
"-k, --key <hex> Key for checking (HEX 16 bytes)",
|
||||
"-d, --dict <fn> Dictionary file with keys",
|
||||
"-f, --file <fn> Dictionary file with default keys",
|
||||
"--pattern1b Check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)",
|
||||
"--pattern2b Check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)",
|
||||
"--startp2b <pattern> Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)",
|
||||
"--dump Dump found keys to JSON file",
|
||||
"-v, --verbose Verbose output"
|
||||
],
|
||||
"usage": "hf mfp chk [-habv] [-s <0..255>] [-e <0..255>] [-k <hex>] [-d <fn>] [--pattern1b] [--pattern2b] [--startp2b <pattern>] [--dump]"
|
||||
"usage": "hf mfp chk [-habv] [-s <0..255>] [-e <0..255>] [-k <hex>] [-f <fn>] [--pattern1b] [--pattern2b] [--startp2b <pattern>] [--dump]"
|
||||
},
|
||||
"hf mfp chkey": {
|
||||
"command": "hf mfp chkey",
|
||||
|
@ -13376,6 +13376,6 @@
|
|||
"metadata": {
|
||||
"commands_extracted": 768,
|
||||
"extracted_by": "PM3Help2JSON v1.00",
|
||||
"extracted_on": "2025-06-08T17:26:24"
|
||||
"extracted_on": "2025-06-08T18:54:12"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue