]> cvs.zerfleddert.de Git - proxmark3-svn/blobdiff - client/cmdhfmf.c
Fix issue #342
[proxmark3-svn] / client / cmdhfmf.c
index 7a6aaa3b9a3cd367a517d2c1f7a2ea56d49ed392..d909cd8c8f9e1fa690ad93871955c0381d53e5a4 100644 (file)
@@ -8,6 +8,8 @@
 // High frequency MIFARE commands\r
 //-----------------------------------------------------------------------------\r
 \r
+#include "cmdhfmf.h"\r
+\r
 #include <inttypes.h>\r
 #include <string.h>\r
 #include <stdio.h>\r
 #include <ctype.h>\r
 #include "proxmark3.h"\r
 #include "cmdmain.h"\r
+#include "cmdhfmfhard.h"\r
 #include "util.h"\r
+#include "util_posix.h"\r
+#include "usb_cmd.h"\r
 #include "ui.h"\r
 #include "mifarehost.h"\r
 #include "mifare.h"\r
 \r
 static int CmdHelp(const char *Cmd);\r
 \r
-\r
 int CmdHF14AMifare(const char *Cmd)\r
 {\r
        int isOK = 0;\r
        uint64_t key = 0;\r
-\r
        isOK = mfDarkside(&key);\r
        switch (isOK) {\r
                case -1 : PrintAndLog("Button pressed. Aborted."); return 1;\r
                case -2 : PrintAndLog("Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests)."); return 1;\r
                case -3 : PrintAndLog("Card is not vulnerable to Darkside attack (its random number generator is not predictable)."); return 1;\r
                case -4 : PrintAndLog("Card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown");\r
-                                       PrintAndLog("generating polynomial with 16 effective bits only, but shows unexpected behaviour."); return 1;\r
+                                 PrintAndLog("generating polynomial with 16 effective bits only, but shows unexpected behaviour."); return 1;\r
                case -5 : PrintAndLog("Aborted via keyboard.");  return 1;\r
                default : PrintAndLog("Found valid key:%012" PRIx64 "\n", key);\r
        }\r
@@ -764,6 +767,127 @@ int CmdHF14AMfNested(const char *Cmd)
        return 0;\r
 }\r
 \r
