diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 3731a672c..2bf375a99 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -3294,10 +3294,10 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { uint8_t cascade_levels = 0; // static variables here, is re-used in the next call - static uint32_t nt_attacked = 0; static int32_t sync_cycles = 0; - static uint8_t par_low = 0; + static uint32_t nt_attacked = 0; static uint8_t mf_nr_ar3 = 0; + static uint8_t par_low = 0; int return_status = PM3_SUCCESS; @@ -3328,7 +3328,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { // Test if the action was cancelled if (checkbtn_cnt == 1000) { if (BUTTON_PRESS() || data_available()) { - isOK = -1; + isOK = 5; return_status = PM3_EOPABORTED; break; } @@ -3382,7 +3382,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time); // Receive the (4 Byte) "random" TAG nonce - if (!ReaderReceive(receivedAnswer, receivedAnswerPar)) + if (ReaderReceive(receivedAnswer, receivedAnswerPar) != 4) continue; previous_nt = nt; @@ -3398,7 +3398,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { else if (resp_res == 4) { // did we get lucky and got our dummykey to be valid? // however we don't feed key w uid it the prng.. - isOK = -6; + isOK = 6; + return_status = PM3_ESOFT; break; } @@ -3416,7 +3417,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { if (nt_distance == -99999) { // invalid nonce received unexpected_random++; if (unexpected_random > MAX_UNEXPECTED_RANDOM) { - isOK = -3; // Card has an unpredictable PRNG. Give up + isOK = 3; // Card has an unpredictable PRNG. Give up + return_status = PM3_ESOFT; break; } else { continue; // continue trying... @@ -3424,7 +3426,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { } if (++sync_tries > MAX_SYNC_TRIES) { - isOK = -4; // Card's PRNG runs at an unexpected frequency or resets unexpectedly + isOK = 4; // Card's PRNG runs at an unexpected frequency or resets unexpectedly + return_status = PM3_ESOFT; break; } @@ -3495,6 +3498,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { // Test if the information is complete if (nt_diff == 0x07) { isOK = 1; + return_status = PM3_SUCCESS; break; } @@ -3507,7 +3511,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { if (nt_diff == 0 && first_try) { par[0]++; if (par[0] == 0) { // tried all 256 possible parities without success. Card doesn't send NACK. - isOK = -2; + isOK = 2; + return_status = PM3_ESOFT; break; } } else { diff --git a/client/luascripts/hf_mf_autopwn.lua b/client/luascripts/hf_mf_autopwn.lua index 461ea8c72..08e8b218c 100644 --- a/client/luascripts/hf_mf_autopwn.lua +++ b/client/luascripts/hf_mf_autopwn.lua @@ -186,14 +186,7 @@ local function main(args) -- Crack it local cnt err, res = core.mfDarkside() - if err == -1 then return oops('Button pressed. Aborted.') - elseif err == -2 then return oops([[Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests).]]) - elseif err == -3 then return oops([[Card is not vulnerable to Darkside attack (its random number generator is not predictable).]]) - elseif err == -4 then return oops([[ - Card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown - generating polynomial with 16 effective bits only, but shows unexpected behaviour.]]) - elseif err == -5 then return oops('aborted via keyboard.') - end + if err ~= 0 then return oops('Darkside attack failed.') end -- The key is actually 8 bytes, so a -- 6-byte key is sent as 00XXXXXX -- This means we unpack it as first diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 3c65007c8..974f54dc7 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -915,27 +915,12 @@ static int CmdHF14AMfDarkside(const char *Cmd) { uint64_t key = 0; uint64_t t1 = msclock(); - int isOK = mfDarkside(blockno, key_type, &key); + int ret = mfDarkside(blockno, key_type, &key); t1 = msclock() - t1; - switch (isOK) { - case PM3_EOPABORTED: - PrintAndLogEx(WARNING, "button pressed or aborted via keyboard. aborted"); - return PM3_EOPABORTED; - case -2 : - PrintAndLogEx(FAILED, "card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests)"); - return PM3_ESOFT; - case -3 : - PrintAndLogEx(FAILED, "card is not vulnerable to Darkside attack (its random number generator is not predictable)"); - return PM3_ESOFT; - case -4 : - PrintAndLogEx(FAILED, "card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown"); - PrintAndLogEx(FAILED, "generating polynomial with 16 effective bits only, but shows unexpected behaviour"); - return PM3_ESOFT; - default : - PrintAndLogEx(SUCCESS, "found valid key: "_GREEN_("%012" PRIx64), key); - break; - } + if (ret != PM3_SUCCESS) return ret; + + PrintAndLogEx(SUCCESS, "found valid key: " _GREEN_("%012" PRIx64), key); PrintAndLogEx(SUCCESS, "time in darkside " _YELLOW_("%.0f") " seconds\n", (float)t1 / 1000.0); return PM3_SUCCESS; } @@ -2907,26 +2892,15 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (verbose) { PrintAndLogEx(INFO, "======================= " _YELLOW_("START DARKSIDE ATTACK") " ======================="); } + + PrintAndLogEx(NORMAL, ""); + isOK = mfDarkside(mfFirstBlockOfSector(sectorno), MIFARE_AUTH_KEYA + keytype, &key64); - switch (isOK) { - case PM3_EOPABORTED : - PrintAndLogEx(WARNING, "\nButton pressed or aborted via keyboard"); - goto noValidKeyFound; - case -2 : - PrintAndLogEx(FAILED, "\nCard is not vulnerable to Darkside attack (doesn't send NACK on authentication requests)."); - goto noValidKeyFound; - case -3 : - PrintAndLogEx(FAILED, "\nCard is not vulnerable to Darkside attack (its random number generator is not predictable)."); - goto noValidKeyFound; - case -4 : - PrintAndLogEx(FAILED, "\nCard is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown"); - PrintAndLogEx(FAILED, "generating polynomial with 16 effective bits only, but shows unexpected behaviour."); - goto noValidKeyFound; - default : - PrintAndLogEx(SUCCESS, "\nFound valid key [ " _GREEN_("%012" PRIx64) " ]\n", key64); - break; - } + if (isOK != PM3_SUCCESS) + goto noValidKeyFound; + + PrintAndLogEx(SUCCESS, "Found valid key [ " _GREEN_("%012" PRIx64) " ]\n", key64); // Store the keys num_to_bytes(key64, MIFARE_KEY_SIZE, key); diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 792b22ed6..8b20cba44 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -57,6 +57,15 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { while (true) { clearCommandBuffer(); + + //TODO: Not really stopping the command in time. + //flush queue + while (kbd_enter_pressed()) { + SendCommandNG(CMD_BREAK_LOOP, NULL, 0); + PrintAndLogEx(WARNING, "Aborted via keyboard"); + return PM3_EOPABORTED; + } + struct { uint8_t first_run; uint8_t blockno; @@ -67,12 +76,6 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { payload.key_type = key_type; SendCommandNG(CMD_HF_MIFARE_READER, (uint8_t *)&payload, sizeof(payload)); - //flush queue - while (kbd_enter_pressed()) { - SendCommandNG(CMD_BREAK_LOOP, NULL, 0); - return PM3_EOPABORTED; - } - PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "Running darkside " NOLF); @@ -80,16 +83,15 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { while (true) { PrintAndLogEx(NORMAL, "." NOLF); + //TODO: Not really stopping the command in time. if (kbd_enter_pressed()) { SendCommandNG(CMD_BREAK_LOOP, NULL, 0); + PrintAndLogEx(WARNING, "\nAborted via keyboard"); return PM3_EOPABORTED; } PacketResponseNG resp; if (WaitForResponseTimeout(CMD_HF_MIFARE_READER, &resp, 2000)) { - if (resp.status == PM3_EOPABORTED) { - return resp.status; - } struct p { int32_t isOK; @@ -101,17 +103,36 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { uint8_t ar[4]; } PACKED; - struct p *package = (struct p *) resp.data.asBytes; + struct p *package = (struct p *)resp.data.asBytes; - if (package->isOK == -6) { - *key = 0101; - return 1; + if (resp.status != PM3_SUCCESS) { + PrintAndLogEx(NORMAL, ""); + + switch (package->isOK) { + case 2: + PrintAndLogEx(FAILED, "Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests)."); + break; + case 3: + PrintAndLogEx(FAILED, "Card is not vulnerable to Darkside attack (its random number generator is not predictable)."); + break; + case 4: + PrintAndLogEx(FAILED, "Card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown"); + PrintAndLogEx(FAILED, "generating polynomial with 16 effective bits only, but shows unexpected behaviour."); + break; + case 5: + PrintAndLogEx(WARNING, "Button pressed. aborted"); + break; + case 6: + *key = 0101; + return PM3_SUCCESS; + default: + PrintAndLogEx(FAILED, "Unknown error. Darkside attack failed."); + break; + } + + return resp.status; } - if (package->isOK < 0) - return package->isOK; - - uid = (uint32_t)bytes_to_num(package->cuid, sizeof(package->cuid)); nt = (uint32_t)bytes_to_num(package->nt, sizeof(package->nr)); par_list = bytes_to_num(package->par_list, sizeof(package->par_list));