Saturday 24 September 2011

JNLP Application Security Assessment - Part 3 : Application decomposition / Static analysis

Hello All,

Now, off to Part 3 of the series.

At this point, we have downloaded and extracted all the required jars from the remote site and we have the required command for launching the application.  No it is time to decompile the class files and see how they look like from a source code perspective. At this point we will also identify any client side application protections that have been applied to the application itself such as code obfuscation. Code obfuscation is usually incorporated in an application as an intellectual property rights protection mechanism - to prevent the source code from disclosure. However it can moonlight as a protection scheme, albeit basic, against static analysis in order to make the analysts job a bit more difficult.

For java code decompilation two tools stand out, jad and java decompiler, that can be downloaded from the below locations respectively.

http://www.varaneckas.com/jad

http://java.decompiler.free.fr/

Java decompiler is an actively maintained tool that comes in three main flavors, a library that can be used as a reference to projects, a standalone decompiler and an eclipse plugin. It can work on jar files and can output the corresponding source code of a jar file in a corresponding zip archive. The screenshot below shows java decompiler in action against our two jar files, gui.jar & logic.jar.







Jad is a bit outdated but contains a few useful features such as batch decompilation of class files in a directory structure, usage of fully qualified class names and the ability to generate java bytecode as comments to the produced .java source files. Jad's help is shown below.
C:\analysis>..\jad158g.win\jad.exe

Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov (jad@kpdus.com).
Usage: jad [option(s)] <filename(s)>
Options: -a - generate JVM instructions as comments (annotate)
-af - output fully qualified names when annotating
-b - generate redundant braces (braces)
-clear - clear all prefixes, including the default ones
-d <dir> - directory for output files
-dead - try to decompile dead parts of code (if there are any)
-dis - disassembler only (disassembler)
-f - generate fully qualified names (fullnames)
-ff - output fields before methods (fieldsfirst)
-i - print default initializers for fields (definits)
-l<num> - split strings into pieces of max <num> chars (splitstr)
-lnc - output original line numbers as comments (lnc)
-lradix<num>- display long integers using the specified radix
-nl - split strings on newline characters (splitstr)
-noconv - don't convert Java identifiers into valid ones (noconv)
-nocast - don't generate auxiliary casts
-noclass - don't convert .class operators
-nocode - don't generate the source code for methods
-noctor - suppress the empty constructors
-nodos - turn off check for class files written in DOS mode
-nofd - don't disambiguate fields with the same names (nofldis)
-noinner - turn off the support of inner classes
-nolvt - ignore Local Variable Table entries (nolvt)
-nonlb - don't insert a newline before opening brace (nonlb)
-o - overwrite output files without confirmation
-p - send all output to STDOUT (for piping)
-pa <pfx>- prefix for all packages in generated source files
-pc <pfx>- prefix for classes with numerical names (default: _cls)
-pe <pfx>- prefix for unused exception names (default: _ex)
-pf <pfx>- prefix for fields with numerical names (default: _fld)
-pi<num> - pack imports into one line using .* (packimports)
-pl <pfx>- prefix for locals with numerical names (default: _lcl)
-pm <pfx>- prefix for methods with numerical names (default: _mth)
-pp <pfx>- prefix for method parms with numerical names (default:_prm)
-pv<num> - pack fields with the same types into one line (packfields)
-r - restore package directory structure
-radix<num>- display integers using the specified radix (8, 10, or 16)
-s <ext> - output file extension (default: .jad)
-safe - generate additional casts to disambiguate methods/fields
-space - output space between keyword (if, while, etc) and expression

-stat - show the total number of processed classes/methods/fields
-t<num> - use <num> spaces for indentation (default: 4)
-t - use tabs instead of spaces for indentation
-v - show method names while decompiling
-8 - convert Unicode strings into ANSI strings (ansi)
-& - redirect STDERR to STDOUT

The following snippet shows jad in action in parsing our two archives and generating the relevant source code.
C:\analysis>..\jad158g.win\jad.exe -d jadsrc -f -r -s .java .\**\*.class
Parsing .\com\jnlptest\Auth2Service.class... Generating jadsrc\com\jnlptest\Auth
2Service.java
Parsing .\com\jnlptest\JNLPFrame.class...Parsing inner class .\com\jnlptest\JNLP
Frame$1.class...Parsing inner class .\com\jnlptest\JNLPFrame$2.class...Parsing i
nner class .\com\jnlptest\JNLPFrame$3.class... Generating jadsrc\com\jnlptest\JN
LPFrame.java
Parsing .\com\jnlptest\TestJnlp.class... Generating jadsrc\com\jnlptest\TestJnlp
.java

C:\analysis>

So, now that we have generated the source code and have asserted that it is not in obfuscated form we can perform static analysis either manually or through the use an automated tool. Given the size and complexity (or lack thereof ) of our application not much can be shown at this point, however the procedure can be followed for any size application.

For illustration purposes we will use findbugs and pmd, two of the most well known open source java source code analysers on our generated source code.
Both of the aforementioned tools are general purpose source code analysers and although the have some capabilities regarding security oriented source code analysis they are not exactly there yet, at least in terms of taint and flow analysis. You can try OWASP for a few projects that can help in this direction, TeSA and LAPSE the most notable, or the CodePro Analytix from the Google Web Toolkit http://code.google.com/javadevtools/codepro/doc/features/audit/audit_details.html .

Findbugs and pmd can be downloaded respectively from the following locations.

In order to run findbugs the source code is not a strict prerequisite, however if the source code is provided it can aid the reviewer by indicating the exact source code responsible for each finding.

The two screenshots below show the output of both findbugs and pmd when run against our simple application.





Of course, not all things can be found via automatic scanning, either security or non-security oriented. There is a specific vulnerability that can be found in the sample application that I doubt any of the automated tools would be able to find out. Lets have a look.

[sourcecode lang="java"]
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
String un = usernameTxt.getText();
String pw = passwordTxt.getText();
if (authenticate(un , pw ))
{
buildGUI( un );
}
};
};
[/sourcecode]

This vulnerability exists in lines 49-58 of JNLPFrame.java and is the action listener attached to the Login button. It tries to authenticate the user and upon success builds the user interface according to the username (ultimately the attached role to that username). Of course since this is client side there are a few ways that we can intervene with it and this will be the focus of Part 4 of the series.

./Z

No comments:

Post a Comment

Note: only a member of this blog may post a comment.