Ekranın parlaklığı gözlerimi yakıyordu, saat sabahın 03:14'üydü ve önümdeki terminal ekranında adb logcat çıktılarının bitmek bilmeyen akışını izliyordum. testCompany'nin yeni piyasaya süreceği mobil ödeme uygulamasının beta sürümünde garip bir şeyler vardı. Uygulama, kullanıcının izni olmadan arka planda garip bir endpoint'e (http://api.example.com/v1/debug/dump) şifrelenmemiş veri gönderiyordu. Üstelik bu veri, kullanıcının son işlem yaptığı kartın maskelenmemiş halini içeriyordu. Kahvemden soğuk bir yudum alıp klavyeye uzandım; o an anladım ki sabah güneşini görmeden bu işi çözmem gerekiyordu.
İlk Adım: Kaleye Arkadan Sızmak (Decompiling)
Mobil güvenlik dediğimizde çoğu kişi sadece telefonuna şifre koymayı ya da 'Root/Jailbreak' kontrolünü anlıyor. Ama işin mutfağı çok daha vahşi. İlk iş olarak APK dosyasını önüme aldım. jadx-gui ile içeri daldığımda gördüğüm manzara içler acısıydı: Geliştirici ekip, debug modunda unutulmuş bir 'Logger' sınıfını canlıya taşımıştı. Üstelik uygulama 'obfuscation' (kod karartma) işleminden de geçirilmemişti. Her şey çırılçıplak ortadaydı.
Sadece APK'yı açıp strings.xml veya AndroidManifest.xml dosyasına bakmak bile bazen bir uygulamanın tüm sırlarını dökebilir. Şuna benzer bir şeyle karşılaştım:
<!-- AndroidManifest.xml içinden bir kesit -->
<activity android:name=".WebViewActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="testcompany-app" android:host="payment" />
</intent-filter>
</activity>
Buradaki testcompany-app://payment bir Deep Link. Eğer bu linkin parametrelerini doğru kurgulamazsanız, bir saldırgan kullanıcıya attığı bir SMS veya e-posta ile uygulamanın içinde istediği aksiyonu aldırabilir. Örneğin: testcompany-app://payment?amount=1000&to=attacker_account. Bu noktada uygulama, parametreyi doğrulamadan işleme alıyorsa geçmiş olsun.
SSL Pinning: Güvenlik mi, Yoksa Yanılsama mı?
"Biz SSL Pinning yapıyoruz, araya kimse giremez" diyen birini görürseniz ona Frida'dan bahsedin. Uygulama ile sunucu arasındaki trafiği Burp Suite ile dinlemek istediğimde, uygulama bağlantıyı reddetti. Güzel, en azından bir sertifika kontrolü vardı. Ama bu Red Team için sadece 5 dakikalık bir engel.
Frida kullanarak uygulamanın sertifika kontrolü yapan fonksiyonunu (TrustManager gibi) çalışma zamanında (runtime) manipüle ettim. İşte o meşhur bypass script'inin mantığı (zararsızlaştırılmış/pseudo-code):
// Frida script to bypass SSL Pinning
Java.perform(function () {
var array_list = Java.use("java.util.ArrayList");
var ApiClient = Java.use("com.testcompany.app.network.ApiClient");
ApiClient.checkServerTrusted.implementation = function (chain, authType) {
// Fonksiyon çağrıldığında hiçbir şey yapma ve hatasız dön
console.log("[+] SSL Pinning bypassed for: " + chain[0]);
return;
};
});
Bu script'i frida -U -f com.testcompany.app -l bypass.js --no-pause komutuyla çalıştırdığımda, uygulamanın tüm o "güvenli" HTTPS trafiği Burp Suite ekranıma 'clear-text' olarak düşmeye başladı. SSL Pinning bir mermi geçirmez yelek değil, sadece bir hız tümseğidir.
SQLite ve Saklanan Sırlar
Analize devam ederken uygulamanın yerel veri depolama alışkanlıklarına baktım. /data/data/com.testcompany.app/databases/ dizininde bir SQLite veritabanı vardı. Çoğu geliştirici "Burası zaten root olmayan kullanıcılar tarafından görülemez" yanılgısına düşüyor. Ancak bir zararlı yazılım telefonunuza bulaştığında veya fiziksel erişim sağlandığında (telefonu tamire verdiğinizi düşünün), o veriler artık sizin değildir.
SQLite içindeki UserSession tablosunda access_token değerinin düz metin olarak saklandığını gördüm. Eğer bir saldırgan bu token'ı ele geçirirse, kullanıcının parolasını bilmesine gerek kalmadan hesabı devralabilir (Account Takeover).
Doğru yaklaşım ne olmalıydı?
Android tarafında EncryptedSharedPreferences veya iOS tarafında Keychain kullanarak bu verileri donanımsal destekli (Keystore/Secure Enclave) şifrelemek şart.
JavaScript Bridge: Webview'un İhaneti
Mobil uygulamalar artık sadece native koddan oluşmuyor. İçinde hibrit kısımlar, Webview'lar barındırıyor. testCompany uygulamasında bir addJavascriptInterface kullanımı fark ettim. Bu, Java kodundaki bir nesneyi Webview içindeki JavaScript dünyasına açar. Eğer bu arayüz kontrolsüz bırakılırsa ve Webview içine yüklenen içerik (örneğin bir reklam banner'ı veya XSS zafiyeti olan bir dış site) manipüle edilirse, saldırgan JavaScript üzerinden telefonun kamerasına erişebilir, SMS'leri okuyabilir.
// Tehlikeli kullanım örneği
webView.addJavascriptInterface(new MyInsecureJSInterface(), "AndroidNative");
Bu kod satırı, Webview içindeki herhangi bir JS kodunun AndroidNative.doSomething() diyerek sistem fonksiyonlarına erişmesine kapı açar. Özellikle Android 4.2 altındaki cihazlarda bu durum doğrudan 'Remote Code Execution' (RCE) demektir.
Defans Hattı: Neler Yapmalıyız?
Sabahın 5'ine doğru gelirken bulduğum tüm bu açıkları raporlamaya başladım. Peki, bu kaostan nasıl kurtuluruz? İşte sahada tecrübe ettiğimiz altın kurallar:
- Kod Karartma (Obfuscation): R8 veya ProGuard sadece uygulama boyutunu küçültmek için değil, kodun tersine mühendislik aşamasını zorlaştırmak içindir. Anlamlı fonksiyon isimlerini (örn:
performPayment) anlamsız karakterlere (örn:a()) dönüştürün. - Sertifika Sabitleme (Certificate Pinning) + CT: Sadece sertifikayı değil, 'Public Key'i pinleyin ve mutlaka 'Certificate Transparency' loglarını kontrol edin.
- Güvenli Depolama: Hassas verileri asla
SharedPreferencesiçinde düz metin tutmayın. SQLCipher veya EncryptedSharedPreferences kullanın. - Runtime Integrity Checks: Uygulama çalışma anında kendi bütünlüğünü kontrol etmeli. Root/Jailbreak tespiti, emülatör kontrolü ve debugger tespiti gibi 'anti-tampering' mekanizmaları kurun. (Tabii bunların da bypass edilebileceğini bilerek, sunucu tarafında da kontrolleri sıkı tutun).
- Deep Link Doğrulaması: Android tarafında
App Links, iOS tarafındaUniversal Linkskullanarak domain doğrulaması yapın. URL parametrelerini asla birer komut gibi çalıştırmayın.
O gece o açığı bulup kapatmasaydık, testCompany ertesi gün binlerce kullanıcısının verisini kaptırabilirdi. Mobil güvenlik, sadece bir uygulama yazıp markete yüklemek değildir; o uygulamanın her bir byte'ının düşman elinde bir silaha dönüşebileceğini bilmektir.
Şimdi kahvemi tazeleyip bir sonraki APK'nın içine dalma vakti. Güvende kalın, derinlikte saklıdır, unutmayın.
