Teknik Araştırma

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi?

Bu yazıda, DJI Fly uygulamasında tespit ettiğimiz bir deep link zafiyetini ve bunun drone pilotunun token, email, konum ve cihaz bilgilerinin…

SCNX Team5 dk okuma

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi?

Özet

Bu yazıda, DJI Fly uygulamasında tespit ettiğimiz bir deep link zafiyetini ve bunun drone pilotunun token, email, konum ve cihaz bilgilerinin sızdırılmasına nasıl yol açtığını anlattık. Dışarıdan tetiklenebilen exported bir Activity, gelen URL'yi hiçbir doğrulamaya sokmadan WebView içinde açıyor. Uygulamanın kendi kimlik doğrulama akışlarında kullandığı email ve token bilgileri hatalı fallback mekanizması yüzünden saldırgan sunucusuna sızıyor. Bunun da üstüne hiçbir kontrole sokulmadan pilotun konum ve cihaz bilgileri bir Javascript fonksiyonuna verilince pilot konumunun bir link aracılığı ile sızdırılması kaçınılmaz oluyor.

I. Sızıntı - Pilotun Token ve Email Bilgileri

Mobil uygulamalar, diğer uygulamalarla iletişimde kalmak için sık sık deep link kullanma yoluna giderler. Bu deep linkler, dışarıdan gelen veriyi mobil uygulamaya ileterek kullanıcı için bir akış başlatır. İncelediğimiz uygulamada, bir deep link şeması ile DJI Fly uygulaması içerisinde bir WebView akışı başlatıldığı ve yanlış yapılandırmaların üst üste binmesi sonucu kullanıcının anlık konum bilgisinin dahi sızdırılabildiği bir senaryo ile karşılaştık.

Uygulamanın AndroidManifest.xml dosyasını incelediğimizde SchemeUrlActivity isimli bir bileşenin BROWSABLE ve exported=true nitelikleriyle tanımlı olduğunu tespit ettik ve odağımızı bu bileşen üzerinde yoğunlaştırdık. Bu iki niteliğin bir arada bulunması, bileşenin yalnızca uygulamanın kendi içinden değil; cihazdaki başka herhangi bir uygulamadan, hatta bir web sunucusunun yönlendirmesiyle dahi tetiklenebileceği anlamına gelmektedir.

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

SchemeUrlActivity sınıfını incelediğimizde parseData metoduyla deep link path’i ve “url” parametresi daha sonra hiçbir kontrole sokulmadan LinkApiRouter çağrısına verilmekteydi.

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseliBir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

LinkApiRouter sınıfının içerisinde, gelen path’i çözümleyen bir enum olduğunu tespit ettik. Enum, gelen path'i v1WebviewPage, v2WebviewPage, openNativePage veya unknown değerlerinden birine çözümlüyordu. Bu sınıfta yalnızca ilk ikisi gerçekten bir WebView’a yönleniyordu.

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

LinkApiRouter kodları incelendiğinde path çözümleniyor ve v1WebviewPage iletilmesi durumunda m160896i ile belirtilen metod çağırılıyor. Bu metodun da IWebviewComponent bileşenini doldurarak UAVSupportShareWebviewActivity activity’sini başlattığını gözlemledik.

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseliBir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseliBir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

UAVSupportShareWebviewActivity activity’si başlatılırken bir bundle oluşturup daha sonra WebView’a vereceği bilgileri bu bundle içerisine yerleştirdi ve UAVSupportShareWebviewFragment adında bir fragment oluşturdu.

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseliBir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

Daha sonra fragment’in oluşmasıyla tetiklenen createView metoduyla loadUrl() çağrısı başlatıldı. Burada en başta deep link parametresi olarak verdiğimiz url, daha sonra kullanılmak üzere set ediliyordu.

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseliBir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseliBir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

Akış devam ettirildiğinde loadWebPage() metodunun içerisinde convertRequestUrlForLogin() metodunun çağırıldığını gördük ve bunu incelemeye başladık. Bu metod, kullanıcının oturum token'ını ve deeplink ile gelen url'i IAccountCenterService üzerinden backend'e gönderiyor.

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseliBir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

UAVAccountCenterService incelendiğinde getToken() ve verilen url, NetworkServices üzerinden sunucuya iletiliyor ve karşılığında bir "login auth URL" bekleniyor. Biz bu testte DJI'a ait olmayan harici bir domain verdiğimiz için, sunucunun bu domain için bir "share session" / auth URL üretmesi beklenmiyor; dolayısıyla akış hata callback'ine düşüyor.

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

Hata callback'i UAVWebBaseFragment'te işleniyor ve doğrudan loadPageByOldWay()'i çağırıyor:

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

Bu noktada kritik olan şey, backend hiçbir URL üretmediği için mHostUrl'in değişmeden kalması. Fragment, bizim deep link ile verdiğimiz orijinal URL'yi olduğu gibi kullanmaya devam ediyor.

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

Fragment kodları incelenmeye devam edildiğinde sayfa yüklemeden hemen önce kritik bir durumla karşılaşıyoruz: Uygulama, istemcide hiçbir kontrol yapmadan WebView’a gitmeden önce token, email ve dil değerlerini bir şablona göre dolduruyor ve URL’ye yerleştiriyor.

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseliBir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseliBir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

