I've been playing around with bar codes recently, specifically the Code-128 variant. I'm looking at this particular type because it has some interesting capabilities, the one that interests me the most is the ablity to encode all 128 ASCII characters. This may seem innocuous, but when you think about how most bar code scanners are connected to computers you'll see the problem. We'll get to that later.
Firstly how do you generate a bar code? Once again Linux comes to the rescue. A command called barcode is quite powerful (but hard to google, don't use common names for programs). It can generate a postscript file containing a wide range of bar code formats. For example, I've encoded a message with the command below.
barcode -b '103 34 100 65 82 0 67 79 68 69 83 0 65 82 69 0 70 85 78 1 98 77 26 13 9' -e 128raw -o blog.ps
|Sample Bar Code|
I've used the 128raw mode because it gives me more flexibility and allows me to enter special characters. If we decode that message using the on-line service at zxing.org we can see the text. Note that there is a carriage return in the bar code, this places the smiley emoticon on the next line. You can try to decode it using your phone, but you may not be able to get a good image off the screen. Some bar code apps don't seem to implement the full standard either, so it may not recognise the carriage return.
|Decoded bar code message|
So what you say. Hold your horses I'm getting there. The decimal numbers I used on the command line can be seen in the results above in hexadecimal. The program also automatically adds a parity symbol and a stop symbol to the bar code, these are the last two numbers, 1e and 6a. The parity symbol is calculated by multiplying the code for each symbol by it's zero referenced position in the bar code and then adding them together along with the code for the first symbol. This is then divided by 103 and the remainder is the parity symbol. For example.
103 + 1x34 + 2x100 + 3x65 + 4x82 + 5x0 + 6x67 + 7x79 + 8x68 + 9x69 + 10x83 + 11x0 + 12x65 + 13x82 + 14x69 + 15x0 + 16x70 + 17x85 + 18x78 + 19x1 + 20x98 + 21x77 + 22x26 + 23x13 + 24x9 = 15274
15274 / 103 = 148 remainder 30.
Code-128 is extensive, it has three code sets to select from. The start symbol you select decides which set you use. Later on in the bar code you can switch to other code sets with a special control symbol. This can be permanent, like using caps lock on a keyboard, or it can be for the next character only, sort of like the shift key. I've used both methods in my sample bar code above.
In the image below I've broken down the bar code into sections explaining what each part does. The patterns for each symbol can be found online, they aren't related to the code number, they've been selected using a specific set of guidelines. So it's basically a look-up table situation.
The bar code starts and ends with a empty area known as the quiet zone. The rest is pretty self explanatory. You should probably check out the Wikipedia page for Code 128 bar codes. It has a great table of all the code sets.
I've put the pdf of the image below here. It might be a bit easier to read. If you open, rotate, and enlarge it so it fill most of your screen, you should be able to scan it with your phone. It works for me.
|Anatomy of a Code 128 Bar Code|
So why is this interesting? Does it have to be? Most bar code readers connected to computers are seen as a simple keyboard input device. They don't sanitise their input at all, why would they, they're only expecting numbers and the occasional letter right? Well, with code-128 you have all the ASCII control characters at your disposal. I've tried this on the Symbol MC3090 (the bane of my existence) and it recognises and executes the escape and carriage return symbols without hesitation. I haven't tried the other control characters. I should also mention that most scanners add a carriage return after each scan, kind of like how you enter data into a text field and press enter to go further. With just these two symbols you can automate processes with a specially crafted bar code, kind of like the USB rubber ducky that +Hak5 sell. I don't want to use this for nefarious purposes, I just want to use it to automate some mind numbing tasks, but you could imagine situations like below are possible.
|XKCD - Exploits of a mum|