From 4a31ce16563e74f4eafce349be1d256f393f1102 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 20 Aug 2022 13:08:24 +0200 Subject: [PATCH] hf mfdes mad textual --- client/src/cmdhfmfdes.c | 48 +++++++++++---- client/src/mifare/desfirecore.c | 101 ++++++++++++++++++-------------- client/src/mifare/mad.c | 9 +-- client/src/mifare/mad.h | 2 +- 4 files changed, 101 insertions(+), 59 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 45849035e..2c350e975 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -51,7 +51,7 @@ #define MAX_KEY_LEN 24 #define MAX_KEYS_LIST_LEN 1024 -#define status(x) ( ((uint16_t)(0x91<<8)) + (uint16_t)x ) +#define status(x) ( ((uint16_t)(0x91 << 8)) + (uint16_t)x ) /* static uint8_t desdefaultkeys[3][8] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, //Official {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}, @@ -342,8 +342,6 @@ static const char *getProductTypeStr(uint8_t *versionhw) { return "UNKNOWN PROD"; } - - static int mfdes_get_info(mfdes_info_res_t *info) { SendCommandNG(CMD_HF_DESFIRE_INFO, NULL, 0); PacketResponseNG resp; @@ -1776,18 +1774,20 @@ static int CmdHF14aDesMAD(const char *Cmd) { } } + PrintAndLogEx(SUCCESS, _CYAN_("Issuer")); + if (foundFFFFFF) { res = DesfireSelectAIDHexNoFieldOn(&dctx, 0xffffff); if (res == PM3_SUCCESS) { uint32_t madver = 0; res = DesfireValueFileOperations(&dctx, 0x00, MFDES_GET_VALUE, &madver); if (res != PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "MAD version : " _RED_("n/a")); + PrintAndLogEx(SUCCESS, "MAD version... " _RED_("n/a")); } else { if (madver == 3) - PrintAndLogEx(SUCCESS, "MAD version : " _GREEN_("3")); + PrintAndLogEx(SUCCESS, "MAD version... " _GREEN_("3")); else - PrintAndLogEx(WARNING, "MAD version : " _YELLOW_("%d"), madver); + PrintAndLogEx(WARNING, "MAD version... " _YELLOW_("%d"), madver); } uint8_t data[250] = {0}; @@ -1795,10 +1795,10 @@ static int CmdHF14aDesMAD(const char *Cmd) { res = DesfireReadFile(&dctx, 01, 0x000000, 0, data, &datalen); if (res != PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "Card Holder : " _RED_("n/a")); + PrintAndLogEx(SUCCESS, "Card Holder... " _RED_("n/a")); } else { if (datalen > 0) { - PrintAndLogEx(SUCCESS, "Card Holder : "); + PrintAndLogEx(SUCCESS, "Card Holder... "); if (verbose) { print_buffer_with_offset(data, datalen, 0, true); PrintAndLogEx(NORMAL, ""); @@ -1806,7 +1806,7 @@ static int CmdHF14aDesMAD(const char *Cmd) { MADCardHolderInfoDecode(data, datalen, verbose); PrintAndLogEx(NORMAL, ""); } else { - PrintAndLogEx(SUCCESS, "Card Holder : " _YELLOW_("none")); + PrintAndLogEx(SUCCESS, "Card Holder... " _YELLOW_("none")); } } @@ -1830,16 +1830,41 @@ static int CmdHF14aDesMAD(const char *Cmd) { } size_t madappcount = 0; - PrintAndLogEx(SUCCESS, "Applications : "); + PrintAndLogEx(SUCCESS, ""); + PrintAndLogEx(SUCCESS, _CYAN_("Applications")); for (int i = 0; i < PICCInfo.appCount; i++) { if ((AppList[i].appNum & 0xf00000) == 0xf00000) { DesfirePrintMADAID(AppList[i].appNum, verbose); + + // read file 0, 1, 2 + res = DesfireSelectAIDHexNoFieldOn(&dctx, AppList[i].appNum); + if (res == PM3_SUCCESS) { + uint8_t buf[APDU_RES_LEN] = {0}; + size_t buflen = 0; + + res = DesfireGetFileIDList(&dctx, buf, &buflen); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Desfire GetFileIDList command " _RED_("error") ". Result: %d", res); + DropField(); + return PM3_ESOFT; + } + + if (buflen > 0) { + for (int j = 0; j < buflen; j++) { + PrintAndLogEx(INFO, " File ID... %02x", buf[j]); + } + } + } + madappcount++; } } - if (madappcount == 0) + if (madappcount == 0) { PrintAndLogEx(SUCCESS, "There is no MAD applications on the card"); + DropField(); + return PM3_SUCCESS; + } DropField(); return PM3_SUCCESS; @@ -3492,6 +3517,7 @@ static int CmdHF14ADesGetFileSettings(const char *Cmd) { DesfirePrintFileSettings(buf, buflen); + PrintAndLogEx(NORMAL, ""); DropField(); return PM3_SUCCESS; } diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index a89ac2a7a..c8987a546 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -942,7 +942,7 @@ void DesfirePrintMADAID(uint32_t appid, bool verbose) { if (appid == 0xffffff) PrintAndLogEx(SUCCESS, " Card issuer information application"); else - MADDFDecodeAndPrint(short_aid); + MADDFDecodeAndPrint(short_aid, verbose); } } @@ -953,7 +953,7 @@ void DesfirePrintAIDFunctions(uint32_t appid) { uint16_t short_aid = ((aid[2] & 0xF) << 12) | (aid[1] << 4) | (aid[0] >> 4); PrintAndLogEx(SUCCESS, " AID mapped to MIFARE Classic AID (MAD): " _YELLOW_("%02X"), short_aid); PrintAndLogEx(SUCCESS, " MAD AID Cluster 0x%02X : " _YELLOW_("%s"), short_aid >> 8, nxp_cluster_to_text(short_aid >> 8)); - MADDFDecodeAndPrint(short_aid); + MADDFDecodeAndPrint(short_aid, false); } else { AIDDFDecodeAndPrint(aid); } @@ -1827,7 +1827,7 @@ void DesfirePrintAppList(DesfireContext_t *dctx, PICCInfo_t *PICCInfo, AppListS DesfirePrintAIDFunctions(appList[i].appNum); if (PICCInfo->authCmdCheck.checked) { - PrintAndLogEx(SUCCESS, "Auth commands: " NOLF); + PrintAndLogEx(SUCCESS, "Auth commands: "); DesfireCheckAuthCommandsPrint(&appList[i].authCmdCheck); PrintAndLogEx(SUCCESS, ""); } @@ -2360,10 +2360,10 @@ void DesfireDecodeFileAcessMode(const uint8_t *mode, uint8_t *r, uint8_t *w, uin void DesfirePrintAccessRight(uint8_t *data) { uint8_t r = 0, w = 0, rw = 0, ch = 0; DesfireDecodeFileAcessMode(data, &r, &w, &rw, &ch); - PrintAndLogEx(SUCCESS, "read : %s", GetDesfireAccessRightStr(r)); - PrintAndLogEx(SUCCESS, "write : %s", GetDesfireAccessRightStr(w)); - PrintAndLogEx(SUCCESS, "readwrite: %s", GetDesfireAccessRightStr(rw)); - PrintAndLogEx(SUCCESS, "change : %s", GetDesfireAccessRightStr(ch)); + PrintAndLogEx(SUCCESS, " read......... %s", GetDesfireAccessRightStr(r)); + PrintAndLogEx(SUCCESS, " write........ %s", GetDesfireAccessRightStr(w)); + PrintAndLogEx(SUCCESS, " read/write... %s", GetDesfireAccessRightStr(rw)); + PrintAndLogEx(SUCCESS, " change....... %s", GetDesfireAccessRightStr(ch)); } void DesfireFillFileSettings(uint8_t *data, size_t datalen, FileSettings_t *fsettings) { @@ -2430,22 +2430,31 @@ static void DesfirePrintShortFileTypeSettings(FileSettings_t *fsettings) { switch (fsettings->fileType) { case 0x00: case 0x01: { - PrintAndLogEx(NORMAL, "size: %d [0x%x] " NOLF, fsettings->fileSize, fsettings->fileSize); + PrintAndLogEx(NORMAL, "Size " _YELLOW_("%d") " / " _YELLOW_("0x%X") NOLF, fsettings->fileSize, fsettings->fileSize); break; } case 0x02: { - PrintAndLogEx(NORMAL, "value [%d .. %d] lim cred: 0x%02x (%d [0x%x]) " NOLF, - fsettings->lowerLimit, fsettings->upperLimit, fsettings->limitedCredit, fsettings->value, fsettings->value); + PrintAndLogEx(NORMAL, "Value [%d .. %d] lim cred: 0x%02x (%d [0x%x]) " NOLF, + fsettings->lowerLimit, + fsettings->upperLimit, + fsettings->limitedCredit, + fsettings->value, + fsettings->value + ); break; } case 0x03: case 0x04: { - PrintAndLogEx(NORMAL, "record count %d/%d size: %d [0x%x]b " NOLF, - fsettings->curRecordCount, fsettings->maxRecordCount, fsettings->recordSize, fsettings->recordSize); + PrintAndLogEx(NORMAL, "Rec cnt %d/%d size: %d [0x%x]b " NOLF, + fsettings->curRecordCount, + fsettings->maxRecordCount, + fsettings->recordSize, + fsettings->recordSize + ); break; } case 0x05: { - PrintAndLogEx(NORMAL, "key type: 0x%02x version: 0x%02x " NOLF, fsettings->keyType, fsettings->keyVersion); + PrintAndLogEx(NORMAL, "Key type: 0x%02x ver: 0x%02x " NOLF, fsettings->keyType, fsettings->keyVersion); break; } default: { @@ -2469,8 +2478,8 @@ void DesfirePrintFileSettingsOneLine(FileSettings_t *fsettings) { void DesfirePrintFileSettingsTable(bool printheader, uint8_t id, bool isoidavail, uint16_t isoid, FileSettings_t *fsettings) { if (printheader) { - PrintAndLogEx(SUCCESS, " ID |ISO ID| File type | Mode | Rights: raw, r w rw ch | File settings "); - PrintAndLogEx(SUCCESS, "------------------------------------------------------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " ID |ISO ID| File type | Mode | Rights: raw, r w rw ch | File settings"); + PrintAndLogEx(SUCCESS, "----------------------------------------------------------------------------------------------------------"); } PrintAndLogEx(SUCCESS, " " _GREEN_("%02x") " |" NOLF, id); if (isoidavail) { @@ -2482,10 +2491,10 @@ void DesfirePrintFileSettingsTable(bool printheader, uint8_t id, bool isoidavail PrintAndLogEx(NORMAL, " |" NOLF); } - PrintAndLogEx(NORMAL, "0x%02x " _CYAN_("%-15s") " |" NOLF, fsettings->fileType, GetDesfireFileType(fsettings->fileType)); + PrintAndLogEx(NORMAL, " 0x%02x " _CYAN_("%-15s") " |" NOLF, fsettings->fileType, GetDesfireFileType(fsettings->fileType)); PrintAndLogEx(NORMAL, " %-5s |" NOLF, GetDesfireCommunicationMode(fsettings->fileCommMode)); - PrintAndLogEx(NORMAL, "%04x, %-4s %-4s %-4s %-4s |" NOLF, + PrintAndLogEx(NORMAL, " %04x, %-4s %-4s %-4s %-4s |" NOLF, fsettings->rawAccessRights, GetDesfireAccessRightShortStr(fsettings->rAccess), GetDesfireAccessRightShortStr(fsettings->wAccess), @@ -2539,15 +2548,12 @@ void DesfirePrintFileSettingsExtended(FileSettings_t *fsettings) { PrintAndLogEx(NORMAL, "change: %s)", GetDesfireAccessRightStr(fsettings->chAccess)); } - static void DesfirePrintFileSettDynPart(uint8_t filetype, uint8_t *data, size_t datalen, uint8_t *dynlen, bool create) { switch (filetype) { case 0x00: case 0x01: { int filesize = MemLeToUint3byte(&data[0]); - - PrintAndLogEx(INFO, "File size : %d (0x%X) bytes", filesize, filesize); - + PrintAndLogEx(INFO, "File size (bytes)... " _YELLOW_("%d") " / " _YELLOW_("0x%X"), filesize, filesize); *dynlen = 3; break; } @@ -2557,15 +2563,23 @@ static void DesfirePrintFileSettDynPart(uint8_t filetype, uint8_t *data, size_t int value = MemLeToUint4byte(&data[8]); uint8_t limited_credit_enabled = data[12]; - PrintAndLogEx(INFO, "Lower limit : %d (0x%08X)", lowerlimit, lowerlimit); - PrintAndLogEx(INFO, "Upper limit : %d (0x%08X)", upperlimit, upperlimit); + PrintAndLogEx(INFO, "Lower limit... %d / 0x%08X", lowerlimit, lowerlimit); + PrintAndLogEx(INFO, "Upper limit... %d / 0x%08X", upperlimit, upperlimit); if (create) { - PrintAndLogEx(INFO, "Value : %d (0x%08X)", value, value); - PrintAndLogEx(INFO, "Limited credit : [%d - %s]", limited_credit_enabled, ((limited_credit_enabled & 1) != 0) ? "enabled" : "disabled"); + PrintAndLogEx(INFO, "Value............ %d / 0x%08X", value, value); + PrintAndLogEx(INFO, "Limited credit... %d - %s" + , limited_credit_enabled + , ((limited_credit_enabled & 1) != 0) ? "enabled" : "disabled" + ); } else { - PrintAndLogEx(INFO, "Limited credit : [%d - %s] %d (0x%08X)", limited_credit_enabled, ((limited_credit_enabled & 1) != 0) ? "enabled" : "disabled", value, value); + PrintAndLogEx(INFO, "Limited credit... %d - %s %d (0x%08X)" + , limited_credit_enabled + , ((limited_credit_enabled & 1) != 0) ? "enabled" : "disabled" + , value + , value + ); } - PrintAndLogEx(INFO, "GetValue access : %s", ((limited_credit_enabled & 0x02) != 0) ? "Free" : "Not Free"); + PrintAndLogEx(INFO, "GetValue access... %s", ((limited_credit_enabled & 0x02) != 0) ? "Free" : "Not Free"); *dynlen = 13; break; @@ -2575,28 +2589,28 @@ static void DesfirePrintFileSettDynPart(uint8_t filetype, uint8_t *data, size_t uint32_t recordsize = MemLeToUint3byte(&data[0]); uint32_t maxrecords = MemLeToUint3byte(&data[3]); uint32_t currentrecord = 0; - if (!create) + if (create == false) currentrecord = MemLeToUint3byte(&data[6]); - PrintAndLogEx(INFO, "Record size : %d (0x%X) bytes", recordsize, recordsize); - PrintAndLogEx(INFO, "Max num records : %d (0x%X)", maxrecords, maxrecords); - PrintAndLogEx(INFO, "Total size : %d (0x%X) bytes", recordsize * maxrecords, recordsize * maxrecords); - if (!create) - PrintAndLogEx(INFO, "Curr num records : %d (0x%X)", currentrecord, currentrecord); + PrintAndLogEx(INFO, "Record size....... %d / 0x%X bytes", recordsize, recordsize); + PrintAndLogEx(INFO, "Max num records... %d / 0x%X", maxrecords, maxrecords); + PrintAndLogEx(INFO, "Total size........ %d / 0x%X bytes", recordsize * maxrecords, recordsize * maxrecords); + if (create == false) + PrintAndLogEx(INFO, "Curr num records... %d / 0x%X", currentrecord, currentrecord); *dynlen = (create) ? 6 : 9; break; } case 0x05: { - PrintAndLogEx(INFO, "Key type [0x%02x] : %s", data[0], GetDesfireKeyType(data[0])); + PrintAndLogEx(INFO, "Key type [0x%02x] ... %s", data[0], GetDesfireKeyType(data[0])); *dynlen = 1; if (create) { - PrintAndLogEx(INFO, "Key : %s", sprint_hex(&data[1], 16)); + PrintAndLogEx(INFO, "Key... %s", sprint_hex(&data[1], 16)); *dynlen += 16; } - PrintAndLogEx(INFO, "Key version : %d (0x%X)", data[*dynlen], data[*dynlen]); + PrintAndLogEx(INFO, "Key version... %d / 0x%X", data[*dynlen], data[*dynlen]); (*dynlen)++; break; } @@ -2608,28 +2622,29 @@ static void DesfirePrintFileSettDynPart(uint8_t filetype, uint8_t *data, size_t void DesfirePrintFileSettings(uint8_t *data, size_t len) { if (len < 6) { - PrintAndLogEx(ERR, "Wrong file settings length: %zu", len); + PrintAndLogEx(ERR, "Wrong file settings length, expected 6> got %zu ", len); return; } uint8_t filetype = data[0]; PrintAndLogEx(INFO, "---- " _CYAN_("File settings") " ----"); - PrintAndLogEx(SUCCESS, "File type [0x%02x] : %s file", filetype, GetDesfireFileType(filetype)); - PrintAndLogEx(SUCCESS, "File comm mode : %s", GetDesfireCommunicationMode(data[1] & 0x03)); + PrintAndLogEx(SUCCESS, "File type " _YELLOW_("0x%02x") " ..... %s file", filetype, GetDesfireFileType(filetype)); + PrintAndLogEx(SUCCESS, "File comm mode...... %s", GetDesfireCommunicationMode(data[1] & 0x03)); bool addaccess = false; if (filetype != 0x05) { addaccess = ((data[1] & 0x80) != 0); - PrintAndLogEx(SUCCESS, "Additional access: %s", (addaccess) ? "Yes" : "No"); + PrintAndLogEx(SUCCESS, "Additional access... %s", (addaccess) ? "Yes" : "No"); } - PrintAndLogEx(SUCCESS, "Access rights : %04x", MemLeToUint2byte(&data[2])); - DesfirePrintAccessRight(&data[2]); //2 bytes + + PrintAndLogEx(SUCCESS, "Access rights....... %04x", MemLeToUint2byte(&data[2])); + DesfirePrintAccessRight(&data[2]); // 2 bytes uint8_t reclen = 0; DesfirePrintFileSettDynPart(filetype, &data[4], len - 4, &reclen, false); reclen += 4; // static part if (addaccess && filetype != 0x05 && reclen > 0 && len > reclen && len == reclen + data[reclen] * 2) { - PrintAndLogEx(SUCCESS, "Add access records: %d", data[reclen]); + PrintAndLogEx(SUCCESS, "Add access records... %d", data[reclen]); for (int i = 0; i < data[reclen] * 2; i += 2) { PrintAndLogEx(SUCCESS, "Add access rights : [%d] %04x", i / 2, MemLeToUint2byte(&data[reclen + 1 + i])); DesfirePrintAccessRight(&data[reclen + 1 + i]); diff --git a/client/src/mifare/mad.c b/client/src/mifare/mad.c index f1d5c0b55..807d0c287 100644 --- a/client/src/mifare/mad.c +++ b/client/src/mifare/mad.c @@ -125,6 +125,7 @@ static int print_aid_description(json_t *root, uint16_t aid, char *fmt, bool ver PrintAndLogEx(INFO, fmt, " (unknown)"); return PM3_ENODATA; } + const char *vmad = mad_json_get_str(elm, "mad"); const char *application = mad_json_get_str(elm, "application"); const char *company = mad_json_get_str(elm, "company"); @@ -132,7 +133,7 @@ static int print_aid_description(json_t *root, uint16_t aid, char *fmt, bool ver const char *integrator = mad_json_get_str(elm, "system_integrator"); if (application && company) { - size_t result_len = 4 + strlen(application) + strlen(company); + size_t result_len = 6 + strlen(application) + strlen(company); char result[result_len]; snprintf(result, result_len, " %s [%s]", application, company); PrintAndLogEx(INFO, fmt, result); @@ -389,12 +390,12 @@ int MAD2DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose) { return PM3_SUCCESS; } -int MADDFDecodeAndPrint(uint32_t short_aid) { +int MADDFDecodeAndPrint(uint32_t short_aid, bool verbose) { open_mad_file(&mad_known_aids, false); - char fmt[50]; + char fmt[128]; snprintf(fmt, sizeof(fmt), " MAD AID Function 0x%04X :" _YELLOW_("%s"), short_aid, "%s"); - print_aid_description(mad_known_aids, short_aid, fmt, false); + print_aid_description(mad_known_aids, short_aid, fmt, verbose); close_mad_file(mad_known_aids); return PM3_SUCCESS; } diff --git a/client/src/mifare/mad.h b/client/src/mifare/mad.h index cf951a0b7..14eae9b54 100644 --- a/client/src/mifare/mad.h +++ b/client/src/mifare/mad.h @@ -25,7 +25,7 @@ int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2); int MADDecode(uint8_t *sector0, uint8_t *sector10, uint16_t *mad, size_t *madlen, bool swapmad); int MAD1DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose, bool *haveMAD2); int MAD2DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose); -int MADDFDecodeAndPrint(uint32_t short_aid); +int MADDFDecodeAndPrint(uint32_t short_aid, bool verbose); int MADCardHolderInfoDecode(uint8_t *data, size_t datalen, bool verbose); void MADPrintHeader(void); bool HasMADKey(uint8_t *d);