Trucchi per ZIP

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Strumenti da riga di comando per gestire i file zip sono essenziali per diagnosticare, riparare e crackare zip. Ecco alcune utility chiave:

  • unzip: Rivela perché un file zip potrebbe non decomprimersi.
  • zipdetails -v: Offre un’analisi dettagliata dei campi del formato zip.
  • zipinfo: Elenca il contenuto di un file zip senza estrarlo.
  • zip -F input.zip --out output.zip e zip -FF input.zip --out output.zip: Provano a riparare file zip corrotti.
  • fcrackzip: Uno strumento per il brute-force delle password zip, efficace per password fino a circa 7 caratteri.

La Zip file format specification fornisce dettagli completi sulla struttura e gli standard dei file zip.

È fondamentale notare che i file zip protetti da password non criptano i nomi dei file né le dimensioni dei file al loro interno, una falla di sicurezza non presente in RAR o 7z che criptano queste informazioni. Inoltre, i file zip criptati con il vecchio metodo ZipCrypto sono vulnerabili a un attacco a plaintext conosciuto se è disponibile una copia non criptata di un file compresso. Questo attacco sfrutta il contenuto noto per crackare la password dello zip, una vulnerabilità dettagliata nell’articolo di HackThis e spiegata più approfonditamente in questo paper accademico. Tuttavia, i file zip protetti con crittografia AES-256 sono immuni a questo attacco a plaintext, sottolineando l’importanza di scegliere metodi di crittografia sicuri per dati sensibili.


Trucchi anti-reversing negli APK usando header ZIP manipolati

I moderni Android malware droppers usano metadati ZIP malformati per rompere tool statici (jadx/apktool/unzip) mantenendo però l’APK installabile sul dispositivo. I trucchi più comuni sono:

  • Crittografia fittizia impostando il bit 0 del ZIP General Purpose Bit Flag (GPBF)
  • Abuso di campi Extra grandi/personalizzati per confondere i parser
  • Collisioni di nomi file/directory per nascondere artefatti reali (es., una directory chiamata classes.dex/ accanto al vero classes.dex)

1) Crittografia fittizia (GPBF bit 0 impostato) senza crittografia reale

Sintomi:

  • jadx-gui fallisce con errori del tipo:
java.util.zip.ZipException: invalid CEN header (encrypted entry)
  • unzip chiede una password per file APK core anche se un APK valido non può avere classes*.dex, resources.arsc, o AndroidManifest.xml criptati:
unzip sample.apk
[sample.apk] classes3.dex password:
skipping: classes3.dex                          incorrect password
skipping: AndroidManifest.xml/res/vhpng-xhdpi/mxirm.png  incorrect password
skipping: resources.arsc/res/domeo/eqmvo.xml            incorrect password
skipping: classes2.dex                          incorrect password

Rilevamento con zipdetails:

zipdetails -v sample.apk | less

Esamina il General Purpose Bit Flag per gli header locali e centrali. Un valore rivelatore è il bit 0 impostato (Encryption) anche per le voci core:

Extract Zip Spec      2D '4.5'
General Purpose Flag  0A09
[Bit 0]   1 'Encryption'
[Bits 1-2] 1 'Maximum Compression'
[Bit 3]   1 'Streamed'
[Bit 11]  1 'Language Encoding'

Euristica: se un APK si installa e viene eseguito sul dispositivo ma le voci core appaiono “crittografate” agli strumenti, il GPBF è stato manomesso.

Correzione: azzera il bit 0 del GPBF sia nei Local File Headers (LFH) sia nelle voci della Central Directory (CD). Byte-patcher minimale:

Patcher minimo per azzerare il bit GPBF ```python # gpbf_clear.py – clear encryption bit (bit 0) in ZIP local+central headers import struct, sys

SIG_LFH = b“\x50\x4b\x03\x04“ # Local File Header SIG_CDH = b“\x50\x4b\x01\x02“ # Central Directory Header

def patch_flags(buf: bytes, sig: bytes, flag_off: int): out = bytearray(buf) i = 0 patched = 0 while True: i = out.find(sig, i) if i == -1: break flags, = struct.unpack_from(‘<H’, out, i + flag_off) if flags & 1: # encryption bit set struct.pack_into(‘<H’, out, i + flag_off, flags & 0xFFFE) patched += 1 i += 4 # move past signature to continue search return bytes(out), patched

if name == ‘main’: inp, outp = sys.argv[1], sys.argv[2] data = open(inp, ‘rb’).read() data, p_lfh = patch_flags(data, SIG_LFH, 6) # LFH flag at +6 data, p_cdh = patch_flags(data, SIG_CDH, 8) # CDH flag at +8 open(outp, ‘wb’).write(data) print(f’Patched: LFH={p_lfh}, CDH={p_cdh}’)

</details>

Uso:
```bash
python3 gpbf_clear.py obfuscated.apk normalized.apk
zipdetails -v normalized.apk | grep -A2 "General Purpose Flag"

Dovresti ora vedere General Purpose Flag 0000 sulle core entries e gli strumenti analizzeranno di nuovo l’APK.

2) Large/custom Extra fields to break parsers

Gli attaccanti inseriscono Extra fields sovradimensionati e ID anomali negli headers per far fallire i decompilers. In natura potresti vedere marker custom (es., stringhe come JADXBLOCK) incorporati lì.

Ispezione:

zipdetails -v sample.apk | sed -n '/Extra ID/,+4p' | head -n 50

Esempi osservati: ID sconosciuti come 0xCAFE (“Java Executable”) o 0x414A (“JA:”) che trasportano payload di grandi dimensioni.

DFIR heuristics:

  • Segnalare quando i campi Extra sono insolitamente grandi sulle voci core (classes*.dex, AndroidManifest.xml, resources.arsc).
  • Considerare gli ID Extra sconosciuti su quelle voci come sospetti.

Mitigazione pratica: ricostruire l’archivio (es., ri-zippare i file estratti) rimuove i campi Extra maligni. Se gli strumenti rifiutano di estrarre a causa di una finta crittografia, prima azzerare il bit 0 di GPBF come sopra, poi ricompattare:

mkdir /tmp/apk
unzip -qq normalized.apk -d /tmp/apk
(cd /tmp/apk && zip -qr ../clean.apk .)

3) Collisioni di nomi file/directory (nascondere artefatti reali)

Un ZIP può contenere sia un file X che una directory X/. Alcuni extractors e decompilers si confondono e possono sovrapporre o nascondere il file reale con una voce di directory. Questo è stato osservato con voci che collidono con nomi core di APK come classes.dex.

Triage e estrazione sicura:

# List potential collisions (names that differ only by trailing slash)
zipinfo -1 sample.apk | awk '{n=$0; sub(/\/$/,"",n); print n}' | sort | uniq -d

# Extract while preserving the real files by renaming on conflict
unzip normalized.apk -d outdir
# When prompted:
# replace outdir/classes.dex? [y]es/[n]o/[A]ll/[N]one/[r]ename: r
# new name: unk_classes.dex

Rilevamento programmatico post-fix:

from zipfile import ZipFile
from collections import defaultdict

with ZipFile('normalized.apk') as z:
names = z.namelist()

collisions = defaultdict(list)
for n in names:
base = n[:-1] if n.endswith('/') else n
collisions[base].append(n)

for base, variants in collisions.items():
if len(variants) > 1:
print('COLLISION', base, '->', variants)

Blue-team — idee di rilevamento:

  • Segnala APKs i cui header locali indicano cifratura (GPBF bit 0 = 1) ma che comunque si installano/eseguono.
  • Segnala Extra fields grandi/sconosciuti sulle voci core (cerca marker come JADXBLOCK).
  • Segnala collisioni di percorso (X e X/) specificamente per AndroidManifest.xml, resources.arsc, classes*.dex.

Altri trucchi ZIP malevoli (2024–2025)

Directory centrali concatenate (evasione multi-EOCD)

Recenti campagne di phishing distribuiscono un singolo blob che in realtà è due file ZIP concatenati. Ognuno ha il proprio End of Central Directory (EOCD) + central directory. Diversi extractor analizzano directory diverse (7zip legge la prima, WinRAR l’ultima), permettendo agli attaccanti di nascondere payload che vengono mostrati solo da alcuni strumenti. Questo aggira anche gli AV dei gateway mail che ispezionano solo la prima directory.

Comandi di triage

# Count EOCD signatures
binwalk -R "PK\x05\x06" suspect.zip
# Dump central-directory offsets
zipdetails -v suspect.zip | grep -n "End Central"

Se appare più di un EOCD o ci sono avvisi “data after payload”, dividi il blob e ispeziona ogni parte:

# recover the second archive (heuristic: start at second EOCD offset)
# adjust OFF based on binwalk output
OFF=123456
dd if=suspect.zip bs=1 skip=$OFF of=tail.zip
7z l tail.zip   # list hidden content

Quoted-overlap / overlapping-entry bombs (non-recursive)

Le moderne “better zip bomb” costruiscono un piccolo kernel (blocco DEFLATE altamente compresso) e lo riutilizzano tramite intestazioni locali sovrapposte. Ogni voce della central directory punta agli stessi dati compressi, raggiungendo rapporti >28M:1 senza annidare archivi. Librerie che si fidano delle dimensioni della central directory (Python zipfile, Java java.util.zip, Info-ZIP prima delle hardened builds) possono essere costrette ad allocare petabyte.

Rilevamento rapido (offset LFH duplicati)

# detect overlapping entries by identical relative offsets
import struct, sys
buf=open(sys.argv[1],'rb').read()
off=0; seen=set()
while True:
i = buf.find(b'PK\x01\x02', off)
if i<0: break
rel = struct.unpack_from('<I', buf, i+42)[0]
if rel in seen:
print('OVERLAP at offset', rel)
break
seen.add(rel); off = i+4

Gestione

  • Esegui un controllo a secco: zipdetails -v file.zip | grep -n "Rel Off" e assicurati che gli offset siano strettamente crescenti e unici.
  • Limita la dimensione totale non compressa accettata e il numero di voci prima dell’estrazione (zipdetails -t or custom parser).
  • Quando devi estrarre, fallo dentro un cgroup/VM con limiti su CPU e disco (evita crash dovuti a espansione illimitata).

Riferimenti

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks