Bilishim Cyber Security & Artificial Intelligence
ARGE

Flutter’da Trafik Dinleme ve Güvenlik Önlemlerini Atlatma

Suleyman Erdem
#mobil#flutter#pentest

Merhaba! Bu yazımızda bir mobil uygulamayı penteste hazırlayacağız. Bu işlemler, güvenlik önlemlerini atlatmak (frida tespiti, root tespiti vs.) ve uygulama trafiğini proxy araclığıyla dinlemek olarak iki bölüme ayrılacak.

Araçlar ve Cihazlar:

Öncelikle uygulamamızı cihaza indiriyoruz ve uygulamanın root tespiti yapma ihtimaline karşın Magisk üzerinden Shamiko modülünü aktif ediyoruz. (bkz. https://www.technopat.net/sosyal/konu/shamiko-ile-root-gizleme.2159998/)

Magisk Reddetme Listesi

Magisk Reddetme Listesi.

Sonrasında adb üzerinden cihaza bağlanıp frida-server’ı çalıştırıyoruz ve uygulamamızı açıyoruz. Bunu yapmamızdaki amaç uygulamanın frida ve debugging tespiti yapıp yapmadığını anlamak.

adb shell

adb shell

Ancak uygulamanın siyah ekranda kalıp bir süre sonra da kapandığını görüyoruz ve uygulamanın frida veya debugging tespiti yaptığını anlıyoruz. Bu aşamada, apk dosyası üzerinde tersine mühendislik yaparak kaynak kodlarını incelememizi sağlayan Jadx GUI uygulamasını kullanmalıyız.

Jadx GUI ile string arama

Jadx GUI ile string arama

Jadx GUI’da apk dosyamızı açıp arama barına “frida” yazıyoruz ve incelememiz gereken t5.b ve t5.c sınıfları karşımıza çıkıyor.

t5.b.n metodu

t5.b.n metodu

t5.c.a metodu

t5.c.a metodu

Sınıfları inceledikten sonra t5.b.n ve t5.c.a metodlarının, frida string ve port tespiti yaptığını görüyoruz. Şimdi sıra bu metodları hooklayacak (yani metodların içeriğindeki kodu çalıştırmak yerine bizim istediğimiz kodu çalıştıracak) bir frida script yazmaya geldi. Ek olarak LLM’ler (ChatGPT, DeepSeek vs.), doğru kod parçasını tespit ettiğiniz takdirde bu scriptleri yazdırmak konusunda çok işlevsellerdir.

frida script

frida script

Bu scriptte 3 ayrı try/catch bloğu bulunur. İşlevleri:

İlk blok, TLS sertifikasını doğrulamak için kullanılır. Hook işlemi sayesinde uygulamanın sunucu sertifikasını geçerli olarak görmesi sağlanıyor, yani pinning etkisiz hâle geliyor. Şimdi uygulamayı, yazdığımız script enjekte ederek başlatalım. Bu sayede ilk denemede uygulamanın açılmasını engelleyen fonksiyonlar etkisiz hale gelecek ve SSL pinning bypass’ın başarılı olup olmadığını göreceğiz.

frida -U -f <paket_adı> -l .\frida_script.js

frida -U -f -l .\frida_script.js

Uygulamamız bu sefer sorunsuz açıldı. Giriş yapalım ve istek proxy’e düşüyor mu bakalım.

SSL Pinning Bypass başarısız

SSL Pinning Bypass başarısız

Proxy’de herhangi bir istek görünmedi yani SSL pinning bypass denememiz başarısız oldu. Burada daha önce edindiğim tecrübelere dayanarak uygulamanın Flutter ile yazılmış olma ihtimalinden şüpheleniyorum. Bunu anlamak için tekrar Jadx’e dönüp kaynak kodu incelemeliyiz.

Press enter or click to view image in full size

Resouces içinde flutter_assets yer alıyor

Resouces içinde flutter_assets yer alıyor

Resources altında flutter_assets klasörünü görüyoruz yani evet, uygulama Flutter ile geliştirilmiş. Klasik Android uygulamalarında SSL pinning’i Frida ile TrustManager ya da SSLContext sınıflarını hook’layarak bypass edebiliyoruz. Ancak Flutter uygulamaları Dart ile yazıldığı için bu yöntemler doğrudan işe yaramıyor.

Uygulamanın HTTPS bağlantıları Dart tarafındaki HttpClient sınıfı üzerinden sağlandığı için, Flutter’a özgü bir analiz ve hook yaklaşımı gerekiyor. Biz bu senaryoda, Java tarafında bir TrustManagerImpl hook’lamamıza rağmen trafiği yakalayamadık. Bu da pinning’in Dart veya C++ seviyesinde yapıldığını gösterdi.

Bu yüzden Flutter uygulamalarında pinning bypass için yazılmış TheDauntless/disable-flutter-tls-v1 scriptini kullanacağız ancak bu durumda çalıştırmamız gereken 2 tane scriptimiz oldu. 2 scripti birleştirip tek script çalıştırmak da mümkündür ancak daha zahmetsiz bir yöntem tercih edeceğiz. Önce uygulamayı kendi yazdığımız script ile çalıştıracağız, sonra uygulamanın PID’sini (process numarası) alacağız ve son olarak Flutter scriptini bu PID’ye attach edeceğiz.

Flutter uygulamaları bazen sistem proxy ayarlarını görmezden gelebilir. Bu nedenle uygulamanın trafiğini yönlendirmek için uygulama seviyesinde değil, sistem düzeyinde bir proxy çözümüne ihtiyaç duyduk. Bu nokta ProxyDroid aracı bu ihtiyacımızı global proxy konfigürasyonu oluşturarak çözüyor.

ProxyDroid üzerinden cihaz trafiğini Burp kurulu makinemize yönlendiriyoruz.

ProxyDroid üzerinden cihaz trafiğini Burp kurulu makinemize yönlendiriyoruz.

Kendi scriptimiz ile çalıştırdık.

Kendi scriptimiz ile çalıştırdık.

frida-ps -U | findstr <uygulama_adı> ile PID bulduk.

frida-ps -U | findstr ile PID bulduk.

Aldığımız PID’yi kullanarak flutter scriptini attach ettik.

Aldığımız PID’yi kullanarak flutter scriptini attach ettik.

Yukarıdaki işlemleri tamamladıktan sonra flutter scriptinin SSL pinning’i patch’lediğini görüyoruz. Şimdi tekrar giriş işlemi yapıp isteği proxy’de görüp göremediğimize bakalım.

Sonunda istek proxy’e düştü!

Sonunda istek proxy’e düştü!

Sonunda istediğimiz sonuca ulaştık, uygulama trafiğini Burp üzerinden görebiliyoruz. Artık teste başlayabiliriz!

← Blog