mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-09-11 18:29:22 -07:00
OLD/MIX convert to NG: Phase C7
This commit is contained in:
+6
-1
@@ -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
@@ -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).
|
||||
|
||||
@@ -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
@@ -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));
|
||||
|
||||
@@ -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_
|
||||
|
||||
Reference in New Issue
Block a user