Wednesday, October 8, 2014

Vol-MsDecompress


Malware I've ran across in the past used LZNT1 compression to help hide/pack itself in memory.  To help defeat this I've created Vol-MsDecompress.  Vol-MsDecompress is a plugin to help forensics investigators recover compressed data in memory.  Currently Vol-MsDecompress supports the lznt1 decompression algorithm, however Xpress and Xpress + huffman will be added soon.  Vol-MsDecompress uses a slightly modified version of ms-compress.  The modified version exports the lznt1_decompress_chunk function which Vol-MsDecompress uses to precisely decompress data.



[Vol-MsDecompress Repository]

A basic build environment is required for building Vol-MsDecompress.  (OSX: xcode, Linux: build-essential, Win: MS Visual Studio)

Install (OSX/Linux): 
1) Download ms-voldecompress.zip  from the repository
2) Unzip the the file $ unzip ms-voldecompress.zip 
3) Build it 

$ ./build.sh (build.bat for windows)
Compiling dynamic shared library...
In file included from lzx.cpp:22:0:
etc..

4) Check for the lib and its exports 
$ ls -l libMSCompression.so 
-rwxrwxr-x 1 ff ff 113000 Sep 30 22:25 libMSCompression.so

$ nm -D libMSCompression.so  | grep -i decompress
00000000000025d0 T decompress
0000000000003450 T lznt1_decompress
0000000000003080 T lznt1_decompress_chunk
0000000000006540 T lzx_cab_decompress
0000000000006010 T lzx_wim_decompress
0000000000011be0 T xpress_decompress
0000000000012d70 T xpress_huff_decompress

Copy libMSCompression.so to another location or just call it from its current location (next step will demonstrate)

5) Copy the msdecompress.py plugin to vols plugin directory

6) Example usage: 
python vol.py msdecompress -f ../zeus.vmem -D out4 -P ~/projects/mchammer/libMSCompression.so -A lznt1 -C -M 5

Options: 
-P path to the LibMScompress file 
-A algorithm to use [lznt1 for now] 
-C Dump the compress data along with the decompress data blocks (useful for comparing compressed and decompressed bytes) 
-M Specify the minimum compressed data size to decompress in bytes (default is 20 bytes)

Sample Output 
Decompresing data for PID: 4, Process: System, Page: 0x81008000, Offset: 0x0
Decompresing data for PID: 4, Process: System, Page: 0x81009000, Offset: 0x4dc
Decompresing data for PID: 4, Process: System, Page: 0x8100a000, Offset: 0x1fd
Decompresing data for PID: 4, Process: System, Page: 0x8100b000, Offset: 0x49e
Decompresing data for PID: 4, Process: System, Page: 0x8100c000, Offset: 0x702
Decompresing data for PID: 4, Process: System, Page: 0x8100d000, Offset: 0x528
Decompresing data for PID: 4, Process: System, Page: 0x8100e000, Offset: 0x321
Decompresing data for PID: 4, Process: System, Page: 0x81011000, Offset: 0x36c
Decompresing data for PID: 4, Process: System, Page: 0x81013000, Offset: 0x1b3

About 225 compressed steams were recovered using LZNT1 for the Zeus.vmem sample.  The decompressed data recovered by the plugin can be found in the msdecompress_zeus.zip

Examining the compressed and decompressed data found in memory.  

Please be sure to download the msdecompress_zeus.zip file to follow the brief example below.

$ hexdump -C 4_System_0x81008000_0x0_lznt1__CompressedBuffer.bin 



$ hexdump -C 4_System_0x81008000_0x0_lznt1__UncompressedBuffer.bin

Conclusion:

A lot of compressed data exists in windows memory.  This plugin is my first basic attempt for helping others to analyze compressed data in memory (without using a debugger to monitor allocated buffers or seeing the return data from RtlDecompressBuffer).  Vol-MsDecompress was able to properly carve and decompress compressed data with much more accuracy than the Lazy_NT python module.  No other framework or platform that I know of currently supports the extraction of LZNT1 compressed data from memory.  As noted above Xpress and Xpress + huffman will be added eventually.  A standalone carver will be released as well along with native python versions of the ms-compression algorithms.  Many many thanks to Jeffrey Bush of http://coderforlife.com/ who's code Vol-MsDecompress uses.  

Notes: 

Visualizing LZNT1 Decompression:  

I am very visual so I found an easy solution to replace pin and paper in figuring out how the LZNT1 decompression process works.  The below visualization helped me enormously and I will be using this process from here on out.  It was created using XMIND.  Ultimately the lznt1_uncompressed_size and lznt1_decompress_chunk functions were used to deduce if data was legitimately decompressed by the plugin.  The below visualization did serve as an excellent example for understanding complex code for the future.


lznt1 carving process visualization




"The greater the artist, the greater the doubt. Perfect confidence is granted to the less talented as a consolation prize". 

No comments:

Post a Comment