ESP8266 And ESP32 WiFi Hacked!

[Matheus Garbelini] just came out with three (3!) different WiFi attacks on the popular ESP32/8266 family of chips. He notified Espressif first (thanks!) and they’ve patched around most of the vulnerabilities already, but if you’re running software on any of these chips that’s in a critical environment, you’d better push up new firmware pretty quick.

The first flaw is the simplest, and only effects ESP8266s. While connecting to an access point, the access point sends the ESP8266 an “AKM suite count” field that contains the number of authentication methods that are available for the connection. Because the ESP doesn’t do bounds-checking on this value, a malicious fake access point can send a large number here, probably overflowing a buffer, but definitely crashing the ESP. If you can send an ESP8266 a bogus beacon frame or probe response, you can crash it.

What’s most fun about the beacon frame crasher is that it can be implemented on an ESP8266 as well. Crash-ception! This takes advantage of the ESP’s packet injection mode, which we’ve covered before.

The second and third vulnerabilities exploit bugs in the way the ESP libraries handle the extensible authentication protocol (EAP) which is mostly used in enterprise and higher-security environments. One hack makes the ESP32 or ESP8266 on the EAP-enabled network crash, but the other hack allows for a complete hijacking of the encrypted session.

These EAP hacks are more troubling, and not just because session hijacking is more dangerous than a crash-DOS scenario. The ESP32 codebase has already been patched against them, but the older ESP8266 SDK has not yet. So as of now, if you’re running an ESP8266 on EAP, you’re vulnerable. We have no idea how many ESP8266 devices are out there in EAP networks,  but we’d really like to see Espressif patch up this hole anyway.

[Matheus] points out the irony that if you’re using WPA2, you’re actually safer than if you’re unpatched and using the nominally more secure EAP. He also wrote us that if you’re stuck with a bunch of ESP8266s in an EAP environment, you should at least encrypt and sign your data to prevent eavesdropping and/or replay attacks.

Again, because [Matheus] informed Espressif first, most of the bugs are already fixed. It’s even percolated downstream into the Arduino-for-ESP, where it’s just been worked into the latest release a few hours ago. Time for an update. But those crusty old NodeMCU builds that we’ve got running everything in our house?  Time for a full recompile.

We’ve always wondered when we’d see the first ESP8266 attacks in the wild, and that day has finally come. Thanks, [Matheus]!

