From f022a8f96e77e6c2894260e5589e09f6e5b3934e Mon Sep 17 00:00:00 2001 From: astrid rowland Date: Thu, 13 Apr 2023 14:44:03 -0500 Subject: [PATCH 01/22] added new keys from The Horde --- client/dictionaries/mfc_default_keys.dic | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 1cd3b0d79..665757f25 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -2029,9 +2029,8 @@ D144BD193063 8627C10A7014 453857395635 # -# Data from "the more, the marriott" mifare project (colonel borkmundus) -# -# Isn't theirs Saflok ? +# Data from "the more the marriott" mifare project (colonelborkmundus) +# aka The Horde # # 20230125-01, Elite Member Marriott Rewards 43012BD9EB87 @@ -2098,6 +2097,15 @@ C49DAE1C6049 6E029927600D 3E173F64C01C C670A9AD6066 +# 20230413-69, Westin +487339FA02E0 +# 20230413-70, Marriott Bonvoy +DBD5CA4EE467 +A0B1F234006C +180DE12B700E +# 20230413-71, Westin +1352C68F7A56 +# # # Food GEM 6686FADE5566 From 17aa99b0c70adf489765efc7af458fb2165265c6 Mon Sep 17 00:00:00 2001 From: astrid rowland Date: Thu, 13 Apr 2023 17:44:55 -0500 Subject: [PATCH 02/22] added new keys from The Horde, badges 76-94 --- client/dictionaries/mfc_default_keys.dic | 37 ++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 665757f25..4af8cf64a 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -2105,6 +2105,43 @@ A0B1F234006C 180DE12B700E # 20230413-71, Westin 1352C68F7A56 +# 20230413-76, Ritz Carlton +318BD98C1CEF +# 20230413-77, Marriott +D23C1CB1216E +# 20230413-78, Caesars +A1D92F808CAF +# 20230413-79, The Cosmopolitan, Vegas +96A301BCE267 +# 20230413-80, Aria +1153C319B4F8 +# 20230413-81, Aria +110C819BBEF8 +# 20230413-82, Aria +1332117E8756 +# 20230413-83, Kimpton +500AE915F50A +5032E362B484 +8B63AB712753 +# 20230413-85, Kimpton +06106E187106 +2E45C23DC541 +D9FF8BEE7550 +# 20230413-87, Marriott +42F7A186BF87 +# 20230413-88, Meritage Resort +D213B093B79A +# 20230413-89, Meritage Resort +216024C49EDF +# 20230413-90, Gaylord Palms +D201DBB6AB6E +# 20230413-91, Residence Inn +9F4AD875BB30 +# 20230413-92, Marriott +3352DB1E8777 +# 20230413-94, Marriott +09074A146605 +151F3E85EC46 # # # Food GEM From 6fe32635760bc17caaf89e5ef115e4ebec35f98b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 26 Apr 2023 00:06:55 +0200 Subject: [PATCH 03/22] hf mfu dump now supports the --ns param to not save the memory dump to file --- CHANGELOG.md | 1 + client/src/cmdhfmfu.c | 31 ++++++++++++++++++------------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef2cf914c..c4d075061 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Changed `hf mfu dump --ns` - now supports `no save` of card memory (@iceman1001) - Changed the PM3 client to honor the preferences dump/trace paths. experimental support (@iceman1001) - Added the possibility to load `.MCT` dump files (@iceman1001) - Changed `lf t55xx dump --ns` - now supports `no save` of memory (@iceman1001) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 963786ebc..e47a60e7c 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -2439,6 +2439,7 @@ static int CmdHF14AMfUDump(const char *Cmd) { arg_lit0("l", NULL, "Swap entered key's endianness"), arg_int0("p", "page", "", "Manually set start page number to start from"), arg_int0("q", "qty", "", "Manually set number of pages to dump"), + arg_lit0(NULL, "ns", "no save to file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -2454,6 +2455,7 @@ static int CmdHF14AMfUDump(const char *Cmd) { bool swap_endian = arg_get_lit(ctx, 3); int start_page = arg_get_int_def(ctx, 4, 0); int pages = arg_get_int_def(ctx, 5, 16); + bool nosave = arg_get_lit(ctx, 6); CLIParserFree(ctx); bool has_auth_key = false; @@ -2649,21 +2651,24 @@ static int CmdHF14AMfUDump(const char *Cmd) { printMFUdumpEx(&dump_file_data, pages, start_page); - // user supplied filename? - if (fnlen < 1) { + if (nosave == false) { + // user supplied filename? + if (fnlen < 1) { + PrintAndLogEx(INFO, "Using UID as filename"); + uint8_t uid[7] = {0}; + memcpy(uid, (uint8_t *)&dump_file_data.data, 3); + memcpy(uid + 3, (uint8_t *)&dump_file_data.data + 4, 4); + strcat(filename, "hf-mfu-"); + FillFileNameByUID(filename, uid, "-dump", sizeof(uid)); + } - PrintAndLogEx(INFO, "Using UID as filename"); - uint8_t uid[7] = {0}; - memcpy(uid, (uint8_t *)&dump_file_data.data, 3); - memcpy(uid + 3, (uint8_t *)&dump_file_data.data + 4, 4); - strcat(filename, "hf-mfu-"); - FillFileNameByUID(filename, uid, "-dump", sizeof(uid)); + uint16_t datalen = pages * MFU_BLOCK_SIZE + MFU_DUMP_PREFIX_LENGTH; + pm3_save_dump(filename, (uint8_t *)&dump_file_data, datalen, jsfMfuMemory, MFU_BLOCK_SIZE); + + if (is_partial) { + PrintAndLogEx(WARNING, "Partial dump created. (%d of %d blocks)", pages, card_mem_size); + } } - uint16_t datalen = pages * MFU_BLOCK_SIZE + MFU_DUMP_PREFIX_LENGTH; - pm3_save_dump(filename, (uint8_t *)&dump_file_data, datalen, jsfMfuMemory, MFU_BLOCK_SIZE); - - if (is_partial) - PrintAndLogEx(WARNING, "Partial dump created. (%d of %d blocks)", pages, card_mem_size); return PM3_SUCCESS; } From 94b0bcc7580cc4523ba98e5d646a688f7d735345 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 26 Apr 2023 00:08:01 +0200 Subject: [PATCH 04/22] changed the key table output. In some cases it didnt print non found keys red --- client/src/cmdhfmf.c | 90 ++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 46 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 765342ec2..a647d90c2 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -2861,6 +2861,9 @@ tryNested: } case PM3_ESTATIC_NONCE: PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n"); + + e_sector[current_sector_i].Key[current_key_type_i] = 0xffffffffffff;; + e_sector[current_sector_i].foundKey[current_key_type_i] = false; // Show the results to the user PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, _GREEN_("found keys:")); @@ -2907,6 +2910,10 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack } case PM3_ESTATIC_NONCE: { PrintAndLogEx(ERR, "\nError: Static encrypted nonce detected. Aborted\n"); + + e_sector[current_sector_i].Key[current_key_type_i] = 0xffffffffffff;; + e_sector[current_sector_i].foundKey[current_key_type_i] = false; + // Show the results to the user PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, _GREEN_("found keys:")); @@ -3899,57 +3906,48 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto PrintAndLogEx(SUCCESS, "-----+-----+--------------+---+--------------+----"); PrintAndLogEx(SUCCESS, " Sec | Blk | key A |res| key B |res"); PrintAndLogEx(SUCCESS, "-----+-----+--------------+---+--------------+----"); + + bool extended_legend = false; for (uint8_t i = 0; i < sectorscnt; i++) { - snprintf(strA, sizeof(strA), "------------"); - snprintf(strB, sizeof(strB), "------------"); - - if (e_sector[i].foundKey[0]) - snprintf(strA, sizeof(strA), "%012" PRIX64, e_sector[i].Key[0]); - - if (e_sector[i].foundKey[1]) - snprintf(strB, sizeof(strB), "%012" PRIX64, e_sector[i].Key[1]); - - if (e_sector[i].foundKey[0] > 1) { - PrintAndLogEx(SUCCESS, " "_YELLOW_("%03d")" | %03d | " _GREEN_("%s")" | " _BRIGHT_GREEN_("%c")" | " _GREEN_("%s")" | " _BRIGHT_GREEN_("%c") - , i - , mfSectorTrailerOfSector(i) - , strA, e_sector[i].foundKey[0] - , strB, e_sector[i].foundKey[1] - ); - } else { - - // keep track if we use start_sector or i... - uint8_t s = start_sector; - if (start_sector == 0) - s = i; - - if (e_sector[i].foundKey[0]) { - snprintf(strA, sizeof(strA), _GREEN_("%012" PRIX64), e_sector[i].Key[0]); - snprintf(resA, sizeof(resA), _BRIGHT_GREEN_("%d"), 1); - } else { - snprintf(strA, sizeof(strA), _RED_("%s"), "------------"); - snprintf(resA, sizeof(resA), _RED_("%d"), 0); - } - - if (e_sector[i].foundKey[1]) { - snprintf(strB, sizeof(strB), _GREEN_("%012" PRIX64), e_sector[i].Key[1]); - snprintf(resB, sizeof(resB), _BRIGHT_GREEN_("%d"), 1); - } else { - snprintf(strB, sizeof(strB), _RED_("%s"), "------------"); - snprintf(resB, sizeof(resB), _RED_("%d"), 0); - } - - PrintAndLogEx(SUCCESS, " " _YELLOW_("%03d") " | %03d | %s | %s | %s | %s" - , s - , mfSectorTrailerOfSector(s) - , strA, resA - , strB, resB - ); + if ((e_sector[i].foundKey[0] > 1) || (e_sector[i].foundKey[1] > 1)) { + extended_legend = true; } + + if (e_sector[i].foundKey[0]) { + snprintf(strA, sizeof(strA), _GREEN_("%012" PRIX64), e_sector[i].Key[0]); + snprintf(resA, sizeof(resA), _BRIGHT_GREEN_("%c"), e_sector[i].foundKey[0]); + } else { + snprintf(strA, sizeof(strA), _RED_("%s"), "------------"); + snprintf(resA, sizeof(resA), _RED_("%d"), 0); + } + + if (e_sector[i].foundKey[1]) { + snprintf(strB, sizeof(strB), _GREEN_("%012" PRIX64), e_sector[i].Key[1]); + snprintf(resB, sizeof(resB), _BRIGHT_GREEN_("%c"), e_sector[i].foundKey[1]); + } else { + snprintf(strB, sizeof(strB), _RED_("%s"), "------------"); + snprintf(resB, sizeof(resB), _RED_("%d"), 0); + } + + // keep track if we use start_sector or i + // show one sector or all. + uint8_t s = start_sector; + if (start_sector == 0) { + s = i; + } + + PrintAndLogEx(SUCCESS, " " _YELLOW_("%03d") " | %03d | %s | %s | %s | %s" + , s + , mfSectorTrailerOfSector(s) + , strA, resA + , strB, resB + ); } + PrintAndLogEx(SUCCESS, "-----+-----+--------------+---+--------------+----"); - if (e_sector[0].foundKey[0] > 1) { + + if (extended_legend) { PrintAndLogEx(INFO, "( " _YELLOW_("D") ":Dictionary / " _YELLOW_("S") ":darkSide / " From d480cbd1d0f679cf009887e6d533ab469a1b71e3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 26 Apr 2023 00:10:15 +0200 Subject: [PATCH 05/22] hf 14b dump now supports the no save parameter --- CHANGELOG.md | 1 + client/src/cmdhf14b.c | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4d075061..c73f7641a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Changed `hf 14b dump --ns` - now supports `no save` of card memory (@iceman1001) - Changed `hf mfu dump --ns` - now supports `no save` of card memory (@iceman1001) - Changed the PM3 client to honor the preferences dump/trace paths. experimental support (@iceman1001) - Added the possibility to load `.MCT` dump files (@iceman1001) diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 12440c676..d0083fbb5 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -1359,6 +1359,7 @@ static int CmdHF14BDump(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_str0("f", "file", "", "(optional) filename, if no UID will be used as filename"), + arg_lit0(NULL, "ns", "no save to file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1366,6 +1367,7 @@ static int CmdHF14BDump(const char *Cmd) { int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + bool nosave = arg_get_lit(ctx, 2); CLIParserFree(ctx); @@ -1514,15 +1516,17 @@ static int CmdHF14BDump(const char *Cmd) { print_sr_blocks(data, cardsize, card.uid); - // save to file - if (fnlen < 1) { - PrintAndLogEx(INFO, "using UID as filename"); - char *fptr = filename + snprintf(filename, sizeof(filename), "hf-14b-"); - FillFileNameByUID(fptr, SwapEndian64(card.uid, card.uidlen, 8), "-dump", card.uidlen); - } + if (nosave == false) { + // save to file + if (fnlen < 1) { + PrintAndLogEx(INFO, "using UID as filename"); + char *fptr = filename + snprintf(filename, sizeof(filename), "hf-14b-"); + FillFileNameByUID(fptr, SwapEndian64(card.uid, card.uidlen, 8), "-dump", card.uidlen); + } - size_t datalen = (lastblock + 2) * ST25TB_SR_BLOCK_SIZE; - pm3_save_dump(filename, data, datalen, jsf14b, ST25TB_SR_BLOCK_SIZE); + size_t datalen = (lastblock + 2) * ST25TB_SR_BLOCK_SIZE; + pm3_save_dump(filename, data, datalen, jsf14b, ST25TB_SR_BLOCK_SIZE); + } } return switch_off_field_14b(); From 9eca7fce8394aad879993134aaf41a259e39ac64 Mon Sep 17 00:00:00 2001 From: Mistial Developer Date: Fri, 28 Apr 2023 00:09:24 -0500 Subject: [PATCH 06/22] Add text explaining that the format is H10301 for binary, and specifying it for non-binary --- client/src/cmdhficlass.c | 6 +++--- doc/commands.json | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index b328436bb..ba6d984ad 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -3836,9 +3836,9 @@ static int CmdHFiClassEncode(const char *Cmd) { CLIParserInit(&ctx, "hf iclass encode", "Encode binary wiegand to block 7,8,9\n" "Use either --bin or --wiegand/--fc/--cn", - "hf iclass encode --bin 10001111100000001010100011 --ki 0 -> FC 31 CN 337\n" - "hf iclass encode --fc 31 --cn 337 --ki 0 -> FC 31 CN 337\n" - "hf iclass encode --bin 10001111100000001010100011 --ki 0 --elite -> FC 31 CN 337, writing w elite key" + "hf iclass encode --bin 10001111100000001010100011 --ki 0 -> FC 31 CN 337 (H10301)\n" + "hf iclass encode -w H10301 --fc 31 --cn 337 --ki 0 -> FC 31 CN 337 (H10301)\n" + "hf iclass encode --bin 10001111100000001010100011 --ki 0 --elite -> FC 31 CN 337 (H10301), writing w elite key" ); void *argtable[] = { diff --git a/doc/commands.json b/doc/commands.json index 703ff688c..f8712fc47 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -3100,9 +3100,9 @@ "command": "hf iclass encode", "description": "Encode binary wiegand to block 7,8,9 Use either --bin or --wiegand/--fc/--cn", "notes": [ - "hf iclass encode --bin 10001111100000001010100011 --ki 0 -> FC 31 CN 337", - "hf iclass encode --fc 31 --cn 337 --ki 0 -> FC 31 CN 337", - "hf iclass encode --bin 10001111100000001010100011 --ki 0 --elite -> FC 31 CN 337, writing w elite key" + "hf iclass encode --bin 10001111100000001010100011 --ki 0 -> FC 31 CN 337 (H10301)", + "hf iclass encode -w H10301 --fc 31 --cn 337 --ki 0 -> FC 31 CN 337 (H10301)", + "hf iclass encode --bin 10001111100000001010100011 --ki 0 --elite -> FC 31 CN 337 (H10301), writing w elite key" ], "offline": true, "options": [ @@ -11991,4 +11991,4 @@ "extracted_by": "PM3Help2JSON v1.00", "extracted_on": "2023-03-26T15:04:49" } -} \ No newline at end of file +} From 2678c8e1a45678b9236d650321b49537616a20c0 Mon Sep 17 00:00:00 2001 From: kormax Date: Tue, 2 May 2023 22:04:40 +0300 Subject: [PATCH 07/22] Add more AID entries --- client/resources/aidlist.json | 60 +++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/client/resources/aidlist.json b/client/resources/aidlist.json index 81a153bba..bd6e4eac8 100644 --- a/client/resources/aidlist.json +++ b/client/resources/aidlist.json @@ -2243,8 +2243,8 @@ "AID": "A0000002480400", "Vendor": "ISO/IEC JTC1/SC17", "Country": "", - "Name": "Personal identification (mDL)", - "Description": "ISO/IEC 18013-5:2021 compliant Mobile driving licence (mDL) application.", + "Name": "Personal identification (mDL) data transfer", + "Description": "ISO/IEC 18013-5:2021 compliant Mobile driving licence (mDL) application data transfer.", "Type": "identity" }, { @@ -2259,10 +2259,26 @@ "AID": "A000000809434343444B467631", "Vendor": "Car Connectivity Consortium (CCC)", "Country": "", + "Name": "Digital Car Key Framework", + "Description": "Used during key provisioning and configuration", + "Type": "access" + }, + { + "AID": "A000000809434343444B417631", + "Vendor": "Car Connectivity Consortium (CCC)", + "Country": "", "Name": "Digital Car Key", "Description": "", "Type": "access" }, + { + "AID": "A0000008580102", + "Vendor": "Apple", + "Country": "", + "Name": "Apple Home Key Framework", + "Description": "Home Key configuration applet. Selected after a first transaction on a newely-invited device (allegedly for mailbox sync/attestation exchange)", + "Type": "" + }, { "AID": "A0000008580101", "Vendor": "Apple", @@ -2270,5 +2286,45 @@ "Name": "Apple Home Key", "Description": "NFC Home Key for select HomeKit-compatible locks", "Type": "access" + }, + { + "AID": "A000000396564341", + "Vendor": "NXP", + "Country": "", + "Name": "MIFARE 2GO", + "Description": "RID used by MIFARE 2GO-based cards", + "Type": "" + }, + { + "AID": "A0000002164954534F2D31", + "Vendor": "ITSO", + "Country": "United Kingdom", + "Name": "ITSO CMD2", + "Description": "AID used by ITSO for smartcard/phone-based transit cards", + "Type": "transit" + }, + { + "AID": "A000000632010105", + "Vendor": "CTTIC", + "Country": "China", + "Name": "China T-Union", + "Description": "Universal transit card used by many big public transit operators", + "Type": "transit" + }, + { + "AID": "D2760000254D010200", + "Vendor": "Zentraler Kreditausschuss (ZKA)", + "Country": "Germany", + "Name": "Girocard Jugendschutz", + "Description": "Age verification", + "Type": "" + }, + { + "AID": "A00000000491", + "Vendor": "MasterCard International", + "Country": "", + "Name": "Mastercard Private Label Transit", + "Description": "RID Used by transit cards that use private label mastercards (E.g. Ventra and HOP)", + "Type": "transit" } ] From f9ea12b98d376a1c0f9aadb2f08a3ee9208cc693 Mon Sep 17 00:00:00 2001 From: Maksym Date: Wed, 3 May 2023 00:48:21 +0300 Subject: [PATCH 08/22] Update aidlist.json Replace "rid" with prefix as it is more correct this way --- client/resources/aidlist.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/resources/aidlist.json b/client/resources/aidlist.json index bd6e4eac8..ff574dd6a 100644 --- a/client/resources/aidlist.json +++ b/client/resources/aidlist.json @@ -2292,7 +2292,7 @@ "Vendor": "NXP", "Country": "", "Name": "MIFARE 2GO", - "Description": "RID used by MIFARE 2GO-based cards", + "Description": "AID prefix used by MIFARE 2GO-based cards", "Type": "" }, { @@ -2324,7 +2324,7 @@ "Vendor": "MasterCard International", "Country": "", "Name": "Mastercard Private Label Transit", - "Description": "RID Used by transit cards that use private label mastercards (E.g. Ventra and HOP)", + "Description": "AID prefix used by transit cards that use private label mastercards (E.g. Ventra and HOP)", "Type": "transit" } ] From f1aedc6bcedf3ae0c4f2c6570cab23e8b546e23f Mon Sep 17 00:00:00 2001 From: Nat McHugh Date: Tue, 2 May 2023 19:42:18 +0000 Subject: [PATCH 09/22] Add paxton id to hitg2 info --- CHANGELOG.md | 1 + client/src/cmdlfhitag.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c73f7641a..61333107d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed `hf legic view` - now also print the decoded info of the dump file (@0xdeb) - Now `script run hf_mf_ultimatecard.lua -u` supports 10bytes UID (@alejandro12120) - Update documentation for installation on macOS with MacPorts (@linuxgemini) + - Added possible Paxton id to hitag2 tag info output ## [Nitride.4.16191][2023-01-29] - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index 66fb3ea42..23b8ac235 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -324,6 +324,37 @@ static int CmdLFHitagSim(const char *Cmd) { return PM3_SUCCESS; } + +static void printHitag2PaxtonDowngrade(const uint8_t *data) { + + uint64_t bytes = 0; + uint64_t num = 0; + uint64_t paxton_id = 0; + uint16_t skip = 48; + uint16_t digit = 0; + uint64_t mask = 0xF80000000000; + + for (int i = 16; i < 22; i++) { + bytes = (bytes * 0x100) + data[i]; + } + + for (int j = 0; j< 8; j++) { + num = bytes & mask; + skip -= 5; + mask = mask >> 5; + digit = (num >> skip & 15); + paxton_id = (paxton_id * 10) + digit; + + if (j == 5) { + skip -= 2; + mask = mask >> 2; + } + } + + PrintAndLogEx(INFO, "-------- " _CYAN_("Possible de-scramble patterns") " ---------"); + PrintAndLogEx(SUCCESS, "Paxton id: %lu | 0x%lx", paxton_id, paxton_id); +} + static void printHitag2Configuration(uint8_t config) { char msg[100]; @@ -630,6 +661,8 @@ static int CmdLFHitagReader(const char *Cmd) { // print data print_hex_break(data, 48, 4); + + printHitag2PaxtonDowngrade(data); } return PM3_SUCCESS; } From b8c7e02ad847a7874ab04ca4246a6c0e2a70e9e4 Mon Sep 17 00:00:00 2001 From: flamebarke <39644720+flamebarke@users.noreply.github.com> Date: Thu, 4 May 2023 21:34:27 +1000 Subject: [PATCH 10/22] Create lf_multihid.c Signed-off-by: flamebarke <39644720+flamebarke@users.noreply.github.com> --- armsrc/Standalone/lf_multihid.c | 76 +++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 armsrc/Standalone/lf_multihid.c diff --git a/armsrc/Standalone/lf_multihid.c b/armsrc/Standalone/lf_multihid.c new file mode 100644 index 000000000..d2edd867c --- /dev/null +++ b/armsrc/Standalone/lf_multihid.c @@ -0,0 +1,76 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Shain Lakin, 2023 +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// LF HID 26 Bit (H10301) multi simulator: +// Simple LF HID26 (H10301) tag simulator +// Short click - select next slot and start simulation +// LEDS = LED ON for selected slot +// Add tags (raw) to the hid26_predefined_raw array +//----------------------------------------------------------------------------- + + +#include "standalone.h" +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "util.h" +#include "dbprint.h" +#include "ticks.h" +#include "lfops.h" + +#define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0])) +#define MAX_IND 4 + +void LED_Slot(int i); + +static uint64_t hid26_predefined_raw[] = {0x2004ec2e87, 0x2004421807, 0x20064312d6, 0x2006ec0c86}; +static uint8_t hid26_slots_count; + +void ModInfo(void) { + DbpString("LF HID 26 Bit (H10301) multi simulator - aka MultiHID (Shain Lakin)"); +} + +void LED_Slot(int i) { + LEDsoff(); + if (hid26_slots_count > 4) { + LED(i % MAX_IND, 0); + } else { + LED(1 << i, 0); + } +} + +void RunMod(void) { + StandAloneMode(); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + Dbprintf(">> LF HID26 multi simulator started - aka MultiHID (Shain Lakin) <<"); + + int selected = 0; //selected slot after start + hid26_slots_count = ARRAYLEN(hid26_predefined_raw); + for (;;) { + WDT_HIT(); + if (data_available()) { + LEDsoff(); + break; + } + + SpinDelay(100); + SpinUp(100); + LED_Slot(selected); + uint64_t raw_data = hid26_predefined_raw[selected]; + CmdHIDsimTAG(0, raw_data >> 32, raw_data & 0xFFFFFFFF, 0, false); + selected = (selected + 1) % hid26_slots_count; + } +} From 0fac149a039d26a33e52ac685bd1a42ae48770e4 Mon Sep 17 00:00:00 2001 From: flamebarke <39644720+flamebarke@users.noreply.github.com> Date: Thu, 4 May 2023 21:44:12 +1000 Subject: [PATCH 11/22] Update Makefile.hal Signed-off-by: flamebarke <39644720+flamebarke@users.noreply.github.com> --- armsrc/Standalone/Makefile.hal | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index cb41bc148..da204eaca 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -50,6 +50,9 @@ define KNOWN_STANDALONE_DEFINITIONS | LF_ICEHID | LF HID collector to flashmem | | (RDV4 only) | | +----------------------------------------------------------+ +| LF_MULTIHID | LF HID 26 Bit (H1031) multi simulator | +| | - Shain Lakin | ++----------------------------------------------------------+ | LF_NEDAP_SIM | LF Nedap ID simple simulator | | | | +----------------------------------------------------------+ @@ -126,7 +129,7 @@ endef STANDALONE_MODES := LF_SKELETON -STANDALONE_MODES += LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_NEDAP_SIM LF_NEXID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE +STANDALONE_MODES += LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_MULTIHID LF_NEDAP_SIM LF_NEXID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_REBLAY HF_TCPRST HF_TMUDFORD HF_YOUNG STANDALONE_MODES += DANKARMULTI STANDALONE_MODES_REQ_BT := HF_REBLAY From 92ec161d08380135d8a233ffe14f9b45ce648dc2 Mon Sep 17 00:00:00 2001 From: flamebarke <39644720+flamebarke@users.noreply.github.com> Date: Thu, 4 May 2023 21:50:14 +1000 Subject: [PATCH 12/22] Update Makefile.inc Signed-off-by: flamebarke <39644720+flamebarke@users.noreply.github.com> --- armsrc/Standalone/Makefile.inc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/armsrc/Standalone/Makefile.inc b/armsrc/Standalone/Makefile.inc index 48ac2217f..6aeb163bb 100644 --- a/armsrc/Standalone/Makefile.inc +++ b/armsrc/Standalone/Makefile.inc @@ -49,6 +49,10 @@ endif ifneq (,$(findstring WITH_STANDALONE_LF_ICEHID,$(APP_CFLAGS))) SRC_STANDALONE = lf_icehid.c endif +# WITH_STANDALONE_LF_MULTIHID +ifneq (,$(findstring WITH_STANDALONE_LF_MULTIHID,$(APP_CFLAGS))) + SRC_STANDALONE = lf_multihid.c +endif # WITH_STANDALONE_LF_NEDAP_SIM ifneq (,$(findstring WITH_STANDALONE_LF_NEDAP_SIM,$(APP_CFLAGS))) SRC_STANDALONE = lf_nedap_sim.c From 6880c51ad60bc760d298bc5c8884c3ebd530be88 Mon Sep 17 00:00:00 2001 From: flamebarke <39644720+flamebarke@users.noreply.github.com> Date: Thu, 4 May 2023 21:55:23 +1000 Subject: [PATCH 13/22] Update CHANGELOG.md Signed-off-by: flamebarke <39644720+flamebarke@users.noreply.github.com> --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61333107d..d8c6d5e95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added new standalone mode `LF_MULTIHID` - HID26 (H1031) multi simulator (@flamebarke) - Changed `hf 14b dump --ns` - now supports `no save` of card memory (@iceman1001) - Changed `hf mfu dump --ns` - now supports `no save` of card memory (@iceman1001) - Changed the PM3 client to honor the preferences dump/trace paths. experimental support (@iceman1001) From caf3bbc026696ff5aa6d20ded92b826e6e2f859d Mon Sep 17 00:00:00 2001 From: flamebarke <39644720+flamebarke@users.noreply.github.com> Date: Thu, 4 May 2023 22:26:39 +1000 Subject: [PATCH 14/22] Update 4_Advanced-compilation-parameters.md Signed-off-by: flamebarke <39644720+flamebarke@users.noreply.github.com> --- doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index 5ead60b1a..53726b9dd 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -108,6 +108,7 @@ Here are the supported values you can assign to `STANDALONE` in `Makefile.platfo | LF_HIDBRUTE | HID corporate 1000 bruteforce - Federico dotta & Maurizio Agazzini | LF_HIDFCBRUTE | LF HID facility code bruteforce - ss23 | LF_ICEHID | LF HID collector to flashmem - Iceman1001 +| LF_MULTIHID | LF HID 26 Bit (H1031) multi simulator - Shain Lakin | LF_NEDAP_SIM | LF Nedap ID simulator | LF_NEXID | Nexwatch credentials detection mode - jrjgjk & Zolorah | LF_PROXBRUTE | HID ProxII bruteforce - Brad Antoniewicz From dd28bc8e5d94f7740b77bc1824c606df951bca75 Mon Sep 17 00:00:00 2001 From: flamebarke <39644720+flamebarke@users.noreply.github.com> Date: Thu, 4 May 2023 22:29:14 +1000 Subject: [PATCH 15/22] Update build_all_firmwares.sh Signed-off-by: flamebarke <39644720+flamebarke@users.noreply.github.com> --- tools/build_all_firmwares.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build_all_firmwares.sh b/tools/build_all_firmwares.sh index 644438032..b38f557ab 100755 --- a/tools/build_all_firmwares.sh +++ b/tools/build_all_firmwares.sh @@ -32,7 +32,7 @@ mv bootrom/obj/bootrom.elf "$DEST/PM3BOOTROM.elf" # cf armsrc/Standalone/Makefile.hal STANDALONE_MODES=(LF_SKELETON) -STANDALONE_MODES+=(LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_NEDAP_SIM LF_NEXID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE) +STANDALONE_MODES+=(LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_MULTIHID LF_NEDAP_SIM LF_NEXID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE) STANDALONE_MODES+=(HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_REBLAY HF_TCPRST HF_TMUDFORD HF_YOUNG) STANDALONE_MODES+=(DANKARMULTI) STANDALONE_MODES_REQ_BT=(HF_REBLAY) From b1839d7318f39f940b6925ec0e3f6ab83847c4ef Mon Sep 17 00:00:00 2001 From: Jonathan Liu Date: Fri, 5 May 2023 12:19:11 +1000 Subject: [PATCH 16/22] hf mf sim: reduce 50ms threshold to 6ms for reset to idle Fixes reader not being able to detect the simulated card on second Inventory command due to the RF field being powered off for only 6ms before being turned on again to reset the card to idle state. Closes #1974 --- CHANGELOG.md | 1 + armsrc/iso14443a.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61333107d..2332cb2c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Now `script run hf_mf_ultimatecard.lua -u` supports 10bytes UID (@alejandro12120) - Update documentation for installation on macOS with MacPorts (@linuxgemini) - Added possible Paxton id to hitag2 tag info output + - Changed `hf mf sim` - reduce 50ms threshold to 6ms for reset to idle #1974 (@net147) ## [Nitride.4.16191][2023-01-29] - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 637215cc3..a8cc1414b 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2084,8 +2084,8 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *par) { if (timer == 0) { timer = GetTickCount(); } else { - // 50ms no field --> card to idle state - if (GetTickCountDelta(timer) > 50) { + // 6ms no field --> card to idle state + if (GetTickCountDelta(timer) > 6) { return 2; } } From 0c9a64438f7e359ad2a1d48e7fafd32f7fac4380 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 May 2023 10:45:35 +0200 Subject: [PATCH 17/22] 256kb version is too large --- tools/build_all_firmwares.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/build_all_firmwares.sh b/tools/build_all_firmwares.sh index b38f557ab..4a0fe5947 100755 --- a/tools/build_all_firmwares.sh +++ b/tools/build_all_firmwares.sh @@ -22,8 +22,7 @@ echo "Destination: ${DEST:=firmware}" echo "Produce stats?: ${STATS:=false}" # Which parts to skip for the 256kb version? -SKIPS256="SKIP_HITAG=1 SKIP_LEGICRF=1 SKIP_FELICA=1 SKIP_EM4x50=1 SKIP_ISO14443b=1 SKIP_NFCBARCODE=1 SKIP_ZX8211=1" - +SKIPS256="SKIP_HITAG=1 SKIP_LEGICRF=1 SKIP_FELICA=1 SKIP_EM4x50=1 SKIP_ISO14443b=1 SKIP_NFCBARCODE=1 SKIP_ZX8211=1 SKIP_LF=1" make $MKFLAGS bootrom || exit 1 chmod 644 bootrom/obj/bootrom.elf From 52981476e208f31c9527dc1751ed47da550114a1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 May 2023 10:47:02 +0200 Subject: [PATCH 18/22] fixed ndef parsing of signature version 1 records --- CHANGELOG.md | 1 + client/src/nfc/ndef.c | 68 ++++++++++++++++++++++++++++++------------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1795ed0a1..35e5f756c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fixed `nfc decode` - now handles NDEF Signature version1 records better (@iceman1001) - Added new standalone mode `LF_MULTIHID` - HID26 (H1031) multi simulator (@flamebarke) - Changed `hf 14b dump --ns` - now supports `no save` of card memory (@iceman1001) - Changed `hf mfu dump --ns` - now supports `no save` of card memory (@iceman1001) diff --git a/client/src/nfc/ndef.c b/client/src/nfc/ndef.c index b995a3e19..99df7e419 100644 --- a/client/src/nfc/ndef.c +++ b/client/src/nfc/ndef.c @@ -289,22 +289,35 @@ static int ndef_print_signature(uint8_t *data, uint8_t data_len, uint8_t *signat } static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { - size_t indx = 1; + size_t indx = 1; uint8_t sigType = sig[indx] & 0x7f; bool sigURI = sig[indx] & 0x80; + indx++; - PrintAndLogEx(SUCCESS, "\tsignature type: %s", ((sigType < stNA) ? ndefSigType_s[sigType] : ndefSigType_s[stNA])); - PrintAndLogEx(SUCCESS, "\tsignature uri: %s", (sigURI ? "present" : "not present")); + PrintAndLogEx(SUCCESS, "\tSignature type... " _YELLOW_("%s"), ((sigType < stNA) ? ndefSigType_s[sigType] : ndefSigType_s[stNA])); + PrintAndLogEx(SUCCESS, "\tSignature URI.... " _YELLOW_("%s"), (sigURI ? "present" : "not present")); + + if (sigType == 0 && sigURI == false) { + PrintAndLogEx(INFO, "\tRecord should be considered a start marker"); + } + if (sigType == 0 && sigURI) { + PrintAndLogEx(INFO, _RED_("\tSignature record is invalid")); + } + + uint16_t intsiglen = MemBeToUint2byte(sig + indx); + indx += 2; - size_t intsiglen = (sig[indx + 1] << 8) + sig[indx + 2]; // ecdsa 0x04 if (sigType == stECDSA_P192 || sigType == stECDSA_P256) { - indx += 3; + int slen = 24; - if (sigType == stECDSA_P256) + if (sigType == stECDSA_P256) { slen = 32; - PrintAndLogEx(SUCCESS, "\tsignature [%zu]: %s", intsiglen, sprint_hex_inrow(&sig[indx], intsiglen)); + } + + PrintAndLogEx(SUCCESS, "\tSignature [%u]...", intsiglen); + print_hex_noascii_break(&sig[indx], intsiglen, 32); uint8_t rval[300] = {0}; uint8_t sval[300] = {0}; @@ -313,38 +326,53 @@ static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { PrintAndLogEx(SUCCESS, "\t\tr: %s", sprint_hex(rval + 32 - slen, slen)); PrintAndLogEx(SUCCESS, "\t\ts: %s", sprint_hex(sval + 32 - slen, slen)); } + } else { + PrintAndLogEx(SUCCESS, "\tSignature [%u]...", intsiglen); + print_hex_noascii_break(&sig[indx], intsiglen, 32); } + indx += intsiglen; if (sigURI) { - size_t intsigurilen = (sig[indx] << 8) + sig[indx + 1]; + + uint16_t intsigurilen = MemBeToUint2byte(sig + indx); indx += 2; - PrintAndLogEx(SUCCESS, "\tsignature uri [%zu]: %.*s", intsigurilen, (int)intsigurilen, &sig[indx]); + + PrintAndLogEx(SUCCESS, "\tSignature URI... " _YELLOW_("%.*s"), (int)intsigurilen, &sig[indx]); indx += intsigurilen; } + // CERTIFICATE SECTION + PrintAndLogEx(INFO, ""); + PrintAndLogEx(INFO, _CYAN_("Certificate")); + uint8_t certFormat = (sig[indx] >> 4) & 0x07; uint8_t certCount = sig[indx] & 0x0f; bool certURI = sig[indx] & 0x80; + indx++; - PrintAndLogEx(SUCCESS, "\tcertificate format: %s", ((certFormat < sfNA) ? ndefCertificateFormat_s[certFormat] : ndefCertificateFormat_s[sfNA])); - PrintAndLogEx(SUCCESS, "\tcertificates count: %d", certCount); + PrintAndLogEx(SUCCESS, "\tFormat............ " _YELLOW_("%s"), ((certFormat < sfNA) ? ndefCertificateFormat_s[certFormat] : ndefCertificateFormat_s[sfNA])); + if (certCount) { + PrintAndLogEx(SUCCESS, "\tNum of certs#..... " _YELLOW_("%d"), certCount); + } // print certificates - indx++; - for (int i = 0; i < certCount; i++) { - size_t intcertlen = (sig[indx + 1] << 8) + sig[indx + 2]; + for (uint8_t i = 0; i < certCount; i++) { + uint16_t intcertlen = MemBeToUint2byte(sig + indx); indx += 2; - PrintAndLogEx(SUCCESS, "\tcertificate %d [%zu]: %s", i + 1, intcertlen, sprint_hex_inrow(&sig[indx], intcertlen)); + PrintAndLogEx(INFO, ""); + PrintAndLogEx(SUCCESS, "\tCertificate %u [%u]...", i + 1, intcertlen); + print_hex_noascii_break(&sig[indx], intcertlen, 32); + indx += intcertlen; } - // have certificate uri + // print certificate uri if ((indx <= siglen) && certURI) { - size_t inturilen = (sig[indx] << 8) + sig[indx + 1]; + uint16_t inturilen = MemBeToUint2byte(sig + indx); indx += 2; - PrintAndLogEx(SUCCESS, "\tcertificate uri [%zu]: %.*s", inturilen, (int)inturilen, &sig[indx]); + PrintAndLogEx(SUCCESS, "\tCertificate URI... " _YELLOW_("%.*s"), (int)inturilen, &sig[indx]); } return PM3_SUCCESS; @@ -417,9 +445,9 @@ static int ndefDecodeSig2(uint8_t *sig, size_t siglen) { } static int ndefDecodeSig(uint8_t *sig, size_t siglen) { - PrintAndLogEx(SUCCESS, "\tsignature version : \t" _GREEN_("0x%02x"), sig[0]); + PrintAndLogEx(SUCCESS, "\tVersion... " _GREEN_("0x%02x"), sig[0]); if (sig[0] != 0x01 && sig[0] != 0x20) { - PrintAndLogEx(ERR, "signature version unknown."); + PrintAndLogEx(ERR, _RED_("Version unknown")); return PM3_ESOFT; } From 3e293b4bc8dbce24c81f18818ad330bf1159ab72 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 May 2023 12:33:14 +0200 Subject: [PATCH 19/22] changed nfc decode to handle external records and if the record happens to be estonian ekaart also ASN1 decode it --- CHANGELOG.md | 1 + client/src/nfc/ndef.c | 63 ++++++++++++++++++++++++++++++++++++------- client/src/nfc/ndef.h | 3 ++- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35e5f756c..e20b440f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Changed `nfc decode` - now handles EXTERNAL RECORDS better (@iceman1001) - Fixed `nfc decode` - now handles NDEF Signature version1 records better (@iceman1001) - Added new standalone mode `LF_MULTIHID` - HID26 (H1031) multi simulator (@flamebarke) - Changed `hf 14b dump --ns` - now supports `no save` of card memory (@iceman1001) diff --git a/client/src/nfc/ndef.c b/client/src/nfc/ndef.c index 99df7e419..a97d5bb55 100644 --- a/client/src/nfc/ndef.c +++ b/client/src/nfc/ndef.c @@ -39,8 +39,6 @@ #define NDEF_VCARDTEXT "text/vcard" #define NDEF_XVCARDTEXT "text/x-vcard" - - static const char *TypeNameFormat_s[] = { "Empty Record", "Well Known Record", @@ -295,8 +293,8 @@ static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { bool sigURI = sig[indx] & 0x80; indx++; - PrintAndLogEx(SUCCESS, "\tSignature type... " _YELLOW_("%s"), ((sigType < stNA) ? ndefSigType_s[sigType] : ndefSigType_s[stNA])); - PrintAndLogEx(SUCCESS, "\tSignature URI.... " _YELLOW_("%s"), (sigURI ? "present" : "not present")); + PrintAndLogEx(SUCCESS, "\tType...... " _YELLOW_("%s"), ((sigType < stNA) ? ndefSigType_s[sigType] : ndefSigType_s[stNA])); + PrintAndLogEx(SUCCESS, "\tURI....... " _YELLOW_("%s"), (sigURI ? "present" : "not present")); if (sigType == 0 && sigURI == false) { PrintAndLogEx(INFO, "\tRecord should be considered a start marker"); @@ -327,7 +325,7 @@ static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { PrintAndLogEx(SUCCESS, "\t\ts: %s", sprint_hex(sval + 32 - slen, slen)); } } else { - PrintAndLogEx(SUCCESS, "\tSignature [%u]...", intsiglen); + PrintAndLogEx(SUCCESS, "\tData [%u]...", intsiglen); print_hex_noascii_break(&sig[indx], intsiglen, 32); } @@ -817,7 +815,7 @@ static int ndefDecodeMime_bt(NDEFHeader_t *ndef) { return PM3_SUCCESS; } PrintAndLogEx(INFO, "Type............ " _YELLOW_("%.*s"), (int)ndef->TypeLen, ndef->Type); - uint16_t ooblen = (ndef->Payload[1] << 8 | ndef->Payload[0]); + uint16_t ooblen = MemBeToUint2byte(ndef->Payload); PrintAndLogEx(INFO, "OOB data len.... %u", ooblen); PrintAndLogEx(INFO, "BT MAC.......... " _YELLOW_("%s"), sprint_hex(ndef->Payload + 2, 6)); // Let's check payload[8]. Tells us a bit about the UUID's. If 0x07 then it tells us a service UUID is 128bit @@ -856,6 +854,38 @@ static int ndefDecodeMime_bt(NDEFHeader_t *ndef) { return PM3_SUCCESS; } +// https://raw.githubusercontent.com/haldean/ndef/master/docs/NFCForum-TS-RTD_1.0.pdf +static int ndefDecodeExternal_record(NDEFHeader_t *ndef) { + + if (ndef->TypeLen == 0) { + PrintAndLogEx(INFO, "no type"); + return PM3_SUCCESS; + } + + if (ndef->PayloadLen == 0) { + PrintAndLogEx(INFO, "no payload"); + return PM3_SUCCESS; + } + + PrintAndLogEx(INFO + , " URN... " _GREEN_("urn:nfc:ext:%.*s") + , (int)ndef->TypeLen + , ndef->Type + ); + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "Payload [%u]...", ndef->PayloadLen); + print_hex_noascii_break(ndef->Payload, ndef->PayloadLen, 32); + + // do a character check? + if (!strncmp((char *)ndef->Type, "pilet.ee:ekaart:2", ndef->TypeLen)) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, _GREEN_("Ekaart detected") " - Trying ASN1 decode..."); + asn1_print(ndef->Payload, ndef->PayloadLen, " "); + } + return PM3_SUCCESS; +} + static int ndefDecodePayload(NDEFHeader_t *ndef, bool verbose) { PrintAndLogEx(INFO, ""); @@ -863,7 +893,7 @@ static int ndefDecodePayload(NDEFHeader_t *ndef, bool verbose) { case tnfEmptyRecord: PrintAndLogEx(INFO, "Empty Record"); if (ndef->TypeLen != 0 || ndef->IDLen != 0 || ndef->PayloadLen != 0) { - PrintAndLogEx(FAILED, "unexpected data in TNF_EMPTY record"); + PrintAndLogEx(FAILED, "unexpected data in empty record"); break; } break; @@ -959,20 +989,33 @@ static int ndefDecodePayload(NDEFHeader_t *ndef, bool verbose) { } case tnfAbsoluteURIRecord: PrintAndLogEx(INFO, "Absolute URI Record"); - PrintAndLogEx(INFO, " payload : %.*s", (int)ndef->PayloadLen, ndef->Payload); + PrintAndLogEx(INFO, " payload : " _YELLOW_("%.*s"), (int)ndef->PayloadLen, ndef->Payload); break; case tnfExternalRecord: PrintAndLogEx(INFO, "External Record"); - PrintAndLogEx(INFO, "- decoder to be impl -"); + ndefDecodeExternal_record(ndef); break; case tnfUnknownRecord: PrintAndLogEx(INFO, "Unknown Record"); - PrintAndLogEx(INFO, "- decoder to be impl -"); + if (ndef->TypeLen != 0) { + PrintAndLogEx(FAILED, "unexpected type field"); + break; + } break; case tnfUnchangedRecord: PrintAndLogEx(INFO, "Unchanged Record"); PrintAndLogEx(INFO, "- decoder to be impl -"); break; + case tnfReservedRecord: + PrintAndLogEx(INFO, "Reserved Record"); + if (ndef->TypeLen != 0) { + PrintAndLogEx(FAILED, "unexpected type field"); + break; + } + break; + default: + PrintAndLogEx(FAILED, "unexpected tnf value... 0x%02x", ndef->TypeNameFormat); + break; } PrintAndLogEx(INFO, ""); return PM3_SUCCESS; diff --git a/client/src/nfc/ndef.h b/client/src/nfc/ndef.h index 478c28e0a..643bb70a7 100644 --- a/client/src/nfc/ndef.h +++ b/client/src/nfc/ndef.h @@ -31,7 +31,8 @@ typedef enum { tnfAbsoluteURIRecord = 0x03, tnfExternalRecord = 0x04, tnfUnknownRecord = 0x05, - tnfUnchangedRecord = 0x06 + tnfUnchangedRecord = 0x06, + tnfReservedRecord = 0x07, } TypeNameFormat_t; typedef enum { From ed555be1804b9f98d59351541a16ee171939d2a8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 May 2023 13:18:53 +0200 Subject: [PATCH 20/22] fix wrong copying when skipping sector trailers --- client/src/mifare/mifarehost.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 9e9f674e1..3b37182fe 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1467,12 +1467,12 @@ int convert_mfc_2_arr(uint8_t *in, uint16_t ilen, uint8_t *out, uint16_t *olen) if (mfIsSectorTrailer(blockno) == false) { memcpy(out, in, MFBLOCK_SIZE); + out += MFBLOCK_SIZE; + *olen += MFBLOCK_SIZE; } blockno++; - out += MFBLOCK_SIZE; in += MFBLOCK_SIZE; ilen -= MFBLOCK_SIZE; - *olen += MFBLOCK_SIZE; } return PM3_SUCCESS; } From 78f097cb5581081f0ee42958b13c41d4b487aa90 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 May 2023 13:20:52 +0200 Subject: [PATCH 21/22] the nfc decode now handling MFC dump files, it detects the MAD key and if so removes all sector trailers. this means a lot of zeros in the end might be there. And ndef prints a bunch of empty records. Better than before atleast --- CHANGELOG.md | 1 + client/src/cmdnfc.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e20b440f8..dff4bcf59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Changed `nfc decode -f` - now can detect and convert MFC dumpfiles to NDEF byte arrays (@iceman1001) - Changed `nfc decode` - now handles EXTERNAL RECORDS better (@iceman1001) - Fixed `nfc decode` - now handles NDEF Signature version1 records better (@iceman1001) - Added new standalone mode `LF_MULTIHID` - HID26 (H1031) multi simulator (@flamebarke) diff --git a/client/src/cmdnfc.c b/client/src/cmdnfc.c index df87ee6f8..6f9561783 100644 --- a/client/src/cmdnfc.c +++ b/client/src/cmdnfc.c @@ -30,6 +30,8 @@ #include "cmdhftopaz.h" #include "cmdnfc.h" #include "fileutils.h" +#include "mifare/mifaredefault.h" +#include "mifare/mad.h" void print_type4_cc_info(uint8_t *d, uint8_t n) { if (n < 0x0F) { @@ -111,6 +113,17 @@ static int CmdNfcDecode(const char *Cmd) { return res; } + // convert from MFC dump file to a pure NDEF byte array + if (HasMADKey(dump)) { + PrintAndLogEx(SUCCESS, "MFC dump file detected. Converting..."); + uint8_t ndef[4096] = {0}; + uint16_t ndeflen = 0; + uint8_t skip = (4 * MFBLOCK_SIZE); + convert_mfc_2_arr(dump + skip, bytes_read - skip, ndef, &ndeflen); + memcpy(dump, ndef, ndeflen); + bytes_read = ndeflen; + } + res = NDEFDecodeAndPrint(dump, bytes_read, verbose); if (res != PM3_SUCCESS) { PrintAndLogEx(INFO, "Trying to parse NDEF records w/o NDEF header"); From 3b68acd2864b3cd401b07da4b98fa2bfc080e529 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 May 2023 19:37:35 +0200 Subject: [PATCH 22/22] comment out duplicate but kept it since documentation --- client/dictionaries/mfc_default_keys.dic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 4af8cf64a..b51989bda 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -2112,7 +2112,7 @@ D23C1CB1216E # 20230413-78, Caesars A1D92F808CAF # 20230413-79, The Cosmopolitan, Vegas -96A301BCE267 +# 96A301BCE267 # 20230413-80, Aria 1153C319B4F8 # 20230413-81, Aria