]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
improved command hf mf sniff. Now it cant decode nested authentication and cant write...
authorMerlokbr@gmail.com <Merlokbr@gmail.com@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Mon, 16 Jul 2012 14:49:51 +0000 (14:49 +0000)
committerMerlokbr@gmail.com <Merlokbr@gmail.com@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Mon, 16 Jul 2012 14:49:51 +0000 (14:49 +0000)
armsrc/apps.h
armsrc/iso14443a.c
armsrc/mifaresniff.c
client/cmdhfmf.c
client/mifarehost.c
client/mifarehost.h
client/util.c
client/util.h

index 5468a9774de57baaafc9fb9ccdb2ae97f62ca740..4c218d0ff4d2efbbbdef2c711ea4f7a6ca5406d4 100644 (file)
@@ -70,6 +70,12 @@ void FpgaGatherVersion(char *dst, int len);
 void FpgaSetupSsc(void);
 void SetupSpi(int mode);
 void FpgaSetupSscDma(uint8_t *buf, int len);
+void inline FpgaDisableSscDma(void){
+       AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
+}
+void inline FpgaEnableSscDma(void){
+       AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
+}
 void SetAdcMuxFor(uint32_t whichGpio);
 
 // Definitions for the FPGA commands.
index a564a32ffcc345b9630f61cf77b4ee0ca6f355aa..d2d79bda6695e85f851f1dcb7ab28dbeee4764cc 100644 (file)
@@ -2416,7 +2416,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
                
                if (++sniffCounter > 65) {
                        if (MfSniffSend(2000)) {
-                               AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
+                               FpgaEnableSscDma();
                        }
                        sniffCounter = 0;
                }
@@ -2442,7 +2442,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
                if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
                        AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf;
                        AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
-                       Dbprintf("RxEmpty ERROR!!! %d", dataLen); // temporary
+                       Dbprintf("RxEmpty ERROR!!! data length:%d", dataLen); // temporary
                }
                // secondary buffer sets as primary, secondary buffer was stopped
                if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
@@ -2487,10 +2487,9 @@ void RAMFUNC SniffMifare(uint8_t param) {
        DbpString("COMMAND FINISHED");
 
 done:
-       AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
+       FpgaDisableSscDma();
        MfSniffEnd();
        
-       Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.byteCnt=%x", maxDataLen, Uart.state, Uart.byteCnt);
-       Dbprintf("Uart.byteCntMax=%x, traceLen=%x", Uart.byteCntMax, traceLen);
+       Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.byteCnt=%x Uart.byteCntMax=%x", maxDataLen, Uart.state, Uart.byteCnt, Uart.byteCntMax);
        LEDsoff();
 }
