ソースを参照

[FL-3156] Mark keys as not found when they couldn't auth successfully (#2476)

* Mark keys as not found when they couldn't auth successfully
* Improve logging and fix the reading bug

Co-authored-by: あく <alleteam@gmail.com>
Astra 2 年 前
コミット
e90042368f
2 ファイル変更33 行追加6 行削除
  1. 11 2
      lib/nfc/nfc_worker.c
  2. 22 4
      lib/nfc/protocols/mifare_classic.c

+ 11 - 2
lib/nfc/nfc_worker.c

@@ -739,7 +739,7 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
                     if(mf_classic_authenticate_skip_activate(
                     if(mf_classic_authenticate_skip_activate(
                            &tx_rx, block_num, key, MfClassicKeyA, !deactivated, cuid)) {
                            &tx_rx, block_num, key, MfClassicKeyA, !deactivated, cuid)) {
                         mf_classic_set_key_found(data, i, MfClassicKeyA, key);
                         mf_classic_set_key_found(data, i, MfClassicKeyA, key);
-                        FURI_LOG_D(TAG, "Key found");
+                        FURI_LOG_D(TAG, "Key A found");
                         nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
                         nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
 
 
                         uint64_t found_key;
                         uint64_t found_key;
@@ -753,22 +753,31 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
                             }
                             }
 
 
                             nfc_worker_mf_classic_key_attack(nfc_worker, found_key, &tx_rx, i + 1);
                             nfc_worker_mf_classic_key_attack(nfc_worker, found_key, &tx_rx, i + 1);
+                            break;
                         }
                         }
                         nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1);
                         nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1);
                     }
                     }
                     furi_hal_nfc_sleep();
                     furi_hal_nfc_sleep();
                     deactivated = true;
                     deactivated = true;
+                } else {
+                    mf_classic_set_key_not_found(data, i, MfClassicKeyA);
+                    is_key_a_found = false;
+                    FURI_LOG_D(TAG, "Key %dA not found in attack", i);
                 }
                 }
                 if(!is_key_b_found) {
                 if(!is_key_b_found) {
                     is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB);
                     is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB);
                     if(mf_classic_authenticate_skip_activate(
                     if(mf_classic_authenticate_skip_activate(
                            &tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) {
                            &tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) {
-                        FURI_LOG_D(TAG, "Key found");
+                        FURI_LOG_D(TAG, "Key B found");
                         mf_classic_set_key_found(data, i, MfClassicKeyB, key);
                         mf_classic_set_key_found(data, i, MfClassicKeyB, key);
                         nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
                         nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
                         nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1);
                         nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1);
                     }
                     }
                     deactivated = true;
                     deactivated = true;
+                } else {
+                    mf_classic_set_key_not_found(data, i, MfClassicKeyB);
+                    is_key_b_found = false;
+                    FURI_LOG_D(TAG, "Key %dB not found in attack", i);
                 }
                 }
                 if(is_key_a_found && is_key_b_found) break;
                 if(is_key_a_found && is_key_b_found) break;
                 if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;
                 if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;

+ 22 - 4
lib/nfc/protocols/mifare_classic.c

@@ -651,7 +651,12 @@ void mf_classic_read_sector(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data, u
         if(!key_a_found) break;
         if(!key_a_found) break;
         FURI_LOG_D(TAG, "Try to read blocks with key A");
         FURI_LOG_D(TAG, "Try to read blocks with key A");
         key = nfc_util_bytes2num(sec_tr->key_a, sizeof(sec_tr->key_a));
         key = nfc_util_bytes2num(sec_tr->key_a, sizeof(sec_tr->key_a));
-        if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyA, &crypto, false, 0)) break;
+        if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyA, &crypto, false, 0)) {
+            mf_classic_set_key_not_found(data, sec_num, MfClassicKeyA);
+            FURI_LOG_D(TAG, "Key %dA not found in read", sec_num);
+            break;
+        }
+
         for(size_t i = start_block; i < start_block + total_blocks; i++) {
         for(size_t i = start_block; i < start_block + total_blocks; i++) {
             if(!mf_classic_is_block_read(data, i)) {
             if(!mf_classic_is_block_read(data, i)) {
                 if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
                 if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
@@ -660,7 +665,11 @@ void mf_classic_read_sector(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data, u
                 } else if(i > start_block) {
                 } else if(i > start_block) {
                     // Try to re-auth to read block in case prevous block was protected from read
                     // Try to re-auth to read block in case prevous block was protected from read
                     furi_hal_nfc_sleep();
                     furi_hal_nfc_sleep();
-                    if(!mf_classic_auth(tx_rx, i, key, MfClassicKeyA, &crypto, false, 0)) break;
+                    if(!mf_classic_auth(tx_rx, i, key, MfClassicKeyA, &crypto, false, 0)) {
+                        mf_classic_set_key_not_found(data, sec_num, MfClassicKeyA);
+                        FURI_LOG_D(TAG, "Key %dA not found in read", sec_num);
+                        break;
+                    }
                     if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
                     if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
                         mf_classic_set_block_read(data, i, &block_tmp);
                         mf_classic_set_block_read(data, i, &block_tmp);
                         blocks_read++;
                         blocks_read++;
@@ -680,7 +689,12 @@ void mf_classic_read_sector(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data, u
         }
         }
         FURI_LOG_D(TAG, "Try to read blocks with key B");
         FURI_LOG_D(TAG, "Try to read blocks with key B");
         key = nfc_util_bytes2num(sec_tr->key_b, sizeof(sec_tr->key_b));
         key = nfc_util_bytes2num(sec_tr->key_b, sizeof(sec_tr->key_b));
-        if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyB, &crypto, false, 0)) break;
+        if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyB, &crypto, false, 0)) {
+            mf_classic_set_key_not_found(data, sec_num, MfClassicKeyB);
+            FURI_LOG_D(TAG, "Key %dB not found in read", sec_num);
+            break;
+        }
+
         for(size_t i = start_block; i < start_block + total_blocks; i++) {
         for(size_t i = start_block; i < start_block + total_blocks; i++) {
             if(!mf_classic_is_block_read(data, i)) {
             if(!mf_classic_is_block_read(data, i)) {
                 if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
                 if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
@@ -689,7 +703,11 @@ void mf_classic_read_sector(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data, u
                 } else if(i > start_block) {
                 } else if(i > start_block) {
                     // Try to re-auth to read block in case prevous block was protected from read
                     // Try to re-auth to read block in case prevous block was protected from read
                     furi_hal_nfc_sleep();
                     furi_hal_nfc_sleep();
-                    if(!mf_classic_auth(tx_rx, i, key, MfClassicKeyB, &crypto, false, 0)) break;
+                    if(!mf_classic_auth(tx_rx, i, key, MfClassicKeyB, &crypto, false, 0)) {
+                        mf_classic_set_key_not_found(data, sec_num, MfClassicKeyB);
+                        FURI_LOG_D(TAG, "Key %dB not found in read", sec_num);
+                        break;
+                    }
                     if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
                     if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
                         mf_classic_set_block_read(data, i, &block_tmp);
                         mf_classic_set_block_read(data, i, &block_tmp);
                         blocks_read++;
                         blocks_read++;