Background
With the proliferation of mobile applications, malware is becoming increasingly sophisticated and evasive. This report focuses on a malicious Android software sample submitted by ReBensk to incinerator.cloud.
-
Sample Hash Values:
- MD5: 2f371969faf2dc239206e81d00c579ff
- SHA-256: b3561bf581721c84fd92501e2d0886b284e8fa8e7dc193e41ab300a063dfe5f3
Among the malicious samples submitted to incinerator.cloud by ReBensk, we have a particular interest in a custom-modified APK file, referred to as "Sample b356." This sample employs unique obfuscation and steganography techniques that thwart the successful extraction of its contents using conventional decompression tools. Through targeted adjustments, we managed to overcome this limitation and conduct a more comprehensive analysis of the sample.
Analysis Process
Investigation of Decompression Failure
While attempting to decompress the APK file (essentially a ZIP file) using the 7z tool, an error surfaced displaying an AndroidManifest.xml header error. This points to the standard decompression process failing to properly extract the contents of Sample b356.
After opening the APK file with 010 Editor and applying the ZipAdv template to parse it, no obvious errors or exceptions were found.
To get a deeper understanding of the problem, we opened a functioning APK file for comparative analysis. This was done to determine if there was some kind of special or irregular structure or data that could be the cause of the decompression failure.
A comparison shows that Sample b356 uses an illegal compression algorithm 0x23C2
. In the standard ZIP format specification, the compression method is indicated by a short integer (short), typically adopting values as shown below (the following code is taken from the ZIPdecompression tools like 7z cannot identify or process it.
//enum used for compression format
typedef enum <short> {
COMP_STORED = 0,
COMP_SHRUNK = 1,
COMP_REDUCED1 = 2,
COMP_REDUCED2 = 3,
COMP_REDUCED3 = 4,
COMP_REDUCED4 = 5,
COMP_IMPLODED = 6,
COMP_TOKEN = 7,
COMP_DEFLATE = 8, // Deflate - standard ZIP codec, used from the start, also found in regular ZIP files
COMP_DEFLATE64 = 9,
COMP_PKImploding = 10,
COMP_BZip2 = 12, // BZIP2 - Newer than deflate, with better compression and slightly slower speed.
COMP_LZMA = 14, // LZMA - advanced ZIPX codec, taken from open source 7-zip format
COMP_Terse = 18,
COMP_Lz77 = 19,
COMP_Jpeg = 0x60, // Jpeg - Codec added by WinZip for specific support of jpeg images ( http://www.winzip.com/wz_jpg_comp.pdf )
COMP_WavPack = 0x61, // WavPack - Codec for compressing specifically wav files. ( http://www.wavpack.com )
COMP_PPMd = 0x62, // PPMd - context modeling based codec, also featured in new ZIP standard. We use it in our Optimized method for text file compression. ( http://www.compression.ru/ds/ )
COMP_WzAES = 0x63 // WZAES encryption methods
} COMPTYPE;
Consequently, Sample b356 employs an unidentified compression algorithm, impeding successful decompression using general-purpose tools. However, how can it still install and run effectively on the Android system?
Factors Enabling Successful Parsing and Execution on the Android System
As depicted in the illustration below, according to the Android system's source code, when confronted with a compression algorithm other than COMP_DEFLATE
, it resorts to handling the input file through the COMP_STORED
method. In detail, the system directly gauges the length of the uncompressed data and subsequently processes it.
Pay close attention to the code comparison within the yellow and red boxes. In the yellow box, if the COMP_DEFLATE compression algorithm is employed, the system decompresses correspondingly. If not, the system directly reads the pre-compression length and processes it.
This elucidates why the system continues to function accurately even after modifying the compression method in AndroidManifest. Sample b356 swaps the package's AndroidManifest.xml content with the pre-compression content and replaces the compression algorithm with something other than COMP_DEFLATE following the completion of the standard packaging process. Consequently, conventional decompression tools falter, but the Android system interprets it as uncompressed, facilitating normal operation.
Recommendations for Enhancing the Decompression Program
Rectifying the APK
In line with the Android system's approach, the AndroidManifest.xml within the Apk can only undergo two compression methods: COMP_DEFLATE
or COMP_STORED
.
If the compression algorithm is not the default COMP_DEFLATE, then it must be uncompressed, so the way to fix the apk is that if you find that the compression algorithm is not COMP_DEFLATE, then set the compression algorithm to 0, i.e. uncompressed, and at the same time, set the compressed length to the length before compression. This way regular decompression tools can decompress it.
After the fix, we tried to decompress it using the 7-Zip (usually shortened to 7z) tool and the results are shown below. Although there are still errors, especially regarding the CRC (Cyclic Redundancy Check) value which has not been fixed, we have successfully extracted the APK file and can access the AndroidManifest.xml content in it.
Static Analysis Tool Enhancement
The static analysis tool can follow the system's decompression method, if it finds that the compression method of AndroidManifest.xml is not COMP_DEFLATE, then it reads the length before compression as the content of AndroidManifest.xml.
Conclusion
As Android system processes non-COMP_DEFLATE compression methods through uncompressed handling during parsing, this approach, from a logical perspective, diverges from specifications. Consequently, b356 effectively exploits this logical vulnerability. An exhaustive solution would necessitate the Android system adhering to the standardized ZIP package decompression format.
Special Thanks:
Thank you to ReBensk for your ongoing support. We're grateful for your quiet use of incinerator.cloud and your tireless contributions of many unique samples. We greatly appreciate your willingness to publicly share all your sample analysis reports from your incinerator.cloud account with the community.
Thanks to 0x6rss for your assistance in both technical and other matters. You're an excellent brother who has taught us many new techniques. Our team hasn't worked in the malware analysis field for many years, and you've helped us learn a lot more. Thank you. Thanks to MalwareBug for submitting many samples and issues to us. Your ongoing support for the development of incinerator is invaluable, and I look forward to each of your articles!
Thanks to JoeSecurity. If it weren't for you identifying the issue with Zip types, we wouldn't have been inspired to analyze related technologies. We also hope to gain access to your Sandbox services since I've never successfully registered. Thank you to Fernando Sánchez for sharing your technical insights. We are very grateful!
