From 7d4c6e8faa604e5c8b2a49050d52402da24639b0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 23 Sep 2020 12:25:30 +0200 Subject: [PATCH] Fix Gen3 detection bug against MFUL --- armsrc/appmain.c | 3 +- armsrc/mifarecmd.c | 51 ++++++++++++++++++---------------- armsrc/mifarecmd.h | 2 +- client/src/cmdhf14a.c | 45 +++++++++++++++--------------- client/src/mifare/mifarehost.c | 7 +++-- client/src/mifare/mifarehost.h | 2 +- 6 files changed, 58 insertions(+), 52 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 6a315999c..42161d738 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1355,7 +1355,8 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_MIFARE_CIDENT: { - MifareCIdent(); + bool is_mfc = packet->data.asBytes[0]; + MifareCIdent(is_mfc); break; } // Gen 3 magic cards diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 3344368cf..76cbea5c1 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2236,14 +2236,14 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { OnSuccessMagic(); } -void MifareCIdent(void) { +void MifareCIdent(bool is_mfc) { // variables uint8_t isGen = 0; uint8_t rec[1] = {0x00}; uint8_t recpar[1] = {0x00}; uint8_t rats[4] = { ISO14443A_CMD_RATS, 0x80, 0x31, 0x73 }; - uint8_t rdbl[4] = { ISO14443A_CMD_READBLOCK, 0xF0, 0x8D, 0x5f}; - uint8_t rdbl0[4] = { ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa8}; + uint8_t rdblf0[4] = { ISO14443A_CMD_READBLOCK, 0xF0, 0x8D, 0x5f}; + uint8_t rdbl00[4] = { ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa8}; uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); uint8_t *uid = BigBuf_malloc(10); @@ -2323,29 +2323,32 @@ void MifareCIdent(void) { goto OUT; } - // magic ntag test - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(40); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); - if (res == 2) { - ReaderTransmit(rdbl, sizeof(rdbl), NULL); - res = ReaderReceive(buf, par); - if (res == 18) { - isGen = MAGIC_NTAG21X; + if (! is_mfc) { + // magic ntag test + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(40); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); + if (res == 2) { + ReaderTransmit(rdblf0, sizeof(rdblf0), NULL); + res = ReaderReceive(buf, par); + if (res == 18) { + isGen = MAGIC_NTAG21X; + } } } - - // magic MFC Gen3 test - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(40); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); - if (res == 2) { - ReaderTransmit(rdbl0, sizeof(rdbl0), NULL); - res = ReaderReceive(buf, par); - if (res == 18) { - isGen = MAGIC_GEN_3; + if (is_mfc) { + // magic MFC Gen3 test + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(40); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); + if (res == 2) { + ReaderTransmit(rdbl00, sizeof(rdbl00), NULL); + res = ReaderReceive(buf, par); + if (res == 18) { + isGen = MAGIC_GEN_3; + } } } }; diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index b024d2d1b..58cec9b49 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -41,7 +41,7 @@ int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keytype); void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); -void MifareCIdent(void); // is "magic chinese" card? +void MifareCIdent(bool is_mfc); // is "magic chinese" card? void MifareHasStaticNonce(void); // Has the tag a static nonce? int DoGen3Cmd(uint8_t *cmd, uint8_t cmd_len); diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index fbd9fc618..cc6a7caab 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -1979,32 +1979,33 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { } int isMagic = 0; - if (isMifareClassic || isMifareUltralight) { - isMagic = detect_classic_magic(); + if (isMifareClassic) { + isMagic = detect_mf_magic(true); + } + if (isMifareUltralight) { + isMagic = detect_mf_magic(false); + } + if (isMifareClassic) { + int res = detect_classic_static_nonce(); + if (res == NONCE_STATIC) + PrintAndLogEx(SUCCESS, "Static nonce: " _YELLOW_("yes")); - if (isMifareClassic) { + if (res == NONCE_FAIL && verbose) + PrintAndLogEx(SUCCESS, "Static nonce: " _RED_("read failed")); - int res = detect_classic_static_nonce(); - if (res == NONCE_STATIC) - PrintAndLogEx(SUCCESS, "Static nonce: " _YELLOW_("yes")); + if (res == NONCE_NORMAL) { - if (res == NONCE_FAIL && verbose) - PrintAndLogEx(SUCCESS, "Static nonce: " _RED_("read failed")); + // not static + res = detect_classic_prng(); + if (res == 1) + PrintAndLogEx(SUCCESS, "Prng detection: " _GREEN_("weak")); + else if (res == 0) + PrintAndLogEx(SUCCESS, "Prng detection: " _YELLOW_("hard")); + else + PrintAndLogEx(FAILED, "Prng detection: " _RED_("fail")); - if (res == NONCE_NORMAL) { - - // not static - res = detect_classic_prng(); - if (res == 1) - PrintAndLogEx(SUCCESS, "Prng detection: " _GREEN_("weak")); - else if (res == 0) - PrintAndLogEx(SUCCESS, "Prng detection: " _YELLOW_("hard")); - else - PrintAndLogEx(FAILED, "Prng detection: " _RED_("fail")); - - if (do_nack_test) - detect_classic_nackbug(false); - } + if (do_nack_test) + detect_classic_nackbug(false); } } diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 032c9eccf..78fca3487 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1154,13 +1154,14 @@ int detect_classic_static_nonce(void) { return NONCE_FAIL; } -/* try to see if card responses to "chinese magic backdoor" commands. */ -int detect_classic_magic(void) { +/* try to see if card responses to "Chinese magic backdoor" commands. */ +int detect_mf_magic(bool is_mfc) { uint8_t isGeneration = 0; PacketResponseNG resp; clearCommandBuffer(); - SendCommandNG(CMD_HF_MIFARE_CIDENT, NULL, 0); + uint8_t payload[] = { is_mfc }; + SendCommandNG(CMD_HF_MIFARE_CIDENT, payload, sizeof(payload)); if (WaitForResponseTimeout(CMD_HF_MIFARE_CIDENT, &resp, 1500)) { if (resp.status == PM3_SUCCESS) isGeneration = resp.data.asBytes[0]; diff --git a/client/src/mifare/mifarehost.h b/client/src/mifare/mifarehost.h index 1e693174e..7a3535257 100644 --- a/client/src/mifare/mifarehost.h +++ b/client/src/mifare/mifarehost.h @@ -88,7 +88,7 @@ int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int detect_classic_prng(void); int detect_classic_nackbug(bool verbose); -int detect_classic_magic(void); +int detect_mf_magic(bool is_mfc); int detect_classic_static_nonce(void); void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted); #endif