From 40d62a5161fdfa4a96cbc20bed262c7c95adb05c Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Sat, 25 Jul 2020 12:45:44 -0700 Subject: [PATCH 1/3] CVE-2020-12638 workaround for WPA downgrade attack When connected to an encrypted (WEP/WPA) router, a rogue packet can cause the ESP8266 WiFi stack to drop to an unecrypted rogue network of the same SSID. Handle this by dropping the WiFi connection immediately and reconnecting to the stored WPA/WEP network requested by the application, whenever the AUTHMODE changes to OPEN from a secured mode. https://lbsfilm.at/blog/wpa2-authenticationmode-downgrade-in-espressif-microprocessors for more details. --- libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index e026ea760a..1c0eaef0ef 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -133,6 +133,12 @@ WiFiEventHandler ESP8266WiFiGenericClass::onStationModeAuthModeChanged(std::func WiFiEventHandler handler = std::make_shared(WIFI_EVENT_STAMODE_AUTHMODE_CHANGE, [f](System_Event_t* e){ auto& src = e->event_info.auth_change; WiFiEventStationModeAuthModeChanged dst; + if ((src.old_mode != AUTH_OPEN) && (src.new_mode == AUTH_OPEN)) { + // CVE-2020-12638 workaround. When we get a change to AUTH_OPEN from any other mode, drop the WiFi link because it's a downgrade attack + // TODO - When upgrading to 3.x.x with fix, remove this code + DEBUG_WIFI("WIFI_EVENT_STAMODE_AUTHMODE_CHANGE downgrade from %s to AUTH_OPEN, potential downgrade attack. Reconnecting WiFi. See CVE-2020-12638 for more details\n"); + WiFi.reconnect(); // Disconnects from STA and then reconnects + } dst.oldMode = src.old_mode; dst.newMode = src.new_mode; f(dst); From 8a7ad8e2854df5781303642c897c338fe4b9c531 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Sat, 25 Jul 2020 20:32:08 -0700 Subject: [PATCH 2/3] Fix the debug message --- libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index 1c0eaef0ef..908e1e72b9 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -136,7 +136,7 @@ WiFiEventHandler ESP8266WiFiGenericClass::onStationModeAuthModeChanged(std::func if ((src.old_mode != AUTH_OPEN) && (src.new_mode == AUTH_OPEN)) { // CVE-2020-12638 workaround. When we get a change to AUTH_OPEN from any other mode, drop the WiFi link because it's a downgrade attack // TODO - When upgrading to 3.x.x with fix, remove this code - DEBUG_WIFI("WIFI_EVENT_STAMODE_AUTHMODE_CHANGE downgrade from %s to AUTH_OPEN, potential downgrade attack. Reconnecting WiFi. See CVE-2020-12638 for more details\n"); + DEBUG_WIFI("WIFI_EVENT_STAMODE_AUTHMODE_CHANGE from encrypted(%d) to AUTH_OPEN, potential downgrade attack. Reconnecting WiFi. See CVE-2020-12638 for more details\n", src.old_mode); WiFi.reconnect(); // Disconnects from STA and then reconnects } dst.oldMode = src.old_mode; From f3342c307dedf7e87c86b11e28170bec373683b8 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Sat, 25 Jul 2020 20:43:44 -0700 Subject: [PATCH 3/3] Check for the downgrade in main WIFI event process The downgrade event needs to be looked for in the main WiFi event processing function instead of the callback function (which will only trigger if the user actually makes a callback themselves). --- libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index 908e1e72b9..abad142ed9 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -133,12 +133,6 @@ WiFiEventHandler ESP8266WiFiGenericClass::onStationModeAuthModeChanged(std::func WiFiEventHandler handler = std::make_shared(WIFI_EVENT_STAMODE_AUTHMODE_CHANGE, [f](System_Event_t* e){ auto& src = e->event_info.auth_change; WiFiEventStationModeAuthModeChanged dst; - if ((src.old_mode != AUTH_OPEN) && (src.new_mode == AUTH_OPEN)) { - // CVE-2020-12638 workaround. When we get a change to AUTH_OPEN from any other mode, drop the WiFi link because it's a downgrade attack - // TODO - When upgrading to 3.x.x with fix, remove this code - DEBUG_WIFI("WIFI_EVENT_STAMODE_AUTHMODE_CHANGE from encrypted(%d) to AUTH_OPEN, potential downgrade attack. Reconnecting WiFi. See CVE-2020-12638 for more details\n", src.old_mode); - WiFi.reconnect(); // Disconnects from STA and then reconnects - } dst.oldMode = src.old_mode; dst.newMode = src.new_mode; f(dst); @@ -234,6 +228,16 @@ void ESP8266WiFiGenericClass::_eventCallback(void* arg) WiFiClient::stopAll(); } + if (event->event == EVENT_STAMODE_AUTHMODE_CHANGE) { + auto& src = event->event_info.auth_change; + if ((src.old_mode != AUTH_OPEN) && (src.new_mode == AUTH_OPEN)) { + // CVE-2020-12638 workaround. When we get a change to AUTH_OPEN from any other mode, drop the WiFi link because it's a downgrade attack + // TODO - When upgrading to 3.x.x with fix, remove this code + DEBUG_WIFI("WIFI_EVENT_STAMODE_AUTHMODE_CHANGE from encrypted(%d) to AUTH_OPEN, potential downgrade attack. Reconnecting WiFi. See CVE-2020-12638 for more details\n", src.old_mode); + WiFi.reconnect(); // Disconnects from STA and then reconnects + } + } + for(auto it = std::begin(sCbEventList); it != std::end(sCbEventList); ) { WiFiEventHandler &handler = *it; if (handler->canExpire() && handler.unique()) {