mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 13:23:51 -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;
|
uint8_t cascade_levels = 0;
|
||||||
|
|
||||||
// static variables here, is re-used in the next call
|
// static variables here, is re-used in the next call
|
||||||
static uint32_t nt_attacked = 0;
|
|
||||||
static int32_t sync_cycles = 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 mf_nr_ar3 = 0;
|
||||||
|
static uint8_t par_low = 0;
|
||||||
|
|
||||||
int return_status = PM3_SUCCESS;
|
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
|
// Test if the action was cancelled
|
||||||
if (checkbtn_cnt == 1000) {
|
if (checkbtn_cnt == 1000) {
|
||||||
if (BUTTON_PRESS() || data_available()) {
|
if (BUTTON_PRESS() || data_available()) {
|
||||||
isOK = -1;
|
isOK = 5;
|
||||||
return_status = PM3_EOPABORTED;
|
return_status = PM3_EOPABORTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3382,7 +3382,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
|
ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
|
||||||
|
|
||||||
// Receive the (4 Byte) "random" TAG nonce
|
// Receive the (4 Byte) "random" TAG nonce
|
||||||
if (!ReaderReceive(receivedAnswer, receivedAnswerPar))
|
if (ReaderReceive(receivedAnswer, receivedAnswerPar) != 4)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
previous_nt = nt;
|
previous_nt = nt;
|
||||||
|
@ -3398,7 +3398,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
else if (resp_res == 4) {
|
else if (resp_res == 4) {
|
||||||
// did we get lucky and got our dummykey to be valid?
|
// did we get lucky and got our dummykey to be valid?
|
||||||
// however we don't feed key w uid it the prng..
|
// however we don't feed key w uid it the prng..
|
||||||
isOK = -6;
|
isOK = 6;
|
||||||
|
return_status = PM3_ESOFT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3416,7 +3417,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
if (nt_distance == -99999) { // invalid nonce received
|
if (nt_distance == -99999) { // invalid nonce received
|
||||||
unexpected_random++;
|
unexpected_random++;
|
||||||
if (unexpected_random > MAX_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;
|
break;
|
||||||
} else {
|
} else {
|
||||||
continue; // continue trying...
|
continue; // continue trying...
|
||||||
|
@ -3424,7 +3426,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++sync_tries > MAX_SYNC_TRIES) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3495,6 +3498,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
// Test if the information is complete
|
// Test if the information is complete
|
||||||
if (nt_diff == 0x07) {
|
if (nt_diff == 0x07) {
|
||||||
isOK = 1;
|
isOK = 1;
|
||||||
|
return_status = PM3_SUCCESS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3507,7 +3511,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
if (nt_diff == 0 && first_try) {
|
if (nt_diff == 0 && first_try) {
|
||||||
par[0]++;
|
par[0]++;
|
||||||
if (par[0] == 0) { // tried all 256 possible parities without success. Card doesn't send NACK.
|
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;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -186,14 +186,7 @@ local function main(args)
|
||||||
-- Crack it
|
-- Crack it
|
||||||
local cnt
|
local cnt
|
||||||
err, res = core.mfDarkside()
|
err, res = core.mfDarkside()
|
||||||
if err == -1 then return oops('Button pressed. Aborted.')
|
if err ~= 0 then return oops('Darkside attack failed.') end
|
||||||
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
|
|
||||||
-- The key is actually 8 bytes, so a
|
-- The key is actually 8 bytes, so a
|
||||||
-- 6-byte key is sent as 00XXXXXX
|
-- 6-byte key is sent as 00XXXXXX
|
||||||
-- This means we unpack it as first
|
-- This means we unpack it as first
|
||||||
|
|
|
@ -915,27 +915,12 @@ static int CmdHF14AMfDarkside(const char *Cmd) {
|
||||||
|
|
||||||
uint64_t key = 0;
|
uint64_t key = 0;
|
||||||
uint64_t t1 = msclock();
|
uint64_t t1 = msclock();
|
||||||
int isOK = mfDarkside(blockno, key_type, &key);
|
int ret = mfDarkside(blockno, key_type, &key);
|
||||||
t1 = msclock() - t1;
|
t1 = msclock() - t1;
|
||||||
|
|
||||||
switch (isOK) {
|
if (ret != PM3_SUCCESS) return ret;
|
||||||
case PM3_EOPABORTED:
|
|
||||||
PrintAndLogEx(WARNING, "button pressed or aborted via keyboard. aborted");
|
PrintAndLogEx(SUCCESS, "found valid key: " _GREEN_("%012" PRIx64), key);
|
||||||
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;
|
|
||||||
}
|
|
||||||
PrintAndLogEx(SUCCESS, "time in darkside " _YELLOW_("%.0f") " seconds\n", (float)t1 / 1000.0);
|
PrintAndLogEx(SUCCESS, "time in darkside " _YELLOW_("%.0f") " seconds\n", (float)t1 / 1000.0);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -2907,26 +2892,15 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "======================= " _YELLOW_("START DARKSIDE ATTACK") " =======================");
|
PrintAndLogEx(INFO, "======================= " _YELLOW_("START DARKSIDE ATTACK") " =======================");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
||||||
isOK = mfDarkside(mfFirstBlockOfSector(sectorno), MIFARE_AUTH_KEYA + keytype, &key64);
|
isOK = mfDarkside(mfFirstBlockOfSector(sectorno), MIFARE_AUTH_KEYA + keytype, &key64);
|
||||||
|
|
||||||
switch (isOK) {
|
if (isOK != PM3_SUCCESS)
|
||||||
case PM3_EOPABORTED :
|
goto noValidKeyFound;
|
||||||
PrintAndLogEx(WARNING, "\nButton pressed or aborted via keyboard");
|
|
||||||
goto noValidKeyFound;
|
PrintAndLogEx(SUCCESS, "Found valid key [ " _GREEN_("%012" PRIx64) " ]\n", key64);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the keys
|
// Store the keys
|
||||||
num_to_bytes(key64, MIFARE_KEY_SIZE, key);
|
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) {
|
while (true) {
|
||||||
clearCommandBuffer();
|
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 {
|
struct {
|
||||||
uint8_t first_run;
|
uint8_t first_run;
|
||||||
uint8_t blockno;
|
uint8_t blockno;
|
||||||
|
@ -67,12 +76,6 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
|
||||||
payload.key_type = key_type;
|
payload.key_type = key_type;
|
||||||
SendCommandNG(CMD_HF_MIFARE_READER, (uint8_t *)&payload, sizeof(payload));
|
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(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "Running darkside " NOLF);
|
PrintAndLogEx(INFO, "Running darkside " NOLF);
|
||||||
|
|
||||||
|
@ -80,16 +83,15 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
|
||||||
while (true) {
|
while (true) {
|
||||||
PrintAndLogEx(NORMAL, "." NOLF);
|
PrintAndLogEx(NORMAL, "." NOLF);
|
||||||
|
|
||||||
|
//TODO: Not really stopping the command in time.
|
||||||
if (kbd_enter_pressed()) {
|
if (kbd_enter_pressed()) {
|
||||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||||
|
PrintAndLogEx(WARNING, "\nAborted via keyboard");
|
||||||
return PM3_EOPABORTED;
|
return PM3_EOPABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (WaitForResponseTimeout(CMD_HF_MIFARE_READER, &resp, 2000)) {
|
if (WaitForResponseTimeout(CMD_HF_MIFARE_READER, &resp, 2000)) {
|
||||||
if (resp.status == PM3_EOPABORTED) {
|
|
||||||
return resp.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct p {
|
struct p {
|
||||||
int32_t isOK;
|
int32_t isOK;
|
||||||
|
@ -101,17 +103,36 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
|
||||||
uint8_t ar[4];
|
uint8_t ar[4];
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
struct p *package = (struct p *) resp.data.asBytes;
|
struct p *package = (struct p *)resp.data.asBytes;
|
||||||
|
|
||||||
if (package->isOK == -6) {
|
if (resp.status != PM3_SUCCESS) {
|
||||||
*key = 0101;
|
PrintAndLogEx(NORMAL, "");
|
||||||
return 1;
|
|
||||||
|
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));
|
uid = (uint32_t)bytes_to_num(package->cuid, sizeof(package->cuid));
|
||||||
nt = (uint32_t)bytes_to_num(package->nt, sizeof(package->nr));
|
nt = (uint32_t)bytes_to_num(package->nt, sizeof(package->nr));
|
||||||
par_list = bytes_to_num(package->par_list, sizeof(package->par_list));
|
par_list = bytes_to_num(package->par_list, sizeof(package->par_list));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue