mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 10:37:23 -07:00
refactor: mfDarkside error code
This commit is contained in:
parent
970c2d0999
commit
5e9533a792
4 changed files with 63 additions and 70 deletions
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue