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

Merge remote-tracking branch 'noproto/nestednonces' into dev

This commit is contained in:
MX
2024-10-26 01:37:44 +03:00
4 changed files with 21 additions and 13 deletions

View File

@@ -45,6 +45,7 @@ static void dict_attack_draw_callback(Canvas* canvas, void* model) {
furi_string_set(m->header, "PRNG Analysis"); furi_string_set(m->header, "PRNG Analysis");
break; break;
case MfClassicNestedPhaseDictAttack: case MfClassicNestedPhaseDictAttack:
case MfClassicNestedPhaseDictAttackVerify:
case MfClassicNestedPhaseDictAttackResume: case MfClassicNestedPhaseDictAttackResume:
furi_string_set(m->header, "Nested Dictionary"); furi_string_set(m->header, "Nested Dictionary");
break; break;
@@ -91,6 +92,7 @@ static void dict_attack_draw_callback(Canvas* canvas, void* model) {
float dict_progress = 0; float dict_progress = 0;
if(m->nested_phase == MfClassicNestedPhaseAnalyzePRNG || if(m->nested_phase == MfClassicNestedPhaseAnalyzePRNG ||
m->nested_phase == MfClassicNestedPhaseDictAttack || m->nested_phase == MfClassicNestedPhaseDictAttack ||
m->nested_phase == MfClassicNestedPhaseDictAttackVerify ||
m->nested_phase == MfClassicNestedPhaseDictAttackResume) { m->nested_phase == MfClassicNestedPhaseDictAttackResume) {
// Phase: Nested dictionary attack // Phase: Nested dictionary attack
uint8_t target_sector = uint8_t target_sector =

View File

@@ -1881,9 +1881,10 @@ NfcCommand mf_classic_poller_handler_nested_controller(MfClassicPoller* instance
uint16_t dict_target_key_max = (dict_attack_ctx->prng_type == MfClassicPrngTypeWeak) ? uint16_t dict_target_key_max = (dict_attack_ctx->prng_type == MfClassicPrngTypeWeak) ?
(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 == MfClassicNestedPhaseDictAttackVerify) {
if(!(mf_classic_nested_is_target_key_found(instance, true)) && if(!(mf_classic_nested_is_target_key_found(instance, true)) &&
(dict_attack_ctx->nested_nonce.count > 0)) { (dict_attack_ctx->nested_nonce.count > 0)) {
dict_attack_ctx->nested_phase = MfClassicNestedPhaseDictAttackResume;
instance->state = MfClassicPollerStateNestedDictAttack; instance->state = MfClassicPollerStateNestedDictAttack;
return command; return command;
} else { } else {
@@ -1898,7 +1899,8 @@ NfcCommand mf_classic_poller_handler_nested_controller(MfClassicPoller* instance
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_phase == MfClassicNestedPhaseDictAttackResume) &&
(dict_attack_ctx->nested_target_key < dict_target_key_max)) { (dict_attack_ctx->nested_target_key < dict_target_key_max)) {
bool is_last_iter_for_hard_key = bool is_last_iter_for_hard_key =
((!is_weak) && ((dict_attack_ctx->nested_target_key % 8) == 7)); ((!is_weak) && ((dict_attack_ctx->nested_target_key % 8) == 7));
@@ -1922,11 +1924,14 @@ NfcCommand mf_classic_poller_handler_nested_controller(MfClassicPoller* instance
NULL; NULL;
} }
if((is_weak || is_last_iter_for_hard_key) && dict_attack_ctx->nested_nonce.count > 0) { if((is_weak || is_last_iter_for_hard_key) && dict_attack_ctx->nested_nonce.count > 0) {
// Key reuse // Key verify and reuse
dict_attack_ctx->nested_phase = MfClassicNestedPhaseDictAttackResume; dict_attack_ctx->nested_phase = MfClassicNestedPhaseDictAttackVerify;
dict_attack_ctx->auth_passed = false; dict_attack_ctx->auth_passed = false;
instance->state = MfClassicPollerStateKeyReuseStartNoOffset; instance->state = MfClassicPollerStateKeyReuseStartNoOffset;
return command; return command;
} else if(dict_attack_ctx->nested_phase == MfClassicNestedPhaseDictAttackResume) {
dict_attack_ctx->nested_phase = MfClassicNestedPhaseDictAttack;
dict_attack_ctx->auth_passed = true;
} }
if(!(dict_attack_ctx->auth_passed)) { if(!(dict_attack_ctx->auth_passed)) {
dict_attack_ctx->attempt_count++; dict_attack_ctx->attempt_count++;

View File

@@ -52,14 +52,15 @@ typedef enum {
* @brief MfClassic poller nested attack phase. * @brief MfClassic poller nested attack phase.
*/ */
typedef enum { typedef enum {
MfClassicNestedPhaseNone, MfClassicNestedPhaseNone, /**< No nested attack has taken place yet. */
MfClassicNestedPhaseAnalyzePRNG, MfClassicNestedPhaseAnalyzePRNG, /**< Analyze nonces produced by the PRNG to determine if they fit a weak PRNG */
MfClassicNestedPhaseDictAttack, MfClassicNestedPhaseDictAttack, /**< Search keys which match the expected PRNG properties and parity for collected nonces */
MfClassicNestedPhaseDictAttackResume, MfClassicNestedPhaseDictAttackVerify, /**< Verify candidate keys by authenticating to the sector with the key */
MfClassicNestedPhaseCalibrate, MfClassicNestedPhaseDictAttackResume, /**< Resume nested dictionary attack from the last tested (invalid) key */
MfClassicNestedPhaseRecalibrate, MfClassicNestedPhaseCalibrate, /**< Perform necessary calculations to recover the plaintext nonce during later collection phase (weak PRNG tags only) */
MfClassicNestedPhaseCollectNtEnc, MfClassicNestedPhaseRecalibrate, /**< Collect the next plaintext static encrypted nonce for backdoor static encrypted nonce nested attack */
MfClassicNestedPhaseFinished, MfClassicNestedPhaseCollectNtEnc, /**< Log nonces collected during nested authentication for key recovery */
MfClassicNestedPhaseFinished, /**< Nested attack has finished */
} MfClassicNestedPhase; } MfClassicNestedPhase;
/** /**

View File

@@ -5,7 +5,7 @@
#include <nfc/helpers/iso14443_crc.h> #include <nfc/helpers/iso14443_crc.h>
#define TAG "MfCLassicPoller" #define TAG "MfClassicPoller"
MfClassicError mf_classic_process_error(Iso14443_3aError error) { MfClassicError mf_classic_process_error(Iso14443_3aError error) {
MfClassicError ret = MfClassicErrorNone; MfClassicError ret = MfClassicErrorNone;