Root Detection — mechanismus ochrany Android aplikací před spuštěním na zařízeních s právy superuživatele. Bankovní, platební a firemní aplikace blokují nebo omezují funkčnost na rootovaných zařízeních, protože root přístup odstraňuje omezení Android sandboxu a otevírá možnost zachycení provozu, čtení paměti procesů a falšování dat. Podle OWASP Mobile Top 10 (2024) spadá absence Root Detection do kategorie M8 (Security Decisions via Untrusted Inputs). Root Detection je postaven na kombinaci statických kontrol souborového systému a dynamické analýzy chování za běhu.
Hlavní body
Root Detection — softwarový mechanismus, který zjišťuje přítomnost root přístupu na zařízení Android. Root přístup poskytuje úplnou kontrolu nad operačním systémem a umožňuje aplikacím a skriptům spouštět příkazy s UID 0. Na rootovaném zařízení dochází ke ztrátě izolace aplikací (Android Sandbox), což umožňuje zachycení vstupu z klávesnice, čtení SQLite databází jiných aplikací, vkládání kódu do procesů a falšování SSL certifikátů v důvěryhodném úložišti.
Pro finanční a firemní aplikace představuje provoz na rootovaném zařízení nepřijatelné riziko: útočník získá přístup k tokenům, relacním klíčům a osobním údajům. Regulační orgány, včetně PCI Security Standards Council, vyžadují od platebních aplikací detekci a reakci na root přístup. V reakci na to vývojáři Android začleňují Root Detection jako součást strategie proaktivní ochrany.
Existují dva přístupy k detekci: statický, který analyzuje souborový systém a nainstalované balíčky, a dynamický, který provádí kontroly za běhu. Kombinovaný přístup je považován za nejspolehlivější, protože pokrývá různé vektory obcházení. Podle výzkumu NowSecure (2025) obsahuje 76 % bankovních aplikací v top 100 Google Play nějakou formu Root Detection.
Statické metody se spouštějí při startu aplikace a kontrolují známky root přístupu zanechané root nástroji v souborovém systému. Tyto metody nevyžadují spouštění privilegovaných příkazů a fungují v kontextu běžné aplikace.
Hlavní známka root přístupu — přítomnost spustitelného souboru su na standardních cestách: /system/bin/su, /system/xbin/su, /sbin/su, /su/bin/su. Aplikace kontroluje existenci souboru přes File.exists() nebo nativní implementaci access() z libc. Dále lze zkusit spustit su --version nebo su -c id a zkontrolovat návratový kód.
Typické aplikace pro správu root přístupu: Superuser, SuperSU, Magisk Manager, KingRoot. Jejich přítomnost se kontroluje přes PackageManager.getPackageInfo() nebo čtením adresáře /data/app/. Balíčky ke kontrole: com.topjohnwu.magisk, eu.chainfire.supersu, com.noshufou.android.su, com.thirdparty.superuser, com.koushikdutta.superuser, com.zacharee1.systemuituner.
Android ukládá informace o stavu systému do systémových vlastností přístupných přes System.getProperty a Build.TAGS. Pokud hodnota Build.TAGS obsahuje test-keys místo release-keys — to ukazuje na vlastní firmware, často s root přístupem. Dále se kontrolují ro.build.tags, ro.debuggable a ro.secure čtením /system/build.prop.
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) {
// balíček nebyl nalezen
}
}
return false;
}
}
Dynamické metody se provádějí za běhu aplikace a analyzují prostředí spouštění. Na rozdíl od statických mohou odhalit root skrytý přes Magisk Hide nebo Zygisk, protože kontrolují chování systému, nejen strukturu souborů.
Při root přístupu jsou některé systémové oddíly připojeny s příznakem rw (read-write) místo ro (read-only). Aplikace čte /proc/mounts a kontroluje, zda je /system připojen jako ro. Pokud je /system připojen jako rw — to je známka modifikovaného systému. Dále se kontroluje přítomnost připojení /su přes Magisk.
Android Safe Mode vypíná aplikace třetích stran, včetně root manažerů. Správná implementace Root Detection může zkontrolovat, zda zařízení pracuje v bezpečném režimu. Pokud aplikace zjistí, že root manažeři nejsou viditelní, ale su binárka existuje — to je známka Magisk Hide.
Pokus o spuštění su -c id přes ProcessBuilder nebo Runtime.exec — přímý test root přístupu. Magisk však může toto volání zachytit. Spolehlivější možnost — kontrola přes nativní kód: otevření /proc/1/limits nebo /proc/self/maps a analýza UID běžících procesů. Pokud aplikace může získat UID 0 nebo číst soubory přístupné pouze root — zařízení je kompromitováno.
public boolean checkRootDynamically() {
// Kontrola příznaků kompilace
String buildTags = Build.TAGS;
if (buildTags != null && buildTags.contains("test-keys")) {
return true;
}
// Kontrola připojení /system
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) {
// chyba při čtení mountu
}
return false;
}
Root Detection implementovaný v Java se snadno obchází pomocí Xposed modulů nebo Frida, které zachycují Java metody a falšují návratové hodnoty. Nativní implementace v C++ přes JNI je výrazně odolnější: nástroje dynamické analýzy pracující na úrovni Java nevidí nativní volání libc, jako jsou stat, access, popen a dlopen.
#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;
}
Nativní kontrola nepoužívá Java API, což ji činí neviditelnou pro nástroje obcházení pracující na úrovni Dalvik/ART. Pro dodatečnou ochranu se doporučuje ukládat konstanty (seznam cest) nikoli v read-only sekci, ale počítat je přes jednoduché reverzibilní funkce. Volání stat z libc se přímo obrací na jádro Linux, obchází Java wrapper a nelze jej zachytit přes Xposed.
Vývojáři ochrany musí rozumět existujícím metodám obcházení, aby mohli vybudovat odolný detekční systém. Každá metoda obcházení vyžaduje protiopatření na odpovídající úrovni.
Magisk — nejpopulárnější root nástroj na Android 9–14. Magisk Hide skrývá přítomnost su z /proc a falšuje výsledky kontrol cest. Magisk pracuje na úrovni jádra a zachycuje stat() a access() dříve, než je aplikace uvidí. Protiopatření: kontrola přítomnosti samotného Magisk přes existenci /sbin/.magisk nebo kontrola přes čtení vlastních maps — Magisk vkládá svou knihovnu do každého procesu.
Frida — nástroj dynamické instrumentace, který může zachycovat nativní funkce přes Ptrace nebo Dobby. Frida nahrazuje návratovou hodnotu každé kontroly a falšuje výsledek stat na ENOENT. Protiopatření: kontrola integrity nativních funkcí přes výpočet kontrolního součtu instrukcí v paměti a detekce Frida přes analýzu /proc/self/maps na přítomnost frida-agent.so nebo frida-helper.
Root Detection implementovaný v Java je odstraněn za 2–3 minuty: APK se rozbalí přes apktool, v kódu smali se změní návratová hodnota metody na false, APK se znovu sestaví a podepíše. Protiopatření: přesun kritické logiky do nativního kódu a kontrola digitálního podpisu aplikace za běhu přes Signature API nebo porovnání hash APK s referencí na serveru.
Efektivní Root Detection je postaven na vícevrstvé architektuře. Žádná metoda samostatně neposkytuje dostatečnou úroveň ochrany. Kombinace statických a dynamických kontrol, nativního kódu a serverového ověření dává maximální odolnost.
Nespoléhejte se pouze na kontrolu na straně klienta. Odesílejte na server výsledky Root Detection spolu s jednorázovým tokenem relace. Server rozhoduje o blokování nebo omezení funkčnosti. To zabraňuje útokům na úrovni API, kde může být klientská aplikace modifikována, ale server zůstává důvěryhodnou stranou.
Kód Root Detection musí být obfuskován. Pokud útočník vidí v jadx jasnou sekvenci kontrol su cest — obcházení bude trvat minuty. Použijte ProGuard nebo DexGuard pro zamotání toku řízení a šifrování řetězců. Obfuskace zvyšuje dobu analýzy bezpečnostního kódu z několika minut na několik hodin.
Seznam kontrolovaných cest, balíčků a indikátorů musí být aktualizován s každým vydáním aplikace. Nové root nástroje a nástroje pro obcházení se objevují měsíčně. Statický seznam, který se nezměnil rok, neodhaluje moderní metody. Doporučuje se načítat aktuální signatury ze serveru při startu aplikace před provedením kontrol.
Často kladené otázky
Root Detection chrání před spuštěním aplikace na zařízení, kde je Android sandbox vypnutý. Na rootovaném zařízení může jakákoli aplikace číst data jiných aplikací. Bankovní a platební aplikace jsou povinny blokovat provoz na rootovaných zařízeních podle požadavků PCI DSS a doporučení OWASP Mobile Security.
Magisk Hide využívá mechanismus mount namespace. Pro každý proces uvedený v seznamu výjimek vytváří Magisk izolovaný namespace, kde je su binárka neviditelná. Systémová volání stat, access a open v tomto namespace nevidí soubory Magisk. Magisk lze odhalit kontrolou přítomnosti /proc/self/maps a hledáním magisk dump.
Ano, pokud aplikace nekontroluje integritu svého kódu. Přes Frida lze zachytit Java metodu kontroly a vynutit vrácení false. Protiopatření — nativní implementace kritické logiky v C++ a kontrola integrity přes hash DEX souboru. Bez obfuskace je jakýkoli Root Detection v Java obcházen za 5–10 minut.
SafetyNet (zastaralý) a Play Integrity API — to jsou serverové kontroly od Google potvrzující integritu zařízení. Zahrnují kontrolu bootloaderu, systémového podpisu a root statusu. Play Integrity API — doporučená náhrada za SafetyNet, poskytující tři úrovně: BASIC, DEVICE a STRONG. Root Detection na klientovi doplňuje serverovou atestaci.
Nainstalujte aplikaci na skutečné rootované zařízení (např. Pixel s Magisk). Zkontrolujte, zda se blokování aktivuje. Poté zkuste skrýt root přes Magisk Hide pro vaši aplikaci a opakujte test. Pro hloubkovou kontrolu použijte Frida k zachycení cílových metod a ujistěte se, že nativní ochrana není obcházitelná.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také