diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b6c1ffd9..ce8505419 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] - Updated the ATR list (@iceman1001) - Fixed fpga binary images to use fixed seed 2 (@n-hutton) -- Changed `hf iclass sim -t 6` - implemented simulation that glitches specific block responses (@antiklesys) +- Changed `hf iclass sim -t 7` - implemented simulation that glitches key block responses (@antiklesys) +- Changed `hf iclass sim -t 6` - implemented simulation that glitches sio block (@antiklesys) - Changed `hf iclass legbrute` - implemented multithreading support (@antiklesys) +- Changed `hf iclass legrec` - added a --sl option for further speed increase by tweaking the communication delays (@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) - Changed `hf iclass tear` - readability improvements for erase phase (@antiklesys) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 2f66143b9..ff267f899 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 || sim_type == ICLASS_SIM_MODE_FULL_GLITCH) { + } else if (sim_type == ICLASS_SIM_MODE_FULL || sim_type == ICLASS_SIM_MODE_FULL_GLITCH || sim_type == ICLASS_SIM_MODE_FULL_GLITCH_KEY) { //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 @@ -328,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 || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { + if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH_KEY) { memcpy(conf_block, emulator + (8 * 1), 8); // blk 1 memcpy(card_challenge_data, emulator + (8 * 2), 8); // e-purse, blk 2 @@ -367,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 || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { + if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH_KEY) { for (int i = 1; i < max_page; i++) { @@ -380,6 +380,8 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) { } } + bool glitch_key_read = false; + // Anti-collision process: // Reader 0a // Tag 0f @@ -600,7 +602,7 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) { goto send; } } // switch - } else if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { + } else if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH_KEY) { if (block == 3 || block == 4) { // Kd, Kc, always respond with 0xff bytes modulated_response = resp_ff; modulated_response_size = resp_ff_len; @@ -663,7 +665,12 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) { goto send; } - if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { + if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH_KEY) { + + if(glitch_key_read){ + goto send; + } + // NR, from reader, is in receivedCmd +1 opt_doTagMAC_2(*cipher_state, receivedCmd + 1, data_generic_trace, diversified_key); @@ -730,7 +737,7 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) { chip_state = HALTED; goto send; - } else if ((simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) && cmd == ICLASS_CMD_READ4 && len == 4) { // 0x06 + } else if ((simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH_KEY) && cmd == ICLASS_CMD_READ4 && len == 4) { // 0x06 if (chip_state != SELECTED) { goto send; @@ -771,20 +778,24 @@ 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 || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { + if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH_KEY) { memcpy(emulator + (current_page * page_size) + (8 * 2), card_challenge_data, 8); } } else if (block == 3) { // update Kd for (int i = 0; i < 8; i++) { - if (personalization_mode) { + if (personalization_mode || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH_KEY) { diversified_kd[i] = receivedCmd[2 + i]; } else { diversified_kd[i] ^= receivedCmd[2 + i]; } } cipher_state_KD[current_page] = opt_doTagMAC_1(card_challenge_data, diversified_kd); - if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { + if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH_KEY) { memcpy(emulator + (current_page * page_size) + (8 * 3), diversified_kd, 8); + if(simulationMode == ICLASS_SIM_MODE_FULL_GLITCH_KEY){ + glitch_key_read = true; + goto send; + } } } else if (block == 4) { // update Kc for (int i = 0; i < 8; i++) { @@ -795,10 +806,10 @@ 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 || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { + if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH_KEY) { memcpy(emulator + (current_page * page_size) + (8 * 4), diversified_kc, 8); } - } else if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) { + } else if (simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH_KEY) { // update emulator memory memcpy(emulator + (current_page * page_size) + (8 * block), receivedCmd + 2, 8); } @@ -838,7 +849,7 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) { goto send; } - if ((simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) && max_page > 0) { + if ((simulationMode == ICLASS_SIM_MODE_FULL || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH || simulationMode == ICLASS_SIM_MODE_FULL_GLITCH_KEY) && 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 7ded7732d..51c90f9b7 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -845,7 +845,8 @@ static int CmdHFiClassSim(const char *Cmd) { "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\n" - "hf iclass sim -t 6 --> simulate full iCLASS 2k tag that doesn't respond to r/w requests to the last SIO block"); + "hf iclass sim -t 6 --> simulate full iCLASS 2k tag that doesn't respond to r/w requests to the last SIO block\n" + "hf iclass sim -t 7 --> simulate full iCLASS 2k tag that doesn't XOR or respond to r/w requests on block 3"); void *argtable[] = { arg_param_begin, @@ -876,7 +877,7 @@ static int CmdHFiClassSim(const char *Cmd) { CLIParserFree(ctx); - if (sim_type > 4 && sim_type != 6) { + if (sim_type > 4 && sim_type != 6 && sim_type != 7) { PrintAndLogEx(ERR, "Undefined simtype %d", sim_type); return PM3_EINVARG; } @@ -1030,6 +1031,7 @@ static int CmdHFiClassSim(const char *Cmd) { case ICLASS_SIM_MODE_CSN_DEFAULT: case ICLASS_SIM_MODE_FULL: case ICLASS_SIM_MODE_FULL_GLITCH: + case ICLASS_SIM_MODE_FULL_GLITCH_KEY: default: { PrintAndLogEx(INFO, "Starting iCLASS simulation"); PrintAndLogEx(INFO, "Press " _GREEN_("`pm3 button`") " to abort"); @@ -1037,7 +1039,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 || sim_type == ICLASS_SIM_MODE_FULL_GLITCH) + if (sim_type == ICLASS_SIM_MODE_FULL || sim_type == ICLASS_SIM_MODE_FULL_GLITCH || sim_type == ICLASS_SIM_MODE_FULL_GLITCH_KEY) 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 f3d1c7896..8210490a8 100644 --- a/include/iclass_cmd.h +++ b/include/iclass_cmd.h @@ -49,6 +49,7 @@ #define ICLASS_SIM_MODE_READER_ATTACK_KEYROLL 4 #define ICLASS_SIM_MODE_EXIT_AFTER_MAC 5 // note: device internal only #define ICLASS_SIM_MODE_FULL_GLITCH 6 +#define ICLASS_SIM_MODE_FULL_GLITCH_KEY 7 // iCLASS auth request data structure