"RUBE GOLDBERG'S INVENTIONS have become synonymous with any maximum effort to achieve minimal results... demonstrating that the unnecessary can also be the mother of invention - often with hilarious results." - Rube Goldberg's Gallery -
Last year we examined Finjan Software's SurfinShield 2.0 for UNIX, and we reported numerous serious flaws in it. When Finjan retained an attorney in an abortive effort to suppress that report, we fought back. As a result, the report remains freely available. We recently downloaded and examined evaluation versions of Finjan's SurfinGate 2.0 (Revision 1.1), SurfinCheck (Revision 1.0), and SurfinShield 2.0 (Revision 1.1). We installed them on machines running Windows NT 4.0 (Service Pack 3). We used Netscape's Navigator 3.04 as our browser for SurfinShield 2.0 because this is the latest version of it supported by Finjan. We used both that and Netscape's Communicator 4.04 for SurfinGate 2.0 and SurfinCheck 1.0. In what follows we assume that the reader has all of these products installed and configured according to Finjan's directions. Unless we state otherwise, our observations about SurfinGate apply to SurfinCheck as well. Likewise, they apply to both versions of Netscape's browser when used in conjunction with those products. Our observations about SurfinShield apply to that tool used in conjunction with Navigator 3.04. We emphasize here that the problems that we report are in no way caused by Netscape's browsers. The reader so inclined is invited to test Finjan's products with the appropriate versions of Microsoft's Internet Explorer. It is highly likely that the results will be the same.
The following is a review of some of the problems suffered by Finjan Software's SurfinGate 2.0, SurfinCheck 1.0, and SurfinShield 2.0. In Section 2 we show that in the six months since learning of the problems, Finjan has not corrected obvious vulnerabilities in their software licensing scheme. In our previous terminology, SurfinGate, SurfinCheck, and SurfinShield all possess Maginot licenses. In Section 3 we point out assorted problems with SurfinGate's and SurfinCheck's installation and logging programs. We also examine some Rube Goldberg-style functionality in SurfinShield. In Section 4 we inspect Finjan's "suspicious applets" database that they provide with their tools. Far from being the "valuable suspect list" that Finjan advertises, we find that it contains URL's for harmless applets, non-existent URL's, and at least one typographical error. While these problems might seem so trivial as to be unworthy of serious attention, we believe that they are indicative of Finjan's lackadaisical attitude toward security - both their own and that of their clients.
In Section 5 we introduce HAMGen, our Hostile Applet Mutation Generator. We illustrate how it allows applets explicitly blocked by SurfinGate or SurfinCheck to pass unhindered. In Section 6 we give a general method of constructing applets which cannot be stopped by SurfinShield, and we illustrate this method with a concrete example. We add this example applet to SurfinGate's database of suspicious applets and instruct SurfinGate to block it. We then apply HAMGen to it to obtain an applet which SurfinGate fails to block and which SurfinShield then fails to stop. Thus we see how Finjan's tools offer unreliable defenses against even known applets residing at known URL's. Our observations and examples justify the conclusion that Finjan's products exemplify a Rube Goldberg approach to Java Security. One may be impressed by all of the gewgaws, doodads, and whim-whams on display, but in the end it would be wise not to rely on them for security.
Contents
In our review
of SurfinShield 2.0 for UNIX last year, we demonstrated the ease with which
a cracker can give SurfinShield a non-expiring demo license. Earlier this
year we analyzed
the folly of using Java applications to enforce licensing terms and
restrictions on software use, and we discussed this problem with SurfinShield
at length. We coined the term Maginot license to describe this
sort of folly. Unfortunately, in the six months since we first reported this
problem, Finjan has done little or nothing to correct it. Retaining an
attorney to make
false allegations against the author in a stillborn attempt to suppress
the publication of Finjan's folly hardly counts as corrective action.
Indeed, in the current (March 1998) versions of SurfinGate 2.0 and
SurfinShield 2.0 for Windows NT Finjan has made the cracker's task even easier.
When you install SurfinGate and SurfinShield, you have only to look in the
main SurfinGate and SurfinShield folders under the installation directories
to find SFped.class, a simple Java class file which contains the installation
date hard coded into it. The same method
that we previously reported works just as before to give the current versions
of SurfinGate and SurfinShield perpetual demo licenses.
Likewise, when you install the current (March 1998) version of
SurfinCheck 1.0 and look in the SurfinCheck folder under the installation
directory, once again you find the notorious SFped.class. Now a cursory
inspection of the product reveals that Finjan has applied standard
obfuscation techniques to their Java class files. But as we pointed out
previously
this form of security-through-obscurity is of little value. In the case
at hand the net result is that the ped field of SFped.class
has been renamed to 0xC69E, and nothing more. The installation date remains
hard coded into SFped.class. So with a modest effort, and perhaps a few
additional adjustments, a cracker could adapt the previous method to work
in this case. Alternatively, it takes only a few minutes to write a Java
program which adjusts the date in SFped.class
and thereby resets the license to expire in 30 days.
Thus it appears that in six months Finjan has done nothing to correct a
well-known vulnerability in SurfinGate and SurfinShield. While they did
attempt to do so in the more recently released SurfinCheck, that effort
fails. When we see Finjan's lack of skill and understanding in handling
the security of their own products, we can only wonder why we should entrust
our security to them. Obviously we do not recommend that anyone actually
use our programs to avoid paying for Finjan's products. Instead, we
recommend that you not use Finjan's products. Sound reasons for this
recommendation will become clear presently.
Contents
Several other observations add to our doubts about the design and effectiveness
of these Finjan products. First of all, we observed that during the
installation of both SurfinGate and SurfinCheck, when a database password
was required, the password that we typed was echoed to the screen, where it
could be observed by any interested person who happened to pass by. This is
a poor substitute for the standard commonsense practices of not echoing
passwords and requiring that they be typed twice for verification.
In the process of downloading test applets and looking at SurfinGate's
reports, we observed that it records the wrong times in each and every
report. For example, when we downloaded a mutated version of the well-known
NoisyBear applet at roughly 10:01 PM (CST) on March 17, 1998 and then
immediately reviewed SurfinGate's "New Applets Report," we found that the
time reported in the "Date and Time Entered" field was 3/18/98 4:01:54 AM,
exactly 6 hours later than the actual time. On further inspection, we
saw that the same held true of every applet in every report in which times
were recorded, including the "Blocked Applets Report" and the "Log Events
Report." Since we are on CST here, and since the reported times are always
6 hours later, we believe that SurfinGate is actually reporting GMT times.
By way of contradiction, the dialog boxes in which you select how and
when to print the reports always display the correct local time. Since
it would be natural to record events using local time, and since SurfinGate
gives no indication in the reports that it is doing otherwise, the
inescapable conclusion is that SurfinGate is in error - not a desirable
property of audit trails that should be able to withstand potential court
challanges.
We also observed that SurfinGate will silently truncate URL's that are
sufficiently long. For example, when we downloaded an applet having the
codebase URL:
SurfinShield also has its fair share of Goldbergian functionality. Consider,
for instance, the "SurfinShield Statistics" window. The "% Memory In Use"
display merely informs us of the percentage of memory that is being used
out of just the memory currently allocated to the Java Runtime.
No matter what sort of applets are running, it is likely to remain high,
and it tells us nothing about applet behavior. Harmless and hostile applets
yield similar numbers, and these numbers fail to reflect what is actually
happening on your machine, as can be seen by simultaneously watching
Finjan's display and the Windows NT Task Manager process statistics.
Thus SurfinShield's display is telling us nothing about any
denial-of-service attacks that may be occurring, and it certainly contributes
nothing to stopping them. To do so effectively, you would have to go outside
of the Java Runtime and the browser. Moreover, the availability of watch,
stopwatch, and graph displays in addition to a digital display qualifies as
"maximum effort to achieve minimal results... demonstrating that the
unnecessary can also be the mother of invention...." Rube Goldberg would
surely have been pleased.
Contents
In our report
on SurfinShield last year, we pointed out the presence of a perfectly benign
applet, Sun's Hangman, in Finjan's list of "suspicious applets." Sun's
friendly little Hangman served to demonstrate some obvious flaws in
SurfinShield, none of which have been fixed. While this particular applet
has been removed from the databases supplied with the current versions of
SurfinGate, SurfinCheck, and SurfinShield, other equally harmless entries have
taken its place. Let us take a look at several examples.
The most telling example, which can be found in the databases of both
SurfinGate and SurfinShield, is the so-called "simpletext" applet.
This applet, whose codebase
URL is given by Finjan as http://www.j-g.com/java/simpletext/,
simply tries to open a connection back to its home and retrieve some text
to display for you. If you think that something evil could be happening
behind the scenes, you can read its
source code, and you can capture its
class file to see for yourself. Note that due to an
error in the "filename" parameter in its applet tag (an extra "simpletext/"
in its value) the applet does not even work correctly. In any case, the
fact that this applet appears at all in Finjan's databases raises serious
questions about the quality of their products. If there were some bona fide
reason to classify this applet as suspicious, then tens of thousands of other
applets should also be so classified, and Finjan should supply its customers
with more than the mere 32 applets found in SurfinGate's initial database.
But this applet is in fact friendly, and we have here another choice example
of a Finjan foible.
A second sparkling example is the so-called
"Telescrivente" applet,
whose codebase URL is given by Finjan as
http://www.jars.com/public-storage/teletext/. This friendly
little applet types some text in your browser and plays the sound of text
being typed by a typewriter. No covert hostile activity takes place, as you
can readily verify by capturing its
class file and inspecting it more closely. The only activity that might
be deemed offensive is that the applet's text requests that you send its
author $10 if you wish to use his applet on your web page. While such an
applet might be an example of bad programming (you do have to wait a while for
its audio to stop) or bad taste, it most certainly is not hostile. Again,
if this applet should be classified as suspicious, then so should thousands
of others on the Web.
For yet another example, consider the threatening "javaCounter" applet, for
which Finjan lists http://www.netobjective.com/java/classes/ as
its codebase URL in its SurfinGate database. When we
visited, we found it running as the second of three such applets, but
no attack materialized. Just to be sure, we captured its classes and
disassembled them, but we found no signs of overt or covert hostile
activity. Once again we are left to wonder how the applet found its way
into Finjan's database.
The SurfinGate database also contains a number of non-existent URL's. Here
we find the codebase URL for the author's defunct Hostile Applets Home Page at
Georgia Tech. This, of course, has not been there for several months, and
it contained no working applets for most of its last year in existence.
For another example, consider the ominous sounding "Stelth2" applet, for
which SurfinGate's database lists
http://www.gameran.com/java/applet/Stelth/ as its codebase URL.
But where is www.gameran.com? Just down
the road from Camelot perhaps. There appears to be no such host anywhere
in the world. There is, however, the well-known
www.gamelan.com, but Gamelan is not a
very likely place to turn up hostile applets. We cordially invite our readers
to visit Gamelan, search the site, and see if they can locate the notorious
Stelth2 applet.
What are we to make of such entries in a database so critical to the proper
functioning of Finjan's products? We are certainly led to wonder whether
or not the folks at Finjan have a clue as to how to dinstinguish a hostile
applet from a harmless one. We are led to wonder whether or not SurfinGate
can block the applets in its database, and we are led to wonder whether or
not SurfinShield is capable of stopping attacking applets. In the next two
sections we shall see that the answers to these last two queries are negative.
Contents
In our
previous report we observed that SurfinShield attempts to block applets
listed in its database upon the basis of their codebase URL's and that this
is a poor defense against hostile applets from parts unknown. Finjan's
SurfinGate and SurfinCheck add an additional twist. For each applet
a signature (i.e., a hash or message digest) is calculated, and applets in the
database seem to be recognized and blocked according to their codebase URL's
and signatures. But any effective message digest function is designed so
that slight changes to its input result in drastic changes to its output.
Consequently, we expect that SurfinGate and SurfinCheck will fail to recognize
and block applets derived from the same source code, but compiled with different
compilers (or even different versions of the same compiler) and downloaded from
different web sites. We also expect that we can slip blocked applets past
SurfinGate and SurfinCheck by deliberately inducing viable mutations in their
class files and shifting their codebase URL's.
To test these ideas, we wrote a simple tool which we call
HAMGen.java, a Hostile Applet Mutation Generator.
The operation of HAMGen is simple. Given a valid Java class file, HAMGen
inserts one of ten pseudo-randomly chosen sequences of code into each method
of that class file. The output is another valid class file which will pass
inspection by the Java Verifier and run just as before. Even such a simple
scheme is capable of generating a large number of mutations for a single
class file. For example, an applet with 5 methods (init(), start(), stop(),
run() and a contructor, say) could have 10^5 = 100,000 distinct mutations
induced by HAMGen. Needless to say, a more sophisticated tool, one which
generates many orders of magnitude more mutations, could easily be written
and could be made to generate mutations which would be all but impossible
to weed out, but this simple example will suffice to make a point. As we
mentioned before, we expect that each mutation of an applet listed as
blocked in SurfinGate's database will go unrecognized and pass straight
through SurfinGate when downloaded from a different URL.
As a simple test of our scheme, we took our well-known NoisyBear applet,
recompiled it with the latest version of Sun's Java compiler, and set it up
at a web site. The applet was always downloaded by pointing Communicator
4.04 at the same URL for NoisyBear.html. The applet's class file, audio,
and image were initially placed in a folder named "Test_1," the name of which
was included as the codebase in the applet tag. We used a
simple shell script to generate the
mutations of NoisyBear.class, rename the Test_1 folder, and adjust the
codebase in NoisyBear.html's applet tag. Although the NoisyBear applet is
included in the initial Finjan database and is listed blocked by SurfinGate,
when we downloaded the original recompiled NoisyBear, it sailed right
through SurfinGate, showing up as a new applet. So we instructed SurfinGate
to block the new version as well, we ran the mutation shell script, and
tried downloading the NoisyBear applet from the same web page once again.
Just as we predicted, the mutated applet passed through SurfinGate unhindered,
ran in our browser, and showed up in the logs as another new applet. We
ran the test repeatedly, being careful to clear the cache and exit the browser
between runs. We also visited Finjan's SurfinGate Test Page and ran their
test applets before we started, just to make sure that SurfinGate was
working as it was designed. As we had already predicted, SurfinGate always
failed to recognize the NoisyBear, which a
sample from the resulting
"New Applets Report" clearly shows. The test is quite easy to reproduce.
You can try out the original,
instruct SurfinGate to block it, and then try
out a mutation.
Note that in this static demonstration two distinct versions of NoisyBear.html
have been provided for convenience.
Now the folks at Finjan will surely argue that this is unfair and that any
mutation of the old NoisyBear is really a distinct applet. However, a
moment's thought reveals that this is simply an attempt to immunize themselves
from criticism over an obvious failure. Every mutation of the NoisyBear
was downloaded by pointing a browser at the same web page. Every mutation
of the NoisyBear contains the complete code of the original and functions just
as the original. Indeed, the code added to the NoisyBear to form mutations
will never be run by the browser and may or may not have been inspected by
the Java Verifier. And it is a simple matter for an adversary to serve
constantly mutated applets at will. The heart of the problem lies in the
fact that SurfinGate is entirely braindead when it comes to scanning Java
byte code. Finjan has built a failed Rube Goldberg machine to catch sand
with a fishing net - a few grains may be contrived to stick to the net, but
the bulk of the sand will flow through unimpeded. Those who wish to defend
SurfinGate are faced with the prospects of logging and blocking countless
billions of mutations of every potentially hostile applet.
Contents
The possibility remains that this may not be such a serious problem at all.
For it is at least conceivable that you could still rely on SurfinShield to
stop those applets which manage to escape SurfinGate's mighty net.
Unfortunately, it turns out that there is a simple method of constructing
applets that are virtually unstoppable, or at least extremely stubborn and
resistant to being stopped. All that one has to do is to run an applet in a
named thread, catch the ThreadDeath error, and then re-create the thread anew
in a finally block. We now disabuse the reader of the notion that
SurfinShield can handle such applets by considering a concrete example.
We constructed a simple applet,
HoseMokie.java, to illustrate yet another serious flaw in SurfinShield.
["Mokie" is, of course, the name of the Finjan mascot.] When the applet
starts, it announces its presence by beginning to play a familiar audio
clip in a loop, writing reminders to the Java Console, and popping up
pseudo-randomly placed little windows, with one window every 3.9 seconds
to keep time with the audio clip. When you try to kill the applet with
SurfinShield's "Kill Applet" or "Kill All Applets" buttons, you find that
the applet's behavior changes. It now reminds you of its continued presence
by popping up 100 little windows per cycle, and the title bar of these
new windows displays a different message. Also, the audio clip continues
to play, and reminders continue to be written to the Java Console. Alas,
if you bring up SurfinShield during a brief pause between cycles, you see
that SurfinShield erroneously reports that "no active applets" are present.
Of course seeing and hearing is believing, so you know better than that.
Once you have seen enough, you can stop the action by bringing up your
browser and exiting. You might just as well put SurfinShield out of its
misery too; obviously it is not doing what Finjan promised.
We tested the applet in two different ways. First we tested the applet
against SurfinShield alone. We started SurfinShield first, and then our
"protected" browser, Navigator 3.04 in this case. We then downloaded
the original applet. Once it had
started, we instructed SurfinShield to halt it by using the "Kill All
Applets" button. As outlined in the preceding discussion, SurfinShield
failed to kill the applet, though it reported that it did so.
Next we tested the applet against SurfinGate and SurfinShield combined.
In this test, with SurfinGate, SurfinConsole, and SurfinShield all running,
we first downloaded the original applet from the web page HoseMokie.html.
As before, after SurfinShield failed to halt the applet, we quit the browser.
Then we instructed SurfinGate to block the offending applet, HoseMokie.
(We could even instruct SurfinShield to refuse the original applet without
effecting the end result.) Next we ran
a mutation shell script to generate a
mutation of HoseMokie.class and make all of the other necessary adjustments.
We then started the browser once again, and, after clearing any trash in
the cache, we tried downloading HoseMokie from the same web page once again.
Just as we expected, SurfinGate failed to recognize the mutant HoseMokie,
as can be seen from a sample from the resulting
"New Applets Report," and then SurfinShield failed to stop it. Again,
this test is quite easily reproduced. You can try out
the original applet, instruct
SurfinGate to block it, and then try
out a mutation. We note once
again that in this static demonstration two distinct versions of
HoseMokie.html have been supplied for convenience.
Why does SurfinShield fail to stop HoseMokie? The reason would seem to
be that its creators lack the insight to properly stop threads in the browser's
Java Runtime. We shall leave it to the Finjan Technical Advisory Board to
enlighten them on the nature of the problem and potential solutions.
Finjan has built a Rube Goldberg machine to stop elephants with twine -
with enough twine and luck you might succeed in stopping a few, but most
will simply march right through. Though SurfinShield cannot stop a stubborn
applet, at least you can use its watch, stopwatch, graph, and digital
displays to monitor that applet as it consumes varying amounts of the
memory allocated to the Java Runtime. Rube Goldberg would be proud.
Contents
From our observations and examples we see that Finjan's SurfinGate,
SurfinCheck, and SurfinShield offer profoundly weak and inadequate solutions
to the problems of Java Security. While they might seem to work well
during contrived demonstrations, we have seen how they are easily defeated
by applets from parts unknown. Therefore we believe that it is a grave
mistake to rely on these tools for any aspect of security. It is far
better to remain aware of the risks of exectuable content and to be sure
to run the latest version of your browser than to let your guard down and
rely on third-party products for protection.
2. More Maginot Licenses
3. Sawing Logs
http://sparky/~mladue/Tests/LongURL/a1234567890/b1234567890/c1234567890/
d1234567890/e1234567890/f1234567890/g1234567890/h1234567890/i1234567890/
j1234567890/k1234567890/l1234567890/m1234567890/n1234567890/o1234567890/
p1234567890/q1234567890/r1234567890/s1234567890/t1234567890/u1234567890/
v1234567890/w1234567890/x1234567890/y1234567890/z1234567890/NoisyBear
that codebase URL shows up in the SurfinGate database and logs as:
http://sparky/~mladue/Tests/LongURL/a1234567890/b1234567890/c1234567890/
d1234567890/e1234567890/f1234567890/g1234567890/h1234567890/i1234567890/
j1234567890/k1234567890/l1234567890/m1234567890/n1234567890/o1234567890/
p1234567890/q1234567890/r1234567890/s12
While not too serious, such an oversight reveals yet another glitch in the
critical area of auditing and maintaining a correct database.
4. Oh, Those Nasty Little Applets!
5. Catching Sand with a Fishing Net
6. Stopping Elephants with Twine
7. Conclusions