Bu durumu doğrulamak amacıyla şablonları içeren bir deep link tetikliyoruz ve aşağıdaki sonucu alıyoruz:

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

II. Sızıntı - Pilotun Anlık Konum ve Cihaz Bilgileri

Bu noktada kullanıcının token, email ve dil bilgilerine sadece bir WebView başlatarak ulaşabiliyoruz. Araştırmaya devam ettiğimizde WebView’ın hangi yetkilerle başlatıldığını ve herhangi bir Javascript interface eklenip eklenmediğini tespit ediyoruz.

WebView fragment’inin ve onun base sınıfının initWebView metodunda şu bilgileri elde ediyoruz:

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseliBir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseliBir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

Üzerinde çalıştığımız WebView’da javascript çalıştırabiliyoruz, bir javascript köprüsüne erişebiliyoruz fakat dosyalara erişemiyoruz. Araştırmaya devam ettiğimizde shouldOverrideUrlLoading içerisinde bir handleCommonPageInit metodunun çağırıldığını gözlemliyoruz. Bu metod incelendiğinde uygulamaya özel bir kod bloğuyla karşılaşıyoruz:

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseliBir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseliBir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

Uygulama, WebView yeni bir URL’yi ziyaret ettiği sırada “cb” parametresiyle gelen bir fonksiyona uygulamayı kullanan drone pilotunun koordinat bilgilerini olduğu gibi basıyor.

Son olarak elde ettiğimiz bütün bu bilgilerle birlikte bir web sunucusuna hazırladığımız scripti yerleştirdik. İlk adımda, siteyi ziyaret eden kişi bir deep link’e yönlendiriliyor ve uygulama üzerinde bir WebView açılıyor. İkinci adımda, bu yüklenen WebView hazırladığımız javascript kodunu çalıştırıyor ve “cb” parametresine bir fonksiyon ismi vererek yeni bir sayfaya yönlendiriyor. Bu adımla birlikte shouldOverrideUrlLoading içerisindeki handleCommonPageInit metodu çalışıyor ve bizim belirlediğimiz fonksiyon, pilotun konum bilgileri de dahil olmak üzere hassas bilgiler ile çağırılıyor.

Sonuç

Bu yazıda, DJI Fly mobil uygulamasının (drone pilotlarının uçuşu yönetmek ve kontrol etmek için kullandığı birincil uygulama) deep link işleme mekanizmasında, kullanıcı etkileşimini minimum düzeye indiren ve hassas veri sızıntısına yol açan bir güvenlik açığı incelenmiştir. Bulgular, uygulamanın harici kaynaklardan gelen bir bağlantıyı karşılayıp bunu bir WebView bileşenine yönlendiren işlem zincirinde, girdi doğrulamasının yetersiz kaldığı iki ayrı noktayı ortaya koymaktadır.

İlk olarak, uygulamanın harici bir URL'yi işlerken, kimlik doğrulama amacıyla kullanılan belirli şablon ifadeleri, hedef alan adının güvenilirliği doğrulanmadan pilotun oturum verileriyle değiştirmekte olduğu görülmüştür. Bu durum, saldırganın kontrolündeki bir adrese yönlendirme yapıldığında, pilotun kimlik doğrulama bilgilerinin bu adrese iletilmesine imkân tanımaktadır.

Daha önemlisi, uygulamanın WebView bileşeninde, her türlü sayfa içi yönlendirme olayında koşulsuz olarak tetiklenen ve dışarıdan gelen bir parametreyi herhangi bir kısıtlama uygulamadan JavaScript ortamına ileten bir işlev tanımlanmıştır. Bu işlev aracılığıyla iletilen veri kümesi, pilotun oturum kimlik bilgilerini, cihaz tanımlayıcısını ve pilotun o anda bulunduğu konuma ait verileri içermektedir. Bir saldırgan, kontrolündeki bir web sayfasını bu mekanizmayla uyumlu şekilde tasarladığında, pilotun yalnızca kötü amaçlı bağlantıya tıklaması, herhangi bir ek onay veya etkileşim gerekmeden söz konusu verilerin saldırgana iletilmesiyle sonuçlanmaktadır.

Bu bulgunun önemi, istismar sürecinin düşük karmaşıklığından kaynaklanmaktadır: saldırı, pilotun tek bir bağlantıya tıklamasıyla tamamlanabilmekte, ayrıca bir izin talebi, dosya sistemi erişimi veya ikinci bir kullanıcı eylemi gerektirmemektedir. Bu özellik, açığı klasik kimlik avı veya kötü amaçlı yazılım senaryolarından ayırmakta ve kimlik doğrulama token'ı ile konum verisinin eşzamanlı sızıntısı nedeniyle hem hesap ele geçirme hem de pilotun gizliliğinin ihlali bakımından yüksek etkili bir tehdit oluşturmaktadır.

Aşağıdaki görüntü, bağlantının DJI Fly içinde açıldığı ve pilot bilgilerinin karşı tarafa ulaştığı anı gösteriyor.

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

Referanslar

Bir Link ile Drone Pilotunun Konum Bilgisi Nasıl Ele Geçirildi? içerik görseli

Red Team ve sızma testi

Teknik makalelerimizdeki saldırı senaryolarını kurumunuzda güvenli ortamda test edin.

Referanslar

Müşteri Portföyümüz