usefulfor.com/security security dojo

26Oct/090

Java Bytecode Injection

When assessing the security posture of a Java thick application we can usually process the code through a decompiler (such as Jad) and have a proper look at the code. It may be the case that we need to bypass the SSL checks but that is usually it.

However, every now and then, we stumble upon more complex scenarios, for instance, an application whose code has been obfuscated causing decompilation errors. In that case it will no longer be enough to decompile, modify the code and compile again, we would need some other technique. Patching the .class file at the bytecode level sounds like a reasonable approach.

Imagine that the class below (Protected) represents the original class we are dealing with. Remember that we would not have access to this code, instead, we would have been given a compiled an obfuscated version of it (different method names, class names and variable names). Also imagine that the class is substantially more complex and has a number of obscure routines that break the decompilation process.

import java.util.Random;
 
class Protected
{
 
  public static boolean checkPassword(String password)
  {
    return String.valueOf( new Random().nextInt() ).equals(password);
  }
 
  public static void main(String[] argv)
  {
    if (argv.length != 1)
    {
      System.err.println(&quote;Please provide a password.&quote;);
      return;
    }
 
    if ( checkPassword(argv[0]) )
    {
      System.out.println("Success");
    }
    else
    {
      System.out.println("Failure");
    }
  }
}

When compiled (javac Protected.java) and run, the result would be as follows:

$ java Protected p4ssword
Failure

In the obfuscated code scenario you would need to use debugging techniques to identify the relevant code (checkout JSwat for this). So, after hours of going through the decompiled obfuscated code, we have managed to identify that Protected is the class and checkPassword() is the method we want to focus our attention on.

In order to inject at the bytecode level we are going to use Javassist, the Java Programming Assistant. From their website:

[...] it enables Java programs to define a new class at runtime and to modify a class file when the JVM loads it.

Which is exactly what we want to do :) So here is how you would bypass the checkPassword method by manipulating the bytecode of the class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import javassist.*;
 
class Injector
{
 
  public static void main(String[] argv) throws Exception
  {
    // Load the 'Protected' class representation
    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("Protected");
 
    // Find the method we want to patch and rename it 
    // (we will be creating a new method with the original name).
    CtMethod m_old = cc.getDeclaredMethod("checkPassword");
    m_old.setName( "checkPassword$impl" );
 
    // Create a new method with the same name as the old one
    CtMethod m_new = CtNewMethod.copy(m_old, "checkPassword", cc, null);
 
    // Provide the new method's implementation
    StringBuilder sb = new StringBuilder();
    sb.append( "{ return true; }" );
    m_new.setBody( sb.toString() );
 
    // Add the new method to the class. Patch the .class file
    cc.addMethod( m_new );
    cc.writeFile();
 
    System.out.println("Injection  complete. List of methods:");
    CtMethod[] methods = cc.getDeclaredMethods();
    for( int i=0; i<methods.length ; i++)
    {
      System.out.println( "\t" + methods[i].getLongName() );
    }
  }
}

When run, the Injector application will patch the Protected.class file with a new implementation of the checkPassword() method.

$ javac -cp .:javassist.jar Injector.java
$ java -cp .:javaassist.jar Injector
Injection complete. Methods in class Protected:
    Protected.checkPassword$impl(java.lang.String)
    Protected.main(java.lang.String[])
    Protected.checkPassword(java.lang.String)
$ java Protected p4ssword
Success

This is just a simple example of what can be accomplished with a framework such as Javassist. Check the References section below for additional information.

References

Popularity: 2% [?]

Share and Enjoy:
  • Digg
  • del.icio.us
  • Slashdot
  • Technorati
  • Meneame
  • Twitter
Tagged as: Leave a comment
Comments (0) Trackbacks (0)

No comments yet.


Leave a comment


No trackbacks yet.

Popular Posts

Categories

Archive