Skip to content
This repository has been archived by the owner on Feb 24, 2021. It is now read-only.

Commit

Permalink
chg: 'hf 14a sim' - possibility to simulate FM11RF005SH (@maozhenyu123)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
iceman1001 committed May 6, 2018
1 parent adb1b90 commit 110a7b2
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 36 deletions.
13 changes: 12 additions & 1 deletion armsrc/iso14443a.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand Down
72 changes: 37 additions & 35 deletions client/cmdhf14a.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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");
PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
DropField();
return 1;
}

if (select_status == 3) {
PrintAndLogEx(NORMAL, "Card doesn't support standard iso14443-3 anticollision");
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, " 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]);
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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions client/lualibs/read14a.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

8 comments on commit 110a7b2

@iceman1001
Copy link
Owner Author

@iceman1001 iceman1001 commented on 110a7b2 May 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. Do you have a full datasheet?
I started a thread on the forum which is a better place to discuss.
http://www.proxmark.org/forum/viewtopic.php?id=5661

@iceman1001
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you have a proxmark3, you can sniff the traffic between reader / card.

hf 14a snoop (to sniff)
hf list 14a (to get trace)

@iceman1001
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have the stream from last summer?

@maozhenyu123
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No....

@iceman1001
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does the simulation here work now?

@maozhenyu123
Copy link

@maozhenyu123 maozhenyu123 commented on 110a7b2 May 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. It works for Access Control, which is based on UID

@iceman1001
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you tried iceman fork or official with yr patch?

@maozhenyu123
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mine was forked from the offical

Please sign in to comment.