4A emulation: avoid overflow and don't rely on TL

This commit is contained in:
Philippe Teuwen 2025-02-12 09:06:04 +01:00
commit fcd6de8b7b
2 changed files with 16 additions and 14 deletions

View file

@ -1131,7 +1131,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
// TB(1) = not present. Defaults: FWI = 4 (FWT = 256 * 16 * 2^4 * 1/fc = 4833us), SFGI = 0 (SFG = 256 * 16 * 2^0 * 1/fc = 302us) // TB(1) = not present. Defaults: FWI = 4 (FWT = 256 * 16 * 2^4 * 1/fc = 4833us), SFGI = 0 (SFG = 256 * 16 * 2^0 * 1/fc = 302us)
// TC(1) = 0x02: CID supported, NAD not supported // TC(1) = 0x02: CID supported, NAD not supported
// static uint8_t rATS[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 }; // static uint8_t rATS[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 };
static uint8_t rATS[40] = { 0x05, 0x75, 0x80, 0x60, 0x02, 0x00, 0x00, 0x00 }; static uint8_t rATS[40] = { 0x06, 0x75, 0x80, 0x60, 0x02, 0x00, 0x00, 0x00 };
uint8_t rATS_len = 8; uint8_t rATS_len = 8;
// GET_VERSION response for EV1/NTAG // GET_VERSION response for EV1/NTAG
@ -1275,15 +1275,17 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
// ats is a pointer to 20 byte array // ats is a pointer to 20 byte array
// rATS is a 40 byte array // rATS is a 40 byte array
if ((flags & FLAG_ATS_IN_DATA) == FLAG_ATS_IN_DATA) { if ((flags & FLAG_ATS_IN_DATA) == FLAG_ATS_IN_DATA) {
memcpy(rATS, ats, ats_len); // Even if RATS protocol defined as max 40 bytes doesn't mean people try stuff. Check for overflow before copy
// rats len is dictated by the first char of the string, add 2 crc bytes if (ats_len + 2 > sizeof(rATS)) {
rATS_len = (ats[0] + 2); if (g_dbglevel >= DBG_ERROR) Dbprintf("[-] ERROR: ATS overflow. Max %zu, got %zu", sizeof(rATS) - 2, ats_len);
// Since its Varible length we can send value > 40 and overflow our array.
// Even if RATS protocol defined as max 40 bytes doesn't mean people try stuff
if (rATS_len > sizeof(rATS)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("[-] ERROR: ATS overflow. Max %zu, got %zu", sizeof(rATS), rATS_len);
return false; return false;
} }
memcpy(rATS, ats, ats_len);
rATS_len = ats_len + 2;
// ATS length (without CRC) is supposed to match its first byte TL
if (ats_len != ats[0]) {
if (g_dbglevel >= DBG_INFO) Dbprintf("[-] WARNING: actual ATS length (%zu) differs from its TL value (%u).", ats_len, ats[0]);
}
} }
// if uid not supplied then get from emulator memory // if uid not supplied then get from emulator memory

View file

@ -3715,12 +3715,12 @@ int CmdHF14AAIDSim(const char *Cmd) {
CLIParserInit(&ctx, "hf 14a simaid", CLIParserInit(&ctx, "hf 14a simaid",
"Simulate ISO/IEC 14443 type A tag with 4,7 or 10 byte UID, and filter for AID Values\n" "Simulate ISO/IEC 14443 type A tag with 4,7 or 10 byte UID, and filter for AID Values\n"
"These AID Values can be responded to and include extra APDU commands on GetData after response\n", "These AID Values can be responded to and include extra APDU commands on GetData after response\n",
"hf 14a simaid -t 3 -> MIFARE Desfire\n" "hf 14a simaid -t 3 -> MIFARE Desfire\n"
"hf 14a simaid -t 4 -> ISO/IEC 14443-4\n" "hf 14a simaid -t 4 -> ISO/IEC 14443-4\n"
"hf 14a simaid -t 11 -> Javacard (JCOP)\n" "hf 14a simaid -t 11 -> Javacard (JCOP)\n"
"hf 14a simaid -t 3 --aid a000000000000000000000 --selectaid_response 9000 --getdata_response 9000 -> Custom AID and responses\n" "hf 14a simaid -t 3 --aid a000000000000000000000 --selectaid_response 9000 --getdata_response 9000 -> Custom AID and responses\n"
"hf 14a simaid -t 3 --ats 05788172220101 --selectaid_response 01009000 --getdata_response 86009000 -> Custom ATS and responses\n" "hf 14a simaid -t 3 --ats 0578817222 --selectaid_response 01009000 --getdata_response 86009000 -> Custom ATS and responses\n"
"hf 14a simaid -t 3 --ats 05788172220101 -x -> Enumerate AID Values\n" "hf 14a simaid -t 3 --ats 0578817222 -x -> Enumerate AID Values\n"
); );
void *argtable[] = { void *argtable[] = {