]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - client/cmdhficlass.c
true fix #472 )))
[proxmark3-svn] / client / cmdhficlass.c
index cd4b4440415cad2baa4e3b3573b97fc044c37a7c..63634cd403e1dcf98d4fc7b87304c4d26f700f1f 100644 (file)
@@ -23,7 +23,7 @@
 #include "common.h"
 #include "util.h"
 #include "cmdmain.h"
 #include "common.h"
 #include "util.h"
 #include "cmdmain.h"
-#include "loclass/des.h"
+#include "polarssl/des.h"
 #include "loclass/cipherutils.h"
 #include "loclass/cipher.h"
 #include "loclass/ikeys.h"
 #include "loclass/cipherutils.h"
 #include "loclass/cipher.h"
 #include "loclass/ikeys.h"
@@ -180,10 +180,10 @@ int CmdHFiClassSim(const char *Cmd) {
 
 int HFiClassReader(const char *Cmd, bool loop, bool verbose) {
        bool tagFound = false;
 
 int HFiClassReader(const char *Cmd, bool loop, bool verbose) {
        bool tagFound = false;
-       UsbCommand c = {CMD_READER_ICLASS, {FLAG_ICLASS_READER_CSN|
-                                       FLAG_ICLASS_READER_CONF|FLAG_ICLASS_READER_AA}};
+       UsbCommand c = {CMD_READER_ICLASS, {FLAG_ICLASS_READER_CSN |
+                   FLAG_ICLASS_READER_CC | FLAG_ICLASS_READER_CONF | FLAG_ICLASS_READER_AA |
+                   FLAG_ICLASS_READER_ONLY_ONCE | FLAG_ICLASS_READER_ONE_TRY } };
        // loop in client not device - else on windows have a communication error
        // loop in client not device - else on windows have a communication error
-       c.arg[0] |= FLAG_ICLASS_READER_ONLY_ONCE | FLAG_ICLASS_READER_ONE_TRY;
        UsbCommand resp;
        while(!ukbhit()){
                SendCommand(&c);
        UsbCommand resp;
        while(!ukbhit()){
                SendCommand(&c);
@@ -191,21 +191,34 @@ int HFiClassReader(const char *Cmd, bool loop, bool verbose) {
                        uint8_t readStatus = resp.arg[0] & 0xff;
                        uint8_t *data = resp.d.asBytes;
 
                        uint8_t readStatus = resp.arg[0] & 0xff;
                        uint8_t *data = resp.d.asBytes;
 
-                       if (verbose)
-                               PrintAndLog("Readstatus:%02x", readStatus);
-                       if( readStatus == 0){
-                               //Aborted
+                       // no tag found or button pressed
+                       if( (readStatus == 0 && !loop) || readStatus == 0xFF) {
+                               // abort
                                if (verbose) PrintAndLog("Quitting...");
                                return 0;
                        }
                                if (verbose) PrintAndLog("Quitting...");
                                return 0;
                        }
-                       if( readStatus & FLAG_ICLASS_READER_CSN){
-                               PrintAndLog("CSN: %s",sprint_hex(data,8));
+
+                       if( readStatus & FLAG_ICLASS_READER_CSN) {
+                               PrintAndLog("   CSN: %s",sprint_hex(data,8));
                                tagFound = true;
                        }
                                tagFound = true;
                        }
-                       if( readStatus & FLAG_ICLASS_READER_CC)  PrintAndLog("CC: %s",sprint_hex(data+16,8));
-                       if( readStatus & FLAG_ICLASS_READER_CONF){
+                       if( readStatus & FLAG_ICLASS_READER_CC) { 
+                               PrintAndLog("    CC: %s",sprint_hex(data+16,8));
+                       }
+                       if( readStatus & FLAG_ICLASS_READER_CONF) {
                                printIclassDumpInfo(data);
                        }
                                printIclassDumpInfo(data);
                        }
+                       if (readStatus & FLAG_ICLASS_READER_AA) {
+                               bool legacy = true;
+                               PrintAndLog(" AppIA: %s",sprint_hex(data+8*5,8));
+                               for (int i = 0; i<8; i++) {
+                                       if (data[8*5+i] != 0xFF) {
+                                               legacy = false;
+                                       } 
+                               }
+                               PrintAndLog("      : Possible iClass %s",(legacy) ? "(legacy tag)" : "(NOT legacy tag)");
+                       }
+
                        if (tagFound && !loop) return 1;
                } else {
                        if (verbose) PrintAndLog("Command execute timeout");
                        if (tagFound && !loop) return 1;
                } else {
                        if (verbose) PrintAndLog("Command execute timeout");
@@ -670,7 +683,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
        SendCommand(&c);
        if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) {
                PrintAndLog("Command execute timeout");
        SendCommand(&c);
        if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) {
                PrintAndLog("Command execute timeout");
-               ul_switch_off_field();
+               DropField();
                return 0;
        }
        uint8_t readStatus = resp.arg[0] & 0xff;
                return 0;
        }
        uint8_t readStatus = resp.arg[0] & 0xff;
@@ -678,7 +691,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
 
        if(readStatus == 0){
                PrintAndLog("No tag found...");
 
        if(readStatus == 0){
                PrintAndLog("No tag found...");
-               ul_switch_off_field();
+               DropField();
                return 0;
        }
        if( readStatus & (FLAG_ICLASS_READER_CSN|FLAG_ICLASS_READER_CONF|FLAG_ICLASS_READER_CC)){
                return 0;
        }
        if( readStatus & (FLAG_ICLASS_READER_CSN|FLAG_ICLASS_READER_CONF|FLAG_ICLASS_READER_CC)){
@@ -689,12 +702,12 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
                // large memory - not able to dump pages currently
                if (numblks > maxBlk) numblks = maxBlk;
        }
                // large memory - not able to dump pages currently
                if (numblks > maxBlk) numblks = maxBlk;
        }
-       ul_switch_off_field();
+       DropField();
        // authenticate debit key and get div_key - later store in dump block 3
        if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, false)){
                //try twice - for some reason it sometimes fails the first time...
                if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, false)){
        // authenticate debit key and get div_key - later store in dump block 3
        if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, false)){
                //try twice - for some reason it sometimes fails the first time...
                if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, false)){
-                       ul_switch_off_field();
+                       DropField();
                        return 0;
                }
        }
                        return 0;
                }
        }
@@ -705,14 +718,14 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
        SendCommand(&w);
        if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) {
                PrintAndLog("Command execute time-out 1");
        SendCommand(&w);
        if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) {
                PrintAndLog("Command execute time-out 1");
-               ul_switch_off_field();
+               DropField();
                return 1;
        }
        uint32_t blocksRead = resp.arg[1];
        uint8_t isOK = resp.arg[0] & 0xff;
        if (!isOK && !blocksRead) {
                PrintAndLog("Read Block Failed");
                return 1;
        }
        uint32_t blocksRead = resp.arg[1];
        uint8_t isOK = resp.arg[0] & 0xff;
        if (!isOK && !blocksRead) {
                PrintAndLog("Read Block Failed");
-               ul_switch_off_field();
+               DropField();
                return 0;
        }
        uint32_t startindex = resp.arg[2];
                return 0;
        }
        uint32_t startindex = resp.arg[2];
@@ -728,13 +741,13 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
        // try AA2
        if (have_credit_key) {
                //turn off hf field before authenticating with different key
        // try AA2
        if (have_credit_key) {
                //turn off hf field before authenticating with different key
-               ul_switch_off_field();
+               DropField();
                memset(MAC,0,4);
                // AA2 authenticate credit key and git c_div_key - later store in dump block 4
                if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false, false)){
                        //try twice - for some reason it sometimes fails the first time...
                        if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false, false)){
                memset(MAC,0,4);
                // AA2 authenticate credit key and git c_div_key - later store in dump block 4
                if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false, false)){
                        //try twice - for some reason it sometimes fails the first time...
                        if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false, false)){
-                               ul_switch_off_field();
+                               DropField();
                                return 0;
                        }
                }
                                return 0;
                        }
                }
@@ -747,14 +760,14 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
                        SendCommand(&w);
                        if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) {
                                PrintAndLog("Command execute timeout 2");
                        SendCommand(&w);
                        if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) {
                                PrintAndLog("Command execute timeout 2");
-                               ul_switch_off_field();
+                               DropField();
                                return 0;
                        }
                        uint8_t isOK = resp.arg[0] & 0xff;
                        blocksRead = resp.arg[1];
                        if (!isOK && !blocksRead) {
                                PrintAndLog("Read Block Failed 2");
                                return 0;
                        }
                        uint8_t isOK = resp.arg[0] & 0xff;
                        blocksRead = resp.arg[1];
                        if (!isOK && !blocksRead) {
                                PrintAndLog("Read Block Failed 2");
-                               ul_switch_off_field();
+                               DropField();
                                return 0;
                        }               
 
                                return 0;
                        }               
 
@@ -769,7 +782,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
 
                        gotBytes += blocksRead*8;                       
                } else { //field is still on - turn it off...
 
                        gotBytes += blocksRead*8;                       
                } else { //field is still on - turn it off...
-                       ul_switch_off_field();
+                       DropField();
                }
        }
 
                }
        }
 
@@ -917,7 +930,7 @@ int CmdHFiClass_WriteBlock(const char *Cmd) {
 
        if (cmdp < 6) return usage_hf_iclass_writeblock();
        int ans = WriteBlock(blockno, bldata, KEY, use_credit_key, elite, rawkey, true);
 
        if (cmdp < 6) return usage_hf_iclass_writeblock();
        int ans = WriteBlock(blockno, bldata, KEY, use_credit_key, elite, rawkey, true);
-       ul_switch_off_field();
+       DropField();
        return ans;
 }
 
        return ans;
 }
 
@@ -1095,12 +1108,19 @@ int CmdHFiClassCloneTag(const char *Cmd) {
        return 1;
 }
 
        return 1;
 }
 
-static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool verbose) {
+static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool verbose, bool auth) {
        uint8_t MAC[4]={0x00,0x00,0x00,0x00};
        uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
 
        uint8_t MAC[4]={0x00,0x00,0x00,0x00};
        uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
 
-       if (!select_and_auth(KEY, MAC, div_key, (keyType==0x18), elite, rawkey, verbose))
-               return 0;
+       if (auth) {
+               if (!select_and_auth(KEY, MAC, div_key, (keyType==0x18), elite, rawkey, verbose))
+                       return 0;
+       } else {
+               uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+               uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+               if (!select_only(CSN, CCNR, (keyType==0x18), verbose))
+                       return 0;
+       }
 
        UsbCommand resp;
        UsbCommand w = {CMD_ICLASS_READBLOCK, {blockno}};
 
        UsbCommand resp;
        UsbCommand w = {CMD_ICLASS_READBLOCK, {blockno}};
@@ -1146,6 +1166,7 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
        bool elite = false;
        bool rawkey = false;
        bool errors = false;
        bool elite = false;
        bool rawkey = false;
        bool errors = false;
+       bool auth = false;
        uint8_t cmdp = 0;
        while(param_getchar(Cmd, cmdp) != 0x00)
        {
        uint8_t cmdp = 0;
        while(param_getchar(Cmd, cmdp) != 0x00)
        {
@@ -1174,6 +1195,7 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
                        break;
                case 'k':
                case 'K':
                        break;
                case 'k':
                case 'K':
+                       auth = true;
                        dataLen = param_getstr(Cmd, cmdp+1, tempStr);
                        if (dataLen == 16) { 
                                errors = param_gethex(tempStr, 0, KEY, dataLen);
                        dataLen = param_getstr(Cmd, cmdp+1, tempStr);
                        if (dataLen == 16) { 
                                errors = param_gethex(tempStr, 0, KEY, dataLen);
@@ -1204,9 +1226,10 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
                if(errors) return usage_hf_iclass_readblock();
        }
 
                if(errors) return usage_hf_iclass_readblock();
        }
 
-       if (cmdp < 4) return usage_hf_iclass_readblock();
-
-       return ReadBlock(KEY, blockno, keyType, elite, rawkey, true);
+       if (cmdp < 2) return usage_hf_iclass_readblock();
+       if (!auth)
+               PrintAndLog("warning: no authentication used with read, only a few specific blocks can be read accurately without authentication.");
+       return ReadBlock(KEY, blockno, keyType, elite, rawkey, true, auth);
 }
 
 int CmdHFiClass_loclass(const char *Cmd) {
 }
 
 int CmdHFiClass_loclass(const char *Cmd) {
@@ -1349,7 +1372,7 @@ uint64_t hexarray_to_uint64(uint8_t *key) {
        for (int i = 0;i < 8;i++)
                sprintf(&temp[(i *2)],"%02X",key[i]);
        temp[16] = '\0';
        for (int i = 0;i < 8;i++)
                sprintf(&temp[(i *2)],"%02X",key[i]);
        temp[16] = '\0';
-       if (sscanf(temp,"%016"llx,&uint_key) < 1)
+       if (sscanf(temp,"%016" SCNx64,&uint_key) < 1)
                return 0;
        return uint_key;
 }
                return 0;
        return uint_key;
 }
@@ -1689,7 +1712,7 @@ static command_t CommandTable[] =
        {"loclass",     CmdHFiClass_loclass,            1,      "[options..] Use loclass to perform bruteforce of reader attack dump"},
        {"managekeys",  CmdHFiClassManageKeys,          1,      "[options..] Manage the keys to use with iClass"},
        {"readblk",     CmdHFiClass_ReadBlock,          0,      "[options..] Authenticate and Read iClass block"},
        {"loclass",     CmdHFiClass_loclass,            1,      "[options..] Use loclass to perform bruteforce of reader attack dump"},
        {"managekeys",  CmdHFiClassManageKeys,          1,      "[options..] Manage the keys to use with iClass"},
        {"readblk",     CmdHFiClass_ReadBlock,          0,      "[options..] Authenticate and Read iClass block"},
-       {"reader",      CmdHFiClassReader,              0,      "            Read an iClass tag"},
+       {"reader",      CmdHFiClassReader,              0,      "            Look for iClass tags until a key or the pm3 button is pressed"},
        {"readtagfile", CmdHFiClassReadTagFile,         1,      "[options..] Display Content from tagfile"},
        {"replay",      CmdHFiClassReader_Replay,       0,      "<mac>       Read an iClass tag via Reply Attack"},
        {"sim",         CmdHFiClassSim,                 0,      "[options..] Simulate iClass tag"},
        {"readtagfile", CmdHFiClassReadTagFile,         1,      "[options..] Display Content from tagfile"},
        {"replay",      CmdHFiClassReader_Replay,       0,      "<mac>       Read an iClass tag via Reply Attack"},
        {"sim",         CmdHFiClassSim,                 0,      "[options..] Simulate iClass tag"},
Impressum, Datenschutz