41 thoughts on “ESP8266 And ESP32 WiFi Hacked!

    1. Eh, everything is gonna have bugs and vulnerabilities. I’m more concerned with whether or not they fix them. The ideal solution would be to open source their Wifi stack, but that’s not likely.

    2. This bug patching is LOOOOONG overdue for the EAP “support” on the ESP. It doesn’t surprise me at all.

      Calling EAP supported is a huge stretch considering how buggy the ESP is. It will frequently work or fail mysteriously depending on your *exact* settings and protocols. It seems the ESP is hard-coded to expect the handshake to go a certain way. That and the fact that the inner identity is hardcoded in one of the *.a files to an espressif domain.

      One would be led to conclude that EAP support is a half-baked experiment that wasn’t supposed to be compiled into any of the official releases of the SDK. And as far as I’m aware, it’s been like this with no improvement since the very beginning. (2016 at least, when I first learned about this)

    1. On that topic, Espressif pushed binary .a files licensed under the GPL at the beginning, which they relicensed under another permissive plus proprietary licence. Don’t know if users have the power to go to court, and ask the judge to get the sources.

    1. No need to worry for tinkering purposes. The people who should be concerned with upgrading their firmware are those who have integrated ESP32/8266s into their commercial products, their business-critical applications, and their homes.

  1. Another vulnerability caused by the lack of a boundary check letting the system prone to a buffer overflow.
    Why don’t firmware programmers think that things may go wrong? Don’t they read the news about digital security ? Would lazyness be the reason? Or an excess of optimism about data delivery?

    1. Bosses breathing down their necks to cut corners to meet ship date?
      Companies unwilling to hire great firmware programmers when mediocre ones are cheaper?
      Department heads vetoing purchases of test fixtures and other tools?
      Bean counters limiting R&D funding?

          1. Baby proof your languages for ID-IoT. Been done long time ago.

            “Does Pascal make buffer overflows less likely or impossible?”
            https://forum.lazarus.freepascal.org/index.php?topic=20843.0
            >Bounds checking (both compile and runtime, which is only inserted if compile time check is impossible), including overflow check (some bugs I’ve found in C programs I’m maintaining at office is due to overflow calculation that leads to a buffer getting allocated wrongly).

      1. Espressif has been quite a good citizen wrt firmware hardening, with several bug hunt contests with cash prizes. Also, the comitters to the SDK are very dedicated and top-notch IMHO.
        Now, only those who have never written code can claim they think of everything everytime.

    2. Perhaps in a idealistic future when we have all moved from c/c++ to Rust at the firmware level many of these memory/buffer bugs will be caught by the compiler, and mere mortal programmers will produce better code.

    3. danjovic, you might take offense that I’m explaining obvious things, but since you asked the question, I’m going to answer it in earnest. But in short, it is a test problem, not necessarily because they don’t understand the constraint to be checked.

      Say you joined expressif tomorrow and they give you the task of adding some new bit of code to a function called, oh, CloneBuffer. The routine is given a pointer to a struct describing a buffer; the routine is to allocate memory big enough to hold a copy of the buffer, copy the contents over, and return a pointer to the new struct describing that clone.

      Do you add code at the start of your routine which validates that the pointer given to you, then validates the contents of the struct the pointer is addressing? You could, but if every subroutine in the call stack validated and revalidated everything, it would hurt performance. So usually the idea is that the code which first touches untrusted data is responsible for validating it, then everything called by that code does not do the redundant checks (at least in production mode).

      But code is often developed by a team, or by a sequence of people over time. A given high level feature is often distributed over different routines (because of code sharing perhaps). Code evolves over time, often by someone who didn’t originally write it. There can be multiple paths into and out of the code in question. Thus someone can make an edit that might elide a check which N-1 of the paths are not affected by, but one is. Maybe the first routine to touch the packet used to validate everything, but it made the routine unwieldy, so instead the first bit of code was changed to do minimal packet parsing then dispatch it to specialized routines to handle each case, and it is now the responsibility of those routines to validate things. To save code (memory is always in short supply) many of those handlers share routines, and ownership gets muddy.

      There are many constraints on a programmer, not just security, and things get complicated. Features, functionality, performance, security, program and data memory space, schedule all need to be satisfied. Memory and schedule are the easiest to measure, and performance is not that much harder. Security is much harder to measure, so it is easier to make a mistake.

      A big part of the answer is simply testing. The fact that his was discovered by a 3rd party by writing edge cases indicates Expressif’s regression suite for their code could be better. They could probably use packet fuzzers to find cases they didn’t think of.

      Sure, maybe it turns out in this specific case it was just an inattentive programmer who didn’t do the obvious check in the obvious place, but your question was more general: why do these errors happen so often?

      1. Uh what? Shouldn’t the actual user at the end of the chain validate the pointer? Putting the responsibility at the start of the chain is asking for trouble. Now if there are multiple users, in various layers, I would question the architecture first. Granted there are great examples where doing it at the start makes sense as its passed around and used so much; but I reckon that’s rather the exception than the rule. More so in microcontroller land.

  2. Probably a lot of exploitable memory corruption. Nobody looks cause there are no valuable targets.. Same deal with a lot of DJI and TP-Link stuff I’ve seen. They barely have any modern stack hardening and no ASLR or nx pages.

    You can probably get RCE with the first bug since you don’t even need ROP

    1. Oh man. With this unholy mixture of symbology, somebody’s head is going to explode, because (3! == 6) == (3 != 6) and in this case, the spaces are part of the syntax. Factorial that out!

  3. So, at the end of the day, unless you’re running eap, which nobody is, the worst they can do is crash it? And that is somehow more serious than just flooding the spectrum with gibberish that will block all communications for everything anyway?

    It’s hard to imagine that anyone would go to the trouble just to crash a few esp’s. I can see someone implementing it as a college dorm room prank, but even that will get old VERY quick.

    All in all… Nothing to worry about.

  4. These companies(Expressif) have to protect their proprietary stuff so they can sell 3rd party locked devices that can only be unlocked via the company that sells them.
    Like say Kangaroo Sensor. It is worthless unless you call the company to remotely unlock it. The unlock is actually a code they send you from your telephone number. If it is authorized, then the app to use and monitor the device will turn on the ESP32 chip. It is actually in the app where to ON command comes from.Need someone to download the app and see how they created code inside. Your phone number is only used to keep track of your account. As the sensor also has support to send messages back to you and the company of it’s status and alarm states.

Leave a Reply to RK Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.