From 4b4afc623f625469bea65b11eac27de89e61a720 Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 14:31:52 +0800 Subject: [PATCH 01/16] Update cmdhf14a.c Added HF 14a AID Sim Signed-off-by: Adam Jon Foster --- client/src/cmdhf14a.c | 178 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index b4a0e0c68..26bb446eb 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -3628,6 +3628,183 @@ int CmdHF14ANdefWrite(const char *Cmd) { return PM3_SUCCESS; } +/* + * Simulate ISO/IEC 14443 type A tag with 4,7 or 10 byte UID, and filter for AID Values + * These AID Values can be responded to and include extra APDU commands after verification +*/ + +int CmdHF14AAIDSim(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 14a simaid", + "Simulate ISO/IEC 14443 type A tag with 4,7 or 10 byte UID, and filter for AID Values\n" + "These AID Values can be responded to and include extra APDU commands on GetData after response\n", + "hf 14a simaid -t 3 -> MIFARE Desfire\n" + "hf 14a simaid -t 4 -> ISO/IEC 14443-4\n" + "hf 14a simaid -t 11 -> Javacard (JCOP)\n" + "hf 14a simaid -t 3 --aid a000000000000000000000 --response 9000 --apdu 9000 -> AID, Response and APDU\n" + "hf 14a simaid -t 3 --rats 05788172220101 --response 01009000 --apdu 86009000 -> Custom RATS Added\n" + "hf 14a simaid -t 3 --rats 05788172220101 -x -> Enumerate AID Values\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_int1("t", "type", "<1-12> ", "Simulation type to use"), + arg_str0("u", "uid", "", "<4|7|10> hex bytes UID"), + arg_str0("r", "rats", "", "<0-20> hex bytes RATS"), + arg_str0("a", "aid", "", "<0-100> hex bytes for AID to respond to (Default: A000000000000000000000)"), + arg_str0("e", "response", "", "<0-100> hex bytes for APDU Response to AID Select (Default: 9000)"), + arg_str0("p", "apdu", "", "<0-100> hex bytes for APDU Response to Get Data request after AID (Default: 9000)"), + arg_lit0("x", "enumerate", "Enumerate all AID values via returning Not Found and print them to console "), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + int tagtype = arg_get_int_def(ctx, 1, 1); + + bool enumerate = arg_get_lit(ctx, 7); + + int uid_len = 0; + int rats_len = 0; + int aid_len = 0; + int respond_len = 0; + int apdu_len = 0; + + uint8_t uid[10] = {0}; + uint8_t rats[20] = {0}; + uint8_t aid[30] = {0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + uint8_t response[100] = {0x90, 0x00}; + uint8_t apdu[100] = {0x90, 0x00}; + + CLIGetHexWithReturn(ctx, 2, uid, &uid_len); + CLIGetHexWithReturn(ctx, 3, rats, &rats_len); + CLIGetHexWithReturn(ctx, 4, aid, &aid_len); + CLIGetHexWithReturn(ctx, 5, response, &respond_len); + CLIGetHexWithReturn(ctx, 6, apdu, &apdu_len); + + // default value fill for the AID, response, and apdu + if (aid_len == 0) { + aid_len = 11; + } + if (respond_len == 0) { + respond_len = 2; + } + if (apdu_len == 0) { + apdu_len = 2; + } + + uint16_t flags = 0; + bool useUIDfromEML = true; + + if (uid_len > 0) { + switch (uid_len) { + case 10: + flags |= FLAG_10B_UID_IN_DATA; + break; + case 7: + flags |= FLAG_7B_UID_IN_DATA; + break; + case 4: + flags |= FLAG_4B_UID_IN_DATA; + break; + default: + PrintAndLogEx(ERR, "Please specify a 4, 7, or 10 byte UID"); + CLIParserFree(ctx); + return PM3_EINVARG; + } + PrintAndLogEx(SUCCESS, "Emulating " _YELLOW_("ISO/IEC 14443 type A tag")" with " _GREEN_("%d byte UID (%s)"), uid_len, sprint_hex(uid, uid_len)); + useUIDfromEML = false; + } + + if (rats_len > 0) { + flags |= RATS_IN_DATA; + } + + + CLIParserFree(ctx); + + if (tagtype > 12) { + PrintAndLogEx(ERR, "Undefined tag %d", tagtype); + return PM3_EINVARG; + } + + if (useUIDfromEML) { + flags |= FLAG_UID_IN_EMUL; + } + + struct { + uint8_t tagtype; + uint16_t flags; + uint8_t uid[10]; + uint8_t rats[20]; + uint8_t aid[30]; + uint8_t response[100]; + uint8_t apdu[100]; + int aid_len; + int respond_len; + int apdu_len; + bool enumerate; + } PACKED payload; + + payload.tagtype = tagtype; + payload.flags = flags; + payload.enumerate = enumerate; + + // Copy data to payload + memcpy(payload.uid, uid, uid_len); + memcpy(payload.rats, rats, rats_len); + memcpy(payload.aid, aid, aid_len); + memcpy(payload.response, response, respond_len); + memcpy(payload.apdu, apdu, apdu_len); + + // copy the lengths data to the payload + memcpy(&payload.aid_len, &aid_len, sizeof(aid_len)); + memcpy(&payload.respond_len, &respond_len, sizeof(respond_len)); + memcpy(&payload.apdu_len, &apdu_len, sizeof(apdu_len)); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO14443A_SIM_AID, (uint8_t *)&payload, sizeof(payload)); + PacketResponseNG resp = {0}; + + sector_t *k_sector = NULL; + size_t k_sectors_cnt = MIFARE_4K_MAXSECTOR; + + PrintAndLogEx(INFO, "Press " _GREEN_("pm3 button") " to abort simulation"); + bool keypress = kbd_enter_pressed(); + while (keypress == false) { + + if (WaitForResponseTimeout(CMD_HF_MIFARE_SIMULATE, &resp, 1500) == 0) + continue; + + if (resp.status != PM3_SUCCESS) + break; + + if ((flags & FLAG_NR_AR_ATTACK) != FLAG_NR_AR_ATTACK) + break; + + keypress = kbd_enter_pressed(); + } + + if (keypress) { + if ((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK) { + // inform device to break the sim loop since client has exited + SendCommandNG(CMD_BREAK_LOOP, NULL, 0); + } + + if (resp.status == PM3_EOPABORTED && ((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK)) { + //iceman: readerAttack call frees k_sector , this call is useless. + showSectorTable(k_sector, k_sectors_cnt); + } + } + + + PrintAndLogEx(INFO, "Done!"); + PrintAndLogEx(HINT, "Try `" _YELLOW_("trace list -t 14a")"` to view captured tracelog"); + PrintAndLogEx(HINT, "Try `" _YELLOW_("trace save -h") "` to save tracelog for later analysing"); + + return PM3_SUCCESS; +} + + static command_t CommandTable[] = { {"-----------", CmdHelp, AlwaysAvailable, "----------------------- " _CYAN_("General") " -----------------------"}, {"help", CmdHelp, AlwaysAvailable, "This help"}, @@ -3638,6 +3815,7 @@ static command_t CommandTable[] = { {"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"}, + {"simaid", CmdHF14AAIDSim, IfPm3Iso14443a, "Simulate ISO 14443-a AID Selection"}, {"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"}, From 92ce2cb780fbc2ee26e355c7f8d4dd312b49f279 Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 14:32:14 +0800 Subject: [PATCH 02/16] Update cmdhf14a.h Added HF 14a AID Sim Signed-off-by: Adam Jon Foster --- client/src/cmdhf14a.h | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/cmdhf14a.h b/client/src/cmdhf14a.h index 7b5bc48be..21b33fc13 100644 --- a/client/src/cmdhf14a.h +++ b/client/src/cmdhf14a.h @@ -54,6 +54,7 @@ typedef enum { 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 CmdHF14AAIDSim(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 From 92767a685f32afbe13624856b9d80a99d15406bf Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 14:33:30 +0800 Subject: [PATCH 03/16] Update pm3_cmd.h Added RATS_IN_DATA as a definition Signed-off-by: Adam Jon Foster --- include/pm3_cmd.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 068898937..2e0ac5456 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -775,6 +775,7 @@ typedef struct { #define FLAG_FORCED_ATQA 0x800 #define FLAG_FORCED_SAK 0x1000 #define FLAG_CVE21_0430 0x2000 +#define RATS_IN_DATA 0x10000 #define MODE_SIM_CSN 0 From 4ff0726eb6bf9021cfdb716220e61a5313734bbb Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 14:34:56 +0800 Subject: [PATCH 04/16] Update appmain.c Signed-off-by: Adam Jon Foster --- armsrc/appmain.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 00753ee66..c3ce7830d 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1639,6 +1639,24 @@ static void PacketReceived(PacketCommandNG *packet) { SimulateIso14443aTag(payload->tagtype, payload->flags, payload->uid, payload->exitAfter); // ## Simulate iso14443a tag - pass tag type & UID break; } + case CMD_HF_ISO14443A_SIM_AID: { + struct p { + uint8_t tagtype; + uint16_t flags; + uint8_t uid[10]; + uint8_t rats[20]; + uint8_t aid[30]; + uint8_t response[100]; + uint8_t apdu[100]; + int aid_len; + int respond_len; + int apdu_len; + bool enumerate; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + SimulateIso14443aTagAID(payload->tagtype, payload->flags, payload->uid, payload->rats, payload->aid, payload->response, payload->apdu, payload->aid_len, payload->respond_len, payload->apdu_len, payload->enumerate); // ## Simulate iso14443a tag - pass tag type, UID, rats, aid, resp, apdu + break; + } case CMD_HF_ISO14443A_ANTIFUZZ: { struct p { uint8_t flag; From 95a8829f20c59e84507ea413f815c339d7a81982 Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 14:38:30 +0800 Subject: [PATCH 05/16] Update iso14443a.c Added SimulateIso14443aTagAID Signed-off-by: Adam Jon Foster --- armsrc/iso14443a.c | 239 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 7d4dcf983..a433db828 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -3865,3 +3865,242 @@ void DetectNACKbug(void) { hf_field_off(); set_tracing(false); } + +/* /// +Based upon the SimulateIso14443aTag, this aims to instead take an AID Value you've supplied, and return your selected response. +It can also continue after the AID has been selected, and respond to other request types. +This was forked from the original function to allow for more flexibility in the future, and to increase the processing speed of the original function. +/// */ + +void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t *iRATs, uint8_t *aid, uint8_t *resp, uint8_t *apdu, int aidLen, int respondLen, int apduLen, bool enumerate) { + tag_response_info_t *responses; + uint32_t cuid = 0; + uint32_t counters[3] = { 0x00, 0x00, 0x00 }; + uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd }; + uint8_t pages = 0; + + // command buffers + uint8_t receivedCmd[MAX_FRAME_SIZE] = { 0x00 }; + uint8_t receivedCmdPar[MAX_PARITY_SIZE] = { 0x00 }; + + // free eventually allocated BigBuf memory but keep Emulator Memory + BigBuf_free_keep_EM(); + + // Increased the buffer size to allow for more complex responses + #define DYNAMIC_RESPONSE_BUFFER2_SIZE 512 + #define DYNAMIC_MODULATION_BUFFER2_SIZE 1536 + + uint8_t * dynamic_response_buffer2 = BigBuf_calloc(DYNAMIC_RESPONSE_BUFFER2_SIZE); + uint8_t * dynamic_modulation_buffer2 = BigBuf_calloc(DYNAMIC_MODULATION_BUFFER2_SIZE); + tag_response_info_t dynamic_response_info = { + .response = dynamic_response_buffer2, + .response_n = 0, + .modulation = dynamic_modulation_buffer2, + .modulation_n = 0 + }; + + if (SimulateIso14443aInit(tagType, flags, data, iRATs, &responses, &cuid, counters, tearings, &pages) == false) { + BigBuf_free_keep_EM(); + reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0); + return; + } + + // We need to listen to the high-frequency, peak-detected path. + iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); + + iso14a_set_timeout(201400); // 106 * 19ms default *100? + + int len = 0; + int retval = PM3_SUCCESS; + int sentCount = 0; + bool odd_reply = true; + + clear_trace(); + set_tracing(true); + LED_A_ON(); + + // Filters for when this comes through + static uint8_t aidFilter[30] = { 0x00 }; // Default AID Value + static uint8_t aidResponse[100] = { 0x00 }; // Default AID Response + static uint8_t apduCommand [100] = { 0x00 }; // Default APDU GetData Response + + // Copy the AID, AID Response, and the GetData APDU response into our variables + if (aid != 0) { + memcpy(aidFilter, aid, aidLen); + } + if (resp != 0) { + memcpy(aidResponse, resp, respondLen); + } + if (apdu != 0) { + memcpy(apduCommand, apdu, apduLen); + } + + + // main loop + bool finished = false; + while (finished == false) { + // BUTTON_PRESS check done in GetIso14443aCommandFromReader + WDT_HIT(); + + tag_response_info_t *p_response = NULL; + + // Clean receive command buffer + if (GetIso14443aCommandFromReader(receivedCmd, sizeof(receivedCmd), receivedCmdPar, &len) == false) { + Dbprintf("Emulator stopped. Trace length: %d ", BigBuf_get_traceLen()); + retval = PM3_EOPABORTED; + break; + } + + if (receivedCmd[0] == ISO14443A_CMD_REQA && len == 1) { // Received a REQUEST, but in HALTED, skip + odd_reply = !odd_reply; + if (odd_reply) { + p_response = &responses[RESP_INDEX_ATQA]; + } + } else if (receivedCmd[0] == ISO14443A_CMD_WUPA && len == 1) { // Received a WAKEUP + p_response = &responses[RESP_INDEX_ATQA]; + } else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 2) { // Received request for UID (cascade 1) + p_response = &responses[RESP_INDEX_UIDC1]; + } else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && len == 2) { // Received request for UID (cascade 2) + p_response = &responses[RESP_INDEX_UIDC2]; + } else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3 && len == 2) { // Received request for UID (cascade 3) + p_response = &responses[RESP_INDEX_UIDC3]; + } else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 9) { // Received a SELECT (cascade 1) + p_response = &responses[RESP_INDEX_SAKC1]; + } else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && len == 9) { // Received a SELECT (cascade 2) + p_response = &responses[RESP_INDEX_SAKC2]; + } else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3 && len == 9) { // Received a SELECT (cascade 3) + p_response = &responses[RESP_INDEX_SAKC3]; + } else if (receivedCmd[0] == ISO14443A_CMD_PPS) { + p_response = &responses[RESP_INDEX_PPS]; + } else if (receivedCmd[0] == ISO14443A_CMD_HALT && len == 4) { // Received a HALT + LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + p_response = NULL; + finished = true; + } else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { // Received a RATS request + p_response = &responses[RESP_INDEX_RATS]; + } else { + // clear old dynamic responses + dynamic_response_info.response_n = 0; + dynamic_response_info.modulation_n = 0; + + // Check for ISO 14443A-4 compliant commands, look at left nibble + switch (receivedCmd[0]) { + case 0x0B: + case 0x0A: { // IBlock (command CID) + dynamic_response_info.response[0] = receivedCmd[0]; + dynamic_response_info.response[1] = 0x00; + + switch (receivedCmd[3]) { // APDU Class Byte + // receivedCmd in this case is expecting to structured with a CID, then the APDU command for SelectFile + // | IBlock (CID) | CID | APDU Command | CRC | + + case 0xA4: { // SELECT FILE + // Select File AID uses the following format for GlobalPlatform + // + // | 00 | A4 | 04 | 00 | xx | AID | 00 | + // xx in this case is len of the AID value in hex + + // aid len is found as a hex value in receivedCmd[6] (Index Starts at 0) + int aid_len = receivedCmd[6]; + uint8_t* recieved_aid = &receivedCmd[7]; + + // aid enumeration flag + if (enumerate == true) { + Dbprintf("Received AID (%d):", aid_len); + Dbhexdump(aid_len, recieved_aid, false); + } + + if (memcmp(aidFilter, recieved_aid, aid_len) == 0) { // Evaluate the AID sent by the Reader to the AID supplied + // AID Response will be parsed here + memcpy(dynamic_response_info.response + 2 , aidResponse, respondLen + 2); + dynamic_response_info.response_n = respondLen + 2; + } else { // Any other SELECT FILE command will return with a Not Found + dynamic_response_info.response[2] = 0x6A; + dynamic_response_info.response[3] = 0x82; + dynamic_response_info.response_n = 4; + } + } + break; + + case 0xDA: { // PUT DATA + // Just send them a 90 00 response + dynamic_response_info.response[2] = 0x90; + dynamic_response_info.response[3] = 0x00; + dynamic_response_info.response_n = 4; + } + break; + + case 0xCA: { // GET DATA + if (sentCount == 0) { + // APDU Command will just be parsed here + memcpy(dynamic_response_info.response + 2 , apduCommand, apduLen + 2); + dynamic_response_info.response_n = respondLen + 2; + } else { + finished = true; + break; + } + sentCount++; + } + break; + default : { + // Any other non-listed command + // Respond Not Found + dynamic_response_info.response[2] = 0x6A; + dynamic_response_info.response[3] = 0x82; + dynamic_response_info.response_n = 4; + } + } + break; + } + break; + + case 0xCA: + case 0xC2: { // Readers sends deselect command + dynamic_response_info.response[0] = 0xCA; + dynamic_response_info.response[1] = 0x00; + dynamic_response_info.response_n = 2; + finished = true; + } + break; + + default: { + // Never seen this command before + LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + if (g_dbglevel >= DBG_DEBUG) { + Dbprintf("Received unknown command (len=%d):", len); + Dbhexdump(len, receivedCmd, false); + } + // Do not respond + dynamic_response_info.response_n = 0; + } + break; + } + if (dynamic_response_info.response_n > 0) { + + // Copy the CID from the reader query + dynamic_response_info.response[1] = receivedCmd[1]; + + // Add CRC bytes, always used in ISO 14443A-4 compliant cards + AddCrc14A(dynamic_response_info.response, dynamic_response_info.response_n); + dynamic_response_info.response_n += 2; + + if (prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE) == false) { + if (g_dbglevel >= DBG_DEBUG) DbpString("Error preparing tag response"); + LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + break; + } + p_response = &dynamic_response_info; + } + } + + // Send response + EmSendPrecompiledCmd(p_response); + } + + switch_off(); + + set_tracing(false); + BigBuf_free_keep_EM(); + + reply_ng(CMD_HF_MIFARE_SIMULATE, retval, NULL, 0); +} From 5be8f92cff0371539e4d2bd30ff5d0f5513ac6b3 Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 14:38:59 +0800 Subject: [PATCH 06/16] Update iso14443a.h Added SimulateIso14443aTagAID Signed-off-by: Adam Jon Foster --- armsrc/iso14443a.h | 1 + 1 file changed, 1 insertion(+) diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index c3b155122..58a4d8302 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -174,6 +174,7 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype); void DetectNACKbug(void); +void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t *iRATs, uint8_t *aid, uint8_t *resp, uint8_t *apdu, int aid_len, int respond_len, int apdu_len, bool enumerate); bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint16_t resp_len, uint8_t *received_len); From d48d69b3e20d32f219ccc64dcc556e0141387894 Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 14:42:22 +0800 Subject: [PATCH 07/16] Update pm3_cmd.h Added Header File Signed-off-by: Adam Jon Foster --- include/pm3_cmd.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 2e0ac5456..6b62d6c28 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -605,6 +605,7 @@ typedef struct { #define CMD_HF_ISO14443A_SNIFF 0x0383 #define CMD_HF_ISO14443A_SIMULATE 0x0384 +#define CMD_HF_ISO14443A_SIM_AID 0x1420 #define CMD_HF_ISO14443A_READER 0x0385 From 2d3cff720b1cd394cffbee8d35cd3ebb8bc2ab79 Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 14:46:31 +0800 Subject: [PATCH 08/16] Update iso14443a.c Added custom RATS option Signed-off-by: Adam Jon Foster --- armsrc/iso14443a.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index a433db828..c7fb280ea 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1086,7 +1086,7 @@ bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_ } } -bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_response_info_t **responses, +bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t *iRATs, tag_response_info_t **responses, uint32_t *cuid, uint32_t counters[3], uint8_t tearings[3], uint8_t *pages) { uint8_t sak = 0; // The first response contains the ATQA (note: bytes are transmitted in reverse order). @@ -1248,6 +1248,13 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r return false; } } + + // copy the iRATs if supplied + if ((flags & RATS_IN_DATA) == RATS_IN_DATA) { + memcpy(rRATS ,iRATs, sizeof(iRATs)); + // rats len is dictated by the first char of the string, add 2 crc bytes + rRATS_len = (iRATs[0] + 2); + } // if uid not supplied then get from emulator memory if ((memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 10) == 0) || ((flags & FLAG_UID_IN_EMUL) == FLAG_UID_IN_EMUL)) { @@ -1342,6 +1349,8 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r return false; } + + AddCrc14A(rRATS, rRATS_len - 2); AddCrc14A(rPPS, sizeof(rPPS) - 2); From 56324b16b2f1fed5dd069112234a76643bf15461 Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 14:46:52 +0800 Subject: [PATCH 09/16] Update iso14443a.h Added custom RATS option Signed-off-by: Adam Jon Foster --- armsrc/iso14443a.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 58a4d8302..1e9b61ff8 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -141,7 +141,7 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t void RAMFUNC SniffIso14443a(uint8_t param); void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t exitAfterNReads); -bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_response_info_t **responses, uint32_t *cuid, uint32_t counters[3], uint8_t tearings[3], uint8_t *pages); +bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t *iRATs, tag_response_info_t **responses, uint32_t *cuid, uint32_t counters[3], uint8_t tearings[3], uint8_t *pages); bool GetIso14443aCommandFromReader(uint8_t *received, uint16_t received_maxlen, uint8_t *par, int *len); void iso14443a_antifuzz(uint32_t flags); void ReaderIso14443a(PacketCommandNG *c); From fd678ae1c7dca0e799eb2ccd8443ef23338c4716 Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 14:49:25 +0800 Subject: [PATCH 10/16] Update appmain.c Signed-off-by: Adam Jon Foster --- armsrc/appmain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index c3ce7830d..14a74fe6c 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1634,9 +1634,10 @@ static void PacketReceived(PacketCommandNG *packet) { uint16_t flags; uint8_t uid[10]; uint8_t exitAfter; + uint8_t rats[20]; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - SimulateIso14443aTag(payload->tagtype, payload->flags, payload->uid, payload->exitAfter); // ## Simulate iso14443a tag - pass tag type & UID + SimulateIso14443aTag(payload->tagtype, payload->flags, payload->uid, payload->exitAfter, payload->rats); // ## Simulate iso14443a tag - pass tag type & UID break; } case CMD_HF_ISO14443A_SIM_AID: { From 089da16ffaa949109fe2d52594559681acd17958 Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 14:53:34 +0800 Subject: [PATCH 11/16] Update iso14443a.c Signed-off-by: Adam Jon Foster --- armsrc/iso14443a.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index c7fb280ea..2e2f31198 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1426,7 +1426,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, uint8 // response to send, and send it. // 'hf 14a sim' //----------------------------------------------------------------------------- -void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t exitAfterNReads) { +void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t exitAfterNReads, uint8_t *iRATS) { #define ATTACK_KEY_COUNT 8 // keep same as define in cmdhfmf.c -> readerAttack() @@ -1468,7 +1468,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_ .modulation_n = 0 }; - if (SimulateIso14443aInit(tagType, flags, data, &responses, &cuid, counters, tearings, &pages) == false) { + if (SimulateIso14443aInit(tagType, flags, data, iRATS,&responses, &cuid, counters, tearings, &pages) == false) { BigBuf_free_keep_EM(); reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0); return; From b7aadc6d66ee38487ab6acd8979049d9e2918fdc Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 14:54:11 +0800 Subject: [PATCH 12/16] Update iso14443a.h Added custom RATS via iRATS to regular iso14443a tag emulation Signed-off-by: Adam Jon Foster --- armsrc/iso14443a.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 1e9b61ff8..c550a4701 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -140,7 +140,7 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time); RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time); void RAMFUNC SniffIso14443a(uint8_t param); -void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t exitAfterNReads); +void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t exitAfterNReads, uint8_t *iRATs); bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t *iRATs, tag_response_info_t **responses, uint32_t *cuid, uint32_t counters[3], uint8_t tearings[3], uint8_t *pages); bool GetIso14443aCommandFromReader(uint8_t *received, uint16_t received_maxlen, uint8_t *par, int *len); void iso14443a_antifuzz(uint32_t flags); From 953bfdb4f9eba9dd60cad0c6e4e225387f7b913c Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 15:03:32 +0800 Subject: [PATCH 13/16] Update iso14443a.c Fixed Names Signed-off-by: Adam Jon Foster --- armsrc/iso14443a.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 2e2f31198..e41c07dbf 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1426,7 +1426,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, uint8 // response to send, and send it. // 'hf 14a sim' //----------------------------------------------------------------------------- -void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t exitAfterNReads, uint8_t *iRATS) { +void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t exitAfterNReads, uint8_t *iRATs) { #define ATTACK_KEY_COUNT 8 // keep same as define in cmdhfmf.c -> readerAttack() @@ -1468,7 +1468,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_ .modulation_n = 0 }; - if (SimulateIso14443aInit(tagType, flags, data, iRATS,&responses, &cuid, counters, tearings, &pages) == false) { + if (SimulateIso14443aInit(tagType, flags, data, iRATs, &responses, &cuid, counters, tearings, &pages) == false) { BigBuf_free_keep_EM(); reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0); return; From 03b291e1736bc28f15a4ec7bcc0bf9a0f77bb2ba Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 15:07:35 +0800 Subject: [PATCH 14/16] Update CHANGELOG.md Signed-off-by: Adam Jon Foster --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38d6eb8dd..089a5088b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added detection for FM11NT021 (@iceman1001) - Added detection of a magic NTAG 215 (@iceman1001) - Fixed hardnested on AVX512F #2410 (@xianglin1998) +- Added `hf 14a aidsim` - simulates a PICC (like `14a sim`), and allows you to respond to specific AIDs and getData responses ## [Backdoor.4.18994][2024-09-10] - Changed flashing messages to be less scary (@iceman1001) From f42e2f76b9fdf9e65db5543b5f08deac158e4d7a Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 15:07:52 +0800 Subject: [PATCH 15/16] Update CHANGELOG.md Signed-off-by: Adam Jon Foster --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 089a5088b..11ca8e8fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added detection for FM11NT021 (@iceman1001) - Added detection of a magic NTAG 215 (@iceman1001) - Fixed hardnested on AVX512F #2410 (@xianglin1998) -- Added `hf 14a aidsim` - simulates a PICC (like `14a sim`), and allows you to respond to specific AIDs and getData responses +- Added `hf 14a aidsim` - simulates a PICC (like `14a sim`), and allows you to respond to specific AIDs and getData responses (@evildaemond) ## [Backdoor.4.18994][2024-09-10] - Changed flashing messages to be less scary (@iceman1001) From 03fcc1d8d6dbbe34531e2c04cbfa38cd6a1e1295 Mon Sep 17 00:00:00 2001 From: Adam Jon Foster Date: Mon, 23 Sep 2024 15:31:46 +0800 Subject: [PATCH 16/16] Update pm3_cmd.h Signed-off-by: Adam Jon Foster --- include/pm3_cmd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 6b62d6c28..8399d50f7 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -776,7 +776,7 @@ typedef struct { #define FLAG_FORCED_ATQA 0x800 #define FLAG_FORCED_SAK 0x1000 #define FLAG_CVE21_0430 0x2000 -#define RATS_IN_DATA 0x10000 +#define RATS_IN_DATA 0x3000 #define MODE_SIM_CSN 0