ZIPs tricks
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
Command-line tools์ zip files ๊ด๋ฆฌ๋ฅผ ์ํด ํ์์ ์ด๋ฉฐ zip files์ ์ง๋จ, ๋ณต๊ตฌ, ํฌ๋ํน์ ์ค์ํฉ๋๋ค. ๋ค์์ ์ฃผ์ ์ ํธ๋ฆฌํฐ์ ๋๋ค:
unzip: zip files๊ฐ ์์ถ ํด์ ๋์ง ์๋ ์ด์ ๋ฅผ ๋ณด์ฌ์ค๋๋ค.zipdetails -v: zip file format ํ๋์ ๋ํ ์์ธ ๋ถ์์ ์ ๊ณตํฉ๋๋ค.zipinfo: ์ถ์ถํ์ง ์๊ณ zip files์ ๋ด์ฉ์ ๋์ดํฉ๋๋ค.zip -F input.zip --out output.zip๋ฐzip -FF input.zip --out output.zip: ์์๋ zip files ๋ณต๊ตฌ๋ฅผ ์๋ํฉ๋๋ค.- fcrackzip: zip ๋น๋ฐ๋ฒํธ๋ฅผ ๋ธ๋ฃจํธํฌ์ค๋ก ํฌ๋ํ๋ ๋๊ตฌ๋ก, ๋๋ต 7์ ๋ด์ธ์ ๋น๋ฐ๋ฒํธ์ ํจ๊ณผ์ ์ ๋๋ค.
The Zip file format specification์ zip files์ ๊ตฌ์กฐ์ ํ์ค์ ๋ํ ์ข ํฉ์ ์ธ ์ธ๋ถ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ํธ๋ก ๋ณดํธ๋ zip files๋ ๋ด๋ถ์ ํ์ผ ์ด๋ฆ์ด๋ ํ์ผ ํฌ๊ธฐ๋ฅผ ์ํธํํ์ง ์๋๋ค๋ ์ ์ ์ ์ํด์ผ ํฉ๋๋ค(์ด ์ ์ RAR๋ 7z ํ์ผ๊ณผ ๋ฌ๋ฆฌ ํด๋น ์ ๋ณด๋ฅผ ์ํธํํ์ง ์๋ ๋ณด์ ๊ฒฐํจ์ ๋๋ค). ๋ํ, ์ค๋๋ ZipCrypto ๋ฐฉ์์ผ๋ก ์ํธํ๋ zip files๋ ์์ถ๋ ํ์ผ์ ์ํธํ๋์ง ์์ ๋ณต์ฌ๋ณธ์ด ์กด์ฌํ ๊ฒฝ์ฐ plaintext attack์ ์ทจ์ฝํฉ๋๋ค. ์ด ๊ณต๊ฒฉ์ ์๋ ค์ง ๋ด์ฉ์ ์ด์ฉํด zip์ ๋น๋ฐ๋ฒํธ๋ฅผ ํฌ๋ํ๋ ๋ฐฉ์์ด๋ฉฐ, ์ด ์ทจ์ฝ์ ์ HackThisโs article์ this academic paper์์ ์์ธํ ์ค๋ช ๋์ด ์์ต๋๋ค. ๋ฐ๋ฉด, AES-256๋ก ๋ณดํธ๋ zip files๋ ์ด plaintext attack์ ๋ฉด์ญ์ด๋ฏ๋ก ๋ฏผ๊ฐํ ๋ฐ์ดํฐ์๋ ์์ ํ ์ํธํ ๋ฐฉ์์ ์ ํํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
APKs์์ ์กฐ์๋ ZIP headers๋ฅผ ์ฌ์ฉํ ์ํฐ๋ฆฌ๋ฒ์ฑ ํธ๋ฆญ
ํ๋์ Android malware droppers๋ ์๋ชป๋ ZIP metadata๋ฅผ ์ฌ์ฉํด static tools (jadx/apktool/unzip)์ ๊นจ๋จ๋ฆฌ๋ฉด์๋ APK๋ฅผ ๊ธฐ๊ธฐ์์ ์ค์น ๊ฐ๋ฅํ๊ฒ ์ ์งํฉ๋๋ค. ๊ฐ์ฅ ํํ ํธ๋ฆญ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ZIP General Purpose Bit Flag (GPBF) ๋นํธ 0์ ์ค์ ํด ๊ฐ์ง ์ํธํ ํ์
- ํ์๋ฅผ ํผ๋์ํค๊ธฐ ์ํ ํฐ/์ปค์คํ Extra ํ๋ ๋จ์ฉ
- ์ค์ ์ํฐํฉํธ๋ฅผ ์จ๊ธฐ๊ธฐ ์ํ ํ์ผ/๋๋ ํฐ๋ฆฌ ์ด๋ฆ ์ถฉ๋(์: ์ค์
classes.dex์์classes.dex/๋ผ๋ ๋๋ ํฐ๋ฆฌ ์์ฑ)
1) Fake encryption (GPBF bit 0 set) without real crypto
์ฆ์:
jadx-gui๊ฐ ๋ค์๊ณผ ๊ฐ์ ์ค๋ฅ๋ก ์คํจํจ:
java.util.zip.ZipException: invalid CEN header (encrypted entry)
unzip์ด ํต์ฌ APK ํ์ผ๋ค์ ๋ํด ๋น๋ฐ๋ฒํธ๋ฅผ ์์ฒญํ์ง๋ง, ์ ํจํ APK๋classes*.dex,resources.arsc, ๋๋AndroidManifest.xml์ ์ํธํํ ์ ์์ต๋๋ค:
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
zipdetails๋ก ํ์ง:
zipdetails -v sample.apk | less
local ๋ฐ central ํค๋์ General Purpose Bit Flag๋ฅผ ํ์ธํ์ธ์. ํต์ฌ ํญ๋ชฉ(core entries)์์๋ ํน์ง์ ์ธ ๊ฐ์ ๋นํธ 0(Encryption)์ด ์ค์ ๋ ๊ฒ์ ๋๋ค:
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'
ํด๋ฆฌ์คํฑ: APK๊ฐ ๊ธฐ๊ธฐ์ ์ค์น๋์ด ์คํ๋์ง๋ง ํต์ฌ ํญ๋ชฉ๋ค์ด ๋๊ตฌ์ ์ํด โencryptedโ๋ก ๋ณด์ธ๋ค๋ฉด GPBF๊ฐ ๋ณ์กฐ๋ ๊ฒ์ ๋๋ค.
ํด๊ฒฐ: Local File Headers (LFH)์ Central Directory (CD) ํญ๋ชฉ ์์ชฝ์์ GPBF์ bit 0์ ํด๋ฆฌ์ดํ์ธ์. Minimal byte-patcher:
# 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}')
์ฌ์ฉ๋ฒ:
python3 gpbf_clear.py obfuscated.apk normalized.apk
zipdetails -v normalized.apk | grep -A2 "General Purpose Flag"
์ด์ ํต์ฌ ์ํธ๋ฆฌ์์ General Purpose Flag 0000์ด ํ์๋๊ณ ๋๊ตฌ๋ค์ด APK๋ฅผ ๋ค์ ํ์ฑํ ๊ฒ์
๋๋ค.
2) ํ์๋ฅผ ๋ฌด๋ ฅํํ๊ธฐ ์ํ ๋ํ/์ปค์คํ Extra ํ๋
๊ณต๊ฒฉ์๋ค์ ๋์ปดํ์ผ๋ฌ๋ฅผ ํผ๋์ํค๊ธฐ ์ํด ํค๋์ ๊ณผ๋ํ ํฌ๊ธฐ์ Extra ํ๋์ ์ด์ํ ID๋ค์ ๋ฃ์ต๋๋ค. ์ค์ ์์๋ (์: JADXBLOCK๊ณผ ๊ฐ์ ๋ฌธ์์ด) ๊ทธ๋ฐ ์ปค์คํ
๋ง์ปค๊ฐ ํฌํจ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
๊ฒ์ฌ:
zipdetails -v sample.apk | sed -n '/Extra ID/,+4p' | head -n 50
๊ด์ฐฐ๋ ์: 0xCAFE(โJava ์คํ ํ์ผโ) ๋๋ 0x414A(โJA:โ) ๊ฐ์ ์ ์ ์๋ ID๊ฐ ๋์ฉ๋ ํ์ด๋ก๋๋ฅผ ํฌํจํ๋ ๊ฒฝ์ฐ.
DFIR ํด๋ฆฌ์คํฑ:
- core ํญ๋ชฉ(
classes*.dex,AndroidManifest.xml,resources.arsc)์์ Extra ํ๋๊ฐ ๋น์ ์์ ์ผ๋ก ํด ๋ ๊ฒฝ๊ณ . - ํด๋น ํญ๋ชฉ๋ค์์ ์ ์ ์๋ Extra ID๋ ์์ฌ์ค๋ฌ์ด ๊ฒ์ผ๋ก ๊ฐ์ฃผ.
์ค๋ฌด์ ์ํ: ์์นด์ด๋ธ๋ฅผ ์ฌ๊ตฌ์ฑ(์: ์ถ์ถ๋ ํ์ผ์ ๋ค์ zip์ผ๋ก ์์ถ)ํ๋ฉด ์ ์ฑ Extra ํ๋๊ฐ ์ ๊ฑฐ๋ฉ๋๋ค. ๋๊ตฌ๊ฐ ๊ฐ์ง ์ํธํ ๋๋ฌธ์ ์ถ์ถ์ ๊ฑฐ๋ถํ๋ฉด, ์์์ ์ค๋ช ํ ๋๋ก ๋จผ์ GPBF bit 0์ ์ง์ด ๋ค์ ์ฌํจํค์งํ์ธ์:
mkdir /tmp/apk
unzip -qq normalized.apk -d /tmp/apk
(cd /tmp/apk && zip -qr ../clean.apk .)
3) ํ์ผ/๋๋ ํฐ๋ฆฌ ์ด๋ฆ ์ถฉ๋ (์ค์ ์ํฐํฉํธ ์จ๊น)
ZIP ํ์ผ์ ํ์ผ X์ ๋๋ ํฐ๋ฆฌ X/๋ฅผ ๋์์ ํฌํจํ ์ ์๋ค. ์ผ๋ถ extractors์ decompilers๋ ํผ๋๋์ด ๋๋ ํฐ๋ฆฌ ํญ๋ชฉ์ผ๋ก ์ค์ ํ์ผ์ ๋ฎ์ด์ฐ๊ฑฐ๋ ์จ๊ธธ ์ ์๋ค. ์ด๋ classes.dex์ ๊ฐ์ ํต์ฌ APK ์ด๋ฆ๊ณผ ์ถฉ๋ํ๋ ํญ๋ชฉ์์ ๊ด์ฐฐ๋์๋ค.
๋ถ์ ๋ฐ ์์ ํ ์ถ์ถ:
# 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
ํ๋ก๊ทธ๋จ์ ํ์ง ์ ๋ฏธ์ฌ:
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 ํ์ง ์์ด๋์ด:
- APK์ local headers๊ฐ ์ํธํ๋ก ํ์๋๋ (GPBF bit 0 = 1) ์ค์น/์คํ๋๋ ๊ฒฝ์ฐ ํ์ง.
- ํต์ฌ ์ํธ๋ฆฌ์ ํฌ๊ฑฐ๋ ์๋ ค์ง์ง ์์ Extra ํ๋(์:
JADXBLOCK๊ฐ์ ๋ง์ปค)๋ฅผ ํ์ง. - ํนํ
AndroidManifest.xml,resources.arsc,classes*.dex์ ๋ํด ๊ฒฝ๋ก ์ถฉ๋(X๋ฐX/)์ ํ์ง.
์ฐธ๊ณ ์๋ฃ
- https://michael-myers.github.io/blog/categories/ctf/
- GodFather โ Part 1 โ A multistage dropper (APK ZIP anti-reversing)
- zipdetails (Archive::Zip script)
- ZIP File Format Specification (PKWARE APPNOTE.TXT)
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


