Saat sabahın 03:14’üydü. Gözlerimde o meşhur 'mavi ışık yorgunluğu', önümde testCompany’nin yeni yayınlanacak Android uygulamasının kaynak kodları duruyordu. Geliştirici ekip 'Sedat, her şeyi şifreledik, SSL Pinning de var, imkanı yok içeri sızamazsın' demişti. Ama terminaldeki loglar bana bambaşka bir hikaye anlatıyordu. JADX-GUI üzerinde uygulamanın strings.xml dosyasına tıkladığım o saniye, projenin tüm AWS gizli anahtarlarının orada, sanki bir alışveriş listesiymiş gibi kabak gibi durduğunu gördüm. O an anladım ki; mobil dünyada en büyük düşmanımız karmaşık exploit’ler değil, 'nasılsa kimse bakmaz' dediğimiz o küçücük ihmaller.
Sizlerle bugün bu 'kimse bakmaz' denilen noktaların, aslında bir saldırgan için nasıl birer giriş kapısına dönüştüğünü konuşalım. Mobil uygulama güvenliği, web güvenliğinden çok daha farklı bir canavar. Çünkü kodunuz, saldırganın cihazında yaşıyor. Yani kale artık sizin kontrolünüzde değil, düşmanın oturma odasında.
Statik Analiz: Kodun İçindeki Hayaletler
Çoğu geliştirici, bir APK veya IPA dosyasının kapalı bir kutu olduğunu sanıyor. Oysa apktool veya jadx gibi araçlarla bu kutuyu açmak yaklaşık 10 saniye sürüyor. O gece karşılaştığım manzara sadece bir başlangıçtı. Uygulamanın decompile edilmiş kodları arasında gezerken, testCompany ekibinin test aşamasında bıraktığı bazı log çıktılarını gördüm.
// Defanged - Zararsızlaştırılmış örnek
public void onLoginSuccess(String token) {
Log.d("DEBUG_TAG", "Kullanıcı giriş yaptı, token: " + token);
// Bu satır production ortamında silinmemiş!
}
Logcat üzerinden bu logları okuyan herhangi bir zararlı uygulama, kullanıcının session token'ını saniyeler içinde çalabilir. Mobil dünyada 'hardcoded' veri bırakmak, evin anahtarını paspasın altına koyup üstüne 'anahtar burada' yazan bir tabela dikmekle aynı şeydir. API anahtarları, Firebase URL'leri, şifreleme tuzları (salts)... Bunların yeri asla istemci tarafı (client-side) değildir.
Dinamik Analiz ve SSL Pinning’in Kırılganlığı
Bir sonraki adımım trafiği izlemekti. Burp Suite'i kurdum, sertifikayı yükledim ama uygulama 'bağlantı hatası' veriyordu. Harika! SSL Pinning (Sertifika Sabitleme) çalışıyordu. Peki bu bizi durdurur mu? Tabii ki hayır.
Frida isimli o muazzam 'isviçre çakısı' devreye girdiğinde, uygulamanın runtime'ına sızmak çocuk oyuncağı haline geliyor. Geliştirici arkadaşların 'kırılamaz' dediği o zırhı, basit bir JavaScript scripti ile bypass ettim.
İşte o meşhur Frida scriptinin (zararsızlaştırılmış) mantığı:
// SSL Pinning Bypass - Eğitim Amaçlı Mock Kod
Java.perform(function() {
var CertificatePinner = Java.use("com.example.trust.Manager");
CertificatePinner.check.implementation = function(hostname, certificates) {
console.log("[+] SSL Pinning bypass edildi: " + hostname);
return; // Güvenlik kontrolünü pas geçiyoruz
};
});
Terminalde frida -U -f com.testcompany.app -l bypass.js komutunu çalıştırdığımda, uygulamanın tüm trafiği Burp Suite ekranına akmaya başladı. Gördüğüm şey daha da vahimdi: Uygulama, kullanıcının kredi kartı bilgilerini (bazı kısımları maskelenmiş olsa da) HTTP üzerinden bir log sunucusuna gönderiyordu. SSL Pinning sadece bir makyajmış, asıl veri güvenliği içeride çoktan iflas etmişti.
Insecure Data Storage: Yerel Veritabanındaki Sırlar
Mobil cihazlarda verilerin nasıl saklandığı konusu genellikle 'nasılsa sandbox var, diğer uygulamalar erişemez' mantığıyla geçiştiriliyor. Ancak cihaz 'root' edilmişse veya bir şekilde fiziksel erişim sağlanmışsa, sandbox bir kağıt parçasından farksızdır.
SharedPrefs veya SQLite veritabanlarını şifrelemeden kullanmak büyük bir risk. testCompany uygulamasında, kullanıcının biyometrik giriş yapıp yapmadığı bilgisini tutan isBiometricEnabled flag'ini true olarak değiştirdiğimde, uygulamanın parmak izi sormadan doğrudan ana ekrana geçtiğini fark ettim. Yerel veriye asla güvenilmemesi gerektiğinin canlı kanıtıydı bu.
Savunma Hattı: Ne Yapmalı?
Buraya kadar hep 'nasıl yıktık' kısmını anlattım, şimdi biraz da 'nasıl koruruz' kısmına gelelim. Çünkü biz Red Team’cilerin asıl amacı, günün sonunda sistemin daha sağlam olmasını sağlamaktır.
- Obfuscation (Kod Karartma) Şart: ProGuard veya R8 gibi araçları sadece kod boyutunu küçültmek için değil, kodun okunabilirliğini zorlaştırmak için de kullanın. Kritik algoritmalarınızı mümkünse C++ (JNI/NDK) katmanında yazın, reverse engineering süreçlerini ciddi anlamda zorlaştırırsınız.
- Network Security Config: Android tarafında
network_security_config.xmlkullanarak sadece güvenli bağlantılara izin verin. - EncryptedSharedPreferences: Verileri saklarken ham metin kullanmayın. Jetpack Security kütüphanesini kullanarak verileri donanım tabanlı anahtarlarla (KeyStore) şifreleyin.
- Root/Jailbreak Tespiti: Uygulamanızın root edilmiş bir cihazda çalışıp çalışmadığını kontrol edin. Eğer cihaz güvensizse, uygulamanın kritik fonksiyonlarını (örneğin ödeme adımı) devre dışı bırakın.
O gece güneş doğarken, testCompany ekibine hazırladığım raporda tek bir cümle kalın puntolarla yazılıydı: 'Güvenlik, bir özellik (feature) değil, bir süreçtir.'
Mobil dünyada yüzde yüz güvenli uygulama yoktur, sadece saldırganın işini o kadar zorlaştırırsınız ki, harcayacağı efor elde edeceği veriden daha değerli hale gelir. Terminalinizi açık, zihninizi uyanık tutun dostlar. Bir sonraki sızıntıda görüşmek üzere.
