hf 14a: add config loopholes to deal with badly configured cards: invalid ATQA, invalid BCC, invalid SAK

This commit is contained in:
Philippe Teuwen
2020-09-07 00:48:36 +02:00
parent 007fc0893d
commit b751354ea2
11 changed files with 243 additions and 22 deletions

View File

@@ -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}
};

View File

@@ -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);

View File

@@ -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;