diff --git a/lib/nfc/protocols/mf_classic/mf_classic_poller.c b/lib/nfc/protocols/mf_classic/mf_classic_poller.c index 8b690cf1b..04d92b401 100644 --- a/lib/nfc/protocols/mf_classic/mf_classic_poller.c +++ b/lib/nfc/protocols/mf_classic/mf_classic_poller.c @@ -916,7 +916,14 @@ NfcCommand mf_classic_poller_handler_nested_analyze_backdoor(MfClassicPoller* in MfClassicAuthContext auth_ctx = {}; MfClassicNt nt = {}; - MfClassicKey auth2_backdoor_key = {.data = {0xa3, 0x96, 0xef, 0xa4, 0xe2, 0x4f}}; + MfClassicKey auth_backdoor_key; + if(dict_attack_ctx->nested_target_key == 1) { + auth_backdoor_key = (MfClassicKey){ + .data = {0xa3, 0x96, 0xef, 0xa4, 0xe2, 0x4f}}; // auth2 backdoor key, more common + } else { + auth_backdoor_key = + (MfClassicKey){.data = {0xa3, 0x16, 0x67, 0xa8, 0xce, 0xc1}}; // auth1 backdoor key + } MfClassicError error; Iso14443_3aError iso_error; bool backdoor_found = false; @@ -961,13 +968,17 @@ NfcCommand mf_classic_poller_handler_nested_analyze_backdoor(MfClassicPoller* in bit_buffer_write_bytes(instance->rx_plain_buffer, nt.data, sizeof(MfClassicNt)); uint32_t nt_enc = bit_lib_bytes_to_num_be(nt.data, sizeof(MfClassicNt)); // Ensure the encrypted nt can be generated by the backdoor - uint32_t decrypted_nt_enc = decrypt_nt_enc(cuid, nt_enc, auth2_backdoor_key); + uint32_t decrypted_nt_enc = decrypt_nt_enc(cuid, nt_enc, auth_backdoor_key); backdoor_found = is_weak_prng_nonce(decrypted_nt_enc); } while(false); if(backdoor_found) { FURI_LOG_E(TAG, "Backdoor identified"); - dict_attack_ctx->backdoor = MfClassicBackdoorAuth2; - } else { + if(dict_attack_ctx->nested_target_key == 1) { + dict_attack_ctx->backdoor = MfClassicBackdoorAuth2; + } else { + dict_attack_ctx->backdoor = MfClassicBackdoorAuth1; + } + } else if(dict_attack_ctx->nested_target_key == 0) { dict_attack_ctx->backdoor = MfClassicBackdoorNone; } instance->state = MfClassicPollerStateNestedController; @@ -1708,14 +1719,15 @@ NfcCommand mf_classic_poller_handler_nested_controller(MfClassicPoller* instance if(dict_attack_ctx->mf_classic_user_dict) { keys_dict_free(dict_attack_ctx->mf_classic_user_dict); } - dict_attack_ctx->nested_target_key = 0; if(mf_classic_is_card_read(instance->data)) { // All keys have been collected FURI_LOG_E(TAG, "All keys collected and sectors read"); + dict_attack_ctx->nested_target_key = 0; dict_attack_ctx->nested_phase = MfClassicNestedPhaseFinished; instance->state = MfClassicPollerStateSuccess; return command; } + dict_attack_ctx->nested_target_key = 2; // Backdoor keys dict_attack_ctx->nested_phase = MfClassicNestedPhaseAnalyzeBackdoor; instance->state = MfClassicPollerStateNestedController; return command; @@ -1739,9 +1751,11 @@ NfcCommand mf_classic_poller_handler_nested_controller(MfClassicPoller* instance } // Analyze tag for NXP/Fudan backdoor if(dict_attack_ctx->backdoor == MfClassicBackdoorUnknown) { + dict_attack_ctx->nested_target_key--; instance->state = MfClassicPollerStateNestedAnalyzeBackdoor; return command; } else if(dict_attack_ctx->nested_phase == MfClassicNestedPhaseAnalyzeBackdoor) { + dict_attack_ctx->nested_target_key = 0; dict_attack_ctx->nested_phase = MfClassicNestedPhaseCalibrate; } // TODO: Need to think about how this works for NXP/Fudan backdoored tags.