]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
added mifare trailer block decoding (#726)
authorOleg Moiseenko <807634+merlokk@users.noreply.github.com>
Mon, 3 Dec 2018 07:29:13 +0000 (09:29 +0200)
committerpwpiwi <pwpiwi@users.noreply.github.com>
Mon, 3 Dec 2018 07:29:13 +0000 (08:29 +0100)
client/cmdhfmf.c
client/mifare4.c
client/mifare4.h

index c382664ba44aee0b08b0c58e3087d841e6b969ad..fa952cb9be55bba7e03323476e5b17e931253325 100644 (file)
@@ -141,12 +141,26 @@ int CmdHF14AMfRdBl(const char *Cmd)
                uint8_t isOK  = resp.arg[0] & 0xff;\r
                uint8_t *data = resp.d.asBytes;\r
 \r
-               if (isOK)\r
+               if (isOK) {\r
                        PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 16));\r
-               else\r
+               } else {\r
                        PrintAndLog("isOk:%02x", isOK);\r
+                       return 1;\r
+               }\r
+\r
+               if (mfIsSectorTrailer(blockNo) && (data[6] || data[7] || data[8])) {\r
+                       PrintAndLogEx(NORMAL, "Trailer decoded:");\r
+                       int bln = mfFirstBlockOfSector(mfSectorNum(blockNo));\r
+                       int blinc = (mfNumBlocksPerSector(mfSectorNum(blockNo)) > 4) ? 5 : 1;\r
+                       for (int i = 0; i < 4; i++) {\r
+                               PrintAndLogEx(NORMAL, "Access block %d%s: %s", bln, ((blinc > 1) && (i < 3) ? "+" : "") , mfGetAccessConditionsDesc(i, &data[6]));\r
+                               bln += blinc;\r
+                       }\r
+                       PrintAndLogEx(NORMAL, "UserData: %s", sprint_hex_inrow(&data[9], 1));\r
+               }\r
        } else {\r
                PrintAndLog("Command execute timeout");\r
+               return 2;\r
        }\r
 \r
   return 0;\r
@@ -2272,6 +2286,20 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
                }\r
 \r
        PrintAndLog("block data:%s", sprint_hex(memBlock, 16));\r
+       \r
+       if (mfIsSectorTrailer(blockNo)) {\r
+               PrintAndLogEx(NORMAL, "Trailer decoded:");\r
+               PrintAndLogEx(NORMAL, "Key A: %s", sprint_hex_inrow(memBlock, 6));\r
+               PrintAndLogEx(NORMAL, "Key B: %s", sprint_hex_inrow(&memBlock[10], 6));\r
+               int bln = mfFirstBlockOfSector(mfSectorNum(blockNo));\r
+               int blinc = (mfNumBlocksPerSector(mfSectorNum(blockNo)) > 4) ? 5 : 1;\r
+               for (int i = 0; i < 4; i++) {\r
+                       PrintAndLogEx(NORMAL, "Access block %d%s: %s", bln, ((blinc > 1) && (i < 3) ? "+" : "") , mfGetAccessConditionsDesc(i, &memBlock[6]));\r
+                       bln += blinc;\r
+               }\r
+               PrintAndLogEx(NORMAL, "UserData: %s", sprint_hex_inrow(&memBlock[9], 1));\r
+       }\r
+       \r
        return 0;\r
 }\r
 \r
index 069c54d4937a23d682cc427936900b7badd32f74..419e9b238e0edba74f27f4266067b99bad6cc69e 100644 (file)
 #include "ui.h"
 #include "crypto/libpcrypto.h"
 
+AccessConditions_t MFAccessConditions[] = {
+       {0x00, "read AB; write AB; increment AB; decrement transfer restore AB"},
+       {0x01, "read AB; decrement transfer restore AB"},
+       {0x02, "read AB"},
+       {0x03, "read B; write B"},
+       {0x04, "read AB; writeB"},
+       {0x05, "read B"},
+       {0x06, "read AB; write B; increment B; decrement transfer restore AB"},
+       {0x07, "none"}
+};
+
+AccessConditions_t MFAccessConditionsTrailer[] = {
+       {0x00, "read A by A; read ACCESS by A; read B by A; write B by A"},
+       {0x01, "write A by A; read ACCESS by A write ACCESS by A; read B by A; write B by A"},
+       {0x02, "read ACCESS by A; read B by A"},
+       {0x03, "write A by B; read ACCESS by AB; write ACCESS by B; write B by B"},
+       {0x04, "write A by B; read ACCESS by AB; write B by B"},
+       {0x05, "read ACCESS by AB; write ACCESS by B"},
+       {0x06, "read ACCESS by AB"},
+       {0x07, "read ACCESS by AB"}
+};
+
+char *mfGetAccessConditionsDesc(uint8_t blockn, uint8_t *data) {
+       static char StaticNone[] = "none";
+       
+       uint8_t data1 = ((data[1] >> 4) & 0x0f) >> blockn;
+       uint8_t data2 = ((data[2]) & 0x0f) >> blockn;
+       uint8_t data3 = ((data[2] >> 4) & 0x0f) >> blockn;
+       
+       uint8_t cond = (data1 & 0x01) << 2 | (data2 & 0x01) << 1 | (data3 & 0x01);
+
+       if (blockn == 3) {
+               for (int i = 0; i < ARRAYLEN(MFAccessConditionsTrailer); i++)
+                       if (MFAccessConditionsTrailer[i].cond == cond) {
+                               return MFAccessConditionsTrailer[i].description;
+                       }
+       } else {
+               for (int i = 0; i < ARRAYLEN(MFAccessConditions); i++)
+                       if (MFAccessConditions[i].cond == cond) {
+                               return MFAccessConditions[i].description;
+                       }
+       };
+       
+       return StaticNone;
+};
+
 int CalculateEncIVCommand(mf4Session *session, uint8_t *iv, bool verbose) {
        memcpy(&iv[0], session->TI, 4);
        memcpy(&iv[4], &session->R_Ctr, 2);
index 2453797b24ba9f972f09cc380ed4a098a1a87ff6..5d9735dafaa890fcd3395eb2982b60fa0ed237e6 100644 (file)
@@ -38,9 +38,16 @@ typedef enum {
        mtypWriteResp,
 } MACType_t;
 
+typedef struct {
+       uint8_t cond;
+       char *description;
+} AccessConditions_t;
+
 extern int CalculateMAC(mf4Session *session, MACType_t mtype, uint8_t blockNum, uint8_t blockCount, uint8_t *data, int datalen, uint8_t *mac, bool verbose);
 extern int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool verbose);
 
+extern char *mfGetAccessConditionsDesc(uint8_t blockn, uint8_t *data);
+
 extern uint8_t mfNumBlocksPerSector(uint8_t sectorNo);
 extern uint8_t mfFirstBlockOfSector(uint8_t sectorNo);
 extern uint8_t mfSectorTrailer(uint8_t blockNo);
Impressum, Datenschutz