Arduino-to-Arduino Voltage Glitching (look ma, no FPGA!)

Recently, I have been delving into the magical world of hardware hacking. One target has given me cause to learn voltage glitching, among other things. On the advice of friends, I ordered a ChipWhisperer kit but while it made it’s merry way across the sea, I wanted to begin experimenting right now.

After giving thanks to Her Majesty the Queen (may she reign eternal) for the long weekend, I decided to follow work done by flawed.net.nz earlier this year, with the hardware I could find on my desk. I will now list the theory behind this work, the process I went through and the final result in this post.

You can download the source files used in this example here and here.

Theory: Voltage Glitching

Voltage glitching is the process of temporarily reducing voltage to a microcontroller as it is performing an operation, causing undefined behaviour. This can be represented as follows:

This can result in surprising and advantageous interactions, such as single CPU instructions not doing the right thing. The impacts of this are immense – it fundamnetally breaks the assumption that computerised systems always do what you tell them to in software.

You can read more about this subject here:

This must be performed with some measure of accuracy: drop the power for too long, and the target microcontroller may reset.

Target Setup

My target code was a simple counting loop:

void loop() {
 int x = 0;
 int y = 0;
 double sum = 0;
 for(x = 0;x < 500; x++)
 {
 for(y = 0;y < 500;y++)
 {
 sum++;
 }
 }
 Serial.print("500 * 500 = ");
 Serial.println(sum,DEC);
 if(sum != 250000.0000000)
 {
 flashRed(100);
 }
 else
 {
 flashGreen(100);
 }
}
]

Simply put, this should always output 250000: our goal is to influence this result via modifying the voltage.

I ran the above “target” code on an Arduino board which I got as part of the Freetronics Experimenters Kit for Arduino (which you can purchase here). I initially hooked it up to two LED’s and ran it, to confirm it works, which it does – it consistently returns the expected result via the serial monitor.

Glitch Source Setup

The next step was to set up a glitch source. For this, an FPGA is typically used, but as I did not have one, I used the ESP8266 component which came with the BSides 2017 badge, as follows:

(Sorry – the unlabelled resistor-shaped component is actually a resistor).

This used a 2N7000 transistor to intercept the ground connection of the target Arduino device – in it’s unintercepted state, this would always be connected, and thus, providing a steady flow of electrons through the microcontroller.

In this case, we send a continuous high voltage signal to the middle pin, keeping it “on” – however, we occasionally stop sending a signal, causing the transistor to break the circuit and induce a “glitch”.

In practice, it looks like this (don’t worry about the microcontroller inserted into the breadboard up top – for now, it’s not connected):

The leftmost orange connection is our “glitch out” – we can break the connection of anything which uses this as it’s ground. You can test this with a LED – send a HIGH signal to pin 13, and break the connection by sending a LOW signal to the same pin.

Pin 13 is the white wire, connected to the pin labelled D7. The pink wire is connected to a Ground pin.

Note that the transistor is directional – if you are following these steps, orient the transistor exactly as shown. Otherwise: the “gate” is Pin 13/D7, the “source” is the glitch out, and the sink is a Ground pin. If you test with a LED, and get a result where the LED slightly dims but does not turn off when you attempt to drop voltage, you’ve probably messed up the direction of the transistor.

Glitch Timing + Destabilizing

We also need to tweak our source code, so we drop power long enough to meaningfully impact the target, but not long enough to reset the target. To do this, I embraced the oldest and noblest of traditions, brute force best force:

void setup() {
 Serial.begin(115200);
 pinMode(13,OUTPUT);
 digitalWrite(13,HIGH);
 delay(10000);
 Serial.println("GLITCH RDY");
}

int glitchCtr = 0;
int secCtr = 1;

void loop() {
 // put your main code here, to run repeatedly:
 if(glitchCtr > 2000000)
 {
 Serial.print("DUMPING POWER FOR ");
 Serial.println(secCtr);
 digitalWrite(13,LOW);
 // try to pass time.
 int waste = 0;
 for(int i = 0;i < secCtr;i++)
 {
 waste++;
 }
 secCtr *= 2;
 digitalWrite(13,HIGH);
 glitchCtr = 0;
 }
 else
 {
 glitchCtr++; 
 digitalWrite(13,HIGH);
 }
}

You’ll notice that we use a while loop instead of the delay() function: the delay function is too slow. Remember, we’ll want to drop the power for a fraction of a clock cycle on the target only, which is much shorter than 1ms.

At this point, we have almost everything we need to run the attack – unfortunately, the Arduino board itself is unfortunately somewhat resilient to voltage glitching, due to the presence of capacitors on the board itself, providing a stable source of voltage in case of accidental noise on the power supply.

If you attempt the glitching attack at this point, you’ll simply see nothing, until you drop the voltage long enough that the device itself resets.

Following on the flawed.net.nz glitching work, I transplanted the microcontroller onto a breadboard, and restored the connections manually, without capacitors. The wiring should look something like this:

  • With the microcontroller facing upwards, pin count starting from 1
  • Pin 8 is connected to our glitch out
  • Pins 2, 3, 7, 9, 10 and 20 out to their respective positions on the Arduino board itself.

Now, we plug in the ESP8266 and the Arduino board, and open up the serial ports on both. You should see the messages from the ESP indicating when it’s dumping power – after a while, you should see the maths on the glitch target returning unexpected results:

You’ll see the results get wierder as you drop the power for longer, until the device itself resets (or you get an integer overflow on the ESP8266). Note that sometimes, you won’t glitch an add operation – you’ll glitch some other function call, and the output from the target will freeze – just reset the device if it doesn’t come back after a while.

I hope you enjoyed this read – I know barely anything about hardware hacking, so any feedback / spotted errors are welcome. Special thanks to Silvio and the BSides Canberra 2017 team for the ESP8266 device which served as the glitch source in this exercise.

Appendix: ESP8266 Mini-Board:

While I was going through this exercise, I had contemplated desoldering the pins on the ESP8266 and resoldering them to the be the same as… every other development board I had (female headers). During my research, I stumbled across a clever, less messy solution (source: http://www.cnx-software.com/2015/10/29/getting-started-with-nodemcu-board-powered-by-esp8266-wisoc/):

About Norman

Sometimes, I write code. Occasionally, it even works.
This entry was posted in Bards, Computers, Jesting and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s