From 222ef4e084d969012c1ddf1fe1ea09145d230a58 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 1 Apr 2023 12:24:32 +0200 Subject: [PATCH] addded static encrypted nonce checks to nested --- armsrc/mifarecmd.c | 33 +++++++++++++++++++++++++++++++-- client/src/cmdhfmf.c | 29 ++++++++++++++++++++--------- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 7eaad3e23..918e977bd 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1154,7 +1154,12 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, } memcpy(prev_enc_nt, receivedAnswer, 4); if (prev_counter == 5) { - if (g_dbglevel >= DBG_EXTENDED) DbpString("Static encrypted nonce detected, exiting..."); + if (g_dbglevel >= DBG_EXTENDED) { + DbpString("Static encrypted nonce detected, exiting..."); + uint32_t a = bytes_to_num(prev_enc_nt, 4); + uint32_t b = bytes_to_num(receivedAnswer, 4); + Dbprintf("( %08x vs %08x )", a, b); + } isOK = PM3_ESTATIC_NONCE; break; } @@ -1224,6 +1229,9 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 LED_B_ON(); WDT_HIT(); + uint8_t prev_enc_nt[] = {0, 0, 0, 0}; + uint8_t prev_counter = 0; + uint16_t unsuccessful_tries = 0; uint16_t davg = 0; dmax = 0; @@ -1266,11 +1274,13 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 }; // cards with fixed nonce + /* if (nt1 == nt2) { Dbprintf("Nested: %08x vs %08x", nt1, nt2); break; } - + */ + uint32_t nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160 for (i = 101; i < 1200; i++) { nttmp = prng_successor(nttmp, 1); @@ -1292,6 +1302,25 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 isOK = PM3_EFAILED; } } + + if (prev_enc_nt[0] == receivedAnswer[0] && + prev_enc_nt[1] == receivedAnswer[1] && + prev_enc_nt[2] == receivedAnswer[2] && + prev_enc_nt[3] == receivedAnswer[3] + ) { + prev_counter++; + } + memcpy(prev_enc_nt, receivedAnswer, 4); + if (prev_counter == 5) { + if (g_dbglevel >= DBG_EXTENDED) { + DbpString("Static encrypted nonce detected, exiting..."); + uint32_t a = bytes_to_num(prev_enc_nt, 4); + uint32_t b = bytes_to_num(receivedAnswer, 4); + Dbprintf("( %08x vs %08x )", a, b); + } + isOK = PM3_ESTATIC_NONCE; + break; + } } if (rtr > 1) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index e4b15c19e..725a3dff4 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -1528,7 +1528,7 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't PrintAndLogEx(ERR, "Command execute timeout\n"); break; case PM3_EOPABORTED: - PrintAndLogEx(WARNING, "Button pressed. Aborted.\n"); + PrintAndLogEx(WARNING, "Button pressed. Aborted\n"); break; case PM3_EFAILED: PrintAndLogEx(FAILED, "Tag isn't vulnerable to Nested Attack (PRNG is not predictable).\n"); @@ -1536,6 +1536,9 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't case PM3_ESOFT: PrintAndLogEx(FAILED, "No valid key found"); break; + case PM3_ESTATIC_NONCE: + PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n"); + break; case PM3_SUCCESS: key64 = bytes_to_num(keyBlock, 6); @@ -1560,7 +1563,7 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't } return PM3_SUCCESS; default : - PrintAndLogEx(ERR, "Unknown error.\n"); + PrintAndLogEx(ERR, "Unknown error\n"); } return PM3_SUCCESS; @@ -1608,15 +1611,18 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't PrintAndLogEx(ERR, "Command execute timeout\n"); break; case PM3_EOPABORTED: - PrintAndLogEx(WARNING, "button pressed. Aborted.\n"); + PrintAndLogEx(WARNING, "button pressed. Aborted\n"); break; case PM3_EFAILED : - PrintAndLogEx(FAILED, "Tag isn't vulnerable to Nested Attack (PRNG is not predictable).\n"); + PrintAndLogEx(FAILED, "Tag isn't vulnerable to Nested Attack (PRNG is not predictable)\n"); break; case PM3_ESOFT: //key not found calibrate = false; continue; + case PM3_ESTATIC_NONCE: + PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n"); + break; case PM3_SUCCESS: calibrate = false; e_sector[sectorNo].foundKey[trgKeyType] = 1; @@ -1625,7 +1631,7 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't mfCheckKeys_fast(SectorsCnt, true, true, 2, 1, keyBlock, e_sector, false); continue; default : - PrintAndLogEx(ERR, "Unknown error.\n"); + PrintAndLogEx(ERR, "Unknown error\n"); } free(e_sector); return PM3_ESOFT; @@ -2179,13 +2185,13 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { if (isOK) { switch (isOK) { case PM3_ETIMEOUT : - PrintAndLogEx(ERR, "Error: No response from Proxmark3.\n"); + PrintAndLogEx(ERR, "Error: No response from Proxmark3\n"); break; case PM3_EOPABORTED: - PrintAndLogEx(WARNING, "Button pressed. Aborted.\n"); + PrintAndLogEx(WARNING, "Button pressed. Aborted\n"); break; case PM3_ESTATIC_NONCE: - PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted.\n"); + PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n"); break; default : break; @@ -2841,6 +2847,11 @@ tryNested: } break; } + case PM3_ESTATIC_NONCE: + PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n"); + free(e_sector); + free(fptr); + return isOK; case PM3_SUCCESS: { calibrate = false; e_sector[current_sector_i].Key[current_key_type_i] = bytes_to_num(tmp_key, 6); @@ -2878,7 +2889,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack break; } case PM3_ESTATIC_NONCE: { - PrintAndLogEx(ERR, "\nError: Static encrypted nonce detected. Aborted.\n"); + PrintAndLogEx(ERR, "\nError: Static encrypted nonce detected. Aborted\n"); break; } default: {