This project is submitted for

Description

The Five Finger Code Finder is an electromechanical device and software designed to efficiently find the PIN code that will unlock Ford automobiles equipped with a 5 button entry keypad.

Its purpose is to demonstrate how the design of this system allows PIN codes to be found in a MUCH SHORTER TIME than would normally be required to brute force search and try all possible PINs. This system allows a good level of usability but in the process sacrifices security. The purpose of this project is to demonstrate how design decisions that put a priority on ease of use can greatly compromise the security of a system such as this.

The system uses an Arduino for control, a standard HD44780 compatible LCD, and five solenoids to press the keypad buttons in sequence.

Details

This project builds
on the previous work of Samy Kamkar and the authors of “The Car Hacking Handbook.” Samy discovered a method to quickly open garage door openers that use a remote with a fixed binary code set by dip
switches. Despite the development of rather secure rolling code
systems these remotes are still in wide use in situations such as
apartment parking garages where a large number of remotes must
operate the same door.

Samy discovered that
the logic that checks for a code match rechecks the entire code
sequence as each individual bit arrives, rather than waiting for a
full code word to be received, and that there is no delay after
checking for a match and no penalty for an incorrect match. If you
have a 12 bit code the check system will check the first 12 bits for
a match. If a 13th bit arrives, it will immediately check
bits 2 through 13 for a match. If a 14th bit arrives, it
will check bits 3 through 14, and so on. This facilitates much
faster code searching as you have just checked three different 12 bit
codes with only 14 bits sent.

The authors of “The
Car Hackers Handbook” discovered that the entry keypads on Ford
vehicles utilize this same shift by one and check for a match system. Also with no delays and no penalties for incorrect entries. In this
case you have five keys to use in the code instead of just the ones
and zeros of a binary code but the concept remains the same. In
their book they published an optimal sequence for manually trying all
possible codes as efficiently as possible. They state that one can
enter this sequence manually in approximately 20 minutes and find the
code to unlock a Ford vehicle with this system.

Well, I’m to lazy
to do that, and thought it would be a fun project to implement a
machine that can enter the sequence automatically for me as quickly
as the door keypad will recognize button presses.

Files

Python code from Wikipedia page on the DeBruijn Sequence, modified by me to output sequence of all 5 digit combinations of 1, 3, 5, 7, and 9, separated by commas and spaces, so it may be pasted into the array initialization in the Arduino code.

Project Logs

I have done another video on my Five Finger Code Finder project. In this one I discuss how I built the device, and I cover the issues encountered along the way, so you don't have to solve the same problems I did.

So I found a small issue with my code that I need to fix. The fix is incredibly easy but took hours to figure out. I was making up some materials for a YouTube video explaining how the system works, when I realized that something not quite right. When you have a 5 digit code with 5 keys, there are 3125 different codes to test. The DeBrujin sequence is 100% efficient at reusing past digits, so I am supposed to be testing a full 5 digit code with each keypress. Yet I realized something. The first four keypresses are not actually testing a code because you haven't completed entering a five digit code until you've pressed five digits. So since the first four digits are wasted, it should take 3129 keypresses to test all 3125 codes. Something is not quite right here, since there are only 3125 digits in the sequence output by the python code I found on Wikipedia.

So apparently I am not testing 4 of the possible codes. After a bit of puzzling about how this could be possible I gave up and decided to brute force figure out which ones were missing. I altered the Wikipedia code to output each digit followed by a newline so I could import into rows in Libreoffice Calc. I wrote a formula to create a column with each code that is tested by each digit - stripping the left digit and adding the new digit to the right end. Then I wrote another piece of code to generate a list of all possible codes. I pasted that list into the spreadsheet and wrote a lookup formula to indicate if each one was found in the first list generated by the sequence. It found four missing codes.

When I looked at the four codes that were missing it suddenly became evident what was going on. The four codes are 91111, 99111, 99911, and 99991. I looked for where these should be in the sequnce and noticed that the sequence ends with five nines and starts with five ones. To actually finish the sequence you have to connect the end to the beginning and continue for four more digits. Those first four digits that don't test anything would be testing the four missing codes if you were continually going around the sequence in a circle.

So all I have to do to fix the problem is add four nines to the start or four ones to the end of the sequence and it will test those four missing codes. I haven't updated the code yet but I know it will work fine when I do. Someday I'll get around to uploading the code to the project page. And making those YouTube videos...

It's hard to believe that it's been six months since I posted anything to the project page for my Five Finger Code Finder device. I may have neglected the page but I haven't neglected the project. I have been working on the project all this time and I now have a working device that proves the concept. It can tap out the entire sequence to find any code in only 11 minutes, and on average will find a code and open a door in under 4 minutes.

My breadboard circuit wouldn't have survived a trip out to the garage so I rebuilt what I had with an Arduino Pro Mini and a better LCD, the ULN2003 driver and some push buttons for control, all on a perfboard. I added a 7805 regulator circuit so I could power it, and mounted that to the clear plastic sheet I put the solenoids on.

Then I found quite a few issues along the way that needed addressing. Like the fact that even though the solenoids are rated at 12 volts, a couple rechargeable 9V batteries in series don't have the power to pound the solenoids hard enough or the capacity to run the machine for long.

After fixing these issues I have a robotic button pusher that works great. I plan to make a few videos for my YouTube channel showing it working, how I came up with the concept and how these minimal length code sequences work, how I fixed the problems I encountered along the way, and maybe even what could be done to improve the design.

I will post those videos here, but I hope to also do longer form write ups on these points as well. Many interesting things happened along the way developing this project.

Today I decided it was time to build something to give people a better idea of the device I intend to build. So I grabbed a piece of acrylic plastic sheet and started drilling holes to build the actual unit.

Turns out I need to find a better way to drill holes in plastic sheets. When I tried to drill 3/8 inch holes for the solenoids with a normal drill bit it would chatter and I figured it would break the plastic before I got the hole drilled. So I used my Dremel drill press and a somewhat cone shaped grinding stone to make the holes. Problem was that it basically melted through the plastic and didn't stay centered where I wanted so the holes aren't aligned as well as I wanted. I suppose when I build a final version I'll have to make some sort of jig to hold things in place as I drill. And I scratched up the plastic a bit scraping the melted mess off around the holes. But it's a workable first attempt and does a good job of showing what I intended.

As you can see I also drilled holes in the corners and mounted a couple flat head screws. I put magnets on the heads of the screws to hold the device to the door. I need to order some magnets with holes in the center for screws. And add two more to the bottom corners. Using screws in this way will allow me to adjust the space between the keypad and the solenoids, allowing me to find that optimal height with the most solenoid force. And the acrylic sheet plastic makes it easier to see the alignment of the solenoids with the keypad and just looks cool.

Also mounted on this plastic sheet would be the Arduino, LCD, a board with the ULN2003 driver chip, and the push button switches (maybe I need a bigger piece of plastic).

I've been experimenting with the push type solenoids I obtained for this project to determine how to get them to operate with enough force to push the keypad buttons reliably. The force produced increases significantly by increasing the voltage from 12V to more like 24V. As I said in a previous log, I think this will work fine due to the low duty cycle that will be applied.

But I discovered another property of these push solenoids. The force produced varies significantly based on the initial position of the armature.

These solenoids work differently than most - the pin pushes outward instead of pulling inward. How do you get the pin to push outward when the armature is attracted to the coil, not repelled? The main part of the armature is thicker than the pusher end pin and so even though the pin is pulled inward the much thicker opposite end is pulled in with much more force, so the net force is to push the pin outward, until the large part of the pin bottoms out against the small hole end.

You would think that the point of maximum push force would be right before the pin hits bottom, as this point would have as much pin as possible inside the coil and would result in the best magnetic coupling between the pin and coil. So when building my device I should place the solenoids as high as possible so that the keypad button is pressed just before the pin bottoms out.

But experimenting at my workbench reveals that the just-before-bottom position is NOT where the solenoid produces the most force. There seems to be a point with the pin farther back and the fat end of the armature farther out the back of the solenoid that produces significantly more force. But finding this point of maximum force is hard to find just holding a solenoid by hand over the surface of my workbench.

I need a device to reliably hold the solenoid in a stable, adjustable, and repeatable distance over a surface and a way to measure the force produced, so that I may build my device with the optimal spacing between the solenoid body and the keypad button surface.

So I am now thinking about building some sort of frame I can clamp to my workbench. A frame on which I can mount a solenoid over my digital scale so I can power the solenoid, read the force produced, and adjust the spacing of the solenoid to find the optimal distance.

The hardware for the breadboard prototype is now complete. I recently got the push buttons wired up, hooked up 5 red LEDs to blink with the solenoids, since everyone likes blinky LEDs, and got the ULN2003 driver chip working and powering solenoids.

I've written several crude Arduino programs to test each of these functions and they all work. Now I have to just start putting the puzzle pieces together to make a code search program with a usable user interface,

A side note, I've been doing electronics for decades and I've worked with microcontrollers since ceramic package PIC 16C54's were a thing. But I've never done an Arduino project before. Just never got around to it and I don't know much about the Arduino language, so this is a bit of a learning experience.

One dilemma I am facing is whether or not I should bother writing switch debouncing routines. I find it extremely annoying to use an electronic device that fails to do proper switch debouncing and just as you have clicked a switch several times it bounces and jumps right over whatever you were trying to select. So the OCD side of me says things won't be right in the world unless I implement proper switch debouncing.

But in the course of testing my hardware I found a chunk of code online that tests for switch debouncing and found that it isn't much of a problem. I can click the buttons I used maybe 20 or 30 times before detecting any actual bounce. And it's not like this project is meant to be a polished consumer product. So the practical side of me says don't bother with the switch debouncing software.

I don't know yet if it will be the practical side or the OCD side of me that wins that argument...

So I figured that before I got much further into this project I should check if the solenoids I bought have enough force to push the buttons on my keypad. The solenoids I purchased were from All Electronics, part number SOL-102. They are a bit odd in that they are push type solenoids, but that is what I need to push buttons without having to build some sort of rocker mechanism.

I was going to start to build a plate with the five solenoids mounted so I could place it over the keypad, but then I decided to just hold the solenoid over the button and energize it with the specified 12 volts. Turns out they don't have the force to reliably push the button.

So now I have to figure out how to fix this problem. I could look for bigger, stronger solenoids, but I would have to find ones that fit in the spacing of the keypad, and are push type. I would rather not have to do more searching, order more parts, etc.

I could hit the solenoids with a voltage much higher than their 12 volt rating. This would probably not cause a failure of the solenoids, since we are pushing five different buttons and each one would be energized less than one fifth of the time on the average. And it would take a significantly higher voltage to break down the insulation internally in the coil.

Another option would be to use a different method entirely. Servos would have much more force. Problem is that they would also be much slower, and one goal of this project is to complete entering the number sequence as fast as the car can recognize the button presses.

So I will try the second option. Hitting the solenoids with a higher voltage is quick and easy and will likely work fine.

So my first log entry is a retroactive entry to catch up on what I have already done. I have been working on this project off and on for months. Mostly off and not a lot of on. As you can see in the photo I have cobbled together a proof of concept test on my workbench with a breadboard and an Arduino and an LCD.

I also did some research on the De Bruijn sequence as I didn't want to just copy the sequence from The Car Hackers Handbook. I found some python code on Wikipedia. I've never programmed in python but it was easy to run the code and change it to work with only the digits 1 through 5. I then modified the code to output the sequence with commas and spaces to make it easy to cut and paste the number sequence into an array declaration in the Arduino code.

So now I was prepared to whip up some Arduino code. Despite programming for decades I have not done an Arudino project before, so it took a bit of learning to get everything going, especially how to get the sequence holding the array to store in flash instead of being copied into RAM, which did not have enough space.

So now I have a breadboard version of the project that boots up the LCD and displays the sequence rolling across the bottom line of the LCD. I've also added some pushbuttons for the user interface as eventually I want to be able to control playback of the sequence to rewind and step through parts of the sequence.

I'm currently working on wiring up some LEDs to indicate the actuation of the solenoids that will actually push the buttons and a ULN2003 darlington transistor driver to power the solenoids.

Once I get the LEDs blinking and the solenoids tapping, then I can start building a more robust unit that can actually be attached to the car door (magnets?) and also work on the user interface code.

Maybe I can add a microphone that can hear the "thunk" when the door lock opens and stop the playback of the sequence so the code can be read back from the LCD.

Jeff, thanks for your interest in my project. I don't know what those broken video links in the gallery even are. I haven't uploaded any video to the project page or to YouTube yet. I finished a video that shows the device working but then I didn't post it to YouTube because I wanted to go back and do some more editing. I ended up going on for several minutes at the end of the video talking about how the device works with nothing in the video but a shot of my SUV door with the device attached and I thought that wasn't a great way to do that part of the video. So I am going to go edit that out and put the discussion of how it works in a second video at my desk where I can use drawings and slides to explain the operation. But I haven't got around to changing the first video that never got posted or got to making that second video on the theory of the system. Stay tuned, hopefully I'll get that done soon.

I have submitted this project for the Anything Goes round of the 2017 Hackaday Prize. This project addresses challenges in security, with the purpose being to demonstrate how compromises that make user interfaces easier and increase user convenience can reduce the effectiveness of your security system. This principle applies well beyond unlocking car doors, and is becoming more important as more devices utilize similar forms of access control.