espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.62k stars 7.27k forks source link

WPA2 enterprise PEAP/MSCHAPv2 not working on IDF release v4.2.2 (IDFGH-5662) #7384

Closed maranhao closed 3 years ago

maranhao commented 3 years ago

Environment

Problem Description

WPA supplicant fails logging on wireless network using WPA2 enterprise with PEAP/MSCHAPv2 login method on IDF release version v4.2.2.

I wanted to update the IDF version we are working on because it solves some issues we stumbled upon, but it fails on the WPA2 enterprise scenario we face in a client. We must connect to a WPA2 enterprise with RADIUS server running on a windows server, and have a scenario replica here. We are not verifying the server certificate to avoid having to input the certificate in every unit.

The server is configured to PEAP/MSCHAPv2, and in our current test we are using a 3com access point as an example. The certificate is self-generated.

Having failed the tests, I have set up in dev kits the WPA2 example code from both IDF versions: the one we have already deployed and works (master commit a45e9985344575a80acb1dc9c12e7bec4d8af401), and several versions of the v4.2 (on this test I used the latest available on the branch (Commit: 45330303d6d04aaf683c66181851497f66a4ec22) because it already solved the crash when it fails).

Follow attached the logs from both scenarios.

wpa2_success.log wpa2_fail.log

Thanks.

Alvin1Zhang commented 3 years ago

Thanks for reporting and letting us know, we will look into.

nishanth-radja commented 3 years ago

@maranhao From the logs, Looks like the client is not sending out client hello in the fail case.can we have the radius logs and the sniffer capture during the failure scenario.We were not able to repro the issue in our setup so far.What is the size of the cert you are using, Is it 4k?

maranhao commented 3 years ago

Thanks for the feedback. We use a 2048 RSA SHA1 certificate, generated from the CA on the windows server. I collected the requested information from the server and sniffing the network, follow logs:

success_log_server.log success_wireshark.zip error_log_server.log error_wireshark.zip

nishanth-radja commented 3 years ago

@maranhao From the logs, Looks like the client is not sending out client hello in the fail case.can we have the radius logs and the sniffer capture during the failure scenario.We were not able to repro the issue in our setup so far.What is the size of the cert you are using, Is it 4k?

nishanth-radja commented 3 years ago

@maranhao Thanks for the logs, From the logs we could see that the in the PASS case,TLS 1.0 version is used with different sets of cipher suits,where as in Fail case TLS 1.2 was used with different sets of cipher suits.We need to analyse the client hello to understand the chipher suite the radius server is choosing. Can we get the wireless capture during the failure,This can be taken from the laptop. (Enable monitor mode on wireless interface and start wireshark). Also if possible,can we have the certs used.We can try out with the same certs.

maranhao commented 3 years ago

I will need some help on how I should be sniffing that. A notebook should be connected on the same AP that the device is trying to request access? I did not manage to sniff anything yet, or I did not successfully enable the monitor mode.

Follow the certificate: CA_certificate.zip

nishanth-radja commented 3 years ago

@maranhao ,The laptop need not be connected to the AP. If you are using an ubuntu laptop, Pls use this script Disconnect the laptop from any wireless network and make sure it does not re associate to any AP and type the following commands. "ifconfig "wireless Interface name" down iwconfig "wireless Interface" mode monitor ifconfig "wireless Interface" up iwconfig "wireless Interface" channel "ap channel" wireshark"

If you have a MAC laptop: press the option key on the MAC laptop and click on the wireless option on the screen and follow the recorded steps. I have recorded the steps here "https://drive.google.com/file/d/1g7CbRr7Zp699UKcTTkdW0L8XI7vu_i3l/view?usp=sharing"

If you have a windows laptop: you can use this link and try, "https://blog.packet-foo.com/2019/04/wireless-capture-on-windows/" It is easier if you have a ubuntu or MAC laptop for capture.

NorbertoNorbs commented 3 years ago

