Thursday, 18 October 2012

Java Instrumentation Agent

We previously blogged about the power of JavaSnoop when performing application security assessments. This tool is especially useful when auditing Java clients that are obfuscated and the usual testing methods (de-compiling, editing the code and then re-compiling) are not an option. JavaSnoop allows you to intercept the Java method calls at runtime and alter the parameters and return value. In situations when you are unsure what methods you actually need to intercept JavaSnoop provides a "canary mode" which tracks a value through the work flow of the application showing all methods that were called that took this value as a parameter. Imagine a FIX trading application that is highly obfuscated and you are unsure which method places the trade in the queue. JavaSnoop canary mode can track the stock name for example, highlighting methods that need further inspection. In some situations methods you need to intercept either do not parameters, or the parameter may be in a form that you do not know about as an attacker - the stock name string may be embedded deep within an object or converted to some other form. In this edge case it is important for the security tester to see all methods called when a button is pressed which they can then inspect or pass through to JavaSnoop to do the heavy intercepting which it is so good at.

To solve this problem we have created a Java Runtime Agent that injects into the JVM of the target process and performs bytecode modification of the class to do a System.out.println each time a method is called. In a number of tests performed recently this has provided a fast and efficient way of targeting useful functionality which we then intercept using JavaSnoop to obtain the desired results.

Java agents can either be launched from the command line using the "javaagent" option:

java -javaagent:agent.jar Application.jar

Or injected at runtime using the Attach API (see previous blog post).

We have created a generic JVM injector that lists all available Java processes and allows the user to inject the agent at runtime.

Fixulate Injector

This generic injector can be reused for other example projects, it is the actual agent that does the bytecode modification and that can be specified from within the GUI.

The agent itself is made up of 3 classes, the AgentMain which contains the premain method as specified within the manifest file, an AgentForm which provides a GUI after being injected into the target process, and finally the transformation class which uses the ASM library to perform the bytecode modification to each method that is called.

After attaching (using the Injector GUI above) the AgentMain GUI is presented to the user - at this point yo are running within the target process and can kill the Injector GUI as it is no longer needed. Although the agent has been injected, the transformation is not yet active and needs to be started using the "Activate" button. We also provide a list of classes that can be edited within the GUI that are to be blacklisted by the transformation agent, this is to reduce noise and allow the tester to focus on classes that are likely to be of interest. For example we do not want to transform javax.swing classes and be flooded with notification of their method calls.

Fixulate Runtime Agent
Once activated the transformation modifies the classes and inserts a print statement that notifies the tester when a method is called. Using this information you can quickly determine what classes and methods are responsible for functionality performed as a result fo GUI actions and then use JavaSnoop to continue your testing.

Console output showing blacklisted classes and then obfuscated method calls

We will be uploading the Fixulate Injector and Runtime Agent to the resources section very soon.





No comments:

Post a Comment