Sunday, February 22, 2015

Java Malware: Java Decompilers for JAR Malware Analysis

Krakatau comes with three tools, an assembler, disassembler and a decompiler.
From the author of Krakatau, Robert Grosse
        " The Krakatau decompiler takes a different approach to most Java decompilers.
         It can be thought of more as a compiler whose input language is Java bytecode
         and whose target language happens to be Java source code. Krakatau takes in
         arbitrary bytecode, and attempts to transform it to equivalent Java code. This
         makes it robust to minor obfuscation, though it has the drawback of not
         reconstructing the "original" source, leading to less readable output than a
         pattern matching decompiler would produce for unobfuscated Java classes." 

decompile.py can extract class files from a .jar file and decompiles the extracted .class file to Java code (.java). Below command decompiles .class file to .java file and places the file in praveendecompile directory.
$ python decompile.py -path . hello.class -out praveendecompile/

Dissecting the command
$ python decompile.py -out temp_praveen/ 2f8d204b747ed971a8bc8927b2e0898c.jar
-out        output directory
-path      path to core language classes, directories etc
-skip      continue upon errors

$ python decompile.py -out temp_praveen/ 2f8d204b747ed971a8bc8927b2e0898c.jar
Krakatau  Copyright (C) 2012-14  Robert Grosse
This program is provided as open source under the GNU General Public License.
See LICENSE.TXT for more details.
Attempting to automatically locate the standard library...
Found at  /usr/lib/jvm/java-1.7.0-openjdk-i386/jre/lib/rt.jar
processing target plugins/Server, 2 remaining
Loading plugins/Server
Loading java/lang/Object
Loading java/lang/Throwable
Loading java/io/Serializable
Loading java/lang/IllegalMonitorStateException
Loading java/lang/RuntimeException
Loading java/lang/Exception
Decompiling method ()V
Decompiling method onLine ()V
Decompiling method offLine ()V
Decompiling method getId ()Ljava/lang/String;
Class written to /home/praveend/javadecompilers/Krakatau/temp_praveen/plugins/Server.java
0.369355201721  seconds elapsed
processing target Main, 1 remaining
Loading Main
Loading java/lang/ClassLoader
Loading java/io/InputStream
Loading java/io/Closeable
Loading java/lang/AutoCloseable
Loading java/io/ByteArrayInputStream
Loading java/io/PrintStream
Loading java/io/FilterOutputStream
Loading java/io/OutputStream
Loading java/io/Flushable
Loading java/lang/Appendable
Loading java/lang/String
Loading java/lang/Comparable
Loading java/lang/CharSequence
Loading java/util/jar/JarInputStream
Loading java/util/zip/ZipInputStream
Loading java/util/zip/InflaterInputStream
Loading java/io/FilterInputStream
Loading java/util/zip/ZipConstants
Loading java/lang/OutOfMemoryError
Loading java/lang/VirtualMachineError
Loading java/lang/Error
Decompiling method iiIiiiiiii ([BLjava/lang/String;)Ljava/util/jar/JarInputStream;
Loading java/util/HashMap
Loading java/util/AbstractMap
Loading java/util/Map
Loading java/lang/Cloneable
Loading java/lang/ClassCastException
Loading java/lang/NullPointerException
Decompiling method getResourceAsStream (Ljava/lang/String;)Ljava/io/InputStream;
Loading java/util/jar/JarEntry
Loading java/util/zip/ZipEntry
Decompiling method ALLATORIxDEMOxapqldkjnfkqieurqoewqeqwdasdascasdasd (Ljava/util/jar/JarEntry;)Ljava/lang/String;
Loading java/lang/ClassNotFoundException
Loading java/lang/ReflectiveOperationException
Loading java/lang/Class
Loading java/lang/reflect/GenericDeclaration
Loading java/lang/reflect/Type
Loading java/lang/reflect/AnnotatedElement
Decompiling method findClass (Ljava/lang/String;)Ljava/lang/Class;
Decompiling method iiIiiiiiii (Ljava/util/jar/JarInputStream;)V
Loading java/io/ByteArrayOutputStream
Decompiling method
()V
Decompiling method ALLATORIxDEMOxapqldkjnfkqieurqoewqeqwdasdascasdasd (Ljava/util/jar/JarInputStream;)Ljava/util/jar/JarEntry;
Decompiling method iiIiiiiiii ()V
Loading java/lang/StackTraceElement
Loading java/lang/StringBuffer
Loading java/lang/AbstractStringBuilder
Loading java/lang/ArrayIndexOutOfBoundsException
Loading java/lang/IndexOutOfBoundsException
Loading java/lang/NegativeArraySizeException
Decompiling method ALLATORIxDEMOxapqldkjnfkqieurqoewqeqwdasdascasdasd (Ljava/lang/String;)Ljava/lang/String;
Loading java/lang/reflect/Method
Loading java/lang/reflect/AccessibleObject
Loading java/lang/reflect/Member
Decompiling method main ([Ljava/lang/String;)V
Decompiling method ALLATORIxDEMOxapqldkjnfkqieurqoewqeqwdasdascasdasd (Ljava/lang/String;[B)Ljava/lang/Class;
Decompiling method ALLATORIxDEMOxapqldkjnfkqieurqoewqeqwdasdascasdasd ()Ljava/io/InputStream;
Loading java/io/Reader
Loading java/lang/Readable
Loading java/io/InputStreamReader
Loading java/io/BufferedReader
Decompiling method ALLATORIxDEMOxapqldkjnfkqieurqoewqeqwdasdascasdasd (Ljava/io/InputStream;)Ljava/lang/String;
Decompiling method ALLATORIxDEMOxapqldkjnfkqieurqoewqeqwdasdascasdasd (Ljava/io/ByteArrayOutputStream;)[B
Decompiling method loadClass (Ljava/lang/String;)Ljava/lang/Class;
Loading java/lang/StringBuilder
Decompiling method ALLATORIxDEMOxapqldkjnfkqieurqoewqeqwdasdascasdasd ([BLjava/lang/String;)[B
Class written to /home/praveend/javadecompilers/Krakatau/temp_praveen/Main.java
15.0299580097  seconds elapsed

*********************************************************

Highlighted the importand parts of the decompilation

Above decompilation creates couple of files under temp_praveen directory
praveend@praveend-VirtualBox:~/javadecompilers/Krakatau/temp_praveen$
$ ls -R
Main.java  plugins
./plugins:
Server.java

Rename 2f8d204b747ed971a8bc8927b2e0898c.jar to 2f8d204b747ed971a8bc8927b2e0898c.zip and unzip the zip file (unzip on .jar file might work, did not try though)
praveend@praveend-VirtualBox:~/javadecompilers/Krakatau$
$ unzip 2f8d204b747ed971a8bc8927b2e0898c.zip 
Archive:  2f8d204b747ed971a8bc8927b2e0898c.zip
  inflating: META-INF/MANIFEST.MF    
  inflating: MANIFEST.MF             
  inflating: ID                      
  inflating: plugins/Server.class    
  inflating: Main.class              
praveend@praveend-VirtualBox:~/javadecompilers/Krakatau$

disassemble.py takes class or jar file as input and converts it to assembly language format and the output can be reassembled. The ouput is saved into .j file. If jar file is input it disassembles all the class files part of jar into .j files.
python disassemble.py Main.class

$ python ../disassemble.py Main.class 
processing target Main.class, 1/1 remaining
Class written to /home/praveend/javadecompilers/Krakatau/unzipped_malware/Main.j
0.280933856964  seconds elapsed

javap binary is included with the JDK installation. javap can be used to see the bytecode of a class
$javap -c Main.class 

assemble.py is used to convert byte code(.j) to class file. JVM class file format
python assemble.py Main.j

$ python ../../assemble.py Server.j
Processing file Server.j, 1/1 remaining
Class written to /home/praveend/javadecompilers/Krakatau/unzipped_malware/plugins/Server.class

Java malware might use different obfuscation techniques to make it difficult for Malware Analyst and detection devices.Errors encountered while decompilation might need to be fixed manually.

http://research.zscaler.com/2013/08/malicious-jar-files-hosted-on-google.html
http://stackoverflow.com/questions/27340147/how-to-decompile-class-and-jar-file-using-storyyeller-krakatau
https://github.com/Storyyeller/Krakatau/blob/master/README.TXT
https://raw.githubusercontent.com/Storyyeller/Krakatau/master/Documentation/assembler.txt