Covert Channels over BitTorrent

BitTorrent is already used for many nefarious activities. Mostly software, music and movie piracy. Here’s another layer of suspicious actions that we can add to the list. At the end of last year me and four other guys got together and created a way to send covert messages over the BitTorrent protocol. With this, even perfectly legit BitTorrent communications could be consider iffy due to the messages hidden within.

Covert Channels

What’s a covert channel anyway? In the simplest of terms it could be considered “hiding in plain sight”. A more complicated definition is given by Wikipedia:

In information theory, a covert channel is a parasitic communications channel that draws bandwidth from another channel in order to transmit information without the authorization or knowledge of the latter channel’s designer, owner, or operator.

OK, maybe that’s a little too complex. Here’s one of the most famous examples of covert channels that I know of. Images are made of two dimensional arrays of three color channels - red, green and blue. Each color channel uses eight bits generally for 256 different shades of red, green and blue. Let’s pretend we have such an image at 512 by 512 pixels. Now, as it turns out, it is difficult for the human eye to see a change of one in a color channel. That is, 127 red is almost identical to 128 red to the human eye. Same goes for each color channel (more so for the blue channel, but let’s just stick with the one bit for now).

Because we know that people will have a hard time seeing this change, we could easily change the last bit of each color channel in each pixel to 1 or 0 without anyone being the wiser. This gives us 512×512x3 = 786,432 bits to play with. I could easily put an eight bit gray scale image at a resolution of 300×300 into the original image without anyone knowing. Plenty of room to hide a secret image within another image. The original image could be used on a company web site and whoever I’m sending the image to can download it and extract the hidden image to find some wrongdoing going on at the company.

The main idea is that covert channels take a perfectly legit and reasonable method of storing or transmitting data, find some weakness in the protocol (or in the above case, human limitations), then exploit the weakness to transmit some form of data along with the original data that can be deciphered.

BitTorrent Protocol

BitTorrent is an interesting file sharing protocol. Normally when someone wants to share a file over the internet they upload it to a web page or FTP server. Let’s say this file is big, an operating system ISO like Linux running anywhere from hundreds of megabytes to even gigabytes in size. Downloading the file from a web site might take a long, long time. Now, if this file is extremely popular you’ll get thousands of people trying to download a big file all a once causing the server to crash in the process.

Here, the problem is that the file is so popular that the one server hosting the file can not handle the traffic from so many different people. BitTorrent solves this problem by distributing the load. First, the big file is broken into smaller pieces, often hundreds of kilobytes in size. Then, whenever someone wants to download the file, they connect to everyone who already have some or all of the file and starts downloading random pieces of the file.

By randomizing the pieces, the file is distributed to many machines instead of being hosted by a single machine. The more popular the file, the people who are hosting parts or all of the file making it even easier to download. It’s actually very clever, taking a problem like server crashes and turning it into an increase of availability of the file.

Each piece of the file is indexed from 0 to n-1 for a file divided into n pieces. When a client wants a specific piece it will send a piece request to another client with the piece index in order to download it. The client then sends the piece to the requester and the operation continues until the downloader has all pieces of the file. Because of the random nature of piece requests, it is entirely possible for two clients to connect and download pieces from each other, giving them both more of the file than they had before the connection.

Covert Channels via Piece Requests

Given the fact that piece requests are random, how can we exploit this to send a covert message while still keeping the requests random looking? Our solution manifests itself in a translation table. As it turned out, the solution was also quite flexible in it’s ability to send all different kinds of messages.

First, we must choose an alphabet. The alphabet consts of all characters that we plan to send in our messages. This can be as large or as small as you want, it doesn’t matter. For instance, plaintext messages can use an alphabet of 29 characters, a-z space and some punctuation. For encrypted messages, you can use a set of two characters for binary, or a set of 256 characters for each 8 bit chunk. We found that encrypted messages using an alphabet of 16 characters, one for each 4 bits was a good fit.

Now that we have an alphabet, we can create a translation table from the available pieces based on the connected clients. Available pieces are pieces that the downloading client does not have and the uploading client does have. That is to say, any piece that makes sense for a piece request.

The translation table is a two-dimensional lookup table where each column represents a letter in the alphabet. The rows are filled with each available piece increasing in order. For an alphabet of s characters, the first row consists of the first s available pieces, the second row of the next s available pieces and so on until no pieces remain.

We send the messages on a character-by-character basis. The set of available pieces is created, the translation table is created and the next character to send is defined. We then index into the translation table using a random row and the corresponding column to find a piece to request. The piece is requested and then removed from the set of available pieces. The translation table is rebuilt and the next character defined and the process starts over again. This continues until we run out of characters or available pieces.

What’s nice about this approach is that it preserves the random nature of the BitTorrent protocol by only adding a small amount of structure. One can send a message consisting of the same character repeated many times without the structure showing up in the piece requests. Add encryption into the mix and even if the message is discovered, another layer of protection is added - maybe even deniability. Another plus is that the covert message does not interfere with the BitTorrent protocol in any way. After the message has been sent, the rest of the file can be downloaded normally and the file will be complete. The message is only hidden within the piece ordering, not the piece itself.

The entire project was implemented using the open source BitTorrent client in Python. We managed to even add a GUI front end to both type and read messages being sent. We achieved two-way communication by using two different downloads. The biggest problem is the time it takes to communicate a message across. As with most covert channels, we need to take a hit somewhere in order to keep the communication secret. In the example I gave earlier, the hit was in image resolution and color. Here it’s all in the time it takes to send the message.

Imagine a 1000 character message with piece sizes of 128 kilobytes each and a download rate of 100 kilobytes per second. That is a very small message with small piece sizes and a fast connection and it will still take over 20 minutes to send the entire message.