Generated by Perplexity’s Research
Recent cybersecurity research has uncovered sophisticated exploitation techniques in BadPack malware targeting Android’s APK file structure12. This advanced persistent threat leverages deliberate manipulation of ZIP archive headers to bypass traditional malware analysis tools while maintaining functionality on Android devices. By creating intentional mismatches between local file headers and central directory headers within APK files, attackers achieve dual objectives: 1) preventing static analysis of critical components like AndroidManifest.xml, and 2) ensuring successful execution on victim devices. Palo Alto Networks’ Unit 42 researchers identified nearly 9,200 BadPack samples between June 2023-June 2024, demonstrating widespread adoption of these techniques by banking Trojans like BianLian and Cerberus2. This report provides comprehensive technical analysis of the ZIP header manipulation mechanics, reverse engineering challenges, and mitigation strategies.
Android Application Packages (APKs) utilize standard ZIP file format with specialized structural requirements:
[Local File Header 1]
[File Data 1]
[Local File Header 2]
[File Data 2]
...
[Central Directory Header 1]
[Central Directory Header 2]
[End of Central Directory Record]
Critical components include:
The hexadecimal signature 50 4B 03 04 (PK) marks local headers, while central directories use 50 4B 01 02 (PK)2.
Key fields vulnerable to BadPack manipulation:
Field Name Offset Size Purpose
Compression Method 0x08 2B 0=Store, 8=Deflate
Compressed Size 0x12 4B Size after compression
Uncompressed Size 0x16 4B Original file size
File Name Length 0x1A 2B Length of subsequent filename
Extra Field Length 0x1C 2B Length of additional metadata
Listing 1: Critical ZIP header fields targeted by BadPack2 BadPack Exploitation Techniques Header Mismatch Methodology BadPack operators exploit differential parsing between analysis tools and Android runtime: Analysis Tools (Apktool/Jadx): Validate consistency between local/central headers Android Runtime: Primarily utilizes central directory headers, ignoring local discrepancies This allows malicious APKs to: Pass Android installation checks (central headers valid) Crash analysis tools (header mismatches trigger parsing errors) Technical Implementation Variants Method 1: Valid Compression with Invalid Sizes
Local Header:
Compression Method: 0x0000 (Store)
Compressed Size: 0x0000A1B0 (41392)
Uncompressed Size: 0x0000A1B0 (41392)
Central Directory:
Compression Method: 0x0000 (Store)
Compressed Size: 0x0000A1B0 (41392)
Uncompressed Size: 0x0000A1B0 (41392)
Actual compressed data size: 0x0000A1B1 (41393)
Analysis tools crash on size validation failure, while Android uses central directory values2.
Method 2: Compression Method Spoofing
text
Local Header:
Compression Method: 0x0008 (Deflate)
Compressed Size: 0x00004370 (17264)
Uncompressed Size: 0x00004370 (17264)
Central Directory:
Compression Method: 0x0000 (Store)
Compressed Size: 0x00004370 (17264)
Uncompressed Size: 0x00004370 (17264)
Here, local header claims Deflate compression while central directory specifies Store. Android honors central directory, while tools attempt Deflate decompression on improperly compressed data2.
Local Header:
Compression Method: 0xFFFF (Invalid)
Compressed Size: 0xDEADBEEF
Uncompressed Size: 0xCAFEBABE
Central Directory:
Compression Method: 0x0000 (Store)
Compressed Size: 0x0002A1F0 (172272)
Uncompressed Size: 0x0002A1F0 (172272)
Invalid local fields cause analysis tool failures, while Android's runtime ignores them.
Critical code paths in Android’s PackageParser class demonstrate header processing differences:
public class PackageParser {
public Package parsePackage(File packageFile, int flags) throws PackageParserException {
// Retrieve central directory entry
ZipEntry manifestEntry = zipFile.getEntry("AndroidManifest.xml");
if (manifestEntry.getMethod() == ZipEntry.DEFLATED) {
InputStream is = zipFile.getInputStream(manifestEntry);
// Decompress using Deflate
} else {
// Read uncompressed data directly
int size = (int) manifestEntry.getSize();
byte[] data = new byte[size];
// Read from offset with STORE method
}
// Parse manifest XML
return parsePackage(data);
}
}
Listing 2: Simplified Android manifest parsing logic2
Relies solely on central directory’s getMethod() and getSize() No validation against local header values Invalid local headers don’t affect runtime extraction Installation Process Experimentation Unit42 researchers validated this behavior through controlled APK modifications:
Valid APK Installation
$ adb install original.apk
Success
Modified Central Directory Compression
bash
$ hexedit modified.apk
# Change central directory compression from 0x0008 → 0x0000
$ adb install modified.apk
Failure [INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION: Corrupt XML]
This demonstrates Android’s dependency on valid central directory metadata2.
Traditional Android reverse engineering tools fail due to strict ZIP specification adherence:
Tool | Failure Mode | BadPack Impact |
---|---|---|
Apktool | Header validation exceptions | AndroidManifest extraction |
Jadx | CRC/Size mismatches | Decompilation errors |
unzip | Invalid compression methods | Extraction aborted |
apksigner | Header integrity checks | Verification failures |
The open-source apkInspector tool succeeds through:
Implementation excerpt:
def fix_local_headers(apk_path):
with open(apk_path, 'r+b') as f:
# Parse central directory
= read_central_directory(f)
cdir
# Overwrite local headers
for entry in cdir.entries:
f.seek(entry.local_header_offset)# Use central dir values
write_local_header(f, entry)
def extract_manifest(apk_path):
fix_local_headers(apk_path)# Proceed with standard extraction
Listing 3: Header normalization approach1
Detection Improvements in Header Consistency Checks:
def detect_badpack(apk):
for entry in apk.infolist():
= entry.header_offset
local = entry.central_offset
central if local.compression != central.compression:
return True
if local.compress_size != central.compress_size:
return True
return False
aapt dump permissions infected.apk
# Check for excessive permissions
BadPack represents a significant evolution in Android malware obfuscation, exploiting fundamental differences between ZIP specification validation and runtime pragmatism. By understanding the technical nuances of local/central header mismatches, security teams can develop better detection mechanisms and analysis tools. The ongoing arms race between malware authors and defenders necessitates continuous updates to APK parsing implementations, emphasizing the need for:
Future research directions should explore machine learning models trained on raw APK bytes to detect structural anomalies indicative of BadPack and similar techniques.