Merge pull request #2853 from sup3rgiu/mfu-counters

Fixed SimulateIso14443aTag() to make MFU counter increments persistent in emulator memory.
This commit is contained in:
Iceman 2025-05-29 14:44:13 +02:00 committed by GitHub
commit 90210fe588
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 34 additions and 34 deletions

View file

@ -15,6 +15,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Fixed `make install` on OSX thanks DaveItsLong (@doegox)
- Added new standalone mode `HF_ST25_TEAROFF` to store/restore ST25TB tags with tearoff for counters (@seclabz)
- Added `hf_mfu_ultra.lua` script enables restoring dump to ULTRA/UL-5 tags and clearing previously written ULTRA tags (@mak-42)
- Fixed `hf mfu sim` to make persistent the counter increases in the emulator memory (@sup3rgiu)
## [Blue Ice.4.20142][2025-03-25]
- Added `des_talk.py` script for easier MIFARE DESFire handling (@trigat)

View file

@ -233,10 +233,8 @@ static void become_card(void) {
tag_response_info_t *canned;
uint32_t cuid;
uint32_t counters[3] = { 0 };
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
uint8_t pages;
SimulateIso14443aInit(tagType, flags, data, NULL, 0, &canned, &cuid, counters, tearings, &pages);
SimulateIso14443aInit(tagType, flags, data, NULL, 0, &canned, &cuid, &pages);
DbpString(_CYAN_("[@]") " Setup done - entering emulation loop");
int fromReaderLen;

View file

@ -379,7 +379,7 @@ void RunMod(void) {
BigBuf_free_keep_EM();
// tag type: 11 = ISO/IEC 14443-4 - javacard (JCOP)
if (SimulateIso14443aInit(11, flags, data, NULL, 0, &responses, &cuid, NULL, NULL, NULL) == false) {
if (SimulateIso14443aInit(11, flags, data, NULL, 0, &responses, &cuid, NULL) == false) {
BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
DbpString(_RED_("Error initializing the emulation process!"));

View file

@ -268,7 +268,7 @@ void RunMod() {
BigBuf_free_keep_EM();
// 4 = ISO/IEC 14443-4 - javacard (JCOP)
if (SimulateIso14443aInit(4, flags, data, NULL, 0, &responses, &cuid, NULL, NULL, NULL) == false) {
if (SimulateIso14443aInit(4, flags, data, NULL, 0, &responses, &cuid, NULL) == false) {
BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
DbpString(_RED_("Error initializing the emulation process!"));

View file

@ -118,8 +118,6 @@ void RunMod(void) {
uint8_t tagType = 10; // 10 = ST25TA IKEA Rothult
tag_response_info_t *responses;
uint32_t cuid = 0;
uint32_t counters[3] = { 0x00, 0x00, 0x00 };
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
uint8_t pages = 0;
// command buffers
@ -193,7 +191,7 @@ void RunMod(void) {
memcpy(data, stuid, sizeof(stuid));
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, counters, tearings, &pages) == false) {
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, &pages) == false) {
BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
DbpString(_YELLOW_("!!") "Error initializing the simulation process!");
@ -371,7 +369,7 @@ void RunMod(void) {
memcpy(data, stuid, sizeof(stuid));
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, counters, tearings, &pages) == false) {
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, &pages) == false) {
BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
DbpString(_YELLOW_("!!") "Error initializing the simulation process!");

View file

@ -1184,7 +1184,7 @@ bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_
bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
uint8_t *ats, size_t ats_len, tag_response_info_t **responses,
uint32_t *cuid, uint32_t counters[3], uint8_t tearings[3], uint8_t *pages) {
uint32_t *cuid, uint8_t *pages) {
uint8_t sak = 0;
// The first response contains the ATQA (note: bytes are transmitted in reverse order).
static uint8_t rATQA[2] = { 0x00 };
@ -1231,14 +1231,11 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
mfu_dump_t *mfu_header = (mfu_dump_t *) BigBuf_get_EM_addr();
*pages = MAX(mfu_header->pages, 15);
// counters and tearing flags
// tearing flags
// for old dumps with all zero headers, we need to set default values.
for (uint8_t i = 0; i < 3; i++) {
counters[i] = le24toh(mfu_header->counter_tearing[i]);
if (mfu_header->counter_tearing[i][3] != 0x00) {
tearings[i] = mfu_header->counter_tearing[i][3];
if (mfu_header->counter_tearing[i][3] == 0x00) {
mfu_header->counter_tearing[i][3] = 0xBD;
}
}
@ -1286,14 +1283,11 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
mfu_dump_t *mfu_header = (mfu_dump_t *) BigBuf_get_EM_addr();
*pages = MAX(mfu_header->pages, 19);
// counters and tearing flags
// tearing flags
// for old dumps with all zero headers, we need to set default values.
for (uint8_t i = 0; i < 3; i++) {
counters[i] = le24toh(mfu_header->counter_tearing[i]);
if (mfu_header->counter_tearing[i][3] != 0x00) {
tearings[i] = mfu_header->counter_tearing[i][3];
if (mfu_header->counter_tearing[i][3] == 0x00) {
mfu_header->counter_tearing[i][3] = 0xBD;
}
}
@ -1539,8 +1533,6 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
tag_response_info_t *responses;
uint32_t cuid = 0;
uint32_t nonce = 0;
uint32_t counters[3] = { 0x00, 0x00, 0x00 };
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
uint8_t pages = 0;
// Here, we collect CUID, block1, keytype1, NT1, NR1, AR1, CUID, block2, keytyp2, NT2, NR2, AR2
@ -1584,12 +1576,22 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
.modulation_n = 0
};
if (SimulateIso14443aInit(tagType, flags, useruid, ats, ats_len, &responses, &cuid, counters, tearings, &pages) == false) {
if (SimulateIso14443aInit(tagType, flags, useruid, ats, ats_len, &responses, &cuid, &pages) == false) {
BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
return;
}
mfu_dump_t *mfu_em_dump = NULL;
if (tagType == 2 || tagType == 7) {
mfu_em_dump = (mfu_dump_t *)BigBuf_get_EM_addr();
if (!mfu_em_dump) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("[-] ERROR: Failed to get EM address for MFU/NTAG operations.");
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EMALLOC, NULL, 0);
return;
}
}
// We need to listen to the high-frequency, peak-detected path.
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
@ -1870,8 +1872,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
// send NACK 0x0 == invalid argument
EmSend4bit(CARD_NACK_IV);
} else {
uint8_t cmd[] = {0x00, 0x00, 0x00, 0x14, 0xa5};
htole24(counters[index], cmd);
uint8_t cmd[] = {0, 0, 0, 0x14, 0xa5};
memcpy(cmd, mfu_em_dump->counter_tearing[index], 3);
AddCrc14A(cmd, sizeof(cmd) - 2);
EmSendCmd(cmd, sizeof(cmd));
}
@ -1882,13 +1884,16 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
// send NACK 0x0 == invalid argument
EmSend4bit(CARD_NACK_IV);
} else {
uint32_t val = le24toh(receivedCmd + 2) + counters[index];
uint32_t val = le24toh(mfu_em_dump->counter_tearing[index]); // get current counter value
val += le24toh(receivedCmd + 2); // increment in
// if new value + old value is bigger 24bits, fail
if (val > 0xFFFFFF) {
// send NACK 0x4 == counter overflow
EmSend4bit(CARD_NACK_NA);
} else {
counters[index] = val;
htole24(val, mfu_em_dump->counter_tearing[index]);
// send ACK
EmSend4bit(CARD_ACK);
}
@ -1902,7 +1907,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
EmSend4bit(CARD_NACK_IV);
} else {
uint8_t cmd[3] = {0, 0, 0};
cmd[0] = tearings[index];
cmd[0] = mfu_em_dump->counter_tearing[index][3];
AddCrc14A(cmd, sizeof(cmd) - 2);
EmSendCmd(cmd, sizeof(cmd));
}
@ -4091,8 +4096,6 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
uint8_t *getdata_response, size_t getdata_response_len) {
tag_response_info_t *responses;
uint32_t cuid = 0;
uint32_t counters[3] = { 0x00, 0x00, 0x00 };
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
uint8_t pages = 0;
// command buffers
@ -4133,7 +4136,7 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
.modulation_n = 0
};
if (SimulateIso14443aInit(tagType, flags, uid, ats, ats_len, &responses, &cuid, counters, tearings, &pages) == false) {
if (SimulateIso14443aInit(tagType, flags, uid, ats, ats_len, &responses, &cuid, &pages) == false) {
BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
return;

View file

@ -152,7 +152,7 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
uint8_t *ats, size_t ats_len, tag_response_info_t **responses,
uint32_t *cuid, uint32_t counters[3], uint8_t tearings[3], uint8_t *pages);
uint32_t *cuid, uint8_t *pages);
bool GetIso14443aCommandFromReader(uint8_t *received, uint16_t received_maxlen, uint8_t *par, int *len);
void iso14443a_antifuzz(uint32_t flags);