September 06, 2018
Dumping Embedded Java Classes
Written by
Scott Nusbaum
Application Security Assessment
Incident Response
Incident Response & Forensics
Penetration Testing
Security Testing & Analysis
A few months ago, I came across a piece of Java malware. This was a nice change of pace for me, since most of what I see is written in C/C++. The malware was heavily obfuscated using a common tool, Allatori v5.3. After working my way manually through decoding, I came to a point where a config.ini was being parsed and each class was loaded directly into memory prior to being executed. This intrigued me because up until this point I had .class files that I could use CFR to decompile. Not having worked with Java malware before, I was unsure of a good way to convert these in-memory classes back to the *.class file format. After some research, I came across a reference to Oracle’s ClassFileTransformer and VirtualMachine.attach(PID). Using these classes, I was able to dump to the memory resident classes to files. The following is a description of the process I took to accomplish this task.
Java Components:
Let start off with an explanation of the VirtualMachine.attach( Agent ) and the Agent Jar (Inherited from ClassFileTransformer in this case). The VirtualMachine.attach( Agent ) function allows us to attach to a Java Virtual Machine(JVM) running another application by its process ID. This feature is only available in the Oracle JVM and is similar to using gdb to attach to another running process. Unlike gdb, this is done programmatically, and a function is provided to process the values in the target JVM. Figure 1 shows the source for the Attacher program using the VirtualMachine attach and loadAgent methods. The loadAgent method is used to instruct the VirtualMachine which Agent Jar file to load into memory and execute.
[caption id="attachment_14849" align="aligncenter" width="974"] Figure 1 - Attacher.java[/caption]
The Agent Jar has two (2) components. The first is the manifest.mf file (see Figure 2). The manifest.mf file contains the name to two entry points into the Agent class. Premain-Class is the entry point for the Agent when the target is not already started. The Agent-Class is the entry point for when the target has already been is launched, as in this case.
[caption id="attachment_14850" align="aligncenter" width="974"] Figure 2 - manifest.mf Example[/caption]
The manifest.mf file contains two (2) other important lines. The Can-Redefine-Classes, which allows the Agent to change the definitions of existing or already loaded classes. The Can-Retransform-Classes is used prior to classes being loaded and can change the byte code prior to the class being initialized. In this case, I used the latter with a ClassFileTransformer. This allows the agent to transform the classes in memory to the *.class files. The Agent can be a simple program that has a single class containing a single method.
Detailed Code Walk-Through:
I used this transform to loop through all loaded classes in the JVM and write these classes to disk in the traditional <filename>.class format. To best use this feature, I modified the malware to loop after loading the values from the config.ini. I then executed the Attacher program and did a little happy dance, as I had the hidden class files. Convert to *.java files and have a nice easy time understanding the rest of the malware. J
This process contains three (3) components:
- Attacher Program (shown in Figure 1)
- Agent Jar file
- mf (shown in Figure 2)
- ClassDumperAgent (My term)
- Malware or VM to attach too