ccTalk - Part 1 : The protocol
Published on 11 August 2013
This article is the first part of a series about the ccTalk protocol. This follows the talk I made at Defcon this year (slides here : defcon2013.pdf)
The ccTalk protocol is used to transfer information and commands to various money processing device, including coin/bill acceptors and coin hoppers.
The bus itself uses UART communication (usually 9600 b/s - 8N1) at TTL levels (0 - 5V) with only one wire, which means the communication is only made half-duplex. As multiple devices can be on the same bus, each of them has its own address on that bus so they don't conflict with each other.
The specs are available on the Crane Payment Solutions company(previously Money Controls LLC) website : http://www.craneps.com/en/products/view/151
It contains many protocol information as commands description and usage and more.
A ccTalk frame is composed of the following elements :
[destination] [length] [source] [header] [data] [cheksum]
- Destination : The destination address
- Length : The data length to follow
- Source : The source address
- Header : The actual command sent to the device
- Data : header-related data
The data length is limited by the specifications to 252.
The addresses are encoded in a byte, which means that a maximum of 255 devices can be used on a single bus. The address 0 is the broadcast address. All devices must process the request and respond with source address 0.
The header field is the actual command sent to the device, it contains a single byte representing the action that must be taken by the destination device. All these headers are documented in the protocol specs and can take arguments that are added in the data field of a frame.
For instance, header 254 (0xfe) is the "Sample poll" header. Any device that receives this one needs to respond with an ACK packet (ie an empty response frame).
Regarding responses, all of them use header 0, which can be considered as an ACK packet. The header 5 is used as a NAK response. There is no indication about the initial request in the response frame. It is normally not a problem, as normally only the controller sends command to devices, but if we want to sniff data on the bus, we will need to know the request before parsing the answer.
Here are some example packets :
[ 02 ] [ 00 ] [ 01 ] [ fe ] [ ff ] [destination] [length] [source] [header] [data] [cheksum] Sample poll from device @1 to device @2 [ 01 ] [ 00 ] [ 02 ] [ 00 ] [ fd ] [destination] [length] [source] [header] [data] [cheksum] Response [ 02 ] [ 00 ] [ 01 ] [ f6 ] [ 07 ] [destination] [length] [source] [header] [data] [cheksum] Request manufacturer ID from @1 to @2 [ 02 ] [ 03 ] [ 01 ] [ 00 ] [4e5249] [ ff ] [destination] [length] [source] [header] [ data ] [cheksum] Response contains ASCII-encoded response : "NRI"
Sniffing and interpreting data
I couldn't find any open source ccTalk sniffer out there to decode ccTalk frames properly, so I created two tools, one that can be used to sniff a ccTalk bus and show live packets and an other that is used to parse sniffed data and display frames in a nice curses interface.
All the tools use a Python ccTalk library I made. This library is able to parse packets as well as generate new ones using few lines of code :
>>> import ccTalk >>> m = ccTalk.ccTalkMessage() >>> print m <cctalk src=1 dst=2 length=0 header=0> >>> m.setPayload(254) >>> m.getPayloadType() 'Simple poll' >>> m '\x02\x00\x01\xfe\xff'
The parser itself is easy to use, just pass a binary file and it will extract all ccTalk frames it can find :
Using these tools, it is quite easy to actually understand how a ccTalk-enabled device works and use it in your own projects.
All the tools can be found here : https://github.com/Baldanos/ccTools
To test ccParse, here is a ccTalk traffic capture : ccData.bin