Project tutorial

Cracking an electronic safe using brute force

I couldn't find the code to my safe and needed to retrieve documents from it, so I cracked it.

  • 5,117 views
  • 1 comment
  • 19 respects

Components and supplies

About this project

Preface

There's nothing nefarious here, nor is the information contained herein particularly helpful to thieves or the dishonest. A thief would just cut the dang thing open and be done with it.

Photos

Arduino sketch

arduino_sketch_safe_cracker.c
Arduino sketch

Warning: Embedding code files within the project story has been deprecated. To edit this file or add more files, go to the "Software" tab. To remove this file from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Software" tab).

/*
 * Brute force safe cracker for a Sentry Fire Safe.  It took me 5 days
 * to open my safe with this.  YMMV.  Have fun!
 */

// map of keypad key number to arduino pin controlling the corresponding relay

unsigned char key2pin[10] = {
   9, // kp0
   2, // kp1
   6, // kp2
   10,// kp3
   3, // kp4
   7, // kp5
   11,// kp6
   4, // kp7
   8, // kp8
   12 // kp9
};

// arduino pin mapped to power cycling relay

unsigned char powerpin = 5;

int verbose = true;

// arduino pins mapped to photocells on green and red LEDs

int grnPin = 0;
int redPin = 1;

void setup()
{
   Serial.begin(9600);

   // Initialize key relays and power relay to open (high is open)
   int i;
   for(i = 0; i <= 9; i++)
   {
      digitalWrite(key2pin[i],HIGH);
      pinMode(key2pin[i],OUTPUT);
   }
   digitalWrite(powerpin, HIGH);
   pinMode(powerpin, OUTPUT);
}

// Read the status LEDs.  Return either the number of red blinks (the
// usual case), or that we got a green LED, which indicates a cracked
// safe.

int readStatus(double time, int& redBlink)
{
   // These values should be independently calibrated
   int redThresh = 200;
   int grnThresh = 200;

   int nsamples = 1000*time;

   redBlink = 0;
   int grnBlink = 0;

   // Count blinks via a moving avg and threshold cross

   int len = 10; // moving average length

   double avgRed = 0.0;
   double avgGrn = 0.0;
   double avgRed_last = 0.0;
   double avgGrn_last = 0.0;

   double redVals[len];
   for (int n = 0; n < len; n++) { 
      redVals[n] = 0.0; 
   }

   double grnVals[len];
   for (int n = 0; n < len; n++) { 
      grnVals[n] = 0.0; 
   }

   for (int n = 0; n < nsamples; n++) {

      // shift values to free up position 0
      for (int k = 9; k >= 1; k--) {
         redVals[k] = redVals[k-1];
         grnVals[k] = grnVals[k-1];
      }
      redVals[0] = analogRead(redPin);
      grnVals[0] = analogRead(grnPin);


      double sumRed = 0;
      for (int k = 0; k < len; k++) {
         sumRed += redVals[k];
      }
      double avgRed = sumRed / len;

      double sumGrn = 0.0;
      for (int k = 0; k < 10; k++) {
         sumGrn += grnVals[k];
      }
      double avgGrn = sumGrn / len;

      if (avgRed > redThresh && avgRed_last < redThresh) {
         redBlink++;
      }
      avgRed_last = avgRed;

      if (avgGrn > grnThresh && avgGrn_last < grnThresh) {
         grnBlink++;
      }
      avgGrn_last = avgGrn;

      delay(time/nsamples*1e3);
   }

   return grnBlink;
}

void turn_on()
{
   if (verbose) Serial.println("turning on");
   digitalWrite(powerpin,LOW);
}

void long_power_cycle()
{
   if (verbose) Serial.println("long power cycle");
   digitalWrite(powerpin, HIGH);
   delay(5000);
   digitalWrite(powerpin, LOW);
   delay(400);
}

void power_cycle()
{
   if (verbose) Serial.print("power cycle... ");
   digitalWrite(powerpin,HIGH);
   delay(3250);
   digitalWrite(powerpin,LOW);
   delay(400);
   if (verbose) Serial.println(" done.");
}

