TUCoPS :: Crypto :: stegfaq.txt

Steganography FAQ

From msuinfo!agate!darkstar.UCSC.EDU!news.hal.COM!decwrl!pacbell.com!amdahl!netcomsv!netcom.com!qwerty Tue May 10 20:38:42 1994
Newsgroups: sci.crypt
Path: msuinfo!agate!darkstar.UCSC.EDU!news.hal.COM!decwrl!pacbell.com!amdahl!netcomsv!netcom.com!qwerty
From: qwerty@netcom.com (-=Xenon=-)
Subject: Steganography FAQ
Message-ID: <qwertyCpKpIy.Dzp@netcom.com>
Organization: PGP Info Clearinghouse.
Date: Tue, 10 May 1994 06:18:33 GMT
Lines: 358

It's 2AM and I'm bored so I'll finally post this thing, and call it a 
FAQ. Steganography: hiding a message in a carrier message.


[Note: the addresses ftp.netcom.com, or netcom#.netcom.com where # is 1-13 
should now be used to "ftp to netcom.com".]

Stego by Romana Machado (ftp to netcom.com in /pub/qwerty as
stego1.0a2.sit.hqx) will hide text as the least significant bit in a Mac
PICT file. 

Stealth by "Henry Hastur" <I, Xenon, will forward mail to "Henry" if you
would like.> (ftp to netcom.com in /pub/qwerty as stealth1.1.tar.Z) strips a
binary PGP message down to the bare message without any of PGP's
convenience wrappers. The resulting message should be hard to distinguish
from random noise data, and this thus turns steganography into an EXCUSE
to send random-looking data, by hiding it as noise. Sophisticated
steganographs are now needed however since real noise in the digital
domain is rarely white noise. Stealth will now compile on DOS or Unix. 
The C source code is contained in the file stealth1.1.tar.Z or separately
as stealth1.1.source.code. To get Stealth set up under Unix, ftp 
stealth1.1.tar.Z in binary mode, then do 'uncompress stealth1.1.tar.Z', 'tar 
xvf stealth1.1.tar', and finally 'make'. 

Stealth has also been ported to work on the Amiga by Peter Simons
<simons@peti.gun.de> (ftp to netcom.com in /pub/qwerty as
AmigaStealth1.0.lha, or to wuarchive.wustl.edu in /pub/aminet/util/crypt
as StealthPGP1_0.lha).

Stealth, compiled for DOS by Chris Wiles is there too, of which he says:

                    Stealth V1.1 MS-DOS Appnotes
                 17 April 1994 Christopher M. Wiles

  These application notes pertain to my port of Henry Hastur's Stealth
  V1.1 to the MS-DOS filesystem.

  First and foremost, this PGP filter does _not_ work with an ascii-armored
  text input file.  It was designed and coded for use with straight binary
  files.  This is fine when your primary purpose is to exchange files via
  the use of steganography, but is rather useless if one wishes to remove
  and replace the PGP headers on an e-mail message.

  It wouldn't be that difficult to patch the source to handle both input
  and output of ascii armor.  If you want to see this modification, send
  me e-mail at the below address.  I'll do it if enough people request it.

  Additionally, there may be an error in Henry's README file, as included
  in this package.  He states that the following command sequence invokes
  PGP with Stealth as a filter:

        "pgp -ef < secrets.dat | stealth > pgp.stl"

  (a direct result of redirecting STDIN to SECRETS.DAT).  This works for
        "pgp -ef < secrets.dat NAME | stealth > pgp.stl"

  ... where NAME is the recipient's name.

MandelSteg by Henry Hastur (ftp to ftp.netcom.com in /pub/qwerty). For 
Unix and DOS so far. Generates fractal GIF pictures and injects your  
messages into them. Also archived is a version compiled for DOS users, by 
Chris Wiles, who writes:

            MandelSteg V1.0/GIFExtract V1.0 MS-DOS Appnotes
                 09 April 1994 Christopher M. Wiles

  These application notes pertain to my port of Henry Hastur's MandelSteg
  V1.0/GIFExtract V1.0 to the MS-DOS filesystem.

  MandelSteg runs _slow_.  Painfully slow.  Anything short of a 486DX
  machine is going to take a good long while creating the GIFs.  Be
  This set of binaries uses the standard RANDOM() function, in case
  anyone was curious.  Probably not crypto secure, but good enough for my
  purposes.  If enough people send mail implying that they want a release
  that incorporates a crupto secure algorithm ...

  -- Christopher M. Wiles (wileyc@quark.chs.wa.com)

Jsteg by Derek Upham (ftp to netcom.com in /pub/qwerty). Get everything. 
jpeg-v4.tar.gz is the raw sources for the djpeg/cjpeg utilities,
jpeg-jsteg-v4.diff.gz are the diffs for building djsteg and cjsteg, and
jpeg.announcement.gz is a readme file describing the steganographic
format. I have NOT used jsteg so I'm not the guy to ask about it. It's so
far only ported to Unix.

S-Tools (shareware) by Andrew Brown (ftp to netcom.com in /pub/qwerty as 

   S-Tools (Steganography Tools) brings you the capability of `hiding'
   files within Windows sound files (.WAV), bitmap (.BMP) and CompuServe GIF
   files. For BMP's and GIF's you can choose whether you want the graphic
   image to look identical after a file has been hidden inside, or 
   whether you can put up with some degradation of definition in order to
   gain other advantages. Files hidden inside WAV's will not sound any
   different to the human ear than the original file. The modified sound file
   will not increase or decrease in size. 

   In order to further conceal the presence of a file, S-Tools picks its
   bits from the sample/graphic based on the output of a random number
   generator. This is designed to defeat an attacker who might apply a
   statistical randomness test to the lower bits of the sample to
   determine whether encrypted data is hidden there (well-encrypted data
   shows up as pure white noise). The random number generator used by
   S-Tools is based on the output of the MD5 message digest algorithm,
   and is not easily (if at all) defeatable.

    - Andy (asb@cs.nott.ac.uk)

   S-Tools 2.00 is incompatible with version 1.00. If you have hidden files
   with version 1.00 then you should extract them and re-hide them with
   version 2.00. You will gain additional security by doing so.

PGMstealth by Timo Rinne <tri@gamma.hut.fi> (ftp to netcom.com in 
/pub/qwerty as PGM.stealth.c):

    I quote,

    A program to merge data into the pgm pixmap. PGM-pixmap is a normal
    grayscale bitmap created by almost any program. At least in pbmplus
    package (or netpbm) there are giftoppm and ppmtopgm converters to create
    these beasts and at least xv-3.* can save pictures in pgm format. 
    PGMstealth can read either ascii or binary PGMs (P2 or P5).  I add the
    format description of PGM from netpbm package at the end of this mail.
    When I used the pgp extension in one of my examples, I was only referring
    to the data file created by Phil Zimmerman's PGP program and maybe
    stripped by stealth program I found in your ftp-site. 

    Anyway, if one can create PGM pictures out of their favourite images, the
    usage of PGMstealth is quite self explanatory, and of course there 
    are few good examples in the comments of the code.  The main principle
    of the program is that it strips the least meaningful bits out of the
    picture and uses these bits to store information.  More bits you spend to
    your information, greater is the affect on the quality of the picture.
    In my experience 1-bit (some cases even 2-bits ) of stored information can
    hardly be noticed in the 8-bit grayscale image. And of course you can
    always deny that there is any crypted information in your pictures. 
    Spreading the grayscale pictures with noise in their least meaningful 
    bits can hardly be considered encriminating, especially when this is
    the case in the most 8-bit grayscale picture. 

    If you (or someone else) like to write a manual page I'd be delighted 

    Description of pgm format:


    pgm - portable graymap file format

    The portable graymap format is a lowest common denominator grayscale
    file format.

    The definition is as follows:

    - A "magic number" for identifying the file type.  A pgm file's magic
      number is the two characters "P2".

    - Whitespace (blanks, TABs, CRs, LFs).

    - A width, formatted as ASCII characters in decimal.

    - Whitespace.

    - A height, again in ASCII decimal.

    - Whitespace.

    - The maximum gray value, ain in ASCII decimal.

    - Whitespace.

    - Width * height gray values, each in ASCII decimal, between 0 and the
      specified maximum value, separated by whitespace, starting at the top-
      left corner of the graymap, proceeding in normal English reading order.
      A value of 0 means black, and the maximum value means white.

    - Characters from a "#" to the next end-of-line are ignored (comments).

    - No line should be longer than 70 characters.

    Here is an example of a small graymap in this format:
    P      # feep.pgm
    0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
    0  3  3  3  3  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15 15 15 15  0
    0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0 15  0
    0  3  3  3  0  0  0  7  7  7  0  0  0 11 11 11  0  0  0 15 15 15 15  0
    0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0  0  0
    0  3  0  0  0  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15  0  0  0  0
    0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

    Programs that read this format should be as lenient as possible, 
    accepting anything that looks remotely like a graymap.

    There is also a variant on the format, available by setting the RAWBITS
    option at compile time.  This variant is different in the following ways:

    - The "magic number" is "P5" instead of "P2".

    - The gray values are stored as plain bytes, instead of ASCII decimal.

    - No whitespace is allowed in the grays section, and only a single 
      character of whitespace (typically a newline) is allowed after the maxval.

    - The files are smaller and many times faster to read and write.

    Note that this raw format can only be used for maxvals less than or equal
    to 255.  If you use the pgm library and try to write a file with a larger
    maxval, it will automatically fall back on the slower but more general
    plain format.

    fitstopgm(1), fstopgm(1), hipstopgm(1), lispmtopgm(1), psidtopgm(1),
    rawtopgm(1), pgmbentley(1), pgmcrater(1), pgmedge(1), pgmenhance(1),
    pgmhist(1), pgmnorm(1), pgmoil(1), pgmramp(1), pgmtexture(1), 
    pgmtofits(1), pgmtofs(1), pgmtolispm(1), pgmtopbm(1), pnm(5), pbm(5), ppm(5)

    AUTHOR     Copyright (C) 1989, 1991 by Jef Poskanzer.

HideSeek by KrAziEst KaT <shaggy@phantom.com>. From the author, concerning
the included source code: "the problem is that i use a commercial toolbox
for the graphics handling, so people won't be able to use it. still, i
guess they want to see it." DOS program for data hiding/seeking using GIF 

Gzsteg, a gzip steganograph by Andrew Brown <asb@cs.nott.ac.uk>.  Gzip is 
the standard compression for Unix systems, and can now be used to hide 
files.  I quote,

   The attached patches will allow you to hide information inside GZIP
   compressed files.


   You need the gzip source code distribution. At the time of writing
   this is version 1.2.4. The patches are context diffs so you stand a
   good chance of them working on versions other than 1.2.4. Firstly
   unpack the gzip source tree, then unpack the attached patches into the
   main source directory. Now apply the patches thus:

   patch -c < patch1
   patch -c < patch2
   patch -c < patch3

   Now all you need to do is follow the normal procedure for making gzip.


   A new option is added to gzip, "-s" or "--steg", that provides for the
   hiding/revealing of files. You hide files during compression and
   reveal them during decompression. e.g.

   gzip -s file-to-hide file-to-compress

   This will hide "file-to-hide" inside file-to-compress as it is
   compressed. Extracting a file could be done like this:

   gunzip -s file-to-extract-to compressed-file

   This will simultaneously decompress the compressed file and extract
   the hidden file to file-to-extract-to. To extract the hidden file
   without uncompressing you might do the following:

   gzip -cds file-to-extract-to compressed-file > /dev/null


   gzip uses LZ77 which compresses data by storing length/offset pairs
   that refer back in the uncompressed data stream to previous
   occurrences of the information being compressed. gzip considers a
   length of 3 to be the shortest acceptable length. We allow gzip to
   find the length/offset pairs and then do the following.

   If the length is at least 5 then we subtract 1 and set bit 0 to the
   value of the bit that we need to hide. We have now hidden information
   in the length without pushing it beyond a valid value.  Drawbacks are
   a slight decrease in compression (very slight) since we have to
   disallow lengths of 4 and some of our meddling will decrease the
   actual matched length by 1. The hidden file is totally invisible to
   the normal operation of gzip, gunzip et al and (if encrypted) will
   only be visible to those in the know. When the "-s" flag is not used
   gzip performs as normal.

   Testing was performed on a 486/33 running Linux, using a 1Mb tar file
   to hide the test information inside. The patched files (inflate.c,
   deflate.c, gzip.c) should compile OK on any system that can compile
   gzip, although non-Unix users may have trouble applying the patches in
   the first place. My tests have shown that you can hide about 1 Kbyte
   in every 100 Kbytes of uncompressed data. This ratio would be

And this,

   From: ken@chinook.halcyon.com (Ken Pizzini)
   [1] Re: Hiding things in gzip files (source)
   Date: Fri Apr 29 05:19:00 EDT 1994
   Organization: A World of Information at Your Fingertips

   In article <1994Apr28.124902.5107@cs.nott.ac.uk>,
   Andrew Brown <asb@cs.nott.ac.uk> wrote:
   >The attached patches will allow you to hide information inside GZIP
   >compressed files.

   The code has an amusing bug in that uncompressing a file will
   output the steganographied file to file descriptor 0.  If you
   just use "gunzip foo.gz" you won't notice this, as the file
   foo.gz gets opened read only as fd 0; but if you use "gzip
   -dc foo.gz >foo" it is quite apparent.  Here is a patch to
   fix this (apply to gzip source after Andrew's patches):

   ***begin patch***
   --- inflate.c-stegbug   Fri Apr 29 01:36:47 1994
   +++ inflate.c   Fri Apr 29 02:07:38 1994
   @@ -592,7 +592,7 @@
     * gzsteg: bit 0 of n is ours, so long as n>3 (MIN_MATCH)

   -      if(n>3)
   +      if(n>3 && steg)

         /* do the copy */
   ***end patch***

                --Ken Pizzini

considerably better if gzip wasn't so damned efficient :)
[Sorry, this list is under construction! Help appreciated.]


Note that grayscale pictures are better for steganography, especially if 
you only have 8-bit color pictures. Note also that even with a stealth 
encryptor (one whose output is not easy to tell from "noise") there is 
the problem that unless your steganograph is somewhat sophisticated, 
which none are so far, someone who really cares to can tell if the 
"noise" in the carrier message is natural or is a hidden message, since 
noise in the digital domain is usually biased towards having more ones 
than zeros (or vice versa, depending on its source, and especially on the 
analogue-to-digital circuits).  

This list is more for use by those developing better steganographs, not so
much for casual "gimmee easy software" types.

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH