Root Detection — μηχανισμός προστασίας εφαρμογών Android από εκτέλεση σε συσκευές με δικαιώματα υπερχρήστη. Οι τραπεζικές, πληρωμών και εταιρικές εφαρμογές αποκλείουν ή περιορίζουν τη λειτουργικότητα σε root-αρισμένες συσκευές, καθώς η πρόσβαση root αφαιρεί τους περιορισμούς του sandbox του Android και ανοίγει τη δυνατότητα υποκλοπής κίνησης, ανάγνωσης μνήμης διεργασιών και παραποίησης δεδομένων. Σύμφωνα με το OWASP Mobile Top 10 (2024), η απουσία Root Detection ανήκει στην κατηγορία M8 (Security Decisions via Untrusted Inputs). Root Detection βασίζεται σε συνδυασμό στατικών ελέγχων συστήματος αρχείων και δυναμικής ανάλυσης συμπεριφοράς κατά το runtime.
Κύρια σημεία
Root Detection — μηχανισμός λογισμικού που προσδιορίζει την ύπαρξη πρόσβασης root σε μια συσκευή Android. Η πρόσβαση root παρέχει πλήρη έλεγχο στο λειτουργικό σύστημα, επιτρέποντας σε εφαρμογές και σενάρια να εκτελούν εντολές με UID 0. Σε μια root-αρισμένη συσκευή, η απομόνωση εφαρμογών (Android Sandbox) χάνεται, καθιστώντας δυνατή την υποκλοπή εισόδου πληκτρολογίου, ανάγνωση βάσεων δεδομένων SQLite άλλων εφαρμογών, έγχυση κώδικα σε διεργασίες και παραποίηση πιστοποιητικών SSL στο αξιόπιστο αποθετήριο.
Για χρηματοοικονομικές και εταιρικές εφαρμογές, η λειτουργία σε root-αρισμένη συσκευή αποτελεί απαράδεκτο κίνδυνο: ο εισβολέας αποκτά πρόσβαση σε κωδικούς, κλειδιά συνεδρίας και προσωπικά δεδομένα. Οι ρυθμιστικές αρχές, συμπεριλαμβανομένου του PCI Security Standards Council, απαιτούν από τις εφαρμογές πληρωμών να ανιχνεύουν και να αντιδρούν στην πρόσβαση root. Ως απάντηση, οι προγραμματιστές Android ενσωματώνουν το Root Detection ως μέρος μιας προληπτικής στρατηγικής ασφάλειας.
Υπάρχουν δύο προσεγγίσεις ανίχνευσης: στατική, που αναλύει το σύστημα αρχείων και εγκατεστημένα πακέτα, και δυναμική, που εκτελεί ελέγχους κατά το runtime. Η συνδυασμένη προσέγγιση θεωρείται η πιο αξιόπιστη, καθώς καλύπτει διαφορετικά διανύσματα παράκαμψης. Σύμφωνα με έρευνα της NowSecure (2025), το 76% των τραπεζικών εφαρμογών στην κορυφή 100 του Google Play περιέχει κάποια μορφή Root Detection.
Οι στατικές μέθοδοι εκτελούνται κατά την εκκίνηση της εφαρμογής και ελέγχουν σημάδια πρόσβασης root που αφήνουν τα εργαλεία root στο σύστημα αρχείων. Αυτές οι μέθοδοι δεν απαιτούν εκτέλεση προνομιούχων εντολών και λειτουργούν στο πλαίσιο μιας κανονικής εφαρμογής.
Το κύριο σημάδι πρόσβασης root — η παρουσία εκτελέσιμου αρχείου su σε τυπικές διαδρομές: /system/bin/su, /system/xbin/su, /sbin/su, /su/bin/su. Η εφαρμογή ελέγχει την ύπαρξη αρχείου μέσω File.exists() ή native υλοποίησης access() από τη libc. Επιπλέον, μπορεί να επιχειρηθεί εκτέλεση su --version ή su -c id και έλεγχος κωδικού εξόδου.
Τυπικές εφαρμογές διαχείρισης πρόσβασης root: Superuser, SuperSU, Magisk Manager, KingRoot. Η παρουσία τους ελέγχεται μέσω PackageManager.getPackageInfo() ή ανάγνωσης του καταλόγου /data/app/. Πακέτα προς έλεγχο: com.topjohnwu.magisk, eu.chainfire.supersu, com.noshufou.android.su, com.thirdparty.superuser, com.koushikdutta.superuser, com.zacharee1.systemuituner.
Το Android αποθηκεύει πληροφορίες σχετικά με την κατάσταση του συστήματος σε ιδιότητες συστήματος προσβάσιμες μέσω System.getProperty και Build.TAGS. Εάν η τιμή Build.TAGS περιέχει test-keys αντί για release-keys — αυτό υποδεικνύει προσαρμοσμένο υλικολογισμικό, συχνά με πρόσβαση root. Επιπλέον, ελέγχονται τα ro.build.tags, ro.debuggable και ro.secure μέσω ανάγνωσης του /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) {
// το πακέτο δεν βρέθηκε
}
}
return false;
}
}
Οι δυναμικές μέθοδοι εκτελούνται κατά τη λειτουργία της εφαρμογής και αναλύουν το περιβάλλον εκτέλεσης. Σε αντίθεση με τις στατικές, μπορούν να ανιχνεύσουν root κρυμμένο μέσω Magisk Hide ή Zygisk, καθώς ελέγχουν τη συμπεριφορά του συστήματος, όχι μόνο τη δομή αρχείων.
Κατά την πρόσβαση root, ορισμένες κατατμήσεις συστήματος προσαρτώνται με σημαία rw (read-write) αντί για ro (read-only). Η εφαρμογή διαβάζει το /proc/mounts και ελέγχει εάν το /system είναι προσαρτημένο ως ro. Εάν το /system είναι προσαρτημένο ως rw — αυτό είναι σημάδι τροποποιημένου συστήματος. Επιπλέον, ελέγχεται η παρουσία προσάρτησης /su μέσω Magisk.
Η Android Safe Mode απενεργοποιεί εφαρμογές τρίτων, συμπεριλαμβανομένων των διαχειριστών root. Μια σωστή υλοποίηση Root Detection μπορεί να ελέγξει εάν η συσκευή λειτουργεί σε ασφαλή λειτουργία. Εάν η εφαρμογή ανιχνεύσει ότι οι διαχειριστές root δεν είναι ορατοί, αλλά το su δυαδικό υπάρχει — αυτό είναι σημάδι Magisk Hide.
Απόπειρα εκτέλεσης su -c id μέσω ProcessBuilder ή Runtime.exec — άμεση δοκιμή πρόσβασης root. Ωστόσο, το Magisk μπορεί να υποκλέψει αυτήν την κλήση. Μια πιο αξιόπιστη επιλογή — έλεγχος μέσω native κώδικα: άνοιγμα /proc/1/limits ή /proc/self/maps και ανάλυση UID διεργασιών σε εκτέλεση. Εάν η εφαρμογή μπορεί να αποκτήσει UID 0 ή να διαβάσει αρχεία προσβάσιμα μόνο στο root — η συσκευή έχει παραβιαστεί.
public boolean checkRootDynamically() {
// Έλεγχος flags μεταγλώττισης
String buildTags = Build.TAGS;
if (buildTags != null && buildTags.contains("test-keys")) {
return true;
}
// Έλεγχος προσάρτησης /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) {
// σφάλμα κατά την ανάγνωση προσάρτησης
}
return false;
}
Το Root Detection που υλοποιείται σε Java παρακάμπτεται εύκολα μέσω μονάδων Xposed ή Frida, που υποκλέπτουν μεθόδους Java και παραποιούν τις επιστρεφόμενες τιμές. Η native υλοποίηση σε C++ μέσω JNI είναι σημαντικά πιο ανθεκτική: τα εργαλεία δυναμικής ανάλυσης που λειτουργούν σε επίπεδο Java δεν βλέπουν native κλήσεις libc, όπως stat, access, popen και 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;
}
Ο native έλεγχος δεν χρησιμοποιεί Java API, καθιστώντας τον αόρατο σε εργαλεία παράκαμψης που λειτουργούν σε επίπεδο Dalvik/ART. Για πρόσθετη προστασία, συνιστάται η αποθήκευση σταθερών (λίστα διαδρομών) όχι στο read-only τμήμα, αλλά ο υπολογισμός τους μέσω απλών αναστρέψιμων συναρτήσεων. Η κλήση stat από τη libc απευθύνεται απευθείας στον πυρήνα Linux, παρακάμπτοντας τα περιτυλίγματα Java, και δεν μπορεί να υποκλαπεί μέσω Xposed.
Οι προγραμματιστές ασφάλειας πρέπει να κατανοούν τις υπάρχουσες μεθόδους παράκαμψης για να χτίσουν ένα ανθεκτικό σύστημα ανίχνευσης. Κάθε μέθοδος παράκαμψης απαιτεί αντίμετρο στο κατάλληλο επίπεδο.
Magisk — το πιο δημοφιλές εργαλείο root σε Android 9–14. Το Magisk Hide κρύβει την παρουσία su από το /proc και παραποιεί τα αποτελέσματα ελέγχου διαδρομών. Το Magisk λειτουργεί σε επίπεδο πυρήνα και υποκλέπτει stat() και access() προτού τα δει η εφαρμογή. Αντίμετρο: έλεγχος παρουσίας του ίδιου του Magisk μέσω ύπαρξης /sbin/.magisk ή έλεγχος μέσω ανάγνωσης των δικών του maps — το Magisk ενσωματώνει τη βιβλιοθήκη του σε κάθε διεργασία.
Frida — εργαλείο δυναμικής ενόργανης μέτρησης που μπορεί να υποκλέπτει native συναρτήσεις μέσω Ptrace ή Dobby. Η Frida αντικαθιστά την επιστρεφόμενη τιμή κάθε ελέγχου, παραποιώντας το αποτέλεσμα stat σε ENOENT. Αντίμετρο: έλεγχος ακεραιότητας native συναρτήσεων μέσω υπολογισμού αθροίσματος ελέγχου εντολών στη μνήμη και ανίχνευση Frida μέσω ανάλυσης /proc/self/maps για παρουσία frida-agent.so ή frida-helper.
Το Root Detection που υλοποιείται σε Java αφαιρείται σε 2–3 λεπτά: το APK αποσυσκευάζεται μέσω apktool, στον κώδικα smali η επιστρεφόμενη τιμή της μεθόδου αλλάζει σε false, το APK επανασυναρμολογείται και υπογράφεται. Αντίμετρο: μεταφορά κρίσιμης λογικής σε native κώδικα και έλεγχος ψηφιακής υπογραφής της εφαρμογής κατά το runtime μέσω Signature API ή σύγκριση hash APK με το πρότυπο στον διακομιστή.
Το αποτελεσματικό Root Detection βασίζεται σε πολυεπίπεδη αρχιτεκτονική. Κανένα μεμονωμένο μέσο δεν παρέχει επαρκές επίπεδο προστασίας. Ο συνδυασμός στατικών και δυναμικών ελέγχων, native κώδικα και ελέγχου από τον διακομιστή δίνει μέγιστη ανθεκτικότητα.
Μην βασίζεστε μόνο στον έλεγχο από την πλευρά του πελάτη. Στείλτε τα αποτελέσματα Root Detection μαζί με ένα κωδικό συνεδρίας μιας χρήσης στον διακομιστή. Ο διακομιστής λαμβάνει την απόφαση αποκλεισμού ή περιορισμού λειτουργικότητας. Αυτό αποτρέπει επιθέσεις σε επίπεδο API, όπου η εφαρμογή πελάτη μπορεί να τροποποιηθεί, αλλά ο διακομιστής παραμένει αξιόπιστο μέρος.
Ο κώδικας Root Detection πρέπει να είναι συσκοτισμένος. Εάν ο εισβολέας βλέπει στο jadx μια σαφή ακολουθία ελέγχων διαδρομών su — η παράκαμψη θα διαρκέσει λεπτά. Χρησιμοποιήστε ProGuard ή DexGuard για μπέρδεμα της ροής ελέγχου και κρυπτογράφηση συμβολοσειρών. Η συσκότιση αυξάνει τον χρόνο ανάλυσης του κώδικα ασφάλειας από λίγα λεπτά σε αρκετές ώρες.
Η λίστα ελεγχόμενων διαδρομών, πακέτων και δεικτών πρέπει να ενημερώνεται με κάθε έκδοση της εφαρμογής. Νέα εργαλεία root και παράκαμψης εμφανίζονται μηνιαία. Μια στατική λίστα που δεν έχει αλλάξει για ένα χρόνο δεν ανιχνεύει σύγχρονες μεθόδους. Συνιστάται η φόρτωση τρεχουσών υπογραφών από τον διακομιστή κατά την εκκίνηση της εφαρμογής πριν από την εκτέλεση ελέγχων.
Συχνές Ερωτήσεις
Το Root Detection προστατεύει από την εκτέλεση της εφαρμογής σε συσκευή όπου το sandbox Android είναι απενεργοποιημένο. Σε μια root-αρισμένη συσκευή, οποιαδήποτε εφαρμογή μπορεί να διαβάσει δεδομένα άλλων εφαρμογών. Οι τραπεζικές εφαρμογές και εφαρμογές πληρωμών υποχρεούνται να αποκλείουν τη λειτουργία σε root-αρισμένες συσκευές σύμφωνα με τις απαιτήσεις PCI DSS και τις συστάσεις OWASP Mobile Security.
Το Magisk Hide χρησιμοποιεί τον μηχανισμό προσάρτησης χώρου ονομάτων (mount namespace). Για κάθε διεργασία που καθορίζεται στη λίστα εξαιρέσεων, το Magisk δημιουργεί ένα απομονωμένο namespace όπου το su δυαδικό είναι αόρατο. Οι κλήσεις συστήματος stat, access και open σε αυτό το namespace δεν βλέπουν αρχεία Magisk. Το Magisk μπορεί να ανιχνευθεί μέσω ελέγχου ύπαρξης /proc/self/maps και αναζήτησης magisk dump.
Ναι, εάν η εφαρμογή δεν ελέγχει την ακεραιότητα του κώδικά της. Μέσω Frida μπορεί να υποκλαπεί η μέθοδος Java ελέγχου και να εξαναγκαστεί σε επιστροφή false. Αντίμετρο — native υλοποίηση κρίσιμης λογικής σε C++ και έλεγχος ακεραιότητας μέσω hash του αρχείου DEX. Χωρίς συσκότιση, οποιοδήποτε Root Detection σε Java παρακάμπτεται σε 5–10 λεπτά.
Το SafetyNet (παρωχημένο) και το Play Integrity API — είναι έλεγχοι διακομιστή από την Google που επιβεβαιώνουν την ακεραιότητα της συσκευής. Περιλαμβάνουν έλεγχο bootloader, υπογραφής συστήματος και κατάστασης root. Play Integrity API — η συνιστώμενη αντικατάσταση του SafetyNet, που παρέχει τρία επίπεδα: BASIC, DEVICE και STRONG. Το Root Detection στην πλευρά του πελάτη συμπληρώνει την πιστοποίηση διακομιστή.
Εγκαταστήστε την εφαρμογή σε μια πραγματική root-αρισμένη συσκευή (π.χ. Pixel με Magisk). Ελέγξτε εάν ο αποκλεισμός ενεργοποιείται. Στη συνέχεια, δοκιμάστε να κρύψετε το root μέσω Magisk Hide για την εφαρμογή σας και επαναλάβετε τη δοκιμή. Για εις βάθος έλεγχο, χρησιμοποιήστε Frida για υποκλοπή στοχευμένων μεθόδων και βεβαιωθείτε ότι η native προστασία δεν μπορεί να παρακαμφθεί.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης