From 7481d73263086194fd30774d9b331ea3f7c6fb83 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 23 Sep 2020 21:03:08 +0200 Subject: [PATCH 01/12] typo --- client/src/cmdhf15.c | 2 +- client/src/cmdhfmfu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 421e7488f..7b76ba792 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -380,7 +380,7 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { {"NXP Public key", "04A748B6A632FBEE2C0897702B33BEA1C074998E17B84ACA04FF267E5D2C91F6DC"}, {"NXP Ultralight Ev1", "0490933BDCD6E99B4E255E3DA55389A827564E11718E017292FAF23226A96614B8"}, {"NXP NTAG21x (2013)", "04494E1A386D3D3CFE3DC10E5DE68A499B1C202DB5B132393E89ED19FE5BE8BC61"}, - {"MICRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"}, + {"MIKRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"}, {"Spark1 Public key", "04d64bb732c0d214e7ec580736acf847284b502c25c0f7f2fa86aace1dada4387a"}, }; /* diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 2a642d4c8..a25569f95 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -880,7 +880,7 @@ static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *sig {"NXP Public key", "04A748B6A632FBEE2C0897702B33BEA1C074998E17B84ACA04FF267E5D2C91F6DC"}, {"NXP Ultralight Ev1", "0490933BDCD6E99B4E255E3DA55389A827564E11718E017292FAF23226A96614B8"}, {"NXP NTAG21x (2013)", "04494E1A386D3D3CFE3DC10E5DE68A499B1C202DB5B132393E89ED19FE5BE8BC61"}, - {"MICRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"}, + {"MIKRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"}, }; /* From ea8bfacb5786261d063c98fc9d653f3b60fd6747 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 24 Sep 2020 01:00:34 +0200 Subject: [PATCH 02/12] textual --- client/src/cmdhf15.c | 8 +++++--- client/src/cmdhfmfdes.c | 13 +++++++++---- client/src/cmdhfmfp.c | 9 +++++++-- client/src/cmdhfmfu.c | 8 +++++--- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 7b76ba792..35d3be6e3 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -437,17 +437,19 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { } PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); if (is_valid == false || i == ARRAYLEN(nxp_15693_public_keys)) { - PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed")); + PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1"); + PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex(signature, 32)); + PrintAndLogEx(SUCCESS, " Signature verification: " _RED_("failed")); return PM3_ESOFT; } - PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); PrintAndLogEx(INFO, " IC signature public key name: %s", nxp_15693_public_keys[i].desc); PrintAndLogEx(INFO, "IC signature public key value: %s", nxp_15693_public_keys[i].value); PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1"); PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex(signature, 32)); - PrintAndLogEx(SUCCESS, " Signature verified: " _GREEN_("successful")); + PrintAndLogEx(SUCCESS, " Signature verification: " _GREEN_("successful")); return PM3_SUCCESS; } diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index e48e54958..60d16f35d 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -1190,13 +1190,18 @@ static int desfire_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signat if (is_valid) break; } +// PrintAndLogEx(NORMAL, ""); +// PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); if (is_valid == false || i == ARRAYLEN(nxp_desfire_public_keys)) { - PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed")); + PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp224r1"); + PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 32, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 48, signature_len - 48)); + PrintAndLogEx(SUCCESS, " Signature verification: " _RED_("failed")); return PM3_ESOFT; } -// PrintAndLogEx(NORMAL, ""); -// PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); PrintAndLogEx(INFO, " IC signature public key name: " _GREEN_("%s"), nxp_desfire_public_keys[i].desc); PrintAndLogEx(INFO, "IC signature public key value: %.32s", nxp_desfire_public_keys[i].value); PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 16); @@ -1207,7 +1212,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signat PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16)); PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 32, 16)); PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 48, signature_len - 48)); - PrintAndLogEx(SUCCESS, " Signature verified: " _GREEN_("successful")); + PrintAndLogEx(SUCCESS, " Signature verification: " _GREEN_("successful")); return PM3_SUCCESS; } diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 4ee04e781..d4d0f99b3 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -186,7 +186,12 @@ static int plus_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signature PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); if (is_valid == false || i == ARRAYLEN(nxp_plus_public_keys)) { - PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed")); + PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp224r1"); + PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 32, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 48, signature_len - 48)); + PrintAndLogEx(SUCCESS, " Signature verification: " _RED_("failed")); return PM3_ESOFT; } @@ -200,7 +205,7 @@ static int plus_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signature PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16)); PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 32, 16)); PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 48, signature_len - 48)); - PrintAndLogEx(SUCCESS, " Signature verified: " _GREEN_("successful")); + PrintAndLogEx(SUCCESS, " Signature verification: " _GREEN_("successful")); return PM3_SUCCESS; } diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index a25569f95..0be6ec728 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -945,17 +945,19 @@ static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *sig } PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); if (is_valid == false || i == ARRAYLEN(nxp_mfu_public_keys)) { - PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed")); + PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1"); + PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, signature_len)); + PrintAndLogEx(SUCCESS, " Signature verification: " _RED_("failed")); return PM3_ESOFT; } - PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); PrintAndLogEx(INFO, " IC signature public key name: %s", nxp_mfu_public_keys[i].desc); PrintAndLogEx(INFO, "IC signature public key value: %s", nxp_mfu_public_keys[i].value); PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1"); PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, signature_len)); - PrintAndLogEx(SUCCESS, " Signature verified: " _GREEN_("successful")); + PrintAndLogEx(SUCCESS, " Signature verification: " _GREEN_("successful")); return PM3_SUCCESS; } From caa4812f64eb393c49160428312bb757a040ba74 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 24 Sep 2020 01:29:38 +0200 Subject: [PATCH 03/12] Add NTAG 213 TT support --- client/src/cmdhfmfu.c | 18 +++++++++++------- client/src/cmdhfmfu.h | 1 + 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 0be6ec728..09b67091d 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -272,14 +272,14 @@ uint32_t UL_TYPES_ARRAY[] = { UNKNOWN, UL, UL_C, UL_EV1_48, UL_EV1_128, NTAG, NTAG_203, NTAG_210, NTAG_212, NTAG_213, NTAG_215, NTAG_216, MY_D, MY_D_NFC, MY_D_MOVE, MY_D_MOVE_NFC, MY_D_MOVE_LEAN, FUDAN_UL, - UL_EV1, NTAG_213_F, NTAG_216_F, UL_NANO_40, NTAG_I2C_1K + UL_EV1, NTAG_213_F, NTAG_216_F, UL_NANO_40, NTAG_I2C_1K, NTAG_213_TT }; uint8_t UL_MEMORY_ARRAY[ARRAYLEN(UL_TYPES_ARRAY)] = { MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_ULC_BLOCKS, MAX_ULEV1a_BLOCKS, MAX_ULEV1b_BLOCKS, MAX_NTAG_203, MAX_NTAG_203, MAX_NTAG_210, MAX_NTAG_212, MAX_NTAG_213, MAX_NTAG_215, MAX_NTAG_216, MAX_UL_BLOCKS, MAX_MY_D_NFC, MAX_MY_D_MOVE, MAX_MY_D_MOVE, MAX_MY_D_MOVE_LEAN, MAX_UL_BLOCKS, - MAX_ULEV1a_BLOCKS, MAX_NTAG_213, MAX_NTAG_216, MAX_UL_NANO_40, MAX_NTAG_I2C_1K + MAX_ULEV1a_BLOCKS, MAX_NTAG_213, MAX_NTAG_216, MAX_UL_NANO_40, MAX_NTAG_I2C_1K, MAX_NTAG_213 }; //------------------------------------ @@ -678,6 +678,8 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces) { PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 213 144bytes (NT2H1311G0DU)"), spaces, ""); else if (tagtype & NTAG_213_F) PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 213F 144bytes (NT2H1311F0DTL)"), spaces, ""); + else if (tagtype & NTAG_213_TT) + PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 213TT 144bytes (NT2H1311TTDU)"), spaces, ""); else if (tagtype & NTAG_215) PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 215 504bytes (NT2H1511G0DU)"), spaces, ""); else if (tagtype & NTAG_216) @@ -758,7 +760,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st PrintAndLogEx(INFO, " cfg0 [%u/0x%02X]: %s", startPage, startPage, sprint_hex(data, 4)); - if ((tagtype & (NTAG_213_F | NTAG_216_F))) { + if ((tagtype & (NTAG_213_F | NTAG_213_TT | NTAG_216_F))) { uint8_t mirror_conf = (data[0] & 0xC0); uint8_t mirror_byte = (data[0] & 0x30); bool sleep_en = (data[0] & 0x08); @@ -801,7 +803,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st break; } // valid mirror start page and byte position within start page. - if (tagtype & NTAG_213_F) { + if ((tagtype & NTAG_213_F)||(tagtype & NTAG_213_TT)) { switch (mirror_conf) { case 1: { PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x24) ? "OK" : "Invalid value"); break;} @@ -1090,6 +1092,7 @@ uint32_t GetHF14AMfU_Type(void) { MF0UNH1001DUx 0004030203000B03 NT2L1001G0DUx 0004040102000B03 NT2H1001G0DUx 0004040202000B03 + NT2H1311TTDUx 0004040203000F03 Micron UL 0034210101000E03 */ @@ -1106,6 +1109,7 @@ uint32_t GetHF14AMfU_Type(void) { else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x13", 7) == 0) { tagtype = NTAG_216; break; } else if (memcmp(version, "\x00\x04\x04\x04\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213_F; break; } else if (memcmp(version, "\x00\x04\x04\x04\x01\x00\x13", 7) == 0) { tagtype = NTAG_216_F; break; } + else if (memcmp(version, "\x00\x04\x04\x02\x03\x00\x0F", 7) == 0) { tagtype = NTAG_213_TT; break; } else if (memcmp(version, "\x00\x04\x04\x05\x02\x01\x13", 7) == 0) { tagtype = NTAG_I2C_1K; break; } else if (memcmp(version, "\x00\x04\x04\x05\x02\x01\x15", 7) == 0) { tagtype = NTAG_I2C_2K; break; } else if (memcmp(version, "\x00\x04\x04\x05\x02\x02\x13", 7) == 0) { tagtype = NTAG_I2C_1K_PLUS; break; } @@ -1330,7 +1334,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { } // NTAG counters? - if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_215 | NTAG_216))) { + if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_213_TT | NTAG_215 | NTAG_216))) { if (ntag_print_counter()) { // failed - re-select if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; @@ -1338,7 +1342,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { } // Read signature - if ((tagtype & (UL_EV1_48 | UL_EV1_128 | UL_EV1 | UL_NANO_40 | NTAG_213 | NTAG_213_F | NTAG_215 | NTAG_216 | NTAG_216_F | NTAG_I2C_1K | NTAG_I2C_2K | NTAG_I2C_1K_PLUS | NTAG_I2C_2K_PLUS))) { + if ((tagtype & (UL_EV1_48 | UL_EV1_128 | UL_EV1 | UL_NANO_40 | NTAG_213 | NTAG_213_F | NTAG_213_TT | NTAG_215 | NTAG_216 | NTAG_216_F | NTAG_I2C_1K | NTAG_I2C_2K | NTAG_I2C_1K_PLUS | NTAG_I2C_2K_PLUS))) { uint8_t ulev1_signature[32] = {0x00}; status = ulev1_readSignature(ulev1_signature, sizeof(ulev1_signature)); if (status == -1) { @@ -2024,7 +2028,7 @@ static int CmdHF14AMfUDump(const char *Cmd) { uint8_t n = 0; // NTAG has 1 counter, at 0x02 - if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_215 | NTAG_216))) { + if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_213_TT | NTAG_215 | NTAG_216))) { n = 2; } diff --git a/client/src/cmdhfmfu.h b/client/src/cmdhfmfu.h index 67e405677..210783874 100644 --- a/client/src/cmdhfmfu.h +++ b/client/src/cmdhfmfu.h @@ -57,6 +57,7 @@ typedef enum TAGTYPE_UL { NTAG_216_F = 0x800000, UL_EV1 = 0x1000000, UL_NANO_40 = 0x2000000, + NTAG_213_TT = 0x4000000, UL_MAGIC = UL | MAGIC, UL_C_MAGIC = UL_C | MAGIC, UL_ERROR = 0xFFFFFF, From 31c96ae7cf19f7991a6319f880a4c8069035e356 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 24 Sep 2020 10:07:18 +0200 Subject: [PATCH 04/12] Add script to recover PKs --- tools/recover_pk.py | 75 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100755 tools/recover_pk.py diff --git a/tools/recover_pk.py b/tools/recover_pk.py new file mode 100755 index 000000000..e59bca8d0 --- /dev/null +++ b/tools/recover_pk.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 + +# @doegox -- 2020 + +import sslcrypto +import binascii +import sys + +debug = False + +def recover(data, signature): + recovered = set() + alghash = None + if len(signature) == 32: + curve = sslcrypto.ecc.get_curve("secp128r1") + recoverable = False + elif len(signature) == 33: + curve = sslcrypto.ecc.get_curve("secp128r1") + recoverable = True + elif len(signature) == 56: + curve = sslcrypto.ecc.get_curve("secp224r1") + recoverable = False + elif len(signature) == 57: + curve = sslcrypto.ecc.get_curve("secp224r1") + recoverable = True + else: + print("Unsupported signature size %i" % len(signature)) + exit(1) + + if (recoverable): + try: + pk = curve.recover(signature, data, hash=alghash) + recovered.add(pk) + if debug: + print("Possible Pk: ", binascii.hexlify(pk)) + except: + pass + else: + for i in range(2): + # Brute force RECID + recid = bytes([27+i]) + try: + pk = curve.recover(recid + signature, data, hash=alghash) + recovered.add(pk) + if debug: + print("Possible Pk: ", binascii.hexlify(pk)) + except: + pass + return recovered + +if len(sys.argv) < 3 or len(sys.argv) % 2 == 0: + print("Usage: \n%s UID SIGN [UID SIGN] [...]" % sys.argv[0]) + print("Example: \n%s 04ee45daa34084 ebb6102bff74b087d18a57a54bc375159a04ea9bc61080b7f4a85afe1587d73b" % sys.argv[0]) + exit(1) + +recovered = set() +for i in range(1, len(sys.argv), 2): + data = binascii.unhexlify(sys.argv[i]) + if debug: + print("UID (%2i): " % len(data), binascii.hexlify(data)) + signature = binascii.unhexlify(sys.argv[i+1]) + if debug: + print("Signature (%2i): " % len(signature), binascii.hexlify(signature)) + recovered_tmp = recover(data, signature) + if i == 1: + if recovered_tmp == set(): + break + else: + recovered = recovered_tmp + else: + recovered &= recovered_tmp + +print("Possible uncompressed Pk(s):") +for pk in list(recovered): + print(binascii.hexlify(pk).decode('utf8')) From 55224eed755853f78b1551ce84a92915e673ddec Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 24 Sep 2020 11:25:43 +0200 Subject: [PATCH 05/12] recover_pk: add note about hashes --- tools/recover_pk.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/recover_pk.py b/tools/recover_pk.py index e59bca8d0..5391e8c57 100755 --- a/tools/recover_pk.py +++ b/tools/recover_pk.py @@ -10,6 +10,8 @@ debug = False def recover(data, signature): recovered = set() + # Some, like Vivokey Spark1, are doing a SHA256 + # alghash = "sha256" alghash = None if len(signature) == 32: curve = sslcrypto.ecc.get_curve("secp128r1") From 56c99d223c5bf01dff074063d057a31d070a87ad Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 24 Sep 2020 11:58:17 +0200 Subject: [PATCH 06/12] recover_pk: seach with and without sha256 --- tools/recover_pk.py | 49 ++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/tools/recover_pk.py b/tools/recover_pk.py index 5391e8c57..b2ff2e6c7 100755 --- a/tools/recover_pk.py +++ b/tools/recover_pk.py @@ -8,11 +8,8 @@ import sys debug = False -def recover(data, signature): +def recover(data, signature, alghash=None): recovered = set() - # Some, like Vivokey Spark1, are doing a SHA256 - # alghash = "sha256" - alghash = None if len(signature) == 32: curve = sslcrypto.ecc.get_curve("secp128r1") recoverable = False @@ -50,28 +47,38 @@ def recover(data, signature): pass return recovered +def recover_multiple(uids, sigs, alghash=None): + recovered = set() + assert len(uids) == len(sigs) + for i in range(len(uids)): + data = binascii.unhexlify(uids[i]) + if debug: + print("UID (%2i): " % len(data), binascii.hexlify(data)) + signature = binascii.unhexlify(sigs[i]) + if debug: + print("Signature (%2i): " % len(signature), binascii.hexlify(signature)) + recovered_tmp = recover(data, signature, alghash) + if i == 0: + if recovered_tmp == set(): + break + else: + recovered = recovered_tmp + else: + recovered &= recovered_tmp + return recovered + if len(sys.argv) < 3 or len(sys.argv) % 2 == 0: print("Usage: \n%s UID SIGN [UID SIGN] [...]" % sys.argv[0]) print("Example: \n%s 04ee45daa34084 ebb6102bff74b087d18a57a54bc375159a04ea9bc61080b7f4a85afe1587d73b" % sys.argv[0]) exit(1) -recovered = set() -for i in range(1, len(sys.argv), 2): - data = binascii.unhexlify(sys.argv[i]) - if debug: - print("UID (%2i): " % len(data), binascii.hexlify(data)) - signature = binascii.unhexlify(sys.argv[i+1]) - if debug: - print("Signature (%2i): " % len(signature), binascii.hexlify(signature)) - recovered_tmp = recover(data, signature) - if i == 1: - if recovered_tmp == set(): - break - else: - recovered = recovered_tmp - else: - recovered &= recovered_tmp - +print("Assuming no hash was used in the signature generation:") +recovered = recover_multiple(sys.argv[1:][::2], sys.argv[1:][1::2]) +print("Possible uncompressed Pk(s):") +for pk in list(recovered): + print(binascii.hexlify(pk).decode('utf8')) +print("Assuming SHA-256 was used in the signature generation:") +recovered = recover_multiple(sys.argv[1:][::2], sys.argv[1:][1::2], alghash="sha256") print("Possible uncompressed Pk(s):") for pk in list(recovered): print(binascii.hexlify(pk).decode('utf8')) From a8185cc8d656ad0743d077afd1ac1c76483bec19 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 24 Sep 2020 13:15:23 +0200 Subject: [PATCH 07/12] validate vivokey spark1, and more details --- client/src/cmdhf15.c | 57 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 35d3be6e3..76500668d 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -423,6 +423,16 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { }; */ uint8_t i; + uint8_t revuid[8]; + for (i = 0; i < sizeof(revuid); i++) { + revuid[i] = uid[7 - i]; + } + uint8_t revsign[32]; + for (i = 0; i < sizeof(revsign); i++) { + revsign[i] = signature[31 - i]; + } + + int reason = 0; bool is_valid = false; for (i = 0; i < ARRAYLEN(nxp_15693_public_keys); i++) { @@ -432,15 +442,42 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, uid, 8, signature, 32, false); is_valid = (res == 0); - if (is_valid) + if (is_valid) { + reason = 1; break; + } + + // try with sha256 + res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, uid, 8, signature, 32, true); + is_valid = (res == 0); + if (is_valid) { + reason = 2; + break; + } + + // try with reversed uid / signature + res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, revuid, sizeof(revuid), revsign, sizeof(revsign), false); + is_valid = (res == 0); + if (is_valid) { + reason = 3; + break; + } + + + // try with sha256 + res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, revuid, sizeof(revuid), revsign, sizeof(revsign), true); + is_valid = (res == 0); + if (is_valid) { + reason = 4; + break; + } } PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); if (is_valid == false || i == ARRAYLEN(nxp_15693_public_keys)) { PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1"); - PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex(signature, 32)); + PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 32)); PrintAndLogEx(SUCCESS, " Signature verification: " _RED_("failed")); return PM3_ESOFT; } @@ -448,8 +485,22 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { PrintAndLogEx(INFO, " IC signature public key name: %s", nxp_15693_public_keys[i].desc); PrintAndLogEx(INFO, "IC signature public key value: %s", nxp_15693_public_keys[i].value); PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1"); - PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex(signature, 32)); + PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 32)); PrintAndLogEx(SUCCESS, " Signature verification: " _GREEN_("successful")); + switch(reason) { + case 1: + PrintAndLogEx(INFO, " Params used: UID and signature, plain"); + break; + case 2: + PrintAndLogEx(INFO, " Params used: UID and signature, SHA256"); + break; + case 3: + PrintAndLogEx(INFO, " Params used: reversed UID and signature, plain"); + break; + case 4: + PrintAndLogEx(INFO, " Params used: reversed UID and signature, SHA256"); + break; + } return PM3_SUCCESS; } From 8c4076281e1dc4aeb0cb49064dc322a485e39989 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 24 Sep 2020 13:58:45 +0200 Subject: [PATCH 08/12] Fix PK secp224r1 display --- client/src/cmdhfmfdes.c | 5 +++-- client/src/cmdhfmfp.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 60d16f35d..5517ad15f 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -1176,6 +1176,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signat {"Mifare Plus EV1", "044409ADC42F91A8394066BA83D872FB1D16803734E911170412DDF8BAD1A4DADFD0416291AFE1C748253925DA39A5F39A1C557FFACD34C62E"} }; + uint32_t i; bool is_valid = false; @@ -1204,9 +1205,9 @@ static int desfire_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signat PrintAndLogEx(INFO, " IC signature public key name: " _GREEN_("%s"), nxp_desfire_public_keys[i].desc); PrintAndLogEx(INFO, "IC signature public key value: %.32s", nxp_desfire_public_keys[i].value); - PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 16); PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 32); - PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 48); + PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 64); + PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 96); PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp224r1"); PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 16)); PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16)); diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index d4d0f99b3..1ecfa0c7f 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -197,9 +197,9 @@ static int plus_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signature PrintAndLogEx(INFO, " IC signature public key name: " _GREEN_("%s"), nxp_plus_public_keys[i].desc); PrintAndLogEx(INFO, "IC signature public key value: %.32s", nxp_plus_public_keys[i].value); - PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 16); PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 32); - PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 48); + PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 64); + PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 96); PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp224r1"); PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 16)); PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16)); From e556b8de5540b14f29c29bf7aa9f8b2e291372dc Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 24 Sep 2020 15:03:38 +0200 Subject: [PATCH 09/12] Fix NTAG I2C UID and signature verification --- client/src/cmdhfmfu.c | 48 +++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 09b67091d..0fcbe1796 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -493,7 +493,7 @@ static int ul_fudan_check(void) { return (!resp.data.asBytes[0]) ? FUDAN_UL : UL; //if response == 0x00 then Fudan, else Genuine NXP } -static int ul_print_default(uint8_t *data) { +static int ul_print_default(uint8_t *data, uint8_t *real_uid) { uint8_t uid[7]; uid[0] = data[0]; @@ -503,10 +503,14 @@ static int ul_print_default(uint8_t *data) { uid[4] = data[5]; uid[5] = data[6]; uid[6] = data[7]; + bool mful_uid_layout = true; - PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(uid, 7)); - PrintAndLogEx(SUCCESS, " UID[0]: %02X, %s", uid[0], getTagInfo(uid[0])); - if (uid[0] == 0x05 && ((uid[1] & 0xf0) >> 4) == 2) { // is infineon and 66RxxP + if (memcmp(uid, real_uid, 7) != 0) { + mful_uid_layout = false; + } + PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(real_uid, 7)); + PrintAndLogEx(SUCCESS, " UID[0]: %02X, %s", real_uid[0], getTagInfo(real_uid[0])); + if (real_uid[0] == 0x05 && ((real_uid[1] & 0xf0) >> 4) == 2) { // is infineon and 66RxxP uint8_t chip = (data[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU switch (chip) { case 0xC2: @@ -520,20 +524,23 @@ static int ul_print_default(uint8_t *data) { break; //512 pages /2 sectors } } - // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2 - int crc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2]; - if (data[3] == crc0) - PrintAndLogEx(SUCCESS, " BCC0: %02X (" _GREEN_("ok") ")", data[3]); - else - PrintAndLogEx(NORMAL, " BCC0: %02X, crc should be %02X", data[3], crc0); + if (mful_uid_layout) { + // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2 + int crc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2]; + if (data[3] == crc0) + PrintAndLogEx(SUCCESS, " BCC0: %02X (" _GREEN_("ok") ")", data[3]); + else + PrintAndLogEx(NORMAL, " BCC0: %02X, crc should be %02X", data[3], crc0); - int crc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6]; - if (data[8] == crc1) - PrintAndLogEx(SUCCESS, " BCC1: %02X (" _GREEN_("ok") ")", data[8]); - else - PrintAndLogEx(NORMAL, " BCC1: %02X, crc should be %02X", data[8], crc1); - - PrintAndLogEx(SUCCESS, " Internal: %02X (%s)", data[9], (data[9] == 0x48) ? _GREEN_("default") : _RED_("not default")); + int crc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6]; + if (data[8] == crc1) + PrintAndLogEx(SUCCESS, " BCC1: %02X (" _GREEN_("ok") ")", data[8]); + else + PrintAndLogEx(NORMAL, " BCC1: %02X, crc should be %02X", data[8], crc1); + PrintAndLogEx(SUCCESS, " Internal: %02X (%s)", data[9], (data[9] == 0x48) ? _GREEN_("default") : _RED_("not default")); + } else { + PrintAndLogEx(SUCCESS, "Blocks 0-2: %s", sprint_hex(data + 0, 12)); + } PrintAndLogEx(SUCCESS, " Lock: %s - %s", sprint_hex(data + 10, 2), @@ -1214,7 +1221,6 @@ static int CmdHF14AMfUInfo(const char *Cmd) { uint8_t *key = pwd; uint8_t pack[4] = {0, 0, 0, 0}; int len; - uint8_t uid[7]; char tempStr[50]; @@ -1267,9 +1273,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { PrintAndLogEx(ERR, "Error: tag didn't answer to READ"); return PM3_ESOFT; } else if (status == 16) { - memcpy(uid, data, 3); - memcpy(uid + 3, data + 4, 4); - ul_print_default(data); + ul_print_default(data, card.uid); ndef_print_CC(data + 12); } else { locked = true; @@ -1351,7 +1355,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { return PM3_ESOFT; } if (status == 32) { - ulev1_print_signature(tagtype, uid, ulev1_signature, sizeof(ulev1_signature)); + ulev1_print_signature(tagtype, card.uid, ulev1_signature, sizeof(ulev1_signature)); } else { // re-select if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT; From ae6d69a337ef895e80381c01c4c981233020184e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 24 Sep 2020 19:04:51 +0200 Subject: [PATCH 10/12] more default --- client/dictionaries/mfdes_default_keys.dic | 1 + client/dictionaries/mfp_default_keys.dic | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/client/dictionaries/mfdes_default_keys.dic b/client/dictionaries/mfdes_default_keys.dic index b71a8a8af..4c863c3f5 100644 --- a/client/dictionaries/mfdes_default_keys.dic +++ b/client/dictionaries/mfdes_default_keys.dic @@ -43,3 +43,4 @@ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 404142434445464748494a4b4c4d4e4f 303132333435363738393a3b3c3d3e3f 9CABF398358405AE2F0E2B3D31C99A8A # Default key +605F5E5D5C5B5A59605F5E5D5C5B5A59 # access control \ No newline at end of file diff --git a/client/dictionaries/mfp_default_keys.dic b/client/dictionaries/mfp_default_keys.dic index e492e2686..a063e34ad 100644 --- a/client/dictionaries/mfp_default_keys.dic +++ b/client/dictionaries/mfp_default_keys.dic @@ -27,4 +27,4 @@ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 100f0e0d0c0b0a090807060504030201 404142434445464748494a4b4c4d4e4f 303132333435363738393a3b3c3d3e3f - +605F5E5D5C5B5A59605F5E5D5C5B5A59 From cabe121ca80dfc8fe8ccb35c9327b0745c5c4d27 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 24 Sep 2020 19:51:57 +0200 Subject: [PATCH 11/12] lf help text --- client/src/cmdlf.c | 13 +++++++------ client/src/cmdparser.c | 6 +++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/client/src/cmdlf.c b/client/src/cmdlf.c index 67042259c..74821b449 100644 --- a/client/src/cmdlf.c +++ b/client/src/cmdlf.c @@ -1522,7 +1522,7 @@ out: } static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"-----------", CmdHelp, AlwaysAvailable, "-------------- " _CYAN_("Direct") " --------------"}, {"awid", CmdLFAWID, AlwaysAvailable, "{ AWID RFIDs... }"}, {"cotag", CmdLFCOTAG, AlwaysAvailable, "{ COTAG CHIPs... }"}, {"em", CmdLFEM4X, AlwaysAvailable, "{ EM4X CHIPs & RFIDs... }"}, @@ -1549,16 +1549,17 @@ static command_t CommandTable[] = { {"t55xx", CmdLFT55XX, AlwaysAvailable, "{ T55xx CHIPs... }"}, {"viking", CmdLFViking, AlwaysAvailable, "{ Viking RFIDs... }"}, {"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"}, - {"", CmdHelp, AlwaysAvailable, ""}, + {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, + {"help", CmdHelp, AlwaysAvailable, "This help"}, {"config", CmdLFConfig, IfPm3Lf, "Get/Set config for LF sampling, bit/sample, decimation, frequency"}, {"cmdread", CmdLFCommandRead, IfPm3Lf, "Modulate LF reader field to send command before read (all periods in microseconds)"}, {"read", CmdLFRead, IfPm3Lf, "Read LF tag"}, {"search", CmdLFfind, AlwaysAvailable, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, {"sim", CmdLFSim, IfPm3Lf, "Simulate LF tag from buffer with optional GAP (in microseconds)"}, - {"simask", CmdLFaskSim, IfPm3Lf, "Simulate LF ASK tag from demodbuffer or input"}, - {"simfsk", CmdLFfskSim, IfPm3Lf, "Simulate LF FSK tag from demodbuffer or input"}, - {"simpsk", CmdLFpskSim, IfPm3Lf, "Simulate LF PSK tag from demodbuffer or input"}, -// {"simpsk", CmdLFnrzSim, IfPm3Lf, "Simulate LF NRZ tag from demodbuffer or input"}, + {"simask", CmdLFaskSim, IfPm3Lf, "Simulate " _YELLOW_("LF ASK tag") " from demodbuffer or input"}, + {"simfsk", CmdLFfskSim, IfPm3Lf, "Simulate " _YELLOW_("LF FSK tag") " from demodbuffer or input"}, + {"simpsk", CmdLFpskSim, IfPm3Lf, "Simulate " _YELLOW_("LF PSK tag") " from demodbuffer or input"}, +// {"simpsk", CmdLFnrzSim, IfPm3Lf, "Simulate " _YELLOW_("LF NRZ tag") " from demodbuffer or input"}, {"simbidir", CmdLFSimBidir, IfPm3Lf, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, {"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"}, {"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"}, diff --git a/client/src/cmdparser.c b/client/src/cmdparser.c index 837c13fed..93bba22bf 100644 --- a/client/src/cmdparser.c +++ b/client/src/cmdparser.c @@ -168,7 +168,11 @@ void CmdsHelp(const command_t Commands[]) { while (Commands[i].Name) { if (Commands[i].IsAvailable()) { g_printAndLog = PRINTANDLOG_PRINT; - PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help); + if (Commands[i].Name[0] == '-' || Commands[i].Name[0] == ' ') { + PrintAndLogEx(NORMAL, "%-16s %s", Commands[i].Name, Commands[i].Help); + } else { + PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help); + } g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; } ++i; From 8e819f1b26a16ff944776afbcff41fdb00f5b7e2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 24 Sep 2020 22:55:09 +0200 Subject: [PATCH 12/12] textual --- client/src/cmdhfmfp.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 1ecfa0c7f..f7d7d2142 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -58,9 +58,9 @@ static char *getCardSizeStr(uint8_t fsize) { // is LSB set? if (fsize & 1) - snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("%d - %d bytes") ")", fsize, usize, lsize); + snprintf(retStr, sizeof(buf), "0x%02X (" _GREEN_("%d - %d bytes") ")", fsize, usize, lsize); else - snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("%d bytes") ")", fsize, lsize); + snprintf(retStr, sizeof(buf), "0x%02X (" _GREEN_("%d bytes") ")", fsize, lsize); return buf; } @@ -88,18 +88,17 @@ static char *getVersionStr(uint8_t major, uint8_t minor) { char *retStr = buf; if (major == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire MF3ICD40") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire MF3ICD40") ")", major, minor); else if (major == 0x01 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire EV1") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV1") ")", major, minor); else if (major == 0x12 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire EV2") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV2") ")", major, minor); else if (major == 0x33 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire EV3") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV3") ")", major, minor); else if (major == 0x30 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire Light") ")", major, minor); - + snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire Light") ")", major, minor); else if (major == 0x11 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("Plus EV1") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("Plus EV1") ")", major, minor); else snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("Unknown") ")", major, minor); return buf; @@ -361,10 +360,8 @@ static int CmdHFMFPInfo(const char *Cmd) { } if (card.sak == 0x20) { - PrintAndLogEx(INFO, " SAK: " _GREEN_("MIFARE Plus SL0/SL3") " or " _GREEN_("MIFARE DESFire")); - if (card.ats_len > 0) { - + PrintAndLogEx(INFO, " SAK: " _GREEN_("MIFARE Plus SL0/SL3") " or " _GREEN_("MIFARE DESFire")); SLmode = 3; // check SL0 uint8_t data[250] = {0}; @@ -373,15 +370,22 @@ static int CmdHFMFPInfo(const char *Cmd) { uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00}; int res = ExchangeRAW14a(cmd, sizeof(cmd), true, false, data, sizeof(data), &datalen, false); - // DESFire answers 0x1C + // DESFire answers 0x1C or 67 00 // Plus answers 0x0B, 0x09 - PrintAndLogEx(INFO, "ICEE: %s", sprint_hex(data, datalen)); - - if (memcmp(data, "\x67\x00", 2) == 0) { - PrintAndLogEx(INFO, "\tMost likely a MIFARE DESFire tag"); + if ( data[0] != 0x0b && data[0] != 0x09 && data[0] != 0x1C && data[0] != 0x67) { + PrintAndLogEx(INFO, _RED_("Send copy to iceman of this command output!")); + PrintAndLogEx(INFO, "data: %s", sprint_hex(data, datalen)); + } + + if ((memcmp(data, "\x67\x00", 2) == 0) || + (memcmp(data, "\x1C\x83\x0C", 3) == 0) + ) { + PrintAndLogEx(INFO, " result: " _RED_("MIFARE DESFire")); PrintAndLogEx(HINT, "Hint: Try " _YELLOW_("`hf mfdes info`")); DropField(); return PM3_SUCCESS; + } else { + PrintAndLogEx(INFO, " result: " _GREEN_("MIFARE Plus SL0/SL3")); } if (!res && datalen > 1 && data[0] == 0x09) {