Giriş

Bu teknik seti, Android APK paketlerinin ZIP tabanlı dosya yapısındaki kritik meta veri alanlarının kasıtlı olarak bozulması yoluyla, statik analiz araçlarının paket içeriğini doğru şekilde ayrıştıramamasını amaçlar. Buradaki zafiyet, Android uygulama yükleyicisinin (PackageManager + Zygote) dosya formatına fault-tolerant davranması, buna karşılık reverse engineering araçlarının (ör. JEB Pro, JADX, apktool) ZIP specification (PKZIP APPNOTE) standartlarına daha sıkı bağlı kalmasından kaynaklanır.

Çalışma mantığı şu şekildedir:

  • Android runtime, yükleme sırasında yalnızca manifest, DEX ve gerekli kaynak segmentlerinin erişilebilirliğini kontrol eder; ZIP header alanlarında küçük tutarsızlıklar göz ardı edilir.
  • Statik analiz araçları ise, tüm ZIP yapısını central directory file header ve End of Central Directory (EOCD) bloklarına göre bütünlük testinden geçirir.
  • Eğer alanlar beklenmeyen değerler içerirse, analiz aracı parse error üreterek işlemi durdurur; bu, anti-analiz tekniğinin başarıyla devreye girdiğini gösterir.

1. Wrong / Manipüle Edilmiş ZIP Header Alanları

Bir APK, normal şartlarda tek bir diskten oluşan standart bir ZIP arşivi formatına sahiptir. Çoklu-disk (multi-volume) arşiv kavramı APK ekosisteminde kullanılmaz. Bu yüzden, EOCD bloğundaki disk sayısı alanları APK'da mantıksal olarak her zaman 0x0000 olmalıdır.

EOCD Multi File Exception
EOCD Multi File Exception hatası

1.2 EOCD — Yapısal Alanlar ve Manipülasyon Tespiti

EOCD Bloğu, ZIP tabanlı APK arşivlerinde central directory yapısının sonunu işaretler ve arşivin bütünlüğü açısından kritik meta verileri içerir. Bu blok her zaman dosyanın son kısmında bulunur ve ZIP formatında şu alanlardan oluşur:

EOCD_Ofset Byte Alan_Adı Normal_APK_Davranışı ZIP64_Geçersiz_Değer
0x00 4 Signature (0x06054b50) Sabit
0x04 2 Number of this disk 0x0000 0xFFFF
0x06 2 Disk where central directory starts Gerçek kayıt sayısı 0xFFFF
0x08 2 Entries in central directory on this disk 0x0000 0xFFFF
0x0A 2 Total entries in central directory 0x0000 0xFFFF
0x0C 4 Size of central directory (bytes) Hesaplanan boyut 0xFFFFFFFF
0x10 4 Offset of start of central directory Geçersiz ofset 0xFFFFFFFF
0x14 4 Comment length (n) 0 veya küçük değer
0x16 n Comment data Opsiyonel

EOCD ZIP'in sonunu işaretler, bu nedenle gerekli bayt dizisi dosyanın sonunda bulunabilir.

EOCD End Sequence
EOCD bayt dizisi dosya sonunda

Düzeltilmiş (ve aşağıda açıklanan düzeltmeler uygulanmış) işlenmiş yapı şu şekilde görünür:

EOCD Values to Change
Değiştirilmesi gereken EOCD değerleri

Disk numarası alanlarındaki çok büyük değerlerden, malware geliştiricilerinin bu alanları ve girdileri değiştirdiği açıkça anlaşılır. Bu APK, herhangi bir meşru APK ile karşılaştırıldığında, meşru APK'larda elDiskNumber ve elStartDiskNumber değerlerinin 0 olduğu görülür. Mevcut durumda da disk numaralarının 0 olması gerekir.

Ayrıca, meşru APK'larda elEntriesInDirectory ve elDirectorySize değerleri aynı iken, hedef APK'da bu durum farklıdır. elEntriesInDirectory alanı ushort tipinde olduğundan (2 bayt uzunluğunda), maksimum değeri 65536 olabilir ve 139122 gibi bir değere eşit olamaz. Yani elDirectorySize değeri, elEntriesInDirectory değerine eşit olmalıdır; tersi değil. Bu yüzden elDirectorySize değerinin değiştirilmesi gerekir.

2. Wrong values in the manifest structure

2.1. Magic değer

AndroidManifest dosyası, APKTool'un beklediği üzere belirli bir magic number ile başlamalıdır (0x00080003 veya 0x00080001):

Manifest Magic Candidates
Olası manifest magic değerleri

Ancak, bu apktool hatası daha yakından incelendiğinde, AndroidManifest başlığındaki tek doğru değerin 0x00080003 olduğu görülür. Bu değer, apktool kaynak kodunda tanımlı CHUNK_AXML_FILE sabitine eşittir; 0x00080001 değeri ise CHUNK_AXML_FILE_BROKEN olarak adlandırılır.

Manifest Magic Constants
APKTool kaynak kodundaki sabitler

Ve analiz edilen dosya 0x00080000 ile başlıyor. Bu değeri doğru olan ile değiştirerek bu sorun giderilebilir.

2.2. String ofsetleri dizisi

Analiz araçlarını yanıltmak için kullanılan bir diğer yöntem, string ofsetleri dizisindeki yanlış ofset değerleridir:

Manifest String Start
String ofset hatası

Bu hataya neyin sebep olduğunu analiz etmek için önce AndroidManifest yapısını parçalarına ayırdım:

Manifest Array Structure
AndroidManifest yapısı

Exception da gösterilen ofseti kontrol ederek, sorunun scStringOffsets dizi alanında, yani dizinin son elemanında olduğunu anlıyoruz (0x24 + 0x160 = 0x184 – istisnada görülen tam ofset). Bu diziyi yakından incelediğimizde, son string'in ofsetinin dosyanın dışını işaret ettiğini görüyoruz.

Manifest String Offset Wrong
Yanlış string ofset değeri

"theme" dizesi, dizinin son elemanında (87 numaralı) bir ofset değeri olarak yanlış yorumlanmış. Bu, scStringCount değerinin 1 azaltılması gerektiği anlamına geliyor, yani 86 olarak ayarlanmalı.

Şu anda dizide 87 eleman var ve her biri 4 bayt uzunluğunda. 87 × 4 = 348 bayt, bu da hex olarak 0x15C'ye eşit. scStringOffsets alanı 0x24 adresinden başladığına göre, 0x24 + 0x15C = 0x180 adresinde bitmesi gerekir — bu da analiz aracında beklenen değerle tam olarak uyuşur.

2.3. Style pool

Bu yöntemde, scStylePoolOffset alanının değeri, gerçek AndroidManifest dosyasının dışını işaret eder. scStyleCount alanının değeri 0 olduğundan, dosyanın "style" içermemesi gerektiği mantıklı bir varsayımdır. Dolayısıyla bu alanın değeri de 0 olmalıdır.

Manifest Style Fix
Style pool düzeltmesi

3. Uzun dosya adları

Bu teknik, APK içindeki dosyalarla ilgilidir. Geliştiriciler, assets klasörüne iç içe geçmiş dizinler içinde çok sayıda dosya eklemiştir. Bunun sonucunda dosya adı ve yolunun uzunluğu 300 karakterin üzerine çıkmıştır.

Bu dosyalar, dosya konumlarını yeniden eşleyemeyen ve APK decompile (tersine derleme) işlemi sırasında başarısız olabilen araçların mantığını bozar — örneğin apktool. Bayt kodundan (bytecode) yapılan API çağrılarının analizi sonucunda, bu dosyalara yönelik herhangi bir gerçek başvuru olmadığı görülür. Bu, söz konusu dosyaların artık gerekli olmadığı için APK'dan elle kaldırılabileceği anlamına gelir.

Ek - Signature önerileri

Bu kaçınma grubuna yönelik özel bir imza önerisi sunulmamaktadır, çünkü teknikler zaten kendilerini açıkça belli etmektedir. Eğer analiz araçları bir örneği işlerken hata veriyor veya başarısız oluyorsa, bu genellikle kullanılan bir anti-analiz tekniğinin işareti olabilir.

Sorumluluk Reddi Beyanı

Bu makale yalnızca eğitim ve araştırma amaçlıdır. Burada açıklanan teknikler, kötü amaçlı yazılımların analiz edilmesi ve savunma mekanizmalarının geliştirilmesi için sunulmaktadır. Bu bilgilerin kötüye kullanılmasından yazar sorumlu tutulamaz.