Steganography [ folder -> image ]
Tags: security, tutorial, image, steganography
Published: 2020-10-31 05:37:30

I spent the last two days reading and learning some cool things related to steganography. Due to the recent youtube-dl takedown, I saw a few tweets of images and videos of the image/video form of the source code repository which piqued my interest. In this post, I will be going over steganography in general as well as walk you through how to convert a folder to a single image file that can be distributed and then restored to the original folder.

You can skip directly to the walkthrough if you want. Here is a list of things I am covering.

* [Steganography](#Steganography)
* [youtube-dl](#youtube-dl)
* [Walkthrough](#ftoimg)

## <a id="Steganography"></a> Steganography

The way I see steganography is that it deals with things related to hiding data/message in something (file) and then distributing the file in which the data is hidden. Steganography is best used when encryption isn't a viable option. Encryption is visible in the sense that you know that an encrypted file is probably hiding something. In the case of steganography, it is a much subtle way of hiding things. That's all I am going to say about it as my knowledge about it is limited. Linked some resources about steganography below

[Wiki](https://en.wikipedia.org/wiki/Steganography)
[Subreddit](https://www.reddit.com/r/Steganography/)

## <a id="youtube-dl"></a> youtube-dl

The only reason I started to dig deeper into steganography was because of youtube-dl. I knew about the concept of steganography and had used `steghide` once or twice before, that's about it. This is a huge topic of discussion right now without delving deeper into it what's happening is, youtube-dl is an open-source program used by a lot of people to download videos from youtube and few other sites using the command line. The RIAA issued a [DMCA takedown notice](https://github.com/github/dmca/blob/master/2020/10/2020-10-23-RIAA.md) and Github took down the repository. I stumbled upon this tweet which made me want to try and implement this method of converting files to images by myself.

{% twitter 1319765986791157761 %}

Looks interesting, what's happening here? People decided to convert the repository/folder that contains the source files of youtube-dl into images and even videos!

{% youtube hyqLv2_zBdA %}
[More about the video above]
(https://twitter.com/gasmanic/status/1320107219866836994).

Having seen the end result with a real-life use case I really wanted to try it out. In the same thread, someone made a [shell script](https://github.com/rekcuFniarB/File2PNG) that converts files to images so I [forked](https://github.com/nishad10/File2PNG) that and started playing around with it.

# <a id="ftoimg"></a> Converting a Folder to an Image

Alright so let's say we want to do the same as above, there are a lot of tools available to convert files to other formats including images. Some tools are better suited to us as they focus on steganography in general. `steghide` is a commonly used tool but in this case, we will be using `imagemagick`. 

[Download and install](https://imagemagick.org/script/download.php) if you haven't already. Once you are done you can take a look at the [convert](https://imagemagick.org/script/convert.php) script This is what we will be using as the core. You can follow an example or two from the above link to make sure everything is working. Now let's see how the script is supposed to work in our case. We want to do something like this:

```
convert -size $heightx$width -depth $depthValue RGB:"$INFILE" PNG00:"$OUTFILE"
```
### Flags and their meanings -

convert => The script we want to run
[-size](https://imagemagick.org/script/command-line-options.php#size) => The size of our output image. [Height x Width] pixels
[-depth](https://imagemagick.org/script/command-line-options.php#depth) => The number of bits in a color sample within a pixel 
[RGB/PNG00](https://imagemagick.org/script/formats.php) => These are just the formats of the files we are transforming from > to respectively where INFILE and OUTFILE filenames of our file that we want to convert and name of the file to convert to respectively.

Now you may notice that there are some variables in the above command that are unknown. 

`$height $width $depthValue` 

Let's start with **depthValue**, you can read more about it in the link above but the depths we usually will work with are 8 or 16. Some websites hate 16 bit in a pixel and may modify the image which would destroy our data. I am using 8 in my shell script but this can be changed as you wish. However, that would dictate our height and width.

**Height** and **Width** are basically the lengths in pixel terms. So how big should the image be so that the file can fit in it? To find that out we can do some simple math. This is what I do in my shell script. To do this we need the total number of pixels required, which is the size. think of it as the area(pixels) of a square/rectangle(image). 

### Total number of pixels 
As this is basically the result of our height x width. Once we have the total amount of pixels needed we can just get its square root and have a nice square, where height = width and height x width = total pixels.

Alright, how do you get the total pixels needed?
So we use the equation below to get the pixels. 

*Size of file (bytes) * PixelsPerByte(pixels/byte)*
*bytes * pixels/byte = pixels*

#### File Size (byte)
In the shell script, we use some cmd line tools to get the byte size of our file to convert. 

#### Pixel per byte (pixel/byte)
This is where we use the depth we defined before. We are using RGB for our file to convert. So we need 3 pixels for (R, G, B) and then we multiply that with the depth(bits per pixel) to get the total number of bits necessary. Now to convert bits to bytes just divide by 8. This will look something like this. 

*PIXBYTE= ( $depthValue * 3 / 8 )*

We are almost done! So now we have everything we need to use the convert script. You can see how it all comes together in my [shell script](https://github.com/nishad10/File2PNG/blob/master/file2png). This will work on most files however I had issues converting .tar.gz and .zip files to images. Convert from ImageMagick was complaining about the file formats and throwing error while reading the file in the RGBread file. 

I fixed that by using the cmd line `cat` operation to feed the file to our convert program. So we use `cat` to output our .tar.gz file or any other file and then use that output as an input for our convert script using the command line [pipeline operators](https://www.geeksforgeeks.org/piping-in-unix-or-linux/#:~:text=Pipe%20is%20used%20to%20combine,more%20commands%2F%20programs%2F%20processes). We use the `|` operator that takes the output of things on the left and feeds it as an input to the things on its right. 

Our final tweaked command would look something like this:

```
cat ${INFILE} | convert -size ${HEIGHT}x${WIDTH} -depth $depthValue RGB:- "$OUTFILE"
```

Let's finish this by accomplishing our objective. Let's convert a folder to an image and then restore it. I'll be converting the youtube-dl repo to a single image.

{% gist https://gist.github.com/nishad10/e1cf86772576799e79bcf74c8b08dab1 %}

### This is how it looked on my end -

![TerminalOutput](https://dev-to-uploads.s3.amazonaws.com/i/7f5qu0qfh7e4p8wuipyc.png)

This was the first time I played around with file conversions and images. Let me know if I misunderstood anything and feel free to correct me on anything above. 

### Here is the image our program created -
Download here: https://dev-to-uploads.s3.amazonaws.com/i/3vipdj6nft67kz6ur163.png

![RGBImage](https://dev-to-uploads.s3.amazonaws.com/i/3vipdj6nft67kz6ur163.png)