From 810a89c4df8098b58d24ae29b94b866fc38ca8c3 Mon Sep 17 00:00:00 2001 From: Jin Jia Date: Wed, 4 Jan 2023 07:11:48 +0000 Subject: [PATCH 01/68] Added Compliance of MIFARE Classic EV1 1K Datasheet footnote of Table 8 --- armsrc/mifaresim.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index c2f81df21..ad975381b 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -46,6 +46,15 @@ #include "dbprint.h" #include "ticks.h" +static bool IsKeyBReadable(uint8_t blockNo) { + uint8_t sector_trailer[16]; + emlGetMem(sector_trailer, SectorTrailer(blockNo), 1); + uint8_t AC = ((sector_trailer[7] >> 5) & 0x04) + | ((sector_trailer[8] >> 2) & 0x02) + | ((sector_trailer[8] >> 7) & 0x01); + return (AC == 0x00 || AC == 0x01 || AC == 0x02); +} + static bool IsTrailerAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action) { uint8_t sector_trailer[16]; emlGetMem(sector_trailer, blockNo, 1); @@ -881,6 +890,17 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 Dbprintf("[MFEMUL_WORK] Reader tried to operate (0x%02x) on block (0x%02x) not authenticated for (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], cardAUTHSC); break; } + + // Compliance of MIFARE Classic EV1 1K Datasheet footnote of Table 8 + // If access bits show that key B is Readable, any subsequent memory access will be refused. + if (cardAUTHKEY == keyB && IsKeyBReadable(blockNo)) { + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + FpgaDisableTracing(); + + if (g_dbglevel >= DBG_ERROR) + Dbprintf("[MFEMUL_WORK] Access denied: Reader tried to access memory on authentication with key B while key B is readable in sector (0x%02x)", cardAUTHSC); + break; + } } // case MFEMUL_WORK => CMD READ block From 949ef8435e9eba27e7766c917d5cbb7c23ef1782 Mon Sep 17 00:00:00 2001 From: Jin Jia Date: Wed, 4 Jan 2023 07:19:29 +0000 Subject: [PATCH 02/68] changed keyB in line 896 to the correct macro --- armsrc/mifaresim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index ad975381b..71195aa62 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -893,7 +893,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 // Compliance of MIFARE Classic EV1 1K Datasheet footnote of Table 8 // If access bits show that key B is Readable, any subsequent memory access will be refused. - if (cardAUTHKEY == keyB && IsKeyBReadable(blockNo)) { + if (cardAUTHKEY == AUTHKEYB && IsKeyBReadable(blockNo)) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); FpgaDisableTracing(); From 303dbae85bd9c88c8e34726c6fb0f818ec89c315 Mon Sep 17 00:00:00 2001 From: Jin Jia Date: Fri, 6 Jan 2023 06:26:21 +0000 Subject: [PATCH 03/68] Fixed a warning on uninitialized variable --- armsrc/mifaresim.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 71195aa62..81f26c5cb 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -881,8 +881,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 break; } */ - - if (MifareBlockToSector(receivedCmd_dec[1]) != cardAUTHSC) { + blockNo = receivedCmd_dec[1]; + if (MifareBlockToSector(blockNo) != cardAUTHSC) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); FpgaDisableTracing(); @@ -893,6 +893,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 // Compliance of MIFARE Classic EV1 1K Datasheet footnote of Table 8 // If access bits show that key B is Readable, any subsequent memory access will be refused. + if (cardAUTHKEY == AUTHKEYB && IsKeyBReadable(blockNo)) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); FpgaDisableTracing(); From a4a7033b2385ff679101e8febcb3ce8c259d6dd6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 21 Jun 2023 18:43:21 +0200 Subject: [PATCH 04/68] adapt comparision of text --- client/src/nfc/ndef.c | 2 +- client/src/wiegand_formats.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/client/src/nfc/ndef.c b/client/src/nfc/ndef.c index 40cfe7113..e03913fbc 100644 --- a/client/src/nfc/ndef.c +++ b/client/src/nfc/ndef.c @@ -927,7 +927,7 @@ static int ndefDecodeExternal_record(NDEFHeader_t *ndef) { print_hex_noascii_break(ndef->Payload, ndef->PayloadLen, 32); // do a character check? - if (!strncmp((char *)ndef->Type, "pilet.ee:ekaart:2", ndef->TypeLen)) { + if (!strncmp((char *)ndef->Type, "pilet.ee:ekaart:", ndef->TypeLen - 1)) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, _GREEN_("Ekaart detected") " - Trying ASN1 decode..."); asn1_print(ndef->Payload, ndef->PayloadLen, " "); diff --git a/client/src/wiegand_formats.c b/client/src/wiegand_formats.c index e63040a19..f88c8f759 100644 --- a/client/src/wiegand_formats.c +++ b/client/src/wiegand_formats.c @@ -730,7 +730,9 @@ static bool Pack_C15001(wiegand_card_t *card, wiegand_message_t *packed, bool pr static bool Unpack_C15001(wiegand_message_t *packed, wiegand_card_t *card) { memset(card, 0, sizeof(wiegand_card_t)); - if (packed->Length != 36) return false; // Wrong length? Stop here. + + if (packed->Length != 36) + return false; // Wrong length? Stop here. card->OEM = get_linear_field(packed, 1, 10); card->FacilityCode = get_linear_field(packed, 11, 8); @@ -976,8 +978,10 @@ static bool Pack_C1k48s(wiegand_card_t *card, wiegand_message_t *packed, bool pr packed->Mid |= (evenparity32((packed->Mid & 0x00001B6D) ^ (packed->Bot & 0xB6DB6DB6))) << 14; packed->Bot |= (oddparity32((packed->Mid & 0x000036DB) ^ (packed->Bot & 0x6DB6DB6C))); packed->Mid |= (oddparity32((packed->Mid & 0x00007FFF) ^ (packed->Bot & 0xFFFFFFFF))) << 15; + if (preamble) return add_HID_header(packed); + return true; } From 681382e0cc429d786317f4858a51ae8d07d01c27 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 21 Jun 2023 18:45:25 +0200 Subject: [PATCH 05/68] new AID for Kiev metro card --- client/resources/mad.json | 14 ++++++++++++++ client/src/cmdhfmfp.h | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/client/resources/mad.json b/client/resources/mad.json index cfa6294d3..38cdf2636 100644 --- a/client/resources/mad.json +++ b/client/resources/mad.json @@ -4073,6 +4073,20 @@ "service_provider": "HID Corporation", "system_integrator": "HID Corporation" }, + { + "application": "City transport, prepaid ticket, cardholder, servicespass", + "company": "Ridango AS", + "mad": "0x3C56", + "service_provider": "Pilet.ee ekaart", + "system_integrator": "Pilet.ee ekaart" + }, + { + "application": "City transport, prepaid ticket, cardholder, servicespass", + "company": "Ridango AS", + "mad": "0x3D56", + "service_provider": "Pilet.ee ekaart", + "system_integrator": "Pilet.ee ekaart" + }, { "application": "City transport bus, ferry, administration", "company": "VFJ Technology Pty Ltd", diff --git a/client/src/cmdhfmfp.h b/client/src/cmdhfmfp.h index 7381f87a2..2a4d7cd2c 100644 --- a/client/src/cmdhfmfp.h +++ b/client/src/cmdhfmfp.h @@ -20,6 +20,10 @@ #include "common.h" + +#define AES_KEY_LEN 16 +#define MAX_AES_KEYS_LIST_LEN 1024 + int CmdHFMFP(const char *Cmd); int CmdHFMFPNDEFRead(const char *Cmd); From cdb906cd23ac66106eaca1f474207220f30c71e0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 21 Jun 2023 18:45:59 +0200 Subject: [PATCH 06/68] style --- client/luascripts/lf_ident_json.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/luascripts/lf_ident_json.lua b/client/luascripts/lf_ident_json.lua index 73794547c..11657910d 100644 --- a/client/luascripts/lf_ident_json.lua +++ b/client/luascripts/lf_ident_json.lua @@ -113,7 +113,7 @@ local function getDefault(block0) block0 = block0:upper() - local T55X7_DEFAULT_CONFIG_BLOCK = '000880E8' --// compat mode, RF/32, manchester, STT, 7 data blocks + local T55X7_DEFAULT_CONFIG_BLOCK = '000880E8' --// compat mode, RF/32, manchester, STT, 7 data blocks local T55X7_RAW_CONFIG_BLOCK = '000880E0' --// compat mode, RF/32, manchester, 7 data blocks local T55X7_EM_UNIQUE_CONFIG_BLOCK = '00148040' --// emulate em4x02/unique - compat mode, manchester, RF/64, 2 data blocks -- FDXB requires data inversion and BiPhase 57 is simply BipHase 50 inverted, so we can either do it using the modulation scheme or the inversion flag From d3792c0853272545282ba6cbde781849415711ee Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 21 Jun 2023 18:48:04 +0200 Subject: [PATCH 07/68] adapt mifare plus key files to be loaded/saved in json. WIP , will need a typedef struct in order to work properly --- client/src/fileutils.c | 44 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/client/src/fileutils.c b/client/src/fileutils.c index 3411215c6..aad9b9cce 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -29,6 +29,7 @@ #include "cmdhficlass.h" // pagemap #include "protocols.h" // iclass defines #include "cmdhftopaz.h" // TOPAZ defines +#include "cmdhfmfp.h" // MFP / AES defines #ifdef _WIN32 #include "scandir.h" @@ -543,13 +544,14 @@ int saveFileJSONex(const char *preferredName, JSONFileType ftype, uint8_t *data, break; } case jsfMfPlusKeys: { - JsonSaveStr(root, "FileType", "mfp"); + JsonSaveStr(root, "FileType", "mfpkeys"); JsonSaveBufAsHexCompact(root, "$.Card.UID", &data[0], 7); JsonSaveBufAsHexCompact(root, "$.Card.SAK", &data[10], 1); JsonSaveBufAsHexCompact(root, "$.Card.ATQA", &data[11], 2); uint8_t atslen = data[13]; - if (atslen > 0) + if (atslen > 0) { JsonSaveBufAsHexCompact(root, "$.Card.ATS", &data[14], atslen); + } uint8_t vdata[2][64][17] = {{{0}}}; memcpy(vdata, data + (14 + atslen), 2 * 64 * 17); @@ -559,12 +561,12 @@ int saveFileJSONex(const char *preferredName, JSONFileType ftype, uint8_t *data, if (vdata[0][i][0]) { snprintf(path, sizeof(path), "$.SectorKeys.%zu.KeyA", i); - JsonSaveBufAsHexCompact(root, path, &vdata[0][i][1], 16); + JsonSaveBufAsHexCompact(root, path, &vdata[0][i][1], AES_KEY_LEN); } if (vdata[1][i][0]) { snprintf(path, sizeof(path), "$.SectorKeys.%zu.KeyB", i); - JsonSaveBufAsHexCompact(root, path, &vdata[1][i][1], 16); + JsonSaveBufAsHexCompact(root, path, &vdata[1][i][1], AES_KEY_LEN); } } break; @@ -1296,6 +1298,40 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz *datalen += sptr; } + + if (!strcmp(ctype, "mfpkeys")) { + + JsonLoadBufAsHex(root, "$.Card.UID", udata.bytes, 7, datalen); + JsonLoadBufAsHex(root, "$.Card.SAK", udata.bytes + 10, 1, datalen); + JsonLoadBufAsHex(root, "$.Card.ATQA", udata.bytes + 11, 2, datalen); + uint8_t atslen = udata.bytes[13]; + if (atslen > 0) { + JsonLoadBufAsHex(root, "$.Card.ATS", udata.bytes + 14, atslen, datalen); + } + + size_t sptr = (14 + atslen); + + // memcpy(vdata, udata.bytes + (14 + atslen), 2 * 64 * 17); + for (size_t i = 0; i < 64; i++) { + + if ((sptr + (AES_KEY_LEN * 2)) > maxdatalen) { + break; + } + + size_t offset = (14 + atslen) + (i * 2 * AES_KEY_LEN); + + char blocks[40] = {0}; + snprintf(blocks, sizeof(blocks), "$.SectorKeys.%zu.KeyA", i); + JsonLoadBufAsHex(root, blocks, udata.bytes + offset, AES_KEY_LEN, datalen); + + snprintf(blocks, sizeof(blocks), "$.SectorKeys.%zu.KeyB", i); + JsonLoadBufAsHex(root, blocks, udata.bytes + offset + AES_KEY_LEN, AES_KEY_LEN, datalen); + + sptr += (2 * AES_KEY_LEN); + } + *datalen += sptr; + } + out: if (callback != NULL) { From c7af7169426b656c556715cbab8b3cacfdbc3e29 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 21 Jun 2023 18:49:12 +0200 Subject: [PATCH 08/68] style --- client/src/uart/uart_posix.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/src/uart/uart_posix.c b/client/src/uart/uart_posix.c index 86d76317b..c64d85db6 100644 --- a/client/src/uart/uart_posix.c +++ b/client/src/uart/uart_posix.c @@ -189,6 +189,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { free(sp); return INVALID_SERIAL_PORT; } + int sfd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); if (sfd == -1) { PrintAndLogEx(ERR, "Error opening Bluetooth socket"); @@ -196,6 +197,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { free(sp); return INVALID_SERIAL_PORT; } + if (connect(sfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { PrintAndLogEx(ERR, "Error: cannot connect device " _YELLOW_("%s") " over Bluetooth", addrstr); close(sfd); From 1bd389bdd0c408e732f4b6c6b3cc89c7e41a53fb Mon Sep 17 00:00:00 2001 From: kormax Date: Thu, 22 Jun 2023 18:06:23 +0300 Subject: [PATCH 09/68] Add annotation for AirDrop ECP frame --- client/src/cmdhflist.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index fe0ee46b0..b38d7fea4 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -189,7 +189,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i if (cmd[1] == 0x01 && cmdsize == 7) { snprintf(exp, size, "ECP1"); return PM3_SUCCESS; - } else if (cmd[1] == 0x02 && cmdsize == (cmd[2] & 0x0f) + 7) { + } else if (cmd[1] == 0x02 && cmdsize == (cmd[2] & 0x0F) + 7) { // Byte 3 is the reader type switch (cmd[3]) { case 0x01: @@ -201,6 +201,9 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i case 0x03: snprintf(exp, size, "ECP2 (Identity)"); break; + case 0x05: + snprintf(exp, size, "ECP2 (AirDrop)"); + break; default: snprintf(exp, size, "ECP2"); break; From 57b827613b91266376a1a463c294036355f9fb95 Mon Sep 17 00:00:00 2001 From: kormax Date: Thu, 22 Jun 2023 18:30:52 +0300 Subject: [PATCH 10/68] Update aidlist.json --- client/resources/aidlist.json | 106 +++++++++++++++++++++++++++++----- 1 file changed, 93 insertions(+), 13 deletions(-) diff --git a/client/resources/aidlist.json b/client/resources/aidlist.json index ff574dd6a..9173d0a10 100644 --- a/client/resources/aidlist.json +++ b/client/resources/aidlist.json @@ -2255,13 +2255,21 @@ "Description": "Student ID cards", "Type": "identity" }, + { + "AID": "D2760000254D010200", + "Vendor": "Zentraler Kreditausschuss (ZKA)", + "Country": "Germany", + "Name": "Girocard Jugendschutz", + "Description": "Age verification", + "Type": "identity" + }, { "AID": "A000000809434343444B467631", "Vendor": "Car Connectivity Consortium (CCC)", "Country": "", "Name": "Digital Car Key Framework", "Description": "Used during key provisioning and configuration", - "Type": "access" + "Type": "" }, { "AID": "A000000809434343444B417631", @@ -2295,13 +2303,69 @@ "Description": "AID prefix used by MIFARE 2GO-based cards", "Type": "" }, + { + "AID": "A00000039656434103F1216000000000", + "Vendor": "LV Monorail", + "Country": "United States", + "Name": "Las Vegas Monorail", + "Description": "", + "Type": "transport" + }, + { + "AID": "A00000039656434103F8852200000000", + "Vendor": "Ubian", + "Country": "Slovakia", + "Name": "Ubian digital transit card", + "Description": "DESFire-based virtual transit card", + "Type": "transport" + }, + { + "AID": "DE5C0D1F1CADA5", + "Vendor": "CRTM", + "Country": "Spain", + "Name": "Madrid transit card", + "Description": "DESFire-based transit card", + "Type": "transport" + }, + { + "AID": "A00000F21100", + "Vendor": "PTV", + "Country": "Australia", + "Name": "Myki transit card", + "Description": "DESFire-based transit card", + "Type": "transport" + }, + { + "AID": "637001ff4c41", + "Vendor": "Cubic", + "Country": "United States", + "Name": "LA Tap", + "Description": "DESFire-based transit card (ASCII cp\\x01\\xffLA)", + "Type": "transport" + }, + { + "AID": "637001ff574d415441", + "Vendor": "Cubic", + "Country": "United States", + "Name": "Smart Trip", + "Description": "DESFire-based transit card (ASCII cp\\x01\\xffWMATA)", + "Type": "transport" + }, + { + "AID": "637001ff434c4950504552", + "Vendor": "Cubic", + "Country": "United States", + "Name": "Clipper", + "Description": "DESFire-based transit card (ASCII cp\\x01\\xffCLIPPER)", + "Type": "transport" + }, { "AID": "A0000002164954534F2D31", "Vendor": "ITSO", "Country": "United Kingdom", "Name": "ITSO CMD2", "Description": "AID used by ITSO for smartcard/phone-based transit cards", - "Type": "transit" + "Type": "transport" }, { "AID": "A000000632010105", @@ -2309,22 +2373,38 @@ "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": "" + "Type": "transport" }, { "AID": "A00000000491", "Vendor": "MasterCard International", "Country": "", "Name": "Mastercard Private Label Transit", - "Description": "AID prefix used by transit cards that use private label mastercards (E.g. Ventra and HOP)", - "Type": "transit" + "Description": "AID prefix used by transit cards that use private label mastercard", + "Type": "transport" + }, + { + "AID": "A0000000049100", + "Vendor": "MasterCard International", + "Country": "United States", + "Name": "HOP Fastpass", + "Description": "", + "Type": "transport" + }, + { + "AID": "A0000000049101", + "Vendor": "MasterCard International", + "Country": "United States", + "Name": "Ventra", + "Description": "", + "Type": "transport" + }, + { + "AID": "A000000858044F53452E4348", + "Vendor": "Apple", + "Country": "", + "Name": "AirDrop connection negotiation", + "Description": "Used by NFC-based AirDrop negotiation added in IOS17", + "Type": "" } ] From f138e54db6289ea936b3da112d740b23f0f61a06 Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 22 Jun 2023 22:34:49 +0200 Subject: [PATCH 11/68] fix: missing includes when building with "gcc (GCC) 11.2.1 20220127 (Red Hat 11.2.1-9)" --- tools/mfd_aes_brute/mfd_aes_brute.c | 1 + tools/mfd_aes_brute/mfd_multi_brute.c | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/mfd_aes_brute/mfd_aes_brute.c b/tools/mfd_aes_brute/mfd_aes_brute.c index 19bb54ce5..53a984421 100644 --- a/tools/mfd_aes_brute/mfd_aes_brute.c +++ b/tools/mfd_aes_brute/mfd_aes_brute.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "util_posix.h" #define AEND "\x1b[0m" diff --git a/tools/mfd_aes_brute/mfd_multi_brute.c b/tools/mfd_aes_brute/mfd_multi_brute.c index 226fd9f7f..b097c77d7 100644 --- a/tools/mfd_aes_brute/mfd_multi_brute.c +++ b/tools/mfd_aes_brute/mfd_multi_brute.c @@ -35,6 +35,7 @@ #include #include #include +#include //#include #include "util_posix.h" #include "randoms.h" From 492a09f5ccd6300df003233a96cbfb34dcea1632 Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 22 Jun 2023 22:51:16 +0200 Subject: [PATCH 12/68] correct LEGIC 16bit CRC calculation "hf legic crc", use init_table(CRC_LEGIC_16) to be consistent with l_crc16legic in client/src/scripting.c --- client/src/cmdhflegic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhflegic.c b/client/src/cmdhflegic.c index 02a43e0aa..b842ddf54 100644 --- a/client/src/cmdhflegic.c +++ b/client/src/cmdhflegic.c @@ -682,7 +682,7 @@ static int CmdLegicCalcCrc(const char *Cmd) { switch (type) { case 16: - init_table(CRC_LEGIC); + init_table(CRC_LEGIC_16); PrintAndLogEx(SUCCESS, "Legic crc16: %X", crc16_legic(data, data_len, mcc[0])); break; default: From 59a2b63d6be3138f6d60d06c0ac5fc074a2842bd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 06:56:05 +0200 Subject: [PATCH 13/68] thanks to user Hawkeye which tested on old conference badges on a NTAG216 --- client/dictionaries/t55xx_default_pwds.dic | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/dictionaries/t55xx_default_pwds.dic b/client/dictionaries/t55xx_default_pwds.dic index e56904ea4..9231b9314 100644 --- a/client/dictionaries/t55xx_default_pwds.dic +++ b/client/dictionaries/t55xx_default_pwds.dic @@ -52,6 +52,8 @@ C0F5009A # prefered pwds of members in the community FEEDBEEF DEADC0DE +# derived from BCARD key B +A9EF2AFC # Default pwd, simple: 00000000 11111111 From db4086718d43a6679afcdb052bed1dcce0cfdd17 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 13:37:37 +0200 Subject: [PATCH 14/68] kety length checks for hf mf rdbl, rdsc, wrbl, and some textual changes to hf mf mad --- client/src/cmdhfmf.c | 66 ++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 6aac4677c..066e1bdfd 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -785,7 +785,8 @@ static int CmdHF14AMfWrBl(const char *Cmd) { " \n" "`--force` param is used to override warnings like bad ACL and BLOCK 0 writes.\n" " if not specified, it will exit if detected", - "hf mf wrbl --blk 1 -k FFFFFFFFFFFF -d 000102030405060708090a0b0c0d0e0f" + "hf mf wrbl --blk 1 -d 000102030405060708090a0b0c0d0e0f\n" + "hf mf wrbl --blk 1 -k A0A1A2A3A4A5 -d 000102030405060708090a0b0c0d0e0f\n" ); void *argtable[] = { arg_param_begin, @@ -813,7 +814,7 @@ static int CmdHF14AMfWrBl(const char *Cmd) { bool force = arg_get_lit(ctx, 4); int keylen = 0; - uint8_t key[6] = {0}; + uint8_t key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; CLIGetHexWithReturn(ctx, 5, key, &keylen); uint8_t block[MFBLOCK_SIZE] = {0x00}; @@ -821,6 +822,11 @@ static int CmdHF14AMfWrBl(const char *Cmd) { CLIGetHexWithReturn(ctx, 6, block, &blen); CLIParserFree(ctx); + if (keylen && keylen != 6) { + PrintAndLogEx(WARNING, "Key must be 12 hex digits. Got %d", keylen); + return PM3_EINVARG; + } + if (blen != MFBLOCK_SIZE) { PrintAndLogEx(WARNING, "block data must include 16 HEX bytes. Got %i", blen); return PM3_EINVARG; @@ -879,7 +885,8 @@ static int CmdHF14AMfRdBl(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf rdbl", "Read MIFARE Classic block", - "hf mf rdbl --blk 0 -k FFFFFFFFFFFF\n" + "hf mf rdbl --blk 0\n" + "hf mf rdbl --blk 0 -k A0A1A2A3A4A5\n" "hf mf rdbl --blk 3 -v -> get block 3, decode sector trailer\n" ); void *argtable[] = { @@ -904,11 +911,16 @@ static int CmdHF14AMfRdBl(const char *Cmd) { } int keylen = 0; - uint8_t key[6] = {0}; + uint8_t key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; CLIGetHexWithReturn(ctx, 4, key, &keylen); bool verbose = arg_get_lit(ctx, 5); CLIParserFree(ctx); + if (keylen && keylen != 6) { + PrintAndLogEx(WARNING, "Key must be 12 hex digits. Got %d", keylen); + return PM3_EINVARG; + } + if (b > 255) { return PM3_EINVARG; } @@ -934,7 +946,8 @@ static int CmdHF14AMfRdSc(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf rdsc", "Read MIFARE Classic sector", - "hf mf rdsc -s 0 -k FFFFFFFFFFFF\n" + "hf mf rdsc -s 0\n" + "hf mf rdsc -s 0 -k A0A1A2A3A4A5\n" ); void *argtable[] = { arg_param_begin, @@ -956,17 +969,23 @@ static int CmdHF14AMfRdSc(const char *Cmd) { } int keylen = 0; - uint8_t key[6] = {0}; + uint8_t key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; CLIGetHexWithReturn(ctx, 3, key, &keylen); int s = arg_get_int_def(ctx, 4, 0); bool verbose = arg_get_lit(ctx, 5); CLIParserFree(ctx); + if (keylen && keylen != 6) { + PrintAndLogEx(WARNING, "Key must be 12 hex digits. Got %d", keylen); + return PM3_EINVARG; + } + if (s > MIFARE_4K_MAXSECTOR) { PrintAndLogEx(WARNING, "Sector number must be less then 40"); return PM3_EINVARG; } + uint8_t sector = (uint8_t)s; uint16_t sc_size = mfNumBlocksPerSector(sector) * MFBLOCK_SIZE; @@ -1266,7 +1285,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { return PM3_ESOFT; } - PrintAndLogEx(INFO, "Using `" _YELLOW_("%s") "`", keyfilename); + PrintAndLogEx(INFO, "Using key file... `" _YELLOW_("%s") "`", keyfilename); // try reading card uid and create filename if (datafnlen == 0) { @@ -5679,7 +5698,6 @@ static int CmdHF14AMfMAD(const char *Cmd) { block_cnt = MIFARE_4K_MAXBLOCK; if (verbose) { - PrintAndLogEx(INFO, "File: " _YELLOW_("%s"), filename); PrintAndLogEx(INFO, "File size %zu bytes, file blocks %d (0x%x)", bytes_read, block_cnt, block_cnt); } @@ -5733,6 +5751,11 @@ static int CmdHF14AMfMAD(const char *Cmd) { PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, _CYAN_("VIGIK PACS detected")); } + + if (haveMAD2) { + MAD2DecodeAndPrint(dump + (MIFARE_1K_MAXBLOCK * MF_MAD2_SECTOR), swapmad, verbose); + } + free(dump); return PM3_SUCCESS; } @@ -5916,8 +5939,9 @@ int CmdHFMFNDEFRead(const char *Cmd) { uint8_t data[4096] = {0}; int datalen = 0; - if (verbose) + if (verbose) { PrintAndLogEx(INFO, "reading MAD v1 sector"); + } if (mfReadSector(MF_MAD1_SECTOR, MF_KEY_A, g_mifare_mad_key, sector0)) { PrintAndLogEx(ERR, "error, read sector 0. card doesn't have MAD or doesn't have MAD on default keys"); @@ -5925,24 +5949,24 @@ int CmdHFMFNDEFRead(const char *Cmd) { return PM3_ESOFT; } + if (verbose) { + PrintAndLogEx(INFO, "reading MAD v2 sector"); + } + + if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, g_mifare_mad_key, sector10)) { + if (verbose) { + PrintAndLogEx(ERR, "error, read sector 0x10. card doesn't have MAD 2 or doesn't have MAD 2 on default keys"); + PrintAndLogEx(INFO, "Skipping MAD 2"); + } + } + bool haveMAD2 = false; - int res = MADCheck(sector0, NULL, verbose, &haveMAD2); + int res = MADCheck(sector0, sector10, verbose, &haveMAD2); if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "MAD error %d", res); return res; } - if (haveMAD2) { - if (verbose) - PrintAndLogEx(INFO, "reading MAD v2 sector"); - - if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, g_mifare_mad_key, sector10)) { - PrintAndLogEx(ERR, "error, read sector 0x10. card doesn't have MAD or doesn't have MAD on default keys"); - PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndefread -k `") " with your custom key"); - return PM3_ESOFT; - } - } - uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; size_t madlen = 0; res = MADDecode(sector0, (haveMAD2 ? sector10 : NULL), mad, &madlen, false); From 7fe02233d82cc8fb49d2ca144348924d2016b595 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 13:56:59 +0200 Subject: [PATCH 15/68] textual changes to MAD output --- client/src/mifare/mad.c | 47 +++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/client/src/mifare/mad.c b/client/src/mifare/mad.c index c870dbb28..42a05c5a2 100644 --- a/client/src/mifare/mad.c +++ b/client/src/mifare/mad.c @@ -190,7 +190,7 @@ int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2) uint8_t GPB = sector0[(3 * 16) + 9]; if (verbose) - PrintAndLogEx(SUCCESS, "%14s " _GREEN_("0x%02x"), "GPB", GPB); + PrintAndLogEx(SUCCESS, "GPB....... " _GREEN_("0x%02X"), GPB); // DA (MAD available) if (!(GPB & 0x80)) { @@ -200,21 +200,22 @@ int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2) uint8_t mad_ver = GPB & 0x03; if (verbose) - PrintAndLogEx(SUCCESS, "%14s " _GREEN_("%d"), "MAD version", mad_ver); + PrintAndLogEx(SUCCESS, "Version... " _GREEN_("%d"), mad_ver); // MAD version if ((mad_ver != 0x01) && (mad_ver != 0x02)) { - PrintAndLogEx(ERR, "Wrong MAD version " _RED_("0x%02x"), mad_ver); + PrintAndLogEx(ERR, "Wrong MAD version " _RED_("0x%02X"), mad_ver); return PM3_ESOFT; }; - if (haveMAD2) + if (haveMAD2) { *haveMAD2 = (mad_ver == 2); + } int res = madCRCCheck(sector0, true, 1); - - if (verbose && res == PM3_SUCCESS) - PrintAndLogEx(SUCCESS, "%14s " _GREEN_("0x%02x") " ( %s )", "CRC8", sector0[16], _GREEN_("ok")); + if (verbose && res == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "CRC8...... 0x%02X ( %s )", sector0[16], _GREEN_("ok")); + } if (mad_ver == 2 && sector10) { int res2 = madCRCCheck(sector10, true, 2); @@ -222,7 +223,7 @@ int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2) res = res2; if (verbose && !res2) - PrintAndLogEx(SUCCESS, "%14s " _GREEN_("0x%02x") " ( %s )", "CRC8", sector10[0], _GREEN_("ok")); + PrintAndLogEx(SUCCESS, "CRC8...... 0x%02X ( %s )", sector10[0], _GREEN_("ok")); } // MA (multi-application card) @@ -284,9 +285,10 @@ static int MADInfoByteDecode(const uint8_t *sector, bool swapmad, int mad_ver, b info = sector[16 + 1] & 0x3f; if (info >= 0xF) { PrintAndLogEx(WARNING, "Invalid Info byte (MAD1) value " _YELLOW_("0x%02x"), info); - if (verbose) + if (verbose) { // I understand the spec in a way that MAD1 InfoByte should not point into MAD2 sectors, @lukaskuzmiak PrintAndLogEx(WARNING, "MAD1 Info byte points outside of MAD1 sector space (0x%02x), report a bug?", info); + } return PM3_ESOFT; } } else { @@ -318,7 +320,7 @@ int MAD1DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose, bool *haveMA int ibs = MADInfoByteDecode(sector, swapmad, 1, verbose); if (ibs > 0) { - PrintAndLogEx(SUCCESS, "Card publisher sector " _MAGENTA_("0x%02x"), ibs); + PrintAndLogEx(SUCCESS, "Card publisher sector " _MAGENTA_("0x%02X"), ibs); } else { PrintAndLogEx(WARNING, "Card publisher " _RED_("not") " present " _YELLOW_("0x%02x"), ibs); } @@ -356,7 +358,7 @@ int MAD1DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose, bool *haveMA } int MAD2DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose) { - open_mad_file(&mad_known_aids, verbose); + open_mad_file(&mad_known_aids, false); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "------------ " _CYAN_("MAD v2 details") " -------------"); @@ -364,14 +366,14 @@ int MAD2DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose) { int res = madCRCCheck(sector, true, 2); if (verbose) { if (res == PM3_SUCCESS) - PrintAndLogEx(SUCCESS, "CRC8 ( %s )", _GREEN_("ok")); + PrintAndLogEx(SUCCESS, "CRC8...... 0x%02X ( " _GREEN_("%s") " )", sector[0], "ok"); else - PrintAndLogEx(WARNING, "CRC8 ( %s )", _RED_("fail")); + PrintAndLogEx(SUCCESS, "CRC8...... 0x%02X ( " _RED_("%s") " )", sector[0], "fail"); } int ibs = MADInfoByteDecode(sector, swapmad, 2, verbose); if (ibs > 0) { - PrintAndLogEx(SUCCESS, "Card publisher sector " _MAGENTA_("0x%02x"), ibs); + PrintAndLogEx(SUCCESS, "Card publisher sector " _MAGENTA_("0x%02X"), ibs); } else { PrintAndLogEx(WARNING, "Card publisher " _RED_("not") " present " _YELLOW_("0x%02x"), ibs); } @@ -385,12 +387,21 @@ int MAD2DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose) { for (int i = 1; i < 8 + 8 + 7 + 1; i++) { uint16_t aid = madGetAID(sector, swapmad, 2, i); if (aid < 6) { - PrintAndLogEx(INFO, (ibs == i) ? _MAGENTA_(" %02d [%04X] (%s)") : " %02d [%04X] (%s)", i + 16, aid, aid_admin[aid]); + PrintAndLogEx(INFO, + (ibs == i) ? _MAGENTA_(" %02d [%04X] %s") : " %02d [" _GREEN_("%04X") "] %s", + i + 16, + aid, + aid_admin[aid] + ); } else if (prev_aid == aid) { - PrintAndLogEx(INFO, (ibs == i) ? _MAGENTA_(" %02d [%04X] (continuation)") : " %02d [%04X] (continuation)", i + 16, aid); + PrintAndLogEx(INFO, + (ibs == i) ? _MAGENTA_(" %02d [%04X] continuation") : " %02d [" _YELLOW_("%04X") "] continuation", + i + 16, + aid + ); } else { - char fmt[30]; - snprintf(fmt, sizeof(fmt), (ibs == i) ? _MAGENTA_(" %02d [%04X]%s") : " %02d [%04X]%s", i + 16, aid, "%s"); + char fmt[60]; + snprintf(fmt, sizeof(fmt), (ibs == i) ? _MAGENTA_(" %02d [%04X]%s") : " %02d [" _GREEN_("%04X") "]%s", i + 16, aid, "%s"); print_aid_description(mad_known_aids, aid, fmt, verbose); prev_aid = aid; } From 673f15c247eb1c7875790a712f19d847b734097d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 14:19:50 +0200 Subject: [PATCH 16/68] text --- client/dictionaries/t55xx_default_pwds.dic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/dictionaries/t55xx_default_pwds.dic b/client/dictionaries/t55xx_default_pwds.dic index 9231b9314..fc9c6bb8b 100644 --- a/client/dictionaries/t55xx_default_pwds.dic +++ b/client/dictionaries/t55xx_default_pwds.dic @@ -37,7 +37,7 @@ A5B4C3D2 E9920427 # paxton bullit? 575F4F4B -# +# Hotel system 50520901 # iCopy-X 20206666 From 419d0c1f5b793d1c8d66d516e6235c99c764445c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 16:25:43 +0200 Subject: [PATCH 17/68] adapt return codes for some mifare commands and their debug logging. this will reduce debug message on the client side --- armsrc/mifarecmd.c | 39 +++++++++++++++++--------------- armsrc/mifareutil.c | 45 +++++++++++++++++++------------------ client/src/mifare/mifare4.c | 16 ++++++------- 3 files changed, 52 insertions(+), 48 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 5dd5dfcf6..4d57ef0ce 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -484,8 +484,8 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { if (res == PM3_ETEAROFF) { retval = PM3_ETEAROFF; goto OUT; - } else if (res) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error"); + } else if (res != PM3_SUCCESS) { + if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error"); retval = PM3_ESOFT; goto OUT; } @@ -554,7 +554,7 @@ void MifareWriteBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key, uint8_t if (res == PM3_ETEAROFF) { retval = PM3_ETEAROFF; goto OUT; - } else if (res) { + } else if (res != PM3_SUCCESS) { retval = PM3_ESOFT; goto OUT; } @@ -688,8 +688,8 @@ void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) { break; }; - if (mifare_classic_value(pcs, cuid, blockNo, blockdata, action)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error"); + if (mifare_classic_value(pcs, cuid, blockNo, blockdata, action) != PM3_SUCCESS) { + if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error"); break; }; @@ -777,8 +777,8 @@ static void MifareUWriteBlockEx(uint8_t arg0, uint8_t arg1, uint8_t *datain, boo } } - if (mifare_ultra_writeblock(blockNo, blockdata)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error"); + if (mifare_ultra_writeblock(blockNo, blockdata) != PM3_SUCCESS) { + if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error"); OnError(0); return; }; @@ -851,8 +851,8 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t arg1, uint8_t *datain) { } } - if (mifare_ultra_writeblock_compat(blockNo, blockdata)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error"); + if (mifare_ultra_writeblock_compat(blockNo, blockdata) != PM3_SUCCESS) { + if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error"); OnError(0); return; }; @@ -896,8 +896,8 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) { blockdata[1] = pwd[6]; blockdata[2] = pwd[5]; blockdata[3] = pwd[4]; - if (mifare_ultra_writeblock(44, blockdata)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error"); + if (mifare_ultra_writeblock(44, blockdata) != PM3_SUCCESS) { + if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error"); OnError(44); return; }; @@ -906,8 +906,8 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) { blockdata[1] = pwd[2]; blockdata[2] = pwd[1]; blockdata[3] = pwd[0]; - if (mifare_ultra_writeblock(45, blockdata)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error"); + if (mifare_ultra_writeblock(45, blockdata) != PM3_SUCCESS) { + if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error"); OnError(45); return; }; @@ -916,8 +916,8 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) { blockdata[1] = pwd[14]; blockdata[2] = pwd[13]; blockdata[3] = pwd[12]; - if (mifare_ultra_writeblock(46, blockdata)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error"); + if (mifare_ultra_writeblock(46, blockdata) != PM3_SUCCESS) { + if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error"); OnError(46); return; }; @@ -926,8 +926,8 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) { blockdata[1] = pwd[10]; blockdata[2] = pwd[9]; blockdata[3] = pwd[8]; - if (mifare_ultra_writeblock(47, blockdata)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error"); + if (mifare_ultra_writeblock(47, blockdata) != PM3_SUCCESS) { + if (g_dbglevel >= DBG_INFO) Dbprintf("Write block error"); OnError(47); return; }; @@ -1522,7 +1522,6 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, target_ks[0] = nt2 ^ target_nt[0]; // second collection - if (mifare_classic_halt(pcs, cuid)) { continue; } @@ -2836,6 +2835,10 @@ OUT: crypto1_deinit(pcs); } +// FUDAN card w static encrypted nonces +// 2B F9 1C 1B D5 08 48 48 03 A4 B1 B1 75 FF 2D 90 +// ^^ ^^ + void OnSuccessMagic(void) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 472c2616f..7296f1abe 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -434,7 +434,7 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); - return 1; + return PM3_EFAILED; } uint8_t d_block[18], d_block_enc[18]; @@ -465,11 +465,11 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3; if ((len != 1) || (res != 0x0A)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd send data2 Error: %02x", res); - return 2; + if (g_dbglevel >= DBG_INFO) Dbprintf("Cmd send data2 Error: %02x", res); + return PM3_EFAILED; } } - return 0; + return PM3_SUCCESS; } int mifare_classic_write_cfg_block_gdm(struct Crypto1State *pcs, uint32_t uid, uint8_t *blockData) { @@ -480,7 +480,7 @@ int mifare_classic_write_cfg_block_gdm(struct Crypto1State *pcs, uint32_t uid, u uint16_t len = mifare_sendcmd_short(pcs, 1, MIFARE_MAGIC_GDM_WRITE_CFG, 0, receivedAnswer, receivedAnswerPar, NULL); if ((len != 1) || (receivedAnswer[0] != 0x0A)) { - return 1; + return PM3_EFAILED; } uint8_t d_block[18], d_block_enc[18]; @@ -511,14 +511,12 @@ int mifare_classic_write_cfg_block_gdm(struct Crypto1State *pcs, uint32_t uid, u res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3; if ((len != 1) || (res != 0x0A)) { - return 2; + return PM3_EFAILED; } } - return 0; + return PM3_SUCCESS; } - - int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, uint8_t action) { // variables uint16_t len = 0; @@ -540,8 +538,8 @@ int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo len = mifare_sendcmd_short(pcs, 1, command, blockNo, receivedAnswer, receivedAnswerPar, NULL); if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK - if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); - return 1; + if (g_dbglevel >= DBG_INFO) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); + return PM3_EFAILED; } memcpy(d_block, blockData, 4); @@ -566,12 +564,12 @@ int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3; if ((len != 1) || (res != 0x0A)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd send data2 Error: %02x", res); - return 2; + if (g_dbglevel >= DBG_INFO) Dbprintf("Cmd send data2 Error: %02x", res); + return PM3_EFAILED; } } - return 0; + return PM3_SUCCESS; } int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) { @@ -585,9 +583,10 @@ int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) { len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK - if (g_dbglevel >= DBG_ERROR) + if (g_dbglevel >= DBG_INFO) { Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0], len); - return 1; + } + return PM3_EFAILED; } memcpy(d_block, blockData, 16); @@ -599,11 +598,12 @@ int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) { len = ReaderReceive(receivedAnswer, receivedAnswerPar); if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK - if (g_dbglevel >= DBG_ERROR) + if (g_dbglevel >= DBG_INFO) { Dbprintf("Cmd Send Data Error: %02x %d", receivedAnswer[0], len); - return 2; + } + return PM3_EFAILED; } - return 0; + return PM3_SUCCESS; } int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) { @@ -618,11 +618,12 @@ int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) { len = mifare_sendcmd(MIFARE_ULC_WRITE, block, sizeof(block), receivedAnswer, receivedAnswerPar, NULL); if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK - if (g_dbglevel >= DBG_ERROR) + if (g_dbglevel >= DBG_INFO) { Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0], len); - return 1; + } + return PM3_EFAILED; } - return 0; + return PM3_SUCCESS; } int mifare_classic_halt_ex(struct Crypto1State *pcs) { uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00}; diff --git a/client/src/mifare/mifare4.c b/client/src/mifare/mifare4.c index ec8d1a6bf..52a5a8465 100644 --- a/client/src/mifare/mifare4.c +++ b/client/src/mifare/mifare4.c @@ -24,9 +24,9 @@ #include "ui.h" #include "crypto/libpcrypto.h" -static bool VerboseMode = false; +static bool g_verbose_mode = false; void mfpSetVerboseMode(bool verbose) { - VerboseMode = verbose; + g_verbose_mode = verbose; } static const PlusErrorsElm_t PlusErrors[] = { @@ -340,12 +340,12 @@ int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool acti } static int intExchangeRAW14aPlus(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { - if (VerboseMode) + if (g_verbose_mode) PrintAndLogEx(INFO, ">>> %s", sprint_hex(datain, datainlen)); int res = ExchangeRAW14a(datain, datainlen, activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen, false); - if (VerboseMode) + if (g_verbose_mode) PrintAndLogEx(INFO, "<<< %s", sprint_hex(dataout, *dataoutlen)); return res; @@ -367,7 +367,7 @@ int MFPCommitPerso(bool activateField, bool leaveSignalON, uint8_t *dataout, int int MFPReadBlock(mf4Session_t *mf4session, bool plain, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) { uint8_t rcmd[4 + 8] = {(plain ? (0x37) : (0x33)), blockNum, 0x00, blockCount}; if (!plain && mf4session) - CalculateMAC(mf4session, mtypReadCmd, blockNum, blockCount, rcmd, 4, &rcmd[4], VerboseMode); + CalculateMAC(mf4session, mtypReadCmd, blockNum, blockCount, rcmd, 4, &rcmd[4], g_verbose_mode); int res = intExchangeRAW14aPlus(rcmd, plain ? 4 : sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); if (res) @@ -377,7 +377,7 @@ int MFPReadBlock(mf4Session_t *mf4session, bool plain, uint8_t blockNum, uint8_t mf4session->R_Ctr++; if (mf4session && mac && *dataoutlen > 11) - CalculateMAC(mf4session, mtypReadResp, blockNum, blockCount, dataout, *dataoutlen - 8 - 2, mac, VerboseMode); + CalculateMAC(mf4session, mtypReadResp, blockNum, blockCount, dataout, *dataoutlen - 8 - 2, mac, g_verbose_mode); return 0; } @@ -386,7 +386,7 @@ int MFPWriteBlock(mf4Session_t *mf4session, uint8_t blockNum, uint8_t *data, boo uint8_t rcmd[1 + 2 + 16 + 8] = {0xA3, blockNum, 0x00}; memmove(&rcmd[3], data, 16); if (mf4session) - CalculateMAC(mf4session, mtypWriteCmd, blockNum, 1, rcmd, 19, &rcmd[19], VerboseMode); + CalculateMAC(mf4session, mtypWriteCmd, blockNum, 1, rcmd, 19, &rcmd[19], g_verbose_mode); int res = intExchangeRAW14aPlus(rcmd, sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); if (res) @@ -396,7 +396,7 @@ int MFPWriteBlock(mf4Session_t *mf4session, uint8_t blockNum, uint8_t *data, boo mf4session->W_Ctr++; if (mf4session && mac && *dataoutlen > 3) - CalculateMAC(mf4session, mtypWriteResp, blockNum, 1, dataout, *dataoutlen, mac, VerboseMode); + CalculateMAC(mf4session, mtypWriteResp, blockNum, 1, dataout, *dataoutlen, mac, g_verbose_mode); return 0; } From ed34453461c59c3037980684da86f66e7058952f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 16:27:30 +0200 Subject: [PATCH 18/68] maur --- client/dictionaries/mfc_default_keys.dic | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 63598f78b..0d34541ff 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -145,6 +145,9 @@ F1D83F964314 222222222222 27DD91F1FCF1 # +# Hotel system +505209016A1F +# # Directory and eventlog KeyB 2BA9621E0A36 # From 88e2618131f8c754b08dea86da2ce594433b5adf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 17:08:32 +0200 Subject: [PATCH 19/68] function to support figuring out if block 0-3 , 0-15 is sectortrailer. The previous function uses 0-255.. --- client/src/mifare/mifare4.c | 10 +++++++++- client/src/mifare/mifare4.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/client/src/mifare/mifare4.c b/client/src/mifare/mifare4.c index 52a5a8465..7a3ec9f77 100644 --- a/client/src/mifare/mifare4.c +++ b/client/src/mifare/mifare4.c @@ -534,7 +534,7 @@ uint8_t mfSectorTrailer(uint16_t blockNo) { if (blockNo < 32 * 4) { return (blockNo | 0x03); } else { - return (blockNo | 0x0f); + return (blockNo | 0x0F); } } @@ -551,3 +551,11 @@ uint8_t mfSectorNum(uint16_t blockNo) { return (32 + (blockNo - 32 * 4) / 16); } + +bool mfIsSectorTrailerBasedOnBlocks(uint8_t sectorno, uint16_t blockno) { + if (sectorno < 32) { + return ((blockno | 0x03) == blockno); + } else { + return ((blockno | 0x0F) == blockno); + } +} diff --git a/client/src/mifare/mifare4.h b/client/src/mifare/mifare4.h index 80d55db7b..fee12ef6e 100644 --- a/client/src/mifare/mifare4.h +++ b/client/src/mifare/mifare4.h @@ -79,6 +79,7 @@ uint8_t mfFirstBlockOfSector(uint8_t sectorNo); uint8_t mfSectorTrailerOfSector(uint8_t sectorNo); uint8_t mfSectorTrailer(uint16_t blockNo); bool mfIsSectorTrailer(uint16_t blockNo); +bool mfIsSectorTrailerBasedOnBlocks(uint8_t sectorno, uint16_t blockno); uint8_t mfSectorNum(uint16_t blockNo); From a508ed76464aef461dce708151dc280f957fa329 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 17:10:04 +0200 Subject: [PATCH 20/68] fix hf mf dump --- client/src/cmdhfmf.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 066e1bdfd..398705074 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -590,12 +590,13 @@ static int mfc_read_tag(iso14a_card_select_t *card, uint8_t *carddata, uint8_t n current_key = MF_KEY_A; uint8_t data_area = (sectorNo < 32) ? blockNo : blockNo / 5; if (rights[sectorNo][data_area] == 0x07) { // no key would work - PrintAndLogEx(WARNING, "access rights do not allow reading of sector %2d block %3d, skipping", sectorNo, blockNo); + PrintAndLogEx(WARNING, "access rights do not allow reading of sector " _YELLOW_("%2d") " block " _YELLOW_("%3d") ", skipping", sectorNo, blockNo); continue; } for (uint8_t tries = 0; tries < MIFARE_SECTOR_RETRY; tries++) { - if (mfIsSectorTrailer(blockNo)) { + + if (mfIsSectorTrailerBasedOnBlocks(sectorNo, blockNo)) { // sector trailer. At least the Access Conditions can always be read with key A. payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo; @@ -649,16 +650,16 @@ static int mfc_read_tag(iso14a_card_select_t *card, uint8_t *carddata, uint8_t n uint8_t *data = resp.data.asBytes; - if (mfIsSectorTrailer(blockNo)) { + if (mfIsSectorTrailerBasedOnBlocks(sectorNo, blockNo)) { // sector trailer. Fill in the keys. memcpy(data, keyA + (sectorNo * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); memcpy(data + 10, keyB + (sectorNo * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); } memcpy(carddata + (MFBLOCK_SIZE * (mfFirstBlockOfSector(sectorNo) + blockNo)), data, MFBLOCK_SIZE); - PrintAndLogEx(SUCCESS, "successfully read block %2d of sector %2d.", blockNo, sectorNo); + PrintAndLogEx(INPLACE, "successfully read block " _YELLOW_("%2d") " of sector " _YELLOW_("%2d"), blockNo, sectorNo); } else { - PrintAndLogEx(FAILED, "could not read block %2d of sector %2d", blockNo, sectorNo); + PrintAndLogEx(FAILED, "\ncould not read block %2d of sector %2d", blockNo, sectorNo); } } else { PrintAndLogEx(WARNING, "command execute timeout when trying to read block %2d of sector %2d.", blockNo, sectorNo); @@ -1125,7 +1126,7 @@ static int CmdHF14AMfDump(const char *Cmd) { // read card iso14a_card_select_t card ; - uint8_t *mem = calloc(MIFARE_4K_MAXBLOCK * MFBLOCK_SIZE, sizeof(uint8_t)); + uint8_t *mem = calloc(MIFARE_4K_MAX_BYTES, sizeof(uint8_t)); if (mem == NULL) { PrintAndLogEx(ERR, "failed to allocate memory"); return PM3_EMALLOC; From 4b12d67632fbbedfebb986811a988d1939a054ca Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 17:12:29 +0200 Subject: [PATCH 21/68] text and fixes for MAD v2 --- client/src/cmdhfmf.c | 72 ++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 398705074..031341c71 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -3446,6 +3446,7 @@ static int CmdHF14AMfChk(const char *Cmd) { PrintAndLogEx(WARNING, "Provided block out of possible MIFARE Type memory map"); return PM3_EINVARG; } + if (sectors_cnt == 1) { sectors_cnt = min_sectors_cnt; } else if (sectors_cnt < min_sectors_cnt) { @@ -3453,6 +3454,7 @@ static int CmdHF14AMfChk(const char *Cmd) { return PM3_EINVARG; } } + if (sectors_cnt == 1) { sectors_cnt = MIFARE_1K_MAXSECTOR; } @@ -3520,6 +3522,7 @@ static int CmdHF14AMfChk(const char *Cmd) { } if (singleSector) break; + b < 127 ? (b += 4) : (b += 16); } } @@ -3974,6 +3977,7 @@ void printKeyTableEx(size_t sectorscnt, sector_t *e_sector, uint8_t start_sector , strA, resA , strB, resB ); + } PrintAndLogEx(SUCCESS, "-----+-----+--------------+---+--------------+----"); @@ -5614,28 +5618,27 @@ static int CmdHF14AMfAuth4(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf auth4", "Executes AES authentication command in ISO14443-4", - "hf mf auth4 4000 000102030405060708090a0b0c0d0e0f -> executes authentication\n" - "hf mf auth4 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> executes authentication\n"); + "hf mf auth4 -n 4000 -k 000102030405060708090a0b0c0d0e0f -> executes authentication\n" + "hf mf auth4 -n 9003 -k FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> executes authentication\n"); void *argtable[] = { arg_param_begin, - arg_str1(NULL, NULL, "", NULL), - arg_str1(NULL, NULL, "", NULL), + arg_str1("n", NULL, "", "key num, 2 hex bytes"), + arg_str1("k", "key", "", "key, 16 hex bytes"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); - CLIGetHexWithReturn(ctx, 1, keyn, &keynlen); CLIGetHexWithReturn(ctx, 2, key, &keylen); CLIParserFree(ctx); if (keynlen != 2) { - PrintAndLogEx(ERR, " must be 2 bytes long instead of: %d", keynlen); + PrintAndLogEx(ERR, "Key number must be 2 bytes. Got... %d", keynlen); return PM3_ESOFT; } if (keylen != 16) { - PrintAndLogEx(ERR, " must be 16 bytes long instead of: %d", keylen); + PrintAndLogEx(ERR, "Key must be 16 bytes. Got... %d", keylen); return PM3_ESOFT; } @@ -5655,12 +5658,12 @@ static int CmdHF14AMfMAD(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("v", "verbose", "show technical data"), - arg_str0(NULL, "aid", "", "print all sectors with specified aid"), - arg_str0("k", "key", "", "key for printing sectors"), + arg_str0(NULL, "aid", "", "print all sectors with specified aid"), + arg_str0("k", "key", "", "key for printing sectors"), arg_lit0("b", "keyb", "use key B for access printing sectors (by default: key A)"), arg_lit0(NULL, "be", "(optional, BigEndian)"), arg_lit0(NULL, "dch", "decode Card Holder information"), - arg_str0("f", "file", "", "load dump file and decode MAD"), + arg_str0("f", "file", "", "load dump file and decode MAD"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -5685,17 +5688,17 @@ static int CmdHF14AMfMAD(const char *Cmd) { // read dump file uint8_t *dump = NULL; size_t bytes_read = 0; - int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK)); + int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, MIFARE_4K_MAX_BYTES); if (res != PM3_SUCCESS) { return res; } uint16_t block_cnt = MIN(MIFARE_1K_MAXBLOCK, (bytes_read / MFBLOCK_SIZE)); - if (bytes_read == 320) + if (bytes_read == MIFARE_MINI_MAX_BYTES) block_cnt = MIFARE_MINI_MAXBLOCK; - else if (bytes_read == 2048) + else if (bytes_read == MIFARE_2K_MAX_BYTES) block_cnt = MIFARE_2K_MAXBLOCK; - else if (bytes_read == 4096) + else if (bytes_read == MIFARE_4K_MAX_BYTES) block_cnt = MIFARE_4K_MAXBLOCK; if (verbose) { @@ -5765,8 +5768,8 @@ static int CmdHF14AMfMAD(const char *Cmd) { return PM3_ENOTTY; - uint8_t sector0[16 * 4] = {0}; - uint8_t sector10[16 * 4] = {0}; + uint8_t sector0[MFBLOCK_SIZE * 4] = {0}; + uint8_t sector10[MFBLOCK_SIZE * 4] = {0}; bool got_first = true; if (mfReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector0) != PM3_SUCCESS) { @@ -5820,7 +5823,7 @@ static int CmdHF14AMfMAD(const char *Cmd) { // user specified key if (keylen == 6) { - memcpy(akey, userkey, 6); + memcpy(akey, userkey, sizeof(akey)); } uint16_t aaid = 0x0004; @@ -5833,7 +5836,7 @@ static int CmdHF14AMfMAD(const char *Cmd) { for (int i = 0; i < madlen; i++) { if (aaid == mad[i]) { - uint8_t vsector[16 * 4] = {0}; + uint8_t vsector[MFBLOCK_SIZE * 4] = {0}; if (mfReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, akey, vsector)) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(ERR, "error, read sector %d", i + 1); @@ -5841,7 +5844,7 @@ static int CmdHF14AMfMAD(const char *Cmd) { } for (int j = 0; j < (verbose ? 4 : 3); j ++) - PrintAndLogEx(NORMAL, " [%03d] %s", (i + 1) * 4 + j, sprint_hex(&vsector[j * 16], 16)); + PrintAndLogEx(NORMAL, " [%03d] %s", (i + 1) * 4 + j, sprint_hex(&vsector[j * MFBLOCK_SIZE], MFBLOCK_SIZE)); } } } @@ -5851,21 +5854,22 @@ static int CmdHF14AMfMAD(const char *Cmd) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "-------- " _CYAN_("Card Holder Info 0x%04x") " --------", aaid); - uint8_t data[4096] = {0}; + uint8_t data[MIFARE_4K_MAX_BYTES] = {0}; int datalen = 0; for (int i = 0; i < madlen; i++) { if (aaid == mad[i]) { - uint8_t vsector[16 * 4] = {0}; + uint8_t vsector[MFBLOCK_SIZE * 4] = {0}; if (mfReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, akey, vsector)) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(ERR, "error, read sector %d", i + 1); return PM3_ESOFT; } - memcpy(&data[datalen], vsector, 16 * 3); - datalen += 16 * 3; + // skip ST block hence only 3 blocks copy + memcpy(&data[datalen], vsector, MFBLOCK_SIZE * 3); + datalen += MFBLOCK_SIZE * 3; } } @@ -5879,9 +5883,16 @@ static int CmdHF14AMfMAD(const char *Cmd) { if (verbose) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "------------ " _CYAN_("MAD sector raw") " -------------"); - for (int i = 0; i < 4; i ++) - PrintAndLogEx(INFO, "[%d] %s", i, sprint_hex(§or0[i * 16], 16)); + PrintAndLogEx(INFO, "------------ " _CYAN_("MAD v1 sector raw") " -------------"); + for (int i = 0; i < 4; i ++) { + PrintAndLogEx(INFO, "[%d] %s", i, sprint_hex(§or0[i * MFBLOCK_SIZE], MFBLOCK_SIZE)); + } + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "------------ " _CYAN_("MAD v2 sector raw") " -------------"); + for (int i = 0; i < 4; i ++) { + PrintAndLogEx(INFO, "[%d] %s", i, sprint_hex(§or10[i * MFBLOCK_SIZE], MFBLOCK_SIZE)); + } } return PM3_SUCCESS; @@ -5912,12 +5923,15 @@ int CmdHFMFNDEFRead(const char *Cmd) { bool verbose = arg_get_lit(ctx, 1); bool verbose2 = arg_get_lit(ctx, 1) > 1; uint8_t aid[2] = {0}; + int aidlen; CLIGetHexWithReturn(ctx, 2, aid, &aidlen); uint8_t key[6] = {0}; + int keylen; CLIGetHexWithReturn(ctx, 3, key, &keylen); bool keyB = arg_get_lit(ctx, 4); + int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; CLIParamStrToBuf(arg_get_str(ctx, 5), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); @@ -5970,7 +5984,7 @@ int CmdHFMFNDEFRead(const char *Cmd) { uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; size_t madlen = 0; - res = MADDecode(sector0, (haveMAD2 ? sector10 : NULL), mad, &madlen, false); + res = MADDecode(sector0, sector10, mad, &madlen, false); if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "can't decode MAD"); return res; @@ -6386,7 +6400,7 @@ int CmdHFMFNDEFWrite(const char *Cmd) { return PM3_ESOFT; } - // decode MAD + // decode MAD v1 uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; size_t madlen = 0; res = MADDecode(sector0, NULL, mad, &madlen, false); @@ -7130,7 +7144,7 @@ static int CmdHF14AMfView(const char *Cmd) { PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, _CYAN_("VIGIK PACS detected")); - // decode MAD + // decode MAD v1 uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; size_t madlen = 0; res = MADDecode(dump, NULL, mad, &madlen, false); From 8700b1e75451fe650b3807e2590895f1a3b91202 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 17:14:58 +0200 Subject: [PATCH 22/68] fix hf mf mad loading mad v2 sector --- client/src/cmdhfmf.c | 61 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 031341c71..9bc763624 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -3407,8 +3407,9 @@ static int CmdHF14AMfChk(const char *Cmd) { CLIParamStrToBuf(arg_get_str(ctx, 12), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); CLIParserFree(ctx); - bool singleSector = blockNo > -1; - if (! singleSector) { + + bool singleSector = (blockNo > -1); + if (singleSector == false) { // start from first trailer block blockNo = 3; } @@ -3431,9 +3432,11 @@ static int CmdHF14AMfChk(const char *Cmd) { } if (singleSector) { - size_t min_sectors_cnt = 0; + // find a MIFARE type that can accommodate the provided block number + size_t min_sectors_cnt = 0; uint8_t s = mfSectorNum(blockNo); + if (s < MIFARE_MINI_MAXSECTOR) { min_sectors_cnt = MIFARE_MINI_MAXSECTOR; } else if (s < MIFARE_1K_MAXSECTOR) { @@ -3578,9 +3581,9 @@ out: PrintAndLogEx(SUCCESS, _GREEN_("found keys:")); //print keys - if (singleSector) - printKeyTableEx(1, e_sector, mfSectorNum(blockNo)); - else +// if (singleSector) +// printKeyTableEx(1, e_sector, mfSectorNum(blockNo)); +// else printKeyTable(sectors_cnt, e_sector); if (transferToEml) { @@ -5760,6 +5763,25 @@ static int CmdHF14AMfMAD(const char *Cmd) { MAD2DecodeAndPrint(dump + (MIFARE_1K_MAXBLOCK * MF_MAD2_SECTOR), swapmad, verbose); } + if (aidlen == 2 || decodeholder) { + uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; + size_t madlen = 0; + if (MADDecode(dump, dump + (0x10 * MIFARE_1K_MAXBLOCK), mad, &madlen, swapmad)) { + PrintAndLogEx(ERR, "can't decode MAD"); + free(dump); + return PM3_ESOFT; + } + + uint16_t aaid = 0x0004; + if (aidlen == 2) { + aaid = (aid[0] << 8) + aid[1]; + } + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "-------- " _CYAN_("Card Holder Info 0x%04x") " --------", aaid); + + MADCardHolderInfoDecode(dump, bytes_read, verbose); + } free(dump); return PM3_SUCCESS; } @@ -5795,17 +5817,34 @@ static int CmdHF14AMfMAD(const char *Cmd) { return PM3_ESOFT; } + got_first = true; + if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector10) != PM3_SUCCESS) { + if (verbose) { + PrintAndLogEx(ERR, "error, read sector 0x10. card doesn't have MAD 2 or doesn't have MAD 2 on default keys"); + } + got_first = false; + } else { + PrintAndLogEx(INFO, "Authentication ( " _GREEN_("ok") " )"); + } + + // User supplied key + if (got_first == false && keylen == 6) { + PrintAndLogEx(INFO, "Trying user specified key..."); + if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, userkey, sector10) != PM3_SUCCESS) { + if (verbose) { + PrintAndLogEx(ERR, "error, read sector 10. card doesn't have MAD 2 or the custom key is wrong"); + } + } else { + PrintAndLogEx(INFO, "Authentication ( " _GREEN_("ok") " )"); + } + } + MADPrintHeader(); bool haveMAD2 = false; MAD1DecodeAndPrint(sector0, swapmad, verbose, &haveMAD2); if (haveMAD2) { - if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector10)) { - PrintAndLogEx(ERR, "error, read sector 0x10. card doesn't have MAD or doesn't have MAD on default keys"); - return PM3_ESOFT; - } - MAD2DecodeAndPrint(sector10, swapmad, verbose); } From 25f84bcb8e6171e0c71e72ec813890b0f7868c88 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 17:21:47 +0200 Subject: [PATCH 23/68] fix 14b detection in hf search --- client/src/cmdhf14b.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index d0083fbb5..77378fda2 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -2229,33 +2229,34 @@ int infoHF14B(bool verbose, bool do_aid_search) { // get and print general info about all known 14b chips int readHF14B(bool loop, bool verbose) { + bool found = false; do { // try std 14b (atqb) - if (HF14B_std_reader(verbose)) - if (loop) - continue; + found = HF14B_std_reader(verbose); + if (found && loop) + continue; // try ST Microelectronics 14b - if (HF14B_st_reader(verbose)) - if (loop) - continue; + found = HF14B_st_reader(verbose); + if (found && loop) + continue; // try ASK CT 14b - if (HF14B_ask_ct_reader(verbose)) - if (loop) - continue; + found = HF14B_ask_ct_reader(verbose); + if (found && loop) + continue; // try unknown 14b read commands (to be identified later) // could be read of calypso, CEPAS, moneo, or pico pass. - if (HF14B_other_reader(verbose)) - if (loop) - continue; - + found = HF14B_other_reader(verbose); + if (found && loop) + continue; } while (loop && kbd_enter_pressed() == false); - if (verbose) { + + if (verbose && found == false) { PrintAndLogEx(FAILED, "no ISO 14443-B tag found"); } - return PM3_EOPABORTED; + return (found) ? PM3_SUCCESS : PM3_EOPABORTED; } From d1b62a5fc21e755723b71d5b8f047b8c38f73a28 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 17:44:15 +0200 Subject: [PATCH 24/68] fix wrong sector trailer detection --- client/src/cmdhfmf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 9bc763624..130654caf 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -280,8 +280,8 @@ static void mf_print_blocks(uint16_t n, uint8_t *d, bool verbose) { PrintAndLogEx(NORMAL, ""); } +// assumes n is in number of blocks 0..255 static int mf_print_keys(uint16_t n, uint8_t *d) { - uint8_t sectors = 0; switch (n) { case MIFARE_MINI_MAXBLOCK: @@ -321,6 +321,7 @@ static int mf_print_keys(uint16_t n, uint8_t *d) { } // MFC dump , extract and save the keys to key file +// assumes n is in number of blocks 0..255 static int mf_save_keys_from_arr(uint16_t n, uint8_t *d) { uint8_t sectors = 0; switch (n) { @@ -412,6 +413,7 @@ static bool mf_write_block(const uint8_t *key, uint8_t keytype, uint8_t blockno, return (resp.oldarg[0] & 0xff); } +// assumes n is in number of blocks 0..255 static void mf_analyse_acl(uint16_t n, uint8_t *d) { for (uint16_t b = 3; b < n; b++) { @@ -6252,7 +6254,7 @@ skipfile: memcpy(block, firstblocks[b], MFBLOCK_SIZE); break; default: { - if (mfIsSectorTrailer(j)) { + if (mfIsSectorTrailerBasedOnBlocks(i,j)) { // ST NDEF memcpy(block, firstblocks[7], MFBLOCK_SIZE); } @@ -7078,7 +7080,7 @@ static int CmdHF14AMfWipe(const char *Cmd) { uint8_t data[26]; memset(data, 0, sizeof(data)); - if (mfIsSectorTrailer(b)) { + if (mfIsSectorTrailerBasedOnBlocks(s, b)) { memcpy(data + 10, st, sizeof(st)); } else { memcpy(data + 10, zeros, sizeof(zeros)); From 85d4e99ae9f552fb6632c7e693a0ced30bb3953e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 17:51:39 +0200 Subject: [PATCH 25/68] mfp changes... --- client/src/cmdhfmfp.c | 278 ++++++++++++++++++++++++++++-------------- client/src/cmdhfmfp.h | 20 +++ 2 files changed, 204 insertions(+), 94 deletions(-) diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 9434d88ed..2368e0f74 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -34,19 +34,12 @@ #include "protocols.h" #include "crypto/libpcrypto.h" #include "cmdhfmf.h" // printblock, header +#include "cmdtrace.h" -static const uint8_t DefaultKey[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -static uint16_t CardAddresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0xA000, 0xA001, 0xA080, 0xA081, 0xC000, 0xC001}; +static const uint8_t mfp_default_key[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +static uint16_t mfp_card_adresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0xA000, 0xA001, 0xA080, 0xA081, 0xC000, 0xC001}; -typedef enum { - MFP_UNKNOWN = 0, - DESFIRE_MF3ICD40, - DESFIRE_EV1, - DESFIRE_EV2, - DESFIRE_EV3, - DESFIRE_LIGHT, - PLUS_EV1, -} nxp_cardtype_t; +#define MFP_KEY_FILE_SIZE 14 + (2 * 64 * (AES_KEY_LEN + 1)) static int CmdHelp(const char *Cmd); @@ -233,9 +226,10 @@ static int get_plus_signature(uint8_t *signature, int *signature_len) { *signature_len = 0; retval = PM3_ESOFT; } - mfpSetVerboseMode(false); + return retval; } + // GET VERSION static int plus_print_version(uint8_t *version) { PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(version + 14, 7)); @@ -261,12 +255,12 @@ static int plus_print_version(uint8_t *version) { PrintAndLogEx(INFO, " Protocol: %s", getProtocolStr(version[13], false)); return PM3_SUCCESS; } + static int get_plus_version(uint8_t *version, int *version_len) { int resplen = 0, retval = PM3_SUCCESS; mfpSetVerboseMode(false); MFPGetVersion(true, false, version, *version_len, &resplen); - mfpSetVerboseMode(false); *version_len = resplen; if (resplen != 28) { @@ -484,16 +478,16 @@ static int CmdHFMFPWritePerso(const char *Cmd) { mfpSetVerboseMode(verbose); if (!keyLen) { - memmove(key, DefaultKey, 16); + memmove(key, mfp_default_key, 16); keyLen = 16; } if (keyNumLen != 2) { - PrintAndLogEx(ERR, "Key number length must be 2 bytes instead of: %d", keyNumLen); + PrintAndLogEx(ERR, "Key number length must be 2 bytes. Got %d", keyNumLen); return PM3_EINVARG; } if (keyLen != 16) { - PrintAndLogEx(ERR, "Key length must be 16 bytes instead of: %d", keyLen); + PrintAndLogEx(ERR, "Key length must be 16 bytes. Got %d", keyLen); return PM3_EINVARG; } @@ -507,7 +501,7 @@ static int CmdHFMFPWritePerso(const char *Cmd) { } if (datalen != 3) { - PrintAndLogEx(ERR, "Command must return 3 bytes instead of: %d", datalen); + PrintAndLogEx(ERR, "Command must return 3 bytes. Got %d", datalen); return PM3_ESOFT; } @@ -539,17 +533,18 @@ static int CmdHFMFPInitPerso(const char *Cmd) { bool verbose2 = arg_get_lit(ctx, 1) > 1; uint8_t key[256] = {0}; - int keyLen = 0; - CLIGetHexWithReturn(ctx, 2, key, &keyLen); + int keylen = 0; + CLIGetHexWithReturn(ctx, 2, key, &keylen); CLIParserFree(ctx); - if (keyLen && keyLen != 16) { - PrintAndLogEx(ERR, "Key length must be 16 bytes instead of: %d", keyLen); + if (keylen && keylen != 16) { + PrintAndLogEx(FAILED, "Key length must be 16 bytes. Got %d", keylen); return PM3_EINVARG; } - if (!keyLen) - memmove(key, DefaultKey, 16); + if (keylen == 0) { + memmove(key, mfp_default_key, sizeof(mfp_default_key)); + } uint8_t keyNum[2] = {0}; uint8_t data[250] = {0}; @@ -572,15 +567,15 @@ static int CmdHFMFPInitPerso(const char *Cmd) { } mfpSetVerboseMode(verbose); - for (int i = 0; i < ARRAYLEN(CardAddresses); i++) { - keyNum[0] = CardAddresses[i] >> 8; - keyNum[1] = CardAddresses[i] & 0xff; + for (int i = 0; i < ARRAYLEN(mfp_card_adresses); i++) { + keyNum[0] = mfp_card_adresses[i] >> 8; + keyNum[1] = mfp_card_adresses[i] & 0xff; res = MFPWritePerso(keyNum, key, false, true, data, sizeof(data), &datalen); if (!res && (datalen == 3) && data[0] == 0x09) { - PrintAndLogEx(WARNING, "Skipped[%04x]...", CardAddresses[i]); + PrintAndLogEx(WARNING, "Skipped[%04x]...", mfp_card_adresses[i]); } else { if (res || (datalen != 3) || data[0] != 0x90) { - PrintAndLogEx(ERR, "Write error on address %04x", CardAddresses[i]); + PrintAndLogEx(ERR, "Write error on address %04x", mfp_card_adresses[i]); break; } } @@ -597,7 +592,9 @@ static int CmdHFMFPInitPerso(const char *Cmd) { static int CmdHFMFPCommitPerso(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfp commitp", - "Executes Commit Perso command. Can be used in SL0 mode only.\nOBS! This command will not be executed if CardConfigKey, CardMasterKey and L3SwitchKey AES keys are not written.", + "Executes Commit Perso command. Can be used in SL0 mode only.\n" + "OBS! This command will not be executed if \n" + "CardConfigKey, CardMasterKey and L3SwitchKey AES keys are not written.", "hf mfp commitp\n" // "hf mfp commitp --sl 1" ); @@ -625,7 +622,7 @@ static int CmdHFMFPCommitPerso(const char *Cmd) { } if (datalen != 3) { - PrintAndLogEx(ERR, "Command must return 3 bytes instead of: %d", datalen); + PrintAndLogEx(ERR, "Command must return 3 bytes. Got %d", datalen); return PM3_EINVARG; } @@ -633,7 +630,7 @@ static int CmdHFMFPCommitPerso(const char *Cmd) { PrintAndLogEx(ERR, "Command error: %02x %s", data[0], mfpGetErrorDescription(data[0])); return PM3_EINVARG; } - PrintAndLogEx(INFO, "Switch level ( " _GREEN_("ok") " )"); + PrintAndLogEx(INFO, "Switched security level ( " _GREEN_("ok") " )"); return PM3_SUCCESS; } @@ -645,7 +642,7 @@ static int CmdHFMFPAuth(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfp auth", - "Executes AES authentication command for Mifare Plus card", + "Executes AES authentication command for MIFARE Plus card", "hf mfp auth --ki 4000 --key 000102030405060708090a0b0c0d0e0f -> executes authentication\n" "hf mfp auth --ki 9003 --key FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -v -> executes authentication and shows all the system data"); @@ -664,12 +661,12 @@ static int CmdHFMFPAuth(const char *Cmd) { CLIParserFree(ctx); if (keynlen != 2) { - PrintAndLogEx(ERR, "ERROR: must be 2 bytes long instead of: %d", keynlen); + PrintAndLogEx(ERR, "ERROR: must be 2 bytes. Got %d", keynlen); return PM3_EINVARG; } if (keylen != 16) { - PrintAndLogEx(ERR, "ERROR: must be 16 bytes long instead of: %d", keylen); + PrintAndLogEx(ERR, "ERROR: must be 16 bytes. Got %d", keylen); return PM3_EINVARG; } @@ -679,7 +676,7 @@ static int CmdHFMFPAuth(const char *Cmd) { static int CmdHFMFPRdbl(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfp rdbl", - "Reads several blocks from Mifare Plus card", + "Reads blocks from MIFARE Plus card", "hf mfp rdbl --blk 0 --key 000102030405060708090a0b0c0d0e0f -> executes authentication and read block 0 data\n" "hf mfp rdbl --blk 1 -v -> executes authentication and shows sector 1 data with default key 0xFF..0xFF"); @@ -710,23 +707,23 @@ static int CmdHFMFPRdbl(const char *Cmd) { mfpSetVerboseMode(verbose); if (!keylen) { - memmove(key, DefaultKey, 16); + memmove(key, mfp_default_key, 16); keylen = 16; } if (blockn > 255) { - PrintAndLogEx(ERR, " must be in range [0..255] got: %d", blockn); + PrintAndLogEx(ERR, " must be in range [0..255]. got %d", blockn); return PM3_EINVARG; } if (keylen != 16) { - PrintAndLogEx(ERR, " must be 16 bytes long. got: %d", keylen); + PrintAndLogEx(ERR, " must be 16 bytes. Got %d", keylen); return PM3_EINVARG; } // 3 blocks - wo iso14443-4 chaining if (blocksCount > 3) { - PrintAndLogEx(ERR, "blocks count must be less than 3. got: %d", blocksCount); + PrintAndLogEx(ERR, "blocks count must be less than 3. Got %d", blocksCount); return PM3_EINVARG; } @@ -763,7 +760,7 @@ static int CmdHFMFPRdbl(const char *Cmd) { } if (datalen != 1 + blocksCount * 16 + 8 + 2) { - PrintAndLogEx(ERR, "Error return length:%d", datalen); + PrintAndLogEx(ERR, "Error return length: %d", datalen); return PM3_ESOFT; } @@ -820,17 +817,17 @@ static int CmdHFMFPRdsc(const char *Cmd) { mfpSetVerboseMode(verbose); if (!keylen) { - memmove(key, DefaultKey, 16); + memmove(key, mfp_default_key, 16); keylen = 16; } if (sectorNum > 39) { - PrintAndLogEx(ERR, " must be in range [0..39] got: %d", sectorNum); + PrintAndLogEx(ERR, " must be in range [0..39]. Got %d", sectorNum); return PM3_EINVARG; } if (keylen != 16) { - PrintAndLogEx(ERR, " must be 16 bytes long. got: %d", keylen); + PrintAndLogEx(ERR, " must be 16 bytes. Got %d", keylen); return PM3_EINVARG; } @@ -894,7 +891,7 @@ static int CmdHFMFPRdsc(const char *Cmd) { static int CmdHFMFPWrbl(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfp wrbl", - "Writes one block to Mifare Plus card", + "Writes one block to MIFARE Plus card", "hf mfp wrbl --blk 1 -d ff0000000000000000000000000000ff --key 000102030405060708090a0b0c0d0e0f -> write block 1 data\n" "hf mfp wrbl --blk 2 -d ff0000000000000000000000000000ff -v -> write block 2 data with default key 0xFF..0xFF" ); @@ -928,22 +925,22 @@ static int CmdHFMFPWrbl(const char *Cmd) { mfpSetVerboseMode(verbose); if (!keylen) { - memmove(key, DefaultKey, 16); + memmove(key, mfp_default_key, 16); keylen = 16; } if (blockNum > 255) { - PrintAndLogEx(ERR, " must be in range [0..255] got: %d", blockNum); + PrintAndLogEx(ERR, " must be in range [0..255]. Got %d", blockNum); return PM3_EINVARG; } if (keylen != 16) { - PrintAndLogEx(ERR, " must be 16 bytes long. got: %d", keylen); + PrintAndLogEx(ERR, " must be 16 bytes. Got %d", keylen); return PM3_EINVARG; } if (datainlen != 16) { - PrintAndLogEx(ERR, " must be 16 bytes long. got: %d", datainlen); + PrintAndLogEx(ERR, " must be 16 bytes. Got %d", datainlen); return PM3_EINVARG; } @@ -997,11 +994,8 @@ static int CmdHFMFPWrbl(const char *Cmd) { return PM3_SUCCESS; } -#define AES_KEY_LEN 16 -#define MAX_KEYS_LIST_LEN 1024 - static int plus_key_check(uint8_t startSector, uint8_t endSector, uint8_t startKeyAB, uint8_t endKeyAB, - uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t keyListLen, uint8_t foundKeys[2][64][AES_KEY_LEN + 1], + uint8_t keyList[MAX_AES_KEYS_LIST_LEN][AES_KEY_LEN], size_t keyListLen, uint8_t foundKeys[2][64][AES_KEY_LEN + 1], bool verbose) { int res; bool selectCard = true; @@ -1088,7 +1082,7 @@ static int plus_key_check(uint8_t startSector, uint8_t endSector, uint8_t startK return PM3_SUCCESS; } -static void Fill2bPattern(uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], uint32_t *keyListLen, uint32_t *startPattern) { +static void Fill2bPattern(uint8_t keyList[MAX_AES_KEYS_LIST_LEN][AES_KEY_LEN], uint32_t *keyListLen, uint32_t *startPattern) { for (uint32_t pt = *startPattern; pt < 0x10000; pt++) { keyList[*keyListLen][0] = (pt >> 8) & 0xff; keyList[*keyListLen][1] = pt & 0xff; @@ -1097,7 +1091,7 @@ static void Fill2bPattern(uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], uint3 memcpy(&keyList[*keyListLen][8], &keyList[*keyListLen][0], 8); (*keyListLen)++; *startPattern = pt; - if (*keyListLen == MAX_KEYS_LIST_LEN) + if (*keyListLen == MAX_AES_KEYS_LIST_LEN) break; } (*startPattern)++; @@ -1111,7 +1105,7 @@ static int CmdHFMFPChk(const char *Cmd) { "hf mfp chk -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B\n" "hf mfp chk -s 2 -a -> check default key list on sector 2, only key A\n" "hf mfp chk -d mfp_default_keys -s0 -e6 -> check keys from dictionary against sectors 0-6\n" - "hf mfp chk --pattern1b -j keys -> check all 1-byte keys pattern and save found keys to json\n" + "hf mfp chk --pattern1b --dump -> check all 1-byte keys pattern and save found keys to file\n" "hf mfp chk --pattern2b --startp2b FA00 -> check all 2-byte keys pattern. Start from key FA00FA00...FA00"); void *argtable[] = { @@ -1125,7 +1119,7 @@ static int CmdHFMFPChk(const char *Cmd) { arg_lit0(NULL, "pattern1b", "Check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)"), arg_lit0(NULL, "pattern2b", "Check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"), arg_str0(NULL, "startp2b", "", "Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)"), - arg_str0("j", "json", "", "Json filename to save keys"), + arg_lit0(NULL, "dump", "Dump found keys to JSON file"), arg_lit0("v", "verbose", "Verbose mode"), arg_param_end }; @@ -1136,7 +1130,7 @@ static int CmdHFMFPChk(const char *Cmd) { uint8_t startSector = arg_get_int_def(ctx, 3, 0); uint8_t endSector = arg_get_int_def(ctx, 4, 0); - uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {{0}}; + uint8_t keyList[MAX_AES_KEYS_LIST_LEN][AES_KEY_LEN] = {{0}}; uint32_t keyListLen = 0; uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {{{0}}}; @@ -1148,7 +1142,7 @@ static int CmdHFMFPChk(const char *Cmd) { memcpy(&keyList[keyListLen], vkey, 16); keyListLen++; } else { - PrintAndLogEx(ERR, "Specified key must have 16 bytes length."); + PrintAndLogEx(ERR, "Specified key must have 16 bytes. Got %d", vkeylen); CLIParserFree(ctx); return PM3_EINVARG; } @@ -1185,7 +1179,7 @@ static int CmdHFMFPChk(const char *Cmd) { if (vpatternlen <= 2) { startPattern = (vpattern[0] << 8) + vpattern[1]; } else { - PrintAndLogEx(ERR, "Pattern must be 2-byte length."); + PrintAndLogEx(ERR, "Pattern must be 2-bytes. Got %d", vpatternlen); CLIParserFree(ctx); return PM3_EINVARG; } @@ -1193,17 +1187,8 @@ static int CmdHFMFPChk(const char *Cmd) { PrintAndLogEx(WARNING, "Pattern entered, but search mode not is 2-byte search."); } - uint8_t jsonname[250] = {0}; - int jsonnamelen = 0; - if (CLIParamStrToBuf(arg_get_str(ctx, 10), jsonname, sizeof(jsonname), &jsonnamelen)) { - PrintAndLogEx(ERR, "Invalid json name."); - CLIParserFree(ctx); - return PM3_EINVARG; - } - jsonname[jsonnamelen] = 0; - + bool create_dumpfile = arg_get_lit(ctx, 10); bool verbose = arg_get_lit(ctx, 11); - CLIParserFree(ctx); uint8_t startKeyAB = 0; @@ -1227,8 +1212,9 @@ static int CmdHFMFPChk(const char *Cmd) { } // 2-byte pattern search mode - if (pattern2b) + if (pattern2b) { Fill2bPattern(keyList, &keyListLen, &startPattern); + } int res = PM3_SUCCESS; @@ -1291,19 +1277,30 @@ static int CmdHFMFPChk(const char *Cmd) { keyListLen = keycnt; } + PrintAndLogEx(INFO, "ICE pos... %zu - %zu", old_pos, endFilePosition); continue; } break; } - if (verbose == false) + + if (verbose == false) { PrintAndLogEx(NORMAL, ""); + } // print result char strA[46 + 1] = {0}; char strB[46 + 1] = {0}; + uint8_t ndef_key[] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7}; + bool has_ndef_key = false; bool printedHeader = false; for (uint8_t s = startSector; s <= endSector; s++) { + + if ((memcmp(&foundKeys[0][s][1], ndef_key, AES_KEY_LEN) == 0) || + (memcmp(&foundKeys[1][s][1], ndef_key, AES_KEY_LEN) == 0)) { + has_ndef_key = true; + } + if (printedHeader == false) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "-----+----------------------------------+----------------------------------"); @@ -1333,7 +1330,13 @@ static int CmdHFMFPChk(const char *Cmd) { PrintAndLogEx(INFO, "-----+----------------------------------+----------------------------------\n"); // save keys to json - if ((jsonnamelen > 0) && printedHeader) { + if (create_dumpfile && printedHeader) { + + size_t keys_len = (2 * 64 * (AES_KEY_LEN + 1)); + + uint8_t data[10 + 1 + 2 + 1 + 256 + keys_len]; + memset(data, 0, sizeof(data)); + // Mifare Plus info SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); @@ -1344,8 +1347,6 @@ static int CmdHFMFPChk(const char *Cmd) { memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); uint64_t select_status = resp.oldarg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision - - uint8_t data[10 + 1 + 2 + 1 + 256 + 2 * 64 * (AES_KEY_LEN + 1)] = {0}; uint8_t atslen = 0; if (select_status == 1 || select_status == 2) { memcpy(data, card.uid, card.uidlen); @@ -1357,9 +1358,16 @@ static int CmdHFMFPChk(const char *Cmd) { memcpy(&data[14], card.ats, atslen); } + char *fptr = calloc(sizeof(char) * (strlen("hf-mfp-") + strlen("-key")) + card.uidlen * 2 + 1, sizeof(uint8_t)); + strcpy(fptr, "hf-mfp-"); + + FillFileNameByUID(fptr, card.uid, "-key", card.uidlen); + // length: UID(10b)+SAK(1b)+ATQA(2b)+ATSlen(1b)+ATS(atslen)+foundKeys[2][64][AES_KEY_LEN + 1] - memcpy(&data[14 + atslen], foundKeys, 2 * 64 * (AES_KEY_LEN + 1)); - saveFileJSON((char *)jsonname, jsfMfPlusKeys, data, 64, NULL); + memcpy(&data[14 + atslen], foundKeys, keys_len); + // 64 here is for how many "rows" there is in the data array. A bit confusing + saveFileJSON(fptr, jsfMfPlusKeys, data, 64, NULL); + free(fptr); } return PM3_SUCCESS; @@ -1369,7 +1377,7 @@ static int CmdHFMFPMAD(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfp mad", - "Checks and prints Mifare Application Directory (MAD)", + "Checks and prints MIFARE Application Directory (MAD)", "hf mfp mad\n" "hf mfp mad --aid e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> read and print NDEF data from MAD aid"); @@ -1411,9 +1419,7 @@ static int CmdHFMFPMAD(const char *Cmd) { return PM3_ESOFT; } - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "--- " _CYAN_("Mifare App Directory Information") " ----------------"); - PrintAndLogEx(INFO, "-----------------------------------------------------"); + MADPrintHeader(); if (verbose) { PrintAndLogEx(SUCCESS, "Raw:"); @@ -1427,7 +1433,7 @@ static int CmdHFMFPMAD(const char *Cmd) { if (haveMAD2) { if (mfpReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector10, verbose)) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(ERR, "error, read sector 0x10. card doesn't have MAD or doesn't have MAD on default keys"); + PrintAndLogEx(ERR, "error, read sector " _YELLOW_("0x10") ". Card doesn't have MAD or doesn't have MAD on default keys"); return PM3_ESOFT; } @@ -1505,6 +1511,36 @@ static int CmdHFMFPMAD(const char *Cmd) { return PM3_SUCCESS; } +static int CmdHFMFPNDEFFormat(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp ndefformat", + "format MIFARE Plus Tag as a NFC tag with Data Exchange Format (NDEF)\n" + "If no given, UID will be used as filename. \n" + "It will try default keys and MAD keys to detect if tag is already formatted in order to write.\n" + "\n" + "If not, it will try finding a key file based on your UID. ie, if you ran autopwn before", + "hf mfp ndefformat\n" + "hf mfp ndefformat --keys hf-mf-01020304-key.bin --> with keys from specified file\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_str0("k", "keys", "", "filename of keys"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + int keyfnlen = 0; + char keyFilename[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)keyFilename, FILE_PATH_SIZE, &keyfnlen); + + CLIParserFree(ctx); + + PrintAndLogEx(SUCCESS, "Not implemented yet. Feel free to contribute!"); + PrintAndLogEx(NORMAL, ""); + return PM3_SUCCESS; +} + int CmdHFMFPNDEFRead(const char *Cmd) { CLIParserContext *ctx; @@ -1641,20 +1677,74 @@ int CmdHFMFPNDEFRead(const char *Cmd) { return PM3_SUCCESS; } +static int CmdHFMFPNDEFWrite(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp ndefwrite", + "Write raw NDEF hex bytes to tag. This commands assumes tag already been NFC/NDEF formatted.\n", + "hf mfp ndefwrite -d 0300FE -> write empty record to tag\n" + "hf mfp ndefwrite -f myfilename\n" + "hf mfp ndefwrite -d 033fd1023a53709101195405656e2d55534963656d616e2054776974746572206c696e6b5101195502747769747465722e636f6d2f686572726d616e6e31303031\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_str0("d", NULL, "", "raw NDEF hex bytes"), + arg_str0("f", "file", "", "write raw NDEF file to tag"), + arg_lit0("p", NULL, "fix NDEF record headers / terminator block if missing"), + arg_lit0("v", "verbose", "verbose output"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + uint8_t raw[4096] = {0}; + int rawlen; + CLIGetHexWithReturn(ctx, 1, raw, &rawlen); + + int fnlen = 0; + char filename[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + + bool fix_msg = arg_get_lit(ctx, 3); + bool verbose = arg_get_lit(ctx, 4); + CLIParserFree(ctx); + + if (fix_msg) { + PrintAndLogEx(NORMAL, "called with fix NDEF message param"); + } + + if (verbose) { + PrintAndLogEx(NORMAL, ""); + } + PrintAndLogEx(SUCCESS, "Not implemented yet. Feel free to contribute!"); + PrintAndLogEx(NORMAL, ""); + return PM3_SUCCESS; +} + +static int CmdHFMFPList(const char *Cmd) { + return CmdTraceListAlias(Cmd, "hf mf", "mf"); +} + static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"info", CmdHFMFPInfo, IfPm3Iso14443a, "Info about Mifare Plus tag"}, - {"wrp", CmdHFMFPWritePerso, IfPm3Iso14443a, "Write Perso command"}, - {"initp", CmdHFMFPInitPerso, IfPm3Iso14443a, "Fill all the card's keys in SL0 mode"}, - {"commitp", CmdHFMFPCommitPerso, IfPm3Iso14443a, "Move card to SL1 or SL3 mode"}, - {"auth", CmdHFMFPAuth, IfPm3Iso14443a, "Authentication"}, - {"rdbl", CmdHFMFPRdbl, IfPm3Iso14443a, "Read blocks"}, - {"rdsc", CmdHFMFPRdsc, IfPm3Iso14443a, "Read sectors"}, - {"wrbl", CmdHFMFPWrbl, IfPm3Iso14443a, "Write blocks"}, - {"chk", CmdHFMFPChk, IfPm3Iso14443a, "Check keys"}, - {"mad", CmdHFMFPMAD, IfPm3Iso14443a, "Check and print MAD"}, - {"ndefread", CmdHFMFPNDEFRead, IfPm3Iso14443a, "Read and print NDEF records from card"}, - {NULL, NULL, 0, NULL} + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"list", CmdHFMFPList, AlwaysAvailable, "List MIFARE Plus history"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "------------------- " _CYAN_("operations") " ---------------------"}, + {"auth", CmdHFMFPAuth, IfPm3Iso14443a, "Authentication"}, + {"chk", CmdHFMFPChk, IfPm3Iso14443a, "Check keys"}, + {"dump", CmdHFMFPDump, IfPm3Iso14443a, "Dump MIFARE Classic tag to binary file"}, + {"info", CmdHFMFPInfo, IfPm3Iso14443a, "Info about MIFARE Plus tag"}, + {"mad", CmdHFMFPMAD, IfPm3Iso14443a, "Check and print MAD"}, + {"rdbl", CmdHFMFPRdbl, IfPm3Iso14443a, "Read blocks from card"}, + {"rdsc", CmdHFMFPRdsc, IfPm3Iso14443a, "Read sectors from card"}, + {"wrbl", CmdHFMFPWrbl, IfPm3Iso14443a, "Write block to card"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "---------------- " _CYAN_("personalization") " -------------------"}, + {"commitp", CmdHFMFPCommitPerso, IfPm3Iso14443a, "Move card to SL1 or SL3 mode"}, + {"initp", CmdHFMFPInitPerso, IfPm3Iso14443a, "Fill all the card's keys in SL0 mode"}, + {"wrp", CmdHFMFPWritePerso, IfPm3Iso14443a, "Write Perso command"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "---------------------- " _CYAN_("ndef") " ------------------------"}, + {"ndefformat", CmdHFMFPNDEFFormat, IfPm3Iso14443a, "Format MIFARE Plus Tag as NFC Tag"}, + {"ndefread", CmdHFMFPNDEFRead, IfPm3Iso14443a, "Read and print NDEF records from card"}, + {"ndefwrite", CmdHFMFPNDEFWrite, IfPm3Iso14443a, "Write NDEF records to card"}, + {NULL, NULL, 0, NULL} }; static int CmdHelp(const char *Cmd) { diff --git a/client/src/cmdhfmfp.h b/client/src/cmdhfmfp.h index 2a4d7cd2c..29723b204 100644 --- a/client/src/cmdhfmfp.h +++ b/client/src/cmdhfmfp.h @@ -24,6 +24,26 @@ #define AES_KEY_LEN 16 #define MAX_AES_KEYS_LIST_LEN 1024 +typedef enum { + MFP_UNKNOWN = 0, + DESFIRE_MF3ICD40, + DESFIRE_EV1, + DESFIRE_EV2, + DESFIRE_EV3, + DESFIRE_LIGHT, + PLUS_EV1, +} nxp_cardtype_t; + +typedef struct mfp_key_item { + uint8_t a[16]; + uint8_t b[16]; +} mfp_key_item_t; + +typedef struct mfp_keys { + uint8_t success; + mfp_key_item_t *keys; +} mfp_keys_t; + int CmdHFMFP(const char *Cmd); int CmdHFMFPNDEFRead(const char *Cmd); From bf8ac54c38c43aadd695c62a3ac1b43689c75751 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 17:58:22 +0200 Subject: [PATCH 26/68] fix loop logic. thanks @jump --- client/src/cmdhf14b.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 77378fda2..29a985b29 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -2231,30 +2231,31 @@ int infoHF14B(bool verbose, bool do_aid_search) { int readHF14B(bool loop, bool verbose) { bool found = false; do { + found = false; + // try std 14b (atqb) - found = HF14B_std_reader(verbose); + found |= HF14B_std_reader(verbose); if (found && loop) continue; // try ST Microelectronics 14b - found = HF14B_st_reader(verbose); + found |= HF14B_st_reader(verbose); if (found && loop) continue; // try ASK CT 14b - found = HF14B_ask_ct_reader(verbose); + found |= HF14B_ask_ct_reader(verbose); if (found && loop) continue; // try unknown 14b read commands (to be identified later) // could be read of calypso, CEPAS, moneo, or pico pass. - found = HF14B_other_reader(verbose); + found |= HF14B_other_reader(verbose); if (found && loop) continue; } while (loop && kbd_enter_pressed() == false); - if (verbose && found == false) { PrintAndLogEx(FAILED, "no ISO 14443-B tag found"); } From b8d3b281ad8fefe4e00302def714f4392a2c53b3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 18:07:56 +0200 Subject: [PATCH 27/68] adapt non commit functions yet --- client/src/cmdhfmfp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 2368e0f74..61f39e9c2 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -1277,7 +1277,6 @@ static int CmdHFMFPChk(const char *Cmd) { keyListLen = keycnt; } - PrintAndLogEx(INFO, "ICE pos... %zu - %zu", old_pos, endFilePosition); continue; } break; @@ -1730,14 +1729,14 @@ static command_t CommandTable[] = { {"-----------", CmdHelp, IfPm3Iso14443a, "------------------- " _CYAN_("operations") " ---------------------"}, {"auth", CmdHFMFPAuth, IfPm3Iso14443a, "Authentication"}, {"chk", CmdHFMFPChk, IfPm3Iso14443a, "Check keys"}, - {"dump", CmdHFMFPDump, IfPm3Iso14443a, "Dump MIFARE Classic tag to binary file"}, +// {"dump", CmdHFMFPDump, IfPm3Iso14443a, "Dump MIFARE Plus tag to binary file"}, {"info", CmdHFMFPInfo, IfPm3Iso14443a, "Info about MIFARE Plus tag"}, {"mad", CmdHFMFPMAD, IfPm3Iso14443a, "Check and print MAD"}, {"rdbl", CmdHFMFPRdbl, IfPm3Iso14443a, "Read blocks from card"}, {"rdsc", CmdHFMFPRdsc, IfPm3Iso14443a, "Read sectors from card"}, {"wrbl", CmdHFMFPWrbl, IfPm3Iso14443a, "Write block to card"}, {"-----------", CmdHelp, IfPm3Iso14443a, "---------------- " _CYAN_("personalization") " -------------------"}, - {"commitp", CmdHFMFPCommitPerso, IfPm3Iso14443a, "Move card to SL1 or SL3 mode"}, + {"commitp", CmdHFMFPCommitPerso, IfPm3Iso14443a, "Configure security layer (SL1/SL3 mode)"}, {"initp", CmdHFMFPInitPerso, IfPm3Iso14443a, "Fill all the card's keys in SL0 mode"}, {"wrp", CmdHFMFPWritePerso, IfPm3Iso14443a, "Write Perso command"}, {"-----------", CmdHelp, IfPm3Iso14443a, "---------------------- " _CYAN_("ndef") " ------------------------"}, From 3fbd53ac2f3d500344ec210881357c7889669cf5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 18:27:33 +0200 Subject: [PATCH 28/68] hf mf wipe - text --- client/src/cmdhfmf.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 130654caf..98ac30b98 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -7015,33 +7015,33 @@ static int CmdHF14AMfWipe(const char *Cmd) { return PM3_ESOFT; } - uint8_t keyA[MIFARE_4K_MAXSECTOR * 6]; - uint8_t keyB[MIFARE_4K_MAXSECTOR * 6]; + uint8_t keyA[MIFARE_4K_MAXSECTOR * MIFARE_KEY_SIZE]; + uint8_t keyB[MIFARE_4K_MAXSECTOR * MIFARE_KEY_SIZE]; uint8_t num_sectors = 0; uint8_t mf[MFBLOCK_SIZE]; switch (keyslen) { - case (MIFARE_MINI_MAXSECTOR * 2 * 6): { + case (MIFARE_MINI_MAXSECTOR * 2 * MIFARE_KEY_SIZE): { PrintAndLogEx(INFO, "Loaded keys matching MIFARE Classic Mini 320b"); - memcpy(keyA, keys, (MIFARE_MINI_MAXSECTOR * 6)); - memcpy(keyB, keys + (MIFARE_MINI_MAXSECTOR * 6), (MIFARE_MINI_MAXSECTOR * 6)); + memcpy(keyA, keys, (MIFARE_MINI_MAXSECTOR * MIFARE_KEY_SIZE)); + memcpy(keyB, keys + (MIFARE_MINI_MAXSECTOR * MIFARE_KEY_SIZE), (MIFARE_MINI_MAXSECTOR * MIFARE_KEY_SIZE)); num_sectors = NumOfSectors('0'); memcpy(mf, "\x11\x22\x33\x44\x44\x09\x04\x00\x62\x63\x64\x65\x66\x67\x68\x69", MFBLOCK_SIZE); break; } - case (MIFARE_1K_MAXSECTOR * 2 * 6): { + case (MIFARE_1K_MAXSECTOR * 2 * MIFARE_KEY_SIZE): { PrintAndLogEx(INFO, "Loaded keys matching MIFARE Classic 1K"); - memcpy(keyA, keys, (MIFARE_1K_MAXSECTOR * 6)); - memcpy(keyB, keys + (MIFARE_1K_MAXSECTOR * 6), (MIFARE_1K_MAXSECTOR * 6)); + memcpy(keyA, keys, (MIFARE_1K_MAXSECTOR * MIFARE_KEY_SIZE)); + memcpy(keyB, keys + (MIFARE_1K_MAXSECTOR * MIFARE_KEY_SIZE), (MIFARE_1K_MAXSECTOR * MIFARE_KEY_SIZE)); num_sectors = NumOfSectors('1'); memcpy(mf, "\x11\x22\x33\x44\x44\x08\x04\x00\x62\x63\x64\x65\x66\x67\x68\x69", MFBLOCK_SIZE); break; } - case (MIFARE_4K_MAXSECTOR * 2 * 6): { + case (MIFARE_4K_MAXSECTOR * 2 * MIFARE_KEY_SIZE): { PrintAndLogEx(INFO, "Loaded keys matching MIFARE Classic 4K"); - memcpy(keyA, keys, (MIFARE_4K_MAXSECTOR * 6)); - memcpy(keyB, keys + (MIFARE_4K_MAXSECTOR * 6), (MIFARE_4K_MAXSECTOR * 6)); + memcpy(keyA, keys, (MIFARE_4K_MAXSECTOR * MIFARE_KEY_SIZE)); + memcpy(keyB, keys + (MIFARE_4K_MAXSECTOR * MIFARE_KEY_SIZE), (MIFARE_4K_MAXSECTOR * MIFARE_KEY_SIZE)); num_sectors = NumOfSectors('4'); memcpy(mf, "\x11\x22\x33\x44\x44\x18\x02\x00\x62\x63\x64\x65\x66\x67\x68\x69", MFBLOCK_SIZE); break; @@ -7063,6 +7063,8 @@ static int CmdHF14AMfWipe(const char *Cmd) { memset(zeros, 0x00, sizeof(zeros)); uint8_t st[MFBLOCK_SIZE] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + PrintAndLogEx(INFO, " blk | "); + PrintAndLogEx(INFO, "-----+------------------------------------------------------------"); // time to wipe card for (uint8_t s = 0; s < num_sectors; s++) { @@ -7095,11 +7097,11 @@ static int CmdHF14AMfWipe(const char *Cmd) { for (int8_t kt = MF_KEY_B; kt > -1; kt--) { if (kt == MF_KEY_A) - memcpy(data, keyA + (s * 6), 6); + memcpy(data, keyA + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); else - memcpy(data, keyB + (s * 6), 6); + memcpy(data, keyB + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); - PrintAndLogEx(INFO, "block %3d: %s" NOLF, mfFirstBlockOfSector(s) + b, sprint_hex(data + 10, MFBLOCK_SIZE)); + PrintAndLogEx(INFO, " %3d | %s" NOLF, mfFirstBlockOfSector(s) + b, sprint_hex(data + 10, MFBLOCK_SIZE)); clearCommandBuffer(); SendCommandMIX(CMD_HF_MIFARE_WRITEBL, mfFirstBlockOfSector(s) + b, kt, 0, data, sizeof(data)); PacketResponseNG resp; @@ -7118,6 +7120,7 @@ static int CmdHF14AMfWipe(const char *Cmd) { } } + PrintAndLogEx(INFO, "-----+------------------------------------------------------------"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "Done!"); out: From a4e22416b94620ad943d55f533b95d28eb2975fd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 18:28:44 +0200 Subject: [PATCH 29/68] less debug output when an auth fails --- armsrc/mifarecmd.c | 4 ++-- armsrc/mifareutil.c | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 4d57ef0ce..7a5abf2c8 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -3221,7 +3221,7 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain) { return; }; - if (mifare_desfire_des_auth1(cuid, dataout)) { + if (mifare_desfire_des_auth1(cuid, dataout) != PM3_SUCCESS) { if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication part1: Fail."); OnError(4); return; @@ -3241,7 +3241,7 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain) { isOK = mifare_desfire_des_auth2(cuid, key, dataout); - if (isOK) { + if (isOK != PM3_SUCCESS) { if (g_dbglevel >= DBG_EXTENDED) Dbprintf("Authentication part2: Failed"); OnError(4); return; diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 7296f1abe..487c71706 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -433,7 +433,7 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t } if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK - if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); + if (g_dbglevel >= DBG_INFO) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); return PM3_EFAILED; } @@ -805,9 +805,10 @@ int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData) { len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer, receivedAnswerPar, NULL); if (len == 1) { - if (g_dbglevel >= DBG_ERROR) + if (g_dbglevel >= DBG_INFO) { Dbprintf("Cmd Error: %02x", receivedAnswer[0]); - return 1; + } + return PM3_EFAILED; } if (len == 12) { @@ -818,9 +819,9 @@ int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData) { receivedAnswer[10], receivedAnswer[11]); } memcpy(blockData, receivedAnswer, 12); - return 0; + return PM3_SUCCESS; } - return 1; + return PM3_EFAILED; } int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData) { @@ -835,9 +836,10 @@ int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData) { len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, receivedAnswerPar, NULL); if ((receivedAnswer[0] == 0x03) && (receivedAnswer[1] == 0xae)) { - if (g_dbglevel >= DBG_ERROR) + if (g_dbglevel >= DBG_ERROR) { Dbprintf("Auth Error: %02x %02x", receivedAnswer[0], receivedAnswer[1]); - return 1; + } + return PM3_EFAILED; } if (len == 12) { @@ -848,7 +850,7 @@ int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData) { receivedAnswer[10], receivedAnswer[11]); } memcpy(blockData, receivedAnswer, 12); - return 0; + return PM3_SUCCESS; } - return 1; + return PM3_EFAILED; } From 2d70ff5085d7ccf11019fc97da5f68915b724bca Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 18:33:16 +0200 Subject: [PATCH 30/68] fix compilation by adding the WIP func --- client/src/cmdhfmfp.c | 93 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 61f39e9c2..089e041d3 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -1369,9 +1369,100 @@ static int CmdHFMFPChk(const char *Cmd) { free(fptr); } + // MAD detection + if ((memcmp(&foundKeys[0][0][1], "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7", AES_KEY_LEN) == 0)) { + PrintAndLogEx(HINT, "MAD key detected. Try " _YELLOW_("`hf mfp mad`") " for more details"); + } + + // NDEF detection + if (has_ndef_key) { + PrintAndLogEx(HINT, "NDEF key detected. Try " _YELLOW_("`hf mfp ndefread -h`") " for more details"); + } + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } +static int CmdHFMFPDump(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp dump", + "Dump MIFARE Plus tag to binary file\n" + "If no given, UID will be used as filename", + "hf mfp dump\n" + "hf mfp dump --keys hf-mf-066C8B78-key.bin --> MIFARE Plus with keys from specified file\n"); + + void *argtable[] = { + arg_param_begin, + arg_str0("f", "file", "", "filename of dump"), + arg_str0("k", "keys", "", "filename of keys"), + arg_lit0(NULL, "ns", "no save to file"), + arg_lit0("v", "verbose", "Verbose mode"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + int datafnlen = 0; + char data_fn[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)data_fn, FILE_PATH_SIZE, &datafnlen); + + int keyfnlen = 0; + char key_fn[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)key_fn, FILE_PATH_SIZE, &keyfnlen); + + bool nosave = arg_get_lit(ctx, 3); + bool verbose = arg_get_lit(ctx, 4); + CLIParserFree(ctx); + + mfpSetVerboseMode(verbose); + + // read card + uint8_t *mem = calloc(MIFARE_4K_MAXBLOCK * MFBLOCK_SIZE, sizeof(uint8_t)); + if (mem == NULL) { + PrintAndLogEx(ERR, "failed to allocate memory"); + return PM3_EMALLOC; + } + +/* + iso14a_card_select_t card ; + int res = mfp_read_tag(&card, mem, key_fn); + if (res != PM3_SUCCESS) { + free(mem); + return res; + } +*/ + + // Skip saving card data to file + if (nosave) { + PrintAndLogEx(INFO, "Called with no save option"); + free(mem); + return PM3_SUCCESS; + } +/* + // Save to file + if (strlen(data_fn) < 1) { + + char *fptr = calloc(sizeof(char) * (strlen("hf-mfp-") + strlen("-dump")) + card.uidlen * 2 + 1, sizeof(uint8_t)); + strcpy(fptr, "hf-mfp-"); + + FillFileNameByUID(fptr, card.uid, "-dump", card.uidlen); + + strcpy(data_fn, fptr); + free(fptr); + } + + saveFile(data_fn, ".bin", mem, MIFARE_4K_MAX_BYTES); + saveFileEML(data_fn, mem, MIFARE_4K_MAX_BYTES, MFBLOCK_SIZE); + + iso14a_mf_extdump_t xdump; + xdump.card_info = card; + xdump.dump = mem; + xdump.dumplen = MIFARE_4K_MAX_BYTES; + saveFileJSON(data_fn, jsfCardMemory, (uint8_t *)&xdump, sizeof(xdump), NULL); +*/ + free(mem); + return PM3_SUCCESS; +} + + static int CmdHFMFPMAD(const char *Cmd) { CLIParserContext *ctx; @@ -1729,7 +1820,7 @@ static command_t CommandTable[] = { {"-----------", CmdHelp, IfPm3Iso14443a, "------------------- " _CYAN_("operations") " ---------------------"}, {"auth", CmdHFMFPAuth, IfPm3Iso14443a, "Authentication"}, {"chk", CmdHFMFPChk, IfPm3Iso14443a, "Check keys"}, -// {"dump", CmdHFMFPDump, IfPm3Iso14443a, "Dump MIFARE Plus tag to binary file"}, + {"dump", CmdHFMFPDump, IfPm3Iso14443a, "Dump MIFARE Plus tag to binary file"}, {"info", CmdHFMFPInfo, IfPm3Iso14443a, "Info about MIFARE Plus tag"}, {"mad", CmdHFMFPMAD, IfPm3Iso14443a, "Check and print MAD"}, {"rdbl", CmdHFMFPRdbl, IfPm3Iso14443a, "Read blocks from card"}, From 55b780074fed9b169124bdfae134fbe60284d846 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 18:59:16 +0200 Subject: [PATCH 31/68] move defines --- client/src/fileutils.c | 2 +- client/src/mifare/mifaredefault.h | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/client/src/fileutils.c b/client/src/fileutils.c index aad9b9cce..917a7ee77 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -29,7 +29,7 @@ #include "cmdhficlass.h" // pagemap #include "protocols.h" // iclass defines #include "cmdhftopaz.h" // TOPAZ defines -#include "cmdhfmfp.h" // MFP / AES defines +#include "mifare/mifaredefault.h" // MFP / AES defines #ifdef _WIN32 #include "scandir.h" diff --git a/client/src/mifare/mifaredefault.h b/client/src/mifare/mifaredefault.h index e3590329d..7bb7e144a 100644 --- a/client/src/mifare/mifaredefault.h +++ b/client/src/mifare/mifaredefault.h @@ -21,6 +21,9 @@ #include "common.h" +#define AES_KEY_LEN 16 +#define MAX_AES_KEYS_LIST_LEN 1024 + #define MFKEY_SIZE 6 #define MFBLOCK_SIZE 16 @@ -41,6 +44,12 @@ #define MIFARE_KEY_SIZE 6 +#define MIFARE_MINI_MAX_KEY_SIZE (MIFARE_MINI_MAXSECTOR * 2 * MIFARE_KEY_SIZE) +#define MIFARE_1K_MAX_KEY_SIZE (MIFARE_1K_MAXSECTOR * 2 * MIFARE_KEY_SIZE) +#define MIFARE_2K_MAX_KEY_SIZE (MIFARE_2K_MAXSECTOR * 2 * MIFARE_KEY_SIZE) +#define MIFARE_4K_MAX_KEY_SIZE (MIFARE_4K_MAXSECTOR * 2 * MIFARE_KEY_SIZE) + + static const uint64_t g_mifare_default_keys[] = { 0xffffffffffff, // Default key (first key used by program if no user defined key) 0xa0a1a2a3a4a5, // NFCForum MAD key From 5087581a509839a9fe9ceffa399ea1e5ba38c602 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 19:58:33 +0200 Subject: [PATCH 32/68] fix some wrong sector comparisions. And return value for restore command when sending wrbl. --- client/src/cmdhfmf.c | 55 ++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 98ac30b98..fe48bb1fe 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -984,7 +984,7 @@ static int CmdHF14AMfRdSc(const char *Cmd) { return PM3_EINVARG; } - if (s > MIFARE_4K_MAXSECTOR) { + if (s >= MIFARE_4K_MAXSECTOR) { PrintAndLogEx(WARNING, "Sector number must be less then 40"); return PM3_EINVARG; } @@ -1321,6 +1321,9 @@ static int CmdHF14AMfRestore(const char *Cmd) { PrintAndLogEx(INFO, "Restoring " _YELLOW_("%s")" to card", datafilename); + PrintAndLogEx(INFO, " blk | "); + PrintAndLogEx(INFO, "-----+------------------------------------------------------------"); + // main loop for restoring. // a bit more complicated than needed // this is because of two things. @@ -1334,7 +1337,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { memcpy(bldata, dump, MFBLOCK_SIZE); // if sector trailer - if (mfNumBlocksPerSector(s) - 1 == b) { + if (mfIsSectorTrailerBasedOnBlocks(s, b)) { if (use_keyfile_for_auth == false) { // replace KEY A memcpy(bldata, keyA + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); @@ -1381,33 +1384,40 @@ static int CmdHF14AMfRestore(const char *Cmd) { // use default key to authenticate for the write command memcpy(wdata, default_key, MIFARE_KEY_SIZE); } - PrintAndLogEx(INFO, "block %3d: %s", mfFirstBlockOfSector(s) + b, sprint_hex(bldata, sizeof(bldata))); + + PrintAndLogEx(INFO, " %3d | %s", mfFirstBlockOfSector(s) + b, sprint_hex(bldata, sizeof(bldata))); clearCommandBuffer(); SendCommandMIX(CMD_HF_MIFARE_WRITEBL, mfFirstBlockOfSector(s) + b, kt, 0, wdata, sizeof(wdata)); PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - uint8_t isOK = resp.oldarg[0] & 0xff; - if (isOK == 0) { - if (b == 0) { - PrintAndLogEx(INFO, "Writing to manufacture block w key %c ( " _RED_("fail") " )", (kt == MF_KEY_A) ? 'A' : 'B'); - } else { - PrintAndLogEx(FAILED, "Write to block %u w key %c ( " _RED_("fail") " ) ", b, (kt == MF_KEY_A) ? 'A' : 'B'); - } - } else { - // if success, skip to next block - break; - } - } else { + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { PrintAndLogEx(WARNING, "Command execute timeout"); + continue; + } + + int isOK = resp.oldarg[0] & 0xff; + if (isOK == 1) { + // if success, skip to next block + break; + } else if (isOK == PM3_ETEAROFF) { + PrintAndLogEx(INFO, "Tear off triggerd. Recommendation is not to use tear-off with restore command"); + return isOK; + } else { + if (b == 0) { + PrintAndLogEx(INFO, "Writing to manufacture block w key %c ( " _RED_("fail") " )", (kt == MF_KEY_A) ? 'A' : 'B'); + } else { + PrintAndLogEx(FAILED, "Write to block %u w key %c ( " _RED_("fail") " ) ", b, (kt == MF_KEY_A) ? 'A' : 'B'); + } } - } + } // end loop key types } // end loop B } // end loop S free(ref_dump); free(keyA); free(keyB); + PrintAndLogEx(INFO, "-----+------------------------------------------------------------"); + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "Done!"); return PM3_SUCCESS; } @@ -4071,7 +4081,7 @@ static int CmdHF14AMfEGetSc(const char *Cmd) { bool verbose = arg_get_lit(ctx, 2); CLIParserFree(ctx); - if (s > 39) { + if (s >= MIFARE_4K_MAXSECTOR) {v PrintAndLogEx(WARNING, "Sector number must be less then 40"); return PM3_EINVARG; } @@ -5065,7 +5075,8 @@ static int CmdHF14AMfCGetSc(const char *Cmd) { int s = arg_get_int_def(ctx, 1, 0); bool verbose = arg_get_lit(ctx, 2); CLIParserFree(ctx); - if (s > 39) { + + if (s >= MIFARE_4K_MAXSECTOR) { PrintAndLogEx(WARNING, "Sector number must be less then 40"); return PM3_EINVARG; } @@ -7021,7 +7032,7 @@ static int CmdHF14AMfWipe(const char *Cmd) { uint8_t mf[MFBLOCK_SIZE]; switch (keyslen) { - case (MIFARE_MINI_MAXSECTOR * 2 * MIFARE_KEY_SIZE): { + case (MIFARE_MINI_MAX_KEY_SIZE): { PrintAndLogEx(INFO, "Loaded keys matching MIFARE Classic Mini 320b"); memcpy(keyA, keys, (MIFARE_MINI_MAXSECTOR * MIFARE_KEY_SIZE)); memcpy(keyB, keys + (MIFARE_MINI_MAXSECTOR * MIFARE_KEY_SIZE), (MIFARE_MINI_MAXSECTOR * MIFARE_KEY_SIZE)); @@ -7029,7 +7040,7 @@ static int CmdHF14AMfWipe(const char *Cmd) { memcpy(mf, "\x11\x22\x33\x44\x44\x09\x04\x00\x62\x63\x64\x65\x66\x67\x68\x69", MFBLOCK_SIZE); break; } - case (MIFARE_1K_MAXSECTOR * 2 * MIFARE_KEY_SIZE): { + case (MIFARE_1K_MAX_KEY_SIZE): { PrintAndLogEx(INFO, "Loaded keys matching MIFARE Classic 1K"); memcpy(keyA, keys, (MIFARE_1K_MAXSECTOR * MIFARE_KEY_SIZE)); memcpy(keyB, keys + (MIFARE_1K_MAXSECTOR * MIFARE_KEY_SIZE), (MIFARE_1K_MAXSECTOR * MIFARE_KEY_SIZE)); @@ -7038,7 +7049,7 @@ static int CmdHF14AMfWipe(const char *Cmd) { memcpy(mf, "\x11\x22\x33\x44\x44\x08\x04\x00\x62\x63\x64\x65\x66\x67\x68\x69", MFBLOCK_SIZE); break; } - case (MIFARE_4K_MAXSECTOR * 2 * MIFARE_KEY_SIZE): { + case (MIFARE_4K_MAX_KEY_SIZE): { PrintAndLogEx(INFO, "Loaded keys matching MIFARE Classic 4K"); memcpy(keyA, keys, (MIFARE_4K_MAXSECTOR * MIFARE_KEY_SIZE)); memcpy(keyB, keys + (MIFARE_4K_MAXSECTOR * MIFARE_KEY_SIZE), (MIFARE_4K_MAXSECTOR * MIFARE_KEY_SIZE)); From c6e9f9781c22a2f38609bebfbabccf31dbf082fb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Jun 2023 20:02:56 +0200 Subject: [PATCH 33/68] fix char --- client/src/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index fe48bb1fe..5a676e390 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -4081,7 +4081,7 @@ static int CmdHF14AMfEGetSc(const char *Cmd) { bool verbose = arg_get_lit(ctx, 2); CLIParserFree(ctx); - if (s >= MIFARE_4K_MAXSECTOR) {v + if (s >= MIFARE_4K_MAXSECTOR) { PrintAndLogEx(WARNING, "Sector number must be less then 40"); return PM3_EINVARG; } From c937e3b760e09beb193c871e80376f5dee30d62c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 24 Jun 2023 00:02:50 +0200 Subject: [PATCH 34/68] fix tear off to work with topaz wrbl. fix topas wrbl to handle LOCK/OTP block 13,14, which needs write_nonerase command, fixed output for rdbl --- armsrc/iso14443a.c | 34 ++++++++-- client/src/cmdhftopaz.c | 138 +++++++++++++++++++++++++++++++++------- 2 files changed, 143 insertions(+), 29 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 01eed12c1..42b42c180 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1291,7 +1291,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r { .response = rPPS, .response_n = sizeof(rPPS) }, // PPS response { .response = rPACK, .response_n = sizeof(rPACK) } // PACK response }; - + // "precompile" responses. There are 12 predefined responses with a total of 84 bytes data to transmit. // Coded responses need one byte per bit to transfer (data, parity, start, stop, correction) @@ -3094,13 +3094,33 @@ void ReaderIso14443a(PacketCommandNG *c) { } } - if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred - FpgaDisableTracing(); - reply_mix(CMD_ACK, 0, 0, 0, NULL, 0); + if ((param & ISO14A_TOPAZMODE)) { + + if (cmd[0] == TOPAZ_WRITE_E8 || cmd[0] == TOPAZ_WRITE_NE8) { + if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred + FpgaDisableTracing(); + reply_mix(CMD_ACK, 0, 0, 0, NULL, 0); + } else { + arg0 = ReaderReceive(buf, par); + FpgaDisableTracing(); + reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf)); + } + } else { + arg0 = ReaderReceive(buf, par); + FpgaDisableTracing(); + reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf)); + } + } else { - arg0 = ReaderReceive(buf, par); - FpgaDisableTracing(); - reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf)); + + if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred + FpgaDisableTracing(); + reply_mix(CMD_ACK, 0, 0, 0, NULL, 0); + } else { + arg0 = ReaderReceive(buf, par); + FpgaDisableTracing(); + reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf)); + } } } diff --git a/client/src/cmdhftopaz.c b/client/src/cmdhftopaz.c index 6311b50ed..766889438 100644 --- a/client/src/cmdhftopaz.c +++ b/client/src/cmdhftopaz.c @@ -224,6 +224,8 @@ static int topaz_write_erase8_block(uint8_t blockno, uint8_t *block_data) { uint16_t resp_len = 11; uint8_t response[11] = {0}; + // + if (topaz_send_cmd(wr8_cmd, sizeof(wr8_cmd), response, &resp_len, true) == PM3_ETIMEOUT) { topaz_switch_off_field(); return PM3_ESOFT; // WriteErase 8bytes failed @@ -243,6 +245,61 @@ static int topaz_write_erase8_block(uint8_t blockno, uint8_t *block_data) { return PM3_ESOFT; } +// write a block (8 Bytes) of a selected Topaz tag. +static int topaz_write_nonerase8_block(uint8_t blockno, uint8_t *block_data) { + + uint8_t atqa[2] = {0}; + uint8_t rid_response[8] = {0}; + int res = topaz_select(atqa, sizeof(atqa), rid_response, sizeof(rid_response), true); + if (res != PM3_SUCCESS) { + return res; + } + + if (atqa[1] != 0x0c && atqa[0] != 0x00) { + return res; + } + + uint8_t *uid_echo = &rid_response[2]; + uint8_t rall_response[124] = {0}; + + res = topaz_rall(uid_echo, rall_response); + if (res == PM3_ESOFT) { + return res; + } + + // ADD + // 7 6 5 4 3 2 1 0 + // b b b --- Byte 0 - 7 + // B B B B --------- BLOCK + // r ----------------- 0 + // + + uint8_t wr8_cmd[] = {TOPAZ_WRITE_NE8, blockno, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + memcpy(wr8_cmd + 10, uid_echo, 4); + memcpy(wr8_cmd + 2, block_data, 8); + + uint16_t resp_len = 11; + uint8_t response[11] = {0}; + + // + if (topaz_send_cmd(wr8_cmd, sizeof(wr8_cmd), response, &resp_len, true) == PM3_ETIMEOUT) { + topaz_switch_off_field(); + return PM3_ESOFT; + } + + if (resp_len != 11) { + return PM3_EFAILED; + } + + if (blockno != response[0]) { + return PM3_EFAILED; + } + + if (memcmp(block_data, response + 1, 8) == 0) { + return PM3_SUCCESS; + } + return PM3_ESOFT; +} // search for the lock area descriptor for the lockable area including byteno static dynamic_lock_area_t *get_dynamic_lock_area(uint16_t byteno) { @@ -402,6 +459,12 @@ static int topaz_print_CC(uint8_t *data) { return PM3_SUCCESS; } +static void topaz_print_hdr(uint8_t blockno) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, " # | block " _GREEN_("0x%02X") " | ascii", blockno); + PrintAndLogEx(INFO, "----+-------------------------+---------"); +} + // return type, length and value of a TLV, starting at memory position *TLV_ptr static void get_TLV(uint8_t **TLV_ptr, uint8_t *TLV_type, uint16_t *TLV_length, uint8_t **TLV_value) { *TLV_length = 0; @@ -782,6 +845,7 @@ static int CmdHFTopazDump(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_str0("f", "file", "", "filename of dump"), + arg_lit0(NULL, "ns", "no save to file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -789,6 +853,8 @@ static int CmdHFTopazDump(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); int status = readTopazUid(false, false); @@ -811,9 +877,18 @@ static int CmdHFTopazDump(const char *Cmd) { ); } - PrintAndLogEx(INFO, "-------------------------------------------------------------"); topaz_switch_off_field(); + // Skip saving card data to file + if (nosave) { + PrintAndLogEx(INFO, "Called with no save option"); + if (set_dynamic) { + free(topaz_tag.dynamic_memory); + } + return PM3_SUCCESS; + } + + // user supplied filename? if (fnlen < 1) { PrintAndLogEx(INFO, "Using UID as filename"); @@ -888,13 +963,13 @@ static int CmdHFTopazRdBl(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf topaz rdbl", - "Read a block", - "hf topaz rdbl -b 7\n" + "Read Topaz block", + "hf topaz rdbl --blk 7\n" ); void *argtable[] = { arg_param_begin, - arg_int1("b", "block", "", "Block number to write"), + arg_int1(NULL, "blk", "", "Block number"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -910,7 +985,11 @@ static int CmdHFTopazRdBl(const char *Cmd) { uint8_t data[8] = {0}; int res = topaz_read_block(blockno, data); if (res == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "Block: %0d (0x%02X) [ %s]", blockno, blockno, sprint_hex(data, sizeof(data))); + + topaz_print_hdr(blockno); + + PrintAndLogEx(INFO, " %2d | %s", blockno, sprint_hex_ascii(data, sizeof(data))); + PrintAndLogEx(NORMAL, ""); } topaz_switch_off_field(); @@ -922,13 +1001,13 @@ static int CmdHFTopazWrBl(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf topaz wrbl", - "Write a block", - "hf topaz wrbl -b 7 -d 1122334455667788\n" + "Write Topaz block with 8 hex bytes of data", + "hf topaz wrbl --blk 7 -d 1122334455667788\n" ); void *argtable[] = { arg_param_begin, - arg_int1("b", "block", "", "Block number to write"), + arg_int1(NULL, "blk", "", "Block number"), arg_str1("d", "data", "", "Block data (8 hex bytes)"), arg_param_end }; @@ -954,14 +1033,23 @@ static int CmdHFTopazWrBl(const char *Cmd) { PrintAndLogEx(INFO, "Block: %0d (0x%02X) [ %s]", blockno, blockno, sprint_hex(data, dlen)); - // send write Block - int res = topaz_write_erase8_block(blockno, data); + int res; + if (blockno != 13 && blockno != 14) { + // send write/erase block + res = topaz_write_erase8_block(blockno, data); + } else { + // send write/non erase block + res = topaz_write_nonerase8_block(blockno, data); + } if (res == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )"); + PrintAndLogEx(HINT, "try `" _YELLOW_("hf topaz rdbl --blk %u") "` to verify", blockno); + } else { PrintAndLogEx(WARNING, "Write ( " _RED_("fail") " )"); } + PrintAndLogEx(NORMAL, ""); topaz_switch_off_field(); return res; @@ -970,18 +1058,24 @@ static int CmdHFTopazWrBl(const char *Cmd) { static int CmdHelp(const char *Cmd); static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"dump", CmdHFTopazDump, IfPm3Iso14443a, "Dump TOPAZ family tag to file"}, - {"list", CmdHFTopazList, AlwaysAvailable, "List Topaz history"}, - {"info", CmdHFTopazInfo, IfPm3Iso14443a, "Tag information"}, - {"reader", CmdHFTopazReader, IfPm3Iso14443a, "Act like a Topaz reader"}, - {"sim", CmdHFTopazSim, IfPm3Iso14443a, "Simulate Topaz tag"}, - {"sniff", CmdHFTopazSniff, IfPm3Iso14443a, "Sniff Topaz reader-tag communication"}, - {"raw", CmdHFTopazRaw, IfPm3Iso14443a, "Send raw hex data to tag"}, - {"rdbl", CmdHFTopazRdBl, IfPm3Iso14443a, "Read block"}, - {"view", CmdHFTopazView, AlwaysAvailable, "Display content from tag dump file"}, - {"wrbl", CmdHFTopazWrBl, IfPm3Iso14443a, "Write block"}, - {NULL, NULL, 0, NULL} + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"list", CmdHFTopazList, AlwaysAvailable, "List Topaz history"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "------------------- " _CYAN_("operations") " ---------------------"}, + {"dump", CmdHFTopazDump, IfPm3Iso14443a, "Dump TOPAZ family tag to file"}, + {"info", CmdHFTopazInfo, IfPm3Iso14443a, "Tag information"}, + {"raw", CmdHFTopazRaw, IfPm3Iso14443a, "Send raw hex data to tag"}, + {"rdbl", CmdHFTopazRdBl, IfPm3Iso14443a, "Read block"}, + {"reader", CmdHFTopazReader, IfPm3Iso14443a, "Act like a Topaz reader"}, + {"sim", CmdHFTopazSim, IfPm3Iso14443a, "Simulate Topaz tag"}, + {"sniff", CmdHFTopazSniff, IfPm3Iso14443a, "Sniff Topaz reader-tag communication"}, + {"view", CmdHFTopazView, AlwaysAvailable, "Display content from tag dump file"}, + {"wrbl", CmdHFTopazWrBl, IfPm3Iso14443a, "Write block"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("ndef") " -----------------------"}, +// {"ndefformat", CmdHFTopazNDEFFormat, IfPm3Iso14443a, "Format Topaz Tag as NFC Tag"}, +// {"ndefread", CmdHFTopazNDEFRead, IfPm3Iso14443a, "Read and print NDEF records from card"}, +// {"ndefwrite", CmdHFTopazNDEFWrite, IfPm3Iso14443a, "Write NDEF records to card"}, + + {NULL, NULL, 0, NULL} }; static int CmdHelp(const char *Cmd) { From f2d6eb3021b949e6c4dda78417152b25574f0e07 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 24 Jun 2023 00:06:26 +0200 Subject: [PATCH 35/68] text --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94d492c41..5e0c9af78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ 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 topaz dump --ns` - now supports nosave param (@iceman1001) + - Changed `hf topaz rdbl` - unified output (@iceman1001) + - Fixed `hf topaz wrbl` - now supports tear off and write_nonerase command (@iceman1001) + - Fixed `hf mf` commands (@iceman1001) + - Fixed `hf mfp` commands (@iceman1001) + - Added more default keys (@iceman1001) Thanks anon! - Fixed `pm3-flash-all` shell script now correctly identify the if running on outdated bootloader (@iceman1001) - Fixed `hf 15693/iclass sniff` trace timings (@nvx) - Fix LegicCash segment handling in `hf_legic.lua` script (@jmichelp) From 636e6bcc6ba3b2914e3304dd700dfe842068adf9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 24 Jun 2023 17:13:23 +0200 Subject: [PATCH 36/68] adapt restore --- client/src/cmdhfmf.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 5a676e390..e0a01b102 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -1385,10 +1385,12 @@ static int CmdHF14AMfRestore(const char *Cmd) { memcpy(wdata, default_key, MIFARE_KEY_SIZE); } - PrintAndLogEx(INFO, " %3d | %s", mfFirstBlockOfSector(s) + b, sprint_hex(bldata, sizeof(bldata))); + uint16_t blockno = (mfFirstBlockOfSector(s) + b); + + PrintAndLogEx(INFO, " %3d | %s", blockno, sprint_hex(bldata, sizeof(bldata))); clearCommandBuffer(); - SendCommandMIX(CMD_HF_MIFARE_WRITEBL, mfFirstBlockOfSector(s) + b, kt, 0, wdata, sizeof(wdata)); + SendCommandMIX(CMD_HF_MIFARE_WRITEBL, blockno, kt, 0, wdata, sizeof(wdata)); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { PrintAndLogEx(WARNING, "Command execute timeout"); @@ -1401,18 +1403,24 @@ static int CmdHF14AMfRestore(const char *Cmd) { break; } else if (isOK == PM3_ETEAROFF) { PrintAndLogEx(INFO, "Tear off triggerd. Recommendation is not to use tear-off with restore command"); - return isOK; + goto out; } else { if (b == 0) { - PrintAndLogEx(INFO, "Writing to manufacture block w key %c ( " _RED_("fail") " )", (kt == MF_KEY_A) ? 'A' : 'B'); + PrintAndLogEx(INFO, "Writing to manufacture block w key " _YELLOW_("%c") " ( " _RED_("fail") " )", + (kt == MF_KEY_A) ? 'A' : 'B' + ); } else { - PrintAndLogEx(FAILED, "Write to block %u w key %c ( " _RED_("fail") " ) ", b, (kt == MF_KEY_A) ? 'A' : 'B'); + PrintAndLogEx(FAILED, "Write to block " _YELLOW_("%u") " w key " _YELLOW_("%c") " ( " _RED_("fail") " ) ", + blockno, + (kt == MF_KEY_A) ? 'A' : 'B' + ); } } } // end loop key types } // end loop B } // end loop S +out: free(ref_dump); free(keyA); free(keyB); From f0a6b1bd672c8f568499adceb842a8860bc13563 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 24 Jun 2023 17:14:56 +0200 Subject: [PATCH 37/68] "hf mf supercard --furui" - add furui supercard key covery. Thanks to Foxushka for the PoC --- client/src/cmdhfmf.c | 416 +++++++++++++++++++++++++++---------------- 1 file changed, 260 insertions(+), 156 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index e0a01b102..c25e00cff 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6753,6 +6753,102 @@ static int CmdHf14AGen3Freeze(const char *Cmd) { return res; } +#define FURUI_MAX_TRACES 8 +static int mfc_furui_recovery(uint8_t items, uint8_t tracedata[FURUI_MAX_TRACES][18]) { + // recover key from collected traces + // outer loop + for (uint8_t i = 0; i < items; i++) { + + // first + nonces_t data; + data.cuid = bytes_to_num(tracedata[i], 4); + data.nonce = bytes_to_num(tracedata[i] + 6, 4); + data.nr = bytes_to_num(tracedata[i] + 10, 4); + data.ar = bytes_to_num(tracedata[i] + 14, 4); + data.at = 0; + + // inner loop + for (uint8_t j = i + 1; j < items; j++) { + + uint8_t *p = tracedata[j]; + PrintAndLogEx(INFO, "%u... %s", i, sprint_hex_inrow(p, 18)); + + // since data stored as block number but its the same key for all blocks in one sector + // we compare with sector number here + uint8_t s = mfSectorNum(tracedata[i][4]); + if (mfSectorNum(p[4]) == s) { + + data.nonce2 = bytes_to_num(p + 6, 4); + data.nr2 = bytes_to_num(p + 10, 4); + data.ar2 = bytes_to_num(p + 14, 4); + data.sector = s; + data.keytype = tracedata[i][5]; + data.state = FIRST; + + uint64_t key64 = -1; + if (mfkey32_moebius(&data, &key64)) { + PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ "_GREEN_("%012" PRIX64) " ]", + sprint_hex_inrow(tracedata[i], 4), + data.sector, + (data.keytype == 0x60) ? 'A' : 'B', + key64 + ); + break; + } + } + } + } + return PM3_SUCCESS; +} + +static int mfc_supercard_gen2_recovery(uint8_t items, uint8_t tracedata[FURUI_MAX_TRACES][18]) { + for (uint8_t i = 0; i < items; i++) { + uint8_t *tmp = tracedata[i]; + + // first + uint16_t NT0 = (tmp[6] << 8) | tmp[7]; + + nonces_t data; + data.cuid = bytes_to_num(tmp, 4); + data.nonce = prng_successor(NT0, 31); + data.nr = bytes_to_num(tmp + 8, 4); + data.ar = bytes_to_num(tmp + 12, 4); + data.at = 0; + + // second + for (uint8_t j = i + 1; j < items; j++) { + uint8_t *p = tracedata[j]; + + // since data stored as block number but its the same key for all blocks in one sector + // we compare with sector number here + uint8_t s = mfSectorNum(tmp[5]); + if (mfSectorNum(p[5]) == s) { + + NT0 = (p[6] << 8) | p[7]; + + data.nonce2 = prng_successor(NT0, 31); + data.nr2 = bytes_to_num(p + 8, 4); + data.ar2 = bytes_to_num(p + 12, 4); + data.sector = s; + data.keytype = tmp[4]; + data.state = FIRST; + + uint64_t key64 = -1; + if (mfkey32_moebius(&data, &key64)) { + PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ "_GREEN_("%012" PRIX64) " ]", + sprint_hex_inrow(tmp, 4), + data.sector, + (data.keytype == 0x60) ? 'A' : 'B', + key64 + ); + break; + } + } + } + } + return PM3_SUCCESS; +} + static int CmdHf14AMfSuperCard(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf supercard", @@ -6765,6 +6861,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { arg_param_begin, arg_lit0("r", "reset", "Reset card"), arg_str0("u", "uid", "", "New UID (4 hex bytes)"), + arg_lit0(NULL, "furui", "Furui detection card"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -6772,6 +6869,8 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { uint8_t uid[4]; int uidlen = 0; int res = CLIParamHexToBuf(arg_get_str(ctx, 2), uid, sizeof(uid), &uidlen); + bool is_furui = arg_get_lit(ctx, 3); + CLIParserFree(ctx); if (res || (!res && uidlen && uidlen != sizeof(uid))) { @@ -6779,15 +6878,53 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { return PM3_EINVARG; } + uint8_t tracedata[FURUI_MAX_TRACES][18]; + + // Super card FURUI + if (is_furui) { + + // no reset on super card FURUI + if (uidlen || reset_card) { + PrintAndLogEx(FAILED, "Not supported on this card"); + return PM3_SUCCESS; + } + + // read 8 traces + uint8_t i; + for (i = 0; i < FURUI_MAX_TRACES; i++) { + + uint8_t data[] = {0xAA, 0xA8, 0x00, i}; + uint32_t flags = ISO14A_CONNECT | ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_RATS; + clearCommandBuffer(); + SendCommandMIX(CMD_HF_ISO14443A_READER, flags, sizeof(data), 0, data, sizeof(data)); + if (WaitForResponseTimeout(CMD_ACK, NULL, 1500) == false) { + break; + } + + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { + break; + } + + uint16_t len = resp.oldarg[0] & 0xFFFF; + if (len != 20) { + break; // Not trace data + } + + PrintAndLogEx(DEBUG, ">>> %s", sprint_hex_inrow(resp.data.asBytes, len)); + memcpy(&tracedata[i], resp.data.asBytes, len - 2); + } + + return mfc_furui_recovery(i, tracedata); + } + #define SUPER_MAX_TRACES 7 - uint8_t trace = 0; - uint8_t traces[SUPER_MAX_TRACES][16]; + // read 7 traces from super card generation 1,2 + uint8_t i = 0; + for (i = 0; i < SUPER_MAX_TRACES; i++) { - // read 7 traces from super card - for (trace = 0; trace < SUPER_MAX_TRACES; trace++) { - - uint8_t data[] = {0x30, 0x00 + trace}; + uint8_t data[] = {0x30, i}; uint32_t flags = ISO14A_CONNECT | ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_RATS; clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO14443A_READER, flags, sizeof(data), 0, data, sizeof(data)); @@ -6805,11 +6942,12 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { break; // Not trace data } - memcpy(&traces[trace], resp.data.asBytes, len - 2); + PrintAndLogEx(DEBUG, ">>> %s", sprint_hex_inrow(resp.data.asBytes, len)); + memcpy(&tracedata[i], resp.data.asBytes, len - 2); } // Super card generation 2 - if (trace == SUPER_MAX_TRACES) { + if (i == SUPER_MAX_TRACES) { // no reset on super card generation 2. if (uidlen || reset_card) { @@ -6818,174 +6956,140 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { } // recover key from collected traces - for (trace = 0; trace < SUPER_MAX_TRACES; trace++) { - uint8_t *trace_data = traces[trace]; - nonces_t data; + return mfc_supercard_gen2_recovery(i, tracedata); + } - // first - uint16_t NT0 = (trace_data[6] << 8) | trace_data[7]; - data.cuid = bytes_to_num(trace_data, 4); - data.nonce = prng_successor(NT0, 31); - data.nr = bytes_to_num(trace_data + 8, 4); - data.ar = bytes_to_num(trace_data + 12, 4); - data.at = 0; + // Super card generation 1 - // second - for (uint8_t s_strace = trace + 1; s_strace < 7; s_strace++) { - uint8_t *s_trace_data = traces[s_strace]; - if (mfSectorNum(s_trace_data[5]) == mfSectorNum(trace_data[5])) { - NT0 = (s_trace_data[6] << 8) | s_trace_data[7]; - data.nonce2 = prng_successor(NT0, 31); - data.nr2 = bytes_to_num(s_trace_data + 8, 4); - data.ar2 = bytes_to_num(s_trace_data + 12, 4); - data.sector = mfSectorNum(trace_data[5]); - data.keytype = trace_data[4]; - data.state = FIRST; + // Commands: + // a0 - set UID + // b0 - read traces + // c0 - clear card + bool activate_field = true; + bool keep_field_on = true; - uint64_t key64 = -1; - if (mfkey32_moebius(&data, &key64)) { - PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ "_GREEN_("%012" PRIX64) " ]", sprint_hex_inrow(trace_data, 4), data.sector, (data.keytype == 0x60) ? 'A' : 'B', key64); - break; - } - } - } - } - - } else { - - // Super card generation 1 - - // Commands: - // a0 - set UID - // b0 - read traces - // c0 - clear card - bool activate_field = true; - bool keep_field_on = true; - - // change UID on a super card generation 1 - if (uidlen) { - keep_field_on = false; - uint8_t response[6]; - int resplen = 0; - - // --------------- CHANGE UID ---------------- - uint8_t aCHANGE[] = {0x00, 0xa6, 0xa0, 0x00, 0x05, 0xff, 0xff, 0xff, 0xff, 0x00}; - memcpy(aCHANGE + 5, uid, uidlen); - res = ExchangeAPDU14a(aCHANGE, sizeof(aCHANGE), activate_field, keep_field_on, response, sizeof(response), - &resplen); - if (res != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "Super card UID change [ " _RED_("fail") " ]"); - DropField(); - return res; - } - - PrintAndLogEx(SUCCESS, "Super card UID change ( " _GREEN_("ok") " )"); - return PM3_SUCCESS; - } - - // reset a super card generation 1 - if (reset_card) { - keep_field_on = false; - uint8_t response[6]; - int resplen = 0; - - // --------------- RESET CARD ---------------- - uint8_t aRESET[] = {0x00, 0xa6, 0xc0, 0x00}; - res = ExchangeAPDU14a(aRESET, sizeof(aRESET), activate_field, keep_field_on, response, sizeof(response), - &resplen); - if (res != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "Super card reset [ " _RED_("fail") " ]"); - DropField(); - return res; - } - PrintAndLogEx(SUCCESS, "Super card reset ( " _GREEN_("ok") " )"); - return PM3_SUCCESS; - } - - - uint8_t responseA[22]; - uint8_t responseB[22]; - int respAlen = 0; - int respBlen = 0; - - // --------------- First ---------------- - uint8_t aFIRST[] = {0x00, 0xa6, 0xb0, 0x00, 0x10}; - res = ExchangeAPDU14a(aFIRST, sizeof(aFIRST), activate_field, keep_field_on, responseA, sizeof(responseA), &respAlen); - if (res != PM3_SUCCESS) { - DropField(); - return res; - } - - // --------------- Second ---------------- - activate_field = false; + // change UID on a super card generation 1 + if (uidlen) { keep_field_on = false; + uint8_t response[6]; + int resplen = 0; - uint8_t aSECOND[] = {0x00, 0xa6, 0xb0, 0x01, 0x10}; - res = ExchangeAPDU14a(aSECOND, sizeof(aSECOND), activate_field, keep_field_on, responseB, sizeof(responseB), &respBlen); + // --------------- CHANGE UID ---------------- + uint8_t aCHANGE[] = {0x00, 0xa6, 0xa0, 0x00, 0x05, 0xff, 0xff, 0xff, 0xff, 0x00}; + memcpy(aCHANGE + 5, uid, uidlen); + res = ExchangeAPDU14a(aCHANGE, sizeof(aCHANGE), activate_field, keep_field_on, response, sizeof(response), + &resplen); if (res != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Super card UID change [ " _RED_("fail") " ]"); DropField(); return res; } - uint8_t outA[16] = {0}; - uint8_t outB[16] = {0}; + PrintAndLogEx(SUCCESS, "Super card UID change ( " _GREEN_("ok") " )"); + return PM3_SUCCESS; + } - uint8_t key[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; - for (uint8_t i = 0; i < 16; i += 8) { - des_decrypt(outA + i, responseA + i, key); - des_decrypt(outB + i, responseB + i, key); + // reset a super card generation 1 + if (reset_card) { + keep_field_on = false; + uint8_t response[6]; + int resplen = 0; + + // --------------- RESET CARD ---------------- + uint8_t aRESET[] = {0x00, 0xa6, 0xc0, 0x00}; + res = ExchangeAPDU14a(aRESET, sizeof(aRESET), activate_field, keep_field_on, response, sizeof(response), + &resplen); + if (res != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Super card reset [ " _RED_("fail") " ]"); + DropField(); + return res; } + PrintAndLogEx(SUCCESS, "Super card reset ( " _GREEN_("ok") " )"); + return PM3_SUCCESS; + } - PrintAndLogEx(DEBUG, " in : %s", sprint_hex_inrow(responseA, respAlen)); - PrintAndLogEx(DEBUG, "out : %s", sprint_hex_inrow(outA, sizeof(outA))); - PrintAndLogEx(DEBUG, " in : %s", sprint_hex_inrow(responseB, respAlen)); - PrintAndLogEx(DEBUG, "out : %s", sprint_hex_inrow(outB, sizeof(outB))); + uint8_t responseA[22]; + uint8_t responseB[22]; + int respAlen = 0; + int respBlen = 0; - if (memcmp(outA, "\x01\x01\x01\x01\x01\x01\x01\x01", 8) == 0) { - PrintAndLogEx(INFO, "No trace recorded"); - return PM3_SUCCESS; - } + // --------------- First ---------------- + uint8_t aFIRST[] = {0x00, 0xa6, 0xb0, 0x00, 0x10}; + res = ExchangeAPDU14a(aFIRST, sizeof(aFIRST), activate_field, keep_field_on, responseA, sizeof(responseA), &respAlen); + if (res != PM3_SUCCESS) { + DropField(); + return res; + } - // second trace? - if (memcmp(outB, "\x01\x01\x01\x01\x01\x01\x01\x01", 8) == 0) { - PrintAndLogEx(INFO, "Only one trace recorded"); - return PM3_SUCCESS; - } + // --------------- Second ---------------- + activate_field = false; + keep_field_on = false; - nonces_t data; + uint8_t aSECOND[] = {0x00, 0xa6, 0xb0, 0x01, 0x10}; + res = ExchangeAPDU14a(aSECOND, sizeof(aSECOND), activate_field, keep_field_on, responseB, sizeof(responseB), &respBlen); + if (res != PM3_SUCCESS) { + DropField(); + return res; + } - // first - uint16_t NT0 = (outA[6] << 8) | outA[7]; - data.cuid = bytes_to_num(outA, 4); - data.nonce = prng_successor(NT0, 31); - data.nr = bytes_to_num(outA + 8, 4); - data.ar = bytes_to_num(outA + 12, 4); - data.at = 0; + uint8_t outA[16] = {0}; + uint8_t outB[16] = {0}; - // second - NT0 = (outB[6] << 8) | outB[7]; - data.nonce2 = prng_successor(NT0, 31); - data.nr2 = bytes_to_num(outB + 8, 4); - data.ar2 = bytes_to_num(outB + 12, 4); - data.sector = mfSectorNum(outA[5]); - data.keytype = outA[4]; - data.state = FIRST; + uint8_t key[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; + for (i = 0; i < 16; i += 8) { + des_decrypt(outA + i, responseA + i, key); + des_decrypt(outB + i, responseB + i, key); + } - PrintAndLogEx(DEBUG, "A Sector %02x", data.sector); - PrintAndLogEx(DEBUG, "A NT %08x", data.nonce); - PrintAndLogEx(DEBUG, "A NR %08x", data.nr); - PrintAndLogEx(DEBUG, "A AR %08x", data.ar); - PrintAndLogEx(DEBUG, ""); - PrintAndLogEx(DEBUG, "B NT %08x", data.nonce2); - PrintAndLogEx(DEBUG, "B NR %08x", data.nr2); - PrintAndLogEx(DEBUG, "B AR %08x", data.ar2); + PrintAndLogEx(DEBUG, " in : %s", sprint_hex_inrow(responseA, respAlen)); + PrintAndLogEx(DEBUG, "out : %s", sprint_hex_inrow(outA, sizeof(outA))); + PrintAndLogEx(DEBUG, " in : %s", sprint_hex_inrow(responseB, respAlen)); + PrintAndLogEx(DEBUG, "out : %s", sprint_hex_inrow(outB, sizeof(outB))); - uint64_t key64 = -1; - if (mfkey32_moebius(&data, &key64)) { - PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ " _GREEN_("%012" PRIX64) " ]", sprint_hex_inrow(outA, 4), data.sector, (data.keytype == 0x60) ? 'A' : 'B', key64); - } else { - PrintAndLogEx(FAILED, "failed to recover any key"); - } + if (memcmp(outA, "\x01\x01\x01\x01\x01\x01\x01\x01", 8) == 0) { + PrintAndLogEx(INFO, "No trace recorded"); + return PM3_SUCCESS; + } + + // second trace? + if (memcmp(outB, "\x01\x01\x01\x01\x01\x01\x01\x01", 8) == 0) { + PrintAndLogEx(INFO, "Only one trace recorded"); + return PM3_SUCCESS; + } + + nonces_t data; + + // first + uint16_t NT0 = (outA[6] << 8) | outA[7]; + data.cuid = bytes_to_num(outA, 4); + data.nonce = prng_successor(NT0, 31); + data.nr = bytes_to_num(outA + 8, 4); + data.ar = bytes_to_num(outA + 12, 4); + data.at = 0; + + // second + NT0 = (outB[6] << 8) | outB[7]; + data.nonce2 = prng_successor(NT0, 31); + data.nr2 = bytes_to_num(outB + 8, 4); + data.ar2 = bytes_to_num(outB + 12, 4); + data.sector = mfSectorNum(outA[5]); + data.keytype = outA[4]; + data.state = FIRST; + + PrintAndLogEx(DEBUG, "A Sector %02x", data.sector); + PrintAndLogEx(DEBUG, "A NT %08x", data.nonce); + PrintAndLogEx(DEBUG, "A NR %08x", data.nr); + PrintAndLogEx(DEBUG, "A AR %08x", data.ar); + PrintAndLogEx(DEBUG, ""); + PrintAndLogEx(DEBUG, "B NT %08x", data.nonce2); + PrintAndLogEx(DEBUG, "B NR %08x", data.nr2); + PrintAndLogEx(DEBUG, "B AR %08x", data.ar2); + + uint64_t key64 = -1; + if (mfkey32_moebius(&data, &key64)) { + PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ " _GREEN_("%012" PRIX64) " ]", sprint_hex_inrow(outA, 4), data.sector, (data.keytype == 0x60) ? 'A' : 'B', key64); + } else { + PrintAndLogEx(FAILED, "failed to recover any key"); } return PM3_SUCCESS; } From 74f02fef8ab672a2eec2be9e061d0c1848c3c837 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 24 Jun 2023 17:16:28 +0200 Subject: [PATCH 38/68] style --- armsrc/iso14443a.c | 4 +- client/src/cmdhfmf.c | 48 +++++------ client/src/cmdhfmfp.c | 62 +++++++------- client/src/cmdhfmfu.c | 4 +- client/src/cmdhftopaz.c | 14 ++-- client/src/cmdtrace.c | 14 ++-- client/src/fileutils.c | 2 +- client/src/mifare/mad.c | 46 +++++------ client/src/pm3line_vocabulory.h | 22 ++--- common/crc16.c | 2 +- doc/commands.json | 138 ++++++++++++++++++++++++-------- doc/commands.md | 24 +++--- 12 files changed, 229 insertions(+), 151 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 42b42c180..9cff73f63 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1291,7 +1291,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r { .response = rPPS, .response_n = sizeof(rPPS) }, // PPS response { .response = rPACK, .response_n = sizeof(rPACK) } // PACK response }; - + // "precompile" responses. There are 12 predefined responses with a total of 84 bytes data to transmit. // Coded responses need one byte per bit to transfer (data, parity, start, stop, correction) @@ -3105,7 +3105,7 @@ void ReaderIso14443a(PacketCommandNG *c) { FpgaDisableTracing(); reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf)); } - } else { + } else { arg0 = ReaderReceive(buf, par); FpgaDisableTracing(); reply_old(CMD_ACK, arg0, 0, 0, buf, sizeof(buf)); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index c25e00cff..765c515e4 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -1395,7 +1395,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { PrintAndLogEx(WARNING, "Command execute timeout"); continue; - } + } int isOK = resp.oldarg[0] & 0xff; if (isOK == 1) { @@ -1406,14 +1406,14 @@ static int CmdHF14AMfRestore(const char *Cmd) { goto out; } else { if (b == 0) { - PrintAndLogEx(INFO, "Writing to manufacture block w key " _YELLOW_("%c") " ( " _RED_("fail") " )", - (kt == MF_KEY_A) ? 'A' : 'B' - ); + PrintAndLogEx(INFO, "Writing to manufacture block w key " _YELLOW_("%c") " ( " _RED_("fail") " )", + (kt == MF_KEY_A) ? 'A' : 'B' + ); } else { PrintAndLogEx(FAILED, "Write to block " _YELLOW_("%u") " w key " _YELLOW_("%c") " ( " _RED_("fail") " ) ", - blockno, - (kt == MF_KEY_A) ? 'A' : 'B' - ); + blockno, + (kt == MF_KEY_A) ? 'A' : 'B' + ); } } } // end loop key types @@ -1424,7 +1424,7 @@ out: free(ref_dump); free(keyA); free(keyB); - PrintAndLogEx(INFO, "-----+------------------------------------------------------------"); + PrintAndLogEx(INFO, "-----+------------------------------------------------------------"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "Done!"); return PM3_SUCCESS; @@ -3604,7 +3604,7 @@ out: // if (singleSector) // printKeyTableEx(1, e_sector, mfSectorNum(blockNo)); // else - printKeyTable(sectors_cnt, e_sector); + printKeyTable(sectors_cnt, e_sector); if (transferToEml) { // fast push mode @@ -6273,7 +6273,7 @@ skipfile: memcpy(block, firstblocks[b], MFBLOCK_SIZE); break; default: { - if (mfIsSectorTrailerBasedOnBlocks(i,j)) { + if (mfIsSectorTrailerBasedOnBlocks(i, j)) { // ST NDEF memcpy(block, firstblocks[7], MFBLOCK_SIZE); } @@ -6787,12 +6787,12 @@ static int mfc_furui_recovery(uint8_t items, uint8_t tracedata[FURUI_MAX_TRACES] uint64_t key64 = -1; if (mfkey32_moebius(&data, &key64)) { - PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ "_GREEN_("%012" PRIX64) " ]", - sprint_hex_inrow(tracedata[i], 4), - data.sector, - (data.keytype == 0x60) ? 'A' : 'B', - key64 - ); + PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ "_GREEN_("%012" PRIX64) " ]", + sprint_hex_inrow(tracedata[i], 4), + data.sector, + (data.keytype == 0x60) ? 'A' : 'B', + key64 + ); break; } } @@ -6836,11 +6836,11 @@ static int mfc_supercard_gen2_recovery(uint8_t items, uint8_t tracedata[FURUI_MA uint64_t key64 = -1; if (mfkey32_moebius(&data, &key64)) { PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ "_GREEN_("%012" PRIX64) " ]", - sprint_hex_inrow(tmp, 4), - data.sector, - (data.keytype == 0x60) ? 'A' : 'B', - key64 - ); + sprint_hex_inrow(tmp, 4), + data.sector, + (data.keytype == 0x60) ? 'A' : 'B', + key64 + ); break; } } @@ -6957,7 +6957,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { // recover key from collected traces return mfc_supercard_gen2_recovery(i, tracedata); - } + } // Super card generation 1 @@ -6978,7 +6978,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { uint8_t aCHANGE[] = {0x00, 0xa6, 0xa0, 0x00, 0x05, 0xff, 0xff, 0xff, 0xff, 0x00}; memcpy(aCHANGE + 5, uid, uidlen); res = ExchangeAPDU14a(aCHANGE, sizeof(aCHANGE), activate_field, keep_field_on, response, sizeof(response), - &resplen); + &resplen); if (res != PM3_SUCCESS) { PrintAndLogEx(FAILED, "Super card UID change [ " _RED_("fail") " ]"); DropField(); @@ -6998,7 +6998,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { // --------------- RESET CARD ---------------- uint8_t aRESET[] = {0x00, 0xa6, 0xc0, 0x00}; res = ExchangeAPDU14a(aRESET, sizeof(aRESET), activate_field, keep_field_on, response, sizeof(response), - &resplen); + &resplen); if (res != PM3_SUCCESS) { PrintAndLogEx(FAILED, "Super card reset [ " _RED_("fail") " ]"); DropField(); diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 089e041d3..52f3da57e 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -995,8 +995,8 @@ static int CmdHFMFPWrbl(const char *Cmd) { } static int plus_key_check(uint8_t startSector, uint8_t endSector, uint8_t startKeyAB, uint8_t endKeyAB, - uint8_t keyList[MAX_AES_KEYS_LIST_LEN][AES_KEY_LEN], size_t keyListLen, uint8_t foundKeys[2][64][AES_KEY_LEN + 1], - bool verbose) { + uint8_t keyList[MAX_AES_KEYS_LIST_LEN][AES_KEY_LEN], size_t keyListLen, uint8_t foundKeys[2][64][AES_KEY_LEN + 1], + bool verbose) { int res; bool selectCard = true; uint8_t keyn[2] = {0}; @@ -1296,10 +1296,10 @@ static int CmdHFMFPChk(const char *Cmd) { for (uint8_t s = startSector; s <= endSector; s++) { if ((memcmp(&foundKeys[0][s][1], ndef_key, AES_KEY_LEN) == 0) || - (memcmp(&foundKeys[1][s][1], ndef_key, AES_KEY_LEN) == 0)) { + (memcmp(&foundKeys[1][s][1], ndef_key, AES_KEY_LEN) == 0)) { has_ndef_key = true; } - + if (printedHeader == false) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "-----+----------------------------------+----------------------------------"); @@ -1320,7 +1320,7 @@ static int CmdHFMFPChk(const char *Cmd) { snprintf(strB, sizeof(strB), _RED_("%s"), "--------------------------------"); } - PrintAndLogEx(INFO, " " _YELLOW_("%03d") " | %s | %s", s, strA, strB); + PrintAndLogEx(INFO, " " _YELLOW_("%03d") " | %s | %s", s, strA, strB); } if (printedHeader == false) @@ -1395,7 +1395,7 @@ static int CmdHFMFPDump(const char *Cmd) { arg_str0("f", "file", "", "filename of dump"), arg_str0("k", "keys", "", "filename of keys"), arg_lit0(NULL, "ns", "no save to file"), - arg_lit0("v", "verbose", "Verbose mode"), + arg_lit0("v", "verbose", "Verbose mode"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1421,14 +1421,14 @@ static int CmdHFMFPDump(const char *Cmd) { return PM3_EMALLOC; } -/* - iso14a_card_select_t card ; - int res = mfp_read_tag(&card, mem, key_fn); - if (res != PM3_SUCCESS) { - free(mem); - return res; - } -*/ + /* + iso14a_card_select_t card ; + int res = mfp_read_tag(&card, mem, key_fn); + if (res != PM3_SUCCESS) { + free(mem); + return res; + } + */ // Skip saving card data to file if (nosave) { @@ -1436,28 +1436,28 @@ static int CmdHFMFPDump(const char *Cmd) { free(mem); return PM3_SUCCESS; } -/* - // Save to file - if (strlen(data_fn) < 1) { + /* + // Save to file + if (strlen(data_fn) < 1) { - char *fptr = calloc(sizeof(char) * (strlen("hf-mfp-") + strlen("-dump")) + card.uidlen * 2 + 1, sizeof(uint8_t)); - strcpy(fptr, "hf-mfp-"); + char *fptr = calloc(sizeof(char) * (strlen("hf-mfp-") + strlen("-dump")) + card.uidlen * 2 + 1, sizeof(uint8_t)); + strcpy(fptr, "hf-mfp-"); - FillFileNameByUID(fptr, card.uid, "-dump", card.uidlen); + FillFileNameByUID(fptr, card.uid, "-dump", card.uidlen); - strcpy(data_fn, fptr); - free(fptr); - } + strcpy(data_fn, fptr); + free(fptr); + } - saveFile(data_fn, ".bin", mem, MIFARE_4K_MAX_BYTES); - saveFileEML(data_fn, mem, MIFARE_4K_MAX_BYTES, MFBLOCK_SIZE); + saveFile(data_fn, ".bin", mem, MIFARE_4K_MAX_BYTES); + saveFileEML(data_fn, mem, MIFARE_4K_MAX_BYTES, MFBLOCK_SIZE); - iso14a_mf_extdump_t xdump; - xdump.card_info = card; - xdump.dump = mem; - xdump.dumplen = MIFARE_4K_MAX_BYTES; - saveFileJSON(data_fn, jsfCardMemory, (uint8_t *)&xdump, sizeof(xdump), NULL); -*/ + iso14a_mf_extdump_t xdump; + xdump.card_info = card; + xdump.dump = mem; + xdump.dumplen = MIFARE_4K_MAX_BYTES; + saveFileJSON(data_fn, jsfCardMemory, (uint8_t *)&xdump, sizeof(xdump), NULL); + */ free(mem); return PM3_SUCCESS; } diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index e17032507..9f7f54c53 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -1424,7 +1424,7 @@ static mfu_identify_t *mfu_match_fingerprint(uint8_t *version, uint8_t *data) { uint8_t mtmp[40] = {0}; param_gethex_to_eol(mfu_ident_table[i].match, 0, mtmp, sizeof(mtmp), &ml); - bool m2 = (memcmp(mtmp, data + mfu_ident_table[i].mpos, mfu_ident_table[i].mlen) == 0); + bool m2 = (memcmp(mtmp, data + mfu_ident_table[i].mpos, mfu_ident_table[i].mlen) == 0); if (m2) { PrintAndLogEx(DEBUG, "(fingerprint) found %s", mfu_ident_table[i].desc); return &mfu_ident_table[i]; @@ -3608,7 +3608,7 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) { if (ul_select(&card)) { // Philips toothbrush needs page 0x21-0x23 uint8_t data[16] = {0x00}; - int status = ul_read(0x21, data, sizeof(data)); + int status = ul_read(0x21, data, sizeof(data)); if (status == -1) { PrintAndLogEx(DEBUG, "Error: tag didn't answer to READ"); } else if (status == 16) { diff --git a/client/src/cmdhftopaz.c b/client/src/cmdhftopaz.c index 766889438..4483e3154 100644 --- a/client/src/cmdhftopaz.c +++ b/client/src/cmdhftopaz.c @@ -224,7 +224,7 @@ static int topaz_write_erase8_block(uint8_t blockno, uint8_t *block_data) { uint16_t resp_len = 11; uint8_t response[11] = {0}; - // + // if (topaz_send_cmd(wr8_cmd, sizeof(wr8_cmd), response, &resp_len, true) == PM3_ETIMEOUT) { topaz_switch_off_field(); @@ -267,12 +267,12 @@ static int topaz_write_nonerase8_block(uint8_t blockno, uint8_t *block_data) { return res; } - // ADD + // ADD // 7 6 5 4 3 2 1 0 // b b b --- Byte 0 - 7 - // B B B B --------- BLOCK + // B B B B --------- BLOCK // r ----------------- 0 - // + // uint8_t wr8_cmd[] = {TOPAZ_WRITE_NE8, blockno, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; memcpy(wr8_cmd + 10, uid_echo, 4); @@ -281,7 +281,7 @@ static int topaz_write_nonerase8_block(uint8_t blockno, uint8_t *block_data) { uint16_t resp_len = 11; uint8_t response[11] = {0}; - // + // if (topaz_send_cmd(wr8_cmd, sizeof(wr8_cmd), response, &resp_len, true) == PM3_ETIMEOUT) { topaz_switch_off_field(); return PM3_ESOFT; @@ -883,7 +883,7 @@ static int CmdHFTopazDump(const char *Cmd) { if (nosave) { PrintAndLogEx(INFO, "Called with no save option"); if (set_dynamic) { - free(topaz_tag.dynamic_memory); + free(topaz_tag.dynamic_memory); } return PM3_SUCCESS; } @@ -1034,7 +1034,7 @@ static int CmdHFTopazWrBl(const char *Cmd) { PrintAndLogEx(INFO, "Block: %0d (0x%02X) [ %s]", blockno, blockno, sprint_hex(data, dlen)); int res; - if (blockno != 13 && blockno != 14) { + if (blockno != 13 && blockno != 14) { // send write/erase block res = topaz_write_erase8_block(blockno, data); } else { diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index c2e750623..323c7ef7e 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -571,9 +571,9 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr //2 Not crc-command // Draw the data column - #define TRACE_MAX_LINES 36 +#define TRACE_MAX_LINES 36 // number of hex bytes to be printed per row (16 data + 2 crc) - #define TRACE_MAX_HEX_BYTES 18 +#define TRACE_MAX_HEX_BYTES 18 char line[TRACE_MAX_LINES][160] = {{0}}; @@ -700,8 +700,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr // mark short bytes (less than 8 Bit + Parity) if (protocol == ISO_14443A || - protocol == PROTO_MIFARE || - protocol == THINFILM) { + protocol == PROTO_MIFARE || + protocol == THINFILM) { // approximated with 128 * (9 * data_len); uint16_t bitime = 1056 + 32; @@ -874,13 +874,13 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr } else { - if (last_line && (memcmp(crc, "\x20\x20\x20\x20", 4) != 0) && g_session.supports_colors && markCRCBytes) { + if (last_line && (memcmp(crc, "\x20\x20\x20\x20", 4) != 0) && g_session.supports_colors && markCRCBytes) { str_padder = 85; // odd case of multiline, and last single byte on empty row has been colorised... if (strlen(line[j]) < 14) { str_padder = 81; } - } + } if (hdr->isResponse) { PrintAndLogEx(NORMAL, " | | |%-*s | %s| %s", @@ -909,7 +909,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr annotateIso14443a(explanation, sizeof(explanation), mfData, mfDataLen, hdr->isResponse); uint8_t crcc = iso14443A_CRC_check(hdr->isResponse, mfData, mfDataLen); - //iceman: colorise crc bytes here will need a refactor of code from above. + //iceman: colorise crc bytes here will need a refactor of code from above. PrintAndLogEx(NORMAL, " | | * |%-*s | %-4s| %s", str_padder, sprint_hex_inrow_spaces(mfData, mfDataLen, 2), diff --git a/client/src/fileutils.c b/client/src/fileutils.c index 917a7ee77..4dba2c1e4 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -1313,7 +1313,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz // memcpy(vdata, udata.bytes + (14 + atslen), 2 * 64 * 17); for (size_t i = 0; i < 64; i++) { - + if ((sptr + (AES_KEY_LEN * 2)) > maxdatalen) { break; } diff --git a/client/src/mifare/mad.c b/client/src/mifare/mad.c index 42a05c5a2..54f67a6a4 100644 --- a/client/src/mifare/mad.c +++ b/client/src/mifare/mad.c @@ -333,19 +333,19 @@ int MAD1DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose, bool *haveMA for (int i = 1; i < 16; i++) { uint16_t aid = madGetAID(sector, swapmad, 1, i); if (aid < 6) { - PrintAndLogEx(INFO, - (ibs == i) ? _MAGENTA_(" %02d [%04X] %s") : " %02d [" _GREEN_("%04X") "] %s", - i, - aid, - aid_admin[aid] - ); + PrintAndLogEx(INFO, + (ibs == i) ? _MAGENTA_(" %02d [%04X] %s") : " %02d [" _GREEN_("%04X") "] %s", + i, + aid, + aid_admin[aid] + ); } else if (prev_aid == aid) { - PrintAndLogEx(INFO, - (ibs == i) ? _MAGENTA_(" %02d [%04X] continuation") : " %02d [" _YELLOW_("%04X") "] continuation", - i, - aid - ); + PrintAndLogEx(INFO, + (ibs == i) ? _MAGENTA_(" %02d [%04X] continuation") : " %02d [" _YELLOW_("%04X") "] continuation", + i, + aid + ); } else { char fmt[60]; snprintf(fmt, sizeof(fmt), (ibs == i) ? _MAGENTA_(" %02d [%04X]%s") : " %02d [" _GREEN_("%04X") "]%s", i, aid, "%s"); @@ -368,7 +368,7 @@ int MAD2DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose) { if (res == PM3_SUCCESS) PrintAndLogEx(SUCCESS, "CRC8...... 0x%02X ( " _GREEN_("%s") " )", sector[0], "ok"); else - PrintAndLogEx(SUCCESS, "CRC8...... 0x%02X ( " _RED_("%s") " )", sector[0], "fail"); + PrintAndLogEx(SUCCESS, "CRC8...... 0x%02X ( " _RED_("%s") " )", sector[0], "fail"); } int ibs = MADInfoByteDecode(sector, swapmad, 2, verbose); @@ -387,18 +387,18 @@ int MAD2DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose) { for (int i = 1; i < 8 + 8 + 7 + 1; i++) { uint16_t aid = madGetAID(sector, swapmad, 2, i); if (aid < 6) { - PrintAndLogEx(INFO, - (ibs == i) ? _MAGENTA_(" %02d [%04X] %s") : " %02d [" _GREEN_("%04X") "] %s", - i + 16, - aid, - aid_admin[aid] - ); + PrintAndLogEx(INFO, + (ibs == i) ? _MAGENTA_(" %02d [%04X] %s") : " %02d [" _GREEN_("%04X") "] %s", + i + 16, + aid, + aid_admin[aid] + ); } else if (prev_aid == aid) { - PrintAndLogEx(INFO, - (ibs == i) ? _MAGENTA_(" %02d [%04X] continuation") : " %02d [" _YELLOW_("%04X") "] continuation", - i + 16, - aid - ); + PrintAndLogEx(INFO, + (ibs == i) ? _MAGENTA_(" %02d [%04X] continuation") : " %02d [" _YELLOW_("%04X") "] continuation", + i + 16, + aid + ); } else { char fmt[60]; snprintf(fmt, sizeof(fmt), (ibs == i) ? _MAGENTA_(" %02d [%04X]%s") : " %02d [" _GREEN_("%04X") "]%s", i + 16, aid, "%s"); diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index ffe9c66ff..ffad57057 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -367,17 +367,21 @@ const static vocabulory_t vocabulory[] = { { 0, "hf mf ndefread" }, { 0, "hf mf ndefwrite" }, { 1, "hf mfp help" }, - { 0, "hf mfp info" }, - { 0, "hf mfp wrp" }, - { 0, "hf mfp initp" }, - { 0, "hf mfp commitp" }, + { 1, "hf mfp list" }, { 0, "hf mfp auth" }, + { 0, "hf mfp chk" }, + { 0, "hf mfp dump" }, + { 0, "hf mfp info" }, + { 0, "hf mfp mad" }, { 0, "hf mfp rdbl" }, { 0, "hf mfp rdsc" }, { 0, "hf mfp wrbl" }, - { 0, "hf mfp chk" }, - { 0, "hf mfp mad" }, + { 0, "hf mfp commitp" }, + { 0, "hf mfp initp" }, + { 0, "hf mfp wrp" }, + { 0, "hf mfp ndefformat" }, { 0, "hf mfp ndefread" }, + { 0, "hf mfp ndefwrite" }, { 1, "hf mfu help" }, { 1, "hf mfu keygen" }, { 1, "hf mfu pwdgen" }, @@ -461,14 +465,14 @@ const static vocabulory_t vocabulory[] = { { 1, "hf thinfilm list" }, { 0, "hf thinfilm sim" }, { 1, "hf topaz help" }, - { 0, "hf topaz dump" }, { 1, "hf topaz list" }, + { 0, "hf topaz dump" }, { 0, "hf topaz info" }, + { 0, "hf topaz raw" }, + { 0, "hf topaz rdbl" }, { 0, "hf topaz reader" }, { 0, "hf topaz sim" }, { 0, "hf topaz sniff" }, - { 0, "hf topaz raw" }, - { 0, "hf topaz rdbl" }, { 1, "hf topaz view" }, { 0, "hf topaz wrbl" }, { 1, "hf xerox help" }, diff --git a/common/crc16.c b/common/crc16.c index d402977b9..812cd3481 100644 --- a/common/crc16.c +++ b/common/crc16.c @@ -354,4 +354,4 @@ uint16_t crc16_legic(uint8_t const *d, size_t n, uint8_t uidcrc) { uint16_t crc16_philips(uint8_t const *d, size_t n) { return crc16_fast(d, n, 0x49A3, false, false); -} \ No newline at end of file +} diff --git a/doc/commands.json b/doc/commands.json index efb03edd2..7a19db4f2 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -3966,14 +3966,16 @@ "command": "hf mf auth4", "description": "Executes AES authentication command in ISO14443-4", "notes": [ - "hf mf auth4 4000 000102030405060708090a0b0c0d0e0f -> executes authentication", - "hf mf auth4 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> executes authentication" + "hf mf auth4 -n 4000 -k 000102030405060708090a0b0c0d0e0f -> executes authentication", + "hf mf auth4 -n 9003 -k FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> executes authentication" ], "offline": false, "options": [ - "-h, --help This help" + "-h, --help This help", + "-n key num, 2 hex bytes", + "-k, --key key, 16 hex bytes" ], - "usage": "hf mf auth4 [-h] " + "usage": "hf mf auth4 [-h] -n -k " }, "hf mf autopwn": { "command": "hf mf autopwn", @@ -4655,14 +4657,14 @@ "options": [ "-h, --help This help", "-v, --verbose show technical data", - "--aid print all sectors with specified aid", - "-k, --key key for printing sectors", + "--aid print all sectors with specified aid", + "-k, --key key for printing sectors", "-b, --keyb use key B for access printing sectors (by default: key A)", "--be (optional, BigEndian)", "--dch decode Card Holder information", "-f, --file load dump file and decode MAD" ], - "usage": "hf mf mad [-hvb] [--aid ] [-k ] [--be] [--dch] [-f ]" + "usage": "hf mf mad [-hvb] [--aid ] [-k ] [--be] [--dch] [-f ]" }, "hf mf nack": { "command": "hf mf nack", @@ -4784,7 +4786,8 @@ "command": "hf mf rdbl", "description": "Read MIFARE Classic block", "notes": [ - "hf mf rdbl --blk 0 -k FFFFFFFFFFFF", + "hf mf rdbl --blk 0", + "hf mf rdbl --blk 0 -k A0A1A2A3A4A5", "hf mf rdbl --blk 3 -v -> get block 3, decode sector trailer" ], "offline": false, @@ -4802,7 +4805,8 @@ "command": "hf mf rdsc", "description": "Read MIFARE Classic sector", "notes": [ - "hf mf rdsc -s 0 -k FFFFFFFFFFFF" + "hf mf rdsc -s 0", + "hf mf rdsc -s 0 -k A0A1A2A3A4A5" ], "offline": false, "options": [ @@ -4906,9 +4910,10 @@ "options": [ "-h, --help This help", "-r, --reset Reset card", - "-u, --uid New UID (4 hex bytes)" + "-u, --uid New UID (4 hex bytes)", + "--furui Furui detection card" ], - "usage": "hf mf supercard [-hr] [-u ]" + "usage": "hf mf supercard [-hr] [-u ] [--furui]" }, "hf mf value": { "command": "hf mf value", @@ -4976,7 +4981,8 @@ "command": "hf mf wrbl", "description": "Write MIFARE Classic block with 16 hex bytes of data Sector 0 / Block 0 - Manufacturer block When writing to block 0 you must use a VALID block 0 data (UID, BCC, SAK, ATQA) Writing an invalid block 0 means rendering your Magic GEN2 card undetectable. Look in the magic_cards_notes.md file for help to resolve it. `--force` param is used to override warnings like bad ACL and BLOCK 0 writes. if not specified, it will exit if detected", "notes": [ - "hf mf wrbl --blk 1 -k FFFFFFFFFFFF -d 000102030405060708090a0b0c0d0e0f" + "hf mf wrbl --blk 1 -d 000102030405060708090a0b0c0d0e0f", + "hf mf wrbl --blk 1 -k A0A1A2A3A4A5 -d 000102030405060708090a0b0c0d0e0f" ], "offline": false, "options": [ @@ -6126,7 +6132,7 @@ }, "hf mfp auth": { "command": "hf mfp auth", - "description": "Executes AES authentication command for Mifare Plus card", + "description": "Executes AES authentication command for MIFARE Plus card", "notes": [ "hf mfp auth --ki 4000 --key 000102030405060708090a0b0c0d0e0f -> executes authentication", "hf mfp auth --ki 9003 --key FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -v -> executes authentication and shows all the system data" @@ -6145,9 +6151,9 @@ "description": "Checks keys on MIFARE Plus card", "notes": [ "hf mfp chk -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B", - "hf mfp chk -s 2 -a -> check default key list on sector 2, key A", + "hf mfp chk -s 2 -a -> check default key list on sector 2, only key A", "hf mfp chk -d mfp_default_keys -s0 -e6 -> check keys from dictionary against sectors 0-6", - "hf mfp chk --pattern1b -j keys -> check all 1-byte keys pattern and save found keys to json", + "hf mfp chk --pattern1b --dump -> check all 1-byte keys pattern and save found keys to file", "hf mfp chk --pattern2b --startp2b FA00 -> check all 2-byte keys pattern. Start from key FA00FA00...FA00" ], "offline": false, @@ -6162,10 +6168,10 @@ "--pattern1b Check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)", "--pattern2b Check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)", "--startp2b Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)", - "-j, --json Json filename to save keys", + "--dump Dump found keys to JSON file", "-v, --verbose Verbose mode" ], - "usage": "hf mfp chk [-habv] [-s <0..255>] [-e <0..255>] [-k ] [-d ] [--pattern1b] [--pattern2b] [--startp2b ] [-j ]" + "usage": "hf mfp chk [-habv] [-s <0..255>] [-e <0..255>] [-k ] [-d ] [--pattern1b] [--pattern2b] [--startp2b ] [--dump]" }, "hf mfp commitp": { "command": "hf mfp commitp", @@ -6180,9 +6186,26 @@ ], "usage": "hf mfp commitp [-hv]" }, + "hf mfp dump": { + "command": "hf mfp dump", + "description": "Dump MIFARE Plus tag to binary file If no given, UID will be used as filename", + "notes": [ + "hf mfp dump", + "hf mfp dump --keys hf-mf-066C8B78-key.bin -> MIFARE Plus with keys from specified file" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-f, --file filename of dump", + "-k, --keys filename of keys", + "--ns no save to file", + "-v, --verbose Verbose mode" + ], + "usage": "hf mfp dump [-hv] [-f ] [-k ] [--ns]" + }, "hf mfp help": { "command": "hf mfp help", - "description": "help This help", + "description": "help This help list List MIFARE Plus history", "notes": [], "offline": true, "options": [], @@ -6215,9 +6238,30 @@ ], "usage": "hf mfp initp [-hv] [-k ]" }, + "hf mfp list": { + "command": "hf mfp list", + "description": "Alias of `trace list -t mf` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", + "notes": [ + "hf mf list --frame -> show frame delay times", + "hf mf list -1 -> use trace buffer" + ], + "offline": true, + "options": [ + "-h, --help This help", + "-1, --buffer use data from trace buffer", + "--frame show frame delay times", + "-c mark CRC bytes", + "-r show relative times (gap and duration)", + "-u display times in microseconds instead of clock cycles", + "-x show hexdump to convert to pcap(ng)", + "or to import into Wireshark using encapsulation type \"ISO 14443\"", + "-f, --file filename of dictionary" + ], + "usage": "hf mf list [-h1crux] [--frame] [-f ]" + }, "hf mfp mad": { "command": "hf mfp mad", - "description": "Checks and prints Mifare Application Directory (MAD)", + "description": "Checks and prints MIFARE Application Directory (MAD)", "notes": [ "hf mfp mad", "hf mfp mad --aid e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> read and print NDEF data from MAD aid" @@ -6234,6 +6278,14 @@ ], "usage": "hf mfp mad [-hvb] [--aid ] [-k ] [--be] [--dch]" }, + "hf mfp ndefformat": { + "command": "hf mfp ndefformat", + "description": "format MIFARE Plus Tag as a NFC tag with Data Exchange Format (NDEF) If no given, UID will be used as filename. It will try default keys and MAD keys to detect if tag is already formatted in order to write.", + "notes": [], + "offline": false, + "options": [], + "usage": "" + }, "hf mfp ndefread": { "command": "hf mfp ndefread", "description": "Prints NFC Data Exchange Format (NDEF)", @@ -6254,9 +6306,27 @@ ], "usage": "hf mfp ndefread [-hvb] [--aid ] [-k ] [-f ]" }, + "hf mfp ndefwrite": { + "command": "hf mfp ndefwrite", + "description": "Write raw NDEF hex bytes to tag. This commands assumes tag already been NFC/NDEF formatted.", + "notes": [ + "hf mfp ndefwrite -d 0300FE -> write empty record to tag", + "hf mfp ndefwrite -f myfilename", + "hf mfp ndefwrite -d 033fd1023a53709101195405656e2d55534963656d616e2054776974746572206c696e6b5101195502747769747465722e636f6d2f686572726d616e6e31303031" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-d raw NDEF hex bytes", + "-f, --file write raw NDEF file to tag", + "-p fix NDEF record headers / terminator block if missing", + "-v, --verbose verbose output" + ], + "usage": "hf mfp ndefwrite [-hpv] [-d ] [-f ]" + }, "hf mfp rdbl": { "command": "hf mfp rdbl", - "description": "Reads several blocks from Mifare Plus card", + "description": "Reads blocks from MIFARE Plus card", "notes": [ "hf mfp rdbl --blk 0 --key 000102030405060708090a0b0c0d0e0f -> executes authentication and read block 0 data", "hf mfp rdbl --blk 1 -v -> executes authentication and shows sector 1 data with default key 0xFF..0xFF" @@ -6293,7 +6363,7 @@ }, "hf mfp wrbl": { "command": "hf mfp wrbl", - "description": "Writes one block to Mifare Plus card", + "description": "Writes one block to MIFARE Plus card", "notes": [ "hf mfp wrbl --blk 1 -d ff0000000000000000000000000000ff --key 000102030405060708090a0b0c0d0e0f -> write block 1 data", "hf mfp wrbl --blk 2 -d ff0000000000000000000000000000ff -v -> write block 2 data with default key 0xFF..0xFF" @@ -7024,9 +7094,10 @@ "offline": false, "options": [ "-h, --help This help", - "-f, --file filename of dump" + "-f, --file filename of dump", + "--ns no save to file" ], - "usage": "hf topaz dump [-h] [-f ]" + "usage": "hf topaz dump [-h] [-f ] [--ns]" }, "hf topaz help": { "command": "hf topaz help", @@ -7086,16 +7157,16 @@ }, "hf topaz rdbl": { "command": "hf topaz rdbl", - "description": "Read a block", + "description": "Read Topaz block", "notes": [ - "hf topaz rdbl -b 7" + "hf topaz rdbl --blk 7" ], "offline": false, "options": [ "-h, --help This help", - "-b, --block Block number to write" + "--blk Block number" ], - "usage": "hf topaz rdbl [-h] -b " + "usage": "hf topaz rdbl [-h] --blk " }, "hf topaz reader": { "command": "hf topaz reader", @@ -7151,17 +7222,17 @@ }, "hf topaz wrbl": { "command": "hf topaz wrbl", - "description": "Write a block", + "description": "Write Topaz block with 8 hex bytes of data", "notes": [ - "hf topaz wrbl -b 7 -d 1122334455667788" + "hf topaz wrbl --blk 7 -d 1122334455667788" ], "offline": false, "options": [ "-h, --help This help", - "-b, --block Block number to write", + "--blk Block number", "-d, --data Block data (8 hex bytes)" ], - "usage": "hf topaz wrbl [-h] -b -d " + "usage": "hf topaz wrbl [-h] --blk -d " }, "hf tune": { "command": "hf tune", @@ -12022,9 +12093,8 @@ } }, "metadata": { - "commands_extracted": 755, + "commands_extracted": 759, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-06-04T15:36:56" - + "extracted_on": "2023-06-24T15:16:04" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 938413fa8..a27cf6964 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -538,17 +538,21 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`hf mfp help `|Y |`This help` -|`hf mfp info `|N |`Info about Mifare Plus tag` -|`hf mfp wrp `|N |`Write Perso command` -|`hf mfp initp `|N |`Fill all the card's keys in SL0 mode` -|`hf mfp commitp `|N |`Move card to SL1 or SL3 mode` +|`hf mfp list `|Y |`List MIFARE Plus history` |`hf mfp auth `|N |`Authentication` -|`hf mfp rdbl `|N |`Read blocks` -|`hf mfp rdsc `|N |`Read sectors` -|`hf mfp wrbl `|N |`Write blocks` |`hf mfp chk `|N |`Check keys` +|`hf mfp dump `|N |`Dump MIFARE Plus tag to binary file` +|`hf mfp info `|N |`Info about MIFARE Plus tag` |`hf mfp mad `|N |`Check and print MAD` +|`hf mfp rdbl `|N |`Read blocks from card` +|`hf mfp rdsc `|N |`Read sectors from card` +|`hf mfp wrbl `|N |`Write block to card` +|`hf mfp commitp `|N |`Configure security layer (SL1/SL3 mode)` +|`hf mfp initp `|N |`Fill all the card's keys in SL0 mode` +|`hf mfp wrp `|N |`Write Perso command` +|`hf mfp ndefformat `|N |`Format MIFARE Plus Tag as NFC Tag` |`hf mfp ndefread `|N |`Read and print NDEF records from card` +|`hf mfp ndefwrite `|N |`Write NDEF records to card` ### hf mfu @@ -704,14 +708,14 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`hf topaz help `|Y |`This help` -|`hf topaz dump `|N |`Dump TOPAZ family tag to file` |`hf topaz list `|Y |`List Topaz history` +|`hf topaz dump `|N |`Dump TOPAZ family tag to file` |`hf topaz info `|N |`Tag information` +|`hf topaz raw `|N |`Send raw hex data to tag` +|`hf topaz rdbl `|N |`Read block` |`hf topaz reader `|N |`Act like a Topaz reader` |`hf topaz sim `|N |`Simulate Topaz tag` |`hf topaz sniff `|N |`Sniff Topaz reader-tag communication` -|`hf topaz raw `|N |`Send raw hex data to tag` -|`hf topaz rdbl `|N |`Read block` |`hf topaz view `|Y |`Display content from tag dump file` |`hf topaz wrbl `|N |`Write block` From fe204d852906490ecbc25f22538a1a383ee8b33e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 24 Jun 2023 17:28:43 +0200 Subject: [PATCH 39/68] text --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e0c9af78..63c3e2ac6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ 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 topaz dump --ns` - now supports nosave param (@iceman1001) + - Added `hf mf supercard --furui` - now supports key recovery from Furui detection card. Thanks foxushka! (@iceman1001) + - Added `hf topaz dump --ns` - now supports nosave param (@iceman1001) - Changed `hf topaz rdbl` - unified output (@iceman1001) - Fixed `hf topaz wrbl` - now supports tear off and write_nonerase command (@iceman1001) - Fixed `hf mf` commands (@iceman1001) From a43d8ea9e05b872ba2b3a5db946bae7c6dc99ef5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 24 Jun 2023 22:01:10 +0200 Subject: [PATCH 40/68] adapted viewing MFC dump files to also colorize ACL + GPB bytes --- CHANGELOG.md | 1 + client/src/cmdhfmf.c | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63c3e2ac6..1af068e19 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] + - Change viewing MFC dump files - it now colors ACL + GPB bytes (@iceman1001) - Added `hf mf supercard --furui` - now supports key recovery from Furui detection card. Thanks foxushka! (@iceman1001) - Added `hf topaz dump --ns` - now supports nosave param (@iceman1001) - Changed `hf topaz rdbl` - unified output (@iceman1001) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 765c515e4..fcf898a42 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -251,7 +251,27 @@ static void mf_print_block(uint8_t blockno, uint8_t *d, bool verbose) { if (blockno == 0) { PrintAndLogEx(INFO, "%s| %3d | " _RED_("%s"), secstr, blockno, sprint_hex_ascii(d, MFBLOCK_SIZE)); } else if (mfIsSectorTrailer(blockno)) { - PrintAndLogEx(INFO, "%s| %3d | " _YELLOW_("%s"), secstr, blockno, sprint_hex_ascii(d, MFBLOCK_SIZE)); + + char keya[26] = {0}; + hex_to_buffer((uint8_t *)keya, d, MIFARE_KEY_SIZE, sizeof(keya) - 1, 0, 1, true); + + char acl[20] = {0}; + hex_to_buffer((uint8_t *)acl, d + MIFARE_KEY_SIZE, 4, sizeof(acl) - 1, 0, 1, true); + + char keyb[26] = {0}; + hex_to_buffer((uint8_t *)keyb, d + 10, MIFARE_KEY_SIZE, sizeof(keyb) - 1, 0, 1, true); + + char ascii[24] = {0}; + ascii_to_buffer((uint8_t *)ascii, d, MFBLOCK_SIZE, sizeof(ascii) - 1, 1); + + PrintAndLogEx(INFO, "%s| %3d | " _YELLOW_("%s") _MAGENTA_("%s") _YELLOW_("%s") "| " _YELLOW_("%s"), + secstr, + blockno, + keya, + acl, + keyb, + ascii + ); } else { int32_t value = 0; if (verbose && mfc_value(d, &value)) { From 85f8234201716168d7f8017324124810c5730e48 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 24 Jun 2023 22:24:27 +0200 Subject: [PATCH 41/68] fix wrong key file name --- client/src/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index fcf898a42..795ae2b81 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -381,7 +381,7 @@ static int mf_save_keys_from_arr(uint16_t n, uint8_t *d) { } char fn[FILE_PATH_SIZE] = {0}; - snprintf(fn, sizeof(fn), "hf-mf-%s-keys", sprint_hex_inrow(d, 4)); + snprintf(fn, sizeof(fn), "hf-mf-%s-key", sprint_hex_inrow(d, 4)); saveFile(fn, ".bin", keys, keysize); free(keys); return PM3_SUCCESS; From 0f35e89f4e94b597aa6569fc0911cf579ce54bf7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 24 Jun 2023 23:03:43 +0200 Subject: [PATCH 42/68] data diff now prints filenames if they fit in the header. Spiff filenames and other params is untouched --- CHANGELOG.md | 3 ++- client/src/cmddata.c | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1af068e19..3c11a1112 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ 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] - - Change viewing MFC dump files - it now colors ACL + GPB bytes (@iceman1001) + - Changed `data diff` - to print filenames in header if it fits (@iceman1001) + - Changed viewing MFC dump files - it now colors ACL + GPB bytes (@iceman1001) - Added `hf mf supercard --furui` - now supports key recovery from Furui detection card. Thanks foxushka! (@iceman1001) - Added `hf topaz dump --ns` - now supports nosave param (@iceman1001) - Changed `hf topaz rdbl` - unified output (@iceman1001) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 9524cbc63..e1bf655e4 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -2939,7 +2939,7 @@ static int CmdDiff(const char *Cmd) { // "data diff -a fileA --cb\n" "data diff --fa fileA -b fileB\n" "data diff --fa fileA --fb fileB\n" - "data diff --ea --cb\n" +// "data diff --ea --cb\n" ); void *argtable[] = { @@ -3082,11 +3082,20 @@ static int CmdDiff(const char *Cmd) { if (inB == NULL) PrintAndLogEx(INFO, "inB null"); - int hdr_sln = (width * 4) + 2; + int hdr_sln = (width * 4) + 2; + char hdr0[300] = {0}; - char hdr0[200] = " # | " _CYAN_("a"); - memset(hdr0 + strlen(hdr0), ' ', hdr_sln - 2); - strcat(hdr0 + strlen(hdr0), "| " _CYAN_("b")); + int max_fn_space = (width * 5); + + if (fnlenA && fnlenB && (max_fn_space > fnlenA) && (max_fn_space > fnlenB)) { + snprintf(hdr0, sizeof(hdr0) - 1, " # | " _CYAN_("%.*s"), max_fn_space, filenameA); + memset(hdr0 + strlen(hdr0), ' ', hdr_sln - strlen(filenameA) - 1 ); + snprintf(hdr0 + strlen(hdr0), sizeof(hdr0) - 1 - strlen(hdr0), "| " _CYAN_("%.*s"), max_fn_space, filenameB); + } else { + strcat(hdr0, " # | " _CYAN_("a")); + memset(hdr0 + strlen(hdr0), ' ', hdr_sln - 2); + strcat(hdr0 + strlen(hdr0), "| " _CYAN_("b")); + } char hdr1[200] = "----+"; memset(hdr1 + strlen(hdr1), '-', hdr_sln); From 043ff257c46a5dde86c51dd74a10015277e9f63a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 24 Jun 2023 23:28:31 +0200 Subject: [PATCH 43/68] style --- CHANGELOG.md | 1 + client/src/cmdhfmf.c | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c11a1112..bd302c2e8 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 viewing MFC dump - border char is now white (@iceman1001) - Changed `data diff` - to print filenames in header if it fits (@iceman1001) - Changed viewing MFC dump files - it now colors ACL + GPB bytes (@iceman1001) - Added `hf mf supercard --furui` - now supports key recovery from Furui detection card. Thanks foxushka! (@iceman1001) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 795ae2b81..1af32b558 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -226,10 +226,37 @@ bool mfc_value(const uint8_t *d, int32_t *val) { } void mf_print_block_one(uint8_t blockno, uint8_t *d, bool verbose) { + if (blockno == 0) { - PrintAndLogEx(INFO, "%3d | " _RED_("%s"), blockno, sprint_hex_ascii(d, MFBLOCK_SIZE)); + char ascii[24] = {0}; + ascii_to_buffer((uint8_t *)ascii, d, MFBLOCK_SIZE, sizeof(ascii) - 1, 1); + PrintAndLogEx(INFO, "%3d | " _RED_("%s") "| " _RED_("%s"), + blockno, + sprint_hex(d, MFBLOCK_SIZE), + ascii + ); } else if (mfIsSectorTrailer(blockno)) { - PrintAndLogEx(INFO, "%3d | " _YELLOW_("%s"), blockno, sprint_hex_ascii(d, MFBLOCK_SIZE)); + + char keya[26] = {0}; + hex_to_buffer((uint8_t *)keya, d, MIFARE_KEY_SIZE, sizeof(keya) - 1, 0, 1, true); + + char acl[20] = {0}; + hex_to_buffer((uint8_t *)acl, d + MIFARE_KEY_SIZE, 4, sizeof(acl) - 1, 0, 1, true); + + char keyb[26] = {0}; + hex_to_buffer((uint8_t *)keyb, d + 10, MIFARE_KEY_SIZE, sizeof(keyb) - 1, 0, 1, true); + + char ascii[24] = {0}; + ascii_to_buffer((uint8_t *)ascii, d, MFBLOCK_SIZE, sizeof(ascii) - 1, 1); + + PrintAndLogEx(INFO, "%3d | " _YELLOW_("%s") _MAGENTA_("%s") _YELLOW_("%s") "| " _YELLOW_("%s"), + blockno, + keya, + acl, + keyb, + ascii + ); + } else { int32_t value = 0; if (verbose && mfc_value(d, &value)) { @@ -249,7 +276,15 @@ static void mf_print_block(uint8_t blockno, uint8_t *d, bool verbose) { } if (blockno == 0) { - PrintAndLogEx(INFO, "%s| %3d | " _RED_("%s"), secstr, blockno, sprint_hex_ascii(d, MFBLOCK_SIZE)); + char ascii[24] = {0}; + ascii_to_buffer((uint8_t *)ascii, d, MFBLOCK_SIZE, sizeof(ascii) - 1, 1); + PrintAndLogEx(INFO, "%s| %3d | " _RED_("%s") "| " _RED_("%s"), + secstr, + blockno, + sprint_hex(d, MFBLOCK_SIZE), + ascii + ); + } else if (mfIsSectorTrailer(blockno)) { char keya[26] = {0}; From 9f87b6dd9c35da08a7ca59e11842dac2f717f712 Mon Sep 17 00:00:00 2001 From: The-SamminAter Date: Sat, 24 Jun 2023 17:19:46 -0700 Subject: [PATCH 44/68] Add ability to compile on iOS --- Makefile.defs | 14 +++++++++++++- client/CMakeLists.txt | 8 +++++++- client/Makefile | 8 +++++++- client/deps/hardnested/Makefile | 3 +++ client/experimental_lib/CMakeLists.txt | 8 +++++++- tools/mfd_aes_brute/Makefile | 3 +++ 6 files changed, 40 insertions(+), 4 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index bcbbaa67e..76409a37d 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -75,7 +75,15 @@ else endif ifeq ($(platform),Darwin) - USE_BREW ?= 1 + ifeq ($(shell uname -p),arm64) + # The platform is iOS + USE_BREW ?= 0 + # iOS refuses to compile unless this is set + export IPHONEOS_DEPLOYMENT_TARGET=11.0 + else + # M* macOS devices return arm + USE_BREW ?= 1 + endif USE_MACPORTS ?= 0 AR= /usr/bin/ar rcs RANLIB= /usr/bin/ranlib @@ -132,6 +140,10 @@ ifeq ($(shell expr $(CC_VERSION) \>= 10), 1) endif endif ifeq ($(platform),Darwin) + ifeq ($(shell uname -p),arm64) + # iOS will refuse to compile without the minimum target of iOS 11.0 + DEFCFLAGS += -mios-version-min=11.0 + endif # their readline has strict-prototype issues DEFCFLAGS += -Wno-strict-prototypes # some warnings about braced initializers on structs we want to ignore diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 3fd255997..9df0844b9 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -380,7 +380,13 @@ message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}") if (APPLE) message(STATUS "Apple device detected.") set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC}) - set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") + if (EXISTS /private/var/mobile) + message(STATUS "iOS detected.") + set(ADDITIONAL_LNK "-framework Foundation" "-framework UIKit") + else + message(STATUS "macOS detected.") + set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") + endif (EXISTS /private/var/mobile) endif (APPLE) if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) diff --git a/client/Makefile b/client/Makefile index d0cee355e..d44e67011 100644 --- a/client/Makefile +++ b/client/Makefile @@ -434,7 +434,13 @@ LDFLAGS += $(MYLDFLAGS) PM3LDFLAGS = $(LDFLAGS) ifeq ($(platform),Darwin) - PM3LDFLAGS += -framework Foundation -framework AppKit + ifeq ($(shell uname -p),arm64) + # The platform is iOS + PM3LDFLAGS += -framework Foundation -framework UIKit + else + # M* macOS devices return arm + PM3LDFLAGS += -framework Foundation -framework AppKit + endif endif ################### diff --git a/client/deps/hardnested/Makefile b/client/deps/hardnested/Makefile index 1667e036f..badace7e5 100644 --- a/client/deps/hardnested/Makefile +++ b/client/deps/hardnested/Makefile @@ -22,6 +22,9 @@ endif ifneq ($(findstring aarch64, $(cpu_arch)), ) IS_SIMD_ARCH=arm64 endif +ifneq ($(findstring iP, $(cpu_arch)), ) + IS_SIMD_ARCH=arm64 +endif ifneq ($(IS_SIMD_ARCH), ) MULTIARCHSRCS = hardnested_bf_core.c hardnested_bitarray_core.c diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index 2ac10f871..27ee198e1 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -380,7 +380,13 @@ message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}") if (APPLE) message(STATUS "Apple device detected.") set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC}) - set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") + if (EXISTS /private/var/mobile) + message(STATUS "iOS detected.") + set(ADDITIONAL_LNK "-framework Foundation" "-framework UIKit") + else + message(STATUS "macOS detected.") + set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") + endif (EXISTS /private/var/mobile) endif (APPLE) if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) diff --git a/tools/mfd_aes_brute/Makefile b/tools/mfd_aes_brute/Makefile index cf2c457c6..d0df682f6 100644 --- a/tools/mfd_aes_brute/Makefile +++ b/tools/mfd_aes_brute/Makefile @@ -9,6 +9,9 @@ MYLDLIBS = -lcrypto cpu_arch = $(shell uname -m) ifneq ($(findstring arm64, $(cpu_arch)), ) MYCFLAGS += -mcpu=native +# iOS 'fun' +else ifneq ($(findstring iP, $(cpu_arch)), ) + MYCFLAGS += -mcpu=native else MYCFLAGS += -march=native endif From 60480d16ec59b741b069029fc01c0d0bd84fbb1d Mon Sep 17 00:00:00 2001 From: Sam <48739810+The-SamminAter@users.noreply.github.com> Date: Sat, 24 Jun 2023 17:49:26 -0700 Subject: [PATCH 45/68] Update CHANGELOG.md Signed-off-by: Sam <48739810+The-SamminAter@users.noreply.github.com> --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd302c2e8..a9a8cb1f7 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 support for compiling on iOS (@The-SamminAter) - Fixed viewing MFC dump - border char is now white (@iceman1001) - Changed `data diff` - to print filenames in header if it fits (@iceman1001) - Changed viewing MFC dump files - it now colors ACL + GPB bytes (@iceman1001) From de85b3c10cb24062b58d9ce4be57baf5242cad54 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 25 Jun 2023 08:19:43 +0200 Subject: [PATCH 46/68] remove color from GPB --- client/src/cmdhfmf.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 1af32b558..16bb414fd 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -241,7 +241,7 @@ void mf_print_block_one(uint8_t blockno, uint8_t *d, bool verbose) { hex_to_buffer((uint8_t *)keya, d, MIFARE_KEY_SIZE, sizeof(keya) - 1, 0, 1, true); char acl[20] = {0}; - hex_to_buffer((uint8_t *)acl, d + MIFARE_KEY_SIZE, 4, sizeof(acl) - 1, 0, 1, true); + hex_to_buffer((uint8_t *)acl, d + MIFARE_KEY_SIZE, 3, sizeof(acl) - 1, 0, 1, true); char keyb[26] = {0}; hex_to_buffer((uint8_t *)keyb, d + 10, MIFARE_KEY_SIZE, sizeof(keyb) - 1, 0, 1, true); @@ -249,10 +249,11 @@ void mf_print_block_one(uint8_t blockno, uint8_t *d, bool verbose) { char ascii[24] = {0}; ascii_to_buffer((uint8_t *)ascii, d, MFBLOCK_SIZE, sizeof(ascii) - 1, 1); - PrintAndLogEx(INFO, "%3d | " _YELLOW_("%s") _MAGENTA_("%s") _YELLOW_("%s") "| " _YELLOW_("%s"), + PrintAndLogEx(INFO, "%3d | " _YELLOW_("%s") _MAGENTA_("%s") "%02X " _YELLOW_("%s") "| " _YELLOW_("%s"), blockno, keya, acl, + d[9], keyb, ascii ); @@ -291,7 +292,7 @@ static void mf_print_block(uint8_t blockno, uint8_t *d, bool verbose) { hex_to_buffer((uint8_t *)keya, d, MIFARE_KEY_SIZE, sizeof(keya) - 1, 0, 1, true); char acl[20] = {0}; - hex_to_buffer((uint8_t *)acl, d + MIFARE_KEY_SIZE, 4, sizeof(acl) - 1, 0, 1, true); + hex_to_buffer((uint8_t *)acl, d + MIFARE_KEY_SIZE, 3, sizeof(acl) - 1, 0, 1, true); char keyb[26] = {0}; hex_to_buffer((uint8_t *)keyb, d + 10, MIFARE_KEY_SIZE, sizeof(keyb) - 1, 0, 1, true); @@ -299,11 +300,12 @@ static void mf_print_block(uint8_t blockno, uint8_t *d, bool verbose) { char ascii[24] = {0}; ascii_to_buffer((uint8_t *)ascii, d, MFBLOCK_SIZE, sizeof(ascii) - 1, 1); - PrintAndLogEx(INFO, "%s| %3d | " _YELLOW_("%s") _MAGENTA_("%s") _YELLOW_("%s") "| " _YELLOW_("%s"), + PrintAndLogEx(INFO, "%s| %3d | " _YELLOW_("%s") _MAGENTA_("%s") "%02X " _YELLOW_("%s") "| " _YELLOW_("%s"), secstr, blockno, keya, acl, + d[9], keyb, ascii ); From 9b8316c1ddd99e2531730ca33475c969d8bdd68b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 25 Jun 2023 09:04:45 +0200 Subject: [PATCH 47/68] fix cmakelists.txt for missing else --- client/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 9df0844b9..156959ba5 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -380,13 +380,15 @@ message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}") if (APPLE) message(STATUS "Apple device detected.") set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC}) + if (EXISTS /private/var/mobile) message(STATUS "iOS detected.") set(ADDITIONAL_LNK "-framework Foundation" "-framework UIKit") - else + else (EXISTS /private/var/mobile) message(STATUS "macOS detected.") set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") endif (EXISTS /private/var/mobile) + endif (APPLE) if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) From 2b3f3240c67ff9fd18527c2d605674d52cacadca Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 25 Jun 2023 09:07:43 +0200 Subject: [PATCH 48/68] fix incomplete else statement in cmakelists.txt --- client/experimental_lib/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index 27ee198e1..c8a6bb02f 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -383,7 +383,7 @@ if (APPLE) if (EXISTS /private/var/mobile) message(STATUS "iOS detected.") set(ADDITIONAL_LNK "-framework Foundation" "-framework UIKit") - else + else (EXISTS /private/var/mobile) message(STATUS "macOS detected.") set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") endif (EXISTS /private/var/mobile) From d71eed325c7317996686fd58c0ee9156d9391207 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 25 Jun 2023 12:42:34 +0200 Subject: [PATCH 49/68] appkit vs uikit detection --- client/CMakeLists.txt | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 156959ba5..8759c00f3 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -381,13 +381,21 @@ if (APPLE) message(STATUS "Apple device detected.") set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC}) - if (EXISTS /private/var/mobile) - message(STATUS "iOS detected.") + find_library(UIKIT_LIBRARY UIKit) + if (NOT UIKIT_LIBRARY) + message(STATUS "UIKit.framework NOT found!") + else() + message(STATUS "UIKit.framework found! ${UIKIT_LIBRARY}") set(ADDITIONAL_LNK "-framework Foundation" "-framework UIKit") - else (EXISTS /private/var/mobile) - message(STATUS "macOS detected.") - set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") - endif (EXISTS /private/var/mobile) + endif() + + find_library(APPKIT_LIBRARY AppKit) + if (NOT APPKIT_LIBRARY) + message(STATUS "AppKit.framework NOT found!") + else() + message(STATUS "AppKit.framework found! ${APPKIT_LIBRARY}") + set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") + endif() endif (APPLE) From 9b69d7ddfaa7fae2bef165493bb96afe8b520f32 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 25 Jun 2023 13:03:12 +0200 Subject: [PATCH 50/68] fix uikit and appkit detection in cmake --- client/experimental_lib/CMakeLists.txt | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index c8a6bb02f..60e7b4004 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -380,13 +380,23 @@ message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}") if (APPLE) message(STATUS "Apple device detected.") set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC}) - if (EXISTS /private/var/mobile) - message(STATUS "iOS detected.") + + find_library(UIKIT_LIBRARY UIKit) + if (NOT UIKIT_LIBRARY) + message(STATUS "UIKit.framework NOT found!") + else() + message(STATUS "UIKit.framework found! ${UIKIT_LIBRARY}") set(ADDITIONAL_LNK "-framework Foundation" "-framework UIKit") - else (EXISTS /private/var/mobile) - message(STATUS "macOS detected.") - set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") - endif (EXISTS /private/var/mobile) + endif() + + find_library(APPKIT_LIBRARY AppKit) + if (NOT APPKIT_LIBRARY) + message(STATUS "AppKit.framework NOT found!") + else() + message(STATUS "AppKit.framework found! ${APPKIT_LIBRARY}") + set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") + endif() + endif (APPLE) if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) From a9f81a05b4e9b3933b9d4dd4344d41f6a264113d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 25 Jun 2023 14:21:34 +0200 Subject: [PATCH 51/68] text --- client/src/cmdlfindala.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/client/src/cmdlfindala.c b/client/src/cmdlfindala.c index fa59894e1..1af21ec20 100644 --- a/client/src/cmdlfindala.c +++ b/client/src/cmdlfindala.c @@ -120,7 +120,7 @@ static void decodeHeden2L(uint8_t *bits) { if (bits[offset + 7]) cardnumber += 16384; if (bits[offset + 23]) cardnumber += 32768; - PrintAndLogEx(SUCCESS, " Heden-2L | %u", cardnumber); + PrintAndLogEx(SUCCESS, " Heden-2L...... %u", cardnumber); } // sending three times. Didn't seem to break the previous sim? @@ -301,10 +301,11 @@ int demodIndalaEx(int clk, int invert, int maxErr, bool verbose) { ); PrintAndLogEx(DEBUG, "two bit checksum... " _GREEN_("%1d%1d"), checksum >> 1 & 0x01, checksum & 0x01); + PrintAndLogEx(INFO, ""); PrintAndLogEx(SUCCESS, "Possible de-scramble patterns"); // This doesn't seem to line up with the hot-stamp numbers on any HID cards I have seen, but, leaving it alone since I do not know how those work. -MS - PrintAndLogEx(SUCCESS, " Printed | __%04d__ [0x%X]", p1, p1); - PrintAndLogEx(SUCCESS, " Internal ID | %" PRIu64, foo); + PrintAndLogEx(SUCCESS, " Printed....... __%04d__ ( 0x%X )", p1, p1); + PrintAndLogEx(SUCCESS, " Internal ID... %" PRIu64, foo); decodeHeden2L(g_DemodBuffer); } else { @@ -336,6 +337,7 @@ int demodIndalaEx(int clk, int invert, int maxErr, bool verbose) { PrintAndLogEx(DEBUG, "DEBUG: Indala - printing DemodBuffer"); printDemodBuff(0, false, false, false); } + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -503,7 +505,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) { showbits[bit] = '.' + bits[bit]; } showbits[bit + 1] = '\0'; - PrintAndLogEx(SUCCESS, "Partial UID | %s", showbits); + PrintAndLogEx(SUCCESS, "Partial UID... %s", showbits); return PM3_SUCCESS; } else { for (bit = 0; bit < uidlen; bit++) { @@ -528,7 +530,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) { uid2 = (uid2 << 1) | 1; } } - PrintAndLogEx(SUCCESS, "UID | %s (%x%08x)", showbits, uid1, uid2); + PrintAndLogEx(SUCCESS, "UID... %s ( %x%08x )", showbits, uid1, uid2); } else { uint32_t uid3 = 0; uint32_t uid4 = 0; @@ -549,7 +551,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) { else uid7 = (uid7 << 1) | 1; } - PrintAndLogEx(SUCCESS, "UID | %s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); + PrintAndLogEx(SUCCESS, "UID... %s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); } // Checking UID against next occurrences From 20814bc394398b374323eebe9e8c739bf5bb44a3 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sun, 25 Jun 2023 14:27:59 +0200 Subject: [PATCH 52/68] Update README.md Signed-off-by: Iceman --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 20416bdbb..9096c9559 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Iceman Fork - Proxmark3 a RFID / NFC project. +# Iceman Fork - Proxmark3 The Proxmark3 is the swiss-army tool of RFID, allowing for interactions with the vast majority of RFID tags on a global scale. Originally built by Jonathan Westhues, the device is now the goto tool for RFID Analysis for the enthusiast. Iceman repository is considered to be the pinnacle of features and functionality, enabling a huge range of extremely useful and convenient commands and LUA scripts to automate chip identification, penetration testing, and programming From 9b2657294ab9b3e0f22dac236938002cfccb63ac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 25 Jun 2023 14:51:51 +0200 Subject: [PATCH 53/68] adapt test for indala text changes --- tools/pm3_tests.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index 3320d9866..a8ed2a196 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -437,8 +437,7 @@ while true; do if ! CheckExecute slow "lf T55 hid_48 test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid_48.pm3; lf hid demod'" \ "HID Corporate 1000 48-bit"; then break; fi if ! CheckExecute slow "lf T55 indala_hedem test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala_hedem.pm3; lf search -1'" "Indala ID found"; then break; fi - if ! CheckExecute slow "lf T55 indala_hedem test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala_hedem.pm3; lf indala demod'" \ - "Heden-2L \| 888"; then break; fi + if ! CheckExecute slow "lf T55 indala_hedem test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala_hedem.pm3; lf indala demod'" "Heden-2L...... 888"; then break; fi if ! CheckExecute slow "lf T55 indala test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala.pm3; lf search -1'" "Indala ID found"; then break; fi if ! CheckExecute slow "lf T55 indala test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala.pm3; lf indala demod'" \ "Fmt 26 FC: 123 Card: 1337 Parity: 11"; then break; fi From d40a89b27b63f760465f59cbe0739a000ea1da3c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 25 Jun 2023 16:22:39 +0200 Subject: [PATCH 54/68] improve the ecfill function used in autopwn among others. Lessen failed auth/reads by skipping s 16,17 using key A for MFC EV1 cards --- armsrc/mifarecmd.c | 117 ++++++++++++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 43 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 7a5abf2c8..bc9a38971 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2302,64 +2302,98 @@ int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keytype) { int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { - uint32_t cuid = 0; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; - - // variables - uint8_t dataoutbuf[16] = {0x00}; - uint8_t dataoutbuf2[16] = {0x00}; - uint8_t uid[10] = {0x00}; - LED_A_ON(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); clear_trace(); set_tracing(true); + // variables + bool have_uid = false; + uint8_t cascade_levels = 0; + uint32_t cuid = 0; + uint8_t uid[10] = {0x00}; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; + int retval = PM3_SUCCESS; - if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - retval = PM3_ESOFT; - if (g_dbglevel > DBG_ERROR) Dbprintf("Can't select card"); - goto out; - } + for (uint8_t s = 0; s < sectorcnt; s++) { + uint64_t ui64Key = emlGetKey(s, keytype); - for (uint8_t sectorNo = 0; sectorNo < sectorcnt; sectorNo++) { - uint64_t ui64Key = emlGetKey(sectorNo, keytype); - if (sectorNo == 0) { - if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_FIRST)) { - retval = PM3_EPARTIAL; - if (g_dbglevel > DBG_ERROR) Dbprintf("Sector[%2d]. Auth error", sectorNo); + // MFC 1K EV1 sector 16,17 don't use key A. + if ((sectorcnt == 18) && (keytype == 0) && s > 15) { + continue; + } + + // use fast select + if (have_uid == false) { // need a full select cycle to get the uid first + iso14a_card_select_t card_info; + if (iso14443a_select_card(uid, &card_info, &cuid, true, 0, true) == 0) { continue; } - } else { - if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_NESTED)) { - retval = PM3_EPARTIAL; - if (g_dbglevel > DBG_ERROR) Dbprintf("Sector[%2d]. Auth nested error", sectorNo); + + switch (card_info.uidlen) { + case 4 : + cascade_levels = 1; + break; + case 7 : + cascade_levels = 2; + break; + case 10: + cascade_levels = 3; + break; + default: + break; + } + have_uid = true; + } else { // no need for anticollision. We can directly select the card + if (iso14443a_fast_select_card(uid, cascade_levels) == 0) { continue; } } - for (uint8_t blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) { - if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) { - retval = PM3_EPARTIAL; - - if (g_dbglevel > DBG_ERROR) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo); - continue; + // Auth + if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(s), keytype, ui64Key, AUTH_FIRST)) { + retval = PM3_EPARTIAL; + if (g_dbglevel > DBG_ERROR) { + Dbprintf("Sector %2d - Auth error", s); } + continue; + } - if (memcmp(dataoutbuf, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16) == 0) { - continue; - } +#define MAX_RETRIES 2 - if (blockNo < NumBlocksPerSector(sectorNo) - 1) { - emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1); - } else { // sector trailer, keep the keys, set only the AC - emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); - memcpy(dataoutbuf2 + 6, dataoutbuf + 6, 4); - emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); + uint8_t data[16] = {0x00}; + for (uint8_t b = 0; b < NumBlocksPerSector(s); b++) { + + memset(data, 0x00, sizeof(data)); + + for (uint8_t r = 0; r < MAX_RETRIES; r++) { + + if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(s) + b, data)) { + retval |= PM3_EPARTIAL; + if (g_dbglevel > DBG_ERROR) { + Dbprintf("Error reading sector %2d block %2d", s, b); + } + continue; + } + + // No need to copy empty + if (memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16) == 0) { + continue; + } + + if (b < NumBlocksPerSector(s) - 1) { + emlSetMem(data, FirstBlockOfSector(s) + b, 1); + } else { + // sector trailer, keep the keys, set only the AC + uint8_t st[16] = {0x00}; + emlGetMem(st, FirstBlockOfSector(s) + b, 1); + memcpy(st + 6, data + 6, 4); + emlSetMem(st, FirstBlockOfSector(s) + b, 1); + } } } } @@ -2367,9 +2401,6 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { int res = mifare_classic_halt(pcs, cuid); (void)res; - if (g_dbglevel >= DBG_INFO) DbpString("Emulator fill sectors finished"); - -out: crypto1_deinit(pcs); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); From f64f5385192327f67aef5afe0480180bfb5fba72 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 25 Jun 2023 22:30:58 +0200 Subject: [PATCH 55/68] style --- armsrc/mifarecmd.c | 4 ++-- client/src/cmddata.c | 4 ++-- client/src/cmdhfmf.c | 48 ++++++++++++++++++++++---------------------- doc/commands.json | 5 ++--- 4 files changed, 30 insertions(+), 31 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index bc9a38971..4492c3195 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2357,7 +2357,7 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { // Auth if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(s), keytype, ui64Key, AUTH_FIRST)) { retval = PM3_EPARTIAL; - if (g_dbglevel > DBG_ERROR) { + if (g_dbglevel > DBG_ERROR) { Dbprintf("Sector %2d - Auth error", s); } continue; @@ -2387,7 +2387,7 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { if (b < NumBlocksPerSector(s) - 1) { emlSetMem(data, FirstBlockOfSector(s) + b, 1); - } else { + } else { // sector trailer, keep the keys, set only the AC uint8_t st[16] = {0x00}; emlGetMem(st, FirstBlockOfSector(s) + b, 1); diff --git a/client/src/cmddata.c b/client/src/cmddata.c index e1bf655e4..032d31f85 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -3082,14 +3082,14 @@ static int CmdDiff(const char *Cmd) { if (inB == NULL) PrintAndLogEx(INFO, "inB null"); - int hdr_sln = (width * 4) + 2; + int hdr_sln = (width * 4) + 2; char hdr0[300] = {0}; int max_fn_space = (width * 5); if (fnlenA && fnlenB && (max_fn_space > fnlenA) && (max_fn_space > fnlenB)) { snprintf(hdr0, sizeof(hdr0) - 1, " # | " _CYAN_("%.*s"), max_fn_space, filenameA); - memset(hdr0 + strlen(hdr0), ' ', hdr_sln - strlen(filenameA) - 1 ); + memset(hdr0 + strlen(hdr0), ' ', hdr_sln - strlen(filenameA) - 1); snprintf(hdr0 + strlen(hdr0), sizeof(hdr0) - 1 - strlen(hdr0), "| " _CYAN_("%.*s"), max_fn_space, filenameB); } else { strcat(hdr0, " # | " _CYAN_("a")); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 16bb414fd..2eb7fa415 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -231,10 +231,10 @@ void mf_print_block_one(uint8_t blockno, uint8_t *d, bool verbose) { char ascii[24] = {0}; ascii_to_buffer((uint8_t *)ascii, d, MFBLOCK_SIZE, sizeof(ascii) - 1, 1); PrintAndLogEx(INFO, "%3d | " _RED_("%s") "| " _RED_("%s"), - blockno, - sprint_hex(d, MFBLOCK_SIZE), - ascii - ); + blockno, + sprint_hex(d, MFBLOCK_SIZE), + ascii + ); } else if (mfIsSectorTrailer(blockno)) { char keya[26] = {0}; @@ -250,13 +250,13 @@ void mf_print_block_one(uint8_t blockno, uint8_t *d, bool verbose) { ascii_to_buffer((uint8_t *)ascii, d, MFBLOCK_SIZE, sizeof(ascii) - 1, 1); PrintAndLogEx(INFO, "%3d | " _YELLOW_("%s") _MAGENTA_("%s") "%02X " _YELLOW_("%s") "| " _YELLOW_("%s"), - blockno, - keya, - acl, - d[9], - keyb, - ascii - ); + blockno, + keya, + acl, + d[9], + keyb, + ascii + ); } else { int32_t value = 0; @@ -280,11 +280,11 @@ static void mf_print_block(uint8_t blockno, uint8_t *d, bool verbose) { char ascii[24] = {0}; ascii_to_buffer((uint8_t *)ascii, d, MFBLOCK_SIZE, sizeof(ascii) - 1, 1); PrintAndLogEx(INFO, "%s| %3d | " _RED_("%s") "| " _RED_("%s"), - secstr, - blockno, - sprint_hex(d, MFBLOCK_SIZE), - ascii - ); + secstr, + blockno, + sprint_hex(d, MFBLOCK_SIZE), + ascii + ); } else if (mfIsSectorTrailer(blockno)) { @@ -301,14 +301,14 @@ static void mf_print_block(uint8_t blockno, uint8_t *d, bool verbose) { ascii_to_buffer((uint8_t *)ascii, d, MFBLOCK_SIZE, sizeof(ascii) - 1, 1); PrintAndLogEx(INFO, "%s| %3d | " _YELLOW_("%s") _MAGENTA_("%s") "%02X " _YELLOW_("%s") "| " _YELLOW_("%s"), - secstr, - blockno, - keya, - acl, - d[9], - keyb, - ascii - ); + secstr, + blockno, + keya, + acl, + d[9], + keyb, + ascii + ); } else { int32_t value = 0; if (verbose && mfc_value(d, &value)) { diff --git a/doc/commands.json b/doc/commands.json index 7a19db4f2..27e9303e9 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -332,8 +332,7 @@ "data diff -a fileA -b fileB", "data diff -a fileA --eb", "data diff --fa fileA -b fileB", - "data diff --fa fileA --fb fileB", - "data diff --ea --cb" + "data diff --fa fileA --fb fileB" ], "offline": true, "options": [ @@ -12095,6 +12094,6 @@ "metadata": { "commands_extracted": 759, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-06-24T15:16:04" + "extracted_on": "2023-06-25T20:30:44" } } \ No newline at end of file From 2e311a141bdb045b953bbb75763066ce982f9a3e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 25 Jun 2023 22:42:29 +0200 Subject: [PATCH 56/68] misschecks --- client/luascripts/hf_legic.lua | 8 ++++---- client/src/cmdhf15.c | 2 +- doc/commands.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/luascripts/hf_legic.lua b/client/luascripts/hf_legic.lua index 21684b6fb..cbec05f9f 100644 --- a/client/luascripts/hf_legic.lua +++ b/client/luascripts/hf_legic.lua @@ -2520,11 +2520,11 @@ function modifyMode() --- -- edit data-portion of single segment ["ed"] = function(x) - if (type(x)=="string" and string.len(x)>0) then sel=tonumber(x,10) - else sel=selectSegment(inTAG) end + if (type(x) == "string" and string.len(x)>0) then sel=tonumber(x,10) + else sel = selectSegment(inTAG) end if (istable(inTAG.SEG[sel])) then - local uid = inTAG.MCD..inTAG.MSN0..inTAG.MSN1..inTAG.MSN2 - inTAG.SEG[sel].data=editSegmentData(inTAG.SEG[sel].data, uid) + local uid = inTAG.MCD..inTAG.MSN0..inTAG.MSN1..inTAG.MSN2 + inTAG.SEG[sel].data = editSegmentData(inTAG.SEG[sel].data, uid) end end, --- diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index c80f8cac4..c16bfb10b 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -48,7 +48,7 @@ #define Logic1 Iso15693Logic1 #define FrameEOF Iso15693FrameEOF #define CARD_MEMORY_SIZE 4096 -#define HF15_UID_LENGTH 8 +#define HF15_UID_LENGTH 8 #ifndef Crc15 # define Crc15(data, len) Crc16ex(CRC_15693, (data), (len)) diff --git a/doc/commands.json b/doc/commands.json index 27e9303e9..e1a0a020b 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -12094,6 +12094,6 @@ "metadata": { "commands_extracted": 759, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-06-25T20:30:44" + "extracted_on": "2023-06-25T20:42:06" } } \ No newline at end of file From 1cf494cb983f79e446619ab308c19cfe70c78f6b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 26 Jun 2023 00:08:00 +0200 Subject: [PATCH 57/68] preparatins for release --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9a8cb1f7..9e2fa61ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ 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] + +## [Seven][2023-06-25] - Added support for compiling on iOS (@The-SamminAter) - Fixed viewing MFC dump - border char is now white (@iceman1001) - Changed `data diff` - to print filenames in header if it fits (@iceman1001) From bc18dbd847775a0491c1f919f55f7160a42b95f9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 26 Jun 2023 13:10:45 +0200 Subject: [PATCH 58/68] Release v4.16717 - seven --- Makefile.defs | 4 ++-- armsrc/Makefile | 2 +- bootrom/Makefile | 2 +- client/CMakeLists.txt | 4 ++-- client/Makefile | 4 ++-- client/deps/amiibo.cmake | 2 +- client/deps/cliparser.cmake | 2 +- client/deps/hardnested.cmake | 18 +++++++++--------- client/deps/jansson.cmake | 2 +- client/deps/lua.cmake | 2 +- client/deps/mbedtls.cmake | 2 +- client/deps/reveng.cmake | 2 +- client/deps/tinycbor.cmake | 2 +- client/deps/whereami.cmake | 2 +- client/src/proxmark3.c | 2 +- common/default_version_pm3.c | 27 +++++++-------------------- common_arm/Makefile.common | 2 +- 17 files changed, 34 insertions(+), 47 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index 76409a37d..874440a47 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -112,8 +112,8 @@ ifeq ($(DEBUG),1) DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe DEFLDFLAGS = else - DEFCXXFLAGS = -Wall -Werror -O3 -pipe - DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe + DEFCXXFLAGS = -Wall -O3 -pipe + DEFCFLAGS = -Wall -O3 -fstrict-aliasing -pipe DEFLDFLAGS = endif diff --git a/armsrc/Makefile b/armsrc/Makefile index 5203b0292..20090b678 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -187,7 +187,7 @@ showinfo: # version_pm3.c should be remade on every time fullimage.stage1.elf should be remade version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) .FORCE $(info [-] GEN $@) - $(Q)$(SH) ../tools/mkversion.sh > $@ || $(CP) $< $@ + $(Q)$(CP) $< $@ fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) $(info [-] GEN $@) diff --git a/bootrom/Makefile b/bootrom/Makefile index cad3e17d1..6085305c6 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -56,7 +56,7 @@ OBJS = $(OBJDIR)/bootrom.s19 # version_pm3.c should be remade on every compilation version_pm3.c: default_version_pm3.c .FORCE $(info [=] GEN $@) - $(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@ + $(Q)$(CP) $< $@ all: showinfo $(OBJS) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 8759c00f3..0e0b08744 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -365,7 +365,7 @@ set (TARGET_SOURCES add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c - COMMAND sh ${PM3_ROOT}/tools/mkversion.sh > ${CMAKE_BINARY_DIR}/version_pm3.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c + COMMAND ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c DEPENDS ${PM3_ROOT}/common/default_version_pm3.c ) @@ -582,7 +582,7 @@ add_executable(proxmark3 ${ADDITIONAL_SRC} ) -target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3) +target_compile_options(proxmark3 PUBLIC -Wall -O3) if (EMBED_READLINE) if (NOT SKIPREADLINE EQUAL 1) add_dependencies(proxmark3 ncurses readline) diff --git a/client/Makefile b/client/Makefile index d44e67011..d108bb7a0 100644 --- a/client/Makefile +++ b/client/Makefile @@ -412,7 +412,7 @@ endif PM3CFLAGS += -DHAVE_SNPRINTF -CXXFLAGS ?= -Wall -Werror -O3 +CXXFLAGS ?= -Wall -O3 CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES) PM3CXXFLAGS = $(CXXFLAGS) @@ -912,7 +912,7 @@ src/pm3_pywrap.c: pm3.i # version_pm3.c should be remade on every compilation src/version_pm3.c: default_version_pm3.c .FORCE $(info [=] GEN $@) - $(Q)$(SH) ../tools/mkversion.sh > $@ || $(CP) $< $@ + $(Q)$(CP) $< $@ # easy printing of MAKE VARIABLES print-%: ; @echo $* = $($*) diff --git a/client/deps/amiibo.cmake b/client/deps/amiibo.cmake index c946c0682..8c524c170 100644 --- a/client/deps/amiibo.cmake +++ b/client/deps/amiibo.cmake @@ -19,7 +19,7 @@ target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE m pm3rrg_rdv4_mbedtls) -target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_amiibo PRIVATE amiitool diff --git a/client/deps/cliparser.cmake b/client/deps/cliparser.cmake index fccae33b7..a85cc2374 100644 --- a/client/deps/cliparser.cmake +++ b/client/deps/cliparser.cmake @@ -9,5 +9,5 @@ target_include_directories(pm3rrg_rdv4_cliparser PRIVATE ../../include ../src) target_include_directories(pm3rrg_rdv4_cliparser INTERFACE cliparser) -target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_cliparser PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/hardnested.cmake b/client/deps/hardnested.cmake index ec545e2a8..468ee4ef2 100644 --- a/client/deps/hardnested.cmake +++ b/client/deps/hardnested.cmake @@ -2,7 +2,7 @@ add_library(pm3rrg_rdv4_hardnested_nosimd OBJECT hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) -target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_hardnested_nosimd PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_nosimd PRIVATE @@ -32,7 +32,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_mmx BEFORE PRIVATE -mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_mmx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -47,7 +47,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_sse2 BEFORE PRIVATE -mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_sse2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -62,7 +62,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx BEFORE PRIVATE -mmmx -msse2 -mavx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -77,7 +77,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx2 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -92,7 +92,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx512 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mavx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx512 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -116,7 +116,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM64_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_neon PRIVATE @@ -134,7 +134,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM32_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_neon BEFORE PRIVATE -mfpu=neon) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -155,7 +155,7 @@ add_library(pm3rrg_rdv4_hardnested STATIC hardnested/hardnested_bruteforce.c $ ${SIMD_TARGETS}) -target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested PRIVATE ../../common diff --git a/client/deps/jansson.cmake b/client/deps/jansson.cmake index c91a47047..42c701d5e 100644 --- a/client/deps/jansson.cmake +++ b/client/deps/jansson.cmake @@ -14,5 +14,5 @@ add_library(pm3rrg_rdv4_jansson STATIC target_compile_definitions(pm3rrg_rdv4_jansson PRIVATE HAVE_STDINT_H) target_include_directories(pm3rrg_rdv4_jansson INTERFACE jansson) -target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Werror -Wno-unused-function -O3) +target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Wno-unused-function -O3) set_property(TARGET pm3rrg_rdv4_jansson PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/lua.cmake b/client/deps/lua.cmake index 12870342e..5cf33d724 100644 --- a/client/deps/lua.cmake +++ b/client/deps/lua.cmake @@ -52,5 +52,5 @@ if (NOT MINGW) endif (NOT MINGW) target_include_directories(pm3rrg_rdv4_lua INTERFACE liblua) -target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_lua PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/mbedtls.cmake b/client/deps/mbedtls.cmake index 40929e1ea..c726ddeba 100644 --- a/client/deps/mbedtls.cmake +++ b/client/deps/mbedtls.cmake @@ -44,5 +44,5 @@ add_library(pm3rrg_rdv4_mbedtls STATIC target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common) target_include_directories(pm3rrg_rdv4_mbedtls INTERFACE ../../common/mbedtls) -target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/reveng.cmake b/client/deps/reveng.cmake index d7e3cfd8a..1040730f1 100644 --- a/client/deps/reveng.cmake +++ b/client/deps/reveng.cmake @@ -13,5 +13,5 @@ target_include_directories(pm3rrg_rdv4_reveng PRIVATE ../src ../../include) target_include_directories(pm3rrg_rdv4_reveng INTERFACE reveng) -target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_reveng PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/tinycbor.cmake b/client/deps/tinycbor.cmake index 5a6abda25..c74618149 100644 --- a/client/deps/tinycbor.cmake +++ b/client/deps/tinycbor.cmake @@ -11,5 +11,5 @@ add_library(pm3rrg_rdv4_tinycbor STATIC target_include_directories(pm3rrg_rdv4_tinycbor INTERFACE tinycbor) # Strange errors on Mingw when compiling with -O3 -target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -Werror -O2) +target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -O2) set_property(TARGET pm3rrg_rdv4_tinycbor PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/whereami.cmake b/client/deps/whereami.cmake index d2d6a5b2a..721873066 100644 --- a/client/deps/whereami.cmake +++ b/client/deps/whereami.cmake @@ -2,5 +2,5 @@ add_library(pm3rrg_rdv4_whereami STATIC whereami/whereami.c) target_compile_definitions(pm3rrg_rdv4_whereami PRIVATE WAI_PM3_TUNED) target_include_directories(pm3rrg_rdv4_whereami INTERFACE whereami) -target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_whereami PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 162bc7776..d6e4d0346 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -42,7 +42,7 @@ static int mainret = PM3_ESOFT; #ifndef LIBPM3 #define BANNERMSG1 "" #define BANNERMSG2 " [ :coffee: ]" -#define BANNERMSG3 "" +#define BANNERMSG3 "Release v4.16717 - seven" typedef enum LogoMode { UTF8, ANSI, ASCII } LogoMode; diff --git a/common/default_version_pm3.c b/common/default_version_pm3.c index 46eac57c9..016f98e82 100644 --- a/common/default_version_pm3.c +++ b/common/default_version_pm3.c @@ -1,20 +1,5 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- #include "common.h" -/* This is the default version_pm3.c file that Makefile.common falls back to if sh is not available */ +/* Generated file, do not edit */ #ifndef ON_DEVICE #define SECTVERSINFO #else @@ -23,8 +8,10 @@ const struct version_information_t SECTVERSINFO g_version_information = { VERSION_INFORMATION_MAGIC, - 1, /* version 1 */ - 0, /* version information not present */ - 2, /* cleanliness couldn't be determined */ - /* Remaining fields: zero */ + 1, + 1, + 1, + "Iceman/master/v4.16717", + "2023-06-26 13:10:45", + "de506fd18" }; diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index 99f4d9ecd..e40d998a6 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -49,7 +49,7 @@ VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/ INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h ARMCFLAGS = -mthumb-interwork -fno-builtin -DEFCFLAGS = -Wall -Werror -Os -pedantic -fstrict-aliasing -pipe +DEFCFLAGS = -Wall -Os -pedantic -fstrict-aliasing -pipe # Some more warnings we want as errors: DEFCFLAGS += -Wbad-function-cast -Wchar-subscripts -Wundef -Wunused -Wuninitialized -Wpointer-arith -Wformat -Wformat-security -Winit-self -Wmissing-include-dirs -Wnested-externs -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wtype-limits From c7d004de63a73524103289f24dda73be0b188e95 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 26 Jun 2023 13:10:45 +0200 Subject: [PATCH 59/68] Revert "Release v4.16717 - seven" This reverts commit bc18dbd847775a0491c1f919f55f7160a42b95f9. --- Makefile.defs | 4 ++-- armsrc/Makefile | 2 +- bootrom/Makefile | 2 +- client/CMakeLists.txt | 4 ++-- client/Makefile | 4 ++-- client/deps/amiibo.cmake | 2 +- client/deps/cliparser.cmake | 2 +- client/deps/hardnested.cmake | 18 +++++++++--------- client/deps/jansson.cmake | 2 +- client/deps/lua.cmake | 2 +- client/deps/mbedtls.cmake | 2 +- client/deps/reveng.cmake | 2 +- client/deps/tinycbor.cmake | 2 +- client/deps/whereami.cmake | 2 +- client/src/proxmark3.c | 2 +- common/default_version_pm3.c | 27 ++++++++++++++++++++------- common_arm/Makefile.common | 2 +- 17 files changed, 47 insertions(+), 34 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index 874440a47..76409a37d 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -112,8 +112,8 @@ ifeq ($(DEBUG),1) DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe DEFLDFLAGS = else - DEFCXXFLAGS = -Wall -O3 -pipe - DEFCFLAGS = -Wall -O3 -fstrict-aliasing -pipe + DEFCXXFLAGS = -Wall -Werror -O3 -pipe + DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe DEFLDFLAGS = endif diff --git a/armsrc/Makefile b/armsrc/Makefile index 20090b678..5203b0292 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -187,7 +187,7 @@ showinfo: # version_pm3.c should be remade on every time fullimage.stage1.elf should be remade version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) .FORCE $(info [-] GEN $@) - $(Q)$(CP) $< $@ + $(Q)$(SH) ../tools/mkversion.sh > $@ || $(CP) $< $@ fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) $(info [-] GEN $@) diff --git a/bootrom/Makefile b/bootrom/Makefile index 6085305c6..cad3e17d1 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -56,7 +56,7 @@ OBJS = $(OBJDIR)/bootrom.s19 # version_pm3.c should be remade on every compilation version_pm3.c: default_version_pm3.c .FORCE $(info [=] GEN $@) - $(Q)$(CP) $< $@ + $(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@ all: showinfo $(OBJS) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 0e0b08744..8759c00f3 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -365,7 +365,7 @@ set (TARGET_SOURCES add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c - COMMAND ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c + COMMAND sh ${PM3_ROOT}/tools/mkversion.sh > ${CMAKE_BINARY_DIR}/version_pm3.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c DEPENDS ${PM3_ROOT}/common/default_version_pm3.c ) @@ -582,7 +582,7 @@ add_executable(proxmark3 ${ADDITIONAL_SRC} ) -target_compile_options(proxmark3 PUBLIC -Wall -O3) +target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3) if (EMBED_READLINE) if (NOT SKIPREADLINE EQUAL 1) add_dependencies(proxmark3 ncurses readline) diff --git a/client/Makefile b/client/Makefile index d108bb7a0..d44e67011 100644 --- a/client/Makefile +++ b/client/Makefile @@ -412,7 +412,7 @@ endif PM3CFLAGS += -DHAVE_SNPRINTF -CXXFLAGS ?= -Wall -O3 +CXXFLAGS ?= -Wall -Werror -O3 CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES) PM3CXXFLAGS = $(CXXFLAGS) @@ -912,7 +912,7 @@ src/pm3_pywrap.c: pm3.i # version_pm3.c should be remade on every compilation src/version_pm3.c: default_version_pm3.c .FORCE $(info [=] GEN $@) - $(Q)$(CP) $< $@ + $(Q)$(SH) ../tools/mkversion.sh > $@ || $(CP) $< $@ # easy printing of MAKE VARIABLES print-%: ; @echo $* = $($*) diff --git a/client/deps/amiibo.cmake b/client/deps/amiibo.cmake index 8c524c170..c946c0682 100644 --- a/client/deps/amiibo.cmake +++ b/client/deps/amiibo.cmake @@ -19,7 +19,7 @@ target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE m pm3rrg_rdv4_mbedtls) -target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_amiibo PRIVATE amiitool diff --git a/client/deps/cliparser.cmake b/client/deps/cliparser.cmake index a85cc2374..fccae33b7 100644 --- a/client/deps/cliparser.cmake +++ b/client/deps/cliparser.cmake @@ -9,5 +9,5 @@ target_include_directories(pm3rrg_rdv4_cliparser PRIVATE ../../include ../src) target_include_directories(pm3rrg_rdv4_cliparser INTERFACE cliparser) -target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_cliparser PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/hardnested.cmake b/client/deps/hardnested.cmake index 468ee4ef2..ec545e2a8 100644 --- a/client/deps/hardnested.cmake +++ b/client/deps/hardnested.cmake @@ -2,7 +2,7 @@ add_library(pm3rrg_rdv4_hardnested_nosimd OBJECT hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) -target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_hardnested_nosimd PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_nosimd PRIVATE @@ -32,7 +32,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_mmx BEFORE PRIVATE -mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_mmx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -47,7 +47,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_sse2 BEFORE PRIVATE -mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_sse2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -62,7 +62,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx BEFORE PRIVATE -mmmx -msse2 -mavx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -77,7 +77,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx2 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -92,7 +92,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx512 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mavx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx512 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -116,7 +116,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM64_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_neon PRIVATE @@ -134,7 +134,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM32_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_neon BEFORE PRIVATE -mfpu=neon) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -155,7 +155,7 @@ add_library(pm3rrg_rdv4_hardnested STATIC hardnested/hardnested_bruteforce.c $ ${SIMD_TARGETS}) -target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested PRIVATE ../../common diff --git a/client/deps/jansson.cmake b/client/deps/jansson.cmake index 42c701d5e..c91a47047 100644 --- a/client/deps/jansson.cmake +++ b/client/deps/jansson.cmake @@ -14,5 +14,5 @@ add_library(pm3rrg_rdv4_jansson STATIC target_compile_definitions(pm3rrg_rdv4_jansson PRIVATE HAVE_STDINT_H) target_include_directories(pm3rrg_rdv4_jansson INTERFACE jansson) -target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Wno-unused-function -O3) +target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Werror -Wno-unused-function -O3) set_property(TARGET pm3rrg_rdv4_jansson PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/lua.cmake b/client/deps/lua.cmake index 5cf33d724..12870342e 100644 --- a/client/deps/lua.cmake +++ b/client/deps/lua.cmake @@ -52,5 +52,5 @@ if (NOT MINGW) endif (NOT MINGW) target_include_directories(pm3rrg_rdv4_lua INTERFACE liblua) -target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_lua PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/mbedtls.cmake b/client/deps/mbedtls.cmake index c726ddeba..40929e1ea 100644 --- a/client/deps/mbedtls.cmake +++ b/client/deps/mbedtls.cmake @@ -44,5 +44,5 @@ add_library(pm3rrg_rdv4_mbedtls STATIC target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common) target_include_directories(pm3rrg_rdv4_mbedtls INTERFACE ../../common/mbedtls) -target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/reveng.cmake b/client/deps/reveng.cmake index 1040730f1..d7e3cfd8a 100644 --- a/client/deps/reveng.cmake +++ b/client/deps/reveng.cmake @@ -13,5 +13,5 @@ target_include_directories(pm3rrg_rdv4_reveng PRIVATE ../src ../../include) target_include_directories(pm3rrg_rdv4_reveng INTERFACE reveng) -target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_reveng PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/tinycbor.cmake b/client/deps/tinycbor.cmake index c74618149..5a6abda25 100644 --- a/client/deps/tinycbor.cmake +++ b/client/deps/tinycbor.cmake @@ -11,5 +11,5 @@ add_library(pm3rrg_rdv4_tinycbor STATIC target_include_directories(pm3rrg_rdv4_tinycbor INTERFACE tinycbor) # Strange errors on Mingw when compiling with -O3 -target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -O2) +target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -Werror -O2) set_property(TARGET pm3rrg_rdv4_tinycbor PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/whereami.cmake b/client/deps/whereami.cmake index 721873066..d2d6a5b2a 100644 --- a/client/deps/whereami.cmake +++ b/client/deps/whereami.cmake @@ -2,5 +2,5 @@ add_library(pm3rrg_rdv4_whereami STATIC whereami/whereami.c) target_compile_definitions(pm3rrg_rdv4_whereami PRIVATE WAI_PM3_TUNED) target_include_directories(pm3rrg_rdv4_whereami INTERFACE whereami) -target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_whereami PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index d6e4d0346..162bc7776 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -42,7 +42,7 @@ static int mainret = PM3_ESOFT; #ifndef LIBPM3 #define BANNERMSG1 "" #define BANNERMSG2 " [ :coffee: ]" -#define BANNERMSG3 "Release v4.16717 - seven" +#define BANNERMSG3 "" typedef enum LogoMode { UTF8, ANSI, ASCII } LogoMode; diff --git a/common/default_version_pm3.c b/common/default_version_pm3.c index 016f98e82..46eac57c9 100644 --- a/common/default_version_pm3.c +++ b/common/default_version_pm3.c @@ -1,5 +1,20 @@ +//----------------------------------------------------------------------------- +// 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. +//----------------------------------------------------------------------------- #include "common.h" -/* Generated file, do not edit */ +/* This is the default version_pm3.c file that Makefile.common falls back to if sh is not available */ #ifndef ON_DEVICE #define SECTVERSINFO #else @@ -8,10 +23,8 @@ const struct version_information_t SECTVERSINFO g_version_information = { VERSION_INFORMATION_MAGIC, - 1, - 1, - 1, - "Iceman/master/v4.16717", - "2023-06-26 13:10:45", - "de506fd18" + 1, /* version 1 */ + 0, /* version information not present */ + 2, /* cleanliness couldn't be determined */ + /* Remaining fields: zero */ }; diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index e40d998a6..99f4d9ecd 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -49,7 +49,7 @@ VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/ INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h ARMCFLAGS = -mthumb-interwork -fno-builtin -DEFCFLAGS = -Wall -Os -pedantic -fstrict-aliasing -pipe +DEFCFLAGS = -Wall -Werror -Os -pedantic -fstrict-aliasing -pipe # Some more warnings we want as errors: DEFCFLAGS += -Wbad-function-cast -Wchar-subscripts -Wundef -Wunused -Wuninitialized -Wpointer-arith -Wformat -Wformat-security -Winit-self -Wmissing-include-dirs -Wnested-externs -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wtype-limits From f7f1f2e6e78d9626768c4abe133e6fa1b74b7ae6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 26 Jun 2023 13:11:45 +0200 Subject: [PATCH 60/68] update version --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e2fa61ec..47b958b98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] -## [Seven][2023-06-25] +## [Seven.4.16717][2023-06-25] - Added support for compiling on iOS (@The-SamminAter) - Fixed viewing MFC dump - border char is now white (@iceman1001) - Changed `data diff` - to print filenames in header if it fits (@iceman1001) From adfebd6510688667a612141c74ee461c57c84a06 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 26 Jun 2023 15:01:08 +0200 Subject: [PATCH 61/68] text --- armsrc/iso15693.c | 28 ++++++++++++++-------------- client/src/cmdhficlass.c | 5 +++++ client/src/cmdhflist.c | 2 +- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 703f1288f..16dc3c575 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -1835,20 +1835,20 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool icla switch_off(); DbpString(""); - DbpString(_CYAN_("Sniff statistics")); - DbpString("================================="); - Dbprintf(" DecodeTag State........%d", dtag.state); - Dbprintf(" DecodeTag byteCnt......%d", dtag.len); - Dbprintf(" DecodeTag posCount.....%d", dtag.posCount); - Dbprintf(" DecodeTagFSK State.....%d", dtagfsk.state); - Dbprintf(" DecodeTagFSK byteCnt...%d", dtagfsk.len); - Dbprintf(" DecodeTagFSK count.....%d", dtagfsk.count); - Dbprintf(" DecodeReader State.....%d", dreader.state); - Dbprintf(" DecodeReader byteCnt...%d", dreader.byteCount); - Dbprintf(" DecodeReader posCount..%d", dreader.posCount); - Dbprintf(" Trace length..........." _YELLOW_("%d"), BigBuf_get_traceLen()); - DbpString(""); - + if (g_dbglevel > DBG_ERROR) { + DbpString(_CYAN_("Sniff statistics")); + DbpString("================================="); + Dbprintf("DecodeTag State........ %d", dtag.state); + Dbprintf("DecodeTag byteCnt...... %d", dtag.len); + Dbprintf("DecodeTag posCount..... %d", dtag.posCount); + Dbprintf("DecodeTagFSK State..... %d", dtagfsk.state); + Dbprintf("DecodeTagFSK byteCnt... %d", dtagfsk.len); + Dbprintf("DecodeTagFSK count..... %d", dtagfsk.count); + Dbprintf("DecodeReader State..... %d", dreader.state); + Dbprintf("DecodeReader byteCnt... %d", dreader.byteCount); + Dbprintf("DecodeReader posCount.. %d", dreader.posCount); + } + Dbprintf("Trace length........... " _YELLOW_("%d"), BigBuf_get_traceLen()); } // Initialize Proxmark3 as ISO15693 reader diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index ba6d984ad..a48bbb98e 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -683,8 +683,13 @@ static int CmdHFiClassSniff(const char *Cmd) { WaitForResponse(CMD_HF_ICLASS_SNIFF, &resp); + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(HINT, "Try `" _YELLOW_("hf iclass list") "` to view captured tracelog"); PrintAndLogEx(HINT, "Try `" _YELLOW_("trace save -f hf_iclass_mytrace") "` to save tracelog for later analysing"); + if (jam_epurse_update) { + PrintAndLogEx(HINT, "Verify if the jam worked by comparing value in trace and block 2"); + } + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index b38d7fea4..5ddd3f1fa 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -499,7 +499,7 @@ void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool uint8_t key[8]; if (check_known_default(csn, epurse, rmac, tmac, key)) { - snprintf(exp, size, "CHECK ( %s )", sprint_hex_inrow(key, 8)); + snprintf(exp, size, "CHECK ( " _GREEN_("%s") " )", sprint_hex_inrow(key, 8)); } else { snprintf(exp, size, "CHECK"); } From f36ec4645504dae317d152b4b4183099a0c67c6f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 26 Jun 2023 15:01:44 +0200 Subject: [PATCH 62/68] minor rename --- armsrc/mifareutil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 487c71706..b17ac19bc 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -730,8 +730,8 @@ int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) { uint64_t emlGetKey(int sectorNum, int keyType) { uint8_t key[6] = {0x00}; - uint8_t *emCARD = BigBuf_get_EM_addr(); - memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6); + uint8_t *em = BigBuf_get_EM_addr(); + memcpy(key, em + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6); return bytes_to_num(key, 6); } From 9db65186e3394c3b9d666de59021dee2fa01070a Mon Sep 17 00:00:00 2001 From: Self Not Found Date: Tue, 27 Jun 2023 11:28:11 +0800 Subject: [PATCH 63/68] Fix note for hf fudan wrbl --- client/src/cmdhffudan.c | 2 +- doc/commands.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhffudan.c b/client/src/cmdhffudan.c index 502425f83..38ef8eef5 100644 --- a/client/src/cmdhffudan.c +++ b/client/src/cmdhffudan.c @@ -355,7 +355,7 @@ static int CmdHFFudanWrBl(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf fudan wrbl", "Write fudan block with 4 hex bytes of data\n", - "hf mf wrbl --blk 1 -k FFFFFFFFFFFF -d 01020304" + "hf fudan wrbl --blk 1 -k FFFFFFFFFFFF -d 01020304" ); void *argtable[] = { arg_param_begin, diff --git a/doc/commands.json b/doc/commands.json index e1a0a020b..8d4185c52 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -2867,7 +2867,7 @@ "command": "hf fudan wrbl", "description": "Write fudan block with 4 hex bytes of data", "notes": [ - "hf mf wrbl --blk 1 -k FFFFFFFFFFFF -d 01020304" + "hf fudan wrbl --blk 1 -k FFFFFFFFFFFF -d 01020304" ], "offline": false, "options": [ From 66b3ebabb96499f52b5ffe19b091c0450a08cb8b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 27 Jun 2023 15:24:25 +0200 Subject: [PATCH 64/68] fix regex for extracting the description and notes.\n description now must start with a newline and go until it see the word usage:. \n\n notes now go until it sees either === or --- or \n\n\n which all would be indication that the notes section ended. --- client/pyscripts/pm3_help2json.py | 8 +- doc/commands.json | 1038 ++++++++--------------------- 2 files changed, 287 insertions(+), 759 deletions(-) diff --git a/client/pyscripts/pm3_help2json.py b/client/pyscripts/pm3_help2json.py index 8099b5d7c..34faedec5 100755 --- a/client/pyscripts/pm3_help2json.py +++ b/client/pyscripts/pm3_help2json.py @@ -62,21 +62,19 @@ def build_arg_parser(): def build_help_regex(): - """The regex uses to parse the full text output of help data from the pm3 client.""" - # Reads the divider followed by the command itself re_command = r'-{87}\n(?P.+)\n' # Reads if the command is available offline re_offline = r'available offline: (?Pyes|no)\n+' # Reads the description lines - re_description = r'(?P(?:.+\n)+)\n+' + re_description = r'(?P\n[\s\S]*?(?=usage:))' # Reads the usage string re_usage = r'(?:usage:\n(?P(?:.+\n)+)\n+)?' # Reads the options and there individual descriptions re_options = r'(?:options:\n(?P(?:.+\n)+)\n+)?' # Reads the notes and examples - re_notes = r'(?:examples\/notes:\n(?P(?:.+\n)+)\n+)?' + re_notes = r'(?:examples\/notes:\n(?P[\s\S]*?(?=(===|---|\n\n))))' # Combine them into a single regex object - re_full = re.compile(re_command+re_offline+re_description+re_usage+re_options+re_notes, re.MULTILINE); + re_full = re.compile(re_command+re_offline+re_description+re_usage+re_options+re_notes, re.MULTILINE) return re_full diff --git a/doc/commands.json b/doc/commands.json index 8d4185c52..6523703da 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -95,14 +95,6 @@ ], "usage": "analyse freq [-h] [-F ] [-L ] [-C ]" }, - "analyse help": { - "command": "analyse help", - "description": "help This help lcr Generate final byte for XOR LRC crc Stub method for CRC evaluations chksum Checksum with adding, masking and one's complement dates Look for datestamps in a given array of bytes lfsr LFSR tests a num bits test nuid create NUID from 7byte UID demodbuff Load binary string to DemodBuffer freq Calc wave lengths foo muxer units convert ETU <> US <> SSP_CLK (3.39MHz)", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "analyse lcr": { "command": "analyse lcr", "description": "Specifying the bytes of a UID with a known LRC will find the last byte value needed to generate that LRC with a rolling XOR. All bytes should be specified in HEX.", @@ -403,14 +395,6 @@ ], "usage": "data grid [-h] [-x ] [-y ]" }, - "data help": { - "command": "data help", - "description": "help This help ----------- ------------------------- Modulation------------------------- biphaserawdecode Biphase decode bin stream in DemodBuffer detectclock Detect ASK, FSK, NRZ, PSK clock rate of wave in GraphBuffer fsktonrz Convert fsk2 to nrz wave for alternate fsk demodulating (for weak fsk) manrawdecode Manchester decode binary stream in DemodBuffer modulation Identify LF signal for clock and modulation rawdemod Demodulate the data in the GraphBuffer and output binary ----------- ------------------------- Graph------------------------- askedgedetect Adjust Graph for manual ASK demod using the length of sample differences to detect the edge of a wave autocorr Autocorrelation over window dirthreshold Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev. decimate Decimate samples undecimate Un-decimate samples hide Hide graph window hpf Remove DC offset from trace iir Apply IIR buttersworth filter on plot data grid overlay grid on graph window ltrim Trim samples from left of trace mtrim Trim out samples from the specified start to the specified stop norm Normalize max/min to +/-128 plot Show graph window rtrim Trim samples from right of trace setgraphmarkers Set blue and orange marker in graph window shiftgraphzero Shift 0 for Graphed wave + or - shift value timescale Set a timescale to get a differential reading between the yellow and purple markers as time duration zerocrossings Count time between zero-crossings convertbitstream Convert GraphBuffer's 0/1 values to 127 / -127 getbitstream Convert GraphBuffer's >=1 values to 1 and <1 to 0 ----------- ------------------------- General------------------------- asn1 asn1 decoder bin2hex Converts binary to hexadecimal clear Clears bigbuf on deviceside and graph window diff diff of input files hex2bin Converts hexadecimal to binary load Load contents of file into graph window num Converts dec/hex/bin print Print the data in the DemodBuffer save Save signal trace data (from graph window) setdebugmode Set Debugging Level on client side", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "data hex2bin": { "command": "data hex2bin", "description": "This function converts hexadecimal to binary. It will ignore all non-hexadecimal characters but stop reading on whitespace", @@ -853,14 +837,6 @@ ], "usage": "emv gpo [-hkpmatw] []..." }, - "emv help": { - "command": "emv help", - "description": "help This help test Crypto logic test list List ISO7816 history", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "emv intauth": { "command": "emv intauth", "description": "Generate Internal Authenticate command. Usually needs 4-byte random number. It returns data in TLV format . Needs a EMV applet to be selected and GPO to be executed.", @@ -1046,14 +1022,6 @@ ], "usage": "quit [-h]" }, - "help": { - "command": "help", - "description": "help Use ` help` for details of a command prefs { Edit client/device preferences... } -------- ----------------------- Technology ----------------------- analyse { Analyse utils... } data { Plot window / data buffer manipulation... } emv { EMV ISO-14443 / ISO-7816... } hf { High frequency commands... } hw { Hardware commands... } lf { Low frequency commands... } nfc { NFC commands... } piv { PIV commands... } reveng { CRC calculations from RevEng software... } smart { Smart card ISO-7816 commands... } script { Scripting commands... } trace { Trace manipulation... } wiegand { Wiegand format manipulation... } -------- ----------------------- General ----------------------- clear Clear screen hints Turn hints on / off msleep Add a pause in milliseconds rem Add a text line in log file quit exit Exit program", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf 14a antifuzz": { "command": "hf 14a antifuzz", "description": "Tries to fuzz the ISO14443a anticollision phase", @@ -1130,21 +1098,18 @@ ], "usage": "hf 14a chaining [-h10]" }, - "hf 14a config": { - "command": "hf 14a config", - "description": "--------------------------------------------------------------------------------------- hf 14a cuids available offline: no", - "notes": [], + "hf 14a cuids": { + "command": "hf 14a cuids", + "description": "Collect n>0 ISO14443-a UIDs in one go", + "notes": [ + "hf 14a cuids -n 5 -> Collect 5 UIDs" + ], "offline": false, - "options": [], - "usage": "" - }, - "hf 14a help": { - "command": "hf 14a help", - "description": "----------- ----------------------- General ----------------------- help This help list List ISO 14443-a history", - "notes": [], - "offline": true, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-n, --num Number of UIDs to collect" + ], + "usage": "hf 14a cuids [-h] [-n ]" }, "hf 14a info": { "command": "hf 14a info", @@ -1358,14 +1323,6 @@ ], "usage": "hf 14b dump [-h] [-f ] [--ns]" }, - "hf 14b help": { - "command": "hf 14b help", - "description": "help This help list List ISO-14443-B history view Display content from tag dump file", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf 14b info": { "command": "hf 14b info", "description": "Tag information for ISO/IEC 14443 type B based tags", @@ -1627,14 +1584,6 @@ ], "usage": "hf 15 findafi [-h]" }, - "hf 15 help": { - "command": "hf 15 help", - "description": "----------- --------------------- General --------------------- help This help list List ISO-15693 history demod Demodulate ISO-15693 from tag", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf 15 info": { "command": "hf 15 info", "description": "Uses the optional command `get_systeminfo` 0x2B to try and extract information", @@ -2125,14 +2074,6 @@ ], "usage": "hf cipurse formatall [-hav] [-n ] [-k ] [--sreq ] [--sresp ] [--no-auth]" }, - "hf cipurse help": { - "command": "hf cipurse help", - "description": "help This help. test Regression tests", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf cipurse info": { "command": "hf cipurse info", "description": "Get info from CIPURSE tags", @@ -2304,14 +2245,6 @@ ], "usage": "hf emrtd dump [-h] [-n ] [-d ] [-e ] [-m <[0-9A-Z<]>] [--dir ]" }, - "hf emrtd help": { - "command": "hf emrtd help", - "description": "help This help info Display info about an eMRTD list List ISO 14443A/7816 history", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf emrtd info": { "command": "hf emrtd info", "description": "Display info about an eMRTD", @@ -2369,14 +2302,6 @@ ], "usage": "hf epa cnonces [-h] --size --num -d " }, - "hf epa help": { - "command": "hf epa help", - "description": "help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf epa replay": { "command": "hf epa replay", "description": "Perform PACE protocol by replaying given APDUs", @@ -2448,14 +2373,6 @@ ], "usage": "hf felica auth2 [-hv] [-i ] [-c ] [-k ]" }, - "hf felica help": { - "command": "hf felica help", - "description": "help This help ----------- ----------------------- General ----------------------- list List ISO 18092/FeliCa history ----------- ----------------------- FeliCa Standard ----------------------- ----------- ----------------------- FeliCa Light -----------------------", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf felica info": { "command": "hf felica info", "description": "Reader for FeliCa based tags", @@ -2536,11 +2453,25 @@ }, "hf felica rdbl": { "command": "hf felica rdbl", - "description": "Use this command to read block data from authentication-not-required Service.", - "notes": [], + "description": "Use this command to read block data from authentication-not-required Service. - Mode shall be Mode0. - Successful == block data - Unsuccessful == Status Flag1 and Flag2", + "notes": [ + "hf felica rdbl --sn 01 --scl 8B00 --bn 01 --ble 8000", + "hf felica rdbl --sn 01 --scl 4B18 --bn 01 --ble 8000 -b", + "hf felica rdbl -i 01100910c11bc407 --sn 01 --scl 8B00 --bn 01 --ble 8000" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-b get all block list elements 00 -> FF", + "-i set custom IDm", + "-l, --long use 3 byte block list element block number", + "--sn number of service", + "--scl service code list", + "--bn number of block", + "--ble block list element (def 2|3 bytes)", + "-v, --verbose verbose output" + ], + "usage": "hf felica rdbl [-hblv] [-i ] [--sn ] [--scl ] [--bn ] [--ble ]" }, "hf felica reader": { "command": "hf felica reader", @@ -2664,11 +2595,23 @@ }, "hf felica wrbl": { "command": "hf felica wrbl", - "description": "Use this command to write block data to authentication-not-required Service.", - "notes": [], + "description": "Use this command to write block data to authentication-not-required Service. - Mode shall be Mode0. - Un-/Ssuccessful == Status Flag1 and Flag2", + "notes": [ + "hf felica wrbl --sn 01 --scl CB10 --bn 01 --ble 8001 -d 0102030405060708090A0B0C0D0E0F10", + "hf felica wrbl -i 01100910c11bc407 --sn 01 --scl CB10 --bn 01 --ble 8001 -d 0102030405060708090A0B0C0D0E0F10" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-d, --data data, 16 hex bytes", + "-i set custom IDm", + "--sn number of service", + "--scl service code list", + "--bn number of block", + "--ble block list element (def 2|3 bytes)", + "-v, --verbose verbose output" + ], + "usage": "hf felica wrbl [-hv] [-d ] [-i ] [--sn ] [--scl ] [--bn ] [--ble ]" }, "hf fido assert": { "command": "hf fido assert", @@ -2716,14 +2659,6 @@ ], "usage": "hf fido auth [-havuc] default mode: [-f ] [-k ] [--kh ] [--cp ] [--ap ] [--cpx ] [--apx ]" }, - "hf fido help": { - "command": "hf fido help", - "description": "help This help. list List ISO 14443A history", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf fido info": { "command": "hf fido info", "description": "Get info from Fido tags", @@ -2811,14 +2746,6 @@ ], "usage": "hf fudan dump [-h] [-f ]" }, - "hf fudan help": { - "command": "hf fudan help", - "description": "help This help view Display content from tag dump file", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf fudan rdbl": { "command": "hf fudan rdbl", "description": "Read fudan block", @@ -2953,14 +2880,6 @@ ], "usage": "hf gallagher diversify [-h] --aid [--keynum ] [--uid ] [--sitekey ] [--apdu]" }, - "hf gallagher help": { - "command": "hf gallagher help", - "description": "help This help diversifykey Diversify Gallagher key decode Decode Gallagher credential block", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf gallagher reader": { "command": "hf gallagher reader", "description": "Read a Gallagher DESFire tag from the Card Application Directory, CAD Specify site key is required if using non-default key", @@ -2979,14 +2898,6 @@ ], "usage": "hf gallagher reader [-h@v] [--aid ] [--sitekey ] [--apdu]" }, - "hf help": { - "command": "hf help", - "description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } fudan { Fudan RFIDs... } gallagher { Gallagher DESFire RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } jooki { Jooki RFIDs... } iclass { ICLASS RFIDs... } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } tesla { TESLA Cards... } texkom { Texkom RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } xerox { Fuji/Xerox cartridge RFIDs... } waveshare { Waveshare NFC ePaper... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf iclass calcnewkey": { "command": "hf iclass calcnewkey", "description": "Calculate new keys for updating (blocks 3 & 4)", @@ -3048,11 +2959,23 @@ }, "hf iclass decrypt": { "command": "hf iclass decrypt", - "description": "3DES decrypt data This is a naive implementation, it tries to decrypt every block after block 6. Correct behaviour would be to decrypt only the application areas where the key is valid, which is defined by the configuration block.", - "notes": [], + "description": "3DES decrypt data This is a naive implementation, it tries to decrypt every block after block 6. Correct behaviour would be to decrypt only the application areas where the key is valid, which is defined by the configuration block. OBS! In order to use this function, the file `iclass_decryptionkey.bin` must reside in the resources directory. The file should be 16 bytes binary data or... make sure your cardhelper is placed in the sim module", + "notes": [ + "hf iclass decrypt -f hf-iclass-AA162D30F8FF12F1-dump.bin", + "hf iclass decrypt -f hf-iclass-AA162D30F8FF12F1-dump.bin -k 000102030405060708090a0b0c0d0e0f", + "hf iclass decrypt -d 1122334455667788 -k 000102030405060708090a0b0c0d0e0f" + ], "offline": true, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-f, --file filename of dump file (bin/eml/json)", + "-d, --data 3DES encrypted data", + "-k, --key 3DES transport key", + "-v, --verbose verbose output", + "--d6 decode as block 6", + "-z, --dense dense dump output style" + ], + "usage": "hf iclass decrypt [-hvz] [-f ] [-d ] [-k ] [--d6]" }, "hf iclass dump": { "command": "hf iclass dump", @@ -3170,14 +3093,6 @@ ], "usage": "hf iclass eview [-hvz] [-s <256|2048>]" }, - "hf iclass help": { - "command": "hf iclass help", - "description": "----------- --------------------- operations --------------------- help This help info Tag information list List iclass history ----------- --------------------- recovery --------------------- loclass Use loclass to perform bruteforce reader attack lookup Uses authentication trace to check for key in dictionary file ----------- --------------------- simulation --------------------- ----------- --------------------- utils --------------------- configcard Reader configuration card calcnewkey Calc diversified keys (blocks 3 & 4) to write new keys encode Encode binary wiegand to block 7 encrypt Encrypt given block data decrypt Decrypt given block data or tag dump file managekeys Manage keys to use with iclass commands permutekey Permute function from 'heart of darkness' paper view Display content from tag dump file", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf iclass info": { "command": "hf iclass info", "description": "Act as a iCLASS reader. Reads / fingerprints a iCLASS tag.", @@ -3483,14 +3398,6 @@ ], "usage": "hf jooki encode [-hrtv] [-u ] [--dragon] [--fox] [--ghost] [--knight] [--whale] [--blackdragon] [--blackfox] [--blackknight] [--blackwhale] [--whitedragon] [--whitefox] [--whiteknight] [--whitewhale] [--tid ] [--fid ]" }, - "hf jooki help": { - "command": "hf jooki help", - "description": "help This help decode Decode Jooki token encode Encode Jooki token", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf jooki sim": { "command": "hf jooki sim", "description": "Simulate a Jooki token. Either `hf mfu eload` before or use `-d` param", @@ -3519,14 +3426,6 @@ ], "usage": "hf ksx6924 balance [-hka]" }, - "hf ksx6924 help": { - "command": "hf ksx6924 help", - "description": "help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf ksx6924 info": { "command": "hf ksx6924 info", "description": "Get info about a KS X 6924 transit card. This application is used by T-Money (South Korea) and Snapper+ (Wellington, New Zealand).", @@ -3676,14 +3575,6 @@ ], "usage": "hf legic eview [-h] [--22] [--256] [--1024]" }, - "hf legic help": { - "command": "hf legic help", - "description": "----------- --------------------- operations --------------------- help This help list List LEGIC history ----------- --------------------- simulation --------------------- ----------- --------------------- utils --------------------- crc Calculate Legic CRC over given bytes view Display deobfuscated and decoded content from tag dump file", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf legic info": { "command": "hf legic info", "description": "Gets information from a LEGIC Prime tag like systemarea, user areas, etc", @@ -3852,14 +3743,6 @@ ], "usage": "hf lto dump [-h] [-f ]" }, - "hf lto help": { - "command": "hf lto help", - "description": "help This help list List LTO-CM history", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf lto info": { "command": "hf lto info", "description": "Get info from LTO tags", @@ -4450,19 +4333,32 @@ }, "hf mf gen3blk": { "command": "hf mf gen3blk", - "description": "Overwrite full manufacturer block for magic Gen3 card - You can specify part of manufacturer block as 4/7-bytes for UID change only", - "notes": [], + "description": "Overwrite full manufacturer block for magic Gen3 card - You can specify part of manufacturer block as 4/7-bytes for UID change only NOTE: BCC, SAK, ATQA will be calculated automatically", + "notes": [ + "hf mf gen3blk -> print current data", + "hf mf gen3blk -d 01020304 -> set 4 byte uid", + "hf mf gen3blk -d 01020304050607 -> set 7 byte uid", + "hf mf gen3blk -d 01020304FFFFFFFF0102030405060708" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-d, --data manufacturer block data up to 16 hex bytes" + ], + "usage": "hf mf gen3blk [-h] [-d ]" }, "hf mf gen3freeze": { "command": "hf mf gen3freeze", - "description": "Perma lock further UID changes. No more UID changes available after operation completed", - "notes": [], + "description": "Perma lock further UID changes. No more UID changes available after operation completed Note: operation is ! irreversible !", + "notes": [ + "hf mf gen3freeze -y" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-y, --yes confirm UID lock operation" + ], + "usage": "hf mf gen3freeze -y[h]" }, "hf mf gen3uid": { "command": "hf mf gen3uid", @@ -4615,14 +4511,6 @@ ], "usage": "hf mf hardnested [-habrstw] [-k ] [--blk ] [--tblk ] [--ta] [--tb] [--tk ] [-u ] [-f ] [--in] [--im] [--is] [--ia] [--i2] [--i5]" }, - "hf mf help": { - "command": "hf mf help", - "description": "help This help list List MIFARE history hardnested Nested attack for hardened MIFARE Classic cards decrypt [nt] [ar_enc] [at_enc] [data] - to decrypt sniff or trace acl Decode and print MIFARE Classic access rights bytes mad Checks and prints MAD value Value blocks view Display content from tag dump file", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf mf list": { "command": "hf mf list", "description": "Alias of `trace list -t mf` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", @@ -4680,11 +4568,22 @@ }, "hf mf ndefformat": { "command": "hf mf ndefformat", - "description": "format MIFARE Classic Tag as a NFC tag with Data Exchange Format (NDEF) If no given, UID will be used as filename. It will try default keys and MAD keys to detect if tag is already formatted in order to write.", - "notes": [], + "description": "format MIFARE Classic Tag as a NFC tag with Data Exchange Format (NDEF) If no given, UID will be used as filename. It will try default keys and MAD keys to detect if tag is already formatted in order to write. If not, it will try finding a key file based on your UID. ie, if you ran autopwn before", + "notes": [ + "hf mf ndefformat", + "hf mf ndefformat --1k -> MIFARE Classic 1k", + "hf mf ndefformat --keys hf-mf-01020304-key.bin -> MIFARE 1k with keys from specified file" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-k, --keys filename of keys", + "--mini MIFARE Classic Mini / S20", + "--1k MIFARE Classic 1k / S50 (def)", + "--2k MIFARE Classic/Plus 2k", + "--4k MIFARE Classic 4k / S70" + ], + "usage": "hf mf ndefformat [-h] [-k ] [--mini] [--1k] [--2k] [--4k]" }, "hf mf ndefread": { "command": "hf mf ndefread", @@ -4820,11 +4719,27 @@ }, "hf mf restore": { "command": "hf mf restore", - "description": "Restore MIFARE Classic dump file to tag.", - "notes": [], + "description": "Restore MIFARE Classic dump file to tag. The key file and dump file will program the card sector trailers. By default we authenticate to card with key 0xFFFFFFFFFFFF. If access rights in dump file is all zeros, it will be replaced with default values `--uid` param is used for filename templates `hf-mf--dump.bin` and `hf-mf--key.bin. if not specified, it will read the card uid instead. `--ka` param you can indicate that the key file should be used for authentication instead. if so we also try both B/A keys `--force` param is used to override warnings and allow bad ACL block writes. if not specified, it will skip blocks with bad ACL.", + "notes": [ + "hf mf restore", + "hf mf restore --1k --uid 04010203", + "hf mf restore --1k --uid 04010203 -k hf-mf-AABBCCDD-key.bin", + "hf mf restore --4k" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "--mini MIFARE Classic Mini / S20", + "--1k MIFARE Classic 1k / S50 (def)", + "--2k MIFARE Classic/Plus 2k", + "--4k MIFARE Classic 4k / S70", + "-u, --uid uid, (4|7|10 hex bytes)", + "-f, --file specify dump filename (bin/eml/json)", + "-k, --kfn key filename", + "--ka use specified keyfile to authenticate", + "--force override warnings" + ], + "usage": "hf mf restore [-h] [--mini] [--1k] [--2k] [--4k] [-u ] [-f ] [-k ] [--ka] [--force]" }, "hf mf setmod": { "command": "hf mf setmod", @@ -5796,14 +5711,6 @@ ], "usage": "hf mfdes getuid [-hav] [-n ] [-t ] [-k ] [--kdf ] [-i ] [-m ] [-c ] [--schann ] [--aid ] [--isoid ]" }, - "hf mfdes help": { - "command": "hf mfdes help", - "description": "help This help list List DESFire (ISO 14443A) history test Regression crypto tests", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf mfdes info": { "command": "hf mfdes info", "description": "Get info from MIFARE DESfire tags", @@ -6202,14 +6109,6 @@ ], "usage": "hf mfp dump [-hv] [-f ] [-k ] [--ns]" }, - "hf mfp help": { - "command": "hf mfp help", - "description": "help This help list List MIFARE Plus history", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf mfp info": { "command": "hf mfp info", "description": "Get info from MIFARE Plus tags", @@ -6279,11 +6178,17 @@ }, "hf mfp ndefformat": { "command": "hf mfp ndefformat", - "description": "format MIFARE Plus Tag as a NFC tag with Data Exchange Format (NDEF) If no given, UID will be used as filename. It will try default keys and MAD keys to detect if tag is already formatted in order to write.", - "notes": [], + "description": "format MIFARE Plus Tag as a NFC tag with Data Exchange Format (NDEF) If no given, UID will be used as filename. It will try default keys and MAD keys to detect if tag is already formatted in order to write. If not, it will try finding a key file based on your UID. ie, if you ran autopwn before", + "notes": [ + "hf mfp ndefformat", + "hf mfp ndefformat --keys hf-mf-01020304-key.bin -> with keys from specified file" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-k, --keys filename of keys" + ], + "usage": "hf mfp ndefformat [-h] [-k ]" }, "hf mfp ndefread": { "command": "hf mfp ndefread", @@ -6477,14 +6382,6 @@ ], "usage": "hf mfu eview [-h] [-e ]" }, - "hf mfu help": { - "command": "hf mfu help", - "description": "help This help keygen Generate 3DES MIFARE diversified keys pwdgen Generate pwd from known algos view Display content from tag dump file", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf mfu info": { "command": "hf mfu info", "description": "Get info about MIFARE Ultralight Family styled tag. Sometimes the tags are locked down, and you may need a key to be able to read the information", @@ -6708,14 +6605,6 @@ ], "usage": "hf mfu wrbl [-hl] [-k ] -b -d [--force]" }, - "hf ntag424 help": { - "command": "hf ntag424 help", - "description": "help This help view Display content from tag dump file", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf ntag424 info": { "command": "hf ntag424 info", "description": "Get info about NXP NTAG424 DNA Family styled tag.", @@ -6780,14 +6669,6 @@ ], "usage": "hf search [-hv]" }, - "hf seos help": { - "command": "hf seos help", - "description": "help This help list List SEOS history", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf seos info": { "command": "hf seos info", "description": "Get info from SEOS tags", @@ -6838,14 +6719,6 @@ ], "usage": "hf sniff [-h] [--sp ] [--st ] [--smode [none|drop|min|max|avg]] [--sratio ]" }, - "hf st25ta help": { - "command": "hf st25ta help", - "description": "help This help list List ISO 14443A/7816 history ndefread read NDEF file on tag", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf st25ta info": { "command": "hf st25ta info", "description": "Get info about ST25TA tag", @@ -6943,14 +6816,6 @@ ], "usage": "hf st25ta sim [-h] -u " }, - "hf tesla help": { - "command": "hf tesla help", - "description": "help This help list List ISO 14443A/7816 history", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf tesla info": { "command": "hf tesla info", "description": "Get info about TESLA Key tag", @@ -6984,14 +6849,6 @@ ], "usage": "hf tesla list [-h1crux] [--frame] [-f ]" }, - "hf texkom help": { - "command": "hf texkom help", - "description": "help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf texkom reader": { "command": "hf texkom reader", "description": "Read a texkom tag", @@ -7029,14 +6886,6 @@ ], "usage": "hf texkom sim [-hvt] [--raw ] [--id ] [--timeout ]" }, - "hf thinfilm help": { - "command": "hf thinfilm help", - "description": "help This help list List NFC Barcode / Thinfilm history - not correct", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf thinfilm info": { "command": "hf thinfilm info", "description": "Get info from Thinfilm tags", @@ -7098,14 +6947,6 @@ ], "usage": "hf topaz dump [-h] [-f ] [--ns]" }, - "hf topaz help": { - "command": "hf topaz help", - "description": "help This help list List Topaz history view Display content from tag dump file", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf topaz info": { "command": "hf topaz info", "description": "Get info from Topaz tags", @@ -7250,14 +7091,6 @@ ], "usage": "hf tune [-h] [-n ] [--bar] [--mix] [--value]" }, - "hf waveshare help": { - "command": "hf waveshare help", - "description": "help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf waveshare loadbmp": { "command": "hf waveshare loadbmp", "description": "Load BMP file to Waveshare NFC ePaper.", @@ -7294,14 +7127,6 @@ ], "usage": "hf xerox dump [-hd] [-f ]" }, - "hf xerox help": { - "command": "hf xerox help", - "description": "help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hf xerox info": { "command": "hf xerox info", "description": "Tag information for ISO/IEC 14443 type B / XEROX based tags", @@ -7416,14 +7241,6 @@ ], "usage": "hw fpgaoff [-h]" }, - "hw help": { - "command": "hw help", - "description": "------------- ----------------------- Hardware ----------------------- help This help connect Connect Proxmark3 to serial port version Show version information about the client and the connected Proxmark3, if any", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "hw lcd": { "command": "hw lcd", "description": "Send command/data to LCD", @@ -7649,14 +7466,6 @@ ], "usage": "lf awid demod [-h]" }, - "lf awid help": { - "command": "lf awid help", - "description": "help this help demod demodulate an AWID FSK tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf awid reader": { "command": "lf awid reader", "description": "read a AWID Prox tag", @@ -7725,11 +7534,29 @@ }, "lf config": { "command": "lf config", - "description": "Get/Set config for LF sampling, bit/sample, decimation, frequency These changes are temporary, will be reset after a power cycle.", - "notes": [], + "description": "Get/Set config for LF sampling, bit/sample, decimation, frequency These changes are temporary, will be reset after a power cycle. - use `lf read` performs a read (active field) - use `lf sniff` performs a sniff (no active field)", + "notes": [ + "lf config -> shows current config", + "lf config -b 8 --125 -> samples at 125 kHz, 8 bps", + "lf config -b 4 --134 --dec 3 -> samples at 134 kHz, averages three samples into one, stored with a resolution of 4 bits per sample", + "lf config --trig 20 -s 10000 -> trigger sampling when above 20, skip 10 000 first samples after triggered", + "lf config --reset -> reset back to default values" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "--125 125 kHz frequency", + "--134 134 kHz frequency", + "-a, --avg <0|1> averaging - if set, will average the stored sample value when decimating (default 1)", + "-b, --bps <1-8> sets resolution of bits per sample (default 8)", + "--dec <1-8> sets decimation. A value of N saves only 1 in N samples (default 1)", + "--divisor <19-255> Manually set freq divisor. 88 -> 134 kHz, 95 -> 125 kHz", + "-f, --freq <47-600> manually set frequency in kHz", + "-r, --reset reset values to defaults", + "-s, --skip sets a number of samples to skip before capture (default 0)", + "-t, --trig <0-128> sets trigger threshold. 0 means no threshold" + ], + "usage": "lf config [-hr] [--125] [--134] [-a <0|1>] [-b <1-8>] [--dec <1-8>] [--divisor <19-255>] [-f <47-600>] [-s ] [-t <0-128>]" }, "lf cotag demod": { "command": "lf cotag demod", @@ -7743,14 +7570,6 @@ ], "usage": "lf cotag demod [-h]" }, - "lf cotag help": { - "command": "lf cotag help", - "description": "help This help demod demodulate an COTAG tag", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf cotag reader": { "command": "lf cotag reader", "description": "read a COTAG tag, the current support for COTAG is limited.", @@ -7795,14 +7614,6 @@ ], "usage": "lf destron demod [-h]" }, - "lf destron help": { - "command": "lf destron help", - "description": "help This help demod demodulate an Destron tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf destron reader": { "command": "lf destron reader", "description": "read a Destron tag", @@ -7886,14 +7697,6 @@ ], "usage": "lf em 410x demod [-hia] [--clk ] [--err ] [--len ]" }, - "lf em 410x help": { - "command": "lf em 410x help", - "description": "help This help demod demodulate a EM410x tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf em 410x reader": { "command": "lf em 410x reader", "description": "read EM 410x tag", @@ -8020,14 +7823,6 @@ ], "usage": "lf em 4x05 dump [-h] [-p ] [-f ]" }, - "lf em 4x05 help": { - "command": "lf em 4x05 help", - "description": "help This help demod demodulate a EM4x05/EM4x69 tag from the GraphBuffer sniff Attempt to recover em4x05 commands from sample buffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf em 4x05 info": { "command": "lf em 4x05 info", "description": "Tag information EM4205/4305/4469//4569 tags. Tag must be on antenna.", @@ -8217,14 +8012,6 @@ ], "usage": "lf em 4x50 eview [-h]" }, - "lf em 4x50 help": { - "command": "lf em 4x50 help", - "description": "help This help ----------- --------------------- operations --------------------- ----------- --------------------- simulation ---------------------", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf em 4x50 info": { "command": "lf em 4x50 info", "description": "Tag information EM4x50.", @@ -8390,14 +8177,6 @@ ], "usage": "lf em 4x70 brute [-h] [--par] -b --rnd --frn [-s ]" }, - "lf em 4x70 help": { - "command": "lf em 4x70 help", - "description": "help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf em 4x70 info": { "command": "lf em 4x70 info", "description": "Tag Information EM4x70 Tag variants include ID48 automotive transponder. ID48 does not use command parity (default). V4070 and EM4170 do require parity bit.", @@ -8472,14 +8251,6 @@ ], "usage": "lf em 4x70 writepin [-h] [--par] -p " }, - "lf em help": { - "command": "lf em help", - "description": "help This help 410x { EM 4102 commands... } 4x05 { EM 4205 / 4305 / 4369 / 4469 commands... } 4x50 { EM 4350 / 4450 commands... } 4x70 { EM 4070 / 4170 commands... }", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf fdxb clone": { "command": "lf fdxb clone", "description": "clone a FDX-B tag to a T55x7, Q5/T5555 or EM4305/4469 tag.", @@ -8513,14 +8284,6 @@ ], "usage": "lf fdxb demod [-h]" }, - "lf fdxb help": { - "command": "lf fdxb help", - "description": "help this help demod demodulate a FDX-B ISO11784/85 tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf fdxb reader": { "command": "lf fdxb reader", "description": "read a FDX-B animal tag Note that the continuous mode is less verbose", @@ -8585,14 +8348,6 @@ ], "usage": "lf gallagher demod [-h]" }, - "lf gallagher help": { - "command": "lf gallagher help", - "description": "help This help demod demodulate an GALLAGHER tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf gallagher reader": { "command": "lf gallagher reader", "description": "read a GALLAGHER tag", @@ -8658,14 +8413,6 @@ ], "usage": "lf gproxii demod [-h] [-r ]" }, - "lf gproxii help": { - "command": "lf gproxii help", - "description": "help this help demod demodulate a G Prox II tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf gproxii reader": { "command": "lf gproxii reader", "description": "read a Guardall tag", @@ -8695,14 +8442,6 @@ ], "usage": "lf gproxii sim [-h] --xor --fmt --fc --cn " }, - "lf help": { - "command": "lf help", - "description": "help This help ----------- -------------- Low Frequency -------------- awid { AWID RFIDs... } cotag { COTAG CHIPs... } destron { FDX-A Destron RFIDs... } em { EM CHIPs & RFIDs... } fdxb { FDX-B RFIDs... } gallagher { GALLAGHER RFIDs... } gproxii { Guardall Prox II RFIDs... } hid { HID Prox RFIDs... } hitag { Hitag CHIPs... } idteck { Idteck RFIDs... } indala { Indala RFIDs... } io { ioProx RFIDs... } jablotron { Jablotron RFIDs... } keri { KERI RFIDs... } motorola { Motorola RFIDs... } nedap { Nedap RFIDs... } nexwatch { NexWatch RFIDs... } noralsy { Noralsy RFIDs... } pac { PAC/Stanley RFIDs... } paradox { Paradox RFIDs... } pcf7931 { PCF7931 CHIPs... } presco { Presco RFIDs... } pyramid { Farpointe/Pyramid RFIDs... } securakey { Securakey RFIDs... } ti { TI CHIPs... } t55xx { T55xx CHIPs... } viking { Viking RFIDs... } visa2000 { Visa2000 RFIDs... } ----------- --------------------- General --------------------- search Read and Search for valid known tag", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf hid brute": { "command": "lf hid brute", "description": "Enables bruteforce of HID readers with specified facility code or card number. This is an attack against the reader. If the field being bruteforced is provided, it starts with it and goes up / down one step while maintaining other supplied values. If the field being bruteforced is not provided, it will iterate through the full range while maintaining other supplied values.", @@ -8767,14 +8506,6 @@ ], "usage": "lf hid demod [-h]" }, - "lf hid help": { - "command": "lf hid help", - "description": "help this help demod demodulate HID Prox tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf hid reader": { "command": "lf hid reader", "description": "read a HID Prox tag", @@ -8868,14 +8599,6 @@ ], "usage": "lf hitag eload [-h12sm] -f " }, - "lf hitag help": { - "command": "lf hitag help", - "description": "help This help list List Hitag trace history", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf hitag info": { "command": "lf hitag info", "description": "Hitag2 tag information", @@ -9016,14 +8739,6 @@ ], "usage": "lf idteck demod [-h]" }, - "lf idteck help": { - "command": "lf idteck help", - "description": "help This help demod demodulate an Idteck tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf idteck reader": { "command": "lf idteck reader", "description": "read a Idteck tag", @@ -9088,11 +8803,26 @@ }, "lf indala clone": { "command": "lf indala clone", - "description": "clone Indala UID to T55x7 or Q5/T5555 tag using different known formats", - "notes": [], + "description": "clone Indala UID to T55x7 or Q5/T5555 tag using different known formats Warning, encoding with FC/CN doesn't always work", + "notes": [ + "lf indala clone --heden 888", + "lf indala clone --fc 123 --cn 1337", + "lf indala clone --fc 123 --cn 1337 --4041x", + "lf indala clone -r a0000000a0002021", + "lf indala clone -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-r, --raw raw bytes", + "--heden Card number for Heden 2L format", + "--fc Facility code (26 bit H10301 format)", + "--cn Card number (26 bit H10301 format)", + "--q5 Optional - specify writing to Q5/T5555 tag", + "--em Optional - specify writing to EM4305/4469 tag", + "--4041x Optional - specify Indala 4041X format, must use with fc and cn" + ], + "usage": "lf indala clone [-h] [-r ] [--heden ] [--fc ] [--cn ] [--q5] [--em] [--4041x]" }, "lf indala demod": { "command": "lf indala demod", @@ -9112,14 +8842,6 @@ ], "usage": "lf indala demod [-hi] [--clock ] [--maxerr ]" }, - "lf indala help": { - "command": "lf indala help", - "description": "help This help demod Demodulate an Indala tag (PSK1) from the GraphBuffer altdemod Alternative method to demodulate samples for Indala 64 bit UID (option '224' for 224 bit)", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf indala reader": { "command": "lf indala reader", "description": "read a Indala tag", @@ -9186,14 +8908,6 @@ ], "usage": "lf io demod [-h]" }, - "lf io help": { - "command": "lf io help", - "description": "help this help demod demodulate an ioProx tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf io reader": { "command": "lf io reader", "description": "read a ioProx tag", @@ -9263,14 +8977,6 @@ ], "usage": "lf jablotron demod [-h]" }, - "lf jablotron help": { - "command": "lf jablotron help", - "description": "help This help demod demodulate an Jablotron tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf jablotron reader": { "command": "lf jablotron reader", "description": "read a jablotron tag", @@ -9327,14 +9033,6 @@ ], "usage": "lf keri demod [-h]" }, - "lf keri help": { - "command": "lf keri help", - "description": "help This help demod demodulate an KERI tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf keri reader": { "command": "lf keri reader", "description": "read a keri tag", @@ -9390,14 +9088,6 @@ ], "usage": "lf motorola demod [-h]" }, - "lf motorola help": { - "command": "lf motorola help", - "description": "help This help demod demodulate an MOTOROLA tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf motorola reader": { "command": "lf motorola reader", "description": "read a Motorola tag", @@ -9453,14 +9143,6 @@ ], "usage": "lf nedap demod [-h]" }, - "lf nedap help": { - "command": "lf nedap help", - "description": "help This help demod demodulate Nedap tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf nedap reader": { "command": "lf nedap reader", "description": "read a Nedap tag", @@ -9527,14 +9209,6 @@ ], "usage": "lf nexwatch demod [-h]" }, - "lf nexwatch help": { - "command": "lf nexwatch help", - "description": "help This help demod demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf nexwatch reader": { "command": "lf nexwatch reader", "description": "read a Nexwatch tag", @@ -9601,14 +9275,6 @@ ], "usage": "lf noralsy demod [-h]" }, - "lf noralsy help": { - "command": "lf noralsy help", - "description": "help This help demod demodulate an Noralsy tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf noralsy reader": { "command": "lf noralsy reader", "description": "read a Noralsy tag", @@ -9668,14 +9334,6 @@ ], "usage": "lf pac demod [-h]" }, - "lf pac help": { - "command": "lf pac help", - "description": "help This help demod demodulate a PAC tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf pac reader": { "command": "lf pac reader", "description": "read a PAC/Stanley tag", @@ -9737,14 +9395,6 @@ ], "usage": "lf paradox demod [-h] [--old]" }, - "lf paradox help": { - "command": "lf paradox help", - "description": "help This help demod demodulate a Paradox FSK tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf paradox reader": { "command": "lf paradox reader", "description": "read a Paradox tag", @@ -9795,14 +9445,6 @@ ], "usage": "lf pcf7931 config [-hr] [-p ] [-d ] [--lw ] [--lp ]" }, - "lf pcf7931 help": { - "command": "lf pcf7931 help", - "description": "help This help config Configure the password, the tags initialization delay and time offsets (optional)", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf pcf7931 reader": { "command": "lf pcf7931 reader", "description": "read a PCF7931 tag", @@ -9861,14 +9503,6 @@ ], "usage": "lf presco demod [-h]" }, - "lf presco help": { - "command": "lf presco help", - "description": "help This help demod demodulate Presco tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf presco reader": { "command": "lf presco reader", "description": "read a presco tag", @@ -9928,14 +9562,6 @@ ], "usage": "lf pyramid demod [-h]" }, - "lf pyramid help": { - "command": "lf pyramid help", - "description": "help this help demod demodulate a Pyramid FSK tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf pyramid reader": { "command": "lf pyramid reader", "description": "read a Farpointe/Pyramid tag", @@ -10028,14 +9654,6 @@ ], "usage": "lf securakey demod [-h]" }, - "lf securakey help": { - "command": "lf securakey help", - "description": "help This help demod demodulate an Securakey tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf securakey reader": { "command": "lf securakey reader", "description": "read a Securakey tag", @@ -10114,11 +9732,27 @@ }, "lf simfsk": { "command": "lf simfsk", - "description": "Simulate FSK tag from DemodBuffer or input. There are about four FSK modulations to know of. FSK1 - where fc/8 = high and fc/5 = low FSK1a - is inverted FSK1, ie: fc/5 = high and fc/8 = low FSK2 - where fc/10 = high and fc/8 = low FSK2a - is inverted FSK2, ie: fc/10 = high and fc/8 = low", - "notes": [], + "description": "Simulate FSK tag from DemodBuffer or input. There are about four FSK modulations to know of. FSK1 - where fc/8 = high and fc/5 = low FSK1a - is inverted FSK1, ie: fc/5 = high and fc/8 = low FSK2 - where fc/10 = high and fc/8 = low FSK2a - is inverted FSK2, ie: fc/10 = high and fc/8 = low NOTE: if you set one clock manually set them all manually", + "notes": [ + "lf simfsk -c 40 --high 8 --low 5 -d 010203 -> FSK1 rf/40 data 010203", + "lf simfsk -c 40 --high 5 --low 8 -d 010203 -> FSK1a rf/40 data 010203", + "lf simfsk -c 64 --high 10 --low 8 -d 010203 -> FSK2 rf/64 data 010203", + "lf simfsk -c 64 --high 8 --low 10 -d 010203 -> FSK2a rf/64 data 010203", + "", + "lf simfsk -c 50 --high 10 --low 8 -d 1D5559555569A9A555A59569 -> simulate HID Prox tag manually", + "lf simfsk -c 50 --high 10 --low 8 --stt -d 011DB2487E8D811111111111 -> simulate AWID tag manually" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-c, --clk manually set clock - can autodetect if using DemodBuffer (default 64)", + "--low manually set larger Field Clock", + "--high manually set smaller Field Clock", + "--stt TBD! - STT to enable a gap between playback repetitions (default: no gap)", + "-d, --data data to sim - omit to use DemodBuffer", + "-v, --verbose verbose output" + ], + "usage": "lf simfsk [-hv] [-c ] [--low ] [--high ] [--stt] [-d ]" }, "lf simpsk": { "command": "lf simpsk", @@ -10144,19 +9778,38 @@ }, "lf sniff": { "command": "lf sniff", - "description": "Sniff low frequency signal. You need to configure the LF part on the Proxmark3 device manually. Usually a trigger and skip samples is a good thing to set before doing a low frequency sniff.", - "notes": [], + "description": "Sniff low frequency signal. You need to configure the LF part on the Proxmark3 device manually. Usually a trigger and skip samples is a good thing to set before doing a low frequency sniff. - use `lf config` to set parameters. - use `data plot` to look at sniff signal. - use `lf search -1` to see if signal can be automatic decoded", + "notes": [ + "lf sniff -v", + "lf sniff -s 3000 -@ -> oscilloscope style" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-s, --samples number of samples to collect", + "-v, --verbose verbose output", + "-@ continuous sniffing mode" + ], + "usage": "lf sniff [-hv@] [-s ]" }, "lf t55xx bruteforce": { "command": "lf t55xx bruteforce", - "description": "This command uses bruteforce to scan a number range. Try reading Page 0, block 7 before.", - "notes": [], + "description": "This command uses bruteforce to scan a number range. Try reading Page 0, block 7 before. WARNING this may brick non-password protected chips!", + "notes": [ + "lf t55xx bruteforce --r2 -s aaaaaa77 -e aaaaaa99" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-s, --start search start password (4 hex bytes)", + "-e, --end search end password (4 hex bytes)", + "--r0 downlink - fixed bit length", + "--r1 downlink - long leading reference", + "--r2 downlink - leading zero", + "--r3 downlink - 1 of 4 coding reference", + "--all try all downlink modes (def)" + ], + "usage": "lf t55xx bruteforce [-h] -s -e [--r0] [--r1] [--r2] [--r3] [--all]" }, "lf t55xx chk": { "command": "lf t55xx chk", @@ -10311,14 +9964,6 @@ ], "usage": "lf t55xx dump [-ho] [-f ] [-p ] [--ns] [--r0] [--r1] [--r2] [--r3]" }, - "lf t55xx help": { - "command": "lf t55xx help", - "description": "----------- ---------------------------- notice ----------------------------- Remember to run `lf t55xx detect` first whenever a new card is placed on the Proxmark3 or the config block changed. help This help ----------- --------------------- operations --------------------- config Set/Get T55XX configuration (modulation, inverted, offset, rate) detect Try detecting the tag modulation from reading the configuration block info Show T55x7 configuration data (page 0/ blk 0) trace Show T55x7 traceability data (page 1/ blk 0-1) ----------- --------------------- recovery --------------------- sniff Attempt to recover T55xx commands from sample buffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf t55xx info": { "command": "lf t55xx info", "description": "Show T55x7 configuration data (page 0/ blk 0) from reading the configuration block from tag. Use `-c` to specify a config block data to be used instead of reading tag.", @@ -10385,19 +10030,45 @@ }, "lf t55xx read": { "command": "lf t55xx read", - "description": "Read T55xx block data. This commands defaults to page 0.", - "notes": [], + "description": "Read T55xx block data. This commands defaults to page 0. * * * WARNING * * * Use of read with password on a tag not configured for a password can damage the tag * * * * * * * * * *", + "notes": [ + "lf t55xx read -b 0 -> read data from block 0", + "lf t55xx read -b 0 --pwd 01020304 -> read data from block 0, pwd 01020304", + "lf t55xx read -b 0 --pwd 01020304 -o -> read data from block 0, pwd 01020304, override" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-b, --blk <0-7> block number to read", + "-p, --pwd password (4 hex bytes)", + "-o, --override override safety check", + "--pg1 read page 1", + "--r0 downlink - fixed bit length (detected def)", + "--r1 downlink - long leading reference", + "--r2 downlink - leading zero", + "--r3 downlink - 1 of 4 coding reference" + ], + "usage": "lf t55xx read [-ho] -b <0-7> [-p ] [--pg1] [--r0] [--r1] [--r2] [--r3]" }, "lf t55xx recoverpw": { "command": "lf t55xx recoverpw", - "description": "This command uses a few tricks to try to recover mangled password. Try reading Page 0, block 7 before.", - "notes": [], + "description": "This command uses a few tricks to try to recover mangled password. Try reading Page 0, block 7 before. WARNING this may brick non-password protected chips!", + "notes": [ + "lf t55xx recoverpw", + "lf t55xx recoverpw -p 11223344", + "lf t55xx recoverpw -p 11223344 --r3" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-p, --pwd password (4 hex bytes)", + "--r0 downlink - fixed bit length", + "--r1 downlink - long leading reference", + "--r2 downlink - leading zero", + "--r3 downlink - 1 of 4 coding reference", + "--all try all downlink modes (def)" + ], + "usage": "lf t55xx recoverpw [-h] [-p ] [--r0] [--r1] [--r2] [--r3] [--all]" }, "lf t55xx resetread": { "command": "lf t55xx resetread", @@ -10553,14 +10224,6 @@ ], "usage": "lf ti demod [-h]" }, - "lf ti help": { - "command": "lf ti help", - "description": "help This help demod Demodulate raw bits for TI LF tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf ti reader": { "command": "lf ti reader", "description": "read a TI tag", @@ -10637,14 +10300,6 @@ ], "usage": "lf viking demod [-h]" }, - "lf viking help": { - "command": "lf viking help", - "description": "help This help demod demodulate a Viking tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf viking reader": { "command": "lf viking reader", "description": "read a Viking AM tag", @@ -10700,14 +10355,6 @@ ], "usage": "lf visa2000 demod [-h]" }, - "lf visa2000 help": { - "command": "lf visa2000 help", - "description": "help This help demod demodulate an VISA2000 tag from the GraphBuffer", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "lf visa2000 reader": { "command": "lf visa2000 reader", "description": "read a visa2000 tag", @@ -10766,14 +10413,6 @@ ], "usage": "mem dump [-hv] [-o ] [-l ] [-f ] [-c ]" }, - "mem help": { - "command": "mem help", - "description": "help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "mem info": { "command": "mem info", "description": "Collect signature and verify it from flash memory", @@ -10853,14 +10492,6 @@ ], "usage": "mem spiffs dump [-he] -s [-d ]" }, - "mem spiffs help": { - "command": "mem spiffs help", - "description": "help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "mem spiffs info": { "command": "mem spiffs info", "description": "Print file system info and usage statistics", @@ -11014,14 +10645,6 @@ ], "usage": "msleep [-h] [-t ]" }, - "nfc barcode help": { - "command": "nfc barcode help", - "description": "-------- ------------------ NFC Barcode -------------------- -------- --------------------- General --------------------- help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "nfc barcode read": { "command": "nfc barcode read", "description": "Get info from Thinfilm tags", @@ -11065,21 +10688,24 @@ ], "usage": "nfc decode [-hv] [-d ] [-f ]" }, - "nfc help": { - "command": "nfc help", - "description": "-------- --------------------- NFC Tags -------------------- type1 { NFC Forum Tag Type 1... } type2 { NFC Forum Tag Type 2... } type4a { NFC Forum Tag Type 4 ISO14443A... } type4b { NFC Forum Tag Type 4 ISO14443B... } mf { NFC Type MIFARE Classic/Plus Tag... } barcode { NFC Barcode Tag... } -------- --------------------- General --------------------- help This help decode Decode NDEF records", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "nfc mf cformat": { "command": "nfc mf cformat", - "description": "format MIFARE Classic Tag as a NFC tag with Data Exchange Format (NDEF) If no given, UID will be used as filename. It will try default keys and MAD keys to detect if tag is already formatted in order to write.", - "notes": [], + "description": "format MIFARE Classic Tag as a NFC tag with Data Exchange Format (NDEF) If no given, UID will be used as filename. It will try default keys and MAD keys to detect if tag is already formatted in order to write. If not, it will try finding a key file based on your UID. ie, if you ran autopwn before", + "notes": [ + "hf mf ndefformat", + "hf mf ndefformat --1k -> MIFARE Classic 1k", + "hf mf ndefformat --keys hf-mf-01020304-key.bin -> MIFARE 1k with keys from specified file" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help", + "-k, --keys filename of keys", + "--mini MIFARE Classic Mini / S20", + "--1k MIFARE Classic 1k / S50 (def)", + "--2k MIFARE Classic/Plus 2k", + "--4k MIFARE Classic 4k / S70" + ], + "usage": "hf mf ndefformat [-h] [-k ] [--mini] [--1k] [--2k] [--4k]" }, "nfc mf cread": { "command": "nfc mf cread", @@ -11123,14 +10749,6 @@ ], "usage": "hf mf ndefwrite [-hpv] [-d ] [-f ] [--mini] [--1k] [--2k] [--4k]" }, - "nfc mf help": { - "command": "nfc mf help", - "description": "-------- --------- NFC Type MIFARE Classic/Plus Tag -------- -------- --------------------- General --------------------- help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "nfc mf pread": { "command": "nfc mf pread", "description": "Prints NFC Data Exchange Format (NDEF)", @@ -11151,14 +10769,6 @@ ], "usage": "hf mfp ndefread [-hvb] [--aid ] [-k ] [-f ]" }, - "nfc type1 help": { - "command": "nfc type1 help", - "description": "-------- -------------- NFC Forum Tag Type 1 --------------- -------- --------------------- General --------------------- help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "nfc type1 read": { "command": "nfc type1 read", "description": "Get info from Topaz tags", @@ -11174,14 +10784,6 @@ ], "usage": "hf topaz info [-hv] [-f ]" }, - "nfc type2 help": { - "command": "nfc type2 help", - "description": "-------- -------------- NFC Forum Tag Type 2 --------------- -------- --------------------- General --------------------- help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "nfc type2 read": { "command": "nfc type2 read", "description": "Prints NFC Data Exchange Format (NDEF)", @@ -11212,14 +10814,6 @@ ], "usage": "hf 14a ndefformat [-hv]" }, - "nfc type4a help": { - "command": "nfc type4a help", - "description": "-------- --------- NFC Forum Tag Type 4 ISO14443A ---------- -------- --------------------- General --------------------- help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "nfc type4a read": { "command": "nfc type4a read", "description": "Read NFC Data Exchange Format (NDEF) file on Type 4 NDEF tag", @@ -11269,14 +10863,6 @@ ], "usage": "hf 14a ndefwrite [-hpv] [-d ] [-f ]" }, - "nfc type4b help": { - "command": "nfc type4b help", - "description": "-------- --------- NFC Forum Tag Type 4 ISO14443B ------------- -------- --------------------- General --------------------- help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "nfc type4b read": { "command": "nfc type4b read", "description": "Print NFC Data Exchange Format (NDEF)", @@ -11333,14 +10919,6 @@ ], "usage": "piv getdata [-hskatw] [--aid ] " }, - "piv help": { - "command": "piv help", - "description": "help This help list List ISO7816 history", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "piv list": { "command": "piv list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", @@ -11508,14 +11086,6 @@ ], "usage": "prefs get savepaths [-h]" }, - "prefs help": { - "command": "prefs help", - "description": "help This help get { Get a preference } set { Set a preference } show Show all preferences", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "prefs set barmode": { "command": "prefs set barmode", "description": "Set persistent preference of HF/LF tune command styled output in the client", @@ -11590,14 +11160,6 @@ ], "usage": "prefs set emoji [-h] [--alias] [--emoji] [--alttext] [--none]" }, - "prefs set help": { - "command": "prefs set help", - "description": "help This help barmode Set bar mode clientdebug Set client debug level clientdelay Set client execution delay color Set color support emoji Set emoji display hints Set hint display savepaths ... to be adjusted next ... output Set dump output style plotsliders Set plot slider display", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "prefs set hints": { "command": "prefs set hints", "description": "Set persistent preference of showing hint messages in the client", @@ -11695,13 +11257,17 @@ ], "usage": "rem [-h] []..." }, - "script help": { - "command": "script help", - "description": "This is a feature to run Lua/Cmd scripts. You can place scripts within the luascripts/cmdscripts folders. --------------------------------------------------------------------------------------- script list available offline: yes", - "notes": [], + "script list": { + "command": "script list", + "description": "List available Lua, Cmd and Python scripts", + "notes": [ + "script list" + ], "offline": true, - "options": [], - "usage": "" + "options": [ + "-h, --help This help" + ], + "usage": "script list [-h]" }, "script run": { "command": "script run", @@ -11730,14 +11296,6 @@ ], "usage": "smart brute [-ht]" }, - "smart help": { - "command": "smart help", - "description": "help This help list List ISO 7816 history upgrade Upgrade sim module firmware", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "smart info": { "command": "smart info", "description": "Extract more detailed information from smart card.", @@ -11822,14 +11380,6 @@ ], "usage": "smart setclock [-h] [--16mhz] [--8mhz] [--4mhz]" }, - "smart upgrade": { - "command": "smart upgrade", - "description": "[=] ------------------------------------------------------------------- [!] WARNING - sim module firmware upgrade [!] A dangerous command, do wrong and you could brick the sim module [=] -------------------------------------------------------------------", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "trace extract": { "command": "trace extract", "description": "Extracts protocol authentication challenges from trace buffer", @@ -11844,14 +11394,6 @@ ], "usage": "trace extract [-h1]" }, - "trace help": { - "command": "trace help", - "description": "help This help extract Extract authentication challenges found in trace list List protocol data in trace buffer load Load trace from file save Save trace buffer to file", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "trace list": { "command": "trace list", "description": "Annotate trace buffer with selected protocol data You can load a trace from file (see `trace load -h`) or it be downloaded from device by default", @@ -11924,11 +11466,15 @@ }, "usart btfactory": { "command": "usart btfactory", - "description": "Reset BT add-on to factory settings This requires 1) BTpower to be turned ON 2) BT add-on to NOT be connected => the add-on blue LED must blink", - "notes": [], + "description": "Reset BT add-on to factory settings This requires 1) BTpower to be turned ON 2) BT add-on to NOT be connected => the add-on blue LED must blink WARNING: process only if strictly needed!", + "notes": [ + "usart btfactory" + ], "offline": false, - "options": [], - "usage": "" + "options": [ + "-h, --help This help" + ], + "usage": "usart btfactory [-h]" }, "usart btpin": { "command": "usart btpin", @@ -11961,14 +11507,6 @@ ], "usage": "usart config [-hNEO] [-b ]" }, - "usart help": { - "command": "usart help", - "description": "help This help", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "usart rx": { "command": "usart rx", "description": "Receive string over USART. WARNING: it will have side-effects if used in USART HOST mode!", @@ -12070,14 +11608,6 @@ ], "usage": "wiegand encode [-h] [--fc ] --cn [--issue ] [--oem ] [-w ] [--pre]" }, - "wiegand help": { - "command": "wiegand help", - "description": "help This help list List available wiegand formats encode Encode to wiegand raw hex (currently for HID Prox) decode Convert raw hex to decoded wiegand format (currently for HID Prox)", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, "wiegand list": { "command": "wiegand list", "description": "List available wiegand formats", @@ -12092,8 +11622,8 @@ } }, "metadata": { - "commands_extracted": 759, + "commands_extracted": 675, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-06-25T20:42:06" + "extracted_on": "2023-06-27T13:20:13" } } \ No newline at end of file From b0c2ad8ac27fe2c93685b5cfd8284fdf609a3114 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 27 Jun 2023 15:25:00 +0200 Subject: [PATCH 65/68] style --- armsrc/iso15693.c | 2 +- armsrc/mifaresim.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 16dc3c575..a52b953ff 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -1846,7 +1846,7 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool icla Dbprintf("DecodeTagFSK count..... %d", dtagfsk.count); Dbprintf("DecodeReader State..... %d", dreader.state); Dbprintf("DecodeReader byteCnt... %d", dreader.byteCount); - Dbprintf("DecodeReader posCount.. %d", dreader.posCount); + Dbprintf("DecodeReader posCount.. %d", dreader.posCount); } Dbprintf("Trace length........... " _YELLOW_("%d"), BigBuf_get_traceLen()); } diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 81f26c5cb..5aa1a054a 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -893,7 +893,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 // Compliance of MIFARE Classic EV1 1K Datasheet footnote of Table 8 // If access bits show that key B is Readable, any subsequent memory access will be refused. - + if (cardAUTHKEY == AUTHKEYB && IsKeyBReadable(blockNo)) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); FpgaDisableTracing(); From ed0d18f05d6540052e1b973a201fc4b397831465 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 28 Jun 2023 13:27:50 +0200 Subject: [PATCH 66/68] QL88 tag identification. Thanks to AnnPlusPluss and Atlab for finding the key --- CHANGELOG.md | 1 + armsrc/mifarecmd.c | 18 ++++++++++++++++++ client/src/mifare/mifarehost.c | 2 ++ include/pm3_cmd.h | 1 + 4 files changed, 22 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47b958b98..ca0fede15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] ## [Seven.4.16717][2023-06-25] + - Change `hf 14a info` - now identifes QL88 tags (@iceman1001) - Added support for compiling on iOS (@The-SamminAter) - Fixed viewing MFC dump - border char is now white (@iceman1001) - Changed `data diff` - to print filenames in header if it fits (@iceman1001) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 4492c3195..c8a2d5fa2 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2631,6 +2631,7 @@ void MifareCIdent(bool is_mfc) { uint8_t gen4gmd[4] = {MIFARE_MAGIC_GDM_AUTH_KEY, 0x00, 0x6C, 0x92}; uint8_t gen4GetConf[8] = {GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_GETCNF, 0, 0}; uint8_t superGen1[9] = {0x0A, 0x00, 0x00, 0xA6, 0xB0, 0x00, 0x10, 0x14, 0x1D}; + uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); uint8_t *uid = BigBuf_malloc(10); @@ -2787,7 +2788,24 @@ void MifareCIdent(bool is_mfc) { isGen = MAGIC_GEN_4GDM; } } + + if (isGen != MAGIC_GEN_4GDM) { + 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) { + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; + if (mifare_classic_authex(pcs, cuid, 68, MF_KEY_B, 0x707B11FC1481, AUTH_FIRST, NULL, NULL) == 0) { + isGen = MAGIC_QL88; + } + crypto1_deinit(pcs); + } + } } + } }; diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 3b37182fe..6c9d8caa2 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1431,6 +1431,8 @@ int detect_mf_magic(bool is_mfc) { case MAGIC_NTAG21X: PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("NTAG21x")); break; + case MAGIC_QL88: + PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("QL88")); default: break; } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 7a19e6dbe..0983ee2e1 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -621,6 +621,7 @@ typedef struct { #define CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES 0x0613 #define CMD_HF_MIFARE_ACQ_NONCES 0x0614 #define CMD_HF_MIFARE_STATIC_NESTED 0x0615 +#define CMD_HF_MIFARE_STATIC_ENC 0x0616 #define CMD_HF_MIFARE_READBL 0x0620 #define CMD_HF_MIFAREU_READBL 0x0720 From cbfab4fc2021867edcc213e84d0d5bed2d5df841 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 28 Jun 2023 13:29:08 +0200 Subject: [PATCH 67/68] maur keys. Ql88 sector 17 a/b, thanks to AnnPlusplus and Atlab! --- client/dictionaries/mfc_default_keys.dic | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 0d34541ff..d32346428 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -31,6 +31,11 @@ D01AFEEB890A # 17 B 4B791BEA7BCC # +# QL88 keys +# 17 A/B +2612C6DE84CA +707B11FC1481 +# # B0B1B2B3B4B5 C0C1C2C3C4C5 From 5de6fa443c343fb5c492cfe3e1daebd5e7cab964 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 28 Jun 2023 15:11:48 +0200 Subject: [PATCH 68/68] missing define for QL88 --- include/protocols.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/protocols.h b/include/protocols.h index f67ae1798..0183f9f0d 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -263,6 +263,8 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MAGIC_GEN_3 9 #define MAGIC_GEN_4GTU 10 #define MAGIC_GEN_4GDM 11 +#define MAGIC_QL88 12 + // Commands for configuration of Gen4 GTU cards. // see https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/magic_cards_notes.md