]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge branch 'master' of https://github.com/Proxmark/proxmark3
authoriceman1001 <iceman@iuse.se>
Sun, 14 Sep 2014 15:36:00 +0000 (17:36 +0200)
committericeman1001 <iceman@iuse.se>
Sun, 14 Sep 2014 15:36:00 +0000 (17:36 +0200)
1  2 
client/cmdhfmf.c

diff --combined client/cmdhfmf.c
index 0d4813dd43c88cdef82bb443bd9ebaca864f06de,b66aa3a6d59d220d685c8b57ce657b3f415feee8..e892b3774ee12a06ae11c1478b25d4e38fd964cb
@@@ -7,7 -7,7 +7,7 @@@
  //-----------------------------------------------------------------------------\r
  // High frequency MIFARE commands\r
  //-----------------------------------------------------------------------------\r
 -\r
 +#include "../include/mifare.h"\r
  #include "cmdhfmf.h"\r
  \r
  static int CmdHelp(const char *Cmd);\r
@@@ -140,7 -140,6 +140,7 @@@ int CmdHF14AMfWrBl(const char *Cmd
        return 0;\r
  }\r
  \r
 +/*  dublett finns i CMDHFMFU.C \r
  int CmdHF14AMfUWrBl(const char *Cmd)\r
  {\r
        uint8_t blockNo = 0;\r
        }\r
        return 0;\r
  }\r
 -\r
 -\r
 +*/\r
  int CmdHF14AMfRdBl(const char *Cmd)\r
  {\r
        uint8_t blockNo = 0;\r
    return 0;\r
  }\r
  \r
 +/* dublett finns i CMDHFMFU.C \r
  int CmdHF14AMfURdBl(const char *Cmd)\r
  {\r
        uint8_t blockNo = 0;\r
  \r
        return 0;\r
  }\r
 +*/\r
  \r
 -\r
 +/* dublett finns i CMDHFMFU.C \r
  int CmdHF14AMfURdCard(const char *Cmd)\r
  {\r
      int i;\r
          }\r
    return 0;\r
  }\r
 -\r
 +*/\r
  \r
  int CmdHF14AMfRdSc(const char *Cmd)\r
  {\r
@@@ -519,16 -517,7 +519,16 @@@ int CmdHF14AMfDump(const char *Cmd
        \r
        UsbCommand resp;\r
  \r
 +      int size = GetCardSize();               \r
        char cmdp = param_getchar(Cmd, 0);\r
 +      \r
 +      PrintAndLog("Got %d",size);\r
 +      \r
 +      return;\r
 +      \r
 +      if  ( size > -1) \r
 +              cmdp = (char)48+size;\r
 +      \r
        switch (cmdp) {\r
                case '0' : numSectors = 5; break;\r
                case '1' : \r
                return 1;\r
        }\r
        \r
 -      // Read key file\r
 -\r
 +      // Read keys A from file\r
        for (sectorNo=0; sectorNo<numSectors; sectorNo++) {\r
                if (fread( keyA[sectorNo], 1, 6, fin ) == 0) {\r
                        PrintAndLog("File reading error.");\r
                }\r
        }\r
        \r
 +      // Read keys B from file\r
        for (sectorNo=0; sectorNo<numSectors; sectorNo++) {\r
                if (fread( keyB[sectorNo], 1, 6, fin ) == 0) {\r
                        PrintAndLog("File reading error.");\r
                }\r
        }\r
        \r
 -      // Read access rights to sectors\r
 -\r
        PrintAndLog("|-----------------------------------------|");\r
        PrintAndLog("|------ Reading sector access bits...-----|");\r
        PrintAndLog("|-----------------------------------------|");\r
                        uint8_t isOK  = resp.arg[0] & 0xff;\r
                        uint8_t *data  = resp.d.asBytes;\r
                        if (isOK){\r
-                               rights[sectorNo][0] = ((data[7] & 0x10)>>4) | ((data[8] & 0x1)<<1) | ((data[8] & 0x10)>>2);\r
-                               rights[sectorNo][1] = ((data[7] & 0x20)>>5) | ((data[8] & 0x2)<<0) | ((data[8] & 0x20)>>3);\r
-                               rights[sectorNo][2] = ((data[7] & 0x40)>>6) | ((data[8] & 0x4)>>1) | ((data[8] & 0x40)>>4);\r
-                               rights[sectorNo][3] = ((data[7] & 0x80)>>7) | ((data[8] & 0x8)>>2) | ((data[8] & 0x80)>>5);\r
+                               rights[sectorNo][0] = ((data[7] & 0x10)>>2) | ((data[8] & 0x1)<<1) | ((data[8] & 0x10)>>4); // C1C2C3 for data area 0\r
+                               rights[sectorNo][1] = ((data[7] & 0x20)>>3) | ((data[8] & 0x2)<<0) | ((data[8] & 0x20)>>5); // C1C2C3 for data area 1\r
+                               rights[sectorNo][2] = ((data[7] & 0x40)>>4) | ((data[8] & 0x4)>>1) | ((data[8] & 0x40)>>6); // C1C2C3 for data area 2\r
+                               rights[sectorNo][3] = ((data[7] & 0x80)>>5) | ((data[8] & 0x8)>>2) | ((data[8] & 0x80)>>7); // C1C2C3 for sector trailer\r
                        } else {\r
                                PrintAndLog("Could not get access rights for sector %2d. Trying with defaults...", sectorNo);\r
-                               rights[sectorNo][0] = rights[sectorNo][1] = rights[sectorNo][2] = rights[sectorNo][3] = 0x01;\r
+                               rights[sectorNo][0] = rights[sectorNo][1] = rights[sectorNo][2] = 0x00;\r
+                               rights[sectorNo][3] = 0x01;\r
                        }\r
                } else {\r
                        PrintAndLog("Command execute timeout when trying to read access rights for sector %2d. Trying with defaults...", sectorNo);\r
-                       rights[sectorNo][0] = rights[sectorNo][1] = rights[sectorNo][2] = rights[sectorNo][3] = 0x01;\r
+                       rights[sectorNo][0] = rights[sectorNo][1] = rights[sectorNo][2] = 0x00;\r
+                       rights[sectorNo][3] = 0x01;\r
                }\r
        }\r
        \r
 -      // Read blocks and print to file\r
 -      \r
        PrintAndLog("|-----------------------------------------|");\r
        PrintAndLog("|----- Dumping all blocks to file... -----|");\r
        PrintAndLog("|-----------------------------------------|");\r
        for (sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) {\r
                for (blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {\r
                        bool received = false;\r
 +                      \r
                        if (blockNo == NumBlocksPerSector(sectorNo) - 1) {              // sector trailer. At least the Access Conditions can always be read with key A. \r
                                UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}};\r
                                memcpy(c.d.asBytes, keyA[sectorNo], 6);\r
                                received = WaitForResponseTimeout(CMD_ACK,&resp,1500);\r
                        } else {                                                                                                // data block. Check if it can be read with key A or key B\r
                                uint8_t data_area = sectorNo<32?blockNo:blockNo/5;\r
-                               if ((rights[sectorNo][data_area] == 3) || (rights[sectorNo][data_area] == 5)) {                 // only key B would work\r
+                               if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) {   // only key B would work\r
                                        UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 1, 0}};\r
                                        memcpy(c.d.asBytes, keyB[sectorNo], 6);\r
                                        SendCommand(&c);\r
                                        received = WaitForResponseTimeout(CMD_ACK,&resp,1500);\r
-                               } else if (rights[sectorNo][data_area] == 7) {                                                                                  // no key would work\r
+                               } else if (rights[sectorNo][data_area] == 0x07) {                                                                               // no key would work\r
                                        isOK = false;\r
 -                                      PrintAndLog("Access rights do not allow reading of sector %2d block %3d", sectorNo, blockNo);\r
 +                                              PrintAndLog("Access rights do not allow reading of sector %2d block %3d", sectorNo, blockNo);\r
                                } else {                                                                                                                                                                // key A would work\r
 -                                      UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}};\r
 -                                      memcpy(c.d.asBytes, keyA[sectorNo], 6);\r
 -                                      SendCommand(&c);\r
 -                                      received = WaitForResponseTimeout(CMD_ACK,&resp,1500);\r
 +                                              UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}};\r
 +                                              memcpy(c.d.asBytes, keyA[sectorNo], 6);\r
 +                                              SendCommand(&c);\r
 +                                              received = WaitForResponseTimeout(CMD_ACK,&resp,1500);\r
                                }\r
                        }\r
  \r
                                break;\r
                        }\r
                }\r
 -\r
        }\r
  \r
        if (isOK) {\r
                fclose(fout);\r
                PrintAndLog("Dumped %d blocks (%d bytes) to file dumpdata.bin", numblocks, 16*numblocks);\r
        }\r
 -              \r
 +      \r
        fclose(fin);\r
        return 0;\r
  }\r