I just posted a issue that maybe related to the problem you are having (https://github.com/espressif/esp-idf/issues/7422) you may want to try the fix I shown there to see if it solves the problem.

maranhao commented 3 years ago

I finally managed to sniff the raw packets using kali + a wifi usb dongle, follow files:

failure_80211raw.pcapng.tar.gz wlan.addr==3c:71:bf:9d:77:5c

success_80211raw.pcapng.tar.gz wlan.addr==3c:71:bf:6a:48:dc

maranhao commented 3 years ago

I just posted a issue that maybe related to the problem you are having (#7422) you may want to try the fix I shown there to see if it solves the problem.

Thanks, I will check it.

maranhao commented 3 years ago

@NorbertoNorbs it sure changes the behavior, but mine is still taking a different path close to the end of the negotiation. I checked out on idf v4.3 to try to use the same distro as you, but I noticed that the lines differ on the debug. Can you confirm which IDF commit you are using? Thanks.

NorbertoNorbs commented 3 years ago

@maranhao idf.py --version shows 'ESP-IDF v4.3', I didn't use git to download the latest commit, I used the Eclipse internal download tool which downloads the latest release version (https://github.com/espressif/esp-idf/tree/release/v4.3).

But I discovered the problem first testing on version 4.2.2, when I fixed it there I changed the same file on 4.3 and it worked also.

I'm taking the time to debug WPA Enterprise issues since that's what most of my costumers uses, If you want to post the new log messages after you applied the fix I can check them for you. Be sure to enable mbedtls logs also (components->mbedTLS->Enable mbedTLS debugging).

maranhao commented 3 years ago

@NorbertoNorbs Long story short, what I found out is the modification you made cuts it for SHA256, but something else is letting this SHA1 certificate I generated at first hanging, so it times out and restarts endlessly.

I will try to get some meaningful logs, but for now I will check with my clients the kind of certificate they are using and maybe stick with v4.1 for a while.

I also managed to see it stopped working between idf v4.1 and v4.1.1 and to narrow it down to ~23-26oct 2020 (it worked before 976dc42), but could not get it back to work without reverting the full supplicant changes between the two releases.

NorbertoNorbs commented 3 years ago

@maranhao You are right about the certificate, I was able to reproduce the issue you are having by using a sha1 certificate, I had a sha384 initially, I tested also with sha256 and it worked but not with sha1.

I think I found what changed, it boils down to the TLS client ESP is using, in idf version 4.1 it uses a internal client (Although in wpa supplicant settings it has a option to use mbedtls which is enabled by default) in 4.2.2 it does uses mbedtls client.

In order to replicate the 4.1 behavior in 4.2.2+ you have to disable mbedtls in wpa supplicant, after doing this it will go back to using the internal client (After doing this it worked for me).

But if you do that it will not work with sha384 certificate.

To me this is a problem because I have costumers that uses both, so if I fix for sha1 it will not work for sha384, so I'll further investigate this issue.

kapilkedawat commented 3 years ago

Hi @NorbertoNorbs , Can you please try https://github.com/espressif/esp-idf/commit/e8360fe0756ec592cbd5f4ff4d36946a22561d8f on this with SHA1 certificates? We are unable to reproduce this issue.

Please enable logging of wpa_supplicant and mbedtls as well while trying out this.

NorbertoNorbs commented 3 years ago

Hi @kapilkedawat, what I found out is that the sha1 problem was related to '1/1-n splitting' work around for BEAST Attack, the test with sha1 certificate was done using a NPS in a Windows 2008, I don't know if this is a Windows problem, It seems that a early split message is accepted by the server but it just hangs on another and I see the message 'Network Police Server discarded the request for a user' in the server log, disabling this work around in the ESP32 worked.

I tried https://github.com/espressif/esp-idf/commit/e8360fe0756ec592cbd5f4ff4d36946a22561d8f with the same result.

This may be a unrelated issue, but I'm attaching the log for both cases. wpa sha1 Win2008 mbedtls fail.TXT wpa sha1 Win2008 mbedtls no spliting success.TXT

kapilkedawat commented 3 years ago

Hi @NorbertoNorbs , Seems like this is a known issue in windows 2008: https://community.progress.com/s/article/BEAST-Vulnerability

We don't have windows server 2008 to try this presently and will try to check this in near future. However I would suggest to use alternate fixes provided in the article instead of disabling the workaround and see if those work(use TLS1.1?).

NorbertoNorbs commented 3 years ago

@kapilkedawat Thanks for your reply, I guessed it would be a windows issue. I tested in windows 2008 because I had a VW with it already installed but, in retrospect, since this is a old operating system, I don't think one should bother, I don't believe someone will used it in a security application like enterprise Wi-Fi.

Thanks again.

kapilkedawat commented 3 years ago

Hi @NorbertoNorbs , is it possible for you to test this using any other device besides esp32(any current mobile device will suffice). We would like to see whether this is failing for other devices as well?

NorbertoNorbs commented 3 years ago

Hello @kapilkedawat, of course, I was able to successfully connect from a Android device. Since my setup was still running I fired a Ubuntu virtual machine and tried from there also with success, I captured the Ubuntu supplicant logs and network packets.

I performed the test with the version you mention but The ESP communication just hangs as before, I tried disabling TLS1.0 in the ESP but then another error happens.

I couldn't figure if Ubuntu is using record splitting which seems to be related to the root cause.

Please note that the network capture was done in the host of the virtual machine running the Windows 2008 NPS, so you will not see the packets as 'in the air' but encapsulated in the RADIUS messages between the wi-fi router and the server.

Bunch of WPA logs for my friends.zip

kapilkedawat commented 3 years ago

Thanks @NorbertoNorbs, appreciate it.

Is it possible for you to try with following change and see if that works as expected?

diff --git a/components/wpa_supplicant/src/crypto/tls_mbedtls.c b/components/wpa_supplicant/src/crypto/tls_mbedtls.c index 9db60867ad..ebc02357a7 100644 --- a/components/wpa_supplicant/src/crypto/tls_mbedtls.c +++ b/components/wpa_supplicant/src/crypto/tls_mbedtls.c @@ -231,6 +231,8 @@ static void tls_enable_sha1_config(tls_context_t tls) const mbedtls_x509_crt_profile crt_profile = &eap_mbedtls_x509_crt_profile; mbedtls_ssl_conf_cert_profile(&tls->conf, crt_profile); mbedtls_ssl_conf_sig_hashes(&tls->conf, tls_sig_hashes_for_eap);

NorbertoNorbs commented 3 years ago

Hi @kapilkedawat Adding this line works and I'm able to connect with success. Just one detail: if I add this line with TLS1.0 disabled the project won't compile.

kapilkedawat commented 3 years ago

Hi @NorbertoNorbs thanks for confirming. Compilation issue was expected since this API needs to be called under MBEDTLS_SSL_CBC_RECORD_SPLITTING macro.

Just to update, I didn't find any article about beast attack affecting WPA-EAP session and it should be safe to disable this. This was only known to affect older browser extensions. You can read more about it here https://access.redhat.com/security/cve/CVE-2011-3389 .

This fix will be available in IDF in some days. Thanks again for helping out to test this :).

NorbertoNorbs commented 3 years ago

Hi @kapilkedawat You are right, I've done some research and it's not feasible to use this attack on WPA supplicant, in order for this to work an attacker needs a lot more packets than is exchanged in the handshake procedure and it appears to be possible only in HTTP requests because HTTP content is somewhat predictable, so I think it's safe to disable it. Thanks again.