\ No newline at end of file
index aefe6962483315c992c5a61682f29024083e2a42..31e0287ddcf41047caff6426929a6b2f4ee62caa 100644 (file)
@@ -42,7 +42,7 @@ int MfSniffEnd(void){
 \r
 int RAMFUNC MfSniffLogic(const uint8_t * data, int len, int bitCnt, int reader) {\r
 \r
-       if ((len == 1) && (bitCnt = 9)) { \r
+       if ((len == 1) && (bitCnt = 9) && (data[0] > 0x0F)) { \r
                sniffState = SNF_INIT;\r
        }\r
 \r
@@ -163,7 +163,7 @@ int intMfSniffSend() {
        \r
        if (!traceLen) return 0;\r
 \r
-       AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;\r
+       FpgaDisableSscDma();\r
 \r
        while (pckLen > 0) {\r
                pckSize = min(32, pckLen);\r
index 98006d4165c2bef9c630f285110d5496e0b6c6eb..6abfdda23496ce976b3de0ee2aa5693b8859e7a3 100644 (file)
@@ -1542,6 +1542,13 @@ int CmdHF14AMfCSave(const char *Cmd) {
 }\r
 \r
 int CmdHF14AMfSniff(const char *Cmd){\r
+       // params\r
+       bool wantLogToFile = 0;\r
+       bool wantDecrypt = 0;\r
+       bool wantSaveToEml = 0;\r
+       bool wantSaveToEmlFile = 0;\r
+\r
+       //var \r
        int res = 0;\r
        int len = 0;\r
        int blockLen = 0;\r
@@ -1556,11 +1563,25 @@ int CmdHF14AMfSniff(const char *Cmd){
        memset(buf, 0x00, 3000);\r
        \r
        if (param_getchar(Cmd, 0) == 'h') {\r
-               PrintAndLog("Usage:  hf mf sniff ");\r
-               PrintAndLog("        sample: hf mf sniff ");\r
+               PrintAndLog("It continuously get data from the field and saves it to: log, emulator, emulator file.");\r
+               PrintAndLog("You can specify:");\r
+               PrintAndLog("    l - save encrypted sequence to logfile `uid.log`");\r
+               PrintAndLog("    d - decrypt sequence and put it to log file `uid.log`");\r
+               PrintAndLog(" n/a   e - decrypt sequence, collect read and write commands and save the result of the sequence to emulator memory");\r
+               PrintAndLog(" n/a   r - decrypt sequence, collect read and write commands and save the result of the sequence to emulator dump file `uid.eml`");\r
+               PrintAndLog("Usage:  hf mf sniff [l][d][e][r]");\r
+               PrintAndLog("  sample: hf mf sniff l d e");\r
                return 0;\r
        }       \r
        \r
+       for (int i = 0; i < 4; i++) {\r
+               char ctmp = param_getchar(Cmd, i);\r
+               if (ctmp == 'l' || ctmp == 'L') wantLogToFile = true;\r
+               if (ctmp == 'd' || ctmp == 'D') wantDecrypt = true;\r
+               if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true;\r
+               if (ctmp == 'f' || ctmp == 'F') wantSaveToEmlFile = true;\r
+       }\r
+       \r
        printf("-------------------------------------------------------------------------\n");\r
        printf("Executing command. \n");\r
        printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n");\r
@@ -1611,9 +1632,17 @@ int CmdHF14AMfSniff(const char *Cmd){
                                                memcpy(uid, bufPtr + 2, 7);\r
                                                memcpy(atqa, bufPtr + 2 + 7, 2);\r
                                                sak = bufPtr[11];\r
+                                               \r
                                                PrintAndLog("tag select uid:%s atqa:%02x %02x sak:0x%02x", sprint_hex(uid, 7), atqa[0], atqa[1], sak);\r
+                                               if (wantLogToFile) {\r
+                                                       FillFileNameByUID(logHexFileName, uid, ".log");\r
+                                                       AddLogCurrentDT(logHexFileName);\r
+                                               }                                               \r
+                                               if (wantDecrypt) mfTraceInit(uid, atqa, sak);\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);\r
                                        }\r
                                        bufPtr += len;\r
                                        num++;\r
index fb6a4bdbed7172ee4959c801c57427bb3f9ba18c..cfcc17ba17872036c1477b581f3e39de51b96ec0 100644 (file)
@@ -5,7 +5,7 @@
 // at your option, any later version. See the LICENSE.txt file for the text of\r
 // the license.\r
 //-----------------------------------------------------------------------------\r
-// High frequency ISO14443A commands\r
+// mifare commands\r
 //-----------------------------------------------------------------------------\r
 \r
 #include <stdio.h>\r
@@ -13,6 +13,7 @@
 #include <string.h>\r
 #include "mifarehost.h"\r
 \r
+// MIFARE\r
 \r
 int compar_int(const void * a, const void * b) {\r
        return (*(uint64_t*)b - *(uint64_t*)a);\r
@@ -197,6 +198,8 @@ int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * key
        return 0;\r
 }\r
 \r
+// EMULATOR\r
+\r
 int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) {\r
        UsbCommand c = {CMD_MIFARE_EML_MEMGET, {blockNum, blocksCount, 0}};\r
  \r
@@ -216,6 +219,8 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
        return 0;\r
 }\r
 \r
+// "MAGIC" CARD\r
+\r
 int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe) {\r
        uint8_t block0[16];\r
        memset(block0, 0, 16);\r
@@ -267,3 +272,236 @@ int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) {
        }\r
        return 0;\r
 }\r
+\r
+// SNIFFER\r
+\r
+// variables\r
+char logHexFileName[200] = {0x00};\r
+static uint8_t traceCard[4096];\r
+static int traceState = TRACE_IDLE;\r
+static uint8_t traceCurBlock = 0;\r
+static uint8_t traceCurKey = 0;\r
+\r
+struct Crypto1State *traceCrypto1 = NULL;\r
+\r
+struct Crypto1State *revstate;\r
+uint64_t lfsr;\r
+uint32_t ks2;\r
+uint32_t ks3;\r
+\r
+uint32_t uid;     // serial number\r
+uint32_t nt;      // tag challenge\r
+uint32_t nr_enc;  // encrypted reader challenge\r
+uint32_t ar_enc;  // encrypted reader response\r
+uint32_t at_enc;  // encrypted tag response\r
+\r
+int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak) {\r
+\r
+       if (traceCrypto1) crypto1_destroy(traceCrypto1);\r
+       traceCrypto1 = NULL;\r
+\r
+       memset(traceCard, 0x00, 4096);\r
+       memcpy(traceCard, tuid + 3, 4);\r
+       traceCard[4] = traceCard[0] ^ traceCard[1] ^ traceCard[2] ^ traceCard[3];\r
+       traceCard[5] = sak;\r
+       memcpy(&traceCard[6], atqa, 2);\r
+       traceCurBlock = 0;\r
+       uid = bytes_to_num(tuid + 3, 4);\r
+       \r
+       traceState = TRACE_IDLE;\r
+\r
+       return 0;\r
+}\r
+\r
+void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted){\r
+       uint8_t bt = 0;\r
+       int i;\r
+       \r
+       if (len != 1) {\r
+               for (i = 0; i < len; i++)\r
+                       data[i] = crypto1_byte(pcs, 0x00, isEncrypted) ^ data[i];\r
+       } else {\r
+               bt = 0;\r
+               for (i = 0; i < 4; i++)\r
+                       bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], i)) << i;\r
+                               \r
+               data[0] = bt;\r
+       }\r
+       return;\r
+}\r
+\r
+\r
+int mfTraceDecode(uint8_t *data_src, int len) {\r
+       uint8_t data[64];\r
+\r
+       if (traceState == TRACE_ERROR) return 1;\r
+       if (len > 64) {\r
+               traceState = TRACE_ERROR;\r
+               return 1;\r
+       }\r
+       \r
+       memcpy(data, data_src, len);\r
+       if ((traceCrypto1) && ((traceState == TRACE_IDLE) || (traceState > TRACE_AUTH_OK))) {\r
+               mf_crypto1_decrypt(traceCrypto1, data, len, 0);\r
+               PrintAndLog("dec> %s", sprint_hex(data, len));\r
+               AddLogHex(logHexFileName, "dec> ", data, len); \r
+       }\r
+       \r
+       switch (traceState) {\r
+       case TRACE_IDLE: \r
+               // TODO: check packet crc16!\r
+               \r
+               // AUTHENTICATION\r
+               if ((len ==4) && ((data[0] == 0x60) || (data[0] == 0x61))) {\r
+                       traceState = TRACE_AUTH1;\r
+                       traceCurBlock = data[1];\r
+                       traceCurKey = data[0] == 60 ? 1:0;\r
+                       return 0;\r
+               }\r
+\r
+               // READ\r
+               if ((len ==4) && ((data[0] == 0x30))) {\r
+                       traceState = TRACE_READ_DATA;\r
+                       traceCurBlock = data[1];\r
+                       return 0;\r
+               }\r
+\r
+               // WRITE\r
+               if ((len ==4) && ((data[0] == 0xA0))) {\r
+                       traceState = TRACE_WRITE_OK;\r
+                       traceCurBlock = data[1];\r
+                       return 0;\r
+               }\r
+\r
+               // HALT\r
+               if ((len ==4) && ((data[0] == 0x50) && (data[1] == 0x00))) {\r
+                       traceState = TRACE_ERROR;  // do not decrypt the next commands\r
+                       return 0;\r
+               }\r
+               \r
+               return 0;\r
+       break;\r
+       \r
+       case TRACE_READ_DATA: \r
+               if (len == 18) {\r
+                       traceState = TRACE_IDLE;\r
+\r
+                       memcpy(traceCard + traceCurBlock * 16, data, 16);\r
+                       return 0;\r
+               } else {\r
+                       traceState = TRACE_ERROR;\r
+                       return 1;\r
+               }\r
+       break;\r
+\r
+       case TRACE_WRITE_OK: \r
+               if ((len == 1) && (data[0] = 0x0a)) {\r
+                       traceState = TRACE_WRITE_DATA;\r
+\r
+                       return 0;\r
+               } else {\r
+                       traceState = TRACE_ERROR;\r
+                       return 1;\r
+               }\r
+       break;\r
+\r
+       case TRACE_WRITE_DATA: \r
+               if (len == 18) {\r
+                       traceState = TRACE_IDLE;\r
+\r
+                       memcpy(traceCard + traceCurBlock * 16, data, 16);\r
+                       return 0;\r
+               } else {\r
+                       traceState = TRACE_ERROR;\r
+                       return 1;\r
+               }\r
+       break;\r
+\r
+       case TRACE_AUTH1: \r
+               if (len == 4) {\r
+                       traceState = TRACE_AUTH2;\r
+\r
+                       nt = bytes_to_num(data, 4);\r
+                       return 0;\r
+               } else {\r
+                       traceState = TRACE_ERROR;\r
+                       return 1;\r
+               }\r
+       break;\r
+\r
+       case TRACE_AUTH2: \r
+               if (len == 8) {\r
+                       traceState = TRACE_AUTH_OK;\r
+\r
+                       nr_enc = bytes_to_num(data, 4);\r
+                       ar_enc = bytes_to_num(data + 4, 4);\r
+                       return 0;\r
+               } else {\r
+                       traceState = TRACE_ERROR;\r
+                       return 1;\r
+               }\r
+       break;\r
+\r
+       case TRACE_AUTH_OK: \r
+               if (len ==4) {\r
+                       traceState = TRACE_IDLE;\r
+\r
+                       at_enc = bytes_to_num(data, 4);\r
+                       \r
+                       //  decode key here)\r
+                       if (!traceCrypto1) {\r
+                               ks2 = ar_enc ^ prng_successor(nt, 64);\r
+                               ks3 = at_enc ^ prng_successor(nt, 96);\r
+                               revstate = lfsr_recovery64(ks2, ks3);\r
+                               lfsr_rollback_word(revstate, 0, 0);\r
+                               lfsr_rollback_word(revstate, 0, 0);\r
+                               lfsr_rollback_word(revstate, nr_enc, 1);\r
+                               lfsr_rollback_word(revstate, uid ^ nt, 0);\r
+                       }else{\r
+                               ks2 = ar_enc ^ prng_successor(nt, 64);\r
+                               ks3 = at_enc ^ prng_successor(nt, 96);\r
+                               revstate = lfsr_recovery64(ks2, ks3);\r
+                               lfsr_rollback_word(revstate, 0, 0);\r
+                               lfsr_rollback_word(revstate, 0, 0);\r
+                               lfsr_rollback_word(revstate, nr_enc, 1);\r
+                               lfsr_rollback_word(revstate, uid ^ nt, 0);\r
+                       }\r
+                       crypto1_get_lfsr(revstate, &lfsr);\r
+                       printf("key> %x%x\n", (unsigned int)((lfsr & 0xFFFFFFFF00000000) >> 32), (unsigned int)(lfsr & 0xFFFFFFFF));\r
+                       AddLogUint64(logHexFileName, "key> ", lfsr); \r
+                       \r
+                       if (traceCurKey) {\r
+                               num_to_bytes(lfsr, 6, traceCard + traceCurBlock * 16 + 10);\r
+                       } else {\r
+                               num_to_bytes(lfsr, 6, traceCard + traceCurBlock * 16);\r
+                       }\r
+\r
+                       if (traceCrypto1) {\r
+                               crypto1_destroy(traceCrypto1);\r
+                       }\r
+                       \r
+                       // set cryptosystem state\r
+                       traceCrypto1 = lfsr_recovery64(ks2, ks3);\r
+                       \r
+//     nt = crypto1_word(traceCrypto1, nt ^ uid, 1) ^ nt;\r
+\r
+       /*      traceCrypto1 = crypto1_create(lfsr); // key in lfsr\r
+               crypto1_word(traceCrypto1, nt ^ uid, 0);\r
+               crypto1_word(traceCrypto1, ar, 1);\r
+               crypto1_word(traceCrypto1, 0, 0);\r
+               crypto1_word(traceCrypto1, 0, 0);*/\r
+       \r
+                       return 0;\r
+               } else {\r
+                       traceState = TRACE_ERROR;\r
+                       return 1;\r
+               }\r
+       break;\r
+\r
+       default: \r
+               traceState = TRACE_ERROR;\r
+               return 1;\r
+       }\r
+\r
+       return 0;\r
+}\r
index 8241ab70bcdc365d450833beaa2dfac63cbd31d1..4d3824091aa73df682aa38fae8724f4e8dfddd5f 100644 (file)
 #define CSETBLOCK_RESET_FIELD          0x10\r
 #define CSETBLOCK_SINGLE_OPER          0x1F\r
 \r
+// mifare tracer flags\r
+#define TRACE_IDLE                                                     0x00\r
+#define TRACE_AUTH1                                                    0x01\r
+#define TRACE_AUTH2                                                    0x02\r
+#define TRACE_AUTH_OK                                          0x03\r
+#define TRACE_READ_DATA                                0x04\r
+#define TRACE_WRITE_OK                                 0x05\r
+#define TRACE_WRITE_DATA                               0x06\r
+\r
+#define TRACE_ERROR                                                    0xFF\r
+\r
 typedef struct fnVector { uint8_t blockNo, keyType; uint32_t uid, nt, ks1; } fnVector;\r
 \r
 typedef struct {\r
@@ -48,6 +59,8 @@ typedef struct {
         int             count;\r
 } countKeys;\r
 \r
+extern char logHexFileName[200];\r
+\r
 int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * ResultKeys);\r
 int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key);\r
 int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);\r
@@ -55,3 +68,5 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);
 int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe);\r
 int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe, uint8_t params);\r
 int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);\r
+int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak);\r
+int mfTraceDecode(uint8_t *data_src, int len);\r
index be947b8ade4dc57461b7ccadc210fd4438ab7f19..8a62e361aec8f9ba8452c12887627d13eabe70b5 100644 (file)
@@ -8,10 +8,6 @@
 // utilities
 //-----------------------------------------------------------------------------
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
 #include "util.h"
 
 #ifndef WIN32
