Real Steganography with TrueCrypt
Disclaimer: This article has been written at a time when TrueCrypt was still a viable encryption software. This is no longer the case. TrueCrypt has been discontinued and everybody who has been using it should use one of the maintained forks like VeraCrypt instead.
That being said, this article mostly deals with TrueCrypt as a file format, not the application itself. However, the newer forks (and VeraCrypt in particular) use the same file format, so everything in this article is applicable to VeraCrypt as well. So, when this article talks about TrueCrypt and
.tcfiles, you can just mentally replace this with VeraCrypt and
You probably know TrueCrypt, the perhaps most popular tool for encrypting filesystems. As an alternative to full filesystem or even full disk encryption, TrueCrypt can also work with filesystems inside encrypted container files. These are files that look like they’re full of purely random data, but when provided the correct decryption key, they reveal their true contents: A FAT or NTFS filesystem full of your secret data.
In addition to this basic functionality, TrueCrypt also offers a simple form of steganography. For the uninformed, steganography is the term for techniques that conceal the existence of secret data. This means that the secret information is hidden inside another unsuspicious piece of data. TrueCrypt does support this with its »hidden volume« feature. If this is used, a container can be opened with two different keys: The first not-so-secret key opens the »outer volume« with not-so-secret data and a second really secret key opens the hidden volume with the real secrets. There are two problems with this approach, though: First, it’s very simple to destroy the hidden volume since it’s embedded in the outer volume’s data area without proper marking in the outer volume filesystem’s meta-data (otherwise they would give away the presence of the hidden volume). This means that you can overwrite the hidden volume just by putting enough files inside the outer volume. TrueCrypt can protect the hidden volume when mounting the outer volume, but for this to work, you need to provide the hidden volume’s key.
The second issue with TrueCrypt’s approach to steganography is that TrueCrypt container files are just large files with random data and as such, they’re easily detectable. You can disguise them by giving them unsuspicious filenames –
hiberfil.sys in a drive’s root directory are good candidates on Windows systems, for example. But then again, even these filenames are highly suspicious when found on removable media. So let’s use the next best thing: video files. These also tend to be very large and offer a good disguise for hidden data, but unfortunately, they are very easy to detect: Just try to play such a pseudo-video file and whatever player you use, it will tell you that something’s wrong.
So what we really want to call it proper steganography is a usable file that can be opened with standard software so it doesn’t raise any suspicion, but when opened in TrueCrypt with the right key, it should reveal the real payload – a filesystem full of secrets. Video files are the natural choice as for this kind of hack: Multi-gigabyte videos are completely common nowadays and encoders are so good that even large differences in bitrate don’t necessarily mean large differences in quality. In other words: A well-encoded fifteen-minute HD video clip of 1 gigabyte can look just as good as a not-quite-as-well encoded 4 gigabyte version. So let’s put the 3 gigs we can save to good use and store secret data there.
Unfortunately, this can’t be done using TrueCrypt directly. However, with a little bit of file format tweaking, it turns out to be possible anyway. In this blog post, I will describe a method of hiding TrueCrypt containers inside QuickTime / MP4 video files.
In fact, construction of such a »hybrid« steganographic file is just an application of a common discipline in esoteric computing: It’s all about generating a file that is valid in multiple formats. For example, you can create PDF files that are also ZIP files (see here). In this case, we want TrueCrypt container files that are also usable in some other common format. I decided to go for the QuickTime or MP4 format here, because it’s common, useful and easy to understand.
The TrueCrypt format
Let’s see how a TrueCrypt container file is organized. Obviously, there’s no structure that is easily detectable, e.g. with a hex editor. All headers are encrypted and can only be decrypted with the proper key. This is by design, because it’s a stated goal that TrueCrypt containers shall look like random garbage and thus must not have any unencrypted headers in them. However, the location and size of the headers is well-defined and documented: The main header of the outer volume is located at offset 0 in the file and can be up to 65,535 bytes in size (of which usually just a few hundred are used). This means that we can’t create a hybrid file with a format that requires header data within the first 64k bytes without sacrificing the volume header. The bad news is that there’s no format I know of that fulfills this constraint. But the good news is that we don’t need it anyway: As it turns out, the hidden volume header, located at offsets 65,536 to 131,072, is sufficient to mount a hidden volume. So we can overwrite the first 64k bytes of a TrueCrypt file with anything we want – file headers of another format in our case – and still have access to the hidden volume. The outer volume will be lost then, but this is an acceptable trade-off. After all, we can make the hidden volume as large as possible when creating the container and the only space we lose is the filesystem overhead of the outer volume, which is typically less than 5 percent of the volume size.
In addition to the two volume headers, there are backups of both starting at 128k before the end of the file. Since we’re going to append data to the TrueCrypt file to store the data of our video file, we are going to lose those, too. (Strictly speaking we’re not necessarily losing them, it’s just that TrueCrypt won’t find them any longer.) However, TrueCrypt will only resort to the backups if the main headers are damaged, so this is no issue.
So the task is clear: We can create a hybrid file with a hidden TrueCrypt volume out of an existing TrueCrypt container file by appending data and rewriting the first 64k of the file at will. We now need to re-construct our disguise file to meet these requirements. In particular, we need a way to create some empty space between the 64k mark and the end of the TrueCrypt volume that is ignored by applications reading the file in the format that it claims to be.
The QuickTime format
The QuickTime format and the MPEG-4 file format (ISO 14496-14), which is based on it, consists of so-called »atoms«. These are chunks of data consisting of a 4-byte length value, a 4-byte ASCII type identifier and an arbitrary amount of payload which may be composed of sub-atoms again. We’re (almost) only interested in top-level atoms here, though.
There are three top-level atoms that are required in every proper QuickTime or MP4 file: The main file header (atom ID ‘
ftyp‘), which is just a few bytes; the media header (»movie« header, atom ID ‘
moov‘) which is in the range from a few kilobytes to a few megabytes; and finally the main media data (atom ID ‘
mdat‘). Regarding the file layout, the only restriction enforced by the file format specification is that the
ftyp atom must start at the beginning of the file, all other atoms may be reordered at will. In particular, it is not required that
moov (the media header) precedes
mdat (the media data).
There are some additional atom types that are common, but are not required to make a file playable, so we can remove these without risk of damage. The most prominent one is ‘
free‘: Such atoms are just placeholders and don’t contain any useful data. Think of these as the QuickTime equivalent of comments.
One interesting thing to note about
mdat is that it doesn’t have any proper enforced structure. From the file format’s point of view,
mdat is just a big blob of data that happens to contain media samples (i.e. audio and video frames). Where these samples can be found is specified in so-called »chunk offset tables« (atom ID ‘
stco‘) inside the
moov atom. These tables contain file offsets for each chunk of samples of the movie. The nice thing is that all parts of the file that are inside
mdat but are not referenced by the
stcos are ignored by a player and thus usable for our steganographic hacks.
Creating an innocent-looking QuickTime/TrueCrypt hybrid
In practice, I found all MOV and MP4 files follow one of two different structures: The most common one is simply
mdia, sometimes with a
free at the end containing version information about the tool used to generate the file. The other common pattern is
moov (often with a very small 8-byte
mdat as a placeholder for 64-bit offsets should the file grow above 4 GiB later on). This is a very useful layout for our purposes: We can fake this one easily and still maintain the illusion of a perfectly legitimate QuickTime file. We just put the real
mdat right after the end of the TrueCrypt volume, followed by the
moov header. Then we generate a new
mdat that spans both the TrueCrypt volume and the real media data. Since we change the file offsets of the media samples in this process, we need to adjust the chunk offset tables, but this is manageable. For maximum credibility, we copy the first kilobytes of the original
mdat to the front of the file. This way, the file looks innocuous even when viewed in a hex editor – for example, if the file was encoded with x264, the encoder’s SEI message is still visible.
Here’s a figure that illustrates the embedding process (not to scale):
There are only four ways to detect the presence of the hidden volume, all of which are unlikely to be checked even by a knowledgeable person. The easiest way to tell about the manipulation would be bitrate monitoring: If a player tells you that the stream has a bitrate of 1 Mbps, but by analyzing the file size, you can compute that it must have at least 5 Mbps, you can tell something is amiss. But who looks at bitrates this detailed? The only other ways would be (1) a sophisticated packet-by-packet analysis of the
mdat data that would find out that from offset 65,536 on, there’s not only random-looking compressed data, but random-looking garbage; (2) checking for a repetition of the first 64k of
mdat somewhere later in the file and (3) seeing that there’s much unused space in the
mdat that isn’t referenced by any chunk offset table. I can imagine, in theory, that there might be tools to do the latter, but until someone shows me such a tool, I boldly declare my method as safe :)
I implemented this approach in a Python 2.x script:
tcsteg2.py (14k) (newer version, see below) (for Python 2.x)
tcsteg3.py (14k) (for Python 3.x)
To generate a steganographic TrueCrypt/QuickTime hybrid using the script, do the following:
- Find a good candidate QuickTime or MP4 file to use as a disguise, let’s say
SomeVideo.mp4. The file should be encoded in a very efficient way so that an increase in filesize is believable in relation to the length and quality of the video. Estimate how much larger the file may become without becoming suspicious.
- Use TrueCrypt’s Volume Creating Wizard to create a new hidden(!) TrueCrypt volume.
- Use the name of the final hybrid file as the container file name, e.g.
- As the outer volume size, enter the estimated maximum enlargment from step 1.
- Don’t bother entering a good password for the outer volume, it will be destroyed anyway.
- Use the maximum possible size for the hidden volume. Enter the size in KB instead of MB and do a bit of number guessing – the »Next« button in the wizard is disabled when the size is too large. Find the maximum size where the button is still clickable. (Technically, you could enter lower values, but why should you? Every byte left to the outer volume is a wasted byte!)
- Use your real ultra-secret password or keyfile for the hidden volume.
- Do not mount the outer volume! You will likely destroy the hidden volume otherwise.
- Use the name of the final hybrid file as the container file name, e.g.
- Use the script:
python tcsteg.py SomeVideo.mp4 InnocentLookingVideo.mp4
This will modify the TrueCrypt container file in-place. It might still take a while to process, since the disguise file is basically copied over into the container file.
- If everything worked, you will now have a file that
- looks like a video file in every way
- can be played as a video file using normal video player applications
- can still be mounted in TrueCrypt as a hidden volume
- is very hard to detect as a hybrid file
Sounds neat, eh? ;)
The script currently has one major caveat: It only supports files with a total output size of 4 GiB at a maximum. This is mainly due to laziness – it is left as an exercise to the reader to extend the script to larger files. (This task even comes in two complexity levels: If the input QuickTime file is already larger than 4 GiB, it’s a walk in the park. However, if the original QuickTime file was smaller and only grows above the limit because of the TrueCrypt volume hidden in it, good luck replacing the
co64s and adjusting all the atom hierarchy in the
moov to accomodate for the change ;) And while we’re speaking of interesting homework: if somebody feels like adding other formats, I’d be happy to update the script as well.
Update (2012-02-18): Vladimir Ivanov has contributed an updated version of the script – it now handles 64-bit QuickTime files properly and can also extend 32-bit files to 64-bit if they grow above the limit because of the hidden container. There’s also a new option to temporarily modify the hybrid file in a way that makes it possible to change the TrueCrypt password of the encrypted volume.
The most common one is simply ftyp–moov–mdia..
This order is normally required for streaming since the moov-data has to be read before the mdia-data can be processed. If you create a file with ftyp-mdia-moov and distribute it, someone will probably use qtfaststart, mp4box or whatever other tool to move the atom, so this procedure should create the streaming-compatible order out of the box.
Lars: I fully agree that
moov–mdat makes much more sense and I’d love to use that order, but I can’t. For this to work,
moovmust be smaller than 64k bytes, and this isn’t the case even for very simple files.
The problem that tools that modify MP4 files will destroy the TrueCrypt container is also known and expected – but after all, if you really want to distribute such a steganographic file, those who know that you’re hiding something in there will also know that they need to get the original file. Uploading such a file to some video sharing service will inevitably break it anyway :)
Would it be possible with a format that is interleaved like VOB files on DVD, to interleave a TC volume into them, but still work and appear normal to a DVD player?
I guess the benefit to the big chunk method in the MP4 file is that TC still mounts the volume without having to “extract/replace” the volume into the file every time…
Maybe there could be a plugin for Truecrypt to add stenographic hidden volumes though, that would support an interleaved format. This way streaming still works and if one inspects the offsets of the files as they are playing video one will still see it only reading beginning of movie from 3GB into the file as opposed to normal appearing seeking.
I would also be interested then if a file would somehow be able to lie to the decoder as to it’s bitrate… may be easier with a CBR type video format?
anyways thanks, this is a great trick :)
The best Tool I found for a long time! Great works thanks a lot for that! Worked very well and my hidden container is now in a video.
Joe: Interleaving the container would be indeed a perfect thing, because this makes it possible to embed the container easily in lots of other file formats. However, as you already noted, TrueCrypt doesn’t support such a thing as-is. I’m not sure if it is possible to add plugins to TrueCrypt that mess with the file format at such a level. What would still be possible though is to embed any kind of file into, say, a VOB file and extract it »offline« with some program before using the hidden file. This would be cumbersome, but possible (and I bet such a solution already exists somewhere … :)
Regarding the bitrate idea, I think it’s just a minor issue. Few container formats have a bitrate field in their headers in the first place (I’m not sure about QT/MP4), and even if there is, it is normally just a coarse estimate that need not represent the true bitrate of the media data, especially not in if VBR is used. However, if anyone feels like writing code for patching bitrate information when embedding the container, I’d be glad to add it to the script :)
how do you use the script? In a .cmd file, or the command prompt?
Neither is working for me.
WesK: It’s a Python script, so you need to have Python (version 2.x, not 3.x!) installed on your system. However, if you’re on Windows, there’s a small additional obstacle: By default, Python doesn’t install itself in the PATH. This means that you can’t just type »
python tcsteg.py a.mp4 b.mp4« into a command promt window – you need to specify the full path of the Python executable, e.g. »
C:\Python26\python tcsteg.py a.mp4 b.mp4«. Blame the Python Software Foundation for that, or use another OS (every major operating system except Windows comes with Python 2.x preinstalled today).
The python command prompt says that there is a syntax error when I type out the script.
I entered: C:\Program Files\Python tcsteg.py random video.mp4 super duper secret video.mp4
Must I write out the paths to all of the other files in win7?
I do have python 2.7.1
WesK: Don’t forget to enclose paths and file names containing spaces in double quotes (
"). Also, double-check your Python path: Your command line would only be correct if you installed Python in
C:\Program Filesdirectly, but it’s much more likely that it’s in something like
C:\Program Files\Python, so you’re missing the name of the executable. The correct command line would thus be something like »
"C:\Program Files\Python\python.exe" tcsteg.py "random video.mp4" "super duper secret video.mp4"« (given that the .mp4 files are in the current directory, of course :)
Besides … I really don’t want to be rude, but frankly: If you can’t manage to run something as simple as this script without assistance, you possibly shouldn’t be reading this blog in the first place.
Sorry for these harsh words, but I don’t really intend to give »command prompt 101« courses here.
i have this error…
Error reading the source file: duplicate ‘mdat’ atom
toto: Then try another file :) The script is very basic and can’t deal with all the peculiarities of the QuickTime format. You may also try to »repackage« the file with a tool like MP4Box first.
May I ask where you got the non-working file from and/or which software was used to generate it?
Just letting you know, the script worked perfectly for me and I’m very happy with the results. Thanks!
Hi there, I read your Blog with great interest. I have a huge problem!! An entire portable hard drive, with very critical data – that I can no longer access, that I used TrueCrypt on….Appreciate any help you might be able to offer. Thank you in advance.
Here is what the error reads:
“The container has been compressed at the file system level.TrueCrypt does not support compressed containers (note the compression of encrypted data is ineffective and redundant)
Please disable compression of the container by following these steps.
1) right click the container in windows explorer
3)In the properties dialog box click advanced
4)in the “advanced attributes” dialog box, disable the option, “compress contents to save disk space” and click ok
5)in the “properties” dialog box click ok
That is the problem – the issue is when I try and follow these directions – click ok, and then click apply…… it looks like it works but – go back to the file, its still blue in color on the screen meaning its still compressed – i repeat the process and the box refuses to be “unclicked” so i can decompress the files!
Since I can’t decompress the files – I can’t fix the problem. What other options can I try – or ideas do you have. Thanks
You could just try and copy the container file to a non compressed folder/drive.
If the file is still valid, this should work.
Good luck or, better: sucess :-)
Dear Key J,
I am using Mac OSX10.6.6. I have TC 7.0 installed on my Mac. I had created a container and inside it put my data. My friend deleted the “container” by mistake. Now when I try to mount the volume, it does not locate that because seems it is deleted.
I am sure the data is still there. I am not a technical person and I do not know software programming. How can I find the container or TC volume. I remember the password.
Please help. I badly need the data.
Need Help: I don’t fully understand what you’re saying. In one sentence you say that your container file has been deleted, and in the very next sentence you describe that you tried to mount it. So please tell me: What kind of file is it that you have now, and in which way was it altered to become »unmountable«?
To remount the volume, you said just enter the mp4 as a TrueCrypt container and make sure to mark that there is a hidden volume along with the password. Everything worked but mounting it. You said mark that there is a hidden volume along with the password.How do you do that. I am running TrueCrypt 7.0a. Thanks for any help.
Troy: Where did I say that you need to »mark that there is a hidden volume«? You can mount the volume just as any other hidden volume: Just mount the file with TrueCrypt and enter the hidden volume’s password as the only password. All the options about hidden volumes in TrueCrypt’s mount dialog are only relevant for mounting a normal (non-hidden) volume while making sure that the hidden volume doesn’t get clobbered.
Thanks for this, I’ve tested it this morning and it works perfectly!
I’m actually doing some research on bitcoin, and it might be a great way to securely store you wallet in the presentation video of bitcoin: http://www.weusecoins.com/
Very useful information, a while back I had a quick write up on how to secure a thumbdrive within OSX and TrueCrypt and I was actually wondering about embeding the data within a working video and found your entry. I’m planning on revising my article with a link back here.
PS to Alexandre, I use BitCoins as well and I actually thought of that.
PS #2 , script works just fine on OS X 10.6.7
Is there any way to “spoof” the size of a file on ext3/4? Like, that way you could have gigs of stuff hidden in a video but still have it report the original file size.
Or, alternatively, how can I change the bit rate info so it looks like the file size is legit?
Blah: Spoofing the size of a file to a lower value is generally not possible. The on-disk data structures of most file systems allow such a trick in theory, but this would be regarded as an inconsistency when checking the file system.
Faking the bitrate information would be much more interesting. However, I don’t know if any container format actually stores this value in its file headers – after all, it isn’t needed for playback, it would be just there in case the user asks for the average bitrate of the stream. Live bitrate statistics (i.e. display of the current bitrate during playback) could only be faked if it would be possible to interleave the container with the data. There are some ways to hide a few bytes or kilobytes of data per frame in most video formats, but TrueCrypt requires the volume to be one contiguous chunk of data, so this isn’t an option either.
Okay, thanks for the info. I know that avi files do store bitrate info sometimes, but I guess not quicktime.
Ok, i installed python, put the original video and the TC mp4 file in the same path, then i typed “C:\Program Files\Python32\python.exe” tcsteg.py SomeVideo.mp4 InnocentLookingVideo.mp4 or either without the “”” it doesn’t work… What did i miss?
Alone: I totally forgot to mention that the script is written in Python 2.x – but this is fixed now :) You seem to have 3.x installed, which is a subtly different programming language. Also next time please post the whole error message instead of just saying »it doesn’t work« ;)
If there was an error message, i would have posted it… Anyway it works now, so thanks. It was on Windows. I just tried on Mac (i’m not so experienced with the system) and i couldn’t make it.
Where should i put the script? And the files? I tried on desktop and inside the Python folder (in Applications) but it didn’t work, terminal says that the script couldn’t be opened…
Anyway, about the rest, I think the most interesting format to add would be mkv without a size limit (or if it has to be one, then let’s say 50GB..) and.. that’s all:)
Oh and about faking bitrate, changing filesize, etc… Another idea : The file would be around 10GB when finished, it would be a fake 1080P rip.
You know when you download a video torrent, before it has ended downloading, you can preview with VLC but only some parts will show up;
That’s the plan, video info would show it’s 150minutes (for example) but it would actually be 2,5,10minutes randomly cut into many parts.
It would look like an unfinished download. For now, if i wanna use an HD RIP from a MKV, is there a simple way to extract video/audio and “glue” them QUICKLY?
Alone: I don’t know any reason why the script should work any differently on Mac than it does on Windows or Linux. Just copy it whereever you want it, open a console,
cdto that directory and run the script as described in the article. To my knowledge, OS X even comes with Python preinstalled, so this should not be an issue either.
Matroska would indeed be a nice format to support, however it’s extraordinarily complicated and badly documented, so I didn’t put any effort in this and decided to earn the low-hanging QuickTime fruit (simple format, decent documentation) instead :)
Producing a fake partial file like you described in your second post would require splitting the container in multiple parts, which isn’t supported by TrueCrypt.
Ok, that’s sad… Therefore i would have to do what i asked before: “if i wanna use an HD RIP from a MKV, is there a simple way to extract video/audio and “glue” them QUICKLY?” i was talking aboit getting an mp4 of course. Cause i actually don’t have such big mp4 files.
Hmmm i changed the mkv into mp4 using MediaCoder, i tried few files but it always refuse “can’t open tcsteg.py no such file or directory”… My mp4 size was always above 4GB, so i don’t get it!! Any clue?
tcsteg.pyreally present in the directory you want to run it from? If not, specify the full path.
Also note that it won’t work with files above 4 GB anyway (and if you read the article carefully, you’d know that :)
Of course it’s in the right path… And of course i read the 4GB thing… It says “If the input QuickTime file is already larger than 4 GiB, it’s a walk in the park” doesn’t it mean that in the case the original MP4 is above 4GB it’s ok?
Alone: Read that sentence and its context again carefully :) What it says is that extending the code to work with files that are already above 4 GiB is relatively easy.
Sorry, english’s not my native.. ;) How sad!! Cause 720P rip are usually just a little more than 4GB… Damn it!! I’m stuck with little MP4 that have low bitrate and would then look highly suspicious :(
Well i hope someone will make that change soon then… Since my programming knowledge is ZERO if not under!
I think i got it well now (after finishing my testing). So with the actual script, possibilities are (in my case) pretty limited.
I really hope you’d make the change since, as you said “it’s a walk in the park” > for those with the knowledge of course…
I would spend time on it, but don’t know a single thing about programming as i said… I’ll come back later! Bye~
How do I have to place the files to get tcsteg working? (Windows 7 – Python 3.2) All in the same folder? I put container.tc in one folder with the test.mp4 (both exactly the same size), I opened cmd and cd to the folder…
E:\TEST>"C:\Program Files\python\python.exe" tcsteg.py test.mp4 TES
File "tcsteg.py", line 136
except (IOError, ValueError), e:
SyntaxError: invalid syntax
Where do I have to enter the path to the container.tc or does the program automatically detects the container?
paradonym: As somebody found out, I forgot to mention in the original article that the script is made for Python 2.x. Since Python 3.x is a different and incompatible language, it won’t work with that, sorry :(
@KeyJ – Great – I installed Python 2.7 – now it works… awesome to see how secure the truecrypt container is…
just wanted to let you know, your script works fine for me.
I´ve also found a way to use the outer volume after the creation of the hybrid file. To do so, i´ve created the usual tc volume with an inner and outer volume. The inner volume got only half the maximum size, to leave some space for the outer volume. After putting some files in the inner and the outer volume i made a backup of the volume header via tc and put it aside. Then i ran your script with the usual result. I could mount the hidden, but not the outer volume. But by restoring the volume header with tc i was able to mount the outer volume again and access the files in it. (But due to the missing ftyp-header i couldn´t play the Video anymore, of course. One might reverse this process by backing up and restoring the ftyp header, but that´s a little too complicated for me).
So, this way you can create an ultra-hidden encrypted volume, hidden inside a hybrid file (containing another encryted volume) that nobody can access without the original header data and the password/keyfiles for the outer volume. +1000 internets to the person that finds an actual application for this crypto-maze :D
Still nobody who could update the code to work with bigger files? :P
Ok, i Try it with Python 2.7 and Python 3.2, I Type in “C:\Python27\python.exe” “tcsteg.py” “Vid.mp4” “tcvid.mp4”
For the 3.2 I type the syame, with Python32\python.exe
The Files are all in the Python directory.
When I press Enter, he show me the command without “”, and nothing more happens.
Hello KeyJ, here is the error I get :
Error reading the source file: 64-bit files are not supported
Which file is a 64-bit file, python ? Do I have to install a 32-bit version ? I’m on Windows 7 (64)
Gein: The 64 bits refer to the QuickTime file. Normally, only files above 4 GiB in size should use the 64-bit format, but occasionally, you may find smaller files which make use of that format, too. In this case, you can’t do anything but re-multiplex the file with a tool like MP4Box or FFmpeg – or find another file to hide your data in.
Ok thanks a lot, it worked perfectly :)
I found another file, MP4Box or FFmpeg were to complicated for me ^^’
I have the same query as Alone: can somebody provide an update for OSX for a container that is larger that 4Gb? I have a 16Gb mkv movie which I can convert to MP4 using Handbrake 0.9.5. Can somebody be kind enough to update the python code to be able to insert a hidden container which is at least 10Gb in size? Unfortunately, like Alone here, I am not savvy with programming! Thanks for any help anyone can provide!
Very cool! I like the idea of hiding the TrueCrypt volume in a video. You may be interested this article describing how to hide a truecrypt volume in a picture file too.
Really cool script. I tested it out on a 2GB mp4 file, it worked great! I will experiment with it and try to get rid of the 4GB limitation.
I’m getting an error when trying to run this..
i wrote the program with the addresses, C:\Python27\python.exe tcsteg.py Snake.mp4 DeadSnake.mp4
and i get
File “”, line 1
SyntaxError Incorrect Syntax
and i have
Win-xp, 32bit Python 2.7
NVM got it
First of all: the tool works very well.
Second: it is one of the best solutions i’ve seen.
Third: unfortunately, as many others steganographic solutions it is simple to detect :).
The bitrate isn’t a problem (not so serious, at least). The stream size is the very problem. Look at this test for the difference. First one is a real MP4 video. The Second is the same video with a Truecrypt volume (6 mb) inside.
Infos from mp4 file:
File size : 68.1 MiB
Video Stream size : 58.7 MiB (86%)
Audio Stream size : 9.23 MiB (14%)
Total Stream : 67.93 MiB (100% – more or less, the rest is header)
Infos from TC hybrid file:
File size : 74.6 MiB
Video Stream size : 58.7 MiB (79%)
Audio Stream size : 9.23 MiB (12%)
Total Stream: 67.93 MiB (91% – the rest, of course, is TC volume)
Every file with a stream size lower than 100% is a suspicious file.
Many tools are capable to calculate stream size, MediaInfo (http://mediainfo.sourceforge.net) can do it, for example.
I used MediaInfo.dll and AutoIt (http://www.autoitscript.com/) for doing a (very rough) CLI utility for quickly hybrid files detection. It is here: https://rapidshare.com/files/63434631/TCHFind.zip (MD5: zip file: 774DA43D5706B1B8E5ABA9847420EE87 exe file: A1D68BDAD3FE1CCA8D5717BB0443B330 – tested on Win 7) Read the “ReadMe” file for usage.
However, you did a good job.
WetStone Technologies already has a detector for this in their steganalysis product lines. Although it is simple to detect, someone has to be looking for it in the first place. Chances are a laptop thief or even local law enforcement won’t give your videos a second glance. The only time someone would even bother to use such tools is if steganography is already suspected.
It’s a clever idea and keeps your data moderately safe. The key and encryption algorithms are still unknown to an adversary. It’s very import to evaluate the importance of the hidden data and the strength of your adversary. In most cases the presence of steganography will go unnoticed.
It’s merely adding a little spice to your TrueCrypt volumes is all.
Hi, this looks great. Can this be done with MKV files? I have several hundred HD movies. All of these are mkv and are between 10 and 50 GB each. It would be very nice to hide 10GB or so into a 50GB file HD movie that plays normally.
Rachel: Yes, the Matroska format allows for a similar hack. It can be even easier to implement than for MOV/MP4, because no offset fixing is needed: If I understand the specification correctly, all offsets are relative to a specific element in the file (the »Segment« element), and if a »void« element with the hidden data is put before the Segment element, everything should just work nicely. Somebody has to try that in practice, though.
Similar? What exactly is needed? Does someone have a script for MKV written? I think, even though this thread is a year old that would be a welcome trick. MKV has really grown and 1080P movies are very common in large sizes. I am tech savvy enough to understand, but not a coder to write this myself. So, is there, as you said: “somebody” who would “try” this? Thanks for the reply.
this is really amazing work. Thank you very much for publishing this.
Does anybody else experience that the resulting file is not playable with Windows Media Player?
VLC Media Player plays the file, but the first few frames are blurred (maybe the first I-frame is corrupt).
Is there any way to fix either of these issues?
July: You mean that the resulting »hybrid« file has artifacts but the original file did not? That’s interesting, I never had that before. Is the file you used publicly available somewhere? If so, I could try to reproduce the issue.
Can this tool be used to find those hidden containers?
I am on nix so i cant test it :)
lord dulrah: No, TCHunt won’t find QuickTime/TrueCrypt hybrid files created with
tcsteg. They say that they explicitly exclude files with recognized standard headers, but since the hybrid files are, by design, standard QuickTime files, they won’t be found.
thanks a bunch for this answer !
Maybe you have an idea for this topic?
yes, exactly, the original file plays well and does not have artifacts at the beginning, but after applying tcsteg2, it does show them and does not play in Windows Media Player. However, using your original version of the script, everything works really great.
I have uploaded the files to my dropbox: https://www.dropbox.com/sh/5j7a7938p141eh3/vX0fhThFhn
The password for the TrueCrypt container is “testtest”.
Thank you very much,
Amazing piece of software!!!
But I can only confirm that tcsteg2.py produces files which Windows Media Player can’t play. In Media Player Classic HomeCinema there isn’t any problem with tcsteg2.py files. Any fix for this?
On the other hand, tcsteg.py produces correct files, but there is a 4GB filesize limit :(
Runs perfect if video file has no errors.
I tried with a file downloaded from youtube, no success, but when recoded (copied streams) it works great. Thank you!
Another idea might be to create a normal TC volume with a hidden volume of max. size, the outer volume named “noise.wav” or “some artist’s song.wav”. With a simple script using some filesize calc and “dd.exe” it is possible to write an valid 44 byte header to the file and now it is a fully playable audio file, playing senseless noise though. The outer volume will be unreadable, still mountable after 3 tries with the backup header (which is useless here, when using full hidden volume size)
1) noise data recorded for some research reason
2) corrupted wav, by accident e.g. scrambled unzip or by virus scanner
1) who has really big wav files?
2) who keeps corrupted files and does not delete them?
3) noise is not distributed equally when filling the vol. with data
Another approach – NOT TESTED YET, when you aren’t too lazy to enter the password 3 times it is possible to overwrite the beginning of a TC-volume with playable data, up to the beginning of encrypted data.
In theory a player does its work until there, then quits for some unknown error. As the volume headers are overwritten, the backup headers are used, after 2 unsuccessful attempts
If you are a technician: some oscilloscopes store data in a binary format, with a header about the time and voltage scales and sampling rate and number of data, followed by a stream of 4- to 8-byte real-number words for time and voltage values. Offering a slightly better deniability for big files
Someone may give it a try.
Great stuff, but I can confirm what have been said by others earlier., the files created by tcsteg2.py does not work in Windows Media Player, but if i use tcsteg.py they work excellently. (Same files used for both tests, original video file also works fine in WMP)
The hack works but my final TC file is not working anymore. I can open it with TC, it asks for password but when I type it, it says “not valid TC file or wrong password”.
Is it because I’m using Keyfiles as well to decrypt my protected file?
(I tried again with my backup TC file and the password is the right one so there is definitely an issue and the problem isn’t between the chair and the keyboard :) )
Ok, I tried with another MP4 file and it worked. No idea of what happened with the other file.
And I also can confirm that the file can’t be loaded in WMP. Woks with MPc and VLC tho.
Thank you for your work!
It worked for me very well one year ago : )
Now I have a little problem…
I know which the video file is, I know 75% of my strong password but I can’t remember the end :-D
A little help?
Perhaps splitting again if possible and try to crack the hidden volume ?
I have the video too if it helps!
Now that Truecrypt development have stop. Does this script support veracrypt in the same way?
Unicycle0ne: It should work, but I’m not completely certain. It seems that VeraCrypt did change some details of the TrueCrypt format, but those are mostly related to crypto details – as long as they kept the concept of the two 64k volume headers, everything will be fine.
I am doing a report about hiding data in videos and you know I need the source code so I was trying this tool and it is good but how to decrypt (getting the data back after I merged the tow videos) can that be done with this script and if it not can you help me
YAGHA: There’s no need to »get the data back«. If everything works, you should get a file that is both playable as a normal video file and mountable in TrueCrypt or VeraCrypt. The contents of the TrueCrypt outer volume, however, are lost forever.
I have an mp4 file with hidden information. I wonder if this stegano method is applied to my file. (82Mo)
Could you please explain to me (or help to do) how to retrieve the hidden information? I do not have Python and I’m on W10. I do not speak English very well but I understand not too badly.(frenchspeaking)
Maybe you could tell me other methods of steganography on video files too ?
thanks for your help
Nath: Well, as wargus pointed out, the presence of a tcsteg hybrid file can be detected with MediaInfo. You can also have a look with a hex editor and check if there’s a large
freeatom directly after the initial
What you can not do, however, is retrieve the hidden information without the encryption key. (That’s the whole point of TrueCrypt, after all :) If you do know the key, you could just go ahead and open the volume in TrueCrypt/VeraCrypt: If it’s indeed a hybrid file and the key was correct, it should be possible to mount it without a hitch.
Please help KeyJ.
In the python folder, I have 3 files: vcsteg2.py video.mp4 (movie, 800mb) and vera.mp4 (container 2gb, inner has 150mb). I click the right mouse button and choose ‘open the powershell window here’. I’m writing a command: python vcsteg2.py video.mp4 vera.mp4 and in the result I get this error: Error opening file ‘vera.mp4’. Whatever I do, I always get this error. What’s wrong with my container ??
I hate all these stupid rights and politics!
My problem was solved when I installed python on disk D.
Thanks for the script!
Can the 2to3 utility (
python3 -m lib2to3 file.py) be used to automatically convert the code to python 3? The diff mostly only gives me print and except to change, so I assume it should “just work”, but I just wanted to double-check, since this is security-related.
FooBar: 2to3 takes care of the purely syntactical changes, but not the semantical ones, which are much harder to tackle. Fortunately,
tcstegis relatively simple to fix – I did just that and now there’s a Python 3 version, too.
great, thank you
This is really cool. Many thanks to your great work! However, I have a problem with python3. Executing
a bytes-like object is required, not 'str'. Is that normal?
Hi, I changed line 128 “
f_dest.write("\0")” into “
f_dest.write(b'\0')” and it stops complaining, but I am not sure if I did it right :P