diff --git a/CHANGELOG.md b/CHANGELOG.md index ff6616744..005709b2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] +- Changed `hf iclass sim` - implemented a sim -t 3 variation that glitches specific block responses (@antiklesys) - Changed `hf iclass legbrute` - implemented multithreading support (@antiklesys) - Changed `hf iclass legrec` - added a --fast option for further speed increase and automated AA2 block selection (@antiklesys) - Changed `hf iclass legrec` - additional code optimizations gaining a ~147% speed increase (@antiklesys) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 8e8702bf2..02cf8ada0 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -196,7 +196,7 @@ void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, uint8_ if (send_reply) reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i, 0, mac_responses, i * EPURSE_MAC_SIZE); - } else if (sim_type == ICLASS_SIM_MODE_FULL) { + } else if (sim_type == ICLASS_SIM_MODE_FULL || sim_type == ICLASS_SIM_MODE_FULL_GLITCH) { //This is 'full sim' mode, where we use the emulator storage for data. //ie: BigBuf_get_EM_addr should be previously filled with data from the "eload" command @@ -205,19 +205,13 @@ void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, uint8_ if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) { do_iclass_simulation_nonsec(); } else { - do_iclass_simulation(ICLASS_SIM_MODE_FULL, NULL); + do_iclass_simulation(sim_type, NULL); } if (send_reply) { reply_mix(CMD_ACK, CMD_HF_ICLASS_SIMULATE, 0, 0, NULL, 0); } - } else if (sim_type == ICLASS_SIM_MODE_CONFIG_CARD) { - - // config card - do_iclass_simulation(ICLASS_SIM_MODE_FULL, NULL); - // swap bin - } else if (sim_type == ICLASS_SIM_MODE_READER_ATTACK_KEYROLL) { // This is the KEYROLL version of sim 2. @@ -334,7 +328,7 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) { // AIA uint8_t aia_data[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00}; - if (simulationMode == ICLASS_SIM_MODE_FULL) { + if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { memcpy(conf_block, emulator + (8 * 1), 8); // blk 1 memcpy(card_challenge_data, emulator + (8 * 2), 8); // e-purse, blk 2 @@ -373,7 +367,7 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) { cipher_state_KD[0] = opt_doTagMAC_1(card_challenge_data, diversified_kd); cipher_state_KC[0] = opt_doTagMAC_1(card_challenge_data, diversified_kc); - if (simulationMode == ICLASS_SIM_MODE_FULL) { + if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { for (int i = 1; i < max_page; i++) { @@ -606,13 +600,21 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) { goto send; } } // switch - } else if (simulationMode == ICLASS_SIM_MODE_FULL) { + } else if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { if (block == 3 || block == 4) { // Kd, Kc, always respond with 0xff bytes modulated_response = resp_ff; modulated_response_size = resp_ff_len; trace_data = ff_data; trace_data_size = sizeof(ff_data); } else { // use data from emulator memory + if (simulationMode == ICLASS_SIM_MODE_FULL_GLITCH){ + uint8_t block_check[8] ={0}; + memcpy(block_check, emulator + (current_page * page_size) + (31 * 8), 8); + if (block == block_check[7]){ + goto send; + } + } + memcpy(data_generic_trace, emulator + (current_page * page_size) + (block * 8), 8); AddCrc(data_generic_trace, 8); trace_data = data_generic_trace; @@ -655,7 +657,7 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) { goto send; } - if (simulationMode == ICLASS_SIM_MODE_FULL) { + if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { // NR, from reader, is in receivedCmd +1 opt_doTagMAC_2(*cipher_state, receivedCmd + 1, data_generic_trace, diversified_key); @@ -722,7 +724,7 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) { chip_state = HALTED; goto send; - } else if (simulationMode == ICLASS_SIM_MODE_FULL && cmd == ICLASS_CMD_READ4 && len == 4) { // 0x06 + } else if ((simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH)&& cmd == ICLASS_CMD_READ4 && len == 4) { // 0x06 if (chip_state != SELECTED) { goto send; @@ -763,7 +765,7 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) { resp_cc_len = ts->max; cipher_state_KD[current_page] = opt_doTagMAC_1(card_challenge_data, diversified_kd); cipher_state_KC[current_page] = opt_doTagMAC_1(card_challenge_data, diversified_kc); - if (simulationMode == ICLASS_SIM_MODE_FULL) { + if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { memcpy(emulator + (current_page * page_size) + (8 * 2), card_challenge_data, 8); } } else if (block == 3) { // update Kd @@ -775,7 +777,7 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) { } } cipher_state_KD[current_page] = opt_doTagMAC_1(card_challenge_data, diversified_kd); - if (simulationMode == ICLASS_SIM_MODE_FULL) { + if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { memcpy(emulator + (current_page * page_size) + (8 * 3), diversified_kd, 8); } } else if (block == 4) { // update Kc @@ -787,14 +789,22 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) { } } cipher_state_KC[current_page] = opt_doTagMAC_1(card_challenge_data, diversified_kc); - if (simulationMode == ICLASS_SIM_MODE_FULL) { + if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { memcpy(emulator + (current_page * page_size) + (8 * 4), diversified_kc, 8); } - } else if (simulationMode == ICLASS_SIM_MODE_FULL) { + } else if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { // update emulator memory memcpy(emulator + (current_page * page_size) + (8 * block), receivedCmd + 2, 8); } + if (simulationMode == ICLASS_SIM_MODE_FULL_GLITCH){ + uint8_t block_check[8] ={0}; + memcpy(block_check, emulator + (current_page * page_size) + (31 * 8), 8); + if (block == block_check[7]){ + goto send; + } + } + memcpy(data_generic_trace, receivedCmd + 2, 8); AddCrc(data_generic_trace, 8); trace_data = data_generic_trace; @@ -814,7 +824,7 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) { goto send; } - if (simulationMode == ICLASS_SIM_MODE_FULL && max_page > 0) { + if ((simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH)&& max_page > 0) { // if on 2k, always ignore 3msb, & 0x1F) uint8_t page = receivedCmd[1] & 0x1F; diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 6722b0051..1fb8b5353 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -844,7 +844,8 @@ static int CmdHFiClassSim(const char *Cmd) { "hf iclass sim -t 1 --> simulate with default CSN\n" "hf iclass sim -t 2 --> execute loclass attack online part\n" "hf iclass sim -t 3 --> simulate full iCLASS 2k tag\n" - "hf iclass sim -t 4 --> Reader-attack, adapted for KeyRoll mode, gather reader responses to extract elite key"); + "hf iclass sim -t 4 --> Reader-attack, adapted for KeyRoll mode, gather reader responses to extract elite key\n" + "hf iclass sim -t 6 --> same as -t 3, but doesn't respond to r/w for the block specified in last byte of blk 31"); void *argtable[] = { arg_param_begin, @@ -875,7 +876,7 @@ static int CmdHFiClassSim(const char *Cmd) { CLIParserFree(ctx); - if (sim_type > 4) { + if (sim_type > 4 && sim_type != 6) { PrintAndLogEx(ERR, "Undefined simtype %d", sim_type); return PM3_EINVARG; } @@ -1028,6 +1029,7 @@ static int CmdHFiClassSim(const char *Cmd) { case ICLASS_SIM_MODE_CSN: case ICLASS_SIM_MODE_CSN_DEFAULT: case ICLASS_SIM_MODE_FULL: + case ICLASS_SIM_MODE_FULL_GLITCH: default: { PrintAndLogEx(INFO, "Starting iCLASS simulation"); PrintAndLogEx(INFO, "Press " _GREEN_("`pm3 button`") " to abort"); @@ -1035,7 +1037,7 @@ static int CmdHFiClassSim(const char *Cmd) { clearCommandBuffer(); SendCommandMIX(CMD_HF_ICLASS_SIMULATE, sim_type, numberOfCSNs, 1, csn, 8); - if (sim_type == ICLASS_SIM_MODE_FULL) + if (sim_type == ICLASS_SIM_MODE_FULL || ICLASS_SIM_MODE_FULL_GLITCH) PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf iclass esave -h") "` to save the emulator memory to file"); break; } diff --git a/include/iclass_cmd.h b/include/iclass_cmd.h index dcab87809..ca0f154e0 100644 --- a/include/iclass_cmd.h +++ b/include/iclass_cmd.h @@ -48,7 +48,7 @@ #define ICLASS_SIM_MODE_FULL 3 #define ICLASS_SIM_MODE_READER_ATTACK_KEYROLL 4 #define ICLASS_SIM_MODE_EXIT_AFTER_MAC 5 // note: device internal only -#define ICLASS_SIM_MODE_CONFIG_CARD 6 +#define ICLASS_SIM_MODE_FULL_GLITCH 6 // iCLASS auth request data structure