From 1c28ca1335da8293b3bd2c37dc1e48dcc8146de4 Mon Sep 17 00:00:00 2001 From: feitoi <40636007+feitoi@users.noreply.github.com> Date: Tue, 2 May 2023 21:49:34 -0300 Subject: [PATCH] Tracks how many times timeouts with deauth request without NACK Automatically treat the timeout as NACK if receive deauth request while waiting for M5/M7 when deauth_is_nack_count >= MAX_DEAUTH_IS_NACK_COUNT and it have never received WSC_NACK. The count value is stored in .wpc file, the -1 equal the AP sends NACK. --- src/argsparser.c | 1 + src/defs.h | 2 ++ src/exchange.c | 26 +++++++++++++++++++++----- src/globule.c | 9 +++++++++ src/globule.h | 4 ++++ src/session.c | 8 ++++++++ 6 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/argsparser.c b/src/argsparser.c index 7b99aea..8740281 100644 --- a/src/argsparser.c +++ b/src/argsparser.c @@ -235,6 +235,7 @@ void init_default_settings(void) pixie.do_pixie = 0; set_pin_string_mode(0); set_mac_changer(0); + set_deauth_is_nack_count(0); } /* Parses the recurring delay optarg */ diff --git a/src/defs.h b/src/defs.h index dfb776b..a63d68a 100644 --- a/src/defs.h +++ b/src/defs.h @@ -79,6 +79,8 @@ #define EAPOL_START_MAX_TRIES 10 #define WARN_FAILURE_COUNT 10 +#define MAX_DEAUTH_IS_NACK_COUNT 10 + #define EAPOL_START 1 #define EAP_IDENTITY 0x01 #define EAP_EXPANDED 0xFE diff --git a/src/exchange.c b/src/exchange.c index 128dbac..82c8577 100644 --- a/src/exchange.c +++ b/src/exchange.c @@ -229,6 +229,7 @@ enum wps_result do_wps_exchange() { /* The AP is properly sending WSC_NACKs, so don't treat future timeouts as pin failures. */ set_timeout_is_nack(0); + set_deauth_is_nack_count(-1); ret_val = KEY_REJECTED; @@ -267,16 +268,31 @@ enum wps_result do_wps_exchange() (last_msg == M3 || last_msg == M5)) { ret_val = KEY_REJECTED; - /* Got timeout instead of an M5 message, when cracking second half */ - if (!get_pin_string_mode() && last_msg == M3 && get_key_status() == KEY2_WIP) { - ret_val = UNKNOWN_ERROR; - cprintf(WARNING, "[!] WARNING: Potential first half pin has changed!\n"); - } + } + /* + * Some WPS implementations sending deauth request instead of sending a NACK. + * Treat the timeout as NACK if receive deauth request while waiting for M5/M7. + */ + else if (deauth_flag && (last_msg == M3 || last_msg == M5) + && get_deauth_is_nack_count() >= MAX_DEAUTH_IS_NACK_COUNT) + { + ret_val = KEY_REJECTED; } else { /* If we timed out at any other point in the session, then we need to try the pin again */ ret_val = RX_TIMEOUT; + /* increase by 1 for timeout with deauth request without NACK count value */ + if (deauth_flag && (last_msg == M3 || last_msg == M5) + && get_deauth_is_nack_count() >= 0 && get_deauth_is_nack_count() < MAX_DEAUTH_IS_NACK_COUNT) + { + set_deauth_is_nack_count(get_deauth_is_nack_count() + 1); + } + } + /* Got timeout instead of an M5 message when cracking second half */ + if (ret_val == KEY_REJECTED && !get_pin_string_mode() && last_msg == M3 && get_key_status() == KEY2_WIP) { + ret_val = UNKNOWN_ERROR; + cprintf(WARNING, "[!] WARNING: Potential first half pin has changed!\n"); } } /* diff --git a/src/globule.c b/src/globule.c index 6960f3b..200bbf5 100644 --- a/src/globule.c +++ b/src/globule.c @@ -526,6 +526,15 @@ enum nack_code get_nack_reason() return globule->nack_reason; } +void set_deauth_is_nack_count(int value) +{ + globule->deauth_is_nack_count = value; +} +int get_deauth_is_nack_count() +{ + return globule->deauth_is_nack_count; +} + void set_handle(pcap_t *value) { globule->handle = value; diff --git a/src/globule.h b/src/globule.h index 378958e..69773d5 100644 --- a/src/globule.h +++ b/src/globule.h @@ -84,6 +84,8 @@ struct globals int timeout_is_nack; /* Treat M5/M7 receive timeouts as NACKs (only needed for shoddy WPS implementations) */ + int deauth_is_nack_count; /* Tracks how many times M5/M7 receive timeouts with deauth request without NACK. -1: AP sends NACK */ + int m57_timeout; /* Timeout period for receiving an M5/M7 response (uSeconds) */ int out_of_time; /* Set to 1 when sigalrm sounds */ @@ -252,6 +254,8 @@ void set_external_association(int value); int get_external_association(void); void set_nack_reason(enum nack_code value); enum nack_code get_nack_reason(); +void set_deauth_is_nack_count(int value); +int get_deauth_is_nack_count(); void set_handle(pcap_t *value); pcap_t *get_handle(); void set_wps(struct wps_data *value); diff --git a/src/session.c b/src/session.c index 1fb4dce..562f89f 100644 --- a/src/session.c +++ b/src/session.c @@ -185,6 +185,11 @@ int restore_session() } } + /* Get the timeout with deauth request without NACKs count value */ + if (fgets(line, MAX_LINE_SIZE, fp) != NULL) { + set_deauth_is_nack_count(atoi(line)); + } + return ret_val; } @@ -240,6 +245,9 @@ int save_session() /* Save all the p2 values */ for(i=0; i