OLD/MIX convert to NG: Phase C7

This commit is contained in:
iceman1001
2026-08-29 15:00:03 +02:00
parent 3762130c42
commit 0bbc9025ae
5 changed files with 92 additions and 30 deletions
+6 -1
View File
@@ -2663,7 +2663,12 @@ static void PacketReceived(PacketCommandNG *packet) {
struct p *payload = (struct p *) packet->data.asBytes;
*/
SimulateIClass(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes);
if (packet->length < sizeof(iclass_sim_t)) {
reply_ng(CMD_HF_ICLASS_SIMULATE, PM3_EINVARG, NULL, 0);
break;
}
iclass_sim_t *payload = (iclass_sim_t *)packet->data.asBytes;
iclass_simulate(payload->sim_type, payload->num_csns, payload->send_reply, true, payload->csns, NULL, NULL);
break;
}
case CMD_HF_ICLASS_READER: {
+15 -8
View File
@@ -138,8 +138,15 @@ static void CodeIClassTagSOF(void) {
* @param datain
*/
// turn off afterwards
void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) {
iclass_simulate(arg0, arg1, arg2, true, datain, NULL, NULL);
static void reply_iclass_sim(uint16_t num_mac, const uint8_t *macs, uint16_t maclen) {
uint8_t respbuf[sizeof(iclass_sim_resp_t) + PM3_CMD_DATA_SIZE] = {0};
iclass_sim_resp_t *response = (iclass_sim_resp_t *)respbuf;
response->num_mac = num_mac;
if (maclen && macs) {
memcpy(response->mac, macs, maclen);
}
reply_ng(CMD_HF_ICLASS_SIMULATE, PM3_SUCCESS, respbuf, sizeof(iclass_sim_resp_t) + maclen);
}
void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, bool trace, uint8_t *datain, uint8_t *dataout, uint16_t *dataoutlen) {
@@ -187,7 +194,7 @@ void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, bool t
// Button pressed
if (send_reply)
reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i, 0, mac_responses, i * EPURSE_MAC_SIZE);
reply_iclass_sim(i, mac_responses, i * EPURSE_MAC_SIZE);
goto out;
}
}
@@ -195,7 +202,7 @@ void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, bool t
*dataoutlen = i * EPURSE_MAC_SIZE;
if (send_reply)
reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i, 0, mac_responses, i * EPURSE_MAC_SIZE);
reply_iclass_sim(i, mac_responses, i * EPURSE_MAC_SIZE);
} else if (sim_type == ICLASS_SIM_MODE_FULL || sim_type == ICLASS_SIM_MODE_FULL_GLITCH || sim_type == ICLASS_SIM_MODE_FULL_GLITCH_KEY || sim_type == ICLASS_SIM_MODE_FULL_LIVE) {
@@ -210,7 +217,7 @@ void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, bool t
}
if (send_reply) {
reply_mix(CMD_ACK, CMD_HF_ICLASS_SIMULATE, 0, 0, NULL, 0);
reply_iclass_sim(0, NULL, 0);
}
} else if (sim_type == ICLASS_SIM_MODE_READER_ATTACK_KEYROLL) {
@@ -239,7 +246,7 @@ void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, bool t
*dataoutlen = i * EPURSE_MAC_SIZE * 2;
if (send_reply)
reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2);
reply_iclass_sim(i * 2, mac_responses, i * EPURSE_MAC_SIZE * 2);
// Button pressed
goto out;
@@ -252,7 +259,7 @@ void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, bool t
*dataoutlen = i * EPURSE_MAC_SIZE * 2;
if (send_reply)
reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2);
reply_iclass_sim(i * 2, mac_responses, i * EPURSE_MAC_SIZE * 2);
// Button pressed
goto out;
@@ -264,7 +271,7 @@ void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, bool t
// double the amount of collected data.
if (send_reply)
reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2);
reply_iclass_sim(i * 2, mac_responses, i * EPURSE_MAC_SIZE * 2);
} else {
// We may want a mode here where we hardcode the csns to use (from proxclone).
-1
View File
@@ -58,7 +58,6 @@ void iClass_Restore(iclass_restore_req_t *msg);
int do_iclass_simulation_nonsec(void);
int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf);
void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, bool trace, uint8_t *datain, uint8_t *dataout, uint16_t *dataoutlen);
void iClass_Authentication_fast(iclass_chk_t *p);
+53 -20
View File
@@ -1140,9 +1140,15 @@ static int CmdHFiClassSim(const char *Cmd) {
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to abort");
PacketResponseNG resp;
clearCommandBuffer();
SendCommandMIX(CMD_HF_ICLASS_SIMULATE, sim_type, NUM_CSNS, 1, csns, NUM_CSNS * PICOPASS_BLOCK_SIZE);
uint8_t sbuf[sizeof(iclass_sim_t) + (NUM_CSNS * PICOPASS_BLOCK_SIZE)] = {0};
iclass_sim_t *spayload = (iclass_sim_t *)sbuf;
spayload->sim_type = sim_type;
spayload->num_csns = NUM_CSNS;
spayload->send_reply = 1;
memcpy(spayload->csns, csns, NUM_CSNS * PICOPASS_BLOCK_SIZE);
SendCommandNG(CMD_HF_ICLASS_SIMULATE, sbuf, sizeof(sbuf));
while (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) {
while (WaitForResponseTimeout(CMD_HF_ICLASS_SIMULATE, &resp, 2000) == false) {
tries++;
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\naborted via keyboard.");
@@ -1153,7 +1159,8 @@ static int CmdHFiClassSim(const char *Cmd) {
return PM3_ETIMEOUT;
}
}
uint8_t num_mac = resp.oldarg[1];
const iclass_sim_resp_t *sresp = (const iclass_sim_resp_t *)resp.data.asBytes;
uint8_t num_mac = (resp.length >= sizeof(iclass_sim_resp_t)) ? sresp->num_mac : 0;
bool success = (NUM_CSNS == num_mac);
PrintAndLogEx((success) ? SUCCESS : WARNING, "[%c] %d out of %d MAC obtained [%s]", (success) ? '+' : '!', num_mac, NUM_CSNS, (success) ? "OK" : "FAIL");
@@ -1174,9 +1181,9 @@ static int CmdHFiClassSim(const char *Cmd) {
//copy CSN
memcpy(dump + (i * MAC_ITEM_SIZE), csns + i * 8, 8);
//copy epurse
memcpy(dump + (i * MAC_ITEM_SIZE) + 8, resp.data.asBytes + i * 16, 8);
memcpy(dump + (i * MAC_ITEM_SIZE) + 8, sresp->mac + i * 16, 8);
// NR_MAC (eight bytes from the response) ( 8b csn + 8b epurse == 16)
memcpy(dump + (i * MAC_ITEM_SIZE) + 16, resp.data.asBytes + i * 16 + 8, 8);
memcpy(dump + (i * MAC_ITEM_SIZE) + 16, sresp->mac + i * 16 + 8, 8);
}
/** Now, save to dumpfile **/
saveFile("iclass_mac_attack", ".bin", dump, datalen);
@@ -1191,9 +1198,15 @@ static int CmdHFiClassSim(const char *Cmd) {
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to abort");
PacketResponseNG resp;
clearCommandBuffer();
SendCommandMIX(CMD_HF_ICLASS_SIMULATE, sim_type, NUM_CSNS, 1, csns, NUM_CSNS * PICOPASS_BLOCK_SIZE);
uint8_t sbuf[sizeof(iclass_sim_t) + (NUM_CSNS * PICOPASS_BLOCK_SIZE)] = {0};
iclass_sim_t *spayload = (iclass_sim_t *)sbuf;
spayload->sim_type = sim_type;
spayload->num_csns = NUM_CSNS;
spayload->send_reply = 1;
memcpy(spayload->csns, csns, NUM_CSNS * PICOPASS_BLOCK_SIZE);
SendCommandNG(CMD_HF_ICLASS_SIMULATE, sbuf, sizeof(sbuf));
while (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) {
while (WaitForResponseTimeout(CMD_HF_ICLASS_SIMULATE, &resp, 2000) == false) {
tries++;
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\naborted via keyboard.");
@@ -1204,7 +1217,8 @@ static int CmdHFiClassSim(const char *Cmd) {
return PM3_ETIMEOUT;
}
}
uint8_t num_mac = resp.oldarg[1];
const iclass_sim_resp_t *sresp = (const iclass_sim_resp_t *)resp.data.asBytes;
uint8_t num_mac = (resp.length >= sizeof(iclass_sim_resp_t)) ? sresp->num_mac : 0;
bool success = ((NUM_CSNS * 2) == num_mac);
PrintAndLogEx((success) ? SUCCESS : WARNING, "[%c] %d out of %d MAC obtained [%s]", (success) ? '+' : '!', num_mac, NUM_CSNS * 2, (success) ? "OK" : "FAIL");
@@ -1225,9 +1239,9 @@ static int CmdHFiClassSim(const char *Cmd) {
// copy CSN
memcpy(dump + (i * MAC_ITEM_SIZE), csns + i * 8, 8); //CSN
// copy EPURSE
memcpy(dump + (i * MAC_ITEM_SIZE) + 8, resp.data.asBytes + i * 16, 8);
memcpy(dump + (i * MAC_ITEM_SIZE) + 8, sresp->mac + i * 16, 8);
// copy NR_MAC (eight bytes from the response) ( 8b csn + 8b epurse == 16)
memcpy(dump + (i * MAC_ITEM_SIZE) + 16, resp.data.asBytes + i * 16 + 8, 8);
memcpy(dump + (i * MAC_ITEM_SIZE) + 16, sresp->mac + i * 16 + 8, 8);
}
saveFile("iclass_mac_attack_keyroll_A", ".bin", dump, datalen);
@@ -1238,9 +1252,9 @@ static int CmdHFiClassSim(const char *Cmd) {
// Copy CSN
memcpy(dump + (i * MAC_ITEM_SIZE), csns + i * 8, 8);
// copy EPURSE
memcpy(dump + (i * MAC_ITEM_SIZE) + 8, resp.data.asBytes + resp_index, 8);
memcpy(dump + (i * MAC_ITEM_SIZE) + 8, sresp->mac + resp_index, 8);
// copy NR_MAC (eight bytes from the response) ( 8b csn + 8 epurse == 16)
memcpy(dump + (i * MAC_ITEM_SIZE) + 16, resp.data.asBytes + resp_index + 8, 8);
memcpy(dump + (i * MAC_ITEM_SIZE) + 16, sresp->mac + resp_index + 8, 8);
resp_index++;
}
saveFile("iclass_mac_attack_keyroll_B", ".bin", dump, datalen);
@@ -1260,7 +1274,13 @@ static int CmdHFiClassSim(const char *Cmd) {
PrintAndLogEx(INFO, "Press " _GREEN_("`pm3 button`") " to abort");
uint8_t numberOfCSNs = 0;
clearCommandBuffer();
SendCommandMIX(CMD_HF_ICLASS_SIMULATE, sim_type, numberOfCSNs, 0, csn, 8);
uint8_t sbuf[sizeof(iclass_sim_t) + 8] = {0};
iclass_sim_t *spayload = (iclass_sim_t *)sbuf;
spayload->sim_type = sim_type;
spayload->num_csns = numberOfCSNs;
spayload->send_reply = 0;
memcpy(spayload->csns, csn, 8);
SendCommandNG(CMD_HF_ICLASS_SIMULATE, sbuf, sizeof(sbuf));
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");
@@ -1609,7 +1629,13 @@ static int CmdHFiClassTagSim(const char *Cmd) {
}
clearCommandBuffer();
SendCommandMIX(CMD_HF_ICLASS_SIMULATE, ICLASS_SIM_MODE_FULL_LIVE, 0, 1, csn, 8);
uint8_t sbuf[sizeof(iclass_sim_t) + 8] = {0};
iclass_sim_t *spayload = (iclass_sim_t *)sbuf;
spayload->sim_type = ICLASS_SIM_MODE_FULL_LIVE;
spayload->num_csns = 0;
spayload->send_reply = 1;
memcpy(spayload->csns, csn, 8);
SendCommandNG(CMD_HF_ICLASS_SIMULATE, sbuf, sizeof(sbuf));
PacketResponseNG resp;
bool running = true;
@@ -7002,10 +7028,16 @@ static int CmdHFiClassLookUp(const char *Cmd) {
// Device returns: epurse[8] + NR[4] + MAC_reader[4]
PacketResponseNG resp;
clearCommandBuffer();
SendCommandMIX(CMD_HF_ICLASS_SIMULATE, ICLASS_SIM_MODE_READER_ATTACK, 1, 1, csn, 8);
uint8_t sbuf[sizeof(iclass_sim_t) + 8] = {0};
iclass_sim_t *spayload = (iclass_sim_t *)sbuf;
spayload->sim_type = ICLASS_SIM_MODE_READER_ATTACK;
spayload->num_csns = 1;
spayload->send_reply = 1;
memcpy(spayload->csns, csn, 8);
SendCommandNG(CMD_HF_ICLASS_SIMULATE, sbuf, sizeof(sbuf));
uint8_t tries = 0;
while (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) {
while (WaitForResponseTimeout(CMD_HF_ICLASS_SIMULATE, &resp, 2000) == false) {
tries++;
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\naborted via keyboard.");
@@ -7017,16 +7049,17 @@ static int CmdHFiClassLookUp(const char *Cmd) {
}
}
uint8_t num_mac = resp.oldarg[1];
const iclass_sim_resp_t *sresp = (const iclass_sim_resp_t *)resp.data.asBytes;
uint8_t num_mac = (resp.length >= sizeof(iclass_sim_resp_t)) ? sresp->num_mac : 0;
if (num_mac == 0) {
PrintAndLogEx(WARNING, "No CHECK command captured from reader");
return PM3_ESOFT;
}
uint8_t cap_epurse[8], nr[4], mac_r[4];
memcpy(cap_epurse, resp.data.asBytes, 8);
memcpy(nr, resp.data.asBytes + 8, 4);
memcpy(mac_r, resp.data.asBytes + 12, 4);
memcpy(cap_epurse, sresp->mac, 8);
memcpy(nr, sresp->mac + 8, 4);
memcpy(mac_r, sresp->mac + 12, 4);
PrintAndLogEx(SUCCESS, "Captured CHECK:");
PrintAndLogEx(SUCCESS, " ePurse.... %s", sprint_hex(cap_epurse, 8));
+18
View File
@@ -209,4 +209,22 @@ typedef struct {
uint8_t data[PICOPASS_MAX_BYTES];
} PACKED iclass_tag_t;
// CMD_HF_ICLASS_SIMULATE payload.
// Replaces oldargs: arg0 = sim_type, arg1 = num_csns, arg2 = send_reply
typedef struct {
uint8_t sim_type;
uint8_t num_csns;
uint8_t send_reply;
uint8_t rfu;
uint8_t csns[];
} PACKED iclass_sim_t;
// Reply for the reader-attack sim modes. The old reply put the opcode itself
// into arg0 so the client could tell anonymous CMD_ACKs apart; NG carries the
// opcode in the frame, so only the mac count is left to send.
typedef struct {
uint16_t num_mac;
uint8_t mac[];
} PACKED iclass_sim_resp_t;
#endif // _ICLASS_H_