void press(int key)
{
   digitalWrite(key2pin[key], LOW);  // CLOSE
   delay(100);
   digitalWrite(key2pin[key], HIGH); // OPEN
   delay(250);
}

// try all combinations of buttons we can press

void loop()
{
   int lo = 0;
   int hi = 9;

   int attempt_count = 0;

   int cracked = 0;

   turn_on();
   delay(500);

   for (int digit1 = lo; digit1 <= hi; digit1++) {
      for (int digit2 = lo; digit2 <= hi; digit2++) {
         for (int digit3 = lo; digit3 <= hi; digit3++) {
            for (int digit4 = lo; digit4 <= hi; digit4++) {
               for (int digit5 = lo; digit5 <= hi; digit5++) { 

                  attempt_count++;

                  int redBlinks = 0;

                  if (verbose) Serial.print("Trying ");
                  Serial.print(digit1);
                  Serial.print(digit2);
                  Serial.print(digit3);
                  Serial.print(digit4);
                  Serial.print(digit5);
                  if (verbose) Serial.println();

                  press(digit1);
                  press(digit2);
                  press(digit3);
                  press(digit4);
                  press(digit5);

                  cracked = readStatus(2.0, redBlinks);

                  // 3 red blinks is a wrong combination.  5 red
                  // blinks is some mysterious error code.  When we
                  // get one of those, do a long power cycle to try to
                  // get things back to normal.
                  
                  if (redBlinks > 3) long_power_cycle();
            
                  Serial.print(redBlinks);
                  if (verbose) Serial.println(" red blinks");

                  Serial.print(cracked);
                  if (verbose) Serial.println(" green blinks");
            
                  if (cracked) {
                     Serial.print("Cracked!  Code is ");
                     Serial.print(digit1);
                     Serial.print(digit2);
                     Serial.print(digit3);
                     Serial.print(digit4);
                     Serial.print(digit5);
                     while (1) {
                     }
                  }

                  // We need to power cycle after 3 failed attempts to get
                  // out of lockout mode

                  if (attempt_count == 3) {
                     power_cycle();
                     attempt_count = 0;
                  }


               }
            }
         }
      }
   }
}

The story

So I bought a fire safe to protect some documents that I wanted protected in the unlikely event of a house fire. When I got the safe, I promptly emailed myself the manufacturer's code, set up an easily remembered user code, and stored the manual with the manufacturer's code in a "safe place."

Fast forward two years. I need to get to one of the documents in the safe. I can't seem to remember the user code. No problem, I say, I'll just look up the manufacturer's code in my email. So, what keywords did I use to make it searchable? Apparently not safe, combo, password, combination, or any combination or related word thereof. Ok, no problem, I'll just go get my manual from... umm, nope, not in my drawer with user manuals, nor in my filing system. WTF. The combos are both lost for good.

So I start considering my options. I could send a notarized letter to the safe company, but where's the fun in that? I could open it destructively, but I didn't really want to do that either. The lock is an electronic combination with a five digit password, so brute forcing seems plausible, but there's a two minute lockout on 3 wrong combinations, taking the brute force time to 140 days. That won't work. Unless...

I open up the battery compartment, enter three wrong combos, it goes into lockout mode, I remove the battery for a couple seconds and put it back. Yep, it "forgot" it was in lockout mode, and I can now enter 3 more passwords. Only 99,994 more to go. I estimate the safe could be opened in less than 6 days using brute force. I'm not in a real hurry for the documents, don't want to break the safe, and love the challenge of getting my safecracking on, so I commit to cracking this sucker via brute force.

At first I considered a mechanical dialer that would punch the buttons for me, but the mechanics of doing that with acceptable speed seemed somewhat difficult - not an afternoon's kind of project.

However, by cutting away a couple globs of hot glue with a blade, i could access the keypad contacts directly. Conveniently, there are access holes for connecting wires to the contact array. So I started sketching up where I need jumper wires and placing them.

Then it was a simple matter of using some relay boards I had laying around to start dialing the keypad using an arduino I also had laying around. I used a couple of photosensors to read the LED status indicators so that I could know if the combo failed or succeeded. Finally, I used an additional relay to power cycle the keypad after 3 failed combinations to defeat the lockout feature.
With a little programming work, I had an automated dialer that should (!) stop when the correct combination was found. By logging each attempt on a laptop and writing a couple of little helper scripts, I had hourly status updates being delivered via email. It was a bit of a programmer's nightmare in that I could not test the code directly for success, and didn't have the exact details of what the success scenario looked like, for example, how long until the green LED would light, how brightly it would light, or if it would be solid or flashing. Some youtubing failed to turn up these details as well. So I did my best to make it robust to these details and prayed.

And prayed, and prayed, and prayed... for five days, the robot dialed, and failed, and dialed again. When over 2/3 of the keyspace had been searched and no combination found, I started to doubt the success of the project.

However, this morning at 7:09 am, one minute before my alarm usually goes off (weird coincidence), the phone on my nightstand buzzed with an email alert. It was the safecracking robot calling, saying it had found the correct code. Somewhat scared of a false positive, I showered first, then headed into the room and removed the heavy blanket which I'd been using to muffle the incessant beeping. I entered the code sent via email and lo and behold, it opened. You can see a pen propping open the door in the lower left corner.

I love it when a plan comes together. With a little hot glue the keypad will go right back together and the safe will be like new. And this time my email with the combination will not be titled "Remember this number". *facepalm*

Now, as a wisecracking friend said "Dude, you can totally rob a bank now, at least when it's closed for a week". And when they are using cheap Walmart fire safes...

Code

arduino_sketch_safe_cracker.cC/C++
arduino_sketch_safe_cracker.c
/*
 * Brute force safe cracker for a Sentry Fire Safe.  It took me 5 days
 * to open my safe with this.  YMMV.  Have fun!
 */

// map of keypad key number to arduino pin controlling the corresponding relay

unsigned char key2pin[10] = {
   9, // kp0
   2, // kp1
   6, // kp2
   10,// kp3
   3, // kp4
   7, // kp5
   11,// kp6
   4, // kp7
   8, // kp8
   12 // kp9
};

// arduino pin mapped to power cycling relay

unsigned char powerpin = 5;

int verbose = true;

// arduino pins mapped to photocells on green and red LEDs

int grnPin = 0;
int redPin = 1;

void setup()
{
   Serial.begin(9600);

   // Initialize key relays and power relay to open (high is open)
   int i;
   for(i = 0; i <= 9; i++)
   {
      digitalWrite(key2pin[i],HIGH);
      pinMode(key2pin[i],OUTPUT);
   }
   digitalWrite(powerpin, HIGH);
   pinMode(powerpin, OUTPUT);
}

// Read the status LEDs.  Return either the number of red blinks (the
// usual case), or that we got a green LED, which indicates a cracked
// safe.

int readStatus(double time, int& redBlink)
{
   // These values should be independently calibrated
   int redThresh = 200;
   int grnThresh = 200;

   int nsamples = 1000*time;

   redBlink = 0;
   int grnBlink = 0;

   // Count blinks via a moving avg and threshold cross

   int len = 10; // moving average length

   double avgRed = 0.0;
   double avgGrn = 0.0;
   double avgRed_last = 0.0;
   double avgGrn_last = 0.0;

   double redVals[len];
   for (int n = 0; n < len; n++) { 
      redVals[n] = 0.0; 
   }

   double grnVals[len];
   for (int n = 0; n < len; n++) { 
      grnVals[n] = 0.0; 
   }

   for (int n = 0; n < nsamples; n++) {

      // shift values to free up position 0
      for (int k = 9; k >= 1; k--) {
         redVals[k] = redVals[k-1];
         grnVals[k] = grnVals[k-1];
      }
      redVals[0] = analogRead(redPin);
      grnVals[0] = analogRead(grnPin);


      double sumRed = 0;
      for (int k = 0; k < len; k++) {
         sumRed += redVals[k];
      }
      double avgRed = sumRed / len;

      double sumGrn = 0.0;
      for (int k = 0; k < 10; k++) {
         sumGrn += grnVals[k];
      }
      double avgGrn = sumGrn / len;

      if (avgRed > redThresh && avgRed_last < redThresh) {
         redBlink++;
      }
      avgRed_last = avgRed;

      if (avgGrn > grnThresh && avgGrn_last < grnThresh) {
         grnBlink++;
      }
      avgGrn_last = avgGrn;

      delay(time/nsamples*1e3);
   }

   return grnBlink;
}

void turn_on()
{
   if (verbose) Serial.println("turning on");
   digitalWrite(powerpin,LOW);
}

void long_power_cycle()
{
   if (verbose) Serial.println("long power cycle");
   digitalWrite(powerpin, HIGH);
   delay(5000);
   digitalWrite(powerpin, LOW);
   delay(400);
}

void power_cycle()
{
   if (verbose) Serial.print("power cycle... ");
   digitalWrite(powerpin,HIGH);
   delay(3250);
   digitalWrite(powerpin,LOW);
   delay(400);
   if (verbose) Serial.println(" done.");
}

void press(int key)
{
   digitalWrite(key2pin[key], LOW);  // CLOSE
   delay(100);
   digitalWrite(key2pin[key], HIGH); // OPEN
   delay(250);
}

// try all combinations of buttons we can press

void loop()
{
   int lo = 0;
   int hi = 9;

   int attempt_count = 0;

   int cracked = 0;

   turn_on();
   delay(500);

   for (int digit1 = lo; digit1 <= hi; digit1++) {
      for (int digit2 = lo; digit2 <= hi; digit2++) {
         for (int digit3 = lo; digit3 <= hi; digit3++) {
            for (int digit4 = lo; digit4 <= hi; digit4++) {
               for (int digit5 = lo; digit5 <= hi; digit5++) { 

                  attempt_count++;

                  int redBlinks = 0;

                  if (verbose) Serial.print("Trying ");
                  Serial.print(digit1);
                  Serial.print(digit2);
                  Serial.print(digit3);
                  Serial.print(digit4);
                  Serial.print(digit5);
                  if (verbose) Serial.println();

                  press(digit1);
                  press(digit2);
                  press(digit3);
                  press(digit4);
                  press(digit5);

                  cracked = readStatus(2.0, redBlinks);

                  // 3 red blinks is a wrong combination.  5 red
                  // blinks is some mysterious error code.  When we
                  // get one of those, do a long power cycle to try to
                  // get things back to normal.
                  
                  if (redBlinks > 3) long_power_cycle();
            
                  Serial.print(redBlinks);
                  if (verbose) Serial.println(" red blinks");

                  Serial.print(cracked);
                  if (verbose) Serial.println(" green blinks");
            
                  if (cracked) {
                     Serial.print("Cracked!  Code is ");
                     Serial.print(digit1);
                     Serial.print(digit2);
                     Serial.print(digit3);
                     Serial.print(digit4);
                     Serial.print(digit5);
                     while (1) {
                     }
                  }

                  // We need to power cycle after 3 failed attempts to get
                  // out of lockout mode

                  if (attempt_count == 3) {
                     power_cycle();
                     attempt_count = 0;
                  }


               }
            }
         }
      }
   }
}

Comments

Similar projects you might like

Electronic Safe with Arduino

Project showcase by chummer1010

  • 23,074 views
  • 28 comments
  • 50 respects

Electronic Components Review Made With Electronic Components

Project tutorial by Team M&M

  • 166 views
  • 0 comments
  • 1 respect

Safe City: A Device to Keep You Safe

Project tutorial by Patel Darshil

  • 6,036 views
  • 0 comments
  • 24 respects

Electronic Piano Keyboard With Preset Songs

Project tutorial by Lindsay Fox

  • 74,606 views
  • 59 comments
  • 138 respects

Safe Home Smart Home: Safety Device For Every Family Member

Project tutorial by Patel Darshil

  • 3,325 views
  • 0 comments
  • 8 respects
Add projectSign up / Login