Dumping the Firwmare from a Ham Radio TNC

TNC

After working on my WinAPRS exploits, I had a thought that my ham radio TNC (radio modem) could have vulnerabilities built right into the TNC itself. I have a Kantronics KPC 9612+ TNC. I think it originally was released sometime in the 1990’s and was finally discontinued in 2020 for a newer model. Mine still works just fine, though. The TNC runs its own little operating system that supports decoding different kinds of packet data. You connect to it via serial terminal and are presented with a command prompt. From there you can edit configuration options, setup a local BBS, decode APRS packets, and much more. I figure with all of those functions there is opportunity for security bugs. I just need a way to find them. I figured the best place to start was to crack it open and have a look inside.

TNC guts

The main CPU appeared to be a Motorola MC68HC11K0CFN4.

CPU

There was also a PIC microcontroller.

PIC

I also found an external EPROM chip and RAM chip. The sticker on the EPROM was labeled “KPC-9612P 8.2”. It was a good bet that this was the main firmware for the TNC.

EPROM and RAM

I wanted to dump the firmware from the EPROM but wasn’t exactly sure where to start. I figured I should find the datasheet and figure out how you are supposed to interface to it. The EPROM is a M27C1001-10F1 chip. I found a datasheet at DigiKey The datasheet revealed this chip was a 1Mbit (128KB) parallel EPROM running at 5V. The parallel bit was annoying because it apparently meant that in order to read the firmware, I’d need to interface a ton of pins.

A parallel EPROM requires you to set the address you want to read or write to using a bunch of address pins. The chip will then reveal whatever byte is stored at that address on eight output pins. Each of the output pins represents a single bit of the byte you are reading. Because this was a 1Mbit EPROM, it meant there were 17 address pins! So that’s 17 address pins plus 8 output pins for a total of 25 pins! That doesn’t include power, ground, and the two enable pins. Here’s the pinout diagram from the datasheet.

EPROM pinout

I had never attempted to read an EPROM before, so I did some searching online and found a helpful post that showed how an EPROM could be dumped using an Arduino Mega. The Mega was required because it had way more pins than an Uno. Unfortunately, I only had an Uno available. Fortunately, this gave me an excuse to buy a new toy! I ordered an Arduino Mega and it arrived a few days later.

The example from that blog post used a smaller EPROM with less pins. I had to modify the author’s Arduino source code to use the pins I wired up myself, and to include more pins to read more data. It wasn’t hard though. The template provided was very helpful. In no time I had a simple EPROM reader wired up. My modified source code can be found here.

EPROM reader circuit

The EPROM reader program simply dumped the code to to the serial terminal as hexadecimal digits along with the ASCII representation.

Serial output

I scrolled through the output and eventually found some readable ASCII data that made me think I must be on the right track!

ASCII data

I copied all of the output to a text file and used some bash to remove all of the ASCII data, leaving only the hex values behind. I then wrote a simple Python script to convert the hex values to binary data and write it to a new file.

from binascii import unhexlify

data = b''

with open('kantronics.hex', 'r') as f:
    for line in f:
        data += unhexlify(line.strip())

with open('kantronics.bin', 'wb') as f:
    f.write(data)

I now have a hopefully intact firmware image I can disassemble and reverse engineer to search for security vulnerabilities. I just have to figure out how to do that…