2005 Contest Results
This was a very difficult contest to judge. The two top entries
were incomparable owing to a very different approaches towards
underhanded coding.
That being said, I'm going to announce two winners.
One was far too sophisticated to earn a 2nd place.
The other was simpler, but exactly in keeping with the
philosophy of the contest. Both will get prizes.
-
M Joonas Pihlaja and Paul V-Khuong
This entry was huge, sophisticated and the most impressive fingerprinting
code. You have to give these guys an award just for the work they
employed to smuggle executable code into a vector of doubles.
On the other hand, the underhanded code was a straightforward
array bounds violation. Concealing bad behavior in data is very
clever, but also easier than hiding it in plain sight: the programmers
could hide whatever they wanted in your image, and do so robustly.
Another interesting aspect of this entry is that the "overprogram,"
the innocent image processing operation, is embedding a watermark.
This lets the programmers hide the message robustly, just by hijacking
the mark data.
-
Natori Shin
Natori Shin's entry was a very small and simple C program, which earns
extra points. Why? Because the challenge is to write innocent-looking code.
Huge source files are less innocent-looking, because you can
hide a lot in them. Small programs are inherently more trustworthy.
Also, a simple program presents more of a challenge.
Shin's source trick earns points as well. It does not perform
an array bounds violation, it does not confuse assignment and comparison.
It can not be easily flagged by automatic source code analysis.
This is very much in the spirit of the contest: write a program that
looks very simple and innocent, but hides bad behavior in the source right
in front of your eyes.
-
The descriptions of 5 entries follows. The code can be found in
this directory here
-
Matt Skala
-
- Difficulty / Sophistication
-
- Simplicity of Code
-
At nearly 600 lines, the code has many potential hiding places.
- Imperceptibility (of bad code, and results)
-
The bad code is small (1 character,) but blunt: an extra equals sign
in a loop test.
Other stylistic elements of the code help to make the bad behavior
look innocent.
- Obscurity of attack
-
Munges pointers by a buffer overrun so that a subsequent call to
stat() will put file info in a logo embedded in the image.
Techniques include the use of stat() (not the only submission to
do this,) confusion by levels of indirection, and an array bounds
condition.
- Amount of Information
-
Stat() information is added to the image, but not necessarily recoverable. This is not so bad if we suspect certain stat data a priori.
- Robustness of mark (extra credit)
-
- Immunity to syntax coloring (extra credit)
-
This is completely immune to syntax coloring
- Universality (not platform specific)
-
The code is relatively universal.
- Creativity and Cleverness
-
The entry was executed in a creative way, with several stylistic
tricks to conceal the bad behavior.
-
Natori Shin
-
- Difficulty / Sophistication
-
- Simplicity of Code
-
184 lines.
- Imperceptibility (of bad code, and results)
-
There is no evil code at all, for the underhanded part
is the lack of code. A filter matrix is uninitialized,
and ends up filled with info from a previous stat() call.
- Obscurity of attack
-
Relies on stat(), stack flotsam, and uninitialized memory.
- Amount of Information
-
Retrieving the information might be more difficult (although
if you can make a good guess at the stack flotsam, you might
be able to test for it using cepstral analysis.)
The image should still be slightly different every time,
which qualifies as a fingerprint.
- Robustness of mark (extra credit)
-
Since the recovered fingerprint is a strong hash of a simplified
version of the image, under compression this fingerprint will
be rendered unusable. However, I suspect that this is not
the only useful way to do this.
- Immunity to syntax coloring (extra credit)
-
This is completely immune to syntax coloring.
- Universality (not platform specific)
-
Relatively universal. It relies on fairly universal assumptions
of stack organization.
- Creativity and Cleverness
-
Hiding fingerprint data in a convolution matrix is a clever idea.
It is an interesting question how this data can be optimally
extracted--and what data could be dropped on the stack to
increase fingerprint robustness.
-
M Joonas Pihlaja and
Paul V-Khuong
-
- Difficulty / Sophistication
-
This is the most sophisticated entry. Watermarking is performed
by assembly language code smuggled into filter tap data.
- Simplicity of Code
-
This is a very large application, with numerous hiding places
- Imperceptibility (of bad code, and results)
-
The malicious C code is a static overrun. The rest is buried
in data, and is well hidden.
This submission raises two issues in judging. First,
if executable code is smuggled in an arbitrary data block, is
that genuinely innocent-looking? Second, can the code be
plausibly denied if caught? Someone debugging the code may
see some clear evidence of malicious behavior--whereas data
leaked in an uninitialized variable can be dismissed as a
programmer error.
- Obscurity of attack
-
Running code hidden in a data vector is pretty sneaky.
- Amount of Information
-
The code embeds IP information, owing to the approach that lets
the attackers embed whatever they want without raising suspicion
in the code.
- Robustness of mark (extra credit)
-
The mark is attached to a second watermark, the one that the
program really embeds. With a robust watermarking scheme,
this can be made as robust as one wants.
- Immunity to syntax coloring (extra credit)
-
This is completely immune to syntax coloring.
- Universality (not platform specific)
-
This code is definitely processor-dependent.
- Creativity and Cleverness
-
This is a very clever solution.
-
Tom Burns
-
- Difficulty / Sophistication
-
The program performs some pretty heavy pointer shuffling,
to drop data into the BMP file.
It hides assembly code in the constants, which I missed at first.
- Simplicity of Code
-
The code is short, although the image processing code
is pretty strange.
- Imperceptibility (of bad code, and results)
-
A single equal instead of a double equal, causes pointer
munging. The code around it is unusual, and not
very innocent-looking.
- Obscurity of attack
Uses pointer munging to lay text in a BMP file.
-
- Amount of Information
-
Like other entries, this technique can be used to lay
stack detritus in a file.
- Robustness of mark (extra credit)
-
Not robust.
- Immunity to syntax coloring (extra credit)
-
Depends on the syntax coloring.
- Universality (not platform specific)
-
The code has certain specific requirements to work.
Must run on an x86 running Linux with libsdl installed.
- Creativity and Cleverness
-
The pointer shuffling is unusual. Embedding code in
constants was apparently clever enough to fool me.
-
Uwe Hermann and Daniel Reutter
-
- Difficulty / Sophistication
-
This is a very simple submission.
- Simplicity of Code
-
Very short and simple program. To hide bad behavior in such a
small program deserves extra points.
- Imperceptibility (of bad code, and results)
-
The bad code is an array bounds overrun, with an extra equals sign.
- Obscurity of attack
-
The program simply writes the program start time into an ASCII PPM
header
- Amount of Information
-
Time is embedded, and easily extracted.
- Robustness of mark (extra credit)
-
This mark is not very robust, although given a marked image
we can at least estimate its creation times after compression.
- Immunity to syntax coloring (extra credit)
-
This is immune to syntax coloring.
- Universality (not platform specific)
-
This isn't very platform specific
- Creativity and Cleverness
-
The solution is straightforward, but impressive in its simplicity.