Xamarin Android/iOS Güvenlik Önlemleri

Merhaba,

Geliştirdiğimiz uygulamalarda ilk dikkat ettiğimiz noktaları özetleyecek olursak genelde kod kalitesi ve sonradan geliştirilebilirlik kavramları oluyor. Fakat mobil uygulamalarda kesinlikle atlamamamız gereken çok kesin bir nokta var o da güvenlik.

Kodlarımızın bazı yöntemlerle elde edilememesi ve uygulamalarımızın root/jailbreak işlemleri yapılmış cihazlarda çalıştırılamaması gibi yöntemleri de düşünmeliyiz.

Mobil Uygulama Kaynak Kodunun Elde Edilebilmesi

Tersine mühendislik bir aygıtın, objenin veya sistemin yapısının, işlevinin veya çalışmasının, çıkarımcı bir akıl yürütme analiziyle keşfedilmesi işlemidir. Bir Android uygulamasını herhangi bir sıkıştırma programı ile açtığımızda içerisinde;

  • Meta-InfClass
  • Resorce
  • AndroidManifest
  • Res
  • class.dex

dosyalarını ve dizinlerini barındırdığı görülür. Burada classes.dex: Dalvik sanal makinesi tarafından anlaşılabilir dex dosya biçiminde derlenmiş dosyadır. Saldırgan tersine mühendislik adımlarını izleyerek uygulamayı yerel ortamında analiz edebilir.

Çözüm Önerisi

Kaynak koda erişimi zorlaştırmak için kod karmaşıklaştırma yöntemlerinin geliştirme aşamasında uygulanması önerilmektedir.
Karmaşıklaştırma yöntemi olarak ProGuard vb. araçlar kullanılabilir.

Referanslar

https://www.owasp.org/index.php/OWASP_Reverse_Engineering_and_Code_Modification_Prevention_Project

https://www.guardsquare.com/en/proguard

Android uygulamalarınızda APK çıktı alırken, Android Options kısmından Proguard işlevini aktif hale getirebilirsiniz.

Verilerin Yedeklenebilir Olması

Uygulama verilerinin USB yardımıyla yedeklenememesi gerekmektedir.

Çözüm Önerisi

AndroidManifest.xml içerisindeki application tag’ine android:allowBackup=”false” eklenir.

<application android:label=”ApplicationName” android:allowBackup=”false”>

Root/Jailbreak Tespiti Yapılmaması

Jailbreak işlemi gerçekleştirilmemiş bir Apple cihazına App Store’da yer almayan bir uygulamayı yüklemek ya da cihazın sistem dosyalarına erişmek mümkün değildir. (Kendi uygulamalarımızı test etmek için iTunes üzerinden yüklemeler yapabiliyorduk. Apple Developer sertifikamızla .ipa dosyasını çıkarttığımız için sorun olmuyordu. Fakat iTunes son versiyonlarında bunu kaldırdı. Çünkü Apple tarafından güvenli ve doğru bir yöntem olarak düşünülmüyor.) Bu nedenle Jailbreak ve Root, mobil cihazlar için kullanılan işletim sisteminin dayattığı kısıtları aşmak ve güvenlik yöntemlerinin atlatılmasını sağlayan yöntemler olarak bilinmektedir.

Çözüm Önerisi

Mobil uygulama, üzerinde çalıştığı mobil cihazın root/jailbreak’li olup olmadığının tespit edebilmelidir.

Referanslar

https://www.owasp.org/index.php/Mobile_Jailbreaking_Cheat_Sheet

http://resources.infosecinstitute.com/ios-application-security-part-23-jailbreak-detection-evasion/

https://www.trustwave.com/Resources/SpiderLabs-Blog/Jailbreak-Detection-Methods/

Android Root

Bir cihazın rootlu olduğunu anlayabilmek için temel olarak 3 yöntem kullanılabilir;

  1. “Su” komutunun başarılı olup olmadığını kontrol edin
  2. “/system/app/Superuser.apk” dosyasının var olup olmadığını kontrol edin
  3. OS sisteminin test keys ile oluşturulup oluşturulmadığını kontrol edin

Execute “su” command

İlk yöntem, uygulamanın bulunduğu ortamın GetRuntime () işlevini çağırarak ve “su” komutunu
göndererek bir singleton örneği elde ederek ortamın arayüzü oluşturmuştur.

 private bool CanExecuteSuCommand()
 {
    try
    {
      Java.Lang.Runtime.GetRuntime().Exec("su");
      return true;
    }
    catch (Exception ex)
    {
      return false;
    }
 }

Check for apk

Superuser uygulaması

Dosyanın var olup olmadığını kontrol etmek için dosyanın bu gösterimi için arama yapılır.


private bool HasSuperApk()
{
   return new Java.IO.File("/system/app/Superuser.apk").Exists();
}

OS built with test-keys

Bir sistem özellikleri dosyasından (/system/build.prop) işletim sistemi oluşturma bilgisini çıkarır.
Ayıklanan build tag bilgileri ” test-keys ” için aranır ve build tag bilgilerinde ” test-keys ” bulunursa,
komut başarılı olarak belirlenir.

private bool IsTestKeyBuild()
{
   string str = Build.Tags;
   if ((str != null) && (str.Contains("test-keys")))
       return true;
   return false;
}

Eğer bu üç test sonucundan herhangi biri başarılı olursa, cihazın rootlu olduğu kararına varılır.

//MainActivity OnCreate
private void CheckForRoot()
{
    if (CanExecuteSuCommand() || HasSuperApk() || IsTestKeyBuild())
    {
       //Eğer rootlu bir cihaz uygulamanızı yüklediyse, uygulamanızı kapatabilirsiniz.
       Process.KillProcess(Process.MyPid());
    }
}

iOS JAILBREAK

Jailbroken’lı bir cihaza birçok uygulama ve dosya yüklenir. Dosya sistemindeki bu dosyaların kontrol edilmesi, cihazın jailbroken olup olmadığını tespit etmemize yardımcı olabilir. Örneğin, jailbreak yazılımlarının çoğu, jailbreak’ten sonra Cydia’yı cihaza yükler. Bu nedenle, Cydia için basit bir file path kontrol, cihazın jailbroken olup olmadığını belirleyebilir.

Bununla birlikte, jailbreak olan tüm cihazlarda Cydia yüklü değildir. Hatta kötü niyetli bir saldırgan Cydia App’ın yerini değiştirebilir. Bu nedenle Jailbroken’lı bir cihazda ilgili birçok dosyayı kontrol etmek, bu yöntemi çok daha verimli hale getirebilir.
SSH Daemon, shell interpreter, Mobile Substrate gibi uygulamalar kontrol edilebilir.


 private bool CheckCydia()
 {
     string[] cydiaPaths = new string[]
     { 
         @"/Applications/Cydia.app",
         @"/Library/MobileSubstrate/MobileSubstrate.dylib",
         @"/bin/bash",
         @"/usr/sbin/sshd",
         @"/etc/apt"
     };
     foreach (var item in cydiaPaths)
     {
        NSString filePath = new NSString(item);
        if (File.Exists(filePath))
            return true;
     }
     return false;
 }

Normal bir cihazda çalışan mobil uygulamalar sandbox ortamında çalışır ve /var/mobile/Applications dizini içine girerler. Ancak root kullanıcı ile çalışan uygulamalar (örneğin, Apple’ın önceden yüklenmiş uygulamaları) herhangi bir sanal alana tabi değildir ve /Applications dizinin içine girerler.

Jailbroken’lı bir cihazda uygulamanızı çalıştıran bir kullanıcı, uygulamayı /Applications klasörüne kurabilir, böylece ona root yetkileri verir. Bu nedenle, uygulamanın sandbox kurallarını izleyip izlemediğini kontrol etmek için bir kontrol eklenmesi, kullanıcının uygulamanın jailbroken olup olmadığını belirlemesine yardımcı olabilir. Bunu kontrol etmenin iyi bir yolu, bir dosyayı uygulama paketi dışındaki başka bir yere taşıyabilir miyiz, değiştirebilir miyiz bakmaktır.


 private bool WriteToJailBreak()
 {
     try
     {
         NSString testString = new NSString("This is a test");
         var filename = @"/private/jailbreak.txt";
         File.WriteAllText(filename, testString, Encoding.UTF8);
         return true;
     }
     catch (Exception ex)
     {
         return false;
     }
 }

Cydia uygulamasının yeri değiştirebiliyor olsa da, bu uygulamanın URL şemasını değiştirmeyeceğini
biliyoruz. Cydia’nın URL şemasını (cydia: //) uygulamanızdan çağırmak başarı veriyorsa, cihazın
jailbroken olduğunu söyleyebiliriz.


private bool CheckCydiaPath()
{
    try
    {
         return UIApplication.SharedApplication.OpenUrl(
         new NSUrl(@"cydia://package/com.example.package"));
    }
    catch (Exception ex)
    {
         return false;
    }
}

Eğer bu üç test sonucundan herhangi biri başarılı olursa, cihazın rootlu olduğu kararına varılır.

//AppDelegate FinishedLaunching
//Genelde bu 2 işlem yeterli oluyor.
private void CheckJailBreak()
{
      if (CheckCydia() || WriteToJailBreak())
         throw new Exception("JailBreak!");
}

Geliştirdiğimiz uygulamaları daha güvenli hale getirmek tamamen bizim elimizde. Xamarin kullanarak bu tarz güvenlik önlemlerini alt katmanlarda (Android,iOS) alabilirsiniz.

Görüşmek üzere,

Yiğit

Xamarin Developer, Consultant & Architect. Community Leader and Director of Xamarin Türkiye

3 Comments

You can post comments in this post.


  • Merhabalar Yigit,

    Herhangibir uygulamada shell komutlarını çalıştırmamamız mumkunmudur?
    Java.Lang.Process process = Java.Lang.Runtime.GetRuntime().Exec(“input text \”ddde:\””);
    gibi.

    ozgur 8 ay ago Reply


    • Selam,
      Java.Lang.Runtime.GetRuntime().Exec(“su”); burada oldugu gibi, kullanabilirsin.

      Yiğit 8 ay ago Reply


      • Tekrar Selamlar,

        Intentle açtımız başka bir uygulamaya root olmadan klavye kursorunun aktif olduğu yere input text yapmak mumkunmudur? yani edittext uzerine.

        ozgur 8 ay ago Reply


Post A Reply