|
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. Steganographs: [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 me: "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 forewarned. 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-tools20.zip): 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(5) NAME pgm - portable graymap file format DESCRIPTION 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 24 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 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. SEE ALSO 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 files. 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. APPLYING THE PATCHES 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. USER INTERFACE 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 HOW IT'S DONE 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) steg_wbit(n&1); /* do the copy */ ***end patch*** --Ken Pizzini considerably better if gzip wasn't so damned efficient :) [Sorry, this list is under construction! Help appreciated.] -=Xenon=- 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.