← All talks

Breaking Into My 3D Printer's Firmware

BSides TLV · 201844:38200 viewsPublished 2018-11Watch on YouTube ↗
Speakers
Tags
CategoryTechnical
StyleTalk
Mentioned in this talk
About this talk
breaking into my 3d printer's fimware.flv - uri shaked BSidesTLV 2018 - Tel Aviv University - 19 June 2018
Show transcript [en]

it's a very promising I really looking forward to it thank you good luck Thanks Cheers so yes so good book everybody my name is URI yeah so I'm worried shaked I'm a front-end web developer I my day job is I worked part time for blackberry yes they still exist and in my free time I do a lot of fun stuff which I'm going to tell you about right now so these are the slides I also be quiet mister feedback I also share them on Twitter so you can find the link to the slides on my Twitter it's going to be up here if you can see the mouse it's going to be up here for the

duration of the talk so let's start my story starts a few about a year ago or a little more when I found this 3d printer on Kickstarter and of course I begged this printer it came with a lot of promises and I decided I want it I want to have it how many people in the audience have 3d printers so it's fun when it works but unfortunately this Kickstarter process a problem progress project came with a lot of promises but failed to deliver the real thing behind the real story is that tourists earlier I ordered another printer from the same company on Kickstarter and it was pretty much a failure this software didn't work at all and the hardware was pretty good

so in this new campaign they said we learned from the past mistakes and we are going to do it so much better and we are also going to open source the femur and everything and I believe them luckily for the older printer the micro printer the micro 3d printer they all the one there was some guy from the community who created an open-source framework and a better software which made the that printer work perfectly so when I got my new printer my M 3d Pro I was hoping for something similar to happen and then I saw this comment on github basically it's the same guy who built the alternate femur for the meat the micro D alder printer and he said

getting our femur to run on the micro plus or the MPD Pro that was my new printer first requires figuring out how to decrypt an 3ds official femur he also included a lot of information about how he did it with the previous femur and at some point here we mentioned they used the substitution cipher so anything funny about substitution ciphers all right perfect everyone should use it and we're going to see why right now so I said okay decrypting em 3ds official fumer accepted challenge so I had his femur and I wanted to decrypt it how would I go about it I had two options first of all I needed to get to put my hands on that

femur one option would be just to try to connect with the hardware with a microcontroller inside the femur and extract it somehow the problem is that it would void warranty and there is a good chance I will destroy my femur so I tried to see if I could somehow get through the femur update mechanism and extract the femur from there which was supposedly encrypted as the guy said on the github comment so I tried to download or I downloaded this where and how many of you know dot pic not too many am I in the right place anyway dot pick is a nice tool that allows you to take dotnet projects D compile them so I loaded their software

which was written in dotnet into dot peak and I found in one of their file this resources section which included very promising files called M 3d embedded femur I found four of them they only had three printers I filled out later why they had four here so after I extracted the femur we had a fun part of trying to figure out what kind of encryption be used and whether we can defeat it somehow and this is what we are going to do now together we are going to walk through the journey of decrypting this femur so initial analysis you get a new femur you start looking at the file first of all it had no readable ASCII strings so obviously

it was encrypted I hope maybe it would not be but it was the file size was forty fifty four kilobytes but when I try to compress it it was smaller so this means this was not some kind of a s encryption and that substitution cipher was very likely here I also find found another comment on get up saying that this was an SDN 32 CPU which is armed little india and i found the documentation for the cpu which will see how it turned useful in a bit and then i also found some mention that there are actually two female files which explained why they had four fumer files in the software for only three products

so we are going to use both of this ephemeral file through our firmware defeating process so the first thing I did was taking the file and trying to analyze it basically I used Jupiter which is repple for Python how many Python reading people do we have in the audience all right so I am in the right place indeed and Jupiter is a very nice tool used in the data science community so let's open Jupiter and I hope can you see the code here is the font large enough please say yes yes I get likes if not please move to the second row so basically I have here a little code that these imports we are going to use later

the tweets the fumer from the encrypted filmer from a file and the first thing I did was simply to create a histogram that shows for each of the byte values how common they are so we are not going to go over all the code I will just explain what each what each block of code does so we can get to the exciting parts faster so let's run this and we can see this histogram which has a very nice this spike in the middle so there was one byte which appeared much more than the other byte one value that appeared one more much more this is the value the zoom is too large so we can't

see it here but this was 138 139 I still remember this so my guess that was that this was not this was 0 0 is a very common value in a few more files because it appears in memory address s a lot of pointers every now terminated string is obviously terminated by now so my first guess was that this spike that we see here the most common value 139 was actually 0 so with that in mind I started creating a small table let's do it together here that map's 130 nine to zero that's our first guest for today then I went to the Fillmore file and I started just you know going over it and then nearly this is the Fillmore

file the encrypted one and near the end of it I discovered is one F one F one F one F actually have a slide for it so so yes you can see those one F 1 F 1 F 1 F near the end of the thermal file and my guess was usually when you have few more files they are padded with f FS because of the way flash memories works that's the best value for padding because it can be overwritten later so my guess was that this sequence of 1 FS actually stood for F F at the end of the file so with that second guess let's update the table and say that one F maps to F F

not F F F and I already guessed two characters 0 and F F which were the easiest and now I started like trying to explore a de fumer see if I can find any patterns and interestingly I don't know if you can see it here but I have a slide for this I found at the beginning of the femur so this 8 b is actually 138 9 in hexa which is the zeros but then we have a lot of twenty fours and by reading the documentation for the CPU I found at the beginning of the femur actually contains interrupt vector which is just a list of pointers to functions that handle specific events that happen

on the system and I also learned from the CPU documentation that everything all the flash memory all this femur is loaded to 0 0 0 8 so there is a lot of repetition here and I know these are this or should the addresses that are mapped into the femoral code so I and this is zero zero and this is a little endian cpu so my next guess would be that ninety four would be zero eight so this would be a legitimate memory address so let's add this guest to the table as well that would be nine ninety four would be zero eight and we have those we have those three bytes we guessed so let's check on

our progress we have about 1% of the firmware and this was about two hours of work into guessing and at that point I was like okay there is this huge file with a lot of zeros and some other random bytes how do I continue from here and I had this idea what if I look for strings you know but the thing is you won't find the strings in the file but if I knew one of the strings that is likely to appear in the fumer and it was long enough perhaps I could find a pattern of repeating letters in that string so before we see that I went began to dot pick and looked at the

software that runs on the computer and found a file called femur controller which sounded really promises promising where I found is unable to Hindi in it hardware check micro micro motion cable connection and I took this string and the first thing I wanted to know is how many repetitions are you having this string so hoping that this string would appear in the femur I wrote the following snippet it's a little bit long but basically let's run it what it does it creates this nice plot where you can see each star each different height represented the and character different letter so this one is above a so the green one represents all the a and we can see the

eight characters repeats for time and basically this chart visualizes how many characters are being repeated the pattern of repetition of characters so we can see there are a lot of there are a lot of repetitions like these above the sea this purple one repeats 16 and then we have these Oh red one above the O which also repeats like six times so this string had a very distinct pattern of character repetition so we know the spacing and how many times they should repeat and with that in mind we can write some code that we look for a pattern of this repetition and try to find a match so I went ahead and let's add a new block yes and I crafted some

code that would try to find this pattern so this is the string again and then I have this code that basically goes over the entire framework and goes over the search ring and tries to find a match to the pattern and if it does it's it's print hey I found it and updates our table with the corresponding keys so as you can imagine I debug the rotate debug date ran it and it ran no output nothing found but if you look at the string it says me micromotion caliber cable and micro was their older model so perhaps this string was just not relevant from my specific framer they had the same software for all the models of this

printer so I went to look for other strings with a lot of repetition and luckily I could find another one that was repetier protocol and you can see how many E's and O's and ours we have repeating here so less repetitions but still unique enough so I said okay why won't I just copy paste this code and try to search for it and I copy paste of the code run it again and yet again no match so so far I spent like more more more than 10 hours trying to figure this out and I only figured out around 1% of the dictionary for decrypting this fumer but I decided it was not a time to give up

yet and I tried to look at the code that I used for the micro Treaty so the guy on get up posted the exact process that he used for micro Treaty and he also open sourced the code that encrypts and decrypts their femur so looking into that code I actually found on github this is the code and nothing is important here I just want you to take my word for it if we find the right line so yeah this is the line that actually does the description from the table and what you can basically see here this little expression basically swaps any pair of adjacent bytes and take my word for that we are not going to spend time

on that so in the micro femur they swept any pair of adjacent bytes and I wanted to see maybe that was the part I was missing so I went back to my Python and I added another method just before loading the femur that would just swap the pairs of bytes so let's go over this let's run this method and if you are really quick python reader you can identify this expression from the C code that we saw earlier just written in pythons way and let's run this and run this so now we have reloaded the fumer but with every pair of bytes swept just like they did with the micro and i prayed for the gods of

the cryptid Froome encrypted humorous and run this code again searching from unable to he need the hardware bla bla bla bla bla ah no not that code the one below so I ran it again and it found it

so well thank you first sign of progress and since I already copy pasted the code with the other string I also ran it and it found it as well so I wrote another method so I could easily measure my progress and I call it obviously call it progress so we have 8% of the femur figured out and oh another thing I want you to notice is that the offsets for to these two strings is 48 something and this is also 84 something and this is also 48 something they are both very close so I figured out this part who could probably be where they have the strings so the next step for me would be

for us would be to try to look there and try to see if we can guess some of the letters there so I wrote a small hex damped method you can probably some of you can probably recognize these escape characters that will put colors in our exams and I will show you in a moment what this does let's run it first so this is our super-powerful hex dump and [Music] we are going to try to dump the area of the string and make some guesses so that would be first SK and now you can see their output of this hex dump and as you can see it prints the bytes that we already know and for those we still

don't have the translation it prints them in purple so we can easily tell the difference between bytes that we already know and bytes that we do not know yet and by looking at these strings we can make a few wild guesses here like this ear more name you could probably guess what the first letter would be right yeah shout it out it you're right right right so let's update our table rerun the code and we can see it says formal name framer Ian Aryan any ideas yeah yeah yeah I just need to copy paste this correctly so we have this say it louder I couldn't hear the ass it sounds like F but it's an S right actually no

this is V that's okay that one was incorrect and that would be the 23 I guess alright so we have this guesswork and now it reads three more version and we also have machine to pool why I also asked myself why why am I doing this to myself you know anyway so type and then I took the liberty so we can see serial number which is another string and this gave me the confidence we are going through the right path and we also have this M D yeah three that's right so let's put our tree that would be sixty something so that would be a tree and then table is not good you only want a table okay so

we have M 3d underscore P something and since this name of the product is M to the pro I would guess that this to Carter's are our and O so let's try to add them as well so for T a and F 5 would be for our and oh and by the way thank you for helping me love that we are doing this together so yeah so at this point I took a few guesses and I have most of the letters it starts to look promising like we are onto something so I went over both femurs and I was looking for even more ASCII originals with ASCII characters when I found this nice thing next to the

end of the second femur and as you can see it figured me out a lot of characters we are going not going to do them by hand but basically this is what is so when I started h o bo d any guesses all right so I guess I started by guessing that this Bo AR D would be bored so I guess it's a guest a and D and made a lot of other gases which revealed this string said hello board hi nice to see you today try D and then it was cuz I really wanted to know what I needed to try so I tried to google it but no results if you know where these

come from I would love to learn from you anyway with that in mind I went and looked for more ascii and i found a few more regions and fumer strengths that I added to my dictionary and at this point I even found % and at this point I was pretty happy I type I type progress and we are only almost 20% just by doing some guesses we got 10 more % so where can we take this next we are I scanned files a few more times we were out of ASCII strings so I started looking for other predators when I found this mysterious table I found in the smaller femoris some offset where I had an

interesting pattern let me show you this so this would be the mastery table and you can see here this is a table and it has this see II ll be T WA WI and this is an ascending sequence of letters and then we also have an ascending sequence of lowercase letters and at this point I said okay I have most of the uppercase letters let's check which letters I'm still missing and try to figure out if I could just put them in missing spots so I wrote another small snippet that would go over the table that will be in so far and look for all the escalators and prints the ones that are missing and we

have only a few missing letters we can see we have G and J Q X and Z so we have C e something something L and since the only letters we don't know are G and J and these are also the only letters from this list that happened to be between e and L and we assume that this is actually an ascending sequence we are going to make another guess and say that and say that these are G and J and let me say so this was G 95 and J would be just next to it 27 so that would be G and that would be J and I have a little OCD so excuse me for that and then we

have L Oh something T and the only letter we are still missing our Q X and so that must be cute so again a table position what was that e 8 0 XE 8 equals to Q and then just to run it again we have this nice sequence I did a very same process with the lowercase letters just trying to deduce what letters we could have and we're not going to repeat it right now I'll just write a result and we had this nice sequence there was one letter here I couldn't figure out because we had both let's update the list of missing letters we had both P and Q which are next to each other so I

couldn't guess which one would fit here between M and s and at this point I was looking at the beginning and I found this interesting pattern where you have 0 0 0 a lot then something something something something something something a lot of repeated bites and then 8 8 8 which we figured out at the beginning so I thought to myself perhaps this would be 1 1 1 2 2 2 3 3 3 etc perhaps this is again ascending sequence and I just tried to match and there was 7 different values between here and here so it seems like a good match so obviously I updated the table with these guesses as well and okay and let's print this again with the

new guesses and it seems like a good match so we have the start of the beginning of the double table we have some D values at the beginning of the middle of the table and it seems like it's some sort of curve represented here because we had this value 0 repeating for a lot of times and then we had less number if you want less toothless tree like it seems to reduce the number of repetitions and then in the middle we have every other letter so approving in this table and near the end we can also see FF and a few more repeating characters I could try to do more guesswork and try to interpolate the

values in the sequence but I decided to turn to Google at that point and to Google this string hoping hoping Google would open of course I do all my searches incognito hoping I would find something and I indeed found this string in a lot of the results results but if you if you look closely you will see it looks promising but then the lowercase letters are ACF or ADF and I had different lowercase letters so it looked promising but I couldn't find anything that matched the other letters I had in this table so I ran a few more searches I tried to search for the lowercase letters and then I try to search for you know the

hex values maybe they are represented as X values so running this hex value search with quotes or will find exact matches and basically I found do you like riddles but it's not the riddle I was looking at when it occurred to me that if I just add 0x at it before each of the characters each of the X numbers I may have a better chance so I googled it correcting nonlinear brightness LEDs interesting the printer had an LED that was blinking like fading on and off and this seems like this could be something useful for the femur and it's from electronics s tacky J exchange so it must be legit trust me on this so I

opened this answer and started blah blah blah blah and nice this is a curve and I was expecting to find some care of and here is a table here's the full set of 256 levels that I used so somebody posted an answer how to control the brightness of the LED LED on Stack Overflow so I was really pumped I just could be pasted it into my jupiter notebook let's close this incognito thing and paste it so I just copy-paste the entire table and I wrote a little snippet of code that would just go over each of the bytes try to match them with the bytes on the table if this is a value that we already know we already

have it in our table we compare it with what we expect to find there and if it fails we die miserably with an assert otherwise we just update our table and to my surprise I run it and we had a perfect match

so time to check on our progress and we see we have 70% of the femur we are getting there this at this point I started to develop new hope so I found this mystery table which turned out to be the controller for the brightness of the LED and then I found I googled it I found a table and we saw some light at the end of the Fatimid tunnel and then I went to look for other patterns in the femur where I found another table so let's have a look there that would be the second table right so I found this table and you can see there is like this nice column here which read Chrissy

something we don't know that repeats all of time 3e and then something we don't know again so a wild gas would say that if this is Christy and this is 3e this would probably be 3d like the printer and this one would be 3f and I also had another guess that since we had another column here that started with Christy but it had these 22 it could be 3 be the value before so I ran this guesses and now with this guesses the table looks like 3 B 3 C D looks legit and at this point I was started to wonder what the other values could be represent like its group of 4 bytes actually it's little India and so we

read it this way these are groups of 4 bytes and they they seem to be increasing that when I try to convert it to a D word it didn't mean a lot to me I would like seeing an increasing sequence with some difference between the numbers but they had no meaning and then could you guess what it could be if it's not D words so I had another guest this might be floating-point numbers so I wrote a little code I basically just copy pasted some of those some of those numbers like this one from the sequence and tried to ask Python to print them as little endian floats and I found out these were all floating numbers between 0 and 1 and

they were increasing they were in a setting sequence so it seems to be like a function that goes between 0 and 1 and in order to know what his function looks like I decided to plot it so I wrote a little code snippet that would just go over this table from the float offset in jumps of 4 go over each set of 4 bytes see if we have all of them in the table if we could find translation for all of them we would just add them to an array otherwise would put none so we'll have a plot with all the points that we know and spaces where there are points we don't know so I found this table I

figured out how this could be floats and now I'm going to try between 0 and 1 and now I'm going to try to plot them to see what it looks like oh I have 10 minutes I thought I have 7 thank you in bar so I can breathe and take a sip of water before we blow to these numbers I love title so this is the numbers that we found it's indeed an ascending sequence it seems like another kind of curve why am I wasting real estate on the address bar I don't know it seems like a real nice curve and at this point I was like okay I have those points I have the missing points it's Python it

can help me find a missing points and I remember there was a way to interpolate if I have a function I could interpolate but to be honest not too much into data science so I turned into two of my friends I can't see if they are here in the audience avi I mean of and Yanni Rosen shine were more into math and data stands and they told me yeah there is this package called Syfy and it has this amazing function called interpolate which can take a list of numbers with some gaps and fill the gaps just what we need here so for another snippet called interpolate basically there is this interpolator that builds the list of the

points that we already know there X values and Y values and we called Saipa interpolate in Terp 1d which should yes create a function that guesses the gaps and then we plot the original points and they interpolated points so the interpolated points will be yellow and the original ones will be green let's do this and just to see if yeah if it guesses well and these are the interpolated points the points that Python guessed for us all the can you see the difference between green and yellow yes yes like like like like okay let's actually make it even easier yeah let's change these ones to an X so yeah so we have all these guest numbers now

since these are floating-point numbers and these are just guesses we could be off by one by by like one or two because these are just guesses and floating point is not super accurate but I try to so we know the most significant byte of each of those numbers these are like this like this 3 e 3 F 3 D and 3b that we guessed and we want to fill the gaps in the second most significant byte so even if there is an error there is a lower chance of an error in the more significant bytes so basically I wrote another snippet of code that we are going to run now and that snippet of code would know that we already run that

we try to predict the missing values for the second most significant byte in places where it's still missing and basically it just takes it goes over the points we are only going from the tenth point since we can see that at the beginning we only have two data points and the curve is kind of high so there is a better chance of errors so we just try to interpolate the values between this point and the end of the curve and basically we're trying to see whether our predictions match the actual bytes there just to check how close we are I'll close our predictions for bytes we already know and then for bytes we don't know we just update our table with the

prediction so let's run it and we are trying to predict the second most significant byte for each of the few Moabites and this had no errors which means that thank you in bar which means that we still have five minutes to do the next byte amazing which means that all the predicted values match the values that we already know and for some of those values these values that did not appear in our original points array because they had other bytes missing so this is a good signal that our prediction function works well and we also fill the table even more so now we are 85% it feels like we're all almost there I think we are also up 85 percent

of the time so that's a perfect match so the next thing would obviously be to do the same let's update the plots let's plot them again so this is now with the new bytes that we predicted they are already in the table so we already see them on the plot and we can update our predictions as well and just a moment let's run this one again so yeah so we see a lot more green and less yellow and we are going to do the same now with a third most significant byte and hope we still get a good amount of matches even though the precision drops as we go to the least significant bytes so running the same

snippet again and again and again and again predict missing bytes but this time we are going to go one byte back to the byte number the second byte it's little endian so the most significant is three next is two and now we're going over byte number one and here we see that there was one error that could be expected because the precision went less but we spotted that we already had read translation for the value that we guessed incorrectly so we just skip that one and we see that we have ninety-eight percent of the femur and no other errors so we are probably doing good at our guesswork and at this point I felt like we are still missing

20 values and that would be a good time to stop doing data science and looked for patterns and actually try to look at the code so I opened I da and I wrote a little script that would go over the disassembly and whenever it found a line which had a missing bytes it would color it red and then I created a keyboard shortcut that would allow me to cycle through the possibilities because we only had 20 possibilities to fill in and after about three hours of finding small functions trying to figure out what they do I mean with this function you can see it touches it load something into r1 and then it compares r1 to zero

and then it does something and then the missing byte obviously it doesn't make a lot of sense here where we compare our six with rst with where we load something into our six because we don't have our six mentioned here and the next thing we do is compare our one so we would there would be much more sense to have some opcode here that would do something with our one that would load a value into our one and going through all the twenty possibilities I found only one that loaded something into r1 which was that one so I did this until I figure out the rest of the missing 20 bytes which finally revealed this secret

of the femur and the end of the story

so he takeaways before we when we wrap up when you are doing such a thing look for patterns everything was found I found here was just because I found some patterns that code my eyes and I decided to dig into them use data science tools Python rocks it helps it's hard and frustrating so don't give up thank you

Wow thank you