]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
ADD: @go_tus simple bruteforce for t55xx, refactored a bit.
authoriceman1001 <iceman@iuse.se>
Fri, 27 Nov 2015 15:24:00 +0000 (16:24 +0100)
committericeman1001 <iceman@iuse.se>
Fri, 27 Nov 2015 15:24:00 +0000 (16:24 +0100)
ADD: @pwpiwi 's implementation of Hardnested

18 files changed:
armsrc/appmain.c
armsrc/apps.h
armsrc/epa.c
armsrc/iso14443a.c
armsrc/iso14443a.h
armsrc/mifarecmd.c
armsrc/mifaredesfire.c
client/Makefile
client/cmddata.c
client/cmdhfmf.c
client/cmdhfmf.h
client/cmdlft55xx.c
client/cmdlft55xx.h
client/data.c
client/hid-flasher/usb_cmd.h
client/lualibs/commands.lua
common/lfdemod.h
include/usb_cmd.h

index b29a61010de21b31edfcca4466ebf8ab9137d34d..4cbf5acdc1ed11ab7d5afd53b66439f42f9d7eeb 100644 (file)
@@ -432,7 +432,7 @@ void StandAloneMode14a()
                                                SpinDelay(300);
                                        }
                                }
-                               if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid))
+                               if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid, true, 0))
                                        continue;
                                else
                                {
@@ -1131,6 +1131,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
                case CMD_MIFAREU_WRITEBL:
                        MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes);
                        break;
+               case CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES:
+                       MifareAcquireEncryptedNonces(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+                       break;
                case CMD_MIFARE_NESTED:
                        MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
index 3baf11ae8cf4bdf387a28a64bdfbb02427dff6a9..83cd94ec88a77c6fe52dd4c56f083a4931ebaced 100644 (file)
@@ -132,6 +132,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 //void MifareUWriteBlockCompat(uint8_t arg0,uint8_t *datain);
 void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
 void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
+void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain);
 void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
 void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
 void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
index 737e633fcbb516c394d9ef1b1f801146cbec7e78..b89d495659d8171dc4b5a0c48497d1b5e9a049d2 100644 (file)
@@ -529,7 +529,7 @@ int EPA_Setup()
        // power up the field
        iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
        // select the card
-       return_code = iso14443a_select_card(uid, &card_select_info, NULL);
+       return_code = iso14443a_select_card(uid, &card_select_info, NULL, true, 0);
        if (return_code == 1) {
        // send the PPS request
        ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
index e213783262733f84bfbb7a7062312d24a181c39f..29d9728a0f8e95e777b7c6f6f8ef397054faf451 100644 (file)
@@ -1896,10 +1896,12 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
        return Demod.len;
 }
 
-/* performs iso14443a anticollision procedure
- * fills the uid pointer unless NULL
- * fills resp_data unless NULL */
-int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr) {
+// performs iso14443a anticollision (optional) and card select procedure
+// fills the uid and cuid pointer unless NULL
+// fills the card info record unless NULL
+// if anticollision is false, then the UID must be provided in uid_ptr[] 
+// and num_cascades must be set (1: 4 Byte UID, 2: 7 Byte UID, 3: 10 Byte UID)
+int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades) {
        uint8_t wupa[]       = { 0x52 };  // 0x26 - REQA  0x52 - WAKE-UP
        uint8_t sel_all[]    = { 0x93,0x20 };
        uint8_t sel_uid[]    = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
@@ -1914,7 +1916,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
        int len;
 
        // Broadcast for a card, WUPA (0x52) will force response from all cards in the field
-    ReaderTransmitBitsPar(wupa,7,0, NULL);
+    ReaderTransmitBitsPar(wupa, 7, NULL, NULL);
        
        // Receive the ATQA
        if(!ReaderReceive(resp, resp_par)) return 0;
@@ -1925,10 +1927,12 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
                memset(p_hi14a_card->uid,0,10);
        }
 
+       if (anticollision) {
        // clear uid
        if (uid_ptr) {
                memset(uid_ptr,0,10);
        }
+       }
 
        // check for proprietary anticollision:
        if ((resp[0] & 0x1F) == 0) {
@@ -1942,6 +1946,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
                // SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97)
                sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2;
 
+               if (anticollision) {
                // SELECT_ALL
                ReaderTransmit(sel_all, sizeof(sel_all), NULL);
                if (!ReaderReceive(resp, resp_par)) return 0;
@@ -1977,6 +1982,14 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
                } else {                // no collision, use the response to SELECT_ALL as current uid
                        memcpy(uid_resp, resp, 4);
                }
+               } else {
+                       if (cascade_level < num_cascades - 1) {
+                               uid_resp[0] = 0x88;
+                               memcpy(uid_resp+1, uid_ptr+cascade_level*3, 3);
+                       } else {
+                               memcpy(uid_resp, uid_ptr+cascade_level*3, 4);
+                       }
+               }
                uid_resp_len = 4;
 
                // calculate crypto UID. Always use last 4 Bytes.
@@ -1986,7 +1999,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
 
                // Construct SELECT UID command
                sel_uid[1] = 0x70;                                                                                                      // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC)
-               memcpy(sel_uid+2, uid_resp, 4);                                                                         // the UID
+               memcpy(sel_uid+2, uid_resp, 4);                                                                         // the UID received during anticollision, or the provided UID
                sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5];         // calculate and add BCC
                AppendCrc14443a(sel_uid, 7);                                                                            // calculate and add CRC
                ReaderTransmit(sel_uid, sizeof(sel_uid), NULL);
@@ -2002,11 +2015,10 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
                        uid_resp[0] = uid_resp[1];
                        uid_resp[1] = uid_resp[2];
                        uid_resp[2] = uid_resp[3]; 
-
                        uid_resp_len = 3;
                }
 
-               if(uid_ptr) {
+               if(uid_ptr && anticollision) {
                        memcpy(uid_ptr + (cascade_level*3), uid_resp, uid_resp_len);
                }
 
@@ -2127,7 +2139,7 @@ void ReaderIso14443a(UsbCommand *c)
                iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
                if(!(param & ISO14A_NO_SELECT)) {
                        iso14a_card_select_t *card = (iso14a_card_select_t*)buf;
-                       arg0 = iso14443a_select_card(NULL,card,NULL);
+                       arg0 = iso14443a_select_card(NULL,card,NULL, true, 0);
                        cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
                }
        }
@@ -2325,7 +2337,7 @@ void ReaderMifare(bool first_try)
                        SpinDelay(100);
                }
                
-               if(!iso14443a_select_card(uid, NULL, &cuid)) {
+               if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
                        if (MF_DBGLEVEL >= 1)   Dbprintf("Mifare: Can't select card");
                        continue;
                }
index 81871dc7128230dd82c48ff36a6de471920b1c2b..c9da0da7d05e735528a4af88da3ff0c5418b8659 100644 (file)
@@ -83,7 +83,7 @@ extern int ReaderReceive(uint8_t *receivedAnswer, uint8_t *par);
 
 extern void iso14443a_setup(uint8_t fpga_minor_mode);
 extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data);
-extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr);
+extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades);
 extern void iso14a_set_trigger(bool enable);
 
 #endif /* __ISO14443A_H */
index 1e42d5b45875e097cb2c753bde2f2169e4286a27..be25273de8d461c5dff1acc878fa95499dfa24a9 100644 (file)
@@ -49,7 +49,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        LED_C_OFF();\r
 \r
        while (true) {\r
-               if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
+               if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
                        if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
                        break;\r
                };\r
@@ -96,7 +96,7 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
 \r
        clear_trace();\r
 \r
-       if(!iso14443a_select_card(NULL, NULL, NULL)) {\r
+       if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");\r
                OnError(0);\r
                return;\r
@@ -131,7 +131,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
 \r
        clear_trace();\r
 \r
-       int len = iso14443a_select_card(NULL, NULL, NULL);\r
+       int len = iso14443a_select_card(NULL, NULL, NULL, true, 0);\r
        if(!len) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);\r
                OnError(1);\r
@@ -207,7 +207,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        LED_C_OFF();\r
 \r
        isOK = 1;\r
-       if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
+       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
                isOK = 0;\r
                if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
        }\r
@@ -271,7 +271,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
                return;\r
        }\r
 \r
-       int len = iso14443a_select_card(NULL, NULL, NULL);\r
+       int len = iso14443a_select_card(NULL, NULL, NULL, true, 0);\r
        if (!len) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);\r
                OnError(1);\r
@@ -373,7 +373,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        LED_C_OFF();\r
 \r
        while (true) {\r
-                       if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
+                       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
                        if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
                        break;\r
                };\r
@@ -427,7 +427,7 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t *datain)
        clear_trace();\r
        iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
 \r
-       if(!iso14443a_select_card(uid, NULL, NULL)) {\r
+       if(!iso14443a_select_card(uid, NULL, NULL, true, 0)) {\r
                if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
                OnError(0);\r
                return;\r
@@ -473,7 +473,7 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
 \r
        clear_trace();\r
 \r
-       if(!iso14443a_select_card(NULL, NULL, NULL)) {\r
+       if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {\r
                if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
                OnError(0);\r
                return;\r
@@ -532,7 +532,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
 \r
        clear_trace();\r
 \r
-       if(!iso14443a_select_card(NULL, NULL, NULL)) {\r
+       if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {\r
                if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
                OnError(0);\r
                return;\r
@@ -597,6 +597,138 @@ int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) {
 }\r
 \r
 \r
+//-----------------------------------------------------------------------------\r
+// acquire encrypted nonces in order to perform the attack described in\r
+// Carlo Meijer, Roel Verdult, "Ciphertext-only Cryptanalysis on Hardened\r
+// Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on \r
+// Computer and Communications Security, 2015\r
+//-----------------------------------------------------------------------------\r
+void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain)\r
+{\r
+       uint64_t ui64Key = 0;\r
+       uint8_t uid[10];\r
+       uint32_t cuid;\r
+       uint8_t cascade_levels = 0;\r
+       struct Crypto1State mpcs = {0, 0};\r
+       struct Crypto1State *pcs;\r
+       pcs = &mpcs;\r
+       uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
+       int16_t isOK = 0;\r
+       uint8_t par_enc[1];\r
+       uint8_t nt_par_enc = 0;\r
+       uint8_t buf[USB_CMD_DATA_SIZE];\r
+       uint32_t timeout;\r
+       \r
+       uint8_t blockNo = arg0 & 0xff;\r
+       uint8_t keyType = (arg0 >> 8) & 0xff;\r
+       uint8_t targetBlockNo = arg1 & 0xff;\r
+       uint8_t targetKeyType = (arg1 >> 8) & 0xff;\r
+       ui64Key = bytes_to_num(datain, 6);\r
+       bool initialize = flags & 0x0001;\r
+       bool slow = flags & 0x0002;\r
+       bool field_off = flags & 0x0004;\r
+       \r
+       #define AUTHENTICATION_TIMEOUT 848                      // card times out 1ms after wrong authentication (according to NXP documentation)\r
+       #define PRE_AUTHENTICATION_LEADTIME 400         // some (non standard) cards need a pause after select before they are ready for first authentication \r
+       \r
+       LED_A_ON();\r
+       LED_C_OFF();\r
+\r
+       if (initialize) {\r
+               iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
+               clear_trace();\r
+               set_tracing(true);\r
+       }\r
+       \r
+       LED_C_ON();\r
+       \r
+       uint16_t num_nonces = 0;\r
+       bool have_uid = false;\r
+       for (uint16_t i = 0; i <= USB_CMD_DATA_SIZE - 9; ) {\r
+\r
+               // Test if the action was cancelled\r
+               if(BUTTON_PRESS()) {\r
+                       isOK = 2;\r
+                       field_off = true;\r
+                       break;\r
+               }\r
+\r
+               if (!have_uid) { // need a full select cycle to get the uid first\r
+                       iso14a_card_select_t card_info;         \r
+                       if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("AcquireNonces: Can't select card (ALL)");\r
+                               continue;\r
+                       }\r
+                       switch (card_info.uidlen) {\r
+                               case 4 : cascade_levels = 1; break;\r
+                               case 7 : cascade_levels = 2; break;\r
+                               case 10: cascade_levels = 3; break;\r
+                               default: break;\r
+                       }\r
+                       have_uid = true;        \r
+               } else { // no need for anticollision. We can directly select the card\r
+                       if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("AcquireNonces: Can't select card (UID)");\r
+                               continue;\r
+                       }\r
+               }\r
+               \r
+               if (slow) {\r
+                       timeout = GetCountSspClk() + PRE_AUTHENTICATION_LEADTIME;\r
+                       while(GetCountSspClk() < timeout);\r
+               }\r
+\r
+               uint32_t nt1;\r
+               if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, NULL)) {\r
+                       if (MF_DBGLEVEL >= 1)   Dbprintf("AcquireNonces: Auth1 error");\r
+                       continue;\r
+               }\r
+\r
+               // nested authentication\r
+               uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par_enc, NULL);\r
+               if (len != 4) {\r
+                       if (MF_DBGLEVEL >= 1)   Dbprintf("AcquireNonces: Auth2 error len=%d", len);\r
+                       continue;\r
+               }\r
+       \r
+               // send a dummy byte as reader response in order to trigger the cards authentication timeout\r
+               uint8_t dummy_answer = 0;\r
+               ReaderTransmit(&dummy_answer, 1, NULL);\r
+               timeout = GetCountSspClk() + AUTHENTICATION_TIMEOUT;\r
+               \r
+               num_nonces++;\r
+               if (num_nonces % 2) {\r
+                       memcpy(buf+i, receivedAnswer, 4);\r
+                       nt_par_enc = par_enc[0] & 0xf0;\r
+               } else {\r
+                       nt_par_enc |= par_enc[0] >> 4;\r
+                       memcpy(buf+i+4, receivedAnswer, 4);\r
+                       memcpy(buf+i+8, &nt_par_enc, 1);\r
+                       i += 9;\r
+               }\r
+\r
+               // wait for the card to become ready again\r
+               while(GetCountSspClk() < timeout);\r
+       \r
+       }\r
+\r
+       LED_C_OFF();\r
+       \r
+       crypto1_destroy(pcs);\r
+       \r
+       LED_B_ON();\r
+       cmd_send(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf));\r
+       LED_B_OFF();\r
+\r
+       if (MF_DBGLEVEL >= 3)   DbpString("AcquireEncryptedNonces finished");\r
+\r
+       if (field_off) {\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+               LEDsoff();\r
+       }\r
+}\r
+\r
+\r
 //-----------------------------------------------------------------------------\r
 // MIFARE nested authentication. \r
 // \r
@@ -668,7 +800,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
                                continue;\r
                        }\r
 \r
-                       if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
+                       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("Nested: Can't select card");\r
                                rtr--;\r
                                continue;\r
@@ -741,7 +873,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
                                continue;\r
                        }\r
 \r
-                       if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
+                       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("Nested: Can't select card");\r
                                continue;\r
                        };\r
@@ -857,7 +989,7 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                        if (MF_DBGLEVEL >= 1)   Dbprintf("ChkKeys: Halt error");\r
                }\r
 \r
-               if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
+               if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
                        if (OLD_MF_DBGLEVEL >= 1)       Dbprintf("ChkKeys: Can't select card");\r
                        break;\r
                };\r
@@ -952,7 +1084,7 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
        \r
        bool isOK = true;\r
 \r
-       if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
+       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
                isOK = false;\r
                if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
        }\r
@@ -1051,7 +1183,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
 \r
        // read UID and return to client\r
        if (workFlags & MAGIC_UID) {\r
-               if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
+               if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
                        if (MF_DBGLEVEL >= MF_DBG_ERROR)        Dbprintf("Can't select card");\r
                        OnErrorMagic(MAGIC_UID);\r
                };\r
@@ -1222,7 +1354,7 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
        iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
        clear_trace();\r
 \r
-       int len = iso14443a_select_card(uid, NULL, &cuid);\r
+       int len = iso14443a_select_card(uid, NULL, &cuid, true, 0);\r
        if(!len) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");\r
                OnError(1);\r
index cacd767f913a729440b8a8bacff74cf697616f79..8336d79330e588b7197fdb40896838ed663caf97 100644 (file)
@@ -25,7 +25,7 @@ bool InitDesfireCard(){
        byte_t cardbuf[USB_CMD_DATA_SIZE] = {0x00};
        iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
        
-       int len = iso14443a_select_card(NULL,card,NULL);
+       int len = iso14443a_select_card(NULL,card,NULL,true,0);
 
        if (!len) {
                if (MF_DBGLEVEL >= MF_DBG_ERROR)
@@ -114,7 +114,7 @@ void MifareDesfireGetInformation(){
 
        // card select - information
        iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
-       byte_t isOK = iso14443a_select_card(NULL, card, NULL);
+       byte_t isOK = iso14443a_select_card(NULL, card, NULL, true, 0);
        if ( isOK == 0) {
                if (MF_DBGLEVEL >= MF_DBG_ERROR) {
                        Dbprintf("Can't select card");
index bcd59397191bcf80258a551f2ae2edb9fe068f94..27617a5ddc86cf4145365147c3e96b2a4a04b014 100644 (file)
@@ -109,6 +109,7 @@ CMDSRCS =   nonce2key/crapto1.c\
                        cmdhficlass.c \
                        cmdhfmf.c \
             cmdhfmfu.c \
+cmdhfmfhard.c \
                        cmdhfmfdes.c \
                        cmdhftopaz.c \
                        cmdhw.c \
index aaff0302f901e964017904749f81d85627dd6f26..aeabd985612af6c7f2a1a02be2f223b07fa0ae58 100644 (file)
@@ -1987,7 +1987,11 @@ int getSamples(const char *Cmd, bool silent)
        GetFromBigBuf(got,n,0);
        PrintAndLog("Data fetched");
        UsbCommand response;
-       WaitForResponse(CMD_ACK, &response);
+       if ( !WaitForResponseTimeout(CMD_ACK, &response, 10000) ) {
+        PrintAndLog("timeout while waiting for reply.");
+               return 1;
+    }
+       
        uint8_t bits_per_sample = 8;
 
        //Old devices without this feature would send 0 at arg[0]
@@ -2030,9 +2034,9 @@ int CmdTuneSamples(const char *Cmd)
        int timeout = 0;
        printf("\nMeasuring antenna characteristics, please wait...");
 
-       UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING};
+       UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING, {0,0,0}};
+       clearCommandBuffer();
        SendCommand(&c);
-
        UsbCommand resp;
        while(!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING,&resp,1000)) {
                timeout++;
@@ -2080,7 +2084,6 @@ int CmdTuneSamples(const char *Cmd)
                ShowGraphWindow();
                RepaintGraphWindow();
        }
-
        return 0;
 }
 
@@ -2096,7 +2099,7 @@ int CmdLoad(const char *Cmd)
        
        FILE *f = fopen(filename, "r");
        if (!f) {
-                PrintAndLog("couldn't open '%s'", filename);
+               PrintAndLog("couldn't open '%s'", filename);
                return 0;
        }
 
@@ -2115,11 +2118,13 @@ int CmdLoad(const char *Cmd)
 int CmdLtrim(const char *Cmd)
 {
        int ds = atoi(Cmd);
-       if (GraphTraceLen<=0) return 0;
+
+       if (GraphTraceLen <= 0) return 0;
+
        for (int i = ds; i < GraphTraceLen; ++i)
                GraphBuffer[i-ds] = GraphBuffer[i];
-       GraphTraceLen -= ds;
 
+       GraphTraceLen -= ds;
        RepaintGraphWindow();
        return 0;
 }
@@ -2128,9 +2133,7 @@ int CmdLtrim(const char *Cmd)
 int CmdRtrim(const char *Cmd)
 {
        int ds = atoi(Cmd);
-
        GraphTraceLen = ds;
-
        RepaintGraphWindow();
        return 0;
 }
index 1d1dc2f433456a197f06e28010877308d14e3caa..ae380b3c348ce87e174d7d498ad829041863321b 100644 (file)
@@ -9,6 +9,7 @@
 //-----------------------------------------------------------------------------\r
 \r
 #include "cmdhfmf.h"\r
+#include "cmdhfmfhard.h"\r
 #include "nonce2key/nonce2key.h"\r
 \r
 static int CmdHelp(const char *Cmd);\r
@@ -791,6 +792,104 @@ 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
+       \r
+       char ctmp;\r
+       ctmp = param_getchar(Cmd, 0);\r
+       if (ctmp != 'R' && ctmp != 'r' && 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> [w] [s]");\r
+               PrintAndLog("  or  hf mf hardnested r");\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
+\r
+               return 0;\r
+       }       \r
+       \r
+       bool nonce_file_read = false;\r
+       bool nonce_file_write = false;\r
+       bool slow = false;\r
+       \r
+       if (ctmp == 'R' || ctmp == 'r') {\r
+\r
+               nonce_file_read = true;\r
+\r
+       } else {\r
+\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
+               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, file action: %s, Slow: %s ", \r
+                       trgBlockNo, \r
+                       trgKeyType?'B':'A', \r
+                       nonce_file_write?"write":nonce_file_read?"read":"none",\r
+                       slow?"Yes":"No");\r
+       int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, nonce_file_read, nonce_file_write, slow);\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
@@ -2017,6 +2116,7 @@ static command_t CommandTable[] =
   {"chk",              CmdHF14AMfChk,                  0, "Test block keys"},\r
   {"mifare",   CmdHF14AMifare,                 0, "Read parity error messages."},\r
   {"nested",   CmdHF14AMfNested,               0, "Test nested authentication"},\r
+       {"hardnested",  CmdHF14AMfNestedHard,   0, "Nested attack for hardened Mifare cards"},\r
   {"sniff",            CmdHF14AMfSniff,                0, "Sniff card-reader communication"},\r
   {"sim",              CmdHF14AMf1kSim,                0, "Simulate MIFARE card"},\r
   {"eclr",             CmdHF14AMfEClear,               0, "Clear simulator memory block"},\r
index 19adbe304e78942564ab773f67775cf8bf420928..31c84dc4790867a8117f3593a4113c956962e942 100644 (file)
@@ -38,6 +38,7 @@ int CmdHF14AMfUWrBl(const char* cmd);
 int CmdHF14AMfChk(const char* cmd);
 int CmdHF14AMifare(const char* cmd);
 int CmdHF14AMfNested(const char* cmd);
+int CmdHF14AMfNestedHard(const char *Cmd);\r
 int CmdHF14AMfSniff(const char* cmd);\r
 int CmdHF14AMf1kSim(const char* cmd);\r
 int CmdHF14AMfEClear(const char* cmd);\r
index d864c9ed0ec1fe6075645877abe0edad2200bd43..2605784e84ca498002c93f572011f50a4b4fc775 100644 (file)
@@ -134,7 +134,7 @@ int usage_t55xx_detect(){
        PrintAndLog("Examples:");\r
        PrintAndLog("      lf t55xx detect");\r
        PrintAndLog("      lf t55xx detect 1");\r
-       PrintAndLog("      lf t55xx detect 11223344");\r
+       PrintAndLog("      lf t55xx detect 11223344");\r
        PrintAndLog("");\r
        return 0;\r
 }\r
@@ -149,6 +149,14 @@ int usage_t55xx_wakup(){
     PrintAndLog("      lf t55xx wakeup p 11223344  - send wakeup password");\r
        return 0;\r
 }\r
+int usage_t55xx_bruteforce(){\r
+    PrintAndLog("Usage: lf t55xx bruteforce <start password> <end password>");\r
+    PrintAndLog("       password must be 4 bytes (8 hex symbols)");\r
+    PrintAndLog("Examples:");\r
+    PrintAndLog("       lf t55xx bruteforce aaaaaaaa bbbbbbbb");\r
+    PrintAndLog("");\r
+    return 0;\r
+}\r
 \r
 static int CmdHelp(const char *Cmd);\r
 \r
@@ -1307,20 +1315,61 @@ int CmdT55xxWipe(const char *Cmd) {
        return 0;\r
 }\r
 \r
+int CmdT55xxBruteForce(const char *Cmd) {\r
+    uint32_t start_password = 0x00000000; //start password\r
+    uint32_t end_password   = 0xFFFFFFFF; //end   password\r
+\r
+    bool found = false;\r
+    char cmdp = param_getchar(Cmd, 0);\r
+    if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_bruteforce();\r
+\r
+    start_password = param_get32ex(Cmd, 0, 0, 16);\r
+       end_password = param_get32ex(Cmd, 1, 0, 16);\r
+       \r
+       if ( start_password == end_password ) return usage_t55xx_bruteforce();\r
+       \r
+    PrintAndLog("Start Password %08x", start_password);\r
+    PrintAndLog("  End Password %08x", end_password);\r
+       \r
+    int i = start_password;\r
+\r
+    while ((!found) && (i <= end_password)){\r
+\r
+               AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, TRUE, i);\r
+               found = tryDetectModulation();\r
+        \r
+               if (found)\r
+                       break;\r
+        \r
+        if ((i % 0x100) == 0) printf("[%08x], ",i);\r
+\r
+               i++;\r
+    }\r
+    \r
+    PrintAndLog("");\r
+       \r
+    if (found)\r
+               PrintAndLog("Found Password [%08x]", i);\r
+    else\r
+               PrintAndLog("NOT Found Last Password [%08x]", i);\r
+    return 0;\r
+}\r
+\r
 static command_t CommandTable[] = {\r
-  {"help",   CmdHelp,           1, "This help"},\r
-  {"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},\r
-  {"detect",   CmdT55xxDetect,    1, "[1] Try detecting the tag modulation from reading the configuration block."},\r
-  {"read",     CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},\r
-  {"resetread",CmdResetRead,      0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},\r
-  {"write",    CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},\r
-  {"trace",    CmdT55xxReadTrace, 1, "[1] Show T55x7 traceability data (page 1/ blk 0-1)"},\r
-  {"info",     CmdT55xxInfo,      1, "[1] Show T55x7 configuration data (page 0/ blk 0)"},\r
-  {"dump",     CmdT55xxDump,      0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},\r
-  {"special", special,          0, "Show block changes with 64 different offsets"},\r
-  {"wakeup", CmdT55xxWakeUp,    0, "Send AOR wakeup command"},\r
-  {"wipe",     CmdT55xxWipe,      0, "Wipe a T55xx tag and set defaults (will destroy any data on tag)"},\r
-  {NULL, NULL, 0, NULL}\r
+       {"help",                CmdHelp,           1, "This help"},\r
+       {"bruceforce",  CmdT55xxBruteForce,0, "Simple bruteforce attack to find password"},\r
+       {"config",              CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},\r
+       {"detect",              CmdT55xxDetect,    1, "[1] Try detecting the tag modulation from reading the configuration block."},\r
+       {"dump",                CmdT55xxDump,      0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},\r
+       {"info",                CmdT55xxInfo,      1, "[1] Show T55x7 configuration data (page 0/ blk 0)"},\r
+       {"read",                CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},\r
+       {"resetread",   CmdResetRead,      0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},\r
+       {"special",             special,           0, "Show block changes with 64 different offsets"},  \r
+       {"trace",               CmdT55xxReadTrace, 1, "[1] Show T55x7 traceability data (page 1/ blk 0-1)"},\r
+       {"wakeup",              CmdT55xxWakeUp,    0, "Send AOR wakeup command"},\r
+       {"wipe",                CmdT55xxWipe,      0, "Wipe a T55xx tag and set defaults (will destroy any data on tag)"},\r
+       {"write",               CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},\r
+       {NULL, NULL, 0, NULL}\r
 };\r
 \r
 int CmdLFT55XX(const char *Cmd) {\r
index a58fa44e701705d7b071f6b79f59f8a811b6425b..77963fde3a3e5881f24691b6e2dd87c794bf8315 100644 (file)
@@ -75,6 +75,7 @@ int CmdT55xxInfo(const char *Cmd);
 int CmdT55xxDetect(const char *Cmd);\r
 int CmdResetRead(const char *Cmd);\r
 int CmdT55xxWipe(const char *Cmd);\r
+int CmdT55xxBruteForce(const char *Cmd);\r
 \r
 char * GetBitRateStr(uint32_t id);\r
 char * GetSaferStr(uint32_t id);\r
@@ -92,4 +93,5 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5)
 int special(const char *Cmd);\r
 int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password );\r
 \r
+bool detectPassword(int password);\r
 #endif\r
index 4d7d1e410fdc04e73789345b3560c7a671d5a624..1725944eb9b10cc9eab469cb91e30eebf951b3a0 100644 (file)
@@ -17,9 +17,9 @@
 
 uint8_t* sample_buf;
 
-void GetFromBigBuf(uint8_t *dest, int bytes, int start_index)
-{
-  sample_buf = dest;
-  UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
-  SendCommand(&c);
+void GetFromBigBuf(uint8_t *dest, int bytes, int start_index) {
+       sample_buf = dest;
+       UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
+       clearCommandBuffer();
+       SendCommand(&c);
 }
index 01b2d83b10cc336ad44397ae3fd63e6bab99ee4b..be0cf9ced086ac4b79ded5f343971444db3880dc 100644 (file)
@@ -168,6 +168,8 @@ typedef struct{
 
 #define CMD_READER_MIFARE                                                 0x0611
 #define CMD_MIFARE_NESTED                                                 0x0612
+#define        CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES                               0x0613
+
 
 #define CMD_MIFARE_READBL                                                 0x0620
 #define CMD_MIFAREU_READBL                                                0x0720
index 957c99b460b1fbe9112775a2248db5b70063bc68..92fc9bb0bdaa468f7ad64a89b399c6ab18d8ccde 100644 (file)
@@ -129,6 +129,7 @@ local _commands = {
 
        CMD_READER_MIFARE =                                                  0x0611,
        CMD_MIFARE_NESTED =                                                  0x0612,
+       CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES =                                0x0613,
 
        CMD_MIFARE_READBL =                                                  0x0620,
        CMD_MIFAREU_READBL =                                                 0x0720,
index 20eb6769502283d7972d438c6a44d5d6a245b14d..a1d99e113f210cf592015c6140ed0f54b5e5ab44 100644 (file)
@@ -16,6 +16,7 @@
 #include <stdint.h>
 
 //generic
+uint8_t justNoise(uint8_t *BitStream, size_t size);
 size_t   addParity(uint8_t *BitSource, uint8_t *dest, uint8_t sourceLen, uint8_t pLen, uint8_t pType);
 int      askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType);
 int      BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert);
index ff20fde76645136955f89786b79d3891804e4a0a..d2f746a7ca3eae245501fafc6a6bf95fae7be85d 100644 (file)
@@ -171,6 +171,7 @@ typedef struct{
 
 #define CMD_READER_MIFARE                                                 0x0611
 #define CMD_MIFARE_NESTED                                                 0x0612
+#define CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES                               0x0613
 
 #define CMD_MIFARE_READBL                                                 0x0620
 #define CMD_MIFAREU_READBL                                                0x0720
Impressum, Datenschutz