diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 6aa42fd78..ed72a6b28 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -6176,7 +6176,7 @@ static int AppListSearchAID(uint32_t appNum, AppListS AppList, size_t appcount) for (int i = 0; i < appcount; i++) if (AppList[i].appNum == appNum) return i; - + return -1; } @@ -6227,6 +6227,10 @@ static int CmdHF14ADesLsApp(const char *Cmd) { uint8_t buf[250] = {0}; size_t buflen = 0; + uint32_t freemem = 0; + DesfireGetFreeMem(&dctx, &freemem); + + res = DesfireGetAIDList(&dctx, buf, &buflen); if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "Desfire GetAIDList command " _RED_("error") ". Result: %d", res); @@ -6253,12 +6257,25 @@ static int CmdHF14ADesLsApp(const char *Cmd) { } } } - + + AuthCommandsChk authCmdCheck0 = {0}; + DesfireCheckAuthCommands(0x000000, 0, &authCmdCheck0); + if (appcount > 0) { + for (int i = 0; i < appcount; i++) { + DesfireCheckAuthCommands(AppList[i].appNum, 0, &AppList[i].authCmdCheck); + } + } + PrintAndLogEx(INFO, "-------------- " _CYAN_("Alications list") " --------------"); - PrintAndLogEx(INFO, "Applications count: " _GREEN_("%zu"), appcount); + PrintAndLogEx(INFO, "Applications count: " _GREEN_("%zu") " free memory " _GREEN_("%d"), appcount, freemem); + PrintAndLogEx(INFO, "PICC level auth commands: " NOLF); + DesfireCheckAuthCommandsPrint(&authCmdCheck0); + if (appcount > 0) { for (int i = 0; i < appcount; i++) { PrintAndLogEx(INFO, "App num: 0x%02x iso id: 0x%04x name: %s", AppList[i].appNum, AppList[i].appISONum, AppList[i].appDFName); + PrintAndLogEx(INFO, "Auth commands: " NOLF); + DesfireCheckAuthCommandsPrint(&AppList[i].authCmdCheck); } } diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 3ab153f78..1d087876f 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1350,6 +1350,47 @@ int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel return 100; } +static bool DesfireCheckAuthCmd(uint32_t appAID, uint8_t keyNum, uint8_t authcmd) { + size_t recv_len = 0; + uint8_t respcode = 0; + uint8_t recv_data[256] = {0}; + + DesfireContext dctx = {0}; + dctx.keyNum = keyNum; + dctx.commMode = DCMPlain; + dctx.cmdSet = DCCNative; + + // if cant select - return false + int res = DesfireSelectAIDHex(&dctx, appAID, false, 0); + if (res != PM3_SUCCESS) + return false; + + uint8_t data[] = {keyNum, 0x00}; + res = DesfireExchangeEx(false, &dctx, authcmd, data, (authcmd == MFDES_AUTHENTICATE_EV2F) ? 2 : 1, &respcode, recv_data, &recv_len, false, 0); + DropField(); + return (res == PM3_SUCCESS && respcode == 0xaf); +} + +void DesfireCheckAuthCommands(uint32_t appAID, uint8_t keyNum, AuthCommandsChk *authCmdCheck) { + memset(authCmdCheck, 0, sizeof(AuthCommandsChk)); + + authCmdCheck->auth = DesfireCheckAuthCmd(appAID, keyNum, MFDES_AUTHENTICATE); + authCmdCheck->authISO = DesfireCheckAuthCmd(appAID, keyNum, MFDES_AUTHENTICATE_ISO); + authCmdCheck->authAES = DesfireCheckAuthCmd(appAID, keyNum, MFDES_AUTHENTICATE_AES); + authCmdCheck->authEV2 = DesfireCheckAuthCmd(appAID, keyNum, MFDES_AUTHENTICATE_EV2F); + +} + +void DesfireCheckAuthCommandsPrint(AuthCommandsChk *authCmdCheck) { + PrintAndLogEx(NORMAL, "auth:%s auth iso: %s auth aes: %s auth ev2: %s auth iso native: %s", + authCmdCheck->auth ? _GREEN_("YES") : _RED_("NO"), + authCmdCheck->authISO ? _GREEN_("YES") : _RED_("NO"), + authCmdCheck->authAES ? _GREEN_("YES") : _RED_("NO"), + authCmdCheck->authEV2 ? _GREEN_("YES") : _RED_("NO"), + authCmdCheck->authISONative ? _GREEN_("YES") : _RED_("NO") + ); +} + static int DesfireCommandEx(DesfireContext *dctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *resp, size_t *resplen, int checklength, size_t splitbysize) { if (resplen) *resplen = 0; diff --git a/client/src/mifare/desfirecore.h b/client/src/mifare/desfirecore.h index b8370b7a5..e8236768b 100644 --- a/client/src/mifare/desfirecore.h +++ b/client/src/mifare/desfirecore.h @@ -85,10 +85,19 @@ typedef struct { typedef FileListElmS FileListS[32]; +typedef struct { + bool auth; + bool authISO; + bool authAES; + bool authEV2; + bool authISONative; +} AuthCommandsChk; + typedef struct { uint32_t appNum; uint16_t appISONum; char appDFName[16]; + AuthCommandsChk authCmdCheck; } AppListElmS; typedef AppListElmS AppListS[64]; @@ -126,6 +135,8 @@ const char *DesfireAuthErrorToStr(int error); int DesfireSelectAndAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel, uint32_t aid, bool verbose); int DesfireSelectAndAuthenticateEx(DesfireContext *dctx, DesfireSecureChannel secureChannel, uint32_t aid, bool noauth, bool verbose); int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool verbose); +void DesfireCheckAuthCommands(uint32_t appAID, uint8_t keyNum, AuthCommandsChk *authCmdCheck); +void DesfireCheckAuthCommandsPrint(AuthCommandsChk *authCmdCheck); int DesfireFormatPICC(DesfireContext *dctx); int DesfireGetFreeMem(DesfireContext *dctx, uint32_t *freemem);