refactor: mfDarkside error code

This commit is contained in:
douniwan5788 2024-09-03 14:51:00 +08:00
commit 5e9533a792
4 changed files with 63 additions and 70 deletions

View file

@ -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 {

View file

@ -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

View file

@ -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);

View file

@ -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));