1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 12:42:30 +04:00

Update found keys, second attempt

This commit is contained in:
noproto
2024-08-20 16:33:13 -04:00
parent bbc10cdfaf
commit 75a0e4bc9d
2 changed files with 35 additions and 34 deletions

View File

@@ -729,9 +729,6 @@ NfcCommand mf_classic_poller_handler_key_reuse_auth_key_a(MfClassicPoller* insta
instance, block, &dict_attack_ctx->current_key, MfClassicKeyTypeA, NULL); instance, block, &dict_attack_ctx->current_key, MfClassicKeyTypeA, NULL);
if(error == MfClassicErrorNone) { if(error == MfClassicErrorNone) {
FURI_LOG_I(TAG, "Key A found"); FURI_LOG_I(TAG, "Key A found");
if(dict_attack_ctx->nested_phase == MfClassicNestedPhaseDictAttackResume) {
dict_attack_ctx->reuse_success = true;
}
mf_classic_set_key_found( mf_classic_set_key_found(
instance->data, dict_attack_ctx->reuse_key_sector, MfClassicKeyTypeA, key); instance->data, dict_attack_ctx->reuse_key_sector, MfClassicKeyTypeA, key);
@@ -768,9 +765,6 @@ NfcCommand mf_classic_poller_handler_key_reuse_auth_key_b(MfClassicPoller* insta
instance, block, &dict_attack_ctx->current_key, MfClassicKeyTypeB, NULL); instance, block, &dict_attack_ctx->current_key, MfClassicKeyTypeB, NULL);
if(error == MfClassicErrorNone) { if(error == MfClassicErrorNone) {
FURI_LOG_I(TAG, "Key B found"); FURI_LOG_I(TAG, "Key B found");
if(dict_attack_ctx->nested_phase == MfClassicNestedPhaseDictAttackResume) {
dict_attack_ctx->reuse_success = true;
}
mf_classic_set_key_found( mf_classic_set_key_found(
instance->data, dict_attack_ctx->reuse_key_sector, MfClassicKeyTypeB, key); instance->data, dict_attack_ctx->reuse_key_sector, MfClassicKeyTypeB, key);
@@ -1613,12 +1607,26 @@ NfcCommand mf_classic_poller_handler_nested_controller(MfClassicPoller* instance
(instance->sectors_total * 2) : (instance->sectors_total * 2) :
(instance->sectors_total * 16); (instance->sectors_total * 16);
if(dict_attack_ctx->nested_phase == MfClassicNestedPhaseDictAttackResume) { if(dict_attack_ctx->nested_phase == MfClassicNestedPhaseDictAttackResume) {
if(!(dict_attack_ctx->reuse_success)) { bool is_weak = dict_attack_ctx->prng_type == MfClassicPrngTypeWeak;
MfClassicKeyType target_key_type =
(((is_weak) && ((dict_attack_ctx->nested_target_key % 2) == 0)) ||
((!is_weak) && ((dict_attack_ctx->nested_target_key % 16) < 8))) ?
MfClassicKeyTypeA :
MfClassicKeyTypeB;
uint8_t target_sector = (is_weak) ? (dict_attack_ctx->nested_target_key / 2) :
(dict_attack_ctx->nested_target_key / 16);
if(!(mf_classic_is_key_found(instance->data, target_sector, target_key_type))) {
instance->state = MfClassicPollerStateNestedDictAttack; instance->state = MfClassicPollerStateNestedDictAttack;
return command; return command;
} } else {
dict_attack_ctx->auth_passed = true;
furi_assert(dict_attack_ctx->nested_nonce.nonces);
free(dict_attack_ctx->nested_nonce.nonces);
dict_attack_ctx->nested_nonce.nonces = NULL;
dict_attack_ctx->nested_nonce.count = 0;
dict_attack_ctx->nested_phase = MfClassicNestedPhaseDictAttack; dict_attack_ctx->nested_phase = MfClassicNestedPhaseDictAttack;
} }
}
if((dict_attack_ctx->nested_phase == MfClassicNestedPhaseDictAttack) && if((dict_attack_ctx->nested_phase == MfClassicNestedPhaseDictAttack) &&
(dict_attack_ctx->nested_target_key < dict_target_key_max)) { (dict_attack_ctx->nested_target_key < dict_target_key_max)) {
bool is_weak = dict_attack_ctx->prng_type == MfClassicPrngTypeWeak; bool is_weak = dict_attack_ctx->prng_type == MfClassicPrngTypeWeak;
@@ -1633,14 +1641,7 @@ NfcCommand mf_classic_poller_handler_nested_controller(MfClassicPoller* instance
} }
if(!(dict_attack_ctx->auth_passed)) { if(!(dict_attack_ctx->auth_passed)) {
dict_attack_ctx->attempt_count++; dict_attack_ctx->attempt_count++;
} else if(dict_attack_ctx->auth_passed || dict_attack_ctx->reuse_success) { } else if(dict_attack_ctx->auth_passed) {
if(dict_attack_ctx->reuse_success) {
furi_assert(dict_attack_ctx->nested_nonce.nonces);
free(dict_attack_ctx->nested_nonce.nonces);
dict_attack_ctx->nested_nonce.nonces = NULL;
dict_attack_ctx->nested_nonce.count = 0;
dict_attack_ctx->reuse_success = false;
}
dict_attack_ctx->nested_target_key++; dict_attack_ctx->nested_target_key++;
dict_attack_ctx->attempt_count = 0; dict_attack_ctx->attempt_count = 0;
} }
@@ -1654,8 +1655,7 @@ NfcCommand mf_classic_poller_handler_nested_controller(MfClassicPoller* instance
} }
dict_attack_ctx->nested_target_key = 0; dict_attack_ctx->nested_target_key = 0;
if(mf_classic_is_card_read(instance->data)) { if(mf_classic_is_card_read(instance->data)) {
// TODO: Ensure this works // All keys have been collected
// All keys have been collected, skip to reading blocks
FURI_LOG_E(TAG, "All keys collected and sectors read"); FURI_LOG_E(TAG, "All keys collected and sectors read");
dict_attack_ctx->nested_phase = MfClassicNestedPhaseFinished; dict_attack_ctx->nested_phase = MfClassicNestedPhaseFinished;
instance->state = MfClassicPollerStateSuccess; instance->state = MfClassicPollerStateSuccess;
@@ -1665,6 +1665,7 @@ NfcCommand mf_classic_poller_handler_nested_controller(MfClassicPoller* instance
instance->state = MfClassicPollerStateNestedController; instance->state = MfClassicPollerStateNestedController;
return command; return command;
} }
if(dict_attack_ctx->attempt_count == 0) {
// Check if the nested target key is a known key // Check if the nested target key is a known key
MfClassicKeyType target_key_type = MfClassicKeyType target_key_type =
(((is_weak) && ((dict_attack_ctx->nested_target_key % 2) == 0)) || (((is_weak) && ((dict_attack_ctx->nested_target_key % 2) == 0)) ||
@@ -1679,6 +1680,7 @@ NfcCommand mf_classic_poller_handler_nested_controller(MfClassicPoller* instance
instance->state = MfClassicPollerStateNestedController; instance->state = MfClassicPollerStateNestedController;
return command; return command;
} }
}
if(dict_attack_ctx->attempt_count >= 3) { if(dict_attack_ctx->attempt_count >= 3) {
// Unpredictable, skip // Unpredictable, skip
FURI_LOG_E(TAG, "Failed to collect nonce, skipping key"); FURI_LOG_E(TAG, "Failed to collect nonce, skipping key");
@@ -1757,8 +1759,8 @@ NfcCommand mf_classic_poller_handler_nested_controller(MfClassicPoller* instance
instance->state = MfClassicPollerStateNestedCollectNtEnc; instance->state = MfClassicPollerStateNestedCollectNtEnc;
return command; return command;
} }
// TODO: If we've recovered all keys, read blocks and go to complete dict_attack_ctx->nested_phase = MfClassicNestedPhaseFinished;
instance->state = MfClassicPollerStateKeyReuseStart; instance->state = MfClassicPollerStateSuccess;
return command; return command;
} }

View File

@@ -134,7 +134,6 @@ typedef struct {
MfClassicKey current_key; MfClassicKey current_key;
MfClassicKeyType current_key_type; MfClassicKeyType current_key_type;
bool auth_passed; bool auth_passed;
bool reuse_success;
uint16_t current_block; uint16_t current_block;
uint8_t reuse_key_sector; uint8_t reuse_key_sector;
// Enhanced dictionary attack and nested nonce collection // Enhanced dictionary attack and nested nonce collection