+\r
+int CmdHF14AMfNestedHard(const char *Cmd)\r
+{\r
+       uint8_t blockNo = 0;\r
+       uint8_t keyType = 0;\r
+       uint8_t trgBlockNo = 0;\r
+       uint8_t trgKeyType = 0;\r
+       uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
+       uint8_t trgkey[6] = {0, 0, 0, 0, 0, 0};\r
+       \r
+       char ctmp;\r
+       ctmp = param_getchar(Cmd, 0);\r
+\r
+       if (ctmp != 'R' && ctmp != 'r' && ctmp != 'T' && ctmp != 't' && strlen(Cmd) < 20) {\r
+               PrintAndLog("Usage:");\r
+               PrintAndLog("      hf mf hardnested <block number> <key A|B> <key (12 hex symbols)>");\r
+               PrintAndLog("                       <target block number> <target key A|B> [known target key (12 hex symbols)] [w] [s]");\r
+               PrintAndLog("  or  hf mf hardnested r [known target key]");\r
+               PrintAndLog(" ");\r
+               PrintAndLog("Options: ");\r
+               PrintAndLog("      w: Acquire nonces and write them to binary file nonces.bin");\r
+               PrintAndLog("      s: Slower acquisition (required by some non standard cards)");\r
+               PrintAndLog("      r: Read nonces.bin and start attack");\r
+               PrintAndLog(" ");\r
+               PrintAndLog("      sample1: hf mf hardnested 0 A FFFFFFFFFFFF 4 A");\r
+               PrintAndLog("      sample2: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w");\r
+               PrintAndLog("      sample3: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w s");\r
+               PrintAndLog("      sample4: hf mf hardnested r");\r
+               PrintAndLog(" ");\r
+               PrintAndLog("Add the known target key to check if it is present in the remaining key space:");\r
+               PrintAndLog("      sample5: hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF");\r
+               return 0;\r
+       }       \r
+       \r
+       bool know_target_key = false;\r
+       bool nonce_file_read = false;\r
+       bool nonce_file_write = false;\r
+       bool slow = false;\r
+       int tests = 0;\r
+       \r
+       \r
+       if (ctmp == 'R' || ctmp == 'r') {\r
+               nonce_file_read = true;\r
+               if (!param_gethex(Cmd, 1, trgkey, 12)) {\r
+                       know_target_key = true;\r
+               }\r
+       } else if (ctmp == 'T' || ctmp == 't') {\r
+               tests = param_get32ex(Cmd, 1, 100, 10);\r
+               if (!param_gethex(Cmd, 2, trgkey, 12)) {\r
+                       know_target_key = true;\r
+               }\r
+       } else {\r
+               blockNo = param_get8(Cmd, 0);\r
+               ctmp = param_getchar(Cmd, 1);\r
+               if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {\r
+                       PrintAndLog("Key type must be A or B");\r
+                       return 1;\r
+               }\r
+               if (ctmp != 'A' && ctmp != 'a') { \r
+                       keyType = 1;\r
+               }\r
+               \r
+               if (param_gethex(Cmd, 2, key, 12)) {\r
+                       PrintAndLog("Key must include 12 HEX symbols");\r
+                       return 1;\r
+               }\r
+               \r
+               trgBlockNo = param_get8(Cmd, 3);\r
+               ctmp = param_getchar(Cmd, 4);\r
+               if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {\r
+                       PrintAndLog("Target key type must be A or B");\r
+                       return 1;\r
+               }\r
+               if (ctmp != 'A' && ctmp != 'a') {\r
+                       trgKeyType = 1;\r
+               }\r
+\r
+               uint16_t i = 5;\r
+\r
+               if (!param_gethex(Cmd, 5, trgkey, 12)) {\r
+                       know_target_key = true;\r
+                       i++;\r
+               }\r
+\r
+               while ((ctmp = param_getchar(Cmd, i))) {\r
+                       if (ctmp == 's' || ctmp == 'S') {\r
+                               slow = true;\r
+                       } else if (ctmp == 'w' || ctmp == 'W') {\r
+                               nonce_file_write = true;\r
+                       } else {\r
+                               PrintAndLog("Possible options are w and/or s");\r
+                               return 1;\r
+                       }\r
+                       i++;\r
+               }\r
+       }\r
+\r
+       PrintAndLog("--target block no:%3d, target key type:%c, known target key: 0x%02x%02x%02x%02x%02x%02x%s, file action: %s, Slow: %s, Tests: %d ", \r
+                       trgBlockNo, \r
+                       trgKeyType?'B':'A',\r
+                       trgkey[0], trgkey[1], trgkey[2], trgkey[3], trgkey[4], trgkey[5],\r
+                       know_target_key?"":" (not set)",\r
+                       nonce_file_write?"write":nonce_file_read?"read":"none",\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
+\r
+       if (isOK) {\r
+               switch (isOK) {\r
+                       case 1 : PrintAndLog("Error: No response from Proxmark.\n"); break;\r
+                       case 2 : PrintAndLog("Button pressed. Aborted.\n"); break;\r
+                       default : break;\r
+               }\r
+               return 2;\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+\r
 int CmdHF14AMfChk(const char *Cmd)\r
 {\r
        if (strlen(Cmd)<3) {\r
@@ -782,7 +906,7 @@ int CmdHF14AMfChk(const char *Cmd)
        char filename[FILE_PATH_SIZE]={0};\r
        char buf[13];\r
        uint8_t *keyBlock = NULL, *p;\r
-       uint8_t stKeyBlock = 20;\r
+       uint16_t stKeyBlock = 20;\r
        \r
        int i, res;\r
        int     keycnt = 0;\r
@@ -847,6 +971,7 @@ int CmdHF14AMfChk(const char *Cmd)
                break;\r
        default:\r
                PrintAndLog("Key type must be A , B or ?");\r
+               free(keyBlock);\r
                return 1;\r
        };\r
        \r
@@ -997,7 +1122,8 @@ int CmdHF14AMfChk(const char *Cmd)
 }\r
 \r
 void readerAttack(nonces_t ar_resp[], bool setEmulatorMem, bool doStandardAttack) {\r
-       #define ATTACK_KEY_COUNT 8 // keep same as define in iso14443a.c -> Mifare1ksim()\r
+       #define ATTACK_KEY_COUNT 7 // keep same as define in iso14443a.c -> Mifare1ksim()\r
+                                  // cannot be more than 7 or it will overrun c.d.asBytes(512)\r
        uint64_t key = 0;\r
        typedef struct {\r
                        uint64_t keyA;\r
@@ -2183,33 +2309,34 @@ int CmdDecryptTraceCmds(const char *Cmd){
 \r
 static command_t CommandTable[] =\r
 {\r
-  {"help",             CmdHelp,                                1, "This help"},\r
-  {"dbg",              CmdHF14AMfDbg,                  0, "Set default debug mode"},\r
-  {"rdbl",             CmdHF14AMfRdBl,                 0, "Read MIFARE classic block"},\r
-  {"rdsc",             CmdHF14AMfRdSc,                 0, "Read MIFARE classic sector"},\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
-  {"sniff",            CmdHF14AMfSniff,                0, "Sniff card-reader communication"},\r
-  {"sim",              CmdHF14AMf1kSim,                0, "Simulate MIFARE card"},\r
-  {"eclr",             CmdHF14AMfEClear,               0, "Clear simulator memory block"},\r
-  {"eget",             CmdHF14AMfEGet,                 0, "Get simulator memory block"},\r
-  {"eset",             CmdHF14AMfESet,                 0, "Set simulator memory block"},\r
-  {"eload",            CmdHF14AMfELoad,                0, "Load from file emul dump"},\r
-  {"esave",            CmdHF14AMfESave,                0, "Save to file emul dump"},\r
-  {"ecfill",   CmdHF14AMfECFill,               0, "Fill simulator memory with help of keys from simulator"},\r
-  {"ekeyprn",  CmdHF14AMfEKeyPrn,              0, "Print keys from simulator memory"},\r
-  {"csetuid",  CmdHF14AMfCSetUID,              0, "Set UID for magic Chinese card"},\r
-  {"csetblk",  CmdHF14AMfCSetBlk,              0, "Write block - Magic Chinese card"},\r
-  {"cgetblk",  CmdHF14AMfCGetBlk,              0, "Read block - Magic Chinese card"},\r
-  {"cgetsc",   CmdHF14AMfCGetSc,               0, "Read sector - Magic Chinese card"},\r
-  {"cload",            CmdHF14AMfCLoad,                0, "Load dump into magic Chinese card"},\r
-  {"csave",            CmdHF14AMfCSave,                0, "Save dump from magic Chinese card into file or emulator"},\r
-  {"decrypt", CmdDecryptTraceCmds,1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"},\r
-  {NULL, NULL, 0, NULL}\r
+  {"help",             CmdHelp,                 1, "This help"},\r
+  {"dbg",              CmdHF14AMfDbg,           0, "Set default debug mode"},\r
+  {"rdbl",             CmdHF14AMfRdBl,          0, "Read MIFARE classic block"},\r
+  {"rdsc",             CmdHF14AMfRdSc,          0, "Read MIFARE classic sector"},\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
+  {"hardnested",       CmdHF14AMfNestedHard,    0, "Nested attack for hardened Mifare cards"},\r
+  {"nested",           CmdHF14AMfNested,        0, "Test nested authentication"},\r
+  {"sniff",            CmdHF14AMfSniff,         0, "Sniff card-reader communication"},\r
+  {"sim",              CmdHF14AMf1kSim,         0, "Simulate MIFARE card"},\r
+  {"eclr",             CmdHF14AMfEClear,        0, "Clear simulator memory block"},\r
+  {"eget",             CmdHF14AMfEGet,          0, "Get simulator memory block"},\r
+  {"eset",             CmdHF14AMfESet,          0, "Set simulator memory block"},\r
+  {"eload",            CmdHF14AMfELoad,         0, "Load from file emul dump"},\r
+  {"esave",            CmdHF14AMfESave,         0, "Save to file emul dump"},\r
+  {"ecfill",           CmdHF14AMfECFill,        0, "Fill simulator memory with help of keys from simulator"},\r
+  {"ekeyprn",          CmdHF14AMfEKeyPrn,       0, "Print keys from simulator memory"},\r
+  {"csetuid",          CmdHF14AMfCSetUID,       0, "Set UID for magic Chinese card"},\r
+  {"csetblk",          CmdHF14AMfCSetBlk,       0, "Write block - Magic Chinese card"},\r
+  {"cgetblk",          CmdHF14AMfCGetBlk,       0, "Read block - Magic Chinese card"},\r
+  {"cgetsc",           CmdHF14AMfCGetSc,        0, "Read sector - Magic Chinese card"},\r
+  {"cload",            CmdHF14AMfCLoad,         0, "Load dump into magic Chinese card"},\r
+  {"csave",            CmdHF14AMfCSave,         0, "Save dump from magic Chinese card into file or emulator"},\r
+  {"decrypt",          CmdDecryptTraceCmds,     1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"},\r
+  {NULL,               NULL,                    0, NULL}\r
 };\r
 \r
 int CmdHFMF(const char *Cmd)\r
Impressum, Datenschutz