hf 14a: add config loopholes to deal with badly configured cards: invalid ATQA, invalid BCC, invalid SAK
This commit is contained in:
@@ -168,6 +168,23 @@ const char *getTagInfo(uint8_t uid) {
|
||||
static uint16_t frameLength = 0;
|
||||
uint16_t atsFSC[] = {16, 24, 32, 40, 48, 64, 96, 128, 256};
|
||||
|
||||
static int usage_hf_14a_config(void) {
|
||||
PrintAndLogEx(NORMAL, "Usage: hf 14a config [a 0|1] [b 0|1]");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h This help");
|
||||
PrintAndLogEx(NORMAL, " a 0|1 Force standard anticollision sequence even if ATQA tells not to do it");
|
||||
PrintAndLogEx(NORMAL, " b 0|1 Obey bad BCC in anticollision sequence");
|
||||
PrintAndLogEx(NORMAL, " 2 0|1|-1 Override CL2 decision: 0=auto, 1=always perform CL2, -1=never perform CL2");
|
||||
PrintAndLogEx(NORMAL, " 3 0|1|-1 Override CL3 decision: 0=auto, 1=always perform CL3, -1=never perform CL3");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config ")" Print current configuration");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a ")" Force standard anticollision");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 0 ")" Restore ATQA interpretation");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config b ")" Force obey bad BCC in anticollision");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config b 0 ")" Restore BCC computation in anticollision");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_hf_14a_sim(void) {
|
||||
// PrintAndLogEx(NORMAL, "\n Emulating ISO/IEC 14443 type A tag with 4,7 or 10 byte UID\n");
|
||||
PrintAndLogEx(NORMAL, "\n Emulating ISO/IEC 14443 type A tag with 4,7 byte UID\n");
|
||||
@@ -234,6 +251,98 @@ static int CmdHF14AList(const char *Cmd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hf14a_getconfig(hf14a_config *config) {
|
||||
if (!session.pm3_present) return PM3_ENOTTY;
|
||||
|
||||
if (config == NULL)
|
||||
return PM3_EINVARG;
|
||||
|
||||
clearCommandBuffer();
|
||||
|
||||
SendCommandNG(CMD_HF_ISO14443A_GET_CONFIG, NULL, 0);
|
||||
PacketResponseNG resp;
|
||||
if (!WaitForResponseTimeout(CMD_HF_ISO14443A_GET_CONFIG, &resp, 2000)) {
|
||||
PrintAndLogEx(WARNING, "command execution time out");
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
memcpy(config, resp.data.asBytes, sizeof(hf14a_config));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int hf14a_setconfig(hf14a_config *config) {
|
||||
if (!session.pm3_present) return PM3_ENOTTY;
|
||||
|
||||
clearCommandBuffer();
|
||||
if (config != NULL)
|
||||
SendCommandNG(CMD_HF_ISO14443A_SET_CONFIG, (uint8_t *)config, sizeof(hf14a_config));
|
||||
else
|
||||
SendCommandNG(CMD_HF_ISO14443A_PRINT_CONFIG, NULL, 0);
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHf14AConfig(const char *Cmd) {
|
||||
|
||||
if (!session.pm3_present) return PM3_ENOTTY;
|
||||
|
||||
// if called with no params, just print the device config
|
||||
if (strlen(Cmd) == 0) {
|
||||
return hf14a_setconfig(NULL);
|
||||
}
|
||||
|
||||
hf14a_config config = {
|
||||
.forceanticol = -1,
|
||||
.obeybadbcc = -1,
|
||||
.forcecl2 = -2,
|
||||
.forcecl3 = -2
|
||||
};
|
||||
|
||||
bool errors = false;
|
||||
char cl[3] = {0};
|
||||
uint8_t cmdp = 0;
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch (param_getchar(Cmd, cmdp)) {
|
||||
case 'h':
|
||||
return usage_hf_14a_config();
|
||||
case 'a':
|
||||
config.forceanticol = (param_getchar(Cmd, cmdp + 1) == '1');
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'b':
|
||||
config.obeybadbcc = (param_getchar(Cmd, cmdp + 1) == '1');
|
||||
cmdp += 2;
|
||||
break;
|
||||
case '2':
|
||||
param_getstr(Cmd, cmdp + 1, cl, sizeof(cl));
|
||||
if (strcmp(cl, "-1") == 0) {
|
||||
config.forcecl2 = -1;
|
||||
} else {
|
||||
config.forcecl2 = strcmp(cl, "1") == 0;
|
||||
}
|
||||
cmdp += 2;
|
||||
break;
|
||||
case '3':
|
||||
param_getstr(Cmd, cmdp + 1, cl, sizeof(cl));
|
||||
if (strcmp(cl, "-1") == 0) {
|
||||
config.forcecl3 = -1;
|
||||
} else {
|
||||
config.forcecl3 = strcmp(cl, "1") == 0;
|
||||
}
|
||||
cmdp += 2;
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// validations
|
||||
if (errors) return usage_hf_14a_config();
|
||||
|
||||
return hf14a_setconfig(&config);
|
||||
}
|
||||
|
||||
int Hf14443_4aGetCardData(iso14a_card_select_t *card) {
|
||||
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0);
|
||||
|
||||
@@ -1241,6 +1350,7 @@ static command_t CommandTable[] = {
|
||||
{"chaining", CmdHF14AChaining, IfPm3Iso14443a, "Control ISO 14443-4 input chaining"},
|
||||
{"raw", CmdHF14ACmdRaw, IfPm3Iso14443a, "Send raw hex data to tag"},
|
||||
{"antifuzz", CmdHF14AAntiFuzz, IfPm3Iso14443a, "Fuzzing the anticollision phase. Warning! Readers may react strange"},
|
||||
{"config", CmdHf14AConfig, IfPm3Iso14443a, "Configure 14a settings (use with caution)"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#define CMDHF14A_H__
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "pm3_cmd.h" //hf14a_config
|
||||
#include "mifare.h" // structs
|
||||
|
||||
// structure and database for uid -> tagtype lookups
|
||||
@@ -26,6 +26,8 @@ int CmdHF14A(const char *Cmd);
|
||||
int CmdHF14ASniff(const char *Cmd); // used by hf topaz sniff
|
||||
int CmdHF14ASim(const char *Cmd); // used by hf mfu sim
|
||||
|
||||
int hf14a_getconfig(hf14a_config *config);
|
||||
int hf14a_setconfig(hf14a_config *config);
|
||||
int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search);
|
||||
const char *getTagInfo(uint8_t uid);
|
||||
int Hf14443_4aGetCardData(iso14a_card_select_t *card);
|
||||
|
||||
@@ -22,7 +22,6 @@ extern "C" {
|
||||
#define _USE_MATH_DEFINES
|
||||
|
||||
typedef enum logLevel {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG, INPLACE, HINT} logLevel_t;
|
||||
#define NOLF "\xff"
|
||||
typedef enum emojiMode {ALIAS, EMOJI, ALTTEXT, ERASE} emojiMode_t;
|
||||
typedef enum clientdebugLevel {cdbOFF, cdbSIMPLE, cdbFULL} clientdebugLevel_t;
|
||||
// typedef enum devicedebugLevel {ddbOFF, ddbERROR, ddbINFO, ddbDEBUG, ddbEXTENDED} devicedebugLevel_t;
|
||||
|
||||
Reference in New Issue
Block a user