mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
hf mfu sim: add support to inject card replies
This commit is contained in:
@@ -246,7 +246,7 @@ void RunMod(void) {
|
||||
FLAG_SET_UID_IN_DATA(flags, 7);
|
||||
|
||||
Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state.");
|
||||
SimulateIso14443aTag(7, flags, card.uid, 0, NULL, 0, false, false);
|
||||
SimulateIso14443aTag(7, flags, card.uid, 0);
|
||||
|
||||
// Go back to search state if user presses pm3-button
|
||||
state = STATE_SEARCH;
|
||||
|
||||
@@ -89,22 +89,22 @@ void RunMod(void) {
|
||||
Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state.");
|
||||
if (card.sak == 0x08 && card.atqa[0] == 0x04 && card.atqa[1] == 0) {
|
||||
DbpString("Mifare Classic 1k");
|
||||
SimulateIso14443aTag(1, flags, card.uid, 0, NULL, 0, false, false);
|
||||
SimulateIso14443aTag(1, flags, card.uid, 0);
|
||||
} else if (card.sak == 0x08 && card.atqa[0] == 0x44 && card.atqa[1] == 0) {
|
||||
DbpString("Mifare Classic 4k ");
|
||||
SimulateIso14443aTag(8, flags, card.uid, 0, NULL, 0, false, false);
|
||||
SimulateIso14443aTag(8, flags, card.uid, 0);
|
||||
} else if (card.sak == 0x00 && card.atqa[0] == 0x44 && card.atqa[1] == 0) {
|
||||
DbpString("Mifare Ultralight");
|
||||
SimulateIso14443aTag(2, flags, card.uid, 0, NULL, 0, false, false);
|
||||
SimulateIso14443aTag(2, flags, card.uid, 0);
|
||||
} else if (card.sak == 0x20 && card.atqa[0] == 0x04 && card.atqa[1] == 0x03) {
|
||||
DbpString("Mifare DESFire");
|
||||
SimulateIso14443aTag(3, flags, card.uid, 0, NULL, 0, false, false);
|
||||
SimulateIso14443aTag(3, flags, card.uid, 0);
|
||||
} else if (card.sak == 0x20 && card.atqa[0] == 0x44 && card.atqa[1] == 0x03) {
|
||||
DbpString("Mifare DESFire Ev1/Plus/JCOP");
|
||||
SimulateIso14443aTag(3, flags, card.uid, 0, NULL, 0, false, false);
|
||||
SimulateIso14443aTag(3, flags, card.uid, 0);
|
||||
} else {
|
||||
Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
|
||||
SimulateIso14443aTag(1, flags, card.uid, 0, NULL, 0, false, false);
|
||||
SimulateIso14443aTag(1, flags, card.uid, 0);
|
||||
}
|
||||
|
||||
// Go back to search state if user presses pm3-button
|
||||
|
||||
@@ -253,25 +253,25 @@ void RunMod(void) {
|
||||
|
||||
if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0) {
|
||||
DbpString("Mifare Classic 1k");
|
||||
SimulateIso14443aTag(1, flags, data, 0, NULL, 0, false, false);
|
||||
SimulateIso14443aTag(1, flags, data, 0);
|
||||
} else if (uids[selected].sak == 0x18 && uids[selected].atqa[0] == 0x02 && uids[selected].atqa[1] == 0) {
|
||||
DbpString("Mifare Classic 4k (4b uid)");
|
||||
SimulateIso14443aTag(8, flags, data, 0, NULL, 0, false, false);
|
||||
SimulateIso14443aTag(8, flags, data, 0);
|
||||
} else if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) {
|
||||
DbpString("Mifare Classic 4k (7b uid)");
|
||||
SimulateIso14443aTag(8, flags, data, 0, NULL, 0, false, false);
|
||||
SimulateIso14443aTag(8, flags, data, 0);
|
||||
} else if (uids[selected].sak == 0x00 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) {
|
||||
DbpString("Mifare Ultralight");
|
||||
SimulateIso14443aTag(2, flags, data, 0, NULL, 0, false, false);
|
||||
SimulateIso14443aTag(2, flags, data, 0);
|
||||
} else if (uids[selected].sak == 0x20 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0x03) {
|
||||
DbpString("Mifare DESFire");
|
||||
SimulateIso14443aTag(3, flags, data, 0, NULL, 0, false, false);
|
||||
SimulateIso14443aTag(3, flags, data, 0);
|
||||
} else if (uids[selected].sak == 0x20 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0x03) {
|
||||
DbpString("Mifare DESFire Ev1/Plus/JCOP");
|
||||
SimulateIso14443aTag(3, flags, data, 0, NULL, 0, false, false);
|
||||
SimulateIso14443aTag(3, flags, data, 0);
|
||||
} else {
|
||||
Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
|
||||
SimulateIso14443aTag(1, flags, data, 0, NULL, 0, false, false);
|
||||
SimulateIso14443aTag(1, flags, data, 0);
|
||||
}
|
||||
|
||||
} else if (button_pressed == BUTTON_SINGLE_CLICK) {
|
||||
|
||||
+8
-4
@@ -1779,13 +1779,17 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
uint8_t uid[10];
|
||||
uint8_t exitAfter;
|
||||
uint8_t rats[20];
|
||||
bool ulauth_z1;
|
||||
bool ulauth_z2;
|
||||
uint8_t ulauth_1a1_len;
|
||||
uint8_t ulauth_1a2_len;
|
||||
uint8_t ulauth_1a1[16];
|
||||
uint8_t ulauth_1a2[16];
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *) packet->data.asBytes;
|
||||
SimulateIso14443aTag(payload->tagtype, payload->flags, payload->uid,
|
||||
SimulateIso14443aTagEx(payload->tagtype, payload->flags, payload->uid,
|
||||
payload->exitAfter, payload->rats, sizeof(payload->rats),
|
||||
payload->ulauth_z1, payload->ulauth_z2); // ## Simulate iso14443a tag - pass tag type & UID
|
||||
payload->ulauth_1a1, payload->ulauth_1a1_len,
|
||||
payload->ulauth_1a2, payload->ulauth_1a2_len
|
||||
); // ## Simulate iso14443a tag - pass tag type & UID
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ISO14443A_SIM_AID: {
|
||||
|
||||
+15
-12
@@ -1621,9 +1621,14 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
||||
// response to send, and send it.
|
||||
// 'hf 14a sim'
|
||||
//-----------------------------------------------------------------------------
|
||||
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads,
|
||||
uint8_t *ats, size_t ats_len, bool ulauth_z1, bool ulauth_z2) {
|
||||
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads) {
|
||||
SimulateIso14443aTagEx(tagType, flags, useruid, exitAfterNReads, NULL, 0, NULL, 0, NULL, 0);
|
||||
}
|
||||
|
||||
void SimulateIso14443aTagEx(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads,
|
||||
uint8_t *ats, size_t ats_len,
|
||||
uint8_t *ulauth_1a1, uint8_t ulauth_1a1_len,
|
||||
uint8_t *ulauth_1a2, uint8_t ulauth_1a2_len) {
|
||||
#define ATTACK_KEY_COUNT 16
|
||||
#define ULC_TAG_NONCE "\x01\x02\x03\x04\x05\x06\x07\x08"
|
||||
|
||||
@@ -2065,8 +2070,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
||||
// our very random TAG NONCE
|
||||
memcpy(dynamic_response_info.response + 1, ULC_TAG_NONCE, 8);
|
||||
|
||||
if (ulauth_z1) {
|
||||
memset(dynamic_response_info.response + 1, 0, 8);
|
||||
if (ulauth_1a1_len == 8 && ulauth_1a1 != NULL) {
|
||||
memcpy(dynamic_response_info.response + 1, ulauth_1a1, ulauth_1a1_len);
|
||||
} else {
|
||||
// encrypt TAG NONCE
|
||||
tdes_nxp_send(dynamic_response_info.response + 1, dynamic_response_info.response + 1, 8, ulc_key, ulc_iv, 2);
|
||||
@@ -2104,9 +2109,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
||||
// OK response
|
||||
dynamic_response_info.response[0] = 0x00;
|
||||
|
||||
if (ulauth_z2) {
|
||||
// try empty auth but with correct CRC and 0x00 command
|
||||
memset(dynamic_response_info.response + 1, 0, 8);
|
||||
if (ulauth_1a2_len == 8 && ulauth_1a2 != NULL) {
|
||||
memcpy(dynamic_response_info.response + 1, ulauth_1a2, ulauth_1a2_len);
|
||||
} else {
|
||||
// rol RndA
|
||||
rol(rnd_ab, 8);
|
||||
@@ -2139,8 +2143,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
||||
memcpy(dynamic_response_info.response + 1, ULC_TAG_NONCE, 8);
|
||||
memcpy(dynamic_response_info.response + 9, ULC_TAG_NONCE, 8);
|
||||
|
||||
if (ulauth_z1) {
|
||||
memset(dynamic_response_info.response + 1, 0, 16);
|
||||
if (ulauth_1a1_len == 16 && ulauth_1a1 != NULL) {
|
||||
memcpy(dynamic_response_info.response + 1, ulauth_1a1, ulauth_1a1_len);
|
||||
} else {
|
||||
// encrypt TAG NONCE
|
||||
aes128_nxp_send(dynamic_response_info.response + 1, dynamic_response_info.response + 1, 16, ulc_key, ulc_iv);
|
||||
@@ -2180,9 +2184,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
||||
// OK response
|
||||
dynamic_response_info.response[0] = 0x00;
|
||||
|
||||
if (ulauth_z2) {
|
||||
// try empty auth but with correct CRC and 0x00 command
|
||||
memset(dynamic_response_info.response + 1, 0, 16);
|
||||
if (ulauth_1a2_len == 16 && ulauth_1a2 != NULL) {
|
||||
memcpy(dynamic_response_info.response + 1, ulauth_1a2, ulauth_1a2_len);
|
||||
} else {
|
||||
// rol RndA
|
||||
rol(rnd_ab, 16);
|
||||
|
||||
+6
-2
@@ -142,8 +142,12 @@ 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 *useruid, uint8_t exitAfterNReads,
|
||||
uint8_t *ats, size_t ats_len, bool ulauth_z1, bool ulauth_z2);
|
||||
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads);
|
||||
|
||||
void SimulateIso14443aTagEx(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads,
|
||||
uint8_t *ats, size_t ats_len,
|
||||
uint8_t *ulauth_1a1, uint8_t ulauth_1a1_len,
|
||||
uint8_t *ulauth_1a2, uint8_t ulauth_1a2_len);
|
||||
|
||||
void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
|
||||
uint8_t *ats, size_t ats_len, uint8_t *aid, size_t aid_len,
|
||||
|
||||
+55
-9
@@ -921,8 +921,8 @@ int CmdHF14ASim(const char *Cmd) {
|
||||
arg_lit0("x", NULL, "Performs the 'reader attack', nr/ar attack against a reader"),
|
||||
arg_lit0(NULL, "sk", "Fill simulator keys from found keys"),
|
||||
arg_lit0("v", "verbose", "verbose output"),
|
||||
arg_lit0(NULL, "z1", "ULC/ULAES Auth - all zero handshake part 1"),
|
||||
arg_lit0(NULL, "z2", "ULC/ULAES Auth - all zero handshake part 2"),
|
||||
arg_str0(NULL, "1a1", "<hex>", "<8|16> hex bytes ULC/ULAES Auth reply step1: ek(RndB)"),
|
||||
arg_str0(NULL, "1a2", "<hex>", "<8|16> hex bytes ULC/ULAES Auth reply step2: ek(RndA')"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
@@ -956,11 +956,53 @@ int CmdHF14ASim(const char *Cmd) {
|
||||
bool setEmulatorMem = arg_get_lit(ctx, 5);
|
||||
bool verbose = arg_get_lit(ctx, 6);
|
||||
|
||||
bool ulauth_z1 = arg_get_lit(ctx, 7);
|
||||
bool ulauth_z2 = arg_get_lit(ctx, 8);
|
||||
|
||||
int ulauth_1a1_len = 0;
|
||||
int ulauth_1a2_len = 0;
|
||||
uint8_t ulauth_1a1[16] = {0};
|
||||
uint8_t ulauth_1a2[16] = {0};
|
||||
CLIGetHexWithReturn(ctx, 7, ulauth_1a1, &ulauth_1a1_len);
|
||||
CLIGetHexWithReturn(ctx, 8, ulauth_1a2, &ulauth_1a2_len);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (ulauth_1a1_len > 0) {
|
||||
switch (tagtype) {
|
||||
case 13: // ULC
|
||||
if (ulauth_1a1_len != 8) {
|
||||
PrintAndLogEx(ERR, "ULC --1a1 length must be 8 bytes");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
break;
|
||||
case 14: // ULAES
|
||||
if (ulauth_1a1_len != 16) {
|
||||
PrintAndLogEx(ERR, "ULAES --1a1 length must be 16 bytes");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(ERR, "--1a1 option is only valid for tag types 13 (ULC) and 14 (ULAES)");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
if (ulauth_1a2_len > 0) {
|
||||
switch (tagtype) {
|
||||
case 13: // ULC
|
||||
if (ulauth_1a2_len != 8) {
|
||||
PrintAndLogEx(ERR, "ULC --1a2 length must be 8 bytes");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
break;
|
||||
case 14: // ULAES
|
||||
if (ulauth_1a2_len != 16) {
|
||||
PrintAndLogEx(ERR, "ULAES --1a2 length must be 16 bytes");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(ERR, "--1a2 option is only valid for tag types 13 (ULC) and 14 (ULAES)");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
|
||||
if (tagtype > 14) {
|
||||
PrintAndLogEx(ERR, "Undefined tag %d", tagtype);
|
||||
return PM3_EINVARG;
|
||||
@@ -976,16 +1018,20 @@ int CmdHF14ASim(const char *Cmd) {
|
||||
uint8_t uid[10];
|
||||
uint8_t exitAfter;
|
||||
uint8_t rats[20];
|
||||
bool ulauth_z1;
|
||||
bool ulauth_z2;
|
||||
uint8_t ulauth_1a1_len;
|
||||
uint8_t ulauth_1a2_len;
|
||||
uint8_t ulauth_1a1[16];
|
||||
uint8_t ulauth_1a2[16];
|
||||
} PACKED payload;
|
||||
|
||||
payload.tagtype = tagtype;
|
||||
payload.flags = flags;
|
||||
payload.exitAfter = exitAfterNReads;
|
||||
payload.ulauth_z1 = ulauth_z1;
|
||||
payload.ulauth_z2 = ulauth_z2;
|
||||
payload.ulauth_1a1_len = ulauth_1a1_len;
|
||||
payload.ulauth_1a2_len = ulauth_1a2_len;
|
||||
memcpy(payload.uid, uid, uid_len);
|
||||
memcpy(payload.ulauth_1a1, ulauth_1a1, ulauth_1a1_len);
|
||||
memcpy(payload.ulauth_1a2, ulauth_1a2, ulauth_1a2_len);
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_ISO14443A_SIMULATE, (uint8_t *)&payload, sizeof(payload));
|
||||
|
||||
@@ -4125,8 +4125,8 @@ static int CmdHF14AMfUSim(const char *Cmd) {
|
||||
arg_str0("u", "uid", "<hex>", "<4|7|10> hex bytes UID"),
|
||||
arg_int0("n", "num", "<dec>", "Exit simulation after <numreads> blocks. 0 = infinite"),
|
||||
arg_lit0("v", "verbose", "Verbose output"),
|
||||
arg_lit0(NULL, "z1", "ULC/ULAES Auth - all zero handshake part 1"),
|
||||
arg_lit0(NULL, "z2", "ULC/ULAES Auth - all zero handshake part 2"),
|
||||
arg_str0(NULL, "1a1", "<hex>", "<8|16> hex bytes ULC/ULAES Auth reply step1: ek(RndB)"),
|
||||
arg_str0(NULL, "1a2", "<hex>", "<8|16> hex bytes ULC/ULAES Auth reply step2: ek(RndA')"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
Reference in New Issue
Block a user