mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 13:00:42 -07:00
fix: sneaky bug in magic detection where bigbuf wasnt emptied before next run
This commit is contained in:
parent
ebb2ac6f66
commit
b8776b593e
2 changed files with 26 additions and 20 deletions
|
@ -925,31 +925,37 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8
|
||||||
|
|
||||||
// prepare next select. No need to power down the card.
|
// prepare next select. No need to power down the card.
|
||||||
if (mifare_classic_halt(pcs, cuid)) {
|
if (mifare_classic_halt(pcs, cuid)) {
|
||||||
if (DBGLEVEL >= 2) Dbprintf("Nested: Halt error");
|
if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Halt error");
|
||||||
rtr--;
|
rtr--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
|
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
|
||||||
if (DBGLEVEL >= 2) Dbprintf("Nested: Can't select card");
|
if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Can't select card");
|
||||||
rtr--;
|
rtr--;
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
auth1_time = 0;
|
auth1_time = 0;
|
||||||
if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) {
|
if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) {
|
||||||
if (DBGLEVEL >= 2) Dbprintf("Nested: Auth1 error");
|
if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Auth1 error");
|
||||||
rtr--;
|
rtr--;
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
auth2_time = (delta_time) ? auth1_time + delta_time : 0;
|
auth2_time = (delta_time) ? auth1_time + delta_time : 0;
|
||||||
|
|
||||||
if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_NESTED, &nt2, &auth2_time)) {
|
if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_NESTED, &nt2, &auth2_time)) {
|
||||||
if (DBGLEVEL >= 2) Dbprintf("Nested: Auth2 error");
|
if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Auth2 error");
|
||||||
rtr--;
|
rtr--;
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// cards with fixed nonce
|
||||||
|
if (nt1 == nt2) {
|
||||||
|
Dbprintf("Nested: %08x vs %08x", nt1, nt2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160
|
uint32_t nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160
|
||||||
for (i = 101; i < 1200; i++) {
|
for (i = 101; i < 1200; i++) {
|
||||||
nttmp = prng_successor(nttmp, 1);
|
nttmp = prng_successor(nttmp, 1);
|
||||||
|
@ -964,7 +970,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8
|
||||||
} else {
|
} else {
|
||||||
delta_time = auth2_time - auth1_time + 32; // allow some slack for proper timing
|
delta_time = auth2_time - auth1_time + 32; // allow some slack for proper timing
|
||||||
}
|
}
|
||||||
if (DBGLEVEL >= 3) Dbprintf("Nested: calibrating... ntdist=%d", i);
|
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Nested: calibrating... ntdist=%d", i);
|
||||||
} else {
|
} else {
|
||||||
unsuccessful_tries++;
|
unsuccessful_tries++;
|
||||||
if (unsuccessful_tries > NESTED_MAX_TRIES) { // card isn't vulnerable to nested attack (random numbers are not predictable)
|
if (unsuccessful_tries > NESTED_MAX_TRIES) { // card isn't vulnerable to nested attack (random numbers are not predictable)
|
||||||
|
@ -975,7 +981,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8
|
||||||
|
|
||||||
davg = (davg + (rtr - 1) / 2) / (rtr - 1);
|
davg = (davg + (rtr - 1) / 2) / (rtr - 1);
|
||||||
|
|
||||||
if (DBGLEVEL >= 3) Dbprintf("rtr=%d isOK=%d min=%d max=%d avg=%d, delta_time=%d", rtr, isOK, dmin, dmax, davg, delta_time);
|
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("rtr=%d isOK=%d min=%d max=%d avg=%d, delta_time=%d", rtr, isOK, dmin, dmax, davg, delta_time);
|
||||||
|
|
||||||
dmin = davg - 2;
|
dmin = davg - 2;
|
||||||
dmax = davg + 2;
|
dmax = davg + 2;
|
||||||
|
@ -994,18 +1000,18 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8
|
||||||
|
|
||||||
// prepare next select. No need to power down the card.
|
// prepare next select. No need to power down the card.
|
||||||
if (mifare_classic_halt(pcs, cuid)) {
|
if (mifare_classic_halt(pcs, cuid)) {
|
||||||
if (DBGLEVEL >= 2) Dbprintf("Nested: Halt error");
|
if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Halt error");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
|
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
|
||||||
if (DBGLEVEL >= 2) Dbprintf("Nested: Can't select card");
|
if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Can't select card");
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
auth1_time = 0;
|
auth1_time = 0;
|
||||||
if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) {
|
if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) {
|
||||||
if (DBGLEVEL >= 2) Dbprintf("Nested: Auth1 error");
|
if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Auth1 error");
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1014,12 +1020,12 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8
|
||||||
|
|
||||||
len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time);
|
len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time);
|
||||||
if (len != 4) {
|
if (len != 4) {
|
||||||
if (DBGLEVEL >= 2) Dbprintf("Nested: Auth2 error len=%d", len);
|
if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Auth2 error len=%d", len);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
nt2 = bytes_to_num(receivedAnswer, 4);
|
nt2 = bytes_to_num(receivedAnswer, 4);
|
||||||
if (DBGLEVEL >= 3) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i + 1, nt1, nt2, par[0]);
|
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i + 1, nt1, nt2, par[0]);
|
||||||
|
|
||||||
// Parity validity check
|
// Parity validity check
|
||||||
for (j = 0; j < 4; j++) {
|
for (j = 0; j < 4; j++) {
|
||||||
|
@ -1034,7 +1040,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8
|
||||||
|
|
||||||
if (valid_nonce(nttest, nt2, ks1, par_array)) {
|
if (valid_nonce(nttest, nt2, ks1, par_array)) {
|
||||||
if (ncount > 0) { // we are only interested in disambiguous nonces, try again
|
if (ncount > 0) { // we are only interested in disambiguous nonces, try again
|
||||||
if (DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (ambiguous), ntdist=%d", i + 1, j);
|
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Nonce#%d: dismissed (ambiguous), ntdist=%d", i + 1, j);
|
||||||
target_nt[i] = 0;
|
target_nt[i] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1043,10 +1049,10 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8
|
||||||
ncount++;
|
ncount++;
|
||||||
if (i == 1 && target_nt[1] == target_nt[0]) { // we need two different nonces
|
if (i == 1 && target_nt[1] == target_nt[0]) { // we need two different nonces
|
||||||
target_nt[i] = 0;
|
target_nt[i] = 0;
|
||||||
if (DBGLEVEL >= 3) Dbprintf("Nonce#2: dismissed (= nonce#1), ntdist=%d", j);
|
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Nonce#2: dismissed (= nonce#1), ntdist=%d", j);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (DBGLEVEL >= 3) Dbprintf("Nonce#%d: valid, ntdist=%d", i + 1, j);
|
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Nonce#%d: valid, ntdist=%d", i + 1, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (target_nt[i] == 0 && j == dmax + 1 && DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (all invalid)", i + 1);
|
if (target_nt[i] == 0 && j == dmax + 1 && DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (all invalid)", i + 1);
|
||||||
|
@ -2013,7 +2019,7 @@ void MifareCIdent() {
|
||||||
|
|
||||||
// reset card
|
// reset card
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
SpinDelay(100);
|
SpinDelay(40);
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
|
int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
|
||||||
|
@ -2041,6 +2047,7 @@ OUT:
|
||||||
// turns off
|
// turns off
|
||||||
OnSuccessMagic();
|
OnSuccessMagic();
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
|
BigBuf_Clear_ext(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnSuccessMagic() {
|
void OnSuccessMagic() {
|
||||||
|
|
|
@ -1099,19 +1099,18 @@ void detect_classic_magic(void) {
|
||||||
|
|
||||||
switch (isGeneration) {
|
switch (isGeneration) {
|
||||||
case MAGIC_GEN_1A:
|
case MAGIC_GEN_1A:
|
||||||
PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1a): " _GREEN_("YES"));
|
PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Gen 1a"));
|
||||||
break;
|
break;
|
||||||
case MAGIC_GEN_1B:
|
case MAGIC_GEN_1B:
|
||||||
PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1b): " _GREEN_("YES"));
|
PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Gen 1b"));
|
||||||
break;
|
break;
|
||||||
case MAGIC_GEN_2:
|
case MAGIC_GEN_2:
|
||||||
PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 2 / CUID): " _GREEN_("YES"));
|
PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Gen 2 / CUID"));
|
||||||
break;
|
break;
|
||||||
case MAGIC_GEN_UNFUSED:
|
case MAGIC_GEN_UNFUSED:
|
||||||
PrintAndLogEx(SUCCESS, "Answers to magic commands (Write Once / FUID): " _GREEN_("YES"));
|
PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Write Once / FUID"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLogEx(INFO, "Answers to magic commands: " _YELLOW_("NO"));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue