PrintAndLog(" i (Optional) Interactive, means that console will not be returned until simulation finishes or is aborted");\r
PrintAndLog(" x (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)");\r
PrintAndLog(" e (Optional) Fill simulator keys from what we crack");\r
+ PrintAndLog(" v (Optional) Show maths used for cracking reader. Useful for debugging.");\r
PrintAndLog("samples:");\r
PrintAndLog(" hf mf sim u 0a0a0a0a");\r
PrintAndLog(" hf mf sim u 11223344556677");\r
}\r
} \r
printf("\n");\r
+ // error\r
+ if (isOK != 1) return 1;\r
\r
- // par == 0, and -4\r
- if (isOK == -4 && par_list == 0) {\r
+ if (par_list == 0 && ks_list != 0) {\r
// this special attack when parities is zero, uses checkkeys. Which now with block/keytype option also needs. \r
// but it uses 0|1 instead of 0x60|0x61...\r
if (nonce2key_ex(blockNo, keytype - 0x60 , uid, nt, nr, ks_list, &r_key) ){\r
- PrintAndLog("Key not found (lfsr_common_prefix list is null)."); \r
- PrintAndLog("Failing is expected to happen in 25%% of all cases. Trying again with a different reader nonce...");\r
+ PrintAndLog("Trying again with a different reader nonce...");\r
c.arg[0] = false;\r
goto start;\r
} else {\r
goto END;\r
}\r
}\r
- \r
- // error\r
- if (isOK != 1) return 1;\r
- \r
+\r
// execute original function from util nonce2key\r
if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key)) {\r
isOK = 2;\r
uint64_t key64 = 0;\r
int res = mfCheckKeys(blockNo, keytype - 0x60 , false, 1, keyblock, &key64);\r
if ( res > 0 ) {\r
- PrintAndLog("Candidate Key found (%012"llx") - Test authentication failed. Starting over darkside attack", r_key); \r
+ PrintAndLog("Candidate Key found (%012"llx") - Test authentication failed. [%d] Restarting darkside attack", r_key, res); \r
goto start;\r
}\r
PrintAndLog("Found valid key: %012"llx" \n", r_key);\r
slow ? "Yes" : "No",\r
tests);\r
\r
- int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests);\r
+ uint64_t foundkey = 0;\r
+ int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey);\r
\r
if (isOK) {\r
switch (isOK) {\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
+void readerAttack(nonces_t data[], bool setEmulatorMem, bool verbose) {\r
\r
// initialize storage for found keys\r
if (k_sector == NULL)\r
\r
// We can probably skip this, mfkey32v2 is more reliable.\r
#ifdef HFMF_TRYMFK32\r
- if (tryMfk32(data[i], &key)) {\r
+ if (tryMfk32(data[i], &key, verbose)) {\r
PrintAndLog("Found Key%s for sector %02d: [%012"llx"]"\r
, (data[i].keytype) ? "B" : "A"\r
, data[i].sector\r
}\r
#endif\r
//moebius attack \r
- if (tryMfk32_moebius(data[i+ATTACK_KEY_COUNT], &key)) {\r
+ if (tryMfk32_moebius(data[i+ATTACK_KEY_COUNT], &key, verbose)) {\r
uint8_t sectorNum = data[i+ATTACK_KEY_COUNT].sector;\r
uint8_t keyType = data[i+ATTACK_KEY_COUNT].keytype;\r
\r
uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\r
uint8_t exitAfterNReads = 0;\r
uint8_t flags = (FLAG_UID_IN_EMUL | FLAG_4B_UID_IN_DATA);\r
- int uidlen = 0; \r
+ int uidlen = 0;\r
bool setEmulatorMem = false;\r
uint8_t cmdp = 0;\r
bool errors = false;\r
\r
+ // If set to true, we should show our workings when doing NR_AR_ATTACK.\r
+ bool verbose = false;\r
+\r
while(param_getchar(Cmd, cmdp) != 0x00) {\r
switch(param_getchar(Cmd, cmdp)) {\r
case 'e':\r
}\r
cmdp +=2;\r
break;\r
+ case 'v':\r
+ case 'V':\r
+ verbose = true;\r
+ cmdp++;\r
+ break;\r
case 'x':\r
case 'X':\r
flags |= FLAG_NR_AR_ATTACK;\r
if ( (resp.arg[0] & 0xffff) != CMD_SIMULATE_MIFARE_CARD ) break;\r
\r
memcpy( data, resp.d.asBytes, sizeof(data) ); \r
- readerAttack(data, setEmulatorMem);\r
+ readerAttack(data, setEmulatorMem, verbose);\r
}\r
\r
if (k_sector != NULL) {\r