Close

Example 1: Simple buffer overflow

A project log for Simple Security Risk Examples on Arduino

Simple Arduino examples of common cyber-security risks, such as buffer overflows and stack smashing

jake-wachlinJake Wachlin 09/19/2020 at 15:430 Comments

C/C++ give the developer enormous amounts of power and control. In a perfect world, that is great. The developers can exploit this to write fast, efficient code. However, it can go wrong, and often does. Many real-world security bugs are due to memory safety issues. In many cases, these are buffer overflow issues.

This example will show a buffer overflow example that can be used to "unlock" something without knowing the "password," simply by overwritting a lock flag. Clearly this is a contrived example, but does provide some insight into the danger of these kinds of issues. The code for this example is on the linked Github repo, but is reproduced here as well.

#define BUFFER_LENGTH   16

void setup() {
  Serial.begin(115200);
  delay(1000);

  Serial.println("Booting...");
  delay(100);
}

void loop() {
  delay(5000);

  char buff[BUFFER_LENGTH] = {0};
  uint8_t unlocked_flags[32] = {0};

  Serial.print("Buffer address: ");
  Serial.println((uint32_t) buff);

  Serial.print("Unlocked flags address: ");
  Serial.println((uint32_t) unlocked_flags);

  int start = millis();

  int index = 0;
  Serial.println("Enter your password");
  while((millis() - start) < 5000)
  {
    if(Serial.available())
    {
      buff[index++] = Serial.read();
    }
  }

  if(strcmp("super_secret", buff) == 0)
  {
    Serial.println("Password correct!");
    unlocked_flags[0] = 1;
  }
  

  if(unlocked_flags[0])
  {
    Serial.println("UNLOCKED!!!!");
  }
  else
  {
    Serial.println("Still locked...");
  }

}

Here, we declare a local buffer of length 16 that will be used to be filled with user input for their password. We also set up a local array of flags used to unlock various things in the codebase. These local variables are stored on the stack. We print out the memory addresses of both of these arrays, which helps make the exploit easier. I ran this test on a Adafruit Feather M0, and I see the following:

Here, we see that the address of the flags is 16 higher than the buffer. This means that if we can write beyond the 16 elements of the buffer, we can overwrite elements in the unlocked flags buffer. We can input a string with 18 characters, like shown below.

Once this is entered, it is unlocked!

There is no length checking in this example, so we keep incrementing "index" according to the input characters, and overflow the buffer.

Discussions