From 141283ef1febe0f1a400d20c1304db9b318b32f4 Mon Sep 17 00:00:00 2001 From: LW Date: Tue, 17 Dec 2019 18:50:03 -0800 Subject: [PATCH] add detection of static tag nonces --- armsrc/mifarecmd.c | 12 +++++++++--- client/cmdhfmf.c | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 8ad9a78b..68bcc804 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -779,6 +779,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat uint32_t cuid, nt1, nt2, nttmp, nttest, ks1; uint8_t par[1]; uint32_t target_nt[2], target_ks[2]; + uint8_t target_nt_duplicate_count = 0; uint8_t par_array[4]; uint16_t ncount = 0; @@ -893,10 +894,9 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat for(i=0; i < 2 && !isOK; i++) { // look for exactly two different nonces target_nt[i] = 0; - while(target_nt[i] == 0) { // continue until we have an unambiguous nonce + while(target_nt[i] == 0 && !isOK) { // continue until we have an unambiguous nonce - // break out of the loop on button press or new usb data as - // cards that do not NACK bad keys will get stuck here + // break out of the loop on button press or new usb data if(BUTTON_PRESS() || usb_poll_validate_length()) { isOK = -2; break; @@ -953,6 +953,12 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat if (i == 1 && target_nt[1] == target_nt[0]) { // we need two different nonces target_nt[i] = 0; if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#2: dismissed (= nonce#1), ntdist=%d", j); + + if( ++target_nt_duplicate_count == 50 ) { // unable to get a 2nd nonce after 50 tries, probably a fixed nonce + isOK = -4; + break; + } + break; } if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: valid, ntdist=%d", i+1, j); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 9ecf99fb..4062ff61 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -712,6 +712,7 @@ int CmdHF14AMfNested(const char *Cmd) case -1 : PrintAndLog("Error: No response from Proxmark.\n"); break; case -2 : PrintAndLog("Button pressed. Aborted.\n"); break; case -3 : PrintAndLog("Tag isn't vulnerable to Nested Attack (random numbers are not predictable).\n"); break; + case -4 : PrintAndLog("Tag isn't vulnerable to Nested Attack (tag nonce is static).\n"); break; default : PrintAndLog("Unknown Error.\n"); } return 2; @@ -797,6 +798,7 @@ int CmdHF14AMfNested(const char *Cmd) case -1 : PrintAndLog("Error: No response from Proxmark.\n"); break; case -2 : PrintAndLog("Button pressed. Aborted.\n"); break; case -3 : PrintAndLog("Tag isn't vulnerable to Nested Attack (random numbers are not predictable).\n"); break; + case -4 : PrintAndLog("Tag isn't vulnerable to Nested Attack (tag nonce is static).\n"); break; default : PrintAndLog("Unknown Error.\n"); } free(e_sector);