Data Hiding additional files in a ZIP archive
ABSTRACT
A
Zip archive consists of local file headers, local files, and at the end of the
Zip file, the central directory. When a zip application like WinZip or Zip File
opens an archive, it first reads the directory. Only when you actually extract
a file, it reads the offset from its directory entry, and then the local file
is read and uncompressed. Something that is not listed in the central directory
will not be listed in the Zip application.
Zip
archives can contain lots of single files, each of them having two sizes:
compressed size and uncompressed. Have you ever calculated the expected archive
size from the compressed file sizes and compared it to the size of the Zip
file? No? Well, that's why a few additional bytes - additional compressed text
files - won't be found by chance.
There are only three steps on the way to partly
invisible Zip archives. We need to:
1.
Read and write zip files in general,
2.
Write Zip entries without adding them to the central directory,
3.
Find those Zip entries in the archive.
Step 1: Using SharpZipLib
Step
one has already been solved by ICSharpCode: I've added the SharpZipLib project
to my solution. It ran perfectly fine. For each Zip entry, it generated a
directory entry automatically.
Step 2: Extending ZipOutputStream
That
leads us directly to step two: how can we avoid the directory entry?
SharpZipLib creates the directory in ZipOutputStream.Finish (). That's where we
have to catch the files that should stay hidden.
Step 3: Extending Zip File
With
the little changes above, we are able to add files to a Zip archive and hide
them from the directory. Now the real challenge begins: we have to find our
files again!
SharpZipLib
contains the class Zip File for reading archives and decompressing single
files. It completely relies on directory entries: GetInputStream () takes a Zip
Entry or its index and reads the local file's content from the given offset.
But our invisible files don't have those directory entries. To solve this, I
had to add two methods and a small change to GetInputStream ().
Before
we can start extracting the invisible files, we have to build a complete list,
which contains all zipped files, no matter whether they are in the central
directory or not. I decided to use the first file from the directory as the
anchor point in the archive, because every archive will contain at least one
visible file (otherwise it would be too obvious that something is wrong).
We will jump into the Zip archive at the
beginning of the first "official" file and walk through the following
local files, finding everything that's really in there. The new method Has
Successor (Zip Entry zip Entry) finds the end of a given Zip entry and checks
the stream for whatever comes after it:
Caution:
If possible, you should avoid encryption, or at least edit/save an unencrypted
archive and add encryption as the very last step. Sometimes it works; sometimes
you lose all hidden files except the first one. :-(
Usually,
the first encryption works well, but re-saving the already encrypted archive
makes the local file headers untraceable. Especially when there is more than
one invisible file in the archive, only try encryption, if everything else is
already saved properly.
SOFTWARE SPECIFICATION:-
OPERATING SYSTEM : Windows XP Professional
FRONT END : Microsoft Visual Studio .Net 2010
CODING LANGUAGE : C# .Net
HARDWARE SPECIFICATION:-
SYSTEM : Pentium III 700 MHz
HARD DISK : 40 GB
MONITOR : 15 VGA color monitor
RAM
: 256MB
No comments:
Post a Comment