ESP32 Vulnerability Affects Older Chips

There is a scene from the movie RED (Retired, Extremely Dangerous) where Bruce Willis encounters a highly-secure door with a constantly changing lock code deep inside the CIA. Knowing the lock would be impossible to break, he simply destroyed the wall next to the door, reached through, and opened the door from the other side. We thought about that when we saw [raelize’s] hack to bypass the ESP32’s security measures.

Before you throw out all your ESP32 spy gadgets, though, be aware that the V3 silicon can be made to prevent the attack. V1 and V2, however, have a flaw that — if you know how to exploit it — renders secure boot and flash encryption almost meaningless.

The hack centers around the UART bootloader. You can cause the chip to enter that mode and do basic operations such as read and write RAM and registers. You can also execute code from RAM. That’s not a particular security risk, though, since the flash memory may be encrypted. Decryption is transparent in the hardware and the chip doesn’t do the decryption during the boot loader mode. Sure, you can read the encrypted flash, but you could do that with some fancy desoldering or probing techniques, too.

During a normal boot, a bootloader in flash is placed in RAM. If you can glitch the CPU at just the right time — in theory — you could force the processor to run your RAM-based code in normal mode where the flash is already decrypted. The only problem is, they tried about 1,000,000 cycles and had no success. But they did notice something odd.

The illegal instruction exception that occurred during the glitch was due to an instruction in the original RAM code winding up in the PC register. This allows an attacker to load an arbitrary address in RAM into the PC if the glitch is timed just perfectly. It turns out, it is just that easy.

We wondered why a data item would wind up in the program counter and apparently [raelize] wondered the same thing. There are a few theories, but no one seems to know for sure. At least, no one who isn’t under a non-disclosure agreement.

Once you can set the PC address arbitrarily, it is easy enough to jump back into the UART bootloader. It took a little experimenting, but eventually, the unencrypted flash came pouring out of the serial port.

This is good work and we are glad the latest silicon doesn’t show the problem. The work is captured in an official advisory, so the community will know what is possible.

There have been quite a few security-related exploits lately. Usually, we think of ESP tools as part of the hacker’s toolset, not a target, but — of course — anything is fair game.

24 thoughts on “ESP32 Vulnerability Affects Older Chips

  1. Mentioning secure boot in the title would be nice. Now I’m expecting a stream of “ZOMG!1!! SHOULD I THROW OUT ALL MY SONOFFS??!!11! CAN HACKERS BURN DOWN MY SMART HOME?!!!111” comments from the tl;dr people ;-)

    1. Yeah it requires physical access which in most usecases means it’s not a big deal :P

      In fact it’s a good thing because it means some ESP-powered devices with closed firmware can now have their firmwares reverse engineered.

      1. It doesn’t allow remote attacks without physical access, so this is not a problem for 99.99% of consumers, DIYers, or anyone except proprietary hardware makers, but still a cool reverse engineering effort.

  2. Oh. So my programs are not vulnerable per se. Because I dont have any encryption or security turned on so doing this is like picking the lock on a car door when the windows are fully rolled down. This is pimarily worrisome to those who need to secure the chips against injection or readback?

  3. The explaination and the conclusion you’re drawing are completely different. It would require *many* *many* days to get a plaintext firmware on a vulnerable V2, because the code only gets 8 bytes of plaintext per “run”. (A run requires the ESP32 to reboot and to be perturbed by the appropriate glitch which is not 100% reliable). So, unless you know where are the secure key required to decode the firmware (which would be a silly thing to do as a manufacturer), you need to fetch ~1MB of data to extract the firmware, that’s 131k reboots. If your success rate to glitch is once every 10s, it means 15 days to get the firmware.

    1. I’ve got a feeling this is just a limitation of a proof-of-concept: they targeted the simplest way to get any data out to prove it works. They could’ve, for instance, targeted the command handler and sent a load_ram command, with a custom program to dump all of RAM. But that’s more work than needed for a POC.

    2. That’s not the conclusion I get from [raelize’s] linked post. The post indicates that they are able to glitch the ESP32 to load an arbitrary value into the program counter after (most of) the firmware has been decrypted into RAM but before control has been transferred to the firmware. This arbitrary value is the address of the small piece of code they loaded via the UART bootloader just prior and jumps back into the command handler of the UART bootloader, giving them remote command access to dump the entire RAM (with the now decrypted firmware) with just one command. One successful glitch allows them to dump the decrypted firmware, not 131K.

      1. The command they used in the bootloader’s command handler was just “read_mem” targeting the flash’s mapped address. So they only get those 4 bytes.

        After that the command would try to jump back to the bootloader, which hasn’t been initialized at all and so it presumedly goes “boom.”

        But this is just a proof-of-concept, so 4 bytes is really all that’s needed. I don’t know why they didn’t, for instance, fill the SRAM with PC values of their own custom code, at which point you could just straight out dump all of the flash anyway. This just might’ve been easier.

        1. Nope. They jumped into the bootloader’s command handler loop which accepts commands and responds via SLIP protocol packets. The “read_mem” command seems to be the 0xa READ_REG command which does indeed only return a 32-bit word but from the address specified in the SLIP-encoded bootloader command, not the address that was stuffed into the PC during the glitch. Since they’re now running the bootloader’s command handler loop, they just can just issue repeated “read_mem” commands to the serial port to dump the whole memory without having to restart and re-glitch from scratch for each word.

          The reason for all of this business is that the firmware in flash is encrypted and decrypted into RAM by the ESP32 on boot-up. This exploit dumps the “plaintext” firmware after the ESP32 has decrypted the firmware into RAM but before the decrypted firmware is executed.

          1. This isn’t how UART bootloader works. The original bootloader only load a small amount of flash to decrypt and run. You can’t ask it to, say “give the word at address 3452142 in flash”, but only hope that part will be loaded by a previous run, you’ll need to warm reboot so it stays in ram and then trigger the bootloader glitch. It’s more like a fishing game here hoping to find what you want at the expected location. Remember that ESP32 as way more flash than RAM so it can’t fit the whole flash in RAM. I too would really really like to see a complete dump of encrypted flash demonstration, but this is not one.

      2. They are not sending any new binary to the system, but only exploit the UART bootloader *existing* code (else they would delete what they are trying to read). So they can’t really have “binary” that’s dumping all the stuff. At best, they can upload the PC value they want the ESP32 to jump to but that’s not code, that’s just a single register.

  4. I think it is still difficult to hack code as per pattern provided into description.

    I just want to know it will be possible to hack in case if boot loader is not secured and flash encryption is not enabled?

    If that is the case then is there any software way to resolve that hack issue or just need to replace module version?

    Ritesh Prajapati

  5. So basically a non-story for DIYers using this chip for DIY projects? I doubt most are making use of encrypting their code for their DIY projects. Seems this primarily affects makers of consumer goods that are using the encryption to protect their code. And DIYers that want to reverse engineer said consumer goods, because it might be possible to break/get around that encryption.

  6. OMG! Somebody could hack into my son’s binary clock and set an alarm! Maybe they could tidy up my code, while they’re at it, there’s something like 3mB of it, I had to use the “huge” compiler options… It’ll only take them 400-odd crash and reboots.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

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