Beetlebug, içerisinde android uygulama güvenliği ile ilgili konuları içeren zafiyetli bir android CTF uygulamasıdır. Uygulama açıldığında bir kullanıcı ismi girerek uygulamaya giriş yapılabilir. Toplamda 16 adet flag değeri bulunmaktadır.
Güvenlik açıklarının bukunduğu başlıklar,
- Hardcoded secrets (Kodlanmış hassas bilgiler)
- Insecure Data Storage (Güvenli olmayan depolama)
- Sensitive Information Disclosure (Hassas bilgi ifşası)
- Vulnerable Android IPC Components (Zafiyetli processler arası iletişim bileşenleri, alıcılar,servisler ve içerik sağlayıcıları)
- Vulnerable Webviews (Zafiyetli webview)
- Insecure Deeplinks (Gğvenli olmayan deeplinkler)
- sqli, xss
- Authentication bypass
- Firebase misconfiguration
Gizli dosyaya erişebilmek için PIN değeri girilmesi gerekmektedir. Verilen ipucunda, string kaynaklarına bakılması öneriliyor.
jadx-gui ile apk uygulama dosyasını açıyoruz. Hangi aktivitenin ilk challange ait olduğunu ilk başta anlamayabiliriz.Burada res/value dizininin içerisindeki strings.xml dosyası incelendiğinde listelenen ilk değer dikkatimizi çekebilir.
genel bir arama yaparsak,
ilgili ekranın EmbeddedSecretStrings isimli aktivite olduğu anlaşılabilir. Aktivite içerisindeki kodlar incelendiğinde burada kullanıcıdan alınan girdi, PIN değeri ile eşit olup olmadığı koşulu bulunmaktadır. Buradaki karşılaştırılan string değeri (R.string.V98bFQrpGkDJ
) istenen PIN değeridir.
Bulduğumuz PIN değerini girdiğimiz zaman ilk flag değerini bulmuş oluyoruz.
Bu challange içerisinde hassas bilgilerin açık metin şekilde kodlanmasını içermektedir. Burada promosyon kodunu bulmamız gerekiyor.
jadx-gui aracını kullanarak kaynak kod incelemesinde, EmbeddedSecretSourceCode isimli aktiviteyi inceliyoruz. Promosyon kodu direkt olarak, değer şeklinde tanımlanmış durumda.
Bulunan kod girildiğinde flag değeri elde edilmiş oluyor.
Shared Preferences yapısı anahtar-değer(key-value) şeklinde küçük verileri depolamak için kullanılır.Verileri /data/data/paket_ismi/shared_prefs dizini altında bir xml dosyasına kaydeder. Burada kullanıcı adı ve parola girilmesi istenmektedir.
Bilgiler girdikten sonra Save butonuna kaydedildiğinde ekranın alt kısmında flag değeri için submit butonu ortaya çıkmaktadır.
Terminal üzerinden adb shell
komutunu kullanarak cihaz üzerine bağlanabiliriz. /data/data dizini altında ilgili uygulama paketine giderek shared_prefs klasörü içerisinde shared_pref_flag isimli xml dosya içeriği görüntülendiğinde girilen kullanıcı ve parola değerlerinin yanı sıra flag değeri de depolanmaktadır.
Burada mail adresi ve parolayı kaydettiğimiz zaman ekranda bir toast mesajı belirmektedir. Verilerin saklandığı dosya yolu ve dosya ismi verilmiştir. Terminal üzerinden cihaza adb shell
komutu ile erişim sağlanmaktadır.
Diğer bir yolda ise InsecureStorageExternal aktivite kaynak kodları incelenebilir ve girilen bilgilerin kaydedildiği bölüm bulunur. Flag değeri açık metin olarak verildiğini görebiliriz.
Herhangi bir parola değeri girdiğimiz zaman flag submit butonu belirmektedir. Burada ilgili aktivite InsecureStorageSQLite. jadx-gui aracı ile kaynak kodu incelendiğinde girilen parola ve flag değerleri kaydedilmektedir. Flag değeri sqlite_string isimli string kaynağıdır.
resource olarak arama yaparsak string.xml dosyasının içerisinde flag değerine erişmiş oluruz.
Bir diğer yöntem parolanın saklandığı dosyayı incelemek olacaktır (girilen hassas bilgi şifrelenmeden açık metin olarak kaydedilmişse bu güvenli olmayan bir yöntemdir), kod içerisinde bulunan parola doğrulama fonksiyonunda belirtilen regex gösterimine uygun karmaşık parola değeri girildiğinde Password Saved mesajı ekranda gösterilmektedir.
adb shell
ile cihaza erişim sağlandığında /data/data dizini altında ilgili uygulama paketine gidilir.
burada listelenen databases dizini altında uygulamaya ait veritabanı bulunmaktadır. sqlite3 user.db
komutunu kullanarak veritabanına erişilir. .tables
içerisindeki tablolar listelenir ve SELECT * FROM users
sql querysi ile tablodaki veriler listelenmektedir. Listelenen değer girilen_parola | flag_degeri şeklinde kaydedilmiştir. Yukarıda incelenen kaynak kod içerisinde de bu şekilde kaydedildiğini görmüştük.
Webview, uygulama içerisinde kullanıcıya web içeriklerini iletmek için kullanılan objeler olarak kulllanılır.
AndroidManifest dosyası içerisinde VulnerablaWebView aktivitesinin export edilmiş olduğu görülmektedir.
Burada aktivite içerisindeki kodlar incelendiğinde, loadWebView()
fonksiyonu içerisinde ilgili intent içerisinde gelen string ile url bağlantısını gerçekleştiriyor[1]. Basitçe bir intent yardımıyla uygulamada çalışacak bir url stringi gönderiliyor.
Verilen ipucunda, adb
ile zararlı sayfayı uygulama içerisinde açılabileceği belirtiliyor. adb shell
komutu ile cihazda shell açtıktan sonra am start
( am = activity manager) komutununu kullanarak export edilmiş aktivite dışarıdan veya uygulamadan bağımsız olarak başlatılabilmektedir. -n
parametresine paket_ismi / aktivite_yolu olarak değerler verilmektedir. -es
parametresi extra değerler (getStringExtra(), getExtra() vs. ) için kullanılmaktadır. reg_url verilen url değerine bağlantı gerçekleştirilir.
am start -n app.beetlebug/.ctf.VulnerableWebView -es reg_url "malicious.site"
Yukarıdaki komutu çalıştırdıktan sonra uygulama içerisinde bağlantı adresine ait sayfanın açıldığı gözlemlenmektedir. Örneğin google.com adresini girdiğimiz zaman, uygulama görüntüsü şekildeki gibidir.
Burada istenen flag değeri kod içerisinde de görüldüğü gibi file:///android_asset/pwn.html
sayfasının içerisinde bulunmaktadır. (Güncelleme aktif olarak verilen bağlantı adresinde görsel bulunmuyor)
Bu yöntem intent-filter yardımıyla export edilmiş bileşenler için çalışmayabilir. Aktivitenin direkt olarak exported edilmiş olması gerekir (androd:exported= true şeklinde).
Bu bölümde, javascript kodu çalıştırarak XSS zafiyetini kullanarak flag değerini elde edeceğiz. Basit bir şekilde <script>alert("XSS");</script>
payload kullanılabilir.
Açılan pop-up mesajı kapattıktan sonra flag değerine erişebiliyoruz.
jadx ile SQLInjectionActivity kodları incelendiğinde aktivite içerisinde direkt olarak veritabanı oluşturulup, kullanıcıların manuel şekilde açık metin olarak eklendiği görülmektedir.
Normalde diğer uygulamalar veya zararlı yazılımlarda okunur durumda olmayabilir. Kod obfuscated edilmiş olabilir veya verilen değerler encoded olabilir. Bu yüzden başka bir yoldan soruyu çözmeye çalışalım.
Burada, input olarak girilen değer, direkt olarak SQL sorgusu içerisine eklenmektedir. Bu durum sayesinde input olarak başka sorgular çalıştırılabilmektedir.
WHERE user = '"
kısmında eşitliğin sağlanması durumunda kullanıcı bilgileri çıktı olarak verilmektedir. Burada kendi payloadımızı da oluşturabiliriz veya internetten de bulup kullanabiliriz[2].
input değere ' or '1
payloadı girildiği zaman kullanıcılar listelenmektedir. beetle-bug kullanıcısı flag değerini içermektedir.
Firebase veritabanının yanlış konfigure edilmesi kullanıcı bilgilerinin açığa çıkması ve yetkisiz erişimlere sebebiyet verebilir. Burada ilk kontrol edilecek kısım strings.xml dosyası olabilir. Çünkü burada yanlışlıkla bırakılmış bağlantı adresleri, api anahtarları ve token değerleri olabilir.
Bulduğumuz firebase proje adresini ipucunda da verilmiş olan /.json dizinine göz atalım.
yapılan ayarları erişim bilgileri ve diğer hassas bilgilere erişim sağlanabildi. Eğer doğru bir şekilde yapılandırılsaydı içeriği görme iznine sahip olunmazdı ve "Permission Denied" hatası verebilir veya null olarak görülebilirdi. Firebase veritabanı enumeration ve keşif aşaması için çeşitli araçlar kullanılmaktadır [3].
Login butonuna tıklandığında başka ekrana yönlendiren ve export edilmiş aktivite gerekli olduğu ipucu olarak verilmiş. Burada adb
komutu ile export edilmiş aktivite başlatılabilmektedir. Farklı araçlar da kullanılabilir.
AndroidManifest dosyası içerisinde export edilmiş ilgili aktiviteyi araştıralım. b33tlebugAdministrator
isimli bir aktivite var.
adb shell am start -n app.beetlebug/.ctf.b33tleAdministrator
komutunu çalıştırıyoruz
Admin paneli ekranı içerisinde en alt kısımda flag değeri bulunmaktadır. b33tlebugAdministrator aktivitesi exported olduğu için uygulamanın akışından bağımsız çalıştırarak farklı bölümlere erişim sağlayabiliyoruz.
Servis bileşeni arkaplanda çalışan bir arayüze sahip olmayan programlardır. Başka uygulamalar tarafından çağrılabilir, dışarıdan erişilebilir özelliklerine sahiptir. Yanlış kullanımı zafiyetlere yol açabilir. exported özelliği aktif halde olması uygulama dışından da erişilebileceğini belirtir.
adb shell am startservice -n app.beetlebug/.handlers.VulnerableService
komutu ile komut ekranından servisi başlatabiliriz.
Content provider (içerik sağlayıcısı), uygulamalar arası veri paylaşımını sağlar, erişim kontrollerinin yapıldığı yer olarak belirtilebilir. Paketin ismini öğrendikten sonra dumpsys
ile sağlayıcılar listelenebilir.
Manifest dosyası içerisinden de görülebilir bu bileşenler.
Bu bileşenin içeriğinde URL bağlantısı verilmiş
adb shell ile cihazın terminaline eriştikten sonra content query --uri content://CONTENT_URL
şeklinde paylaşılan veriler görülebiliyor.
Bu işlemi otomatik gerçekleştiren araçlar ile de yapabiliriz. Drozer bunlardan bir tanesi [4]
Çalışan uygulamnın kayıtlarını adb logcat
komutu ile inceleyebiliriz. Bu kayıtlara erişim olduğundan içerisinde hassas bilgilerin bulunması bilgi ifşasına yol açmaktadır. Bu senaryoda kredi kart bilgilerinin girilerek ödeme yapılması istenmektedir.
Bilgiler girilip, öde butonuna tıklandığında gösterilen kayıtlar içerisinde girilmiş kart bilgisi de yer almaktadır.
Android 9 ve altı sürümlerde pano verilerine tam erişime izin veriliyordu. Android 10 ile birlikte pano verilerine erişim kısıtı geldi.
- https://medium.com/mobis3c/exploiting-android-webview-vulnerabilities-e2bcff780892
- https://github.com/payloadbox/sql-injection-payload-list
- https://cloud.hacktricks.xyz/pentesting-cloud/gcp-security/gcp-services/gcp-firebase-enum
- https://book.hacktricks.xyz/mobile-pentesting/android-app-pentesting/drozer-tutorial/exploiting-content-providers