Skip to content

Web Laundry, Smart Cards, Python and OS X Smorgasbord

Disclaimer: This article is for informational purposes, the author shall not be held liable for any actions taken on the basis of the information presented. I do not condone fraud, theft, or other malfeasance.

In September 2010, posted an article about the insecurity of the stored-value smart card system used by Web Laundry (now Wash Laundry). I’ll let that article stand on its own — it gives a good overview of the bone-headed system that the engineers there had in place. In short, they used a secure memory card made by Atmel (specifically, from the CryptoMemory line), the AT88SC0404C (datasheet here), but neglected to change the default master password. This means that all you need to read or write the stored data is a ISO-7816-3 compliant smart card reader.

This is where my story starts — this summer I’m living in a dorm that uses a Web Laundry stored value system. That was enough of a push for me to buy a smart card reader, seeing as I’d always wanted to play with them, and this looked like a good opportunity. I picked up a smart card reader from, an SCM Microsystems SCR3310. It was both cheap and, according to the manufacturer’s product page, offers full ISO 7816, CCID and PC/SC compatibility (i.e. all of the relevant standards), as well as drivers for OS X, which is my primary operating system for the time being.

Doing some research, it turns out that Apple ships a (modified) version of the open-source PCSC Lite framework for smart card integration. This means that all I would need to get up and running was a driver for my device and a way to interface it. Once the reader arrived I installed the drivers, and ran pcsctest (from PCSC Lite) on the command line. Sadly, all I got was an error message:

Testing SCardEstablishContext    : Service not available.

Googling told me that the appropriate services are supposed to start whenever a smart card reader with appropriate drivers is plugged in, which made this error all the more confusing. Luckily, I found this thread on SCM’s forums — it seems that the driver they have posted doesn’t include the USB identifiers for the version of the reader I had, but a helpful poster left instructions to modify a plist file in the driver (mirrored here for archival purposes). With that, I was up and running!

pcsctest spat out useful output this time around:

$ pcsctest

MUSCLE PC/SC Lite Test Program

Testing SCardEstablishContext    : Command successful.
Testing SCardGetStatusChange
Please insert a working reader   : Command successful.
Testing SCardListReaders         : Command successful.
Reader 01: SCM SCR 3310 00 00
Enter the reader number          : 1
Waiting for card insertion
                                 : Command successful.
Testing SCardConnect             : Command successful.
Testing SCardStatus              : Command successful.
Current Reader Name              : SCM SCR 3310 00 00
Current Reader State             : 0x34
Current Reader Protocol          : 0x0
Current Reader ATR Size          : 8 (0x8)
Current Reader ATR Value         : 3B B2 11 00 10 80 00 04
Testing SCardDisconnect          : Command successful.
Testing SCardReleaseContext      : Command successful.

That left me with the issue of interacting with the smart card somehow. In case you hadn’t guessed from the post title, that solution was Python. Specifically, the pyscard bindings for PCSC Lite, from There’s a nice array of examples, and so I wrote up a python script for interacting with this particular CryptoMemory card, based on the command set from the datasheet and the examples. It’s not as polished or feature-rich as the software Hans posted, but if you’re running OS X or Linux, it should be helpful. At the moment this script is extremely rough — it gets the job done, but in an ugly and unsafe way. I’m posting it here, but you SHOULD NOT USE IT IF YOU DON’T KNOW WHAT YOU’RE DOING. If you aren’t careful, it will mess up your card. Hopefully I’ll have time to wrap it all in a library that will abstract away the messiness and provide nice features like exception handling; if I do, you’ll see it here.

Using my script I was able to verify Hans’ findings — although the card is configured to require cryptographic authentication to access the user zones (where the goodies can be found), the password is left at the default value, which makes overwriting the access registers and conducting a replay attack (as demonstrated by the video in his post) a walk in the park. Following his example, I won’t post any information on how the cards store their values, but it’s surprising that this security hole still isn’t fixed, seeing as it would cost nothing to overwrite the master password when they first configure the cards.

Hopefully this post will give some of you who’ve wanted to work with smart cards a push in that direction — although there are a few hurdles along the way, it’s an interesting area to work on. I’m hoping to move on from poking at other people’s cards and start using my new hardware for authentication and encryption.

Happy hacking!

{ 2 } Comments

  1. Cristian | March 17, 2013 at 6:56 pm | Permalink


    I tried the program, but I’m getting empty .bin files.
    The “write_ar” functions are returning a 69 00 response instead of the expected 90 00.

    Any ideas?

  2. sethjust | December 6, 2016 at 8:52 pm | Permalink

    To answer the commenter above (3 years late), the datasheet defines 69 00 to mean “The command is unauthorized” (see page 49). Most likely the password was incorrect, which would be evident from the response to the authorization command.

Post a Comment

Your email is never published nor shared. Required fields are marked *