@@@ -790,7 -785,7 +792,7 @@@ int CmdHF14AMfNested(const char *Cmd
        uint8_t trgKeyType = 0;\r
        uint8_t SectorsCnt = 0;\r
        uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
 -      uint8_t keyBlock[6*6];\r
 +      uint8_t keyBlock[13*6];\r
        uint64_t key64 = 0;\r
        bool transferToEml = false;\r
        \r
        cmdp = param_getchar(Cmd, 0);\r
        blockNo = param_get8(Cmd, 1);\r
        ctmp = param_getchar(Cmd, 2);\r
 +      \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') keyType = 1;\r
 +      \r
 +      if (ctmp != 'A' && ctmp != 'a') \r
 +              keyType = 1;\r
 +              \r
        if (param_gethex(Cmd, 3, key, 12)) {\r
                PrintAndLog("Key must include 12 HEX symbols");\r
                return 1;\r
                        PrintAndLog("Target key type must be A or B");\r
                        return 1;\r
                }\r
 -              if (ctmp != 'A' && ctmp != 'a') trgKeyType = 1;\r
 +              if (ctmp != 'A' && ctmp != 'a') \r
 +                      trgKeyType = 1;\r
        } else {\r
 +              \r
 +              \r
 +      \r
                switch (cmdp) {\r
                        case '0': SectorsCnt = 05; break;\r
                        case '1': SectorsCnt = 16; break;\r
                num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock + 3 * 6));\r
                num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock + 4 * 6));\r
                num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock + 5 * 6));\r
 +              num_to_bytes(0x4d3a99c351dd, 6, (uint8_t*)(keyBlock + 6 * 6));\r
 +              num_to_bytes(0x1a982c7e459a, 6, (uint8_t*)(keyBlock + 7 * 6));\r
 +              num_to_bytes(0xd3f7d3f7d3f7, 6, (uint8_t*)(keyBlock + 8 * 6));\r
 +              num_to_bytes(0x714c5c886e97, 6, (uint8_t*)(keyBlock + 9 * 6));\r
 +              num_to_bytes(0x587ee5f9350f, 6, (uint8_t*)(keyBlock + 10 * 6));\r
 +              num_to_bytes(0xa0478cc39091, 6, (uint8_t*)(keyBlock + 11 * 6));\r
 +              num_to_bytes(0x533cb6c723f6, 6, (uint8_t*)(keyBlock + 12 * 6));\r
 +              num_to_bytes(0x8fd0a4f256e9, 6, (uint8_t*)(keyBlock + 13 * 6));\r
  \r
                PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt);\r
                for (i = 0; i < SectorsCnt; i++) {\r
@@@ -1178,8 -1157,8 +1180,8 @@@ int CmdHF14AMfChk(const char *Cmd
                PrintAndLog("No key specified, trying default keys");\r
                for (;keycnt < defaultKeysSize; keycnt++)\r
                        PrintAndLog("chk default 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
 +                      (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
                                for (uint16_t t = 0; t < 2; t++) {\r
                                        if (validKey[t][sectorNo]) {\r
                                                memcpy(block + t*10, foundKey[t][sectorNo], 6);\r
 -                                      }\r
 -                              }\r
 +              }\r
 +                      }\r
                                mfEmlSetMem(block, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);\r
                        }\r
                }\r
                PrintAndLog("Found keys have been transferred to the emulator memory");\r
 -      }\r
 +                      }\r
  \r
        if (createDumpFile) {\r
                FILE *fkeys = fopen("dumpkeys.bin","wb");\r
                        PrintAndLog("Could not create file dumpkeys.bin");\r
                        free(keyBlock);\r
                        return 1;\r
 -              }\r
 +                      }\r
                for (uint16_t t = 0; t < 2; t++) {\r
                        fwrite(foundKey[t], 1, 6*SectorsCnt, fkeys);\r
                }\r
  \r
        free(keyBlock);\r
  \r
 -      return 0;\r
 +  return 0;\r
  }\r
  \r
  \r
@@@ -1342,6 -1321,7 +1344,6 @@@ int CmdHF14AMfDbg(const char *Cmd
    return 0;\r
  }\r
  \r
 -\r
  int CmdHF14AMfEGet(const char *Cmd)\r
  {\r
        uint8_t blockNo = 0;\r
@@@ -1638,6 -1618,7 +1640,6 @@@ int CmdHF14AMfCSetUID(const char *Cmd
        return 0;\r
  }\r
  \r
 -\r
  int CmdHF14AMfCSetBlk(const char *Cmd)\r
  {\r
        uint8_t uid[8];\r
@@@ -1763,7 -1744,7 +1765,7 @@@ int CmdHF14AMfCLoad(const char *Cmd
                }\r
                fclose(f);\r
        \r
 -              if (blockNum != 16 * 4){\r
 +              if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){\r
                        PrintAndLog("File content error. There must be 64 blocks");\r
                        return 4;\r
                }\r
        }\r
  }\r
  \r
 -\r
  int CmdHF14AMfCGetBlk(const char *Cmd) {\r
        uint8_t memBlock[16];\r
        uint8_t blockNo = 0;\r
@@@ -2033,121 -2015,30 +2035,121 @@@ int CmdHF14AMfSniff(const char *Cmd)
                                                        FillFileNameByUID(logHexFileName, uid + (7 - uid_len), ".log", uid_len);\r
                                                        AddLogCurrentDT(logHexFileName);\r
                                                }                                               \r
 -                                              if (wantDecrypt) mfTraceInit(uid, atqa, sak, wantSaveToEmlFile);\r
 +                                              if (wantDecrypt) \r
 +                                                      mfTraceInit(uid, atqa, sak, wantSaveToEmlFile);\r
                                        } else {\r
                                                PrintAndLog("%s(%d):%s", isTag ? "TAG":"RDR", num, sprint_hex(bufPtr, len));\r
 -                                              if (wantLogToFile) AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len);\r
 -                                              if (wantDecrypt) mfTraceDecode(bufPtr, len, parity, wantSaveToEmlFile);\r
 +                                              if (wantLogToFile) \r
 +                                                      AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len);\r
 +                                              if (wantDecrypt) \r
 +                                                      mfTraceDecode(bufPtr, len, parity, wantSaveToEmlFile);\r
                                        }\r
                                        bufPtr += len;\r
                                        num++;\r
                                }\r
                        }\r
 -              } // resp not NILL\r
 +              } // resp not NULL\r
        } // while (true)\r
        \r
        return 0;\r
  }\r
  \r
 +// Tries to identify cardsize.\r
 +// Returns <num>  where num is:\r
 +// -1  unidentified\r
 +//  0 - MINI (320bytes)\r
 +//  1 - 1K\r
 +//  2 - 2K\r
 +//  4 - 4K\r
 +int GetCardSize()\r
 +{\r
 +      UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};\r
 +      SendCommand(&c);\r
 +\r
 +      UsbCommand resp;\r
 +      WaitForResponse(CMD_ACK,&resp);\r
 +\r
 +      if(resp.arg[0] == 0) {\r
 +              PrintAndLog("iso14443a card select failed");\r
 +              return -1;\r
 +      }\r
 +      \r
 +      iso14a_card_select_t *card = (iso14a_card_select_t *)resp.d.asBytes;\r
 +\r
 +      PrintAndLog("Trying to detect card size.");\r
 +      \r
 +      uint16_t atqa = 0;\r
 +      uint8_t sak = 0;\r
 +      atqa = (card->atqa[1] & 0xff) << 8;\r
 +    atqa += card->atqa[0] & 0xff;\r
 +      sak = card->sak;\r
 +      \r
 +      // https://code.google.com/p/libnfc/source/browse/libnfc/target-subr.c\r
 +      \r
 +      PrintAndLog("found ATAQ: %04X SAK: %02X", atqa, sak);\r
 +      \r
 +      \r
 +      // NXP MIFARE Mini 0.3k\r
 +      if ( (atqa && 0xff0f == 0x0004) && (sak == 0x09) ) return 0;\r
 +      \r
 +      // MIFARE Classic 1K\r
 +      if ( (atqa && 0xff0f == 0x0004) && (sak == 0x08) ) return 1;\r
 +      \r
 +      // MIFARE Classik 4K\r
 +      if ( (atqa && 0xff0f == 0x0002) && (sak == 0x18) ) return 4;\r
 +      \r
 +      // SmartMX with MIFARE 1K emulation \r
 +      if ( (atqa && 0xf0ff == 0x0004) ) return 1;\r
 +\r
 +      // SmartMX with MIFARE 4K emulation \r
 +      if ( (atqa && 0xf0ff == 0x0002) ) return 4;     \r
 +      \r
 +      // Infineon MIFARE CLASSIC 1K\r
 +      if ( (atqa && 0xffff == 0x0004) && (sak == 0x88) ) return 1;\r
 +      \r
 +      // MFC 4K emulated by Nokia 6212 Classic\r
 +      if ( (atqa && 0xffff == 0x0002) && (sak == 0x38) ) return 4;\r
 +\r
 +      // MFC 4K emulated by Nokia 6131 NFC\r
 +      if ( (atqa && 0xffff == 0x0008) && (sak == 0x38) ) return 4;\r
 +\r
 +      // MIFARE Plus (4 Byte UID or 4 Byte RID)\r
 +      // MIFARE Plus (7 Byte UID)\r
 +      if (\r
 +                      (atqa && 0xffff == 0x0002) ||\r
 +                      (atqa && 0xffff == 0x0004) ||\r
 +                      (atqa && 0xffff == 0x0042) ||   \r
 +                      (atqa && 0xffff == 0x0044) \r
 +              )\r
 +      {\r
 +              switch(sak){\r
 +                      case 0x08:\r
 +                      case 0x10:\r
 +                      //case 0x20:\r
 +                              return 2;\r
 +                              break;\r
 +                      case 0x11:\r
 +                      case 0x18:\r
 +                      //case 0x20:\r
 +                              return 4;\r
 +                              break;\r
 +              }\r
 +      }\r
 +      \r
 +      return -1;\r
 +}\r
 +\r
 +\r
 +\r
 +\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
 -  {"urdbl",     CmdHF14AMfURdBl,        0, "Read MIFARE Ultralight block"},\r
 -  {"urdcard",   CmdHF14AMfURdCard,      0,"Read MIFARE Ultralight Card"},\r
 -  {"uwrbl",           CmdHF14AMfUWrBl,                0,"Write MIFARE Ultralight block"},\r
 +  //{"urdbl",              CmdHF14AMfURdBl,                 0, "Read MIFARE Ultralight block"},\r
 +  //{"urdcard",           CmdHF14AMfURdCard,               0,"Read MIFARE Ultralight Card"},\r
 +  //{"uwrbl",         CmdHF14AMfUWrBl,                0,"Write MIFARE Ultralight 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
Impressum, Datenschutz