diff --git a/client/Makefile b/client/Makefile index a6d987560..4babb528f 100644 --- a/client/Makefile +++ b/client/Makefile @@ -134,6 +134,7 @@ CORESRCS = uart_posix.c \ CMDSRCS = crapto1/crapto1.c \ crapto1/crypto1.c \ + mifare/mifaredefault.c \ mifare/mfkey.c \ tea.c \ fido/additional_ca.c \ diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 777b7d25c..9c1004439 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -551,30 +551,29 @@ int CmdHF14ASniff(const char *Cmd) { return PM3_SUCCESS; } -int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { +int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool silentMode) { static uint8_t responseNum = 0; uint16_t cmdc = 0; *dataoutlen = 0; if (activateField) { - responseNum = 1; PacketResponseNG resp; // Anticollision + SELECT card SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - PrintAndLogEx(ERR, "Proxmark3 connection timeout."); + if (!silentMode) PrintAndLogEx(ERR, "Proxmark3 connection timeout."); return 1; } // check result if (resp.oldarg[0] == 0) { - PrintAndLogEx(ERR, "No card in field."); + if (!silentMode) PrintAndLogEx(ERR, "No card in field."); return 1; } if (resp.oldarg[0] != 1 && resp.oldarg[0] != 2) { - PrintAndLogEx(ERR, "Card not in iso14443-4. res=%" PRId64 ".", resp.oldarg[0]); + if (!silentMode) PrintAndLogEx(ERR, "Card not in iso14443-4. res=%" PRId64 ".", resp.oldarg[0]); return 1; } @@ -583,12 +582,12 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0 SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0, rats, 2); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - PrintAndLogEx(ERR, "Proxmark3 connection timeout."); + if (!silentMode) PrintAndLogEx(ERR, "Proxmark3 connection timeout."); return 1; } if (resp.oldarg[0] == 0) { // ats_len - PrintAndLogEx(ERR, "Can't get ATS."); + if (!silentMode) PrintAndLogEx(ERR, "Can't get ATS."); return 1; } } @@ -610,7 +609,7 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav int iLen = resp.oldarg[0]; if (!iLen) { - PrintAndLogEx(ERR, "No card response."); + if (!silentMode) PrintAndLogEx(ERR, "No card response."); return 1; } @@ -619,12 +618,12 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav *dataoutlen = 0; if (maxdataoutlen && *dataoutlen > maxdataoutlen) { - PrintAndLogEx(ERR, "Buffer too small(%d). Needs %d bytes", *dataoutlen, maxdataoutlen); + if (!silentMode) PrintAndLogEx(ERR, "Buffer too small(%d). Needs %d bytes", *dataoutlen, maxdataoutlen); return 2; } if (recv[0] != data[0]) { - PrintAndLogEx(ERR, "iso14443-4 framing error. Card send %2x must be %2x", dataout[0], data[0]); + if (!silentMode) PrintAndLogEx(ERR, "iso14443-4 framing error. Card send %2x must be %2x", dataout[0], data[0]); return 2; } @@ -632,12 +631,12 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav // CRC Check if (iLen == -1) { - PrintAndLogEx(ERR, "ISO 14443A CRC error."); + if (!silentMode) PrintAndLogEx(ERR, "ISO 14443A CRC error."); return 3; } } else { - PrintAndLogEx(ERR, "Reply timeout."); + if (!silentMode) PrintAndLogEx(ERR, "Reply timeout."); return 4; } diff --git a/client/cmdhf14a.h b/client/cmdhf14a.h index fcea5f5cf..f40ea46f0 100644 --- a/client/cmdhf14a.h +++ b/client/cmdhf14a.h @@ -30,6 +30,6 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search); const char *getTagInfo(uint8_t uid); int Hf14443_4aGetCardData(iso14a_card_select_t *card); int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); -int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); +int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool silentMode); #endif diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 23b418599..ad6fe31b2 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -13,7 +13,7 @@ #include #include "cmdparser.h" // command_t -#include "commonutil.h" // ARRAYLEN +#include "commonutil.h" // ARRAYLEN #include "comms.h" // clearCommandBuffer #include "fileutils.h" #include "cmdtrace.h" @@ -4211,7 +4211,7 @@ static int CmdHF14AMfAuth4(const char *Cmd) { return PM3_ESOFT; } - return MifareAuth4(NULL, keyn, key, true, false, true); + return MifareAuth4(NULL, keyn, key, true, false, true, true, false); } // https://www.nxp.com/docs/en/application-note/AN10787.pdf diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index c6af6305a..affd9dd6c 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -88,7 +88,7 @@ static int CmdHFMFPInfo(const char *cmd) { int datalen = 0; // https://github.com/Proxmark/proxmark3/blob/master/client/luascripts/mifarePlus.lua#L161 uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00}; - int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen); + int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen, false); if (!res && datalen > 1 && data[0] == 0x09) { SLmode = 0; } @@ -105,7 +105,7 @@ static int CmdHFMFPInfo(const char *cmd) { DropField(); - return 0; + return PM3_SUCCESS; } static int CmdHFMFPWritePerso(const char *cmd) { @@ -169,7 +169,7 @@ static int CmdHFMFPWritePerso(const char *cmd) { } PrintAndLogEx(INFO, "Write OK."); - return 0; + return PM3_SUCCESS; } uint16_t CardAddresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0xA000, 0xA001, 0xA080, 0xA081, 0xC000, 0xC001}; @@ -245,7 +245,7 @@ static int CmdHFMFPInitPerso(const char *cmd) { PrintAndLogEx(INFO, "Done."); - return 0; + return PM3_SUCCESS; } static int CmdHFMFPCommitPerso(const char *cmd) { @@ -286,7 +286,7 @@ static int CmdHFMFPCommitPerso(const char *cmd) { } PrintAndLogEx(INFO, "Switch level OK."); - return 0; + return PM3_SUCCESS; } static int CmdHFMFPAuth(const char *cmd) { @@ -324,7 +324,7 @@ static int CmdHFMFPAuth(const char *cmd) { return 1; } - return MifareAuth4(NULL, keyn, key, true, false, verbose); + return MifareAuth4(NULL, keyn, key, true, false, true, verbose, false); } static int CmdHFMFPRdbl(const char *cmd) { @@ -392,7 +392,7 @@ static int CmdHFMFPRdbl(const char *cmd) { PrintAndLogEx(INFO, "--block:%d sector[%d]:%02x key:%04x", blockn, mfNumBlocksPerSector(sectorNum), sectorNum, uKeyNum); mf4Session mf4session; - int res = MifareAuth4(&mf4session, keyn, key, true, true, verbose); + int res = MifareAuth4(&mf4session, keyn, key, true, true, true, verbose, false); if (res) { PrintAndLogEx(ERR, "Authentication error: %d", res); return res; @@ -491,7 +491,7 @@ static int CmdHFMFPRdsc(const char *cmd) { PrintAndLogEx(INFO, "--sector[%d]:%02x key:%04x", mfNumBlocksPerSector(sectorNum), sectorNum, uKeyNum); mf4Session mf4session; - int res = MifareAuth4(&mf4session, keyn, key, true, true, verbose); + int res = MifareAuth4(&mf4session, keyn, key, true, true, true, verbose, false); if (res) { PrintAndLogEx(ERR, "Authentication error: %d", res); return res; @@ -532,7 +532,7 @@ static int CmdHFMFPRdsc(const char *cmd) { } DropField(); - return 0; + return PM3_SUCCESS; } static int CmdHFMFPWrbl(const char *cmd) { @@ -595,7 +595,7 @@ static int CmdHFMFPWrbl(const char *cmd) { PrintAndLogEx(INFO, "--block:%d sector[%d]:%02x key:%04x", blockNum & 0xff, mfNumBlocksPerSector(sectorNum), sectorNum, uKeyNum); mf4Session mf4session; - int res = MifareAuth4(&mf4session, keyn, key, true, true, verbose); + int res = MifareAuth4(&mf4session, keyn, key, true, true, true, verbose, false); if (res) { PrintAndLogEx(ERR, "Authentication error: %d", res); return res; @@ -634,7 +634,40 @@ static int CmdHFMFPWrbl(const char *cmd) { DropField(); PrintAndLogEx(INFO, "Write OK."); - return 0; + return PM3_SUCCESS; +} + +static int CmdHFMFPChk() { + int res; + bool selectCard = true; + + uint8_t startSector = 0; + uint8_t endSector = 0; + uint8_t startKeyAB = 0; + uint8_t endKeyAB = 0; + + + uint8_t keyn[2] = {0}; + uint8_t key[16] = {0}; + // sector number from 0 + for (uint8_t sector = startSector; sector <= endSector; sector++) { + // 0-keyA 1-keyB + for(uint8_t keyAB = startKeyAB; keyAB <= endKeyAB; keyAB++) { + // main cycle with key check + for (int i = 0; i < g_mifare_plus_default_keys_len; i++) { + uint16_t uKeyNum = 0x4000 + sector * 2 + keyAB; + keyn[0] = uKeyNum >> 8; + keyn[1] = uKeyNum & 0xff; + res = MifareAuth4(NULL, keyn, key, selectCard, true, false, false, true); + selectCard = false; + PrintAndLogEx(WARNING, "sector %d key %d [%s] res: %d", sector, key, g_mifare_plus_default_keys[i], res); + } + } + } + + DropField(); + + return PM3_SUCCESS; } static int CmdHFMFPMAD(const char *cmd) { @@ -728,7 +761,7 @@ static int CmdHFMFPMAD(const char *cmd) { } } - return 0; + return PM3_SUCCESS; } static int CmdHFMFPNDEF(const char *cmd) { @@ -832,7 +865,7 @@ static int CmdHFMFPNDEF(const char *cmd) { NDEFDecodeAndPrint(data, datalen, verbose); - return 0; + return PM3_SUCCESS; } static command_t CommandTable[] = { @@ -845,6 +878,7 @@ static command_t CommandTable[] = { {"rdbl", CmdHFMFPRdbl, IfPm3Iso14443a, "Read blocks"}, {"rdsc", CmdHFMFPRdsc, IfPm3Iso14443a, "Read sectors"}, {"wrbl", CmdHFMFPWrbl, IfPm3Iso14443a, "Write blocks"}, + {"chk", CmdHFMFPChk, IfPm3Iso14443a, "Check keys"}, {"mad", CmdHFMFPMAD, IfPm3Iso14443a, "Checks and prints MAD"}, {"ndef", CmdHFMFPNDEF, IfPm3Iso14443a, "Prints NDEF records from card"}, {NULL, NULL, 0, NULL} @@ -853,7 +887,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdHFMFP(const char *Cmd) { diff --git a/client/mifare/mifare4.c b/client/mifare/mifare4.c index 5cdca2e14..7eecbe751 100644 --- a/client/mifare/mifare4.c +++ b/client/mifare/mifare4.c @@ -168,21 +168,24 @@ int CalculateMAC(mf4Session *session, MACType_t mtype, uint8_t blockNum, uint8_t return aes_cmac8(NULL, session->Kmac, macdata, mac, macdatalen); } -int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool verbose) { +int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode) { uint8_t data[257] = {0}; int datalen = 0; uint8_t RndA[17] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00}; uint8_t RndB[17] = {0}; + if (silentMode) + verbose = false; + if (session) session->Authenticated = false; uint8_t cmd1[] = {0x70, keyn[1], keyn[0], 0x00}; - int res = ExchangeRAW14a(cmd1, sizeof(cmd1), activateField, true, data, sizeof(data), &datalen); + int res = ExchangeRAW14a(cmd1, sizeof(cmd1), activateField, true, data, sizeof(data), &datalen, silentMode); if (res) { - PrintAndLogEx(ERR, "Exchande raw error: %d", res); - DropField(); + if (!silentMode) PrintAndLogEx(ERR, "Exchande raw error: %d", res); + if (dropFieldIfError) DropField(); return 2; } @@ -190,20 +193,20 @@ int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateF PrintAndLogEx(INFO, "phase2: %s", sprint_hex(cmd2, 33)); - res = ExchangeRAW14a(cmd2, sizeof(cmd2), false, true, data, sizeof(data), &datalen); + res = ExchangeRAW14a(cmd2, sizeof(cmd2), false, true, data, sizeof(data), &datalen, silentMode); if (res) { - PrintAndLogEx(ERR, "Exchande raw error: %d", res); - DropField(); + if (!silentMode) PrintAndLogEx(ERR, "Exchande raw error: %d", res); + if (dropFieldIfError) DropField(); return 4; } @@ -241,12 +244,12 @@ int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateF } if (memcmp(&raw[4], &RndA[1], 16)) { - PrintAndLogEx(ERR, "\nAuthentication FAILED. rnd not equal"); + if (!silentMode) PrintAndLogEx(ERR, "\nAuthentication FAILED. rnd is not equal"); if (verbose) { PrintAndLogEx(ERR, "RndA reader: %s", sprint_hex(&RndA[1], 16)); PrintAndLogEx(ERR, "RndA card: %s", sprint_hex(&raw[4], 16)); } - DropField(); + if (dropFieldIfError) DropField(); return 5; } @@ -311,7 +314,7 @@ static int intExchangeRAW14aPlus(uint8_t *datain, int datainlen, bool activateFi if (VerboseMode) PrintAndLogEx(INFO, ">>> %s", sprint_hex(datain, datainlen)); - int res = ExchangeRAW14a(datain, datainlen, activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); + int res = ExchangeRAW14a(datain, datainlen, activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen, false); if (VerboseMode) PrintAndLogEx(INFO, "<<< %s", sprint_hex(dataout, *dataoutlen)); @@ -380,7 +383,7 @@ int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data PrintAndLogEx(INFO, "--sector[%d]:%02x key:%04x", mfNumBlocksPerSector(sectorNo), sectorNo, uKeyNum); mf4Session session; - int res = MifareAuth4(&session, keyn, key, true, true, verbose); + int res = MifareAuth4(&session, keyn, key, true, true, true, verbose, false); if (res) { PrintAndLogEx(ERR, "Sector %d authentication error: %d", sectorNo, res); return res; diff --git a/client/mifare/mifare4.h b/client/mifare/mifare4.h index 31eac1fdb..fe07aceaf 100644 --- a/client/mifare/mifare4.h +++ b/client/mifare/mifare4.h @@ -45,7 +45,7 @@ void mfpSetVerboseMode(bool verbose); const char *mfpGetErrorDescription(uint8_t errorCode); int CalculateMAC(mf4Session *session, MACType_t mtype, uint8_t blockNum, uint8_t blockCount, uint8_t *data, int datalen, uint8_t *mac, bool verbose); -int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool verbose); +int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool dropFieldIfError, bool verbose, bool silentMode); int MFPWritePerso(uint8_t *keyNum, uint8_t *key, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); int MFPCommitPerso(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen);