mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-03-16 01:53:02 +08:00
chg: 'hf 14a sim' - possibility to simulate FM11RF005SH (@maozhenyu123)
chg: 'hf 14a info' - tag identification for FM11RF005SH (@maozhenyu123) Fudan FM11RF005SH , has 512bit mem, 16blocks w 4bytes / block. Support REQA, READ, WRITE, AUTH. Unknown how the auth is done. The ATQA/SAK , or a trace from one of these tags would be intersting to look at.
This commit is contained in:
parent
adb1b90580
commit
110a7b28cb
3 changed files with 50 additions and 36 deletions
|
@ -898,6 +898,11 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
|
|||
response1[0] = 0x02;
|
||||
sak = 0x18;
|
||||
} break;
|
||||
case 9 : { // FM11RF005SH (Shanghai Metro)
|
||||
response1[0] = 0x03;
|
||||
response1[1] = 0x00;
|
||||
sak = 0x0A;
|
||||
}
|
||||
default: {
|
||||
Dbprintf("Error: unkown tagtype (%d)",tagType);
|
||||
return;
|
||||
|
@ -951,6 +956,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
|
|||
uint8_t response5[4];
|
||||
|
||||
uint8_t response6[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 }; // dummy ATS (pseudo-ATR), answer to RATS:
|
||||
|
||||
// Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present,
|
||||
// TA(1) = 0x80: different divisors not supported, DR = 1, DS = 1
|
||||
// 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)
|
||||
|
@ -1045,7 +1051,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
|
|||
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { // Received a SELECT (cascade 1)
|
||||
p_response = &responses[3]; order = 3;
|
||||
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received a SELECT (cascade 2)
|
||||
p_response = &responses[4]; order = 30;
|
||||
p_response = &responses[4]; order = 30;
|
||||
} else if (receivedCmd[0] == ISO14443A_CMD_READBLOCK) { // Received a (plain) READ
|
||||
uint8_t block = receivedCmd[1];
|
||||
// if Ultralight or NTAG (4 byte blocks)
|
||||
|
@ -1058,6 +1064,11 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
|
|||
EmSendCmd(emdata, sizeof(emdata));
|
||||
// We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below
|
||||
p_response = NULL;
|
||||
} else if ( tagType == 9 && block == 1 ) {
|
||||
// FM11005SH. 16blocks, 4bytes / block.
|
||||
// block0 = 2byte Customer ID (CID), 2byte Manufacture ID (MID)
|
||||
// block1 = 4byte UID.
|
||||
p_response = &responses[1];
|
||||
} else { // all other tags (16 byte block tags)
|
||||
uint8_t emdata[MAX_MIFARE_FRAME_SIZE];
|
||||
emlGetMemBt( emdata, block, 16);
|
||||
|
|
|
@ -119,6 +119,7 @@ int usage_hf_14a_sim(void) {
|
|||
PrintAndLogEx(NORMAL, " 6 = MIFARE Mini");
|
||||
PrintAndLogEx(NORMAL, " 7 = AMIIBO (NTAG 215), pack 0x8080");
|
||||
PrintAndLogEx(NORMAL, " 8 = MIFARE Classic 4k");
|
||||
PrintAndLogEx(NORMAL, " 9 = FM11RF005SH Shanghai Metro");
|
||||
// PrintAndLogEx(NORMAL, " u : 4, 7 or 10 byte UID");
|
||||
PrintAndLogEx(NORMAL, " u : 4, 7 byte UID");
|
||||
PrintAndLogEx(NORMAL, " x : (Optional) Performs the 'reader attack', nr/ar attack against a reader");
|
||||
|
@ -233,51 +234,52 @@ int CmdHF14AReader(const char *Cmd) {
|
|||
SendCommand(&c);
|
||||
|
||||
if (ISO14A_CONNECT & cm) {
|
||||
UsbCommand resp;
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
|
||||
if (!silent) PrintAndLogEx(WARNING, "iso14443a card select failed");
|
||||
DropField();
|
||||
return 1;
|
||||
}
|
||||
UsbCommand resp;
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
|
||||
if (!silent) PrintAndLogEx(WARNING, "iso14443a card select failed");
|
||||
DropField();
|
||||
return 1;
|
||||
}
|
||||
|
||||
iso14a_card_select_t card;
|
||||
memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
|
||||
iso14a_card_select_t card;
|
||||
memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
|
||||
|
||||
/*
|
||||
0: couldn't read
|
||||
1: OK, with ATS
|
||||
2: OK, no ATS
|
||||
3: proprietary Anticollision
|
||||
*/
|
||||
uint64_t select_status = resp.arg[0];
|
||||
|
||||
if (select_status == 0) {
|
||||
if (!silent) PrintAndLogEx(WARNING, "iso14443a card select failed");
|
||||
DropField();
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
0: couldn't read
|
||||
1: OK, with ATS
|
||||
2: OK, no ATS
|
||||
3: proprietary Anticollision
|
||||
*/
|
||||
uint64_t select_status = resp.arg[0];
|
||||
|
||||
if (select_status == 0) {
|
||||
if (!silent) PrintAndLogEx(WARNING, "iso14443a card select failed");
|
||||
DropField();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (select_status == 3) {
|
||||
PrintAndLogEx(NORMAL, "Card doesn't support standard iso14443-3 anticollision");
|
||||
if (select_status == 3) {
|
||||
PrintAndLogEx(NORMAL, "Card doesn't support standard iso14443-3 anticollision");
|
||||
PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
DropField();
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
DropField();
|
||||
return 1;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, " SAK : %02x [%" PRIu64 "]", card.sak, resp.arg[0]);
|
||||
|
||||
PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
PrintAndLogEx(NORMAL, " SAK : %02x [%" PRIu64 "]", card.sak, resp.arg[0]);
|
||||
|
||||
if(card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes
|
||||
PrintAndLogEx(NORMAL, " ATS : %s", sprint_hex(card.ats, card.ats_len));
|
||||
}
|
||||
if(card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes
|
||||
PrintAndLogEx(NORMAL, " ATS : %s", sprint_hex(card.ats, card.ats_len));
|
||||
}
|
||||
|
||||
if (!disconnectAfter) {
|
||||
if (!silent) PrintAndLogEx(SUCCESS, "Card is selected. You can now start sending commands");
|
||||
}
|
||||
}
|
||||
|
||||
if (disconnectAfter) {
|
||||
if (!silent) PrintAndLogEx(SUCCESS, "field dropped.");
|
||||
if (!silent) PrintAndLogEx(SUCCESS, "field dropped.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -364,6 +366,7 @@ int CmdHF14AInfo(const char *Cmd) {
|
|||
case 0x04: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); isMifareClassic = false; break;
|
||||
case 0x08: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1"); break;
|
||||
case 0x09: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Mini 0.3k"); break;
|
||||
case 0x0A: PrintAndLogEx(NORMAL, "TYPE : FM11RF005SH (Shanghai Metro)"); break;
|
||||
case 0x10: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 2k SL2"); break;
|
||||
case 0x11: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 4k SL2"); break;
|
||||
case 0x18: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1"); break;
|
||||
|
@ -568,7 +571,6 @@ int CmdHF14ACUIDs(const char *Cmd) {
|
|||
}
|
||||
|
||||
// ## simulate iso14443a tag
|
||||
// ## greg - added ability to specify tag UID
|
||||
int CmdHF14ASim(const char *Cmd) {
|
||||
bool errors = false;
|
||||
uint8_t flags = 0;
|
||||
|
|
|
@ -32,6 +32,7 @@ ISO14443a_TYPES[0x01] = "NXP MIFARE TNP3xxx Activision Game Appliance"
|
|||
ISO14443a_TYPES[0x04] = "NXP MIFARE (various !DESFire !DESFire EV1)"
|
||||
ISO14443a_TYPES[0x08] = "NXP MIFARE CLASSIC 1k | Plus 2k"
|
||||
ISO14443a_TYPES[0x09] = "NXP MIFARE Mini 0.3k"
|
||||
ISO14443a_TYPES[0x0A} = "FM11RF005SH (Shanghai Metro)")
|
||||
ISO14443a_TYPES[0x10] = "NXP MIFARE Plus 2k"
|
||||
ISO14443a_TYPES[0x11] = "NXP MIFARE Plus 4k"
|
||||
ISO14443a_TYPES[0x18] = "NXP MIFARE Classic 4k | Plus 4k"
|
||||
|
|
Loading…
Reference in a new issue