improve the ecfill function used in autopwn among others. Lessen failed auth/reads by skipping s 16,17 using key A for MFC EV1 cards

This commit is contained in:
iceman1001 2023-06-25 16:22:39 +02:00
commit d40a89b27b

View file

@ -2302,64 +2302,98 @@ int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keytype) {
int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) { int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) {
uint32_t cuid = 0;
struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs;
pcs = &mpcs;
// variables
uint8_t dataoutbuf[16] = {0x00};
uint8_t dataoutbuf2[16] = {0x00};
uint8_t uid[10] = {0x00};
LED_A_ON(); LED_A_ON();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
clear_trace(); clear_trace();
set_tracing(true); set_tracing(true);
// variables
bool have_uid = false;
uint8_t cascade_levels = 0;
uint32_t cuid = 0;
uint8_t uid[10] = {0x00};
struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs;
pcs = &mpcs;
int retval = PM3_SUCCESS; int retval = PM3_SUCCESS;
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { for (uint8_t s = 0; s < sectorcnt; s++) {
retval = PM3_ESOFT; uint64_t ui64Key = emlGetKey(s, keytype);
if (g_dbglevel > DBG_ERROR) Dbprintf("Can't select card");
goto out;
}
for (uint8_t sectorNo = 0; sectorNo < sectorcnt; sectorNo++) { // MFC 1K EV1 sector 16,17 don't use key A.
uint64_t ui64Key = emlGetKey(sectorNo, keytype); if ((sectorcnt == 18) && (keytype == 0) && s > 15) {
if (sectorNo == 0) { continue;
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_FIRST)) { }
retval = PM3_EPARTIAL;
if (g_dbglevel > DBG_ERROR) Dbprintf("Sector[%2d]. Auth error", sectorNo); // use fast select
if (have_uid == false) { // need a full select cycle to get the uid first
iso14a_card_select_t card_info;
if (iso14443a_select_card(uid, &card_info, &cuid, true, 0, true) == 0) {
continue; continue;
} }
} else {
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_NESTED)) { switch (card_info.uidlen) {
retval = PM3_EPARTIAL; case 4 :
if (g_dbglevel > DBG_ERROR) Dbprintf("Sector[%2d]. Auth nested error", sectorNo); cascade_levels = 1;
break;
case 7 :
cascade_levels = 2;
break;
case 10:
cascade_levels = 3;
break;
default:
break;
}
have_uid = true;
} else { // no need for anticollision. We can directly select the card
if (iso14443a_fast_select_card(uid, cascade_levels) == 0) {
continue; continue;
} }
} }
for (uint8_t blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) { // Auth
if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) { if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(s), keytype, ui64Key, AUTH_FIRST)) {
retval = PM3_EPARTIAL; retval = PM3_EPARTIAL;
if (g_dbglevel > DBG_ERROR) {
if (g_dbglevel > DBG_ERROR) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo); Dbprintf("Sector %2d - Auth error", s);
continue;
} }
continue;
}
if (memcmp(dataoutbuf, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16) == 0) { #define MAX_RETRIES 2
continue;
}
if (blockNo < NumBlocksPerSector(sectorNo) - 1) { uint8_t data[16] = {0x00};
emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1); for (uint8_t b = 0; b < NumBlocksPerSector(s); b++) {
} else { // sector trailer, keep the keys, set only the AC
emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); memset(data, 0x00, sizeof(data));
memcpy(dataoutbuf2 + 6, dataoutbuf + 6, 4);
emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); for (uint8_t r = 0; r < MAX_RETRIES; r++) {
if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(s) + b, data)) {
retval |= PM3_EPARTIAL;
if (g_dbglevel > DBG_ERROR) {
Dbprintf("Error reading sector %2d block %2d", s, b);
}
continue;
}
// No need to copy empty
if (memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16) == 0) {
continue;
}
if (b < NumBlocksPerSector(s) - 1) {
emlSetMem(data, FirstBlockOfSector(s) + b, 1);
} else {
// sector trailer, keep the keys, set only the AC
uint8_t st[16] = {0x00};
emlGetMem(st, FirstBlockOfSector(s) + b, 1);
memcpy(st + 6, data + 6, 4);
emlSetMem(st, FirstBlockOfSector(s) + b, 1);
}
} }
} }
} }
@ -2367,9 +2401,6 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) {
int res = mifare_classic_halt(pcs, cuid); int res = mifare_classic_halt(pcs, cuid);
(void)res; (void)res;
if (g_dbglevel >= DBG_INFO) DbpString("Emulator fill sectors finished");
out:
crypto1_deinit(pcs); crypto1_deinit(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LEDsoff();