hf mfdes mad textual

This commit is contained in:
iceman1001 2022-08-20 13:08:24 +02:00
parent 58d764a49a
commit 4a31ce1656
4 changed files with 101 additions and 59 deletions

View file

@ -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;
}

View file

@ -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: {
@ -2470,7 +2479,7 @@ 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, "----------------------------------------------------------------------------------------------------------");
}
PrintAndLogEx(SUCCESS, " " _GREEN_("%02x") " |" NOLF, id);
if (isoidavail) {
@ -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,20 +2622,21 @@ 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]));
PrintAndLogEx(SUCCESS, "Access rights....... %04x", MemLeToUint2byte(&data[2]));
DesfirePrintAccessRight(&data[2]); // 2 bytes
uint8_t reclen = 0;
@ -2629,7 +2644,7 @@ void DesfirePrintFileSettings(uint8_t *data, size_t len) {
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]);

View file

@ -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;
}

View file

@ -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);