]> cvs.zerfleddert.de Git - proxmark3-svn/blobdiff - client/cmdhfmf.c
FIX: IV now is trunckated to 7bits in 'hf legic read,write, writeraw'
[proxmark3-svn] / client / cmdhfmf.c
index ec542eb3f00800865cdca8aaa1a60aeedb1bf910..16dd6f28bb954a6a0c430b777a84c91ab51a34b9 100644 (file)
@@ -125,6 +125,21 @@ int usage_hf14_chk(void){
        PrintAndLog("      hf mf chk *1 ? d                        -- target all blocks, all keys, 1K, write to file");\r
        return 0;\r
 }\r
        PrintAndLog("      hf mf chk *1 ? d                        -- target all blocks, all keys, 1K, write to file");\r
        return 0;\r
 }\r
+int usage_hf14_keybrute(void){\r
+       PrintAndLog("J_Run's 2nd phase of multiple sector nested authentication key recovery");\r
+       PrintAndLog("You have a known 4 last bytes of a key recovered with mf_nonce_brute tool.");\r
+       PrintAndLog("First 2 bytes of key will be bruteforced");\r
+       PrintAndLog("");\r
+       PrintAndLog("Usage:  hf mf keybrute [h] <block number> <A|B> <key>");\r
+       PrintAndLog("options:");\r
+       PrintAndLog("      h               this help");\r
+       PrintAndLog("      <block number>  target block number");\r
+       PrintAndLog("      <A|B>           target key type");\r
+       PrintAndLog("      <key>           candidate key from mf_nonce_brute tool");\r
+       PrintAndLog("samples:");\r
+       PrintAndLog("           hf mf keybrute 1 A 000011223344");\r
+       return 0;\r
+}\r
 \r
 int CmdHF14AMifare(const char *Cmd) {\r
        uint32_t uid = 0;\r
 \r
 int CmdHF14AMifare(const char *Cmd) {\r
        uint32_t uid = 0;\r
@@ -198,9 +213,16 @@ start:
        }       \r
        printf("\n");\r
        \r
        }       \r
        printf("\n");\r
        \r
-       // par == 0\r
-       if (isOK == -1 && par_list == 0) {\r
-               if (!nonce2key_ex(uid, nt, nr, ks_list, &r_key) ){\r
+       // par == 0,  and -4\r
+       if (isOK == -4 && par_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
+                       c.arg[0] = false;\r
+                       goto start;\r
+               } else {\r
                        PrintAndLog("Found valid key: %012"llx" \n", r_key);\r
                        goto END;\r
                }\r
                        PrintAndLog("Found valid key: %012"llx" \n", r_key);\r
                        goto END;\r
                }\r
@@ -217,6 +239,16 @@ start:
                c.arg[0] = false;\r
                goto start;\r
        } else {\r
                c.arg[0] = false;\r
                goto start;\r
        } else {\r
+               \r
+               // nonce2key found a candidate key.  Lets verify it.\r
+               uint8_t keyblock[] = {0,0,0,0,0,0};\r
+               num_to_bytes(r_key, 6, keyblock);\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
+                       goto start;\r
+               }\r
                PrintAndLog("Found valid key: %012"llx" \n", r_key);\r
        }\r
 END:\r
                PrintAndLog("Found valid key: %012"llx" \n", r_key);\r
        }\r
 END:\r
@@ -1639,6 +1671,43 @@ int CmdHF14AMfDbg(const char *Cmd) {
        return 0;\r
 }\r
 \r
        return 0;\r
 }\r
 \r
+int CmdHF14AMfKeyBrute(const char *Cmd) {\r
+\r
+       uint8_t blockNo = 0, keytype = 0;\r
+       uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
+       uint64_t foundkey = 0;\r
+       \r
+       char cmdp = param_getchar(Cmd, 0);      \r
+       if ( cmdp == 'H' || cmdp == 'h') return usage_hf14_keybrute();\r
+       \r
+       // block number\r
+       blockNo = param_get8(Cmd, 0);    \r
+       \r
+       // keytype\r
+       cmdp = param_getchar(Cmd, 1);\r
+       if (cmdp == 'B' || cmdp == 'b') keytype = 1;\r
+       \r
+       // key\r
+       if (param_gethex(Cmd, 2, key, 12)) return usage_hf14_keybrute();\r
+       \r
+       clock_t t1 = clock();\r
+       time_t start, end;\r
+       time(&start);\r
+       \r
+       if (mfKeyBrute( blockNo, keytype, key, &foundkey))\r
+               PrintAndLog("Found valid key: %012"llx" \n", foundkey);\r
+       else\r
+               PrintAndLog("Key not found");\r
+       \r
+       t1 = clock() - t1;\r
+       time(&end);\r
+       unsigned long elapsed_time = difftime(end, start);      \r
+       if ( t1 > 0 )\r
+               PrintAndLog("\nTime in keybrute: %.0f ticks %u seconds\n", (float)t1, elapsed_time);\r
+       \r
+       return 0;       \r
+}\r
+\r
 void printKeyTable( uint8_t sectorscnt, sector *e_sector ){\r
        PrintAndLog("|---|----------------|---|----------------|---|");\r
        PrintAndLog("|sec|key A           |res|key B           |res|");\r
 void printKeyTable( uint8_t sectorscnt, sector *e_sector ){\r
        PrintAndLog("|---|----------------|---|----------------|---|");\r
        PrintAndLog("|sec|key A           |res|key B           |res|");\r
@@ -2379,10 +2448,11 @@ static command_t CommandTable[] = {
        {"dump",                CmdHF14AMfDump,                 0, "Dump MIFARE classic tag to binary file"},\r
        {"restore",             CmdHF14AMfRestore,              0, "Restore MIFARE classic binary file to BLANK tag"},\r
        {"wrbl",                CmdHF14AMfWrBl,                 0, "Write MIFARE classic block"},\r
        {"dump",                CmdHF14AMfDump,                 0, "Dump MIFARE classic tag to binary file"},\r
        {"restore",             CmdHF14AMfRestore,              0, "Restore MIFARE classic binary file to BLANK tag"},\r
        {"wrbl",                CmdHF14AMfWrBl,                 0, "Write MIFARE classic block"},\r
-       {"chk",                 CmdHF14AMfChk,                  0, "Test block keys"},\r
-       {"mifare",              CmdHF14AMifare,                 0, "Read parity error messages."},\r
-       {"nested",              CmdHF14AMfNested,               0, "Test nested authentication"},\r
+       {"chk",                 CmdHF14AMfChk,                  0, "Check keys"},\r
+       {"mifare",              CmdHF14AMifare,                 0, "Darkside attack. read parity error messages."},\r
+       {"nested",              CmdHF14AMfNested,               0, "Nested attack. Test nested authentication"},\r
        {"hardnested",  CmdHF14AMfNestedHard,   0, "Nested attack for hardened Mifare cards"},\r
        {"hardnested",  CmdHF14AMfNestedHard,   0, "Nested attack for hardened Mifare cards"},\r
+       {"keybrute",    CmdHF14AMfKeyBrute,             0, "J_Run's 2nd phase of multiple sector nested authentication key recovery"},\r
        {"sniff",               CmdHF14AMfSniff,                0, "Sniff card-reader communication"},\r
        {"sim",                 CmdHF14AMf1kSim,                0, "Simulate MIFARE card"},\r
        {"eclr",                CmdHF14AMfEClear,               0, "Clear simulator memory block"},\r
        {"sniff",               CmdHF14AMfSniff,                0, "Sniff card-reader communication"},\r
        {"sim",                 CmdHF14AMf1kSim,                0, "Simulate MIFARE card"},\r
        {"eclr",                CmdHF14AMfEClear,               0, "Clear simulator memory block"},\r
Impressum, Datenschutz