Typically, computers are 100% deterministic. Given the same inputs, it should always produce the same outputs. But, what if this wasn't the case? What if you COULD alter the flow of execution? This is where our friend comes into the game: fault injection.
Generally, fault injection is about purposely creating faults or issues in how something is running. This is commonly done for load balancer testing, to see how much a system can handle if a few servers go offline. In the context of security, it is just about trying to introduce faults into the running program.
Typically, fault injection is done in two ways: voltage glitching and clock glitching. With voltage glitching, the idea is to give the system an unexpected power amount (a ton or very little) to try to cause a fault. In practice, this can be used in order to skip/alter instructions, change the state of the processor or brick the thing entirely.
This article is all about glitching a SoC chip to bypass the BootROM verification. This article is not just the hand-wavy 'glitching' works kind of thing; this is a very in-depth article into how to launch a voltage glitching attack on an SoC.
First, even if we get a glitch what can we do? This particular eMMC chip has the following process:
- BootROM starts and is the immutable part of the Boot Process.
- The pre-loader is stored on the Boot0 eMMC partition and is mutable code. This code is put into RAM to be executed.
- Prior to executing, the BootROM validates that the signature of the pre-loader is valid.
What does this mean? In practically, we want to inject our OWN code into the pre-loader and glitch the signature check to return true, even though it was not signed properly.
To do the actual glitching, an FPGA was programmed for this exact purpose. The FPGA must be used because of the timings being SO exact. The FPGA is connected to the eMMC clock and data0 lines in order to KNOW when to trigger the glitch.
Here's the actual flow:
- The target board is in the middle of this, of course.
- The FPGA then reads the eMMC
clock and DATA0.
- The FPGA outputs a flag to the ChipWhisperer in order to perform the glitch.
- The ChipWhisperer is connected to
VCCK_PMU; it will drop the power to gnd for a very short period of time in order to cause the glitch.
What is this flag? The FPGA is looking to read the very start of the pre-loader. Right after putting this into RAM, the glitch is attempted in order to screw up the signature validation.
To get the ability to glitch, we must set the proper parameters for the ChipWhisperer. What exactly needs to be set? The most important is the width of the glitch. Even with properly brute-forced parameters, the success rate of this attack was around 20% at the most.
With the ability to bypass the signature check, the researcher decided to alter a DEBUG string. In the article, they mention altering the DEBUG string, but I am unsure if they alter the pre-loader on the chip itself or if the modify the string in transit. The former seems more likely though.
Finally, we can run arbitrary code at a VERY low level. So, now what? A malicious actor would probably want to load a malicious firmware image or attempt to steal sensitive data from the device.
How can you patch against this attack? There are hardware mitigations for this but this can ALSO be made much harder in software.
- Add redundant checks to important things, such as signature validation. If getting ONE glitch is hard, getting THREE would make it much more difficult.
- Add random time delays. This works because the glitch attack is ran 700ms after seeing the pre-loader on the data line. Altering the timings would cause issues.
Overall, this was a really good article to look into real world fault injection, instead of the hand-wavy article we normally see.