Where I live, there is a room with the laundry machine. Once every other week, you can use it to wash your clothes.
We have different systems to pay: (pseudo) smart card, coins, etc, it depends on where you live. In my case, it was a pseudo smart card you have to refill with money (to the concierge) every time it gets empty.
Here is how it looks like:
I use the word "pseudo" smart card, because as you can see, it is not really one. Actually, there are only 6 contacts (instead of 8) and there is a sort of bus driving the signal somewhere in the white plastic.
The white plastic was heavily attached to the card, so to remove it, I put the whole card in an acetone bath. After few minutes, I was able to remove it without any pain.
I was amazed to see a simple EEPROM underneath. It already meant that replay attacks were possible, even if we didn't know how to interpret the content: save the content, do your laundry and restore the content afterward.
I was amazed to see a simple EEPROM underneath. It already meant that replay attacks were possible, even if we didn't know how to interpret the content: save the content, do your laundry and restore the content afterward.
We can identify the chip and deduce from the logo that the manufacturer is "National":
71AR
93C46
M8
I found a similar datasheet. However, we'll see that it is not exactly the same.
Since I didn't want to be invasive on the card, I bought a "season 2 interface". This device is usually used by satellite pirate and is handy to do MITM on smartcards. I got mine for 8€.
Since I didn't want to be invasive on the card, I bought a "season 2 interface". This device is usually used by satellite pirate and is handy to do MITM on smartcards. I got mine for 8€.
I also soldered 8 pins on the back of the interface, to inject my signals (I/O of the SPI).
Since we have the datasheet, we can make the pin ring with a multimeter and deduce what corresponds to what on the smart card contacts:
X --- X (not assigned)
Di --- Sk
Do --- CS
GND --- VCC
I'll make a long story short, because I had different, not really relevant issues. To inject the signal, I used the "Bus pirate" (BP) and to verify that the injected signal was correct, I used the OpenBench Logic Analyzer (OLA). The BP is a cool piece of hardware, because there is an interpreter that will help you to send the correct signal with the correct synchronization, so no need to write a program for it. Since I was not mastering it, I used the OLA to make sure the signal was correct. According to the datasheet, the sequence to send is 0y110 + 6 bit address. After some trial and error, I finally was able to dump the whole memory, by sending something like the following command in raw3wire mode, 5V:
Actually, by looking at the longest prefix, we figure out that the memory is 128 B long and looks like the following:
The smallest granularity is 2B when accessing the card (just make the division and it'll fit). At the first look, I don't know what these values really are. So I decided to go to the laundry room, put my card in the reader and pay for a wash. The price was 3.-. Then I dumped the content again and made a diff:
This is interesting, 6 regions in memory changed somehow. But what does 0x0A32 means ? This is 2610, and previously, we had 0x0B5E which are 2910. Remember I told you it costed me 3.-... and what I didn't tell you was the amount of money remaining on my card: 29.10.-. So it is just written in clear in 6 different regions in memory, I couldn't believe it !
The next step was to write 9990 (0x2706) in these memory position and see if it worked. However, to write, according to the datasheet, we have to set WEN, and we just cannot, since all the pinouts are taken. Thus, this is not the good method. I tried to send a "write" command, but without any success :(.
When I was looking for the datasheet of the chip, I found also this one. This is an Atmel, but it turns out the protocol is quite similar. We see there is a "Write Enable", with sequence 0y10011XXXX that has to precede every programming mode.
If we now send a command like
the magic occurs and we see, hopefully, that the content has been correctly written to the EEPROM. This is a good news, so we can now modify the 6 areas we previously found. I did a small script to calculate the offsets, but basically, we need to modify by doing this:
Of course, this can be written in a shorter manner, but for clarity, I leave it this way. To sum up, we just modified the 6 areas in memory to put 9990 (0x2706) in them (99.90 CHF), because it sounded like the mechanism was working this way. Now, let's go back to the laundry room to see if it works as expeced:
]-^^_^ _^:6 r:1024[
Actually, by looking at the longest prefix, we figure out that the memory is 128 B long and looks like the following:
READ:
0x03 0xE8 0x03 0xC8 0x03 0xD7 0x02 0xE9 0x00 0x00
0x00 0x04 0x03 0xEA 0x0B 0x5E 0x01 0xAA 0x0B 0x5E
0x00 0x00 0x0B 0x5E 0x00 0x00 0x00 0x00 0x00 0x00
0x03 0xE8 0x00 0x04 0x03 0xEA 0x0B 0x5E 0x01 0xAA
0x0B 0x5E 0x0B 0x5E 0x00 0x00 0x00 0x00 0x00 0x00
0x25 0xAE 0x15 0xB3 0x1A 0x0A 0x00 0x00 0x00 0x00
0x00 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
The smallest granularity is 2B when accessing the card (just make the division and it'll fit). At the first look, I don't know what these values really are. So I decided to go to the laundry room, put my card in the reader and pay for a wash. The price was 3.-. Then I dumped the content again and made a diff:
READ:
0x03 0xE8 0x03 0xC8 0x03 0xD7 0x02 0xE9 0x00 0x00
0x00 0x04 0x03 0xEA 0x0A 0x32 0x01 0xAA 0x0A 0x32
0x00 0x00 0x0A 0x32 0x00 0x00 0x00 0x00 0x00 0x00
0x03 0xE8 0x00 0x04 0x03 0xEA 0x0A 0x32 0x01 0xAA
0x0A 0x32 0x0A 0x32 0x00 0x00 0x00 0x00 0x00 0x00
0x25 0xAE 0x15 0xB3 0x1A 0x0A 0x00 0x00 0x00 0x00
0x00 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
This is interesting, 6 regions in memory changed somehow. But what does 0x0A32 means ? This is 2610, and previously, we had 0x0B5E which are 2910. Remember I told you it costed me 3.-... and what I didn't tell you was the amount of money remaining on my card: 29.10.-. So it is just written in clear in 6 different regions in memory, I couldn't believe it !
The next step was to write 9990 (0x2706) in these memory position and see if it worked. However, to write, according to the datasheet, we have to set WEN, and we just cannot, since all the pinouts are taken. Thus, this is not the good method. I tried to send a "write" command, but without any success :(.
When I was looking for the datasheet of the chip, I found also this one. This is an Atmel, but it turns out the protocol is quite similar. We see there is a "Write Enable", with sequence 0y10011XXXX that has to precede every programming mode.
If we now send a command like
]-^_^^-^^^^^^^^[ ]-^_^-^ -^^^^^^ 0x12:2[ ]-^^_^ -^^^^^^ r:128[
the magic occurs and we see, hopefully, that the content has been correctly written to the EEPROM. This is a good news, so we can now modify the 6 areas we previously found. I did a small script to calculate the offsets, but basically, we need to modify by doing this:
]-^_^^-^^^^^^^^[ ]-^_^-^ _^^^-^^^ 0x27 0x06[ : 7th word
]-^_^^-^^^^^^^^[ ]-^_^-^ _^^-^_^^-^ 0x27 0x06[ : 9th word
]-^_^^-^^^^^^^^[ ]-^_^-^ _^^-^_^-^^ 0x27 0x06[ : 11th word
]-^_^^-^^^^^^^^[ ]-^_^-^ _^-^_^^-^_^ 0x27 0x06[ : 18th word
]-^_^^-^^^^^^^^[ ]-^_^-^ _^-^_^-^_^^ 0x27 0x06[ : 20th word
]-^_^^-^^^^^^^^[ ]-^_^-^ _^-^_^-^_^-^ 0x27 0x06[ : 21th word
Of course, this can be written in a shorter manner, but for clarity, I leave it this way. To sum up, we just modified the 6 areas in memory to put 9990 (0x2706) in them (99.90 CHF), because it sounded like the mechanism was working this way. Now, let's go back to the laundry room to see if it works as expeced:
First post
ReplyDeleteNice, now none of us have an excuse for turning our pants inside out and re-using them
Very good work, I have tried in the past medling with various smart cards for utilities but never got very far :)
ReplyDelete:D ha ha ha, this is genius!
ReplyDeleteThe hack is great, but remember that a real person owns the laundromat and you are actually stealing from them. So don't do it again. What a fun hack though.
ReplyDeleteCongrats!.
ReplyDeleteNext step, smart cards, bus cards...keep on, and don't forget to post it =D
Great post, love the fact that you get ^_^ in the commands
ReplyDeleteYou should decode the rest of the card to find out if its tied to your room or you personally. Then leave one laying around for someone to find :) nah, not really but very nice proof of concept, maybe show the owner and he may give you free laundry just for bringing it to attention.
ReplyDeleteWhat about fuzzing the reader, with malformed data ?
ReplyDeleteKeep up to good work
Code execution, leading to everybody getting free laundry! (until rebooted).
ReplyDeletereally enjoyed reading this hax. ^_^
ReplyDeleteHi!
ReplyDeleteWhat u used to log traffic?!
I need to log traffic from sc to the reader with that logger.
Thank u m8!
Actually, with the season2 interface, there is a RS232 output (which didn't work in my case). It probably works if you try it with a sat card. However, I soldered 8 pins on the back of the season2 interface. Then, I plugged on the pins the Bus pirate & the OpenBench Logic Analyzer. I also tried to sniff the traffic between the reader and the card with the Logic Analyzer (plugged to the pins), so this is probably what you wanna do.
ReplyDeletevery very nice!
ReplyDeleteI also live in switzerland and wanted to do such a thing.... but never got time.... are you around lausanne?
Yep, still around Lausanne city ;)
ReplyDeleteVery interesting to see that security relies on thinking it's too complicated for "common" people ;-)
ReplyDeleteI had a look on your sequences and after reading the serial eeprom datasheet I think you can remove two clock ticks that are not needed.
EWEN: ]-^_^^-^^^^^^^^[ (1 00 11XXXXXX)
EWEN: ]-^_^^-^^^^^^[ (1 00 11XXXX)
Thanks for the Bus Pirate presentation, great tool !
You can also use PonyProg to write directly to the 93C46 chip...we have the same card system, but different brand. Greets from Genève.
ReplyDeleteall this is great but where do i get all this equipment and how do i learn all this codes or values? i mean im just curious i like to work on complicated things and beacause im actually a normal person with no much knowledge of what you seem to be an expert, please share some tips with me , thank you!
ReplyDeletehi...
ReplyDeletei am Gaurav Garg From How To Hack A Computer
i like your web site or all available content but i like this post the most..
thanks for providing this information in this open way..
Regards
Gaurav garg
Keep Posting
Have A Nice day