+ \r
+ }\r
+ }\r
+ }\r
+ \r
+ if (keycnt == 0) {\r
+ PrintAndLog("No key specified, trying default keys");\r
+ for (;keycnt < defaultKeysSize; keycnt++)\r
+ PrintAndLog("key[%2d] %02x%02x%02x%02x%02x%02x", keycnt,\r
+ (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],\r
+ (keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6);\r
+ }\r
+ \r
+ // initialize storage for found keys\r
+ e_sector = calloc(SectorsCnt, sizeof(sector));\r
+ if (e_sector == NULL) {\r
+ free(keyBlock);\r
+ return 1;\r
+ }\r
+\r
+ // empty e_sector\r
+ for(int i = 0; i < SectorsCnt; ++i){\r
+ e_sector[i].Key[0] = 0xffffffffffff;\r
+ e_sector[i].Key[1] = 0xffffffffffff;\r
+ e_sector[i].foundKey[0] = FALSE;\r
+ e_sector[i].foundKey[1] = FALSE;\r
+ }\r
+ \r
+ \r
+ uint8_t trgKeyType = 0;\r
+ uint32_t max_keys = keycnt > (USB_CMD_DATA_SIZE/6) ? (USB_CMD_DATA_SIZE/6) : keycnt;\r
+ \r
+ // time\r
+ clock_t t1 = clock();\r
+ time_t start, end;\r
+ time(&start);\r
+ \r
+ // check keys.\r
+ for (trgKeyType = !keyType; trgKeyType < 2; (keyType==2) ? (++trgKeyType) : (trgKeyType=2) ) {\r
+\r
+ int b = blockNo;\r
+ for (int i = 0; i < SectorsCnt; ++i) {\r
+ \r
+ // skip already found keys.\r
+ if (e_sector[i].foundKey[trgKeyType]) continue;\r
+ \r
+ for (uint32_t c = 0; c < keycnt; c += max_keys) {\r
+ printf(".");\r
+ fflush(stdout); \r
+ uint32_t size = keycnt-c > max_keys ? max_keys : keycnt-c;\r
+ \r
+ res = mfCheckKeys(b, trgKeyType, true, size, &keyBlock[6*c], &key64);\r
+ if (!res) {\r
+ e_sector[i].Key[trgKeyType] = key64;\r
+ e_sector[i].foundKey[trgKeyType] = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ b < 127 ? ( b +=4 ) : ( b += 16 ); \r
+ }\r
+ }\r
+ t1 = clock() - t1;\r
+ time(&end);\r
+ unsigned long elapsed_time = difftime(end, start); \r
+ if ( t1 > 0 )\r
+ PrintAndLog("\nTime in checkkeys: %.0f ticks %u seconds\n", (float)t1, elapsed_time);\r
+\r
+ \r
+ // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag?\r
+ if ( keyType != 1 ) {\r
+ PrintAndLog("testing to read key B...");\r
+ for (i = 0; i < SectorsCnt; i++) {\r
+ // KEY A but not KEY B\r
+ if ( e_sector[i].foundKey[0] && !e_sector[i].foundKey[1] ) {\r
+ \r
+ uint8_t sectrail = (FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1);\r
+ \r
+ PrintAndLog("Reading block %d", sectrail);\r
+ \r
+ UsbCommand c = {CMD_MIFARE_READBL, {sectrail, 0, 0}};\r
+ num_to_bytes(e_sector[i].Key[0], 6, c.d.asBytes); // KEY A\r
+ clearCommandBuffer();\r
+ SendCommand(&c);\r
+\r
+ UsbCommand resp;\r
+ if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500)) continue;\r
+ \r
+ uint8_t isOK = resp.arg[0] & 0xff;\r
+ if (!isOK) continue;\r
+\r
+ uint8_t *data = resp.d.asBytes;\r
+ key64 = bytes_to_num(data+10, 6);\r
+ if (key64) {\r
+ PrintAndLog("Data:%s", sprint_hex(data+10, 6));\r
+ e_sector[i].foundKey[1] = 1;\r
+ e_sector[i].Key[1] = key64;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ //print them\r
+ printKeyTable( SectorsCnt, e_sector );\r
+ \r
+ if (transferToEml) {\r
+ uint8_t block[16] = {0x00};\r
+ for (uint8_t i = 0; i < SectorsCnt; ++i ) {\r
+ mfEmlGetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1);\r
+ if (e_sector[i].foundKey[0])\r
+ num_to_bytes(e_sector[i].Key[0], 6, block);\r
+ if (e_sector[i].foundKey[1])\r
+ num_to_bytes(e_sector[i].Key[1], 6, block+10);\r
+ mfEmlSetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1);\r
+ }\r
+ PrintAndLog("Found keys have been transferred to the emulator memory");\r
+ }\r
+ \r
+ if (createDumpFile) {\r
+ FILE *fkeys = fopen("dumpkeys.bin","wb");\r
+ if (fkeys == NULL) { \r
+ PrintAndLog("Could not create file dumpkeys.bin");\r
+ free(keyBlock);\r
+ free(e_sector);\r
+ return 1;\r
+ }\r
+ PrintAndLog("Printing keys to binary file dumpkeys.bin...");\r
+ \r
+ for( i=0; i<SectorsCnt; i++) {\r
+ num_to_bytes(e_sector[i].Key[0], 6, tempkey);\r
+ fwrite ( tempkey, 1, 6, fkeys );\r
+ }\r
+ for(i=0; i<SectorsCnt; i++) {\r
+ num_to_bytes(e_sector[i].Key[1], 6, tempkey);\r
+ fwrite ( tempkey, 1, 6, fkeys );\r
+ }\r
+ fclose(fkeys);\r
+ PrintAndLog("Found keys have been dumped to file dumpkeys.bin. 0xffffffffffff has been inserted for unknown keys."); \r
+ }\r
+ \r
+ free(keyBlock);\r
+ free(e_sector);\r
+ PrintAndLog("");\r
+ return 0;\r
+}\r
+#define ATTACK_KEY_COUNT 8\r
+sector *k_sector = NULL;\r
+uint8_t k_sectorsCount = 16;\r
+void readerAttack(nonces_t data[], bool setEmulatorMem) {\r
+\r
+ // initialize storage for found keys\r
+ if (k_sector == NULL)\r
+ k_sector = calloc(k_sectorsCount, sizeof(sector));\r
+ if (k_sector == NULL) \r
+ return;\r
+\r
+ uint64_t key = 0;\r
+ \r
+ // empty e_sector\r
+ for(int i = 0; i < k_sectorsCount; ++i){\r
+ k_sector[i].Key[0] = 0xffffffffffff;\r
+ k_sector[i].Key[1] = 0xffffffffffff;\r
+ k_sector[i].foundKey[0] = FALSE;\r
+ k_sector[i].foundKey[1] = FALSE;\r
+ }\r
+\r
+ printf("enter reader attack\n");\r
+ for (uint8_t i = 0; i < ATTACK_KEY_COUNT; ++i) {\r
+ if (data[i].ar2 > 0) {\r
+ \r
+ if (tryMfk32(data[i], &key)) {\r
+ PrintAndLog("Found Key%s for sector %02d: [%012"llx"]"\r
+ , (data[i].keytype) ? "B" : "A"\r
+ , data[i].sector\r
+ , key\r
+ );\r
+\r
+ k_sector[i].Key[data[i].keytype] = key;\r
+ k_sector[i].foundKey[data[i].keytype] = TRUE;\r
+ \r
+ //set emulator memory for keys\r
+ if (setEmulatorMem) {\r
+ uint8_t memBlock[16] = {0,0,0,0,0,0, 0xff, 0x0F, 0x80, 0x69, 0,0,0,0,0,0};\r
+ num_to_bytes( k_sector[i].Key[0], 6, memBlock);\r
+ num_to_bytes( k_sector[i].Key[1], 6, memBlock+10);\r
+ mfEmlSetMem( memBlock, i*4 + 3, 1);\r
+ PrintAndLog("Setting Emulator Memory Block %02d: [%s]"\r
+ , i*4 + 3\r
+ , sprint_hex( memBlock, sizeof(memBlock))\r
+ );\r
+ }\r
+ break;\r