Bu makalemizde var olan bir android uygulamasına kendi geliştirdiğimiz malware kodu gömecek ve bu kodun aktif hale gelmesini sağlayacağız.
Makalenin içeriğini anlayabilmek için giriş seviyesinde de olsa Android uygulama geliştirme bilgisi gerekli olacaktır. Ama ne de olsa kod yazamayan bir hacker olmaz öyle değil mi :)
Öncelikle izleyeceğimiz adımları (olabildiğince) sadeleştirerek açıklayalım:
- Hedef Android uygulamanın seçilmesi ve APK dosyasının içeriğinde bulunan dosyaların cleartext formatına dönüştürülmesi ve classes.dex dosyasında bulunan derlenmiş kodların ara kod (smali) seviyesine decompile edilmesi
- Zararlı kodun geliştirilmesi ve zararlı kod bölümü aktif hale geldikten sonra hedef olarak belirlenen Android uygulamasının başlangıç aktivitesini çağıracak biçimde düzenlenmesi
- Hedef Android uygulamanın cleartext formata dönüştürülmüş olan Manifest.xml dosyası içinde başlangıç aktivitesi olarak zararlı kodumuzun ilk aktivitesinin tanımlanması
- Manifest.xml dosyası içinde diğer uygulama interface ve kullanıcı izin bilgilerinin tanımlanması
- Zararlı kodun smali seviyesine decompile edilmesi
- Zararlı kodun smali dosyalarının hedef uygulama smali dosyaları arasına yerleştirilmesi
- Zararlı kod gömülmüş hedef uygulamanın tekrar derlenmesi
- Hedef uygulamanın imzalanması ve hedef cihaza yerleştirilmesi
Merak etmeyin, adım adım ilerledikçe herşey berraklaşacak.
Hedef uygulama olarak bir oyun uygulamasını seçtik, ama herhangi bir uygulama için aynı süreç uygulanabilir. Oyun uygulamamız küçük bir uygulama olduğu için derleme, yükleme, v.b. işlemlerimiz de daha hızlı olacak.
İlk adım olarak uygulamamızı smali seviyesine decompile edeceğiz. Smali ve baksmali kelimeleri İzlanda dilinde assembly ve disassembly anlamına geliyor. Apktool aracı ile yapacağımız bu işlem sadece classes.dex dosyası içindeki kodları decompile etmeyecek aynı zamanda diğer dosyaları da okunabilir hale getirecek. Bu dosyalar arasında Manifest.xml dosyası bizim için çok önemli. Manifest.xml dosyasının Android uygulamaları için ne anlama geldiği ile ilgili daha detaylı bir inceleme yapmanız gerekebilir, ancak kısaca uygulamanın içindeki aktivite (bu aktivite sınıfları genellikle birer view yükleyerek kullanıcı arayüzlerini oluşturan ve bu arayüzlerin arkasındaki controller görevini gören sınıflardır) sınıflarını, servis, receiver v.d. interface’leri, uygulamanın ihtiyaç duyduğu izinleri tanımlamak zorunda olduğumuz dosyadır. Bu dosya için de ayrıca uygulamanın ilk çalışacak aktivitesi de tanımlanır.
Uygulamamızı APK formatında elde etmenin pek çok yolu var. Ben bir Chrome add-on’u olan APK Downloader’ı kullandım.
Uygulamamızın APK dosyası aşağıdaki gibi, dosya formatı gördüğünüz gibi geliştiren şirketin alan adının tersten yazılmış hali ile başlıyor. Bu özellikle Java dünyasında ve nesne odaklı uygulama geliştirme yaklaşımı ile geliştirilen diğer dillerde kullanılan bir teamül. Böylece farklı firmalar aynı isimli bir uygulama geliştirse bile paket veya sınıf isimleri farklılaştığından isim çarpışması gerçekleşmiyor.
Pek çoğunuzun bildiği gibi APK dosyası aslında bir arşiv dosyası, yani uzantıyı zip dosyası olarak değiştirdiğimizde içinde barındırdığı dosyaları görebiliriz.
Yukarıda gördüğünüz AndroidManifest.xml dosyası şu anda okunabilir formatta değil. Ayrıca tüm Java sınıflarını içeren classes.dex dosyası da derlenmiş formatta.
Şimdi Apktool ile bu paketi decompile edelim.
Apktool decompile edilmiş olan uygulama için yeni bir dizin oluşturuyor ve bu dizinin yapısı da şu şekilde:
Smali dizini ise uygulama kodlarının smali formatındaki dosyalarını içeriyor.
Teorik olarak ileri derecede (yani okuma düzeyinin daha ilerisinde) smali bilgimiz olsa idi, zararlı kodumuzu mevcut aktivitelerin içine de gömebilirdik. Burada izleyeceğimiz yöntem bu zahmete girmeden sonuca ulaşmamıza imkan sağlayacak. Örnek bir smali kodu örneği olarak aşağıdakini verebiliriz:
Smali kodunun içeriği ile hiçbir işimiz olmamasına rağmen temel düzeyde değinmeden geçemeyeceğim.
Alt seviye kodları açıklamanın en pratik yolu basit bir kaynak kodu derlemek ve daha sonra disassemble edilmiş olan makine veya ara seviye kod üzerinden ilişkilendirerek anlatmak.
Bunun için basit bir Android projesi oluşturalım ve içinde bir sınıf tanımlayalım:
Gördüğünüz gibi kendi çapımızda bir muziplik yapıp Hello world klişesini yurdumuz lehçelerine uyarladık :)
Şimdi bu uygulamayı derleyerek APK dosyasını elde edelim ve yine Apktool ile işleyerek smali koduna erişelim.
Sınıf metodu olan Selam fonksiyonunun başladığı noktayı kolaylıkla ayırt edebiliyoruz.
.locals direktifi metodun içinde kullanılacak olan register sayısını ifade ediyor. Register nedir derseniz (buradaki register’ı işlemci register’ları ile karıştırmayın) fonksiyona parametre aktarmak için kullanılan ve fonksiyon içinde lokal olarak kullanılan parametreler diyebiliriz. Bu register’lar “v” harfi ile ifade ediliyor ve 32 bit uzunluğundalar.
.prologue direktifinin metodun başlangıcına breakpoint konmak istendiğinde bir sonraki komutun uygun komut olduğunu belirtmek için kullanıldığını https://source.android.com/devices/tech/dalvik/dex-format.html sitesinden öğreniyoruz.
.line direktifinin uygulamanın işleyişini doğrudan etkileyen herhangi bir işlevi yok. Sadece uygulama hata aldığında teknik hata mesajı üretmek için hatanın gerçekleştiği satır numarasını mesaj içinde belirtmek üzere kullanılıyor.
const-string v1, "Noruyon Dunya": satırı Noruyon Dunya string’ini (daha doğrusu bu string’in adresini) v1 register’ına atıyor.
.local v1, "selam1":Ljava/lang/String; satırı adı selam1 olan ve veri tipi String sınıfı olan değişken ile v1 register’ını ilişkilendiriyor. Bu ilişkilendirmenin bu kod seviyesindeki anlamını tam olarak anlayamıyorum, ancak muhtemelen makine koduna derlenirken sanal makinenin yapacağı veri tipi kontrolleri için gerekli. Zira birazdan göreceğimiz gibi register parametreleri fonksiyon çağrılarında doğrudan kullanılıyor. Bu parametrelerin temsil ettiği veri tiplerini sanal makine ancak bu tanımlamalar sayesinde anlayabilir.
const/4 v0, 0x1: satırı ile v0 register’ına 1 değeri atanıyor. Biraz aşağıda bu register “a” adında ve Integer temel veri tipinde olan değişken ile ilişkilendiriliyor. Bölü işareti sonrasındaki 4 rakamı v0 parametresinde saklanacak olan verinin 4 bitlik bir integer olduğu anlamına geliyor. Bunun da sanal makine için mutlaka önemi olacaktır.
const/4 v4, 0x1: satırında v4 register’ına da 1 değeri atandığını görüyoruz, ancak bu parametre herhangi bir değişken adı ile ilişkilendirilmiyor. Çünkü bu değer “if” ifadesinde kullanacağımız “a” ile karşılaştıracağımız değer.
if-ne v0, v4, :cond_0: satırı v0 ve v4 register’larındaki değerler eşit değilse “:cond_0” etiketi ile belirtilen satıra atlama koşulunu ifade ediyor. Bu bizim yazdığımız koddan ifade olarak farklı ancak mantık olarak kodumuzun karşılığını yerine getiriyor. Bu satır eğer bu iki değer eşitse, yani “a” değişkeni “1” ise “:cond_0” etiketine atlama, bir sonraki satırdan devam et anlamına geliyor.
const-string v4, "%s": satırında “%s” format string’i (yine daha doğrusu bu string’in adresi) v4 register’ına aktarılıyor.
Bir sonraki satırda “invoke-static {v4, v1}, Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I” satırında ise statik bir metod çağrılıyor. Bu metod “android.util.Log” sınıfının “i” metodu. Bu metod String veri tipinde 2 adet parametre alıyor. En sonda görülen “I” harfi ise metodun Integer veri tipinde veri döndürdüğü anlamına geliyor.
Hemen aşağıdaki “:goto_0” etiketi bu bölüm için birşey ifade etmiyor, ancak daha sonra gelen satırlar da “goto :goto_0” komutu bulunduğu için (kodun bu kısmını yukarıda görüntülemedim) uygulama akışı buraya yönlendiriliyor. Burada önemli olan komut “return-void” komutu. Tahmin edebileceğiniz gibi bu komutla hiçbir değer döndürmeden metod sonlanıyor. Döndürmemiz gerekseydi “return v0” gibi bir komut görebilirdik.
Evet, yolumuzdan epey saptık. Ama bu konuyu da açıklamasaydım rahat edemezdim. Yukarıda da belirttiğim gibi, biz smali kodu üzerinde herhangi bir oynama yapmadan zararlı kodumuzu pakete entegre edeceğiz.
İkinci aşamada zararlımızı geliştireceğiz. Zararlıdan kasıt aslında başka bir android uygulaması. Virüs nasıl yazılır makalemizde olduğu gibi zor koşullarla karşı karşıya değiliz. Tabi yine ufak bir müdahale ile sıra dışı bir işlem yapmamız gerekecek.
Android uygulamalara malware yerleştirme makalemizin bir sonraki bölümünde görüşmek üzere.
Sonraki Bölüm>>
BTRiskBLOG, BTRİSK Bilgi Güvenliği ve BT Yönetişim Hizmetleri şirketi personeli tarafından geliştirilen Pentest (Sızma Testi), ISO27001, BT Denetimi ve bilgi güvenliği hakkında herşeyi bulabileceğiniz blog'dur.