Mobil Uygulama Güvenliğinin Temelleri: Statik ve Dinamik Analiz Dünyası
Mobil uygulamalar hayatımızın merkezinde. Bankacılık işlemlerimizden sosyal medya hesaplarımıza, sağlık verilerimizden kişisel mesajlarımıza kadar her şey akıllı telefonlarımızdaki uygulamalarda barındırılıyor. Peki bu uygulamalar ne kadar güvenli?
Web uygulamalarının aksine, mobil uygulamalarda kaynak kodun ve uygulama paketinin (Android için .apk, iOS için .ipa) kendisi doğrudan kullanıcının (ve dolayısıyla saldırganın) cihazına iner. Bu durum, mobil uygulama güvenliğini tamamen farklı bir boyuta taşır. Bu rehberde, mobil uygulama güvenliğinin temel sütunlarını, en sık karşılaşılan kritik zafiyetleri ve analiz yöntemlerini inceleyeceğiz.
Mobil Güvenliğin İki Ana Sütunu: Statik vs. Dinamik Analiz
Mobil bir uygulamanın güvenliğini test ederken (Pentest süreçlerinde) iki temel yaklaşım kullanılır:
1. Statik Kod Analizi (Static Application Security Testing – SAST)
Uygulama kodunun çalıştırılmadan, paket açılarak (Decompile edilerek) kaynak kod seviyesinde incelenmesidir.
Ne Aranır? Kodun içine sert kodlanmış (Hardcoded) API anahtarları, şifreler, güvensiz veri depolama fonksiyonları ve zafiyetli kütüphaneler.
Android için En Popüler Araçlar: JADX-GUI, Bytecode Viewer, Apktool.
2. Dinamik Kod Analizi (Dynamic Application Security Testing – DAST)
Uygulamanın bir emülatör veya gerçek bir cihaz üzerinde çalışırken test edilmesidir.
Ne Aranır? Çalışma zamanında (Runtime) hafıza manipülasyonları, ağ trafiğinin (HTTP/HTTPS) araya girilerek (Proxy) izlenmesi ve SSL Pinning mekanizmalarının test edilmesi.
En Popüler Araçlar: Frida, Objection, Burp Suite.
Mobil Dünyanın En Tehlikeli 3 Zafiyeti ve Çalışma Sebepleri
Mobil uygulama güvenliğinde en sık sömürülen ve OWASP Mobile Top 10 listesinde başı çeken kritik zafiyetler şunlardır:
1. Güvensiz Veri Depolama (Insecure Data Storage)
Giriş & Çalışma Sebebi: Mobil uygulamalar, kullanıcı oturumlarını veya ayarlarını cihaz hafızasında saklar. Zafiyetin asıl sebebi, geliştiricilerin hassas verileri (Örn: Yetkilendirme token’ları, kullanıcı şifreleri) cihaz yerelinde şifrelemeden, düz metin (Plaintext) olarak SharedPreferences (Android) veya UserDefaults (iOS) içinde saklamasıdır. Cihaz ele geçirildiğinde veya root/jailbreak yapıldığında bu veriler tamamen sızar.
Payload / Tespit Noktası (Android):
cat /data/data/com.hedef.uygulama/shared_prefs/UserSession.xml # Çıktıda şifrelenmemiş veri: <string name="auth_token">GIZLI_TOKEN_123</string>
2. Hardcoded (Kod İçine Gömülü) Hassas Veriler
Giriş & Çalışma Sebebi: Geliştiriciler bazen test süreçlerini hızlandırmak veya üçüncü parti servislere (AWS, Firebase, Google Maps API vb.) kolayca erişmek için API anahtarlarını doğrudan kaynak kodun içine yazarlar. Zafiyetin asıl sebebi, mobil uygulamaların kolayca decompile edilebildiğinin (geri çevrilebildiğinin) unutulmasıdır.
Tespit Noktası (JADX ile açılan kod):
public class Config { // Saldırganın decompile ederek tek tıkla bulabileceği kritik veri public static final String AWS_SECRET_KEY = "AKIAIOSFODNN7EXAMPLE"; }
3. Yetersiz Taşıma Katmanı Güvenliği (Zayıf SSL/TLS ve SSL Pinning Eksikliği)
Giriş & Çalışma Sebebi: Mobil uygulamanın sunucuyla (API) konuşurken trafiği şifrelememesi veya sertifika doğrulaması yapmamasıdır. Saldırgan, araya girme (Man-in-the-Middle – MitM) saldırısıyla tüm trafiği okuyabilir. Uygulama buna önlem olarak SSL Pinning (Sertifika Sabitleme) kullansa bile, dinamik analiz aşamasında Frida gibi araçlarla bu kontrol çalışma zamanında (Runtime) baypas edilebilir.
Güvenli Mobil Geliştirme İçin Altın Kurallar
Kaynak Kod Karıştırma (Code Obfuscation): Kodun decompile edildiğinde kolayca okunmasını engellemek için ProGuard (Android) veya benzeri kod karıştırıcı araçlar kesinlikle kullanılmalıdır.
Güvenli Depolama Mimarıleri: Hassas veriler düz metin olarak saklanmamalı; Android tarafında EncryptedSharedPreferences veya KeyStore, iOS tarafında ise Keychain mimarisi zorunlu kılınmalıdır.
Kök Dizin (Root/Jailbreak) Kontrolü: Uygulama açılırken cihazın güvenli olup olmadığı (Rootlu olup olmadığı) kontrol edilmeli, güvensiz cihazlarda uygulamanın çalışması sınırlandırılmalıdır.
Uygulamalı Lab: Bir APK Dosyası Nasıl Tersine Çevrilir? (Statik Analiz)
Saldırganların veya pentesterların (sızma testi uzmanları), hedef uygulamanın kaynak kodlarına ulaşmak için izlediği standart adımları kendi laboratuvarımızda simüle edelim. Bu işlem için bilgisayarımızda JADX-GUI aracının kurulu olması yeterlidir.
Dinamik Analizin Gücü: Frida ile Runtime Manipülasyonu
Statik analizde kod karıştırma (Obfuscation) kullanılmışsa ve kodlar tamamen okunamaz hale getirilmişse, devreye Frida girer. Frida, uygulamanın kaynak kodunu değiştirmeden, uygulama çalışırken hafızadaki (RAM) fonksiyonları izlememizi, manipüle etmenizi veya tamamen baypas etmemizi sağlayan bir dinamik enjeksiyon (hooking) kütüphanesidir.
Frida Mekanizması Nasıl Çalışır?
Test cihazına (Emülatör veya Rootlu telefon) arka planda çalışması için
frida-serverkurulur.Bilgisayarımız üzerinden JavaScript dilinde yazılmış bir “Hook” scripti hazırlanır.
Frida, bu JavaScript kodunu çalışan uygulamanın hafıza alanına enjekte eder ve orijinal fonksiyonun davranışını değiştirir.
Payload: Fonksiyonun Dönüş Değerini Değiştirmek (Hooking)
Örneğin, uygulamanın giriş ekranında cihazın rootlu olup olmadığını kontrol eden bir isDeviceRooted() fonksiyonu olsun. Bu fonksiyon cihaz rootluysa true, değilse false dönüyor olsun. Cihaz rootlu olduğu için uygulama kendini kapatıyorsa, Frida ile bu kontrolü şu script yardımıyla canlı olarak baypas edebiliriz:
Java.perform(function () {
// Hedef sınıfı ve fonksiyonu RAM'de yakalıyoruz
var SecurityCheck = Java.use("com.hedef.uygulama.helpers.SecurityCheck");
// Orijinal fonksiyonun davranışını yeniden yazıyoruz (Overriding)
SecurityCheck.isDeviceRooted.implementation = function () {
console.log("[*] isDeviceRooted() fonksiyonu tetiklendi! Müdahale ediliyor...");
// Cihaz rootlu olsa bile sunucuya/uygulamaya her zaman 'false' (güvenli) dönüyoruz
return false;
};
});
Çalışma Sebebi: Uygulama çalışırken bu fonksiyona her uğradığında, orijinal kod yerine bizim enjekte ettiğimiz JavaScript bloğu çalışır. Fonksiyonun dönüş değeri RAM seviyesinde manipüle edildiği için uygulama root korumasını tamamen unutur ve çalışmaya devam eder.
