"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 -

The Rube Goldberg Approach to Java Security

Copyright (c) 1998 Mark D. LaDue, Ph. D.

Contents

  1. Introduction
  2. More Maginot Licenses
  3. Sawing Logs
  4. Oh, Those Nasty Little Applets!
  5. Catching Sand with a Fishing Net
  6. Stopping Elephants with Twine
  7. Conclusions

1. Introduction

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

2. More Maginot Licenses

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

3. Sawing Logs

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:

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.

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

4. Oh, Those Nasty Little Applets!

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

5. Catching Sand with a Fishing Net

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

6. Stopping Elephants with Twine

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

7. Conclusions

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.

Contents