hf mfu sim --1a2-mirror

This commit is contained in:
Philippe Teuwen
2026-06-04 20:19:15 +02:00
parent 01b3cd2720
commit fb238015fa
6 changed files with 35 additions and 10 deletions
+3 -1
View File
@@ -1896,12 +1896,14 @@ static void PacketReceived(PacketCommandNG *packet) {
uint8_t ulauth_1a2_len;
uint8_t ulauth_1a1[16];
uint8_t ulauth_1a2[16];
bool ulauth_1a2_mirror;
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
SimulateIso14443aTagEx(payload->tagtype, payload->flags, payload->uid,
payload->exitAfter, payload->rats, sizeof(payload->rats),
payload->ulauth_1a1, payload->ulauth_1a1_len,
payload->ulauth_1a2, payload->ulauth_1a2_len
payload->ulauth_1a2, payload->ulauth_1a2_len,
payload->ulauth_1a2_mirror
); // ## Simulate iso14443a tag - pass tag type & UID
break;
}
+17 -6
View File
@@ -1716,13 +1716,14 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
// 'hf 14a sim'
//-----------------------------------------------------------------------------
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);
SimulateIso14443aTagEx(tagType, flags, useruid, exitAfterNReads, NULL, 0, NULL, 0, NULL, 0, false);
}
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) {
uint8_t *ulauth_1a2, uint8_t ulauth_1a2_len,
bool ulauth_1a2_mirror) {
#define ATTACK_KEY_COUNT 16
#define ULC_TAG_NONCE "\x01\x02\x03\x04\x05\x06\x07\x08"
@@ -2214,10 +2215,12 @@ void SimulateIso14443aTagEx(uint8_t tagType, uint16_t flags, uint8_t *useruid, u
ror(rnd_ab + 8, 8);
if (memcmp(rnd_ab + 8, ULC_TAG_NONCE, 8) != 0) {
Dbprintf("failed authentication");
if (ulauth_1a2_len == 8 && ulauth_1a2 != NULL) {
Dbprintf("failed authentication but --1a2 is set, responding with it anyway");
Dbprintf("but honoring --1a2 anyway");
} else if (ulauth_1a2_mirror) {
Dbprintf("but honoring --1a2-mirror anyway");
} else {
Dbprintf("failed authentication");
EmSend4bit(CARD_NACK_IV);
p_response = NULL;
goto jump;
@@ -2235,6 +2238,9 @@ void SimulateIso14443aTagEx(uint8_t tagType, uint16_t flags, uint8_t *useruid, u
// encrypt RndA
tdes_nxp_send(rnd_ab, dynamic_response_info.response + 1, 8, ulc_key, ulc_iv, 2);
if (ulauth_1a2_mirror) {
memcpy(dynamic_response_info.response + 1, enc_rnd_ab, 8);
}
}
// Add CRC
@@ -2293,10 +2299,12 @@ void SimulateIso14443aTagEx(uint8_t tagType, uint16_t flags, uint8_t *useruid, u
// Remember our tag nonce is twice the ULC_TAG_NONCE
if ((memcmp(rnd_ab + 16, ULC_TAG_NONCE, 8) != 0) || (memcmp(rnd_ab + 24, ULC_TAG_NONCE, 8) != 0)) {
Dbprintf("failed authentication");
if (ulauth_1a2_len == 16 && ulauth_1a2 != NULL) {
Dbprintf("failed authentication but --1a2 is set, responding with it anyway");
Dbprintf("but honoring --1a2 anyway");
} else if (ulauth_1a2_mirror) {
Dbprintf("but honoring --1a2-mirror anyway");
} else {
Dbprintf("failed authentication");
EmSend4bit(CARD_NACK_IV);
p_response = NULL;
goto jump;
@@ -2315,6 +2323,9 @@ void SimulateIso14443aTagEx(uint8_t tagType, uint16_t flags, uint8_t *useruid, u
memset(ulc_iv, 0x00, 16);
// encrypt RndA
aes128_nxp_send(rnd_ab, dynamic_response_info.response + 1, 16, ulc_key, ulc_iv);
if (ulauth_1a2_mirror) {
memcpy(dynamic_response_info.response + 1, enc_rnd_ab, 16);
}
}
// Add CRC
+2 -1
View File
@@ -147,7 +147,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
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);
uint8_t *ulauth_1a2, uint8_t ulauth_1a2_len,
bool ulauth_1a2_mirror);
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,
+5
View File
@@ -927,6 +927,8 @@ int CmdHF14ASim(const char *Cmd) {
arg_lit0("v", "verbose", "verbose output"),
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_lit0(NULL, "1a2-mirror", "Mirror ek(RndA) from step1 reply into step2 reply"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@@ -966,6 +968,7 @@ int CmdHF14ASim(const char *Cmd) {
uint8_t ulauth_1a2[16] = {0};
CLIGetHexWithReturn(ctx, 7, ulauth_1a1, &ulauth_1a1_len);
CLIGetHexWithReturn(ctx, 8, ulauth_1a2, &ulauth_1a2_len);
bool ulauth_1a2_mirror = arg_get_lit(ctx, 9);
CLIParserFree(ctx);
if (ulauth_1a1_len > 0) {
@@ -1026,6 +1029,7 @@ int CmdHF14ASim(const char *Cmd) {
uint8_t ulauth_1a2_len;
uint8_t ulauth_1a1[16];
uint8_t ulauth_1a2[16];
bool ulauth_1a2_mirror;
} PACKED payload;
payload.tagtype = tagtype;
@@ -1033,6 +1037,7 @@ int CmdHF14ASim(const char *Cmd) {
payload.exitAfter = exitAfterNReads;
payload.ulauth_1a1_len = ulauth_1a1_len;
payload.ulauth_1a2_len = ulauth_1a2_len;
payload.ulauth_1a2_mirror = ulauth_1a2_mirror;
memcpy(payload.uid, uid, uid_len);
memcpy(payload.ulauth_1a1, ulauth_1a1, ulauth_1a1_len);
memcpy(payload.ulauth_1a2, ulauth_1a2, ulauth_1a2_len);
+7 -2
View File
@@ -565,13 +565,18 @@ static int CmdHF14AJookiSim(const char *Cmd) {
uint8_t flags;
uint8_t uid[10];
uint8_t exitAfter;
uint8_t rats[20];
uint8_t ulauth_1a1_len;
uint8_t ulauth_1a2_len;
uint8_t ulauth_1a1[16];
uint8_t ulauth_1a2[16];
bool ulauth_1a2_mirror;
} PACKED payload;
memset(&payload, 0x00, sizeof(payload));
// NTAG, 7 byte UID in eloaded data.
payload.tagtype = 7;
payload.flags = 0;
FLAG_SET_UID_IN_EMUL(payload.flags);
payload.exitAfter = 0;
memcpy(payload.uid, uid, sizeof(uid));
clearCommandBuffer();
+1
View File
@@ -4338,6 +4338,7 @@ static int CmdHF14AMfUSim(const char *Cmd) {
arg_lit0("v", "verbose", "Verbose output"),
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_lit0(NULL, "1a2-mirror", "Mirror ek(RndA) from step1 reply into step2 reply"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);