CHG: 'hf mf fchk' - two strategys. depth first for sector 1, AB. and width first with all sectors.

first run strategy 1. then 2.
This commit is contained in:
iceman1001 2017-12-11 01:44:55 +01:00
commit da57e74140
2 changed files with 155 additions and 144 deletions

View file

@ -1079,7 +1079,6 @@ uint8_t chkKey( struct chk_t *c ) {
++i;
continue;
}
res = mifare_classic_authex(c->pcs, c->cuid, c->block, c->keyType, c->key, AUTH_FIRST, NULL, NULL);
CHK_TIMEOUT();
@ -1118,16 +1117,15 @@ uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) {
}
void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) {
// keep track of how many sectors on card.
for (uint8_t s = 0; s < *sectorcnt; ++s) {
uint8_t status;
for (uint8_t s = 0; s < *sectorcnt; s++) {
// skip already found A keys
if ( !found[(s*2)] ) {
if ( found[(s*2)] )
continue;
c->block = FirstBlockOfSector( s );
uint8_t status = chkKey( c );
status = chkKey( c );
if ( status == 0 ) {
num_to_bytes(c->key, 6, k_sector[s].keyA);
found[(s*2)] = 1;
@ -1136,19 +1134,18 @@ void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, ui
if (MF_DBGLEVEL >= 3) Dbprintf("ChkKeys_fast: Scan A (%d)", c->block);
}
}
}
}
void chkKey_scanB(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) {
// keep track of how many sectors on card.
for (uint8_t s = 0; s < *sectorcnt; ++s) {
uint8_t status;
for (uint8_t s = 0; s < *sectorcnt; s++) {
// skip already found B keys
if ( !found[(s*2)+1] ) {
if ( found[(s*2)+1] )
continue;
c->block = FirstBlockOfSector( s );
uint8_t status = chkKey( c );
status = chkKey( c );
if ( status == 0 ) {
num_to_bytes(c->key, 6, k_sector[s].keyB);
found[(s*2)+1] = 1;
@ -1157,15 +1154,12 @@ void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, ui
if (MF_DBGLEVEL >= 3) Dbprintf("ChkKeys_fast: Scan B (%d)", c->block);
}
}
}
}
// loop all A keys,
// when A is found but not B, try to read B.
void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) {
if (MF_DBGLEVEL >= 3) Dbprintf("ChkKeys_fast: Loop B only (%d)", c->block);
// read Block B, if A is found.
for (uint8_t s = 0; s < *sectorcnt; ++s) {
c->block = (FirstBlockOfSector( s ) + NumBlocksPerSector( s ) - 1);
@ -1176,10 +1170,13 @@ void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t *found
if ( status == 0 ){
found[(s*2)+1] = 1;
++*foundkeys;
if (MF_DBGLEVEL >= 3) Dbprintf("ChkKeys_fast: Loop B only (%d)", c->block);
// try quick find all B?
// assume: keys comes in groups. Find one B, test against all B.
c->key = bytes_to_num( k_sector[s].keyB, 6);
c->block = 1;
c->keyType = 1;
chkKey_scanB(c, k_sector, found, sectorcnt, foundkeys);
}
}
@ -1197,6 +1194,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
uint8_t sectorcnt = arg0 & 0xFF; // 16;
uint8_t firstchunk = (arg0 >> 8) & 0xF;
uint8_t lastchunk = (arg0 >> 12) & 0xF;
uint8_t strategy = arg1 & 0xFF;
uint8_t keyCount = arg2 & 0xFF;
uint8_t status = 0;
@ -1233,7 +1231,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
set_tracing(false);
memset(k_sector, 0x00, 480+10);
memset(found, 0x00, 80);
memset(found, 0x00, sizeof(found));
foundkeys = 0;
iso14a_card_select_t card_info;
@ -1256,18 +1254,22 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
chk_data.cuid = cuid;
chk_data.cl = cascade_levels;
chk_data.pcs = pcs;
chk_data.block = 0;
// keychunk loop - depth first for sector0.
if ( strategy == 1 ) {
for (uint8_t i = 0; i < keyCount; ++i) {
// Allow button press / usb cmd to interrupt device
if (BUTTON_PRESS() && !usb_poll_validate_length()) break;
if (BUTTON_PRESS() && !usb_poll_validate_length()) {
goto OUT;
}
WDT_HIT();
// new key
chk_data.key = bytes_to_num(datain + i * 6, 6);
// those scans messes with block.
chk_data.block = 0;
// assume: block0,1,2 has more read rights in accessbits than the sectortrailer. authenticating against block0 in each sector
// skip already found A keys
@ -1283,6 +1285,8 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
// read Block B, if A is found.
chkKey_loopBonly( &chk_data, k_sector, found, &sectorcnt, &foundkeys);
chk_data.block = 0;
}
}
@ -1299,9 +1303,11 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
}
}
} // end look - depth first
} // strategy 1
if ( strategy == 2 ) {
// Keychunk loop
for (uint8_t i = 0; i < keyCount; ++i) {
for (uint8_t i = 0; i < keyCount; i++) {
// Allow button press / usb cmd to interrupt device
if (BUTTON_PRESS() && !usb_poll_validate_length()) break;
@ -1327,10 +1333,12 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
found[(s*2)] = 1;
++foundkeys;
chkKey_scanA(&chk_data, k_sector, found, &sectorcnt, &foundkeys);
chkKey_scanA( &chk_data, k_sector, found, &sectorcnt, &foundkeys);
// read Block B, if A is found.
chkKey_loopBonly( &chk_data, k_sector, found, &sectorcnt, &foundkeys);
chk_data.block = FirstBlockOfSector( s );
}
}
@ -1352,7 +1360,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
if ( foundkeys == allkeys )
break;
} // end loop keys
} // end loop strategy 2
OUT:
LEDsoff();

View file

@ -1323,6 +1323,8 @@ int CmdHF14AMfChk_fast(const char *Cmd) {
// time
uint64_t t1 = msclock();
// strategys. 1= deep first on sector 0 AB, 2= width first on all sectors
for (uint8_t strategy = 1; strategy < 3; strategy++) {
// main keychunk loop
for (uint32_t i = 0; i < keycnt; i += chunksize) {
@ -1333,7 +1335,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) {
lastChunk = true;
// send keychunk
UsbCommand c = {CMD_MIFARE_CHKKEYS_FAST, { (SectorsCnt | (firstChunk << 8) | (lastChunk << 12) ), 0, size}};
UsbCommand c = {CMD_MIFARE_CHKKEYS_FAST, { (SectorsCnt | (firstChunk << 8) | (lastChunk << 12) ), strategy, size}};
memcpy(c.d.asBytes, keyBlock + i * 6, 6 * size);
@ -1373,6 +1375,7 @@ int CmdHF14AMfChk_fast(const char *Cmd) {
break;
}
}
}
t1 = msclock() - t1;
PrintAndLog("[+] Time in checkkeys (fast): %.1fs\n", (float)(t1/1000.0));