mirror of
https://github.com/fdiskyou/Zines.git
synced 2025-03-09 00:00:00 +01:00
785 lines
34 KiB
Text
785 lines
34 KiB
Text
![]() |
---[ Phrack Magazine Volume 8, Issue 52 January 26, 1998, article 08 of 20
|
||
|
|
||
|
|
||
|
-------------------------[ Steganography Thumbprinting
|
||
|
|
||
|
|
||
|
--------[ The HackLab (http://www.hacklab.com)
|
||
|
|
||
|
|
||
|
|
||
|
Steg`a*nog"ra*phy (?), n. [Gr. covered (fr. to cover closely) +
|
||
|
-graphy.] The art of writing in cipher, or in characters which are not
|
||
|
intelligible except to persons who have the key; cryptography.
|
||
|
|
||
|
|
||
|
i. Introduction
|
||
|
|
||
|
While this may be a general description of cryptography, steganography has
|
||
|
come to describe not only the act of encrypting data, but also of hiding its
|
||
|
very existence. Steganography (or "stego") uses techniques to store a
|
||
|
"message" file within a "container" file by altering the container file in
|
||
|
such a way as to make the original file _appear_ unchanged. The resulting
|
||
|
file can be referred to as the stego file and contains the message file
|
||
|
enclosed in a close approximation of the original container file. Several
|
||
|
tools exist (mostly for DOS/Windows/NT) which automate these functions using
|
||
|
DES, DES3 or IDEA as encryption methods and BMP, GIF, JPG, WAV, VOC and even
|
||
|
ASCII files as containers. Using these tools, data can be hidden within
|
||
|
images, sounds, and even other data files. However, these tools do leave
|
||
|
perceptible traces on their container files and do not offer nearly the
|
||
|
level of obfuscation the user assumes.
|
||
|
|
||
|
This article will provide the reader with a fundamental understanding of
|
||
|
basic stego techniques and will highlight some of the "thumbprints" left by
|
||
|
modern steganographic toolsets, specifically on graphic images. Not intended
|
||
|
to challenge the cryptographic strength or perceptible mathematical variances
|
||
|
of current steganographic techniques, this article will give the reader a
|
||
|
basic understanding of stego and suggest low-budget methods for detecting and
|
||
|
cracking basic steganographic techniques. Also presented is a program which
|
||
|
can be used to brute-force two of the most popular stego toolsets.
|
||
|
|
||
|
|
||
|
I. Basic Steganography
|
||
|
|
||
|
|
||
|
Simply put, steganography involves the hiding of messages. While there are
|
||
|
many techniques employed by the various tools, the least common denominator
|
||
|
amongst most toolsets is the modification of some of the Least Significant
|
||
|
Bits (or LSBs) of the container file's individual bytes. In the simplest
|
||
|
example, consider the following binary representations of the numbers 20
|
||
|
through 27:
|
||
|
|
||
|
10100 10101 10110 10111 11000 11001 11010 11011
|
||
|
|
||
|
By modifying the LSBs of these binary digits, we can hide the binary
|
||
|
representation of the number 200 (11001000) across the above bytestream:
|
||
|
|
||
|
10101 10101 10110 10110 11001 11000 11010 11010
|
||
|
|
||
|
By reconstructing the LSBs of the above bytestream, we recover the number
|
||
|
200 (11001000). In the above example, the original bytestream of the numbers
|
||
|
20-27 is the container, while the number 200 is the message file. This is a
|
||
|
very poor basic example since the resulting stego file is not an accurate
|
||
|
representation of the original file. After modification to include the
|
||
|
message file, the numbers 20-27 now read:
|
||
|
|
||
|
21 21 22 22 25 24 26 26
|
||
|
|
||
|
However, in most stego applications, the container file does not contain
|
||
|
bytestreams which are rendered useless by modifying LSB information.
|
||
|
Instead, container files typically contain various levels of "noise" at the
|
||
|
level of the LSB's which when viewed apart from the rest of the byte can
|
||
|
appear random. A sound (.WAV) file, for example contains mostly inaudible
|
||
|
background noise at the LSB level. An 8-bit graphic file will contain minor
|
||
|
color differences at the LSB level, while a 24-bit image will contain color
|
||
|
changes which are nearly imperceptible to the human eye. A very common
|
||
|
container format is a 256 color, 8 bit image such as a GIF or BMP file.
|
||
|
|
||
|
|
||
|
II. Stego Techniques
|
||
|
|
||
|
|
||
|
In an 8-bit image such as a GIF or BMP each pixel is described as a number
|
||
|
from 0 - 255 which refers to an actual color in the "color lookup table" or
|
||
|
palette. A common misconception is that all images simply contain strings of
|
||
|
bytes that describe individual colors, and that the graphic file simply
|
||
|
lists these colors in left-to-right, and top-to-bottom fashion. This is
|
||
|
only partially true for 8-bit images. The palette lists every color that is
|
||
|
used in the image (and extra colors, if less than 256 total colors are actually
|
||
|
used in the image), and the image data itself is stored as a series of digits
|
||
|
from 0 - 255 which reference an entry in the palette. In this way, the image
|
||
|
can be reconstructed by performing palette lookups to determine the color to
|
||
|
insert at that pixel location.
|
||
|
|
||
|
In order to hide data within an 8-bit GIF or BMP container, most existing
|
||
|
tools use one of two techniques which I will term LSB palette reference
|
||
|
modification and RGB element LSB modification.
|
||
|
|
||
|
LSB palette reference modification involves changing the LSB(s) of a
|
||
|
_palette_reference_ (0 - 255) in order to hide the data contained in the
|
||
|
message. Remember that a palette reference simply contains a number from 0 -
|
||
|
255 which references a color, or entry, in the palette. In order to hide
|
||
|
data, a program utilizing palette reference modification may decide which
|
||
|
color to point to based on the color's LSBs. This type of program will pay
|
||
|
no attention to how similar the colors are, only whether or not the LSBs
|
||
|
serve its purpose of data hiding. If the adjacent colors in the palette have
|
||
|
dissimilar LSBs, they are well suited for data hiding and become good
|
||
|
candidates for storing hidden text in the final stegoed container. If a 0
|
||
|
(zero) is meant to be hidden, the stego program inserts the palette index
|
||
|
reference of the color with the LSB of 0 (zero), and vice versa for hiding a
|
||
|
1 (one).
|
||
|
|
||
|
RGB element LSB modification involves modifying the pixel's _actual_color_
|
||
|
by changing the LSB of the Red, Green or Blue elements of the color in the
|
||
|
color table. For example, the color "white" is represented by the RGB values
|
||
|
255,255,255 which in binary equates to:
|
||
|
|
||
|
11111111 11111111 11111111
|
||
|
|
||
|
listed in RGB order. By altering the LSB of each color in the RGB element,
|
||
|
we can hide data by making almost identical copies of colors such that only
|
||
|
the LSBs are different. Since the color is only changed by one or two LSBs,
|
||
|
the resulting colors are very close, perhaps undetectable to the human eye.
|
||
|
The result of this change to the colors in the table enables nearly identical
|
||
|
colors to be referenced by multiple table entries. This becomes extremely
|
||
|
obvious when the palette is viewed and sorted by luminance (relative
|
||
|
brightness)in a product such as Paint Shop Pro. These similar colors will be
|
||
|
grouped right next to each other in a luminance-sorted palette. Using this
|
||
|
technique, a binary 1 in the message file can be represented in the stego file
|
||
|
by replacing a color in the container file with an altered version of that
|
||
|
color whose RG or B element ends with a binary 1. Likewise, a binary 0 in the
|
||
|
message file can be represented in the stego file by replacing the original
|
||
|
color in the container file with an altered version of that color whose RG or
|
||
|
B element ends with a binary 0.
|
||
|
|
||
|
|
||
|
III. Steganographic Thumbprints
|
||
|
|
||
|
|
||
|
Several tools are available that apply these techniques to files on
|
||
|
several different platforms. I will focus on two specific toolsets; Steganos
|
||
|
and S-Tools v4.0. Steganos is perhaps the most versatile and powerful of the
|
||
|
toolsets, while S-Tools seems to be the easiest and most widely used (not to
|
||
|
mention the fact that I like S-Tools; it's been around for a long time and
|
||
|
is very well done). Other available toolsets include similar functionality
|
||
|
and hiding techniques. In order to discover what the tools actually do when
|
||
|
they hide data, it's best to use a simple BMP container file. The RGB BMP
|
||
|
file utilizes a palette scheme identical to that of a GIF for the purposes
|
||
|
of our tests, and all the reviewed toolsets can use BMP files as containers.
|
||
|
|
||
|
For example, consider a container image which is 50 pixels by 50 pixels and
|
||
|
contains only black-colored (0,0,0) pixels. This image references palette
|
||
|
entry 0 (zero) as its only color. I will use a freeware painting program Paint
|
||
|
Shop Pro V4.10 (PSP) to create and analyze the base images. When creating
|
||
|
this image, PSP used a default palette with 216 unique palette entries and 40
|
||
|
"filler" entries at the end of the palette all of which contain the value
|
||
|
(0,0,0) or pure black.
|
||
|
|
||
|
Our message file is simply a text file which contains the phrase "This is a
|
||
|
test."
|
||
|
|
||
|
|
||
|
A. S-Tools
|
||
|
|
||
|
|
||
|
When the message file is hidden using S-Tools, the resulting 8-bit image
|
||
|
appears identical to the human eye when compared to the original. However,
|
||
|
there are perceptible oddities about the file which are revealed under closer
|
||
|
scrutiny.
|
||
|
|
||
|
Since S-Tools uses RGB element LSB modification as its hiding technique,
|
||
|
the palette has distinct and very obvious characteristics. Many of the
|
||
|
palette's colors are offset by a single bit in the R,G or B element. This is
|
||
|
very obvious when the palette is sorted by luminance (brightness) and viewed
|
||
|
with PSP. The first sixteen (and only original) colors in this palette are:
|
||
|
|
||
|
(51,1,1) (51,1,0) (50,1,0) (51,0,1) (51,0,0) (50,0,1) (50,0,0)
|
||
|
|
||
|
(1,1,0) (1,1,0) (0,1,1) (0,1,0) (1,0,1) (1,0,1) (1,0,0) (0,0,1) (0,0,0)
|
||
|
|
||
|
Notice that the offsets of the RGB elements are only 1 bit. This is an
|
||
|
imperceptible color change, and is a very wasteful use of the palette.
|
||
|
Remember, there are only 256 colors to work with. Most 8-bit image creation
|
||
|
programs are very careful when deciding which colors to include in the palette,
|
||
|
and almost all use standard palettes which contain all the most commonly used
|
||
|
colors. To see a palette with this many _nearly_ identical colors is odd.
|
||
|
Also, the palette has been adjusted to contain less colors. The standard
|
||
|
colors selected by PSP have been replaced by some of the colors listed above.
|
||
|
As is typical with this type of hiding, the slack space at the end of the
|
||
|
palette has been reduced to make room for the new copies of existing colors.
|
||
|
This type of hiding will always make itself obvious by using single-bit
|
||
|
offsets in one or more of the LSBs. Since this type of thumbprint is so
|
||
|
easily identifiable, we will concentrate our efforts on the harder-to-detect
|
||
|
palette reference method used by Steganos.
|
||
|
|
||
|
|
||
|
B. Steganos
|
||
|
|
||
|
|
||
|
Steganos kindly reminds you that 8-bit images don't make terribly secure
|
||
|
containers. It's a good thing, too, because when the message file is hidden
|
||
|
using Steganos the resulting 8-bit image has a major anomaly- the stego
|
||
|
image is completely different than the original! As opposed to an all-black
|
||
|
image, the image now resembles a black-and-blue checkerboard. However, this
|
||
|
difference is only obvious if you have access to the original image. Since
|
||
|
an interceptor will most likely not have a copy of the original image, we
|
||
|
will examine other methods of detection. When the palette of the image is
|
||
|
checked for single-bit offset colors (as in the stego image created with
|
||
|
S-Tools), none can be found. Also, there is no more or less slack space at
|
||
|
the end of the palette than existed in the original palette. Steganos does
|
||
|
not alter the palette in any way when hiding data. It uses the LSB palette
|
||
|
reference technique described above. However, there are very distinctive
|
||
|
ways of determining if this technique has been used to hide data, specifically
|
||
|
by looking at _how_ the palette's colors are used. In this simple case, a
|
||
|
histogram will show exactly the type of modification we are looking for.
|
||
|
In the words of the PSP Help documentation,
|
||
|
|
||
|
"A histogram is a graph of image color values, typically RGB values and/or
|
||
|
luminance. In a histogram, the spectrum for a color component appears on the
|
||
|
horizontal axis, and the vertical axis indicates the portion of the image's
|
||
|
color that matches each point on the component's spectrum."
|
||
|
|
||
|
In a nutshell, this simply means a graph is generated showing how the
|
||
|
color(s) are used in an image, and how similar (in shade) they are. When
|
||
|
viewing the "blue" histogram for the Steganos-hidden file, we see something
|
||
|
like this:
|
||
|
|
||
|
100= X X
|
||
|
- X X
|
||
|
90 = X X
|
||
|
- X X
|
||
|
80 = X X
|
||
|
- X X
|
||
|
70 = X X
|
||
|
- X X
|
||
|
60 = X X
|
||
|
- X X
|
||
|
50 = X X
|
||
|
- X X
|
||
|
40 = X X
|
||
|
- X X
|
||
|
30 = X X
|
||
|
- X X
|
||
|
20 = X X
|
||
|
- X X
|
||
|
10 = X X
|
||
|
- X X
|
||
|
00 = X X
|
||
|
. ! . ! . ! . ! . ! . ! . ! . ! . ! . ! . . .
|
||
|
0 1 2 3 4 5 6 7 8 9 2
|
||
|
0 0 0 0 0 0 0 0 0 0 5
|
||
|
5
|
||
|
|
||
|
The X-axis shows the spectrum for the color blue (from 0 to 255). The
|
||
|
Y-axis shows the number of pixels in the image that match that color. When
|
||
|
displaying a histogram, the 100 on the Y axis is not percentage, but a MAX
|
||
|
value (in this case 1272) which indicates the greatest number of pixels used
|
||
|
for _any_one_color_. Since there are really only two colors _used_ in this
|
||
|
stego image, there are only two vertical bars. These bars indicate that in
|
||
|
the Blue color family there are really only two colors used; one with a blue
|
||
|
value of zero, and another with a blue value of approximately 50 (51 to be
|
||
|
exact). Upon examining the color table for this image sorted in
|
||
|
_palette_order_, it is evident that these two referenced colors are only
|
||
|
similar since they are placed right next to one another in the palette. The
|
||
|
two colors are (0,0,0) and (0,0,51) or black and very, very dark blue. The
|
||
|
image mostly has black hues, and Steganos probably picked the very dark blue
|
||
|
color (00110011) as the 1 for some hidden data, and black (00000000) as the
|
||
|
0 for some hidden data since these colors are _right_ next to each other in
|
||
|
a palette-index-order color table listing. Although they reside next to each
|
||
|
other in the palette, the colors are not very similar which makes the final
|
||
|
stego file appear discolored. Steganos does not modify any of the colors,
|
||
|
but it modifies how the original palette is used by making nearly equal
|
||
|
references to a color and its neighbor (when sorted by palette index).
|
||
|
Bottom line: this image uses neighboring palette colors nearly an identical
|
||
|
number of times. 1272 pixels were used for black and 1228 pixels were used
|
||
|
for the dark, dark blue. This would not be unusual if not for the fact that
|
||
|
the colors are palette index neighbors. If the designer of the image were
|
||
|
using some sort of shading effect, there would be many more than just two
|
||
|
shades involved in this 256 color image, and the shading offsets would be
|
||
|
greater. These two colors don't even appear as shades of one another when
|
||
|
placed side-by-side.
|
||
|
|
||
|
A skilled interceptor will know immediately that something is not quite
|
||
|
right with these images. They both display typical signs of data hiding.
|
||
|
|
||
|
|
||
|
IV. Real-World example
|
||
|
|
||
|
|
||
|
Intercepting a single-color image and determining that it is stegoed is a
|
||
|
trivial task. Increasing the number of used colors within the boundaries of
|
||
|
the 256-color palette could (so the reader may think) obfuscate the hidden
|
||
|
message file. However, by applying a few simple methodologies, a pattern
|
||
|
emerges which can increase the odds of detecting a stegoed image. For
|
||
|
example, if a two-color image is created using only the colors black (0,0,0)
|
||
|
and white (255,255,255), and data is hidden in the file by using Steganos,
|
||
|
the results would show that Steganos not only used black and white, but two
|
||
|
more colors from the palette are used with values of (0,0,51) and
|
||
|
(255,255,51) respectively. These newly-used colors adjoin the original two
|
||
|
colors in the palette listing, have differing LSBs, and are referenced
|
||
|
nearly as much in the new image as the original colors are. A similar
|
||
|
situation evolves when a 6-color image is created. After Steganos hides the
|
||
|
data, the original 6 colors and their palette neighbors will be used in
|
||
|
the new file. The 6 new colors become alternate representations of the
|
||
|
original 6 colors in terms of their LSBs. This methodology holds true all
|
||
|
the way up to images containing 256 different colors. By understanding these
|
||
|
patterns, all 8-bit Steganos images can be detected without access to the
|
||
|
original image.
|
||
|
|
||
|
When attempting to detect the use of steganography in 16 or 24-bit images,
|
||
|
a great deal of pattern analysis must be used. 24-bit stego detection is not
|
||
|
for the faint of heart, but it can be done. Standard "randomization" solutions
|
||
|
fall quite short of solving this problem since LSB data in image creation
|
||
|
programs is hardly random. It follows a pronounced pattern when viewed as a
|
||
|
part of a whole: an 8-bit number. Most standard graphics effects do not use
|
||
|
random data, they use patterns to create and maintain a certain graphic
|
||
|
illusion. Inserting "random" data, even at the LSB level can become fuel for
|
||
|
the analyst's fire. In many 24-bit stego programs, bits in the secret text
|
||
|
are generally inserted with average spacing between them, then random "noise"
|
||
|
is added to make the secret bits seem less obvious. The random "noise" would
|
||
|
(should!) have a random interval between differing bits. The contrast of an
|
||
|
average spacing against random spacing may be enough to not only alert an
|
||
|
analyst, but to point out where secret bits start and random bits begin. The
|
||
|
bottom line is that 24-bit detection is doable, just not practical for an
|
||
|
amateur- yet!
|
||
|
|
||
|
|
||
|
V. The Future
|
||
|
|
||
|
|
||
|
Steganography is in it's infancy, but several new technologies are emerging
|
||
|
including selection and construction methods of data hiding and continuing
|
||
|
research in the area of random distribution.
|
||
|
|
||
|
Selection involves the generation of a large number of copies of the same
|
||
|
container file that differ slightly. In the case of an image file, you may
|
||
|
make minor adjustments in hue, saturation and RGB levels to the end that your
|
||
|
secret message will eventually _appear_ in the LSBs of the data! Although
|
||
|
difficult to generate, this type of data hiding is nearly impossible to detect
|
||
|
since the image's characteristics are not altered at all.
|
||
|
|
||
|
Construction simply involves modeling the characteristics of the original
|
||
|
container when creating your message. In simplest terms, mold your message
|
||
|
around the existing container instead of molding the container to your message.
|
||
|
If, for example the original image were left unchanged, and a key was
|
||
|
developed to create the message _from_ the image, detection would be impossible
|
||
|
without the key.
|
||
|
|
||
|
Several advances are being made in the area of random distribution,
|
||
|
specifically by Tuomas Aura at the Helsinki University of Technology. His
|
||
|
paper "Practical Invisibility in Digital Communication" presents a technique
|
||
|
called "pseudorandom permutation", which brings steganography up to the
|
||
|
technical level of cryptography and properly addresses the issue of
|
||
|
randomness from a data hiding perspective. His paper is excellent reading
|
||
|
and can be found at http://deadlock.hut.fi/ste/ste_html.html
|
||
|
|
||
|
Interesting research (and proof-of-concepts) are being done to utilize
|
||
|
stego techniques in reserved fields in TCP, UDP and ICMP packets. This
|
||
|
research proves that steganography has merit and application beyond sound and
|
||
|
image files. Unfortunately, using stego where there was nothing before (ie
|
||
|
within typically blank reserved fields) can raise a flag in and of itself. Use
|
||
|
encryption and compression to further protect data. It really doesn't matter
|
||
|
if the secret data is discovered if the underlying crypto is secure.
|
||
|
|
||
|
|
||
|
VI. Conclusion
|
||
|
|
||
|
|
||
|
Detecting stego in an 8-bit image is fairly easy. Actually gaining access
|
||
|
to the secret text becomes a bit harder yet a simple overlooked method involves
|
||
|
bruteforcing the creating application (see S_BRUTE.WBT program below). On the
|
||
|
other hand, 24-bit image analysis requires quite a bit of work. If you choose
|
||
|
to employ data hiding techniques, use 24-bit images and compress and encrypt
|
||
|
your message file, bearing in mind that 24-bit images can raise flags simply
|
||
|
due to their size.
|
||
|
|
||
|
When attempting to identify stego files in 8-bit images, keep in mind the
|
||
|
following pointers:
|
||
|
|
||
|
* Search for the obvious thumbprint of an RGB element.
|
||
|
* In the stego file: single-bit offsets between colors in a palette sorted by
|
||
|
luminance (this SCREAMS S-Tools!).
|
||
|
* If no single-bit offsets exist between the colors in the palette, search
|
||
|
for Palette Reference thumbprints which include the following:
|
||
|
* Use of palette index neighbors a near-equal number of times either in the
|
||
|
entire image (use a histogram) or in an area which should be primarily
|
||
|
single-color only but contains a checkerboard effect (use zoom 11:1 to see
|
||
|
individual pixels, and the eyedropper tool to quickly view the RGB
|
||
|
elements in PSP)
|
||
|
* Poor image quality (noise and snow are common side-effects).
|
||
|
* For more detailed analysis the reader might consider using an MS-DOS
|
||
|
program msgifscn.zip, available from Simtel mirror sites worldwide, to
|
||
|
dump the entire contents of an 8-bit GIF image's palette to a file, which
|
||
|
can be dumped into MS Excel for analysis (the analysis add-in in for Excel
|
||
|
comes in REAL handy for binary conversions and data sorts.)
|
||
|
* If you have a clue that the file you're looking at may contain stegoed
|
||
|
data, it never hurts to brute force the application that created it! (see
|
||
|
the S_BRUTE program listing at the end of this article) While this may be
|
||
|
one of the slower methods of breaking stego, it is often easier to
|
||
|
derive possible keyphrases from other sources than attacking the stego
|
||
|
algorithm or the crypto.
|
||
|
|
||
|
|
||
|
VII. The program
|
||
|
|
||
|
The author of S-Tools sells the source code for his program, and Steganos
|
||
|
makes available an SDK for hiding/decoding files using it's algorithms, but
|
||
|
an option exists for programs that do not make their source available:
|
||
|
bruteforce of the application itself. Although using the API and SDK's
|
||
|
available would be significantly faster, there are times when this option
|
||
|
just may not exist.
|
||
|
|
||
|
To that end, included below are two files, S_BRUTE.WBT and S_BRUTE.INI.
|
||
|
This program was written in WinBatch, which is a language that acts very much
|
||
|
like the UNIX language TCL/TK (or Expect), but operates in a Windows 95/NT
|
||
|
context. Developed to control Windows applications, WinBatch provides a
|
||
|
perfect vehicle for brute-forcing an application's password function (see
|
||
|
http://www.windowware.com for the free compiler to run S_BRUTE). S_BRUTE is
|
||
|
an application that will bruteforce S-Tools v4 and Steganos using a
|
||
|
dictionary file in an attempt to determine the passphrase of a stegoed image
|
||
|
(which will subsequently reveal the hidden text). The program selects which
|
||
|
tool to use based on which executable you select, and the S-Tools portion of
|
||
|
the program will not only bruteforce the passphrase, but will attempt all
|
||
|
four algorithms available to S- Tools. Unfortunately S-Tools uses certain
|
||
|
mouse-only operations, so you will effectively lose your mouse while the
|
||
|
S-Tools portion runs. The dictionary needed by this program is simply a list
|
||
|
of words or passphrases separated by newlines. Keep in mind that Steganos
|
||
|
does not allow passwords shorter than five characters, so strip those out to
|
||
|
save time. If you need to use a " (double-quote) in the word/passphrase,
|
||
|
simply use "" (two double quotes) in the dictionary. WinBatch likes this. A
|
||
|
log file is created as c:\output.txt which simply lists all the attempted
|
||
|
words/passphrases. The output file can be reused as a dictionary since no
|
||
|
extraneous information is written out. Two options exist for inputting the
|
||
|
names of the Stego tool executable, the dictionary file and the stego image.
|
||
|
The S_BRUTE.INI file format (see below) allows the variables exepath, dict
|
||
|
and stegofile which allow the input of these full path names into the
|
||
|
program. In addition, the program can prompt for the filenames manually
|
||
|
using standard Windows '95 file boxes. In this case, pay attention to the
|
||
|
box titles as they come up. These titles describe what file the program is
|
||
|
looking for. A variable is also available in the INI file called
|
||
|
STEGANOSDELAY. This value (listed in seconds) determines how long to wait
|
||
|
for a passphrase error message from Steganos. The default is 0, but if you
|
||
|
get a lot of false positives (your machine is SLOW!) set this value to a few
|
||
|
seconds. Due to the speed of the bruteforce attack, this program is not
|
||
|
always accurate as to _which_word_ actually worked if it finds a match. In
|
||
|
this case, S_BRUTE will tell you which word it _thinks_ worked, but you may
|
||
|
have to try the word S_BRUTE gave you plus one or two of the previous words
|
||
|
in c:\output.txt (plus a few different algorithms if you're using S-Tools).
|
||
|
Either way, you are only looking at about 12 combinations (not bad!).
|
||
|
|
||
|
Note that S-Tools and/or Steganos must be properly installed prior to using
|
||
|
this program. S_BRUTE was not designed to brute force the entire keyspace, but
|
||
|
to give you a faster method of determining the passphrase if you have any idea
|
||
|
what it might be. If the stego image is found on a web page, create a
|
||
|
dictionary from words and phrases found on that site, and let S_BRUTE do the
|
||
|
work for you.
|
||
|
|
||
|
<++> sbrute/S_BRUTE.WBT
|
||
|
;; Steganography Brute v1.0 written by a researcher at hacklab.com
|
||
|
;; For new versions and support programs see http://www.hacklab.com
|
||
|
;; This little toy brute forces two very common Steganography utilities,
|
||
|
;; specifically Steganos (http://www.steganography.com) and S-Tools written
|
||
|
;; by Andrew Brown (a.brown@nexor.co.uk)
|
||
|
;; This program can be run using a free program called WinBatch
|
||
|
;; from http://www.windowware.com
|
||
|
;;
|
||
|
;;
|
||
|
;;Notes:
|
||
|
;;
|
||
|
;; 1) The program depends on the executable name being either "S-TOOLS.EXE" or
|
||
|
;; "STEGANOS.EXE". This exe name decides many things, including the
|
||
|
;; semantics of the brute force attack and which types of container files
|
||
|
;; to accept. (Remember that the tools accept different types of container
|
||
|
;; files.)
|
||
|
;; 2) The dictionary file is simply a text file with words or phrases separated
|
||
|
;; by CR(LF). If a " (double quote) must be used in the word or phrase,
|
||
|
;; use "" (two double quotes) instead. This is Winbatch's way of representing
|
||
|
;; the double quote in a string.
|
||
|
;; 3) Internally, this program converts all Windows LFN-formatted dir/filenames to
|
||
|
;; DOS-style 8.3 or short dir/filenames. If you have problems, finding/using
|
||
|
;; LFN files, you may want to manually convert them to a SFN dir/file structure.
|
||
|
;; 4) The S-Tools test requires certain mouse-only operations. During this part of
|
||
|
;; the program, it's best to leave your machine alone. Otherwise the mouse will
|
||
|
;; be all over the place. Sorry.
|
||
|
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
:main ;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
|
||
|
|
||
|
Intcontrol(12,4,0,0,0) ;;controls abrupt endings
|
||
|
|
||
|
if (winmetrics(-4) < 4 )
|
||
|
error="This program runs on Windows NT or Windows '95 only!"
|
||
|
gosub bail_error
|
||
|
EndIf
|
||
|
|
||
|
cr=Num2Char(13)
|
||
|
lf=Num2Char(10)
|
||
|
crlf=StrCat(cr, lf)
|
||
|
progname="Steganography Brute"
|
||
|
STEGANOS=0 ;; Flag for Steganos
|
||
|
STOOLS=0 ;; Flag for S-Tools
|
||
|
|
||
|
|
||
|
|
||
|
text1='This program brute forces Steganography programs.'
|
||
|
text2='Including S-Tools v4.0 and Steganos. Do you wish'
|
||
|
text3='to continue?'
|
||
|
;q = AskYesNo('%progname%',"%text1% %crlf% %text2% %crlf% %text3%")
|
||
|
If (AskYesNo('%progname%',"%text1% %crlf% %text2% %crlf% %text3%") == @NO) Then Exit
|
||
|
|
||
|
text1="It is easiest to make all file settings through the"
|
||
|
text2="S_BRUTE.INI file in this directory. If you do not use"
|
||
|
text3="this file, you will be manually prompted for the files."
|
||
|
Text4="Do you wish to use the INI file?"
|
||
|
q= AskYesNo("%progname%"," %text1% %crlf% %text2% %crlf% %text3% %crlf% %text4%")
|
||
|
|
||
|
if (q == @NO) Then gosub prompt_for_files
|
||
|
else gosub set_files
|
||
|
|
||
|
|
||
|
if (STEGANOS)
|
||
|
gosub steganos
|
||
|
else
|
||
|
if (STOOLS) then gosub stools
|
||
|
EndIf
|
||
|
|
||
|
error="Passphrase not found!"
|
||
|
gosub bail_error
|
||
|
|
||
|
Exit
|
||
|
|
||
|
|
||
|
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
:steganos ;;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
Run("%exepath%", "%stegofile%")
|
||
|
WinWaitExist("",10) ;;; Steganos' first window has no title.
|
||
|
;;; If you have problems,
|
||
|
SendKeysTo("","{ENTER}") ;;; comment out these two lines...
|
||
|
;TimeDelay(10) ;;; and uncomment...
|
||
|
;SendKey("{ENTER}") ;;; these two lines.
|
||
|
|
||
|
|
||
|
WinWaitExist("Steganos for Windows 95",30)
|
||
|
SendKeysTo("Steganos for Windows 95","{ENTER}")
|
||
|
|
||
|
dictgrip=FileOpen("%dict%","READ")
|
||
|
fn1="c:\output.txt"
|
||
|
handleout=FileOpen("%fn1%","Append")
|
||
|
stitle="Steganos for Windows 95"
|
||
|
START_TIME=TimeYmdHms()
|
||
|
word=0
|
||
|
|
||
|
while (word != "*EOF*")
|
||
|
word = FileRead(dictgrip)
|
||
|
if word =="" then continue
|
||
|
if word =="*EOF*" then break
|
||
|
ClipPut("%word%")
|
||
|
SendKeysTo(stitle,"^v{ENTER}")
|
||
|
TimeDelay(STEGANOSDELAY)
|
||
|
test=strsub(MsgTextGet(stitle),1,22)
|
||
|
if test==""
|
||
|
text1="I think we have a match!"
|
||
|
text2="Due to the speed of the brute force attack, check c:\output.txt"
|
||
|
text3="to see the last few words used, but I think the passphrase is:"
|
||
|
text4="%word%"
|
||
|
success="%text1% %crlf%%text2% %crlf%%text3% %crlf%%text4%"
|
||
|
gosub bail_success
|
||
|
else
|
||
|
if test=="This password is wrong"
|
||
|
SendKeysTo(stitle,"{ENTER}")
|
||
|
SendKeysTo(stitle,"!B{ENTER}")
|
||
|
FileWrite(handleout,"%word%" )
|
||
|
endif
|
||
|
endif
|
||
|
endwhile
|
||
|
STOP_TIME=TimeYmdHms()
|
||
|
|
||
|
FileClose(dictgrip)
|
||
|
FileClose(handleout)
|
||
|
|
||
|
Return
|
||
|
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
:stools ;;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
Run("%exepath%", "%stegofile%")
|
||
|
if (WinWaitExist("Welcome to S-Tools",5) == @TRUE)
|
||
|
SendKeysTo("Welcome to S-Tools","!C")
|
||
|
EndIf
|
||
|
|
||
|
winplace(0,0,400,400,"~S-Tools")
|
||
|
WinWaitClose("Please Wait")
|
||
|
SendMenusTo("~S-Tools", "Window Tile Horizontally")
|
||
|
|
||
|
text1="S-Tools requires certain mouse-only operations."
|
||
|
text2='After clicking OK, position the mouse within your'
|
||
|
text3="image in the S-Tools window and click the left button."
|
||
|
|
||
|
message("Setup mouse for S-Tools","%text1% %crlf% %text2% %crlf% %text3%")
|
||
|
|
||
|
while (mouseinfo(4)!="4")
|
||
|
magic=mouseinfo(2)
|
||
|
endwhile
|
||
|
|
||
|
magicx=( ItemExtract(1,magic," ") )
|
||
|
magicy=( ItemExtract(2,magic," ") )
|
||
|
|
||
|
|
||
|
dictgrip=FileOpen("%dict%","READ")
|
||
|
fn1="c:\output.txt"
|
||
|
handleout=FileOpen("%fn1%","Append")
|
||
|
|
||
|
START_TIME=TimeYmdHms()
|
||
|
word=0
|
||
|
while (word != "*EOF*")
|
||
|
word = FileRead(dictgrip)
|
||
|
if word =="" then continue
|
||
|
ClipPut("%word%")
|
||
|
|
||
|
;;; write to the output file
|
||
|
if word!="*EOF*"
|
||
|
if (FileWrite(handleout,"%word%" ) >0)
|
||
|
error="Unable to open file %fn1%."
|
||
|
gosub bail_error
|
||
|
EndIf
|
||
|
Endif
|
||
|
|
||
|
for dumnum=1 to 4 ;; for all the algorithms
|
||
|
|
||
|
MouseMove(magicx, magicy, "","")
|
||
|
MouseClick(@RCLICK, 0)
|
||
|
SendKeysTo("~S-Tools","r")
|
||
|
SendKeysTo("~Revealing","!P^v!V^v!E")
|
||
|
|
||
|
if (dumnum==1) then SendKeysTo("~Revealing","I") ;; IDEA
|
||
|
if (dumnum==2) then SendKeysTo("~Revealing","D") ;; DES
|
||
|
if (dumnum==3) then SendKeysTo("~Revealing","T") ;; DES3
|
||
|
if (dumnum==4) then SendKeysTo("~Revealing","M") ;; MDC
|
||
|
SendKeysTo("~Revealing","{ENTER}")
|
||
|
;childlist=WinItemChild("~S-Tools")
|
||
|
numchilds= ItemCount(WinItemChild("~S-Tools"), @TAB)
|
||
|
|
||
|
if (numchilds>2)
|
||
|
text1="We have an extra window in S-Tools! Possible passphrase match."
|
||
|
text2="Due to the speed of the brute force attack, check c:\output.txt"
|
||
|
text3="to see the last few words used, but I think the passphrase is:"
|
||
|
text4="%word%"
|
||
|
success="%text1% %crlf%%text2% %crlf%%text3% %crlf%%text4%"
|
||
|
gosub bail_success
|
||
|
endif
|
||
|
next
|
||
|
|
||
|
endwhile
|
||
|
|
||
|
FileClose(dictgrip)
|
||
|
FileClose(handleout)
|
||
|
|
||
|
return
|
||
|
|
||
|
|
||
|
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
:set_files ;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
fname=IniReadPvt("Main", "exepath", ".\S-TOOLS.EXE", ".\S_BRUTE.INI")
|
||
|
gosub path_clean
|
||
|
exepath=fname
|
||
|
|
||
|
gosub determine_tool_type
|
||
|
|
||
|
fname=IniReadPvt("Main", "dict", ".\DICT.TXT", ".\S_BRUTE.INI")
|
||
|
gosub path_clean
|
||
|
dict=fname
|
||
|
|
||
|
fname=IniReadPvt("Main", "stegofile", ".\STEGO.GIF", ".\S_BRUTE.INI")
|
||
|
gosub path_clean
|
||
|
stegofile=fname
|
||
|
|
||
|
STEGANOSDELAY=IniReadPvt("Main","STEGANOSDELAY","0",".\S_BRUTE.INI")
|
||
|
|
||
|
gifname= ItemExtract( (ItemCount("%stegofile%", "\")), "%stegofile%", "\")
|
||
|
|
||
|
Return
|
||
|
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
:prompt_for_files ;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
msg = "Enter the Steganos error delay 0-60"
|
||
|
STEGANOSDELAY=AskLine("%progname%", msg ,"0")
|
||
|
|
||
|
types="Dictionary Text Files|*.txt|All Files|*.*|"
|
||
|
dict=AskFileName("Select Dictionary Filename", "C:\", types, "dict.txt", 1)
|
||
|
dict=FileNameShort(dict)
|
||
|
|
||
|
types="Steganography tool Executable|*.exe|"
|
||
|
msg="Where is the S-Tools or Steganos executable?"
|
||
|
exepath=AskFileName(msg, "C:\", types, "", 1)
|
||
|
exepath=FileNameShort(exepath)
|
||
|
|
||
|
gosub determine_tool_type
|
||
|
|
||
|
if (STEGANOS)
|
||
|
types="Stego File (with hidden message)|*.bmp;*.dib;*.voc;*.wav;*.txt;*.html|"
|
||
|
else
|
||
|
types="Stego File (with hidden message)|*.gif;*.bmp;*.wav|"
|
||
|
endif
|
||
|
|
||
|
text1="Select Stego Filename (containing hidden message)"
|
||
|
stegofile=AskFileName("%text1%", "C:\", types, "", 1)
|
||
|
stegofile=FileNameShort(stegofile)
|
||
|
gifname= ItemExtract( (ItemCount("%stegofile%", "\")), "%stegofile%", "\")
|
||
|
Return
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
:path_clean ;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
switch FileExist(fname)
|
||
|
case 0
|
||
|
error="File %fname% not found!"
|
||
|
gosub bail_error
|
||
|
break
|
||
|
case (2)
|
||
|
error="File %fname% in use!"
|
||
|
gosub bail_error
|
||
|
break
|
||
|
endswitch
|
||
|
fname=FileNameShort(fname)
|
||
|
Return
|
||
|
|
||
|
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
:determine_tool_type ;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
exename=(StrUpper(ItemExtract( (ItemCount("%exepath%", "\")), "%exepath%", "\")))
|
||
|
|
||
|
if (exename == "S-TOOLS.EXE") then STOOLS=1
|
||
|
else if (exename == "STEGANOS.EXE") then STEGANOS=1
|
||
|
Return
|
||
|
|
||
|
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
:bail_error ;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
STOP_TIME=TimeYmdHms()
|
||
|
Message("%progname% Error!","%error%")
|
||
|
SECONDS=TimeDiffSecs(STOP_TIME,START_TIME)
|
||
|
Message("%progname%","Finished in %SECONDS% seconds.")
|
||
|
Exit
|
||
|
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
:bail_success ;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
STOP_TIME=TimeYmdHms()
|
||
|
Message("%progname% Success!!!","%success%")
|
||
|
Message("%progname%","Time Started: %START_TIME%%crlf%Time Finished: %STOP_TIME%")
|
||
|
Exit
|
||
|
|
||
|
<-->
|
||
|
<++> sbrute/S_BRUTE.INI
|
||
|
[Main]
|
||
|
|
||
|
EXEPATH="C:\Program Files\Deus Ex Machina\Steganos\Steganos.exe"
|
||
|
DICT="C:\win\desktop\dict.txt"
|
||
|
STEGOFILE="C:\win\desktop\steclouds.bmp"
|
||
|
;STEGOFILE="C:\win\desktop\s-tclouds.gif"
|
||
|
STEGANOSDELAY=0 ;; Set this higher for false positives.
|
||
|
;; (Steganos does not use different names for its
|
||
|
;; windows, so this program makes negative result
|
||
|
;; checks (ie bad passwords) based on an error dialog.
|
||
|
;; This timeout controls how many seconds to wait for
|
||
|
;; an error. Default=0
|
||
|
|
||
|
<-->
|
||
|
----[ EOF
|
||
|
|