by Michael 'mihi' Schierl, @mihi42
I won't go into detail here how you can make an applet call your toString method with full privileges – there are several ways to do so. If you don't know any, have a look at Sami Koivu's blog – he describes some of the ways in his articles about previous Java vulnerabilities he found.
On the other hand, when you build such an error object and try to call it from outside the script, you'll see a surprise:
The reason for this is simple: Rhino expects every script call to be run inside of a Context - basically an object that captures your local variables etc. This context is stored in a thread local variable to be available all the time when the script is executed. Since we called an "internal" method directly, there is no context assigned to the current thread any longer, so we get this error. Adding a context directly is hard since all the context related code is in sun.* packages which are not directly accessible from untrusted code.
So we have to examine the stack trace above more thoroughly to find a way to get our code executed without reaching the point where the context is not initialized. In fact, ExternalScriptable provides a better getDefaultValue implementation that will enter a context before calling the toString() method. A bit of digging in a debugger showed that the object that is bound to this inside the script is in fact of type ExternalScriptable, so you can reuse this object for the message property and don't have to find a way of instantiating a new one.
A script that exploits this vulnerability has to:
The applet has to use this script as follows:
The resulting exploit is quite short (about 20 lines of Java code and 120 characters of Rhino code), and I am sure you can make it shorter if you really try. However, I don't want to make it too easy for criminals to leverage this vulnerability just by copying and pasting; therefore I won't publish my exploit code in the near future. (Yes I'm aware that someone else will most likely build a Metasploit module from it, but then it was not my code that got ripped by the criminials...)