Root Detection — Android tətbiqlərini superistifadəçi səlahiyyətləri əldə edilmiş cihazlarda işə salınmaqdan qoruyan mexanizm. Bank, ödəniş və korporativ tətbiqlər root edilmiş cihazlarda funksionallığı bloklayır və ya məhdudlaşdırır, çünki root girişi Android sandbox məhdudiyyətlərini aradan qaldırır və trafikin ələ keçirilməsi, proses yaddaşının oxunması və məlumatların dəyişdirilməsi imkanı yaradır. OWASP Mobile Top 10 (2024) məlumatlarına görə, Root Detection-in olmaması M8 (Security Decisions via Untrusted Inputs) kateqoriyasına aiddir. Root Detection fayl sisteminin statik yoxlanışı və runtime davranışının dinamik analizinin kombinasiyası üzərində qurulur.
Əsas məqamlar
Root Detection — Android cihazında root girişinin mövcudluğunu müəyyən edən proqram mexanizmi. Root girişi əməliyyat sistemi üzərində tam nəzarəti təmin edir, tətbiqlərə və skriptlərə UID 0 ilə əmrlər yerinə yetirməyə imkan verir. Root edilmiş cihazda tətbiq izolyasiyası (Android Sandbox) itirilir ki, bu da klaviatura daxiletməsinin ələ keçirilməsini, digər tətbiqlərin SQLite verilənlər bazalarının oxunmasını, proseslərə kod yeridilməsini və etibarlı depoda SSL sertifikatlarının dəyişdirilməsini mümkün edir.
Maliyyə və korporativ tətbiqlər üçün root edilmiş cihazda işləmək qəbuledilməz riskdir: sındıran tokenlərə, sessiya açarlarına və şəxsi məlumatlara çıxış əldə edir. PCI Security Standards Council daxil olmaqla tənzimləyici qurumlar ödəniş tətbiqlərindən root girişinin aşkarlanmasını və reaksiyasını tələb edir. Buna cavab olaraq Android tərtibatçıları Root Detection-i proaktiv müdafiə strategiyasının bir hissəsi kimi daxil edirlər.
Aşkarlama üçün iki yanaşma mövcuddur: fayl sistemini və quraşdırılmış paketləri analiz edən statik, və runtime-da yoxlamalar aparan dinamik. Kombinə edilmiş yanaşma ən etibarlı hesab olunur, çünki müxtəlif keçmə vektorlarını əhatə edir. NowSecure (2025) araşdırmasına görə, Google Play top-100-də olan bank tətbiqlərinin 76%-i müəyyən formada Root Detection ehtiva edir.
Statik metodlar tətbiq işə düşəndə yerinə yetirilir və root alətlərinin fayl sistemində buraxdığı root girişi əlamətlərini yoxlayır. Bu metodlar imtiyazlı əmrlərin yerinə yetirilməsini tələb etmir və adi tətbiq kontekstində işləyir.
Root girişinin əsas əlaməti — standart yollarda su icraedici faylının olması: /system/bin/su, /system/xbin/su, /sbin/su, /su/bin/su. Tətbiq faylın mövcudluğunu File.exists() və ya libc-dən access() nativ tətbiqi ilə yoxlayır. Əlavə olaraq su --version və ya su -c id yerinə yetirməyə və çıxış kodunu yoxlamağa cəhd etmək olar.
Root girişini idarə etmək üçün tipik tətbiqlər: Superuser, SuperSU, Magisk Manager, KingRoot. Onların mövcudluğu PackageManager.getPackageInfo() və ya /data/app/ kataloqunun oxunması vasitəsilə yoxlanılır. Yoxlanılacaq paketlər: com.topjohnwu.magisk, eu.chainfire.supersu, com.noshufou.android.su, com.thirdparty.superuser, com.koushikdutta.superuser, com.zacharee1.systemuituner.
Android sistemin vəziyyəti haqqında məlumatı System.getProperty və Build.TAGS vasitəsilə əldə edilən sistem xüsusiyyətlərində saxlayır. Build.TAGS dəyəri release-keys deyil, test-keys ehtiva edirsə — bu, çox vaxt root girişi olan fərdi proqram təminatını göstərir. Əlavə olaraq ro.build.tags, ro.debuggable və ro.secure /system/build.prop oxunması vasitəsilə yoxlanılır.
public class RootDetectionChecker {
private static final String[] SU_PATHS = {
"/system/bin/su",
"/system/xbin/su",
"/sbin/su",
"/su/bin/su",
"/system/sd/xbin/su"
};
public boolean checkRootByFiles() {
for (String path : SU_PATHS) {
if (new File(path).exists()) {
return true;
}
}
return false;
}
public boolean checkRootByPackages(Context ctx) {
String[] packages = {
"com.topjohnwu.magisk",
"eu.chainfire.supersu",
"com.noshufou.android.su",
"com.koushikdutta.superuser"
};
for (String pkg : packages) {
try {
ctx.getPackageManager().getPackageInfo(pkg, 0);
return true;
} catch (PackageManager.NameNotFoundException e) {
// paket tapılmadı
}
}
return false;
}
}
Dinamik metodlar tətbiq işləyərkən yerinə yetirilir və icra mühitini analiz edir. Statik metodlardan fərqli olaraq, onlar Magisk Hide və ya Zygisk vasitəsilə gizlədilmiş root-u aşkarlaya bilər, çünki yalnız fayl strukturunu deyil, sistemin davranışını yoxlayır.
Root girişi olduqda bəzi sistem bölmələri ro (read-only) əvəzinə rw (read-write) flagı ilə mount edilir. Tətbiq /proc/mounts-ı oxuyur və /system-in ro kimi mount edildiyini yoxlayır. /system rw kimi mount edilibsə — bu dəyişdirilmiş sistemin əlamətidir. Əlavə olaraq Magisk vasitəsilə /su mount edilməsinin olması yoxlanılır.
Android Safe Mode üçüncü tərəf tətbiqlərini, o cümlədən root menecerlərini söndürür. Root Detection-in düzgün tətbiqi cihazın təhlükəsiz rejimdə işlədiyini yoxlaya bilər. Tətbiq root menecerlərinin görünmədiyini, lakin su-binar faylının mövcud olduğunu aşkarlayırsa — bu Magisk Hide əlamətidir.
ProcessBuilder və ya Runtime.exec vasitəsilə su -c id yerinə yetirmək cəhdi — root girişinin birbaşa testidir. Lakin Magisk bu çağırışı ələ keçirə bilər. Daha etibarlı variant — nativ kod vasitəsilə yoxlama: /proc/1/limits və ya /proc/self/maps açmaq və işləyən proseslərin UID-ni analiz etmək. Tətbiq UID 0 əldə edə və ya yalnız root üçün əlçatan faylları oxuya bilirsə — cihaz kompromat olunub.
public boolean checkRootDynamically() {
// Quraşdırma flaqinin yoxlanması
String buildTags = Build.TAGS;
if (buildTags != null && buildTags.contains("test-keys")) {
return true;
}
// /system mount edilməsinin yoxlanması
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream("/proc/mounts"))
);
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("/system")
&& line.contains("rw")) {
reader.close();
return true;
}
}
reader.close();
} catch (IOException e) {
// mount oxunmasında xəta
}
return false;
}
Java-da tətbiq edilmiş Root Detection asanlıqla Java metodlarını ələ keçirən və qaytarılan dəyərləri dəyişdirən Xposed modulları və ya Frida vasitəsilə keçilir. C++ dilində JNI vasitəsilə nativ tətbiq əhəmiyyətli dərəcədə davamlıdır: Java səviyyəsində işləyən dinamik analiz alətləri stat, access, popen və dlopen kimi libc nativ çağırışlarını görmür.
#include <unistd.h>
#include <sys/stat.h>
#include <cstring>
#include <vector>
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_example_checker_RootCheck_nativeCheck(
JNIEnv* env, jobject instance) {
std::vector<const char*> paths = {
"/system/bin/su",
"/system/xbin/su",
"/sbin/su",
"/data/local/su"
};
struct stat st;
for (const char* path : paths) {
if (stat(path, &st) == 0) {
return JNI_TRUE;
}
}
return JNI_FALSE;
}
Nativ yoxlama Java API-dən istifadə etmir, bu da onu Dalvik/ART səviyyəsində işləyən keçmə alətləri üçün görünməz edir. Əlavə qorunma üçün sabitləri (yol siyahısı) read-only bölməsində deyil, sadə geri dönən funksiyalar vasitəsilə hesablamaq tövsiyə olunur. Stat çağırışı libc-dən birbaşa Linux nüvəsinə müraciət edir, Java örtüklərini yan keçir və onu Xposed vasitəsilə ələ keçirmək mümkün deyil.
Müdafiə tərtibatçıları davamlı aşkarlama sistemi qurmaq üçün mövcud keçmə metodlarını başa düşməlidirlər. Hər bir keçmə metodu müvafiq səviyyədə əks tədbir tələb edir.
Magisk — Android 9–14-də ən populyar root alətidir. Magisk Hide su-nun /proc-dan mövcudluğunu gizlədir və yol yoxlama nəticələrini dəyişdirir. Magisk nüvə səviyyəsində işləyir və tətbiq görməmişdən əvvəl stat() və access()-i ələ keçirir. Əks tədbir: /sbin/.magisk-in mövcudluğu və ya öz maps-in oxunması vasitəsilə Magisk-in özünün mövcudluğunun yoxlanması — Magisk öz kitabxanasını hər bir prosesə yerləşdirir.
Frida — Ptrace və ya Dobby vasitəsilə nativ funksiyaları ələ keçirə bilən dinamik instrumentasiya alətidir. Frida hər bir yoxlamanın qaytarılan dəyərini əvəz edir, stat nəticəsini ENOENT ilə əvəz edir. Əks tədbir: yaddaşdakı təlimatların checksum-ı vasitəsilə nativ funksiyaların bütövlüyünün yoxlanması və Frida-nın /proc/self/maps-da frida-agent.so və ya frida-helper mövcudluğu üçün analizi.
Java-da tətbiq edilmiş Root Detection 2–3 dəqiqəyə silinir: APK apktool vasitəsilə açılır, smali kodunda metodun qaytarma dəyəri false olaraq düzəldilir, APK yenidən yığılır və imzalanır. Əks tədbir: kritik məntiqin nativ koda köçürülməsi və runtime-da Signature API və ya APK hash-ının serverdəki etalonla müqayisəsi vasitəsilə tətbiqin rəqəmsal imzasının yoxlanması.
Effektiv Root Detection çoxqatlı arxitektura üzərində qurulur. Heç bir metod ayrılıqda kifayət qədər qoruma səviyyəsini təmin etmir. Statik və dinamik yoxlamaların, nativ kodun və server yoxlamasının kombinasiyası maksimum davamlılıq verir.
Yalnız klient tərəfində yoxlamaya güvənməyin. Root Detection nəticələrini birdəfəlik sessiya tokeni ilə birlikdə serverə göndərin. Server bloklama və ya funksionallığın məhdudlaşdırılması barədə qərar qəbul edir. Bu, klient tətbiqinin dəyişdirilə bildiyi, lakin serverin etibarlı tərəf olaraq qaldığı API səviyyəsində hücumların qarşısını alır.
Root Detection kodu obfuskasiya edilməlidir. Əgər sındıran jadx-da su yollarının aydın ardıcıllığını görürsə — keçmə dəqiqələr çəkəcək. İdarəetmə axınını qarışdırmaq və sətirləri şifrələmək üçün ProGuard və ya DexGuard istifadə edin. Obfuskasiya müdafiə kodunun analiz müddətini bir neçə dəqiqədən bir neçə saata qədər artırır.
Yoxlanılan yolların, paketlərin və göstəricilərin siyahısı tətbiqin hər buraxılışı ilə yenilənməlidir. Yeni root və keçmə alətləri hər ay çıxır. Bir ildir dəyişməyən statik siyahı müasir metodları aşkarlamır. Yoxlamaları yerinə yetirməzdən əvvəl tətbiq işə düşəndə serverdən cari imzaları yükləmək tövsiyə olunur.
Tez-tez verilən suallar
Root Detection tətbiqi Android sandbox-ın söndürüldüyü cihazda işə salınmaqdan qoruyur. Root edilmiş cihazda istənilən tətbiq digər tətbiqlərin məlumatlarını oxuya bilər. Bank və ödəniş tətbiqləri PCI DSS tələbləri və OWASP Mobile Security tövsiyələrinə əsasən root edilmiş cihazlarda işi bloklamalıdır.
Magisk Hide mount ad sahəsi (mount namespace) mexanizmindən istifadə edir. İstisnalar siyahısında göstərilən hər bir proses üçün Magisk təcrid olunmuş ad sahəsi yaradır, burada su-binar faylı görünməz olur. Bu ad sahəsində sistem çağırışları stat, access və open Magisk fayllarını görmür. Magisk-i /proc/self/maps-ın mövcudluğu və magisk dump axtarışı vasitəsilə aşkarlamaq olar.
Bəli, əgər tətbiq öz kodunun bütövlüyünü yoxlamırsa. Frida vasitəsilə Java yoxlama metodunu ələ keçirib məcburən false qaytarmaq olar. Əks tədbir — kritik məntiqin C++ dilində nativ tətbiqi və DEX faylının hash-ı vasitəsilə bütövlüyün yoxlanması. Obfuskasiya olmadan Java-da istənilən Root Detection 5–10 dəqiqəyə keçilir.
SafetyNet (köhnəlmiş) və Play Integrity API — bunlar cihazın bütövlüyünü təsdiq edən Google-un server yoxlamalarıdır. Onlar bootloader, sistem imzası və root statusunun yoxlanmasını əhatə edir. Play Integrity API — SafetyNet-ə tövsiyə edilən əvəzedici, üç səviyyə verir: BASIC, DEVICE və STRONG. Klient tərəfində Root Detection server attestasiyasını tamamlayır.
Tətbiqi real root edilmiş cihazda (məsələn, Magisk ilə Pixel) quraşdırın. Bloklamanın işə düşdüyünü yoxlayın. Sonra root-u Magisk Hide vasitəsilə tətbiqiniz üçün gizlətməyə çalışın və testi təkrarlayın. Dərindən yoxlama üçün hədəf metodları ələ keçirmək üçün Frida istifadə edin və nativ müdafiənin keçilməz olduğuna əmin olun.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun