StegTorr: Using Python to Set Up A Hidden Torrent Site

Hiding in plain sight

Bot Loves Coffee
, in 25 October 2015

Hiding a Torrenting Website in Plain Sight With Python.

A Brief (and mostly awful) History

======= layout: post —

##Hiding a Torrenting Website in Plain Sight With Python.

###A Brief (and mostly awful) History

Steganography is the practice of concealing hidden information with other nonsecret text, images, or other forms of data. In the pre-internet age, there were a lot of interesting examples. Soldiers or slaves would have information tattooed on their scalps to be shaved off later to read the hidden message. Pieces of clothing might have certain patterns weaved into them. One American soldier, during a press conference in 1966, repeatedly blinked in morse code T-O-R-T-U-R-E to communicate the conditions POWs were living in trapped in Vietnam.

Most of these methods are pretty slow (and horrifically violent) but interesting. Each relies on the idea that, to the unobservant, the hidden message goes entirely unnoticed. Unlike a note written in ceasar cipher or some such, there’s not even any evidence a hidden message exists. This subtely provides a deeper layer of security to those looking to conceal information.

Bringing Stegonagraphy into the 21st Century

The advent of the internet breathed new life into the practice of Stegonagaphy. 1s and 0s and the various forms they can take, from images to audio files, gives secret messages ample hiding place if one knows how to conceal them.

To experiment with this, my friend Ben and I came up with the idea to create a torrenting website, disguised as a series of random images.

The basic idea was simple. We would hide torrenting links inside the images, and create an invite only website that allowed users to share these images with their friends. Part of their invite would be a tool we developed in Python to decode the magnet link from the torrent for a selected image, and start the p2p. To any other user who stumbled upon the site, it would just look like a pretty silly series of random images: a gallery a novice web-dev had set up for practice, rather than a torrenting website.

StegTorr is definitely more of a proof-of-concept demo of Stegongraphy rather than the beginning of a real webservice for a variety of reasons, the least of which is Ben and I’s general aversion to lawbreaking.

The workflow is as as seen above. It’s a work in progress, but you can definitely go on over to see it’s development on github.

For now, I just want to dive into the algorithm that allows us to conceal the messages in the image, because I think it’s neat. This is probably the simplest algorithm around, but it still does the trick to fool anyone who isn’t looking for it.

The Algorithm

The key comes from how the images we see on a website are encoded. Each pixel we observe, no matter how detailed, comes from a pixel with 3 color channels: Red, Green, and Blue. It likely won’t surprise you that these 3 channels take on values from 0 to 256 i.e. the range of values one byte can take on.

These pixels can be represented as a matrix made up of rows and columns, with one pixel at each position.

The key is to edit the information of the bytes of a pixel in a way impossible for the human eye to detect. To do this, we decide to edit the least significant bit of each byte.

The most significant bit has major swing, so the difference between a 0 or a 1 is pretty noticeable with its weight of 2^7 (128). However, the least significant bit has a pretty meager value 2^0 (1). This difference between a channel value of 220 and a channel value of 219 is so insignificant our eyes can’t see it, so it’s the perfect place to encode a message - say, a torrent link. Assuming it’s written in standard ASCII, that shouldn’t be a problem. Encoding something in ASCII takes only 7 bits. Only editing the least significant bit in each pixel means that in 3 pixels, we can store one character just fine.

As I said previously, each pixel has a red, green, and blue channel. The order is significant! In fact, our decoder will have in mind it should check through red green and blue in that specific order to decode the message correctly.

Because the message is so easily hidden, we don’t have to make the encoding particularly difficult. We can just iterate through the columns of the matrix at row 1. If we have a longer message than that, we can just go to the next row and continue.

But hey, I skipped a step didn’t I? I said we’d be editing the least significant bit of the channels of a pixel, but I never mentioned how.

###Bit Manipulation in Python.

Bitwise and and or are just like their logical operators, but instead apply to individual bits. For bitwise and, both bits must be equal to 1 for the result to be 1. For bitwise or, either bit can be 1 to get a result of 0.

Let’s look at some examples:


Binary Number        Operator


01110011                         &



Binary Number        Operator


01110011                          |


These operators are useful for manipulation because they can force any particular bit to be either 0 or 1. For example, if want to force the least significant bit to be a 0, we can use the bitwise & operator with the number 0 - a result of 0. Likewise, if we need a 1 to encode our data, we can use bitwise | with the number 1.

Putting it Together

 def encode_imdata(imdata, data):
    datalen = len(data)
    if datalen == 0:
        raise ValueError('data is empty')
    if datalen * 3 > len(imdata):
        raise ValueError('data is too large for image')

    imdata = iter(imdata)

    for i in xrange(datalen):
        pixels = [value & ~1 for value in
        [:3] +[:3] +[:3]]
        byte = ord(data[i])
        for j in xrange(7, -1, -1):
            pixels[j] |= byte & 1
            byte >>= 1
        if i == datalen - 1:
            pixels[-1] |= 1

What’s featured above is the encoding algorithm - when a user with proper permissions adds an image to the website, this is the algorithm it goes through. As you can see, it’s very simple!

Treating the image as a matrix of pixels, it iterates through the top row and encodes the characters of our message in the image, using our new knowledge of bitwise and and or in order to encode it correctly.

There are definitely more complicated algorithms (that are much more fun!) but this was the easiest to code up and the best for demonstration purposes.

My next post about stegTorr will cover addition of the python-based p2p system that completes the website. In order for this post not to be too long, I figured it my as well be one of a series.

Until next time!