Детектування Jailbreak/Root у мобільних додатках
Jailbreak та root знімають обмеження піскориці ОС. На jailbroken iOS додаток втрачає гарантії ізоляції Secure Enclave, Frida може зацепити будь-які методи, файлова система читається без обмежень. На рутованому Android — аналогічно, плюс можливість модифікації системних бібліотек через Magisk модулі. Для банківських, медичних та корпоративних додатків робота на таких пристроях — неприйнятний ризик.
Що перевіряємо на Android
Три незалежні рівні перевірки дають кращий результат, ніж один «срібний» метод.
Файлові артефакти. Наявність /su, /system/bin/su, /system/xbin/su, /sbin/su — найстарішим способом. Ховається через Magisk DenyList, але спрацьовує на пристроях з більш старими root-рішеннями.
Спроба виконати su. Runtime.getRuntime().exec("su") — якщо не кидає exception та не повертає ненульовий код одразу, процес su існує. Надійніше файлової перевірки, гірше обходиться.
Google Play Integrity API. Найнадійніший варіант на сьогодні. Сервер запитує у Google вердикт по токену пристрою:
-
MEETS_DEVICE_INTEGRITY— пристрій пройшов перевірку цілісності Android -
MEETS_STRONG_INTEGRITY— апаратна аттестація, важче підробити -
MEETS_BASIC_INTEGRITY— мінімальний рівень
На рутованих пристроях з Magisk без додаткової настройки Play Integrity часто повертає MEETS_BASIC_INTEGRITY або нижче. З MagiskHide/DenyList сучасних версій — може пройти MEETS_DEVICE_INTEGRITY. Абсолютної захисти немає, але це серйозний барйєр.
RootBeer — популярна open-source бібліотека, агрегує кілька перевірок. Підходить для базового рівня, але її наявність у APK саме по собі сигнал для атакуючих — легко ищеться в jadx та вимикається. Для серйозних додатків — тільки як доповнення до нативних перевірок.
Що перевіряємо на iOS
Файлові ознаки. /Applications/Cydia.app, /usr/sbin/sshd, /etc/apt, /private/var/lib/apt — артефакти Cydia та Sileo (пакетних менеджерів jailbreak). Checkra1n залишає /var/checkra1n.dmg. Перевіряємо через C API (stat(), access()), а не через Swift FileManager — Objective-C bridging легше хукається.
Sandbox escape тест. На jailbroken пристрої додаток може писати за межами своєї контейнера. Пробуємо створити файл у /private/:
let path = "/private/jailbreak_test_\(UUID().uuidString)"
let result = FileManager.default.createFile(atPath: path, contents: nil)
// На чистому пристрої — false, на jailbroken — true
Наявність Cydia URL scheme. UIApplication.shared.canOpenURL(URL(string: "cydia://")!) — простий та часто обхідний тест, але у зв'язці з іншими додає рівень.
Apple App Attest. iOS еквівалент Play Integrity. DCAppAttestService генерує attestation key у Secure Enclave, сервер перевіряє через Apple API. На jailbroken пристрої App Attest часто не проходить — порушена ланцюжок доверу.
Обхід детектування та контрмери
Проблема в тому, що всі userspace перевірки обходяться інструментами рівня Frida — хукується повертаємо значення методу. JailMonkey.isJailBroken() повертає false незалежно від стану пристрою за одну рядок Frida-скрипта.
Три принципи, які ускладнюють обхід:
Перевірки в нативному коді (JNI/NDK). Нативний код складніше хукати з скрипта, ніж Java/Kotlin. Помістимо критичні перевірки у .so бібліотеку. Обфускуємо імена функцій.
Розмазана перевірка. Не одна функція isRooted() яку патчат в одному місці, а десятки невеличких перевірок, розкидані по коду, результати яких XOR-комбінуються в runtime. Патчити дороже.
Серверна валідація. Клієнт передає на сервер токен від Play Integrity / App Attest. Сервер приймає рішення. Зловмисник не може підробити підпис Google/Apple без фізичного доступу до HSM.
Що робити при виявленні
Жорсткі завершення роботи — погана UX-практика та неефективна безпека (додаток просто не запуститься, атакуючий виправить перевірку). Краще: деградувати функціональність (сховати чутливі операції), логувати подію на сервері з device fingerprint, інвалідувати сесію при наступному сервер-запиті.
Терміни реалізації базового набору перевірок (файлові артефакти + native checks + Play Integrity/App Attest) — 2–3 дні на платформу. Інтеграція серверної валідації з обробкою результатів — ще 1–2 дні.







