Skip to content

Commit ff6e21e

Browse files
authored
Merge pull request #1370 from HackTricks-wiki/update_GodFather_-_Part_1_-_A_multistage_dropper_20250829_183210
GodFather - Part 1 - A multistage dropper
2 parents 2a44001 + 4bc8a8a commit ff6e21e

1 file changed

Lines changed: 160 additions & 3 deletions

File tree

  • src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks

src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/zips-tricks.md

Lines changed: 160 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,168 @@ The [Zip file format specification](https://pkware.cachefly.net/webdocs/casestud
1414

1515
It's crucial to note that password-protected zip files **do not encrypt filenames or file sizes** within, a security flaw not shared with RAR or 7z files which encrypt this information. Furthermore, zip files encrypted with the older ZipCrypto method are vulnerable to a **plaintext attack** if an unencrypted copy of a compressed file is available. This attack leverages the known content to crack the zip's password, a vulnerability detailed in [HackThis's article](https://www.hackthis.co.uk/articles/known-plaintext-attack-cracking-zip-files) and further explained in [this academic paper](https://www.cs.auckland.ac.nz/~mike/zipattacks.pdf). However, zip files secured with **AES-256** encryption are immune to this plaintext attack, showcasing the importance of choosing secure encryption methods for sensitive data.
1616

17-
## References
17+
---
1818

19-
- [https://michael-myers.github.io/blog/categories/ctf/](https://michael-myers.github.io/blog/categories/ctf/)
19+
## Anti-reversing tricks in APKs using manipulated ZIP headers
2020

21-
{{#include ../../../banners/hacktricks-training.md}}
21+
Modern Android malware droppers use malformed ZIP metadata to break static tools (jadx/apktool/unzip) while keeping the APK installable on-device. The most common tricks are:
22+
23+
- Fake encryption by setting the ZIP General Purpose Bit Flag (GPBF) bit 0
24+
- Abusing large/custom Extra fields to confuse parsers
25+
- File/directory name collisions to hide real artifacts (e.g., a directory named `classes.dex/` next to the real `classes.dex`)
26+
27+
### 1) Fake encryption (GPBF bit 0 set) without real crypto
28+
29+
Symptoms:
30+
- `jadx-gui` fails with errors like:
31+
32+
```
33+
java.util.zip.ZipException: invalid CEN header (encrypted entry)
34+
```
35+
- `unzip` prompts for a password for core APK files even though a valid APK cannot have encrypted `classes*.dex`, `resources.arsc`, or `AndroidManifest.xml`:
36+
37+
```bash
38+
unzip sample.apk
39+
[sample.apk] classes3.dex password:
40+
skipping: classes3.dex incorrect password
41+
skipping: AndroidManifest.xml/res/vhpng-xhdpi/mxirm.png incorrect password
42+
skipping: resources.arsc/res/domeo/eqmvo.xml incorrect password
43+
skipping: classes2.dex incorrect password
44+
```
45+
46+
Detection with zipdetails:
47+
48+
```bash
49+
zipdetails -v sample.apk | less
50+
```
51+
52+
Look at the General Purpose Bit Flag for local and central headers. A telltale value is bit 0 set (Encryption) even for core entries:
53+
54+
```
55+
Extract Zip Spec 2D '4.5'
56+
General Purpose Flag 0A09
57+
[Bit 0] 1 'Encryption'
58+
[Bits 1-2] 1 'Maximum Compression'
59+
[Bit 3] 1 'Streamed'
60+
[Bit 11] 1 'Language Encoding'
61+
```
62+
63+
Heuristic: If an APK installs and runs on-device but core entries appear "encrypted" to tools, the GPBF was tampered with.
64+
65+
Fix by clearing GPBF bit 0 in both Local File Headers (LFH) and Central Directory (CD) entries. Minimal byte-patcher:
66+
67+
```python
68+
# gpbf_clear.py – clear encryption bit (bit 0) in ZIP local+central headers
69+
import struct, sys
70+
71+
SIG_LFH = b"\x50\x4b\x03\x04" # Local File Header
72+
SIG_CDH = b"\x50\x4b\x01\x02" # Central Directory Header
73+
74+
def patch_flags(buf: bytes, sig: bytes, flag_off: int):
75+
out = bytearray(buf)
76+
i = 0
77+
patched = 0
78+
while True:
79+
i = out.find(sig, i)
80+
if i == -1:
81+
break
82+
flags, = struct.unpack_from('<H', out, i + flag_off)
83+
if flags & 1: # encryption bit set
84+
struct.pack_into('<H', out, i + flag_off, flags & 0xFFFE)
85+
patched += 1
86+
i += 4 # move past signature to continue search
87+
return bytes(out), patched
88+
89+
if __name__ == '__main__':
90+
inp, outp = sys.argv[1], sys.argv[2]
91+
data = open(inp, 'rb').read()
92+
data, p_lfh = patch_flags(data, SIG_LFH, 6) # LFH flag at +6
93+
data, p_cdh = patch_flags(data, SIG_CDH, 8) # CDH flag at +8
94+
open(outp, 'wb').write(data)
95+
print(f'Patched: LFH={p_lfh}, CDH={p_cdh}')
96+
```
97+
98+
Usage:
99+
100+
```bash
101+
python3 gpbf_clear.py obfuscated.apk normalized.apk
102+
zipdetails -v normalized.apk | grep -A2 "General Purpose Flag"
103+
```
104+
105+
You should now see `General Purpose Flag 0000` on core entries and tools will parse the APK again.
106+
107+
### 2) Large/custom Extra fields to break parsers
108+
109+
Attackers stuff oversized Extra fields and odd IDs into headers to trip decompilers. In the wild you may see custom markers (e.g., strings like `JADXBLOCK`) embedded there.
22110

111+
Inspection:
23112

113+
```bash
114+
zipdetails -v sample.apk | sed -n '/Extra ID/,+4p' | head -n 50
115+
```
116+
117+
Examples observed: unknown IDs like `0xCAFE` ("Java Executable") or `0x414A` ("JA:") carrying large payloads.
118+
119+
DFIR heuristics:
120+
- Alert when Extra fields are unusually large on core entries (`classes*.dex`, `AndroidManifest.xml`, `resources.arsc`).
121+
- Treat unknown Extra IDs on those entries as suspicious.
122+
123+
Practical mitigation: rebuilding the archive (e.g., re-zipping extracted files) strips malicious Extra fields. If tools refuse to extract due to fake encryption, first clear GPBF bit 0 as above, then repackage:
124+
125+
```bash
126+
mkdir /tmp/apk
127+
unzip -qq normalized.apk -d /tmp/apk
128+
(cd /tmp/apk && zip -qr ../clean.apk .)
129+
```
130+
131+
### 3) File/Directory name collisions (hiding real artifacts)
132+
133+
A ZIP can contain both a file `X` and a directory `X/`. Some extractors and decompilers get confused and may overlay or hide the real file with a directory entry. This has been observed with entries colliding with core APK names like `classes.dex`.
134+
135+
Triage and safe extraction:
136+
137+
```bash
138+
# List potential collisions (names that differ only by trailing slash)
139+
zipinfo -1 sample.apk | awk '{n=$0; sub(/\/$/,"",n); print n}' | sort | uniq -d
140+
141+
# Extract while preserving the real files by renaming on conflict
142+
unzip normalized.apk -d outdir
143+
# When prompted:
144+
# replace outdir/classes.dex? [y]es/[n]o/[A]ll/[N]one/[r]ename: r
145+
# new name: unk_classes.dex
146+
```
147+
148+
Programmatic detection post-fix:
149+
150+
```python
151+
from zipfile import ZipFile
152+
from collections import defaultdict
153+
154+
with ZipFile('normalized.apk') as z:
155+
names = z.namelist()
156+
157+
collisions = defaultdict(list)
158+
for n in names:
159+
base = n[:-1] if n.endswith('/') else n
160+
collisions[base].append(n)
161+
162+
for base, variants in collisions.items():
163+
if len(variants) > 1:
164+
print('COLLISION', base, '->', variants)
165+
```
166+
167+
Blue-team detection ideas:
168+
- Flag APKs whose local headers mark encryption (GPBF bit 0 = 1) yet install/run.
169+
- Flag large/unknown Extra fields on core entries (look for markers like `JADXBLOCK`).
170+
- Flag path-collisions (`X` and `X/`) specifically for `AndroidManifest.xml`, `resources.arsc`, `classes*.dex`.
171+
172+
---
173+
174+
## References
175+
176+
- [https://michael-myers.github.io/blog/categories/ctf/](https://michael-myers.github.io/blog/categories/ctf/)
177+
- [GodFather – Part 1 – A multistage dropper (APK ZIP anti-reversing)](https://shindan.io/blog/godfather-part-1-a-multistage-dropper)
178+
- [zipdetails (Archive::Zip script)](https://metacpan.org/pod/distribution/Archive-Zip/scripts/zipdetails)
179+
- [ZIP File Format Specification (PKWARE APPNOTE.TXT)](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)
24180

181+
{{#include ../../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)