@@ -48,6 +44,54 @@ int ukbhit(void) {
 }
 #endif
 
+// log files functions
+void AddLogLine(char *fileName, char *extData, char *c) {
+       FILE *fLog = NULL;
+
+       fLog = fopen(fileName, "a");
+       if (!fLog) {
+               printf("Could not append log file %s", fileName);
+               return;
+       }
+
+       fprintf(fLog, "%s", extData);
+       fprintf(fLog, "%s\n", c);
+       fclose(fLog);
+}
+
+void AddLogHex(char *fileName, char *extData, const uint8_t * data, const size_t len){
+       AddLogLine(fileName, extData, sprint_hex(data, len));
+}
+
+void AddLogUint64(char *fileName, char *extData, const uint64_t data) {
+  char buf[100] = {0};
+       sprintf(buf, "%x%x", (unsigned int)((data & 0xFFFFFFFF00000000) >> 32), (unsigned int)(data & 0xFFFFFFFF));
+       AddLogLine(fileName, extData, buf);
+}
+
+void AddLogCurrentDT(char *fileName) {
+       char buff[20];
+       struct tm *curTime;
+
+       time_t now = time(0);
+       curTime = gmtime(&now);
+
+       strftime (buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", curTime);
+       AddLogLine(fileName, "\nanticollision: ", buff);
+}
+
+void FillFileNameByUID(char *fileName, uint8_t * uid, char *ext) {
+       char * fnameptr = fileName;
+       memset(fileName, 0x00, 200);
+       
+       for (int j = 0; j < 7; j++, fnameptr += 2)
+               sprintf(fnameptr, "%02x", uid[j]); 
+       sprintf(fnameptr, "%s", ext); 
+       
+       printf("fname:%s", fileName);
+}
+
+// printing and converting functions
 
 void print_hex(const uint8_t * data, const size_t len)
 {
index 7ac338cd94d2731a8913e4d667676724a775ce0b..cec187cf23db1bebe911cede313da860aa137192 100644 (file)
 
 #include <stdio.h>
 #include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
 
 int ukbhit(void);
 
+void AddLogLine(char *fileName, char *extData, char *c);
+void AddLogHex(char *fileName, char *extData, const uint8_t * data, const size_t len);
+void AddLogUint64(char *fileName, char *extData, const uint64_t data);
+void AddLogCurrentDT(char *fileName);
+void FillFileNameByUID(char *fileName, uint8_t * uid, char *ext);
+
 void print_hex(const uint8_t * data, const size_t len);
 char * sprint_hex(const uint8_t * data, const size_t len);
 
@@ -26,3 +37,4 @@ uint32_t param_get32ex(const char *line, int paramnum, int deflt, int base);
 uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base);
 int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt);
 int param_getstr(const char *line, int paramnum, char * str);
+
Impressum, Datenschutz