added "hf 14a ndefwrite" - writes ndef to type4a tag

This commit is contained in:
iceman1001 2022-10-24 18:48:56 +02:00
commit 2025c8480a
6 changed files with 561 additions and 67 deletions

View file

@ -18,9 +18,9 @@
#include "cmdhf14a.h" #include "cmdhf14a.h"
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include "cmdparser.h" // command_t #include "cmdparser.h" // command_t
#include "commonutil.h" // ARRAYLEN #include "commonutil.h" // ARRAYLEN
#include "comms.h" // clearCommandBuffer #include "comms.h" // clearCommandBuffer
#include "cmdtrace.h" #include "cmdtrace.h"
#include "cliparser.h" #include "cliparser.h"
#include "cmdhfmf.h" #include "cmdhfmf.h"
@ -29,16 +29,18 @@
#include "emv/emvcore.h" #include "emv/emvcore.h"
#include "ui.h" #include "ui.h"
#include "crc16.h" #include "crc16.h"
#include "util_posix.h" // msclock #include "util_posix.h" // msclock
#include "aidsearch.h" #include "aidsearch.h"
#include "cmdhf.h" // handle HF plot #include "cmdhf.h" // handle HF plot
#include "cliparser.h" #include "cliparser.h"
#include "protocols.h" // definitions of ISO14A/7816 protocol, MAGIC_GEN_1A #include "protocols.h" // definitions of ISO14A/7816 protocol, MAGIC_GEN_1A
#include "iso7816/apduinfo.h" // GetAPDUCodeDescription #include "iso7816/apduinfo.h" // GetAPDUCodeDescription
#include "nfc/ndef.h" // NDEFRecordsDecodeAndPrint #include "nfc/ndef.h" // NDEFRecordsDecodeAndPrint
#include "cmdnfc.h" // print_type4_cc_info #include "cmdnfc.h" // print_type4_cc_info
#include "fileutils.h" // saveFile #include "fileutils.h" // saveFile
#include "atrs.h" // getATRinfo #include "atrs.h" // getATRinfo
#include "desfire.h" // desfire enums
#include "mifare/desfirecore.h" // desfire context
static bool APDUInFramingEnable = true; static bool APDUInFramingEnable = true;
@ -2692,7 +2694,6 @@ int CmdHF14ANdefRead(const char *Cmd) {
keep_field_on = true; keep_field_on = true;
// --------------- CC file reading ---------------- // --------------- CC file reading ----------------
uint8_t aSELECT_FILE_CC[30]; uint8_t aSELECT_FILE_CC[30];
int aSELECT_FILE_CC_n = 0; int aSELECT_FILE_CC_n = 0;
if (backward_compatibility_v1) { if (backward_compatibility_v1) {
@ -2733,7 +2734,10 @@ int CmdHF14ANdefRead(const char *Cmd) {
memcpy(cc_data, response, sizeof(cc_data)); memcpy(cc_data, response, sizeof(cc_data));
uint8_t file_id[2] = {cc_data[9], cc_data[10]}; uint8_t file_id[2] = {cc_data[9], cc_data[10]};
print_type4_cc_info(cc_data, sizeof(cc_data)); if (verbose) {
print_type4_cc_info(cc_data, sizeof(cc_data));
}
uint16_t max_rapdu_size = (cc_data[3] << 8 | cc_data[4]) - 2; uint16_t max_rapdu_size = (cc_data[3] << 8 | cc_data[4]) - 2;
max_rapdu_size = max_rapdu_size < sizeof(response) - 2 ? max_rapdu_size : sizeof(response) - 2; max_rapdu_size = max_rapdu_size < sizeof(response) - 2 ? max_rapdu_size : sizeof(response) - 2;
@ -2760,7 +2764,6 @@ int CmdHF14ANdefRead(const char *Cmd) {
} }
// read first 2 bytes to get NDEF length // read first 2 bytes to get NDEF length
uint8_t aREAD_NDEF[30]; uint8_t aREAD_NDEF[30];
int aREAD_NDEF_n = 0; int aREAD_NDEF_n = 0;
param_gethex_to_eol("00b0000002", 0, aREAD_NDEF, sizeof(aREAD_NDEF), &aREAD_NDEF_n); param_gethex_to_eol("00b0000002", 0, aREAD_NDEF, sizeof(aREAD_NDEF), &aREAD_NDEF_n);
@ -2836,21 +2839,442 @@ int CmdHF14ANdefRead(const char *Cmd) {
return PM3_SUCCESS; return PM3_SUCCESS;
} }
int CmdHF14ANdefFormat(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14a ndefformat",
"Format ISO14443-a Tag as a NFC tag with Data Exchange Format (NDEF)",
"hf 14a ndefformat\n"
);
void *argtable[] = {
arg_param_begin,
arg_litn("v", "verbose", 0, 2, "show technical data"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool verbose = arg_get_lit(ctx, 1);
CLIParserFree(ctx);
if (g_session.pm3_present == false)
return PM3_ENOTTY;
bool activate_field = true;
bool keep_field_on = false;
uint8_t response[PM3_CMD_DATA_SIZE];
int resplen = 0;
SetAPDULogging(false);
// step 1 - Select NDEF Tag application
uint8_t aSELECT_AID[80];
int aSELECT_AID_n = 0;
param_gethex_to_eol("00a4040007d276000085010100", 0, aSELECT_AID, sizeof(aSELECT_AID), &aSELECT_AID_n);
int res = ExchangeAPDU14a(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
if (res != PM3_SUCCESS) {
return res;
}
if (resplen < 2) {
return PM3_ESOFT;
}
bool have_application = true;
uint16_t sw = get_sw(response, resplen);
if (sw != 0x9000) {
have_application = false;
PrintAndLogEx(INFO, "no NDEF application found");
} else {
PrintAndLogEx(INFO, "found ndef application");
}
// setup desfire authentication context
uint8_t empty_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
DesfireContext_t dctx;
dctx.secureChannel = DACNone;
DesfireSetKey(&dctx, 0, T_DES, empty_key);
DesfireSetKdf(&dctx, MFDES_KDF_ALGO_NONE, NULL, 0);
DesfireSetCommandSet(&dctx, DCCNativeISO);
DesfireSetCommMode(&dctx, DCMPlain);
// step 1 - create application
if (have_application == false) {
// "hf mfdes createapp --aid 000001 --fid E110 --ks1 0B --ks2 A1 --dfhex D2760000850101 -t des -n 0 -k 0000000000000000"
PrintAndLogEx(INFO, "creating NDEF application...");
// authenticae first to AID 00 00 00
res = DesfireSelectAndAuthenticateEx(&dctx, DACEV1, 0x000000, false, verbose);
if (res != PM3_SUCCESS) {
DropField();
PrintAndLogEx(INFO, "failed empty auth..");
return res;
}
// create application
uint8_t dfname[] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
uint8_t ks1 = 0x0B;
uint8_t ks2 = 0xA1; // bit FileID in ks2
uint32_t appid = 0x0000001;
uint16_t fileid = 0xE110;
uint8_t data[250] = {0};
size_t datalen = 0;
DesfireAIDUintToByte(appid, &data[0]);
data[3] = ks1;
data[4] = ks2;
Uint2byteToMemLe(&data[5], fileid);
memcpy(&data[7], dfname, sizeof(dfname));
datalen = 14;
if (verbose) {
PrintAndLogEx(INFO, "---------------------------");
PrintAndLogEx(INFO, _CYAN_("Creating Application using:"));
PrintAndLogEx(INFO, "AID........... 0x%02X%02X%02X", data[2], data[1], data[0]);
PrintAndLogEx(INFO, "Key Set 1..... 0x%02X", data[3]);
PrintAndLogEx(INFO, "Key Set 2..... 0x%02X", data[4]);
PrintAndLogEx(INFO, "ISO file ID... %s", (data[4] & 0x20) ? "enabled" : "disabled");
if ((data[4] & 0x20)) {
PrintAndLogEx(INFO, "ISO file ID... 0x%04X", MemLeToUint2byte(&data[5]));
PrintAndLogEx(INFO, "DF Name[%02d] %s | %s\n", 7, sprint_ascii(dfname, sizeof(dfname)), sprint_hex(dfname, sizeof(dfname)));
}
PrintKeySettings(data[3], data[4], true, true);
PrintAndLogEx(INFO, "---------------------------");
}
res = DesfireCreateApplication(&dctx, data, datalen);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire CreateApplication command " _RED_("error") ". Result: %d", res);
DropField();
return PM3_ESOFT;
}
PrintAndLogEx(SUCCESS, "Desfire application %06x successfully " _GREEN_("created"), appid);
// step 2 - create capability container (CC File)
// authenticae to the new AID 00 00 01
uint8_t aes_key[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
dctx.secureChannel = DACNone;
DesfireSetKey(&dctx, 0, T_AES, aes_key);
DesfireSetKdf(&dctx, MFDES_KDF_ALGO_NONE, NULL, 0);
DesfireSetCommandSet(&dctx, DCCNativeISO);
DesfireSetCommMode(&dctx, DCMPlain);
res = DesfireSelectAndAuthenticateEx(&dctx, DACEV1, 0x000001, false, verbose);
if (res != PM3_SUCCESS) {
DropField();
PrintAndLogEx(INFO, "failed aid auth..");
return res;
}
// hf mfdes createfile --aid 000001 --fid 01 --isofid E103 --amode plain --size 00000F
// --rrights free --wrights key0 --rwrights key0 --chrights key0
// -n 0 -t aes -k 00000000000000000000000000000000 -m plain
uint8_t fid = 0x01;
uint16_t isofid = 0xE103;
uint32_t fsize = 0x0F;
uint8_t filetype = 0x00; // standard file
// file access mode: plain 0x00
// read access: free 0x0E
// write access: key0 0x00
// r/w access: key0 0x00
// change access: key0 0x00
memset(data, 0x00, sizeof(data));
datalen = 0;
data[0] = fid;
data[1] = isofid & 0xff;
data[2] = (isofid >> 8) & 0xff;
datalen = 3;
uint8_t *settings = &data[datalen];
settings[0] = 0x00;
datalen++;
DesfireEncodeFileAcessMode(&settings[1], 0x0E, 0x00, 0x00, 0x00) ;
datalen += 2;
Uint3byteToMemLe(&data[datalen], fsize);
datalen += 3;
if (verbose) {
PrintAndLogEx(INFO, "App: %06x. File num: 0x%02x type: 0x%02x data[%zu]: %s", appid, data[0], filetype, datalen, sprint_hex(data, datalen));
}
DesfirePrintCreateFileSettings(filetype, data, datalen);
res = DesfireCreateFile(&dctx, filetype, data, datalen, true); // check length only if we dont use raw mode
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire CreateFile command " _RED_("error") ". Result: %d", res);
DropField();
return PM3_ESOFT;
}
PrintAndLogEx(SUCCESS, "%s file %02x in the app %06x created " _GREEN_("successfully"), GetDesfireFileType(filetype), data[0], appid);
// hf mfdes write --aid 000001 --fid 01 -d 000F20003B00340406E10400FF00FF
// -n 0 -t aes -k 00000000000000000000000000000000 -m plain
res = DesfireSelectAndAuthenticateEx(&dctx, DACEV1, 0x000001, false, verbose);
if (res != PM3_SUCCESS) {
DropField();
PrintAndLogEx(INFO, "failed aid auth..");
return res;
}
uint8_t fnum = 0x01;
uint32_t offset = 0;
uint8_t cc_data[] = {0x00, 0x0F, 0x20, 0x00, 0x3B, 0x00, 0x34, 0x04, 0x06, 0xE1, 0x04, 0x00, 0xFF, 0x00, 0x00};
res = DesfireWriteFile(&dctx, fnum, offset, sizeof(cc_data), cc_data);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire WriteFile command " _RED_("error") ". Result: %d", res);
DropField();
return PM3_ESOFT;
}
if (verbose) {
PrintAndLogEx(INFO, "Write data file %02x " _GREEN_("success"), fnum);
}
// step 3 - create NDEF record file
// hf mfdes write --aid 000001 --fid 02 -d 000CD1010855016E78702E636F6DFE
// -n 0 -t aes -k 00000000000000000000000000000000 -m plain
fid = 0x02;
isofid = 0xE104;
fsize = 0xFF;
filetype = 0x00; // standard file
// file access mode: plain 0x00
// read access: free 0x0E
// write access: key0 0x00
// r/w access: key0 0x00
// change access: key0 0x00
memset(data, 0x00, sizeof(data));
datalen = 0;
data[0] = fid;
data[1] = isofid & 0xff;
data[2] = (isofid >> 8) & 0xff;
datalen = 3;
settings = &data[datalen];
settings[0] = 0x00;
datalen++;
DesfireEncodeFileAcessMode(&settings[1], 0x0E, 0x00, 0x00, 0x00) ;
datalen += 2;
Uint3byteToMemLe(&data[datalen], fsize);
datalen += 3;
if (verbose) {
PrintAndLogEx(INFO, "App: %06x. File num: 0x%02x type: 0x%02x data[%zu]: %s", appid, data[0], filetype, datalen, sprint_hex(data, datalen));
}
DesfirePrintCreateFileSettings(filetype, data, datalen);
res = DesfireCreateFile(&dctx, filetype, data, datalen, true); // check length only if we dont use raw mode
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire CreateFile command " _RED_("error") ". Result: %d", res);
DropField();
return PM3_ESOFT;
}
PrintAndLogEx(SUCCESS, "%s file %02x in the app %06x created " _GREEN_("successfully"), GetDesfireFileType(filetype), data[0], appid);
DropField();
}
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "finished");
return PM3_SUCCESS;
}
int CmdHF14ANdefWrite(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14a ndefwrite",
"Write raw NDEF hex bytes to tag. This commands assumes tag already been NFC/NDEF formatted.\n",
"hf 14a ndefwrite -d 0300FE -> write empty record to tag\n"
"hf 14a ndefwrite -f myfilename\n"
"hf 14a ndefwrite -d 003fd1023a53709101195405656e2d55534963656d616e2054776974746572206c696e6b5101195502747769747465722e636f6d2f686572726d616e6e31303031\n"
);
void *argtable[] = {
arg_param_begin,
arg_str0("d", NULL, "<hex>", "raw NDEF hex bytes"),
arg_str0("f", "file", "<fn>", "write raw NDEF file to tag"),
arg_lit0("p", NULL, "fix NDEF record headers / terminator block if missing"),
arg_lit0("v", "verbose", "verbose output"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
uint8_t raw[256] = {0};
int rawlen = 0;
CLIGetHexWithReturn(ctx, 1, raw, &rawlen);
int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
bool fix_msg = arg_get_lit(ctx, 3);
bool verbose = arg_get_lit(ctx, 4);
CLIParserFree(ctx);
if (g_session.pm3_present == false) {
return PM3_ENOTTY;
}
if ((rawlen && fnlen) || (rawlen == 0 && fnlen == 0)) {
PrintAndLogEx(WARNING, "Please specify either raw hex or filename");
return PM3_EINVARG;
}
int res = PM3_SUCCESS;
int32_t bytes = rawlen;
// read dump file
if (fnlen) {
uint8_t *dump = NULL;
size_t bytes_read = 0;
res = pm3_load_dump(filename, (void **)&dump, &bytes_read, sizeof(raw));
if (res != PM3_SUCCESS) {
return res;
}
memcpy(raw, dump, bytes_read);
bytes = bytes_read;
free(dump);
}
if (verbose) {
PrintAndLogEx(INFO, "Num of bytes... %i (raw %i)", bytes, rawlen);
}
// Has raw bytes ndef message header?bytes
switch (raw[0]) {
case 0x00:
case 0x01:
case 0x02:
case 0x03:
case 0xFD:
case 0xFE:
break;
default: {
if (fix_msg == false) {
PrintAndLogEx(WARNING, "raw NDEF message doesn't have a proper header, continuing...");
} else {
if (bytes + 2 > sizeof(raw)) {
PrintAndLogEx(WARNING, "no room for header, exiting...");
return PM3_EMALLOC;
}
uint8_t tmp_raw[256];
memcpy(tmp_raw, raw, sizeof(tmp_raw));
raw[0] = 0x03;
raw[1] = bytes;
memcpy(raw + 2, tmp_raw, sizeof(raw) - 2);
bytes += 2;
PrintAndLogEx(SUCCESS, "Added generic message header (0x03)");
}
}
}
// Has raw bytes ndef a terminator block?
if (raw[bytes - 1] != 0xFE) {
if (fix_msg == false) {
PrintAndLogEx(WARNING, "raw NDEF message doesn't have a terminator block, continuing...");
} else {
if (bytes + 1 > sizeof(raw)) {
PrintAndLogEx(WARNING, "no room for terminator block, exiting...");
return PM3_EMALLOC;
}
raw[bytes] = 0xFE;
bytes++;
PrintAndLogEx(SUCCESS, "Added terminator block (0xFE)");
}
}
if (verbose) {
PrintAndLogEx(INFO, "Num of Bytes... %u", bytes);
print_buffer(raw, bytes, 0);
}
// setup desfire authentication context
// authenticae to the new AID 00 00 01
uint8_t aes_key[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
DesfireContext_t dctx;
dctx.secureChannel = DACNone;
DesfireSetKey(&dctx, 0, T_AES, aes_key);
DesfireSetKdf(&dctx, MFDES_KDF_ALGO_NONE, NULL, 0);
DesfireSetCommandSet(&dctx, DCCNativeISO);
DesfireSetCommMode(&dctx, DCMPlain);
res = DesfireSelectAndAuthenticateEx(&dctx, DACEV1, 0x000001, false, verbose);
if (res != PM3_SUCCESS) {
DropField();
PrintAndLogEx(INFO, "failed aid auth..");
return res;
}
// write ndef file
// hf mfdes write --aid 000002 --fid 02 -
// -n 0 -t aes -k 00000000000000000000000000000000 -m plain
uint8_t fnum = 0x02;
uint32_t offset = 0;
res = DesfireWriteFile(&dctx, fnum, offset, bytes, raw);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire WriteFile command " _RED_("error") ". Result: %d", res);
DropField();
return PM3_ESOFT;
}
if (verbose) {
PrintAndLogEx(INFO, "Write data file %02x " _GREEN_("success"), fnum);
}
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "finished");
return PM3_SUCCESS;
}
static command_t CommandTable[] = { static command_t CommandTable[] = {
{"-----------", CmdHelp, AlwaysAvailable, "----------------------- " _CYAN_("General") " -----------------------"},
{"help", CmdHelp, AlwaysAvailable, "This help"}, {"help", CmdHelp, AlwaysAvailable, "This help"},
{"list", CmdHF14AList, AlwaysAvailable, "List ISO 14443-a history"}, {"list", CmdHF14AList, AlwaysAvailable, "List ISO 14443-a history"},
{"info", CmdHF14AInfo, IfPm3Iso14443a, "Tag information"}, {"-----------", CmdHelp, IfPm3Iso14443a, "---------------------- " _CYAN_("operations") " ---------------------"},
{"reader", CmdHF14AReader, IfPm3Iso14443a, "Act like an ISO14443-a reader"},
{"ndefread", CmdHF14ANdefRead, IfPm3Iso14443a, "Read an NDEF file from ISO 14443-A Type 4 tag"},
{"cuids", CmdHF14ACUIDs, IfPm3Iso14443a, "Collect n>0 ISO14443-a UIDs in one go"},
{"sim", CmdHF14ASim, IfPm3Iso14443a, "Simulate ISO 14443-a tag"},
{"sniff", CmdHF14ASniff, IfPm3Iso14443a, "sniff ISO 14443-a traffic"},
{"apdu", CmdHF14AAPDU, IfPm3Iso14443a, "Send ISO 14443-4 APDU to tag"},
{"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"}, {"antifuzz", CmdHF14AAntiFuzz, IfPm3Iso14443a, "Fuzzing the anticollision phase. Warning! Readers may react strange"},
{"config", CmdHf14AConfig, IfPm3Iso14443a, "Configure 14a settings (use with caution)"}, {"config", CmdHf14AConfig, IfPm3Iso14443a, "Configure 14a settings (use with caution)"},
{"cuids", CmdHF14ACUIDs, IfPm3Iso14443a, "Collect n>0 ISO14443-a UIDs in one go"},
{"info", CmdHF14AInfo, IfPm3Iso14443a, "Tag information"},
{"sim", CmdHF14ASim, IfPm3Iso14443a, "Simulate ISO 14443-a tag"},
{"sniff", CmdHF14ASniff, IfPm3Iso14443a, "sniff ISO 14443-a traffic"},
{"raw", CmdHF14ACmdRaw, IfPm3Iso14443a, "Send raw hex data to tag"},
{"reader", CmdHF14AReader, IfPm3Iso14443a, "Act like an ISO14443-a reader"},
{"-----------", CmdHelp, IfPm3Iso14443a, "------------------------- " _CYAN_("apdu") " -------------------------"},
{"apdu", CmdHF14AAPDU, IfPm3Iso14443a, "Send ISO 14443-4 APDU to tag"},
{"apdufind", CmdHf14AFindapdu, IfPm3Iso14443a, "Enumerate APDUs - CLA/INS/P1P2"}, {"apdufind", CmdHf14AFindapdu, IfPm3Iso14443a, "Enumerate APDUs - CLA/INS/P1P2"},
{"chaining", CmdHF14AChaining, IfPm3Iso14443a, "Control ISO 14443-4 input chaining"},
{"-----------", CmdHelp, IfPm3Iso14443a, "------------------------- " _CYAN_("ndef") " -------------------------"},
{"ndefformat", CmdHF14ANdefFormat, IfPm3Iso14443a, "Format ISO 14443-A as NFC Type 4 tag"},
{"ndefread", CmdHF14ANdefRead, IfPm3Iso14443a, "Read an NDEF file from ISO 14443-A Type 4 tag"},
{"ndefwrite", CmdHF14ANdefWrite, IfPm3Iso14443a, "Write NDEF records to ISO 14443-A tag"},
{NULL, NULL, NULL, NULL} {NULL, NULL, NULL, NULL}
}; };

View file

@ -37,9 +37,11 @@ typedef struct {
} hintAIDList_t; } hintAIDList_t;
int CmdHF14A(const char *Cmd); int CmdHF14A(const char *Cmd);
int CmdHF14ASniff(const char *Cmd); // used by hf topaz sniff int CmdHF14ASniff(const char *Cmd); // used by hf topaz sniff
int CmdHF14ASim(const char *Cmd); // used by hf mfu sim int CmdHF14ASim(const char *Cmd); // used by hf mfu sim
int CmdHF14ANdefRead(const char *Cmd); int CmdHF14ANdefRead(const char *Cmd); // used by cmdnfc.c
int CmdHF14ANdefFormat(const char *Cmd); // used by cmdnfc.c
int CmdHF14ANdefWrite(const char *Cmd); // used by cmdnfc.c
int hf14a_getconfig(hf14a_config *config); int hf14a_getconfig(hf14a_config *config);
int hf14a_setconfig(hf14a_config *config, bool verbose); int hf14a_setconfig(hf14a_config *config, bool verbose);

View file

@ -223,20 +223,28 @@ static int CmdNFCST25TARead(const char *Cmd) {
return CmdHFST25TANdefRead(Cmd); return CmdHFST25TANdefRead(Cmd);
} }
static int CmdNFCType4AFormat(const char *Cmd) {
return CmdHF14ANdefFormat(Cmd);
}
static int CmdNFCType4AWrite(const char *Cmd) {
return CmdHF14ANdefWrite(Cmd);
}
static int CmdNFCType4AHelp(const char *Cmd); static int CmdNFCType4AHelp(const char *Cmd);
static command_t CommandNFCType4ATable[] = { static command_t CommandNFCType4ATable[] = {
{"--------", CmdNFCType4AHelp, AlwaysAvailable, "--------- " _CYAN_("NFC Forum Tag Type 4 ISO14443A") " ----------"}, {"--------", CmdNFCType4AHelp, AlwaysAvailable, "--------- " _CYAN_("NFC Forum Tag Type 4 ISO14443A") " ----------"},
// {"format", CmdNFCType4AFormat, IfPm3Iso14443a, "format ISO-14443-a tag as NFC Tag"}, {"format", CmdNFCType4AFormat, IfPm3Iso14443a, "format ISO-14443-a tag as NFC Tag"},
{"read", CmdNFCType4ARead, IfPm3Iso14443a, "read NFC Forum Tag Type 4 A"}, {"read", CmdNFCType4ARead, IfPm3Iso14443a, "read NFC Forum Tag Type 4 A"},
// {"write", CmdNFCType4AWrite, IfPm3Iso14443a, "write NFC Forum Tag Type 4 A"}, {"write", CmdNFCType4AWrite, IfPm3Iso14443a, "write NFC Forum Tag Type 4 A"},
// {"mfdesread", CmdNFCMFDESRead, IfPm3Iso14443a, "read NDEF from MIFARE DESfire"}, // hf mfdes ndefread // {"mfdesread", CmdNFCMFDESRead, IfPm3Iso14443a, "read NDEF from MIFARE DESfire"}, // hf mfdes ndefread
// {"mfdesformat", CmdNFCMFDESFormat, IfPm3Iso14443a, "format MIFARE DESfire as NFC Forum Tag Type 4"}, // {"mfdesformat", CmdNFCMFDESFormat, IfPm3Iso14443a, "format MIFARE DESfire as NFC Forum Tag Type 4"},
{"st25taread", CmdNFCST25TARead, IfPm3Iso14443a, "read ST25TA as NFC Forum Tag Type 4"}, {"st25taread", CmdNFCST25TARead, IfPm3Iso14443a, "read ST25TA as NFC Forum Tag Type 4"},
{"--------", CmdNFCType4AHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, {"--------", CmdNFCType4AHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
{"help", CmdNFCType4AHelp, AlwaysAvailable, "This help"}, {"help", CmdNFCType4AHelp, AlwaysAvailable, "This help"},
{NULL, NULL, NULL, NULL} {NULL, NULL, NULL, NULL}
}; };

View file

@ -134,18 +134,20 @@ const static vocabulory_t vocabulory[] = {
{ 0, "hf sniff" }, { 0, "hf sniff" },
{ 1, "hf 14a help" }, { 1, "hf 14a help" },
{ 1, "hf 14a list" }, { 1, "hf 14a list" },
{ 0, "hf 14a info" },
{ 0, "hf 14a reader" },
{ 0, "hf 14a ndefread" },
{ 0, "hf 14a cuids" },
{ 0, "hf 14a sim" },
{ 0, "hf 14a sniff" },
{ 0, "hf 14a apdu" },
{ 0, "hf 14a chaining" },
{ 0, "hf 14a raw" },
{ 0, "hf 14a antifuzz" }, { 0, "hf 14a antifuzz" },
{ 0, "hf 14a config" }, { 0, "hf 14a config" },
{ 0, "hf 14a cuids" },
{ 0, "hf 14a info" },
{ 0, "hf 14a sim" },
{ 0, "hf 14a sniff" },
{ 0, "hf 14a raw" },
{ 0, "hf 14a reader" },
{ 0, "hf 14a apdu" },
{ 0, "hf 14a apdufind" }, { 0, "hf 14a apdufind" },
{ 0, "hf 14a chaining" },
{ 0, "hf 14a ndefformat" },
{ 0, "hf 14a ndefread" },
{ 0, "hf 14a ndefwrite" },
{ 1, "hf 14b help" }, { 1, "hf 14b help" },
{ 0, "hf 14b apdu" }, { 0, "hf 14b apdu" },
{ 0, "hf 14b dump" }, { 0, "hf 14b dump" },
@ -713,6 +715,7 @@ const static vocabulory_t vocabulory[] = {
{ 1, "nfc type1 help" }, { 1, "nfc type1 help" },
{ 0, "nfc type2 read" }, { 0, "nfc type2 read" },
{ 1, "nfc type2 help" }, { 1, "nfc type2 help" },
{ 0, "nfc type4a format" },
{ 0, "nfc type4a read" }, { 0, "nfc type4a read" },
{ 0, "nfc type4a st25taread" }, { 0, "nfc type4a st25taread" },
{ 1, "nfc type4a help" }, { 1, "nfc type4a help" },

View file

@ -1074,6 +1074,29 @@
], ],
"usage": "hf 14a apdu [-hsktde] [-m <head (CLA INS P1 P2) hex>] [-l <Le (int)>] <APDU (hex) | data (hex)> [<APDU (hex) | data (hex)>]..." "usage": "hf 14a apdu [-hsktde] [-m <head (CLA INS P1 P2) hex>] [-l <Le (int)>] <APDU (hex) | data (hex)> [<APDU (hex) | data (hex)>]..."
}, },
"hf 14a apdufind": {
"command": "hf 14a apdufind",
"description": "Enumerate APDU's of ISO7816 protocol to find valid CLS/INS/P1/P2 commands. It loops all 256 possible values for each byte. The loop oder is INS -> P1/P2 (alternating) -> CLA. Tag must be on antenna before running.",
"notes": [
"hf 14a apdufind",
"hf 14a apdufind --cla 80",
"hf 14a apdufind --cla 80 --error-limit 20 --skip-ins a4 --skip-ins b0 --with-le"
],
"offline": false,
"options": [
"-h, --help This help",
"-c, --cla <hex> Start value of CLASS (1 hex byte)",
"-i, --ins <hex> Start value of INSTRUCTION (1 hex byte)",
"--p1 <hex> Start value of P1 (1 hex byte)",
"--p2 <hex> Start value of P2 (1 hex byte)",
"-r, --reset <number> Minimum secondes before resetting the tag (to prevent timeout issues). Default is 5 minutes",
"-e, --error-limit <number> Maximum times an status word other than 0x9000 or 0x6D00 is shown. Default is 512.",
"-s, --skip-ins <hex> Do not test an instruction (can be specified multiple times)",
"-l, --with-le Search for APDUs with Le=0 (case 2S) as well",
"-v, --verbose Verbose output"
],
"usage": "hf 14a apdufind [-hlv] [-c <hex>] [-i <hex>] [--p1 <hex>] [--p2 <hex>] [-r <number>] [-e <number>] [-s <hex>]..."
},
"hf 14a chaining": { "hf 14a chaining": {
"command": "hf 14a chaining", "command": "hf 14a chaining",
"description": "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.", "description": "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.",
@ -1089,25 +1112,12 @@
}, },
"hf 14a config": { "hf 14a config": {
"command": "hf 14a config", "command": "hf 14a config",
"description": "--------------------------------------------------------------------------------------- hf 14a apdufind available offline: no", "description": "--------------------------------------------------------------------------------------- hf 14a cuids available offline: no",
"notes": [], "notes": [],
"offline": false, "offline": false,
"options": [], "options": [],
"usage": "" "usage": ""
}, },
"hf 14a cuids": {
"command": "hf 14a cuids",
"description": "Collect n>0 ISO14443-a UIDs in one go",
"notes": [
"hf 14a cuids -n 5 -> Collect 5 UIDs"
],
"offline": false,
"options": [
"-h, --help This help",
"-n, --num <dec> Number of UIDs to collect"
],
"usage": "hf 14a cuids [-h] [-n <dec>]"
},
"hf 14a help": { "hf 14a help": {
"command": "hf 14a help", "command": "hf 14a help",
"description": "help This help list List ISO 14443-a history", "description": "help This help list List ISO 14443-a history",
@ -1152,6 +1162,19 @@
], ],
"usage": "hf 14a list [-h1fcrux] [--dict <file>]" "usage": "hf 14a list [-h1fcrux] [--dict <file>]"
}, },
"hf 14a ndefformat": {
"command": "hf 14a ndefformat",
"description": "Format ISO14443-a Tag as a NFC tag with Data Exchange Format (NDEF)",
"notes": [
"hf 14a ndefformat"
],
"offline": false,
"options": [
"-h, --help This help",
"-v, --verbose show technical data"
],
"usage": "hf 14a ndefformat [-hv]"
},
"hf 14a ndefread": { "hf 14a ndefread": {
"command": "hf 14a ndefread", "command": "hf 14a ndefread",
"description": "Read NFC Data Exchange Format (NDEF) file on Type 4 NDEF tag", "description": "Read NFC Data Exchange Format (NDEF) file on Type 4 NDEF tag",
@ -1167,6 +1190,24 @@
], ],
"usage": "hf 14a ndefread [-hv] [-f <fn>]" "usage": "hf 14a ndefread [-hv] [-f <fn>]"
}, },
"hf 14a ndefwrite": {
"command": "hf 14a ndefwrite",
"description": "Write raw NDEF hex bytes to tag. This commands assumes tag already been NFC/NDEF formatted.",
"notes": [
"hf 14a ndefwrite -d 0300FE -> write empty record to tag",
"hf 14a ndefwrite -f myfilename",
"hf 14a ndefwrite -d 033fd1023a53709101195405656e2d55534963656d616e2054776974746572206c696e6b5101195502747769747465722e636f6d2f686572726d616e6e31303031"
],
"offline": false,
"options": [
"-h, --help This help",
"-d <hex> raw NDEF hex bytes",
"-f, --file <fn> write raw NDEF file to tag",
"-p fix NDEF record headers / terminator block if missing",
"-v, --verbose verbose output"
],
"usage": "hf 14a ndefwrite [-hpv] [-d <hex>] [-f <fn>]"
},
"hf 14a raw": { "hf 14a raw": {
"command": "hf 14a raw", "command": "hf 14a raw",
"description": "Sends raw bytes over ISO14443a. With option to use TOPAZ 14a mode.", "description": "Sends raw bytes over ISO14443a. With option to use TOPAZ 14a mode.",
@ -10666,6 +10707,19 @@
], ],
"usage": "hf mfu ndefread [-hlv] [-k Replace default key for NDEF] [-f <fn>]" "usage": "hf mfu ndefread [-hlv] [-k Replace default key for NDEF] [-f <fn>]"
}, },
"nfc type4a format": {
"command": "nfc type4a format",
"description": "Format ISO14443-a Tag as a NFC tag with Data Exchange Format (NDEF)",
"notes": [
"hf 14a ndefformat"
],
"offline": false,
"options": [
"-h, --help This help",
"-v, --verbose show technical data"
],
"usage": "hf 14a ndefformat [-hv]"
},
"nfc type4a help": { "nfc type4a help": {
"command": "nfc type4a help", "command": "nfc type4a help",
"description": "-------- --------- NFC Forum Tag Type 4 ISO14443A ---------- -------- --------------------- General --------------------- help This help", "description": "-------- --------- NFC Forum Tag Type 4 ISO14443A ---------- -------- --------------------- General --------------------- help This help",
@ -11420,8 +11474,8 @@
} }
}, },
"metadata": { "metadata": {
"commands_extracted": 722, "commands_extracted": 725,
"extracted_by": "PM3Help2JSON v1.00", "extracted_by": "PM3Help2JSON v1.00",
"extracted_on": "2022-10-23T01:18:01" "extracted_on": "2022-10-24T16:21:33"
} }
} }

View file

@ -177,18 +177,20 @@ Check column "offline" for their availability.
|------- |------- |----------- |------- |------- |-----------
|`hf 14a help `|Y |`This help` |`hf 14a help `|Y |`This help`
|`hf 14a list `|Y |`List ISO 14443-a history` |`hf 14a list `|Y |`List ISO 14443-a history`
|`hf 14a info `|N |`Tag information`
|`hf 14a reader `|N |`Act like an ISO14443-a reader`
|`hf 14a ndefread `|N |`Read an NDEF file from ISO 14443-A Type 4 tag`
|`hf 14a cuids `|N |`Collect n>0 ISO14443-a UIDs in one go`
|`hf 14a sim `|N |`Simulate ISO 14443-a tag`
|`hf 14a sniff `|N |`sniff ISO 14443-a traffic`
|`hf 14a apdu `|N |`Send ISO 14443-4 APDU to tag`
|`hf 14a chaining `|N |`Control ISO 14443-4 input chaining`
|`hf 14a raw `|N |`Send raw hex data to tag`
|`hf 14a antifuzz `|N |`Fuzzing the anticollision phase. Warning! Readers may react strange` |`hf 14a antifuzz `|N |`Fuzzing the anticollision phase. Warning! Readers may react strange`
|`hf 14a config `|N |`Configure 14a settings (use with caution)` |`hf 14a config `|N |`Configure 14a settings (use with caution)`
|`hf 14a cuids `|N |`Collect n>0 ISO14443-a UIDs in one go`
|`hf 14a info `|N |`Tag information`
|`hf 14a sim `|N |`Simulate ISO 14443-a tag`
|`hf 14a sniff `|N |`sniff ISO 14443-a traffic`
|`hf 14a raw `|N |`Send raw hex data to tag`
|`hf 14a reader `|N |`Act like an ISO14443-a reader`
|`hf 14a apdu `|N |`Send ISO 14443-4 APDU to tag`
|`hf 14a apdufind `|N |`Enumerate APDUs - CLA/INS/P1P2` |`hf 14a apdufind `|N |`Enumerate APDUs - CLA/INS/P1P2`
|`hf 14a chaining `|N |`Control ISO 14443-4 input chaining`
|`hf 14a ndefformat `|N |`Format ISO 14443-A as NFC Type 4 tag`
|`hf 14a ndefread `|N |`Read an NDEF file from ISO 14443-A Type 4 tag`
|`hf 14a ndefwrite `|N |`Write NDEF records to ISO 14443-A tag`
### hf 14b ### hf 14b
@ -1284,6 +1286,7 @@ Check column "offline" for their availability.
|command |offline |description |command |offline |description
|------- |------- |----------- |------- |------- |-----------
|`nfc type4a format `|N |`format ISO-14443-a tag as NFC Tag`
|`nfc type4a read `|N |`read NFC Forum Tag Type 4 A` |`nfc type4a read `|N |`read NFC Forum Tag Type 4 A`
|`nfc type4a st25taread `|N |`read ST25TA as NFC Forum Tag Type 4` |`nfc type4a st25taread `|N |`read ST25TA as NFC Forum Tag Type 4`
|`nfc type4a help `|Y |`This help` |`nfc type4a help `|Y |`This help`