- SELinux
- Проверяем на реальном устройстве
- Как устроено шифрование хранилища
- Мой набор Magisk-модулей
- Что же плохого происходит когда загрузчик разблокируется?
- Внедряемся в систему без установленных root-прав
- Способы получения root
- Настройка Magisk или как пройти SafetyNet
- Постановка задачи
- Как получить root-права?
- Шаги для рутирования Android без ПК
- Зачем нужны root-права?
- Стоит ли делать рут
- Как получить рут-права?
SELinux
Безопасность в android устроена сложнее чем хотелось бы злоумышленникам и представляет из себя многослойную систему. Unix DAC (discretionary access control), привычная нам система пользователей и назначения прав на файлы типа rwxrwxrwx является лишь частью мер по предотвращению злоупотребления операционной системой и устройством. Помимо неё есть ещё MAC (mandatory access control), в android это SELinux (Security Enhanced Linux). Суть MAC в возможности намного более гибко управлять доступом к различным ресурсам чем DAC, в том числе описывая для этого свои уникальные сущности и правила.
Уровни контроля доступа в android
Отсюда следует несколько неочевидный ранее вывод – на android root-права в привычном для других дистрибутивов linux понимании, т.е. когда uid пользователя в системе равен 0, вовсе не означают что мы можем делать всё что угодно. Несмотря на то, что процесс init запущен с uid=0, он не может запустить сторонний сервис. Дело в том что SELinux не оперирует понятиями системных пользователей и групп, и если какое-то действие не было явно разрешено, то он его запретит и ему безразлично пытается ли его совершить непривилегированный пользователь или root. Он работает «выше» DAC и может запретить любое действие, которое DAC разрешил.
Вот отличный пример в android с самим файлом, содержащим политики SELinux:
$ ls -laZ /sys/fs/selinux/policy
-r—r—r— 1 root root u:object_r:selinuxfs:s0 0 1970-01-01 03:00 /sys/fs/selinux/policy
$ cat /sys/fs/selinux/policy
cat: /sys/fs/selinux/policy: Permission denied
На нём стоит доступ для чтения для любых пользователей, но при попытке прочитать его мы получим Permission denied, потому что ни для процессов с контекстом u:r:shell:s0, ни для процессов с контекстом u:r:untrustedapp:s0 нет разрешения на чтение файлов u:objectr:selinuxfs:s0.
SELinux оперирует понятиями контекстов, которые присваиваются файлам и процессам, и правил взаимодействия между объектами принадлежащим разным контекстам. Наборы этих правил объединяются в политики. Они описываются в файлах *.te в исходниках android, можно посмотреть примеры вот тут. Политики собираются на этапе сборки системы и, теоретически, не могут изменяться во время её работы, они компилируются в специальный бинарный формат, который уже использует система.
Контекст SELinux на процессах и файлах можно посмотреть, добавив к выполняемой команде флаг -Z. Например, для просмотра контекстов на файлах в текущей папке можно вызвать команду ls -laZ, а на процессах, соответсвенно, ps -efZ.
Как было упомянуто выше в секции про процесс загрузки системы, первое действие которое совершает процесс init – загружает и применяет политики SELinux, а одна из первых применяемых политик заключается в том что процессу с контекстом u:r:init:s0 запрещается делать transition в другой контекст. Политики SELinux специально строятся по принципу «запрещено всё что не разрешено», и создатели операционной системы, разумеется, позаботились о том, чтобы злоумышленник получивший возможность прописать запуск какого-то сервиса в автозапуск не смог это сделать. Контекст процесса init организован таким образом что он может запустить только те системные сервисы, для которых явно прописано разрешение на запуск во время загрузки системы, и после сборки системы это изменить нельзя.
SELinux может работает в трёх режимах:
В нормально работающей системе android версии от 5.0 SELinux всегда будет в режиме enforcing. Если по каким-то причинам он будет переведён в режим permissive, то пользователю ещё до ввода кода разблокировки покажут большое страшное уведомление об этом и о том что его система небезопасна. Мы точно не имеем права переводить SELinux в permissive режим, потому что это выдаст пользователю факт модификации его устройства, и он может предпочесть уничтожить данные.
В каждой версии android, начиная с 5 политики SELinux сильно ужесточаются и всё меньше и меньше всего остаётся разрешённым. Иронично, но начиная с android 8 даже если прошить в системный раздел исполняемый файл su и сделать его системным и принадлежащим root:root, он не сможет работать без специально назначенных ему политик.
Тем не менее инструменты для получения root-прав существуют, и они умеют обходить ограничения MAC, работать на самых свежих версиях android и даже на устройствах, которые помимо них дополнительно имеют отдельные механизмы контроля целостности системы (например устройства Samsung). Так как же тогда работает root в современных реалиях?
Проверяем на реальном устройстве
Ловить удалённое подключение от устройства будем на Kali в виртуалке. Для этого на ней сгенерируем пейлоад:
И настроим слушатель:
После этого возвращаемся на хост машину.
$ git clone https://github.com/LuigiVampa92/unlocked-bootloader-backdoor-demo.git
$ cd unlocked-bootloader-backdoor-demo
Исполняемый файл по пути revshell/revshell заменим на нагрузку сгенерированную в Kali. После этого приступим к сборке.
Создадим для скрипта сборки переменную окружения, указывающую на абсолютный путь к android-sdk (зависит от вашей операционной системы):
$ ANDROID_SDK_ROOT=/usr/lib/android-sdk
$ export ANDROID_SDK_ROOT
Подготавливаем NDK для сборки. Это нужно сделать именно через установочный скрипт, т.к. скрипту будет нужен отдельный изолированный инстанс NDK для сборки и рассчитывать он будет именно на него:
$ ./buildrevshell.py ndk
Собранные пакеты будут лежать в директории out.
Переходим к установке.
Сперва перезагружаем устройство в режим fastboot. На разных устройствах это делается по-разному. В большинстве случаев необходимо выключить устройство, зажать одну из физических кнопок регулирования громкости (например кнопку прибавления громкости) и не отпуская её нажать на несколько секунд кнопку питания.
$ fastboot boot twrp.img
Небольшое важное отступление. Я смог проверить работу только на устройствах которыми располагаю сам. Среди них были устройства на android 9 и 10, LineageOS 16 и 17, с классическим init как в старых системах и two-stage-init + system-as-root. Среди них не было устройств с system-as-root на android 9 и устройств с A/B партициями. Поэтому если конфигурация вашего устройства отличается, то на нём могут возникнуть непредвиденные проблемы. Я рекомендую сделать бэкапы важных разделов и сохранить их для того, чтобы иметь возможность восстановить их руками, в случае если что-то пойдёт не по плану.
Обычно это будет раздел boot, сделать его бэкап после загрузки TWRP можно так:
Проверьте есть ли у вас отдельные разделы для DTB, для этого зайдите в adb shell и выполните:
Если увидите в списке dtb, dtbo и dtbs, то сделайте и их бэкапы тоже.
Ещё пара дежурных предупреждений:
Поехали. Запускаем sideload через GUI (Меню/Advanced/Sideload) или из терминала:
$ adb shell ‘twrp sideload’
$ adb sideload zip_reverse_shell_install.zip
Важно! Здесь в зависимости от того был ли на устройстве предварительно установлен magisk или нет будет пропатчен или не пропатчен boot раздел. Если на устройстве magisk ранее установлен не был, то необходимо будет сохранить бэкапы оригинальных разделов. Сделать это нужно обязательно, даже если предварительно сделали бэкапы руками, иначе удалять наш инструмент также придётся руками, потому что деинсталлятор будет полагаться на наличие именно этих бэкапов, именно в этом формате. В логе TWRP тоже вылезет большое предупреждение об этом.
Вытаскиваем бэкапы с устройства:
$ adb pull /tmp/backup_original_partitions .
Теперь можно выключить или перезагрузить устройство.
Удаление с устройства производится в обратном порядке:
Перезагружаемся в fastboot
Если сохраняли бэкапы во время установки, то вызываем:
$ adb push backuporignialpartitions /tmp/backuporignialpartitions
$ adb shell ‘twrp sideload’
$ adb sideload zip_reverse_shell_uninstall.zip
Как устроено шифрование хранилища
Для начала разберёмся как устроено шифрование хранилища, потому что это самое труднопреодолимое препятствие для изъятия данных. Шифрование применяется на уровне файловой системы. Существует два основных подхода к организации шифрования:
До первого ввода кода разблокировки данные пользователя всегда зашифрованы, после первого ввода – всегда расшифрованы. Даже когда пользователь в дальнейшем нажимает кнопку питания или система сама уходит в сон, то данные, с точки зрения ОС, больше не переходят в зашифрованное состояние, теперь их защищает только экран блокировки. В android пока не предусмотрен механизм очищения ключей для расшифровки файловой системы из памяти после определённого периода неактивности.
Это значит, что если после того, как устройство было разблокировано хотя бы однажды подключиться к нему, например по adb, то пользовательские данные будут доступны и можно получить к ним доступ даже если экран заблокирован.
Вот так выглядит общее хранилище до первого ввода кода разблокировки:
# ls -la /data/media/0/
total 100
drwxrwx— 13 media_rw media_rw 4096 2021-01-29 10:45 .
drwxrwx— 4 media_rw media_rw 4096 2021-01-29 10:43 ..
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 3aIg6706qnt+JRerXQc,9B
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 5RxSnwRfzXH5JsgykyuneB
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 9QCg2626EAEHNRc,IpjzjC
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 XLrhnulSzxYVPwgkHhs8YC
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:45 ZC6kM5uXi6,coHL+OYgLCB
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 kJJ0DN8Tmhcs7hicwcEZ3A
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 mPaCm6PJHF9,MyimVTRozC
drwxrwxr-x 3 media_rw media_rw 4096 2021-01-29 10:43 qIkgta78EOvsfnjupFXQ+C
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 uAP,C13tjXpxdP8PWVeMRD
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 v33cOjp,wu+hlgBIWnQdjB
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 xxjD9tk7bDh9XZUzoDwMbB
А вот так после:
# ls -la /data/media/0/
total 100
drwxrwx— 13 media_rw media_rw 4096 2021-01-29 10:45 .
drwxrwx— 4 media_rw media_rw 4096 2021-01-29 10:43 ..
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 Alarms
drwxrwxr-x 3 media_rw media_rw 4096 2021-01-29 10:43 Android
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 DCIM
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 Download
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 Movies
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 Music
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 Notifications
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 Pictures
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 Podcasts
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:43 Ringtones
drwxrwxr-x 2 media_rw media_rw 4096 2021-01-29 10:45 bluetooth
На самом деле, шифрование хранилища – самая трудно преодолимая часть нашей задачи по извлечению данных. Обойти шифрование с ключами в аппаратном ТЕЕ никак не представляется возможным, но зато из этой информации следует несколько полезных выводов, а наша задача начинает формироваться в конкретные технические требования.
Это подводит нас к мысли о том, что можно воспользоваться возможностью модифицировать никогда не шифруемую часть системы, внедрить в неё агента, который никак не затронет и не испортит зашифрованные данные, а в последствие даст нам доступ к ней после того как устройство будет возвращено пользователю и он сам первый раз введёт код разблокировки. Поскольку пользователь явно не будет вводить код разблокировки подключив устройство к нашему usb кабелю или находясь в нашей локальной сети, то использование adb нам не подходит и необходимо организовать удалённый доступ в формате reverse-shell.
Мой набор Magisk-модулей
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Получали ли вы Root на своем устройстве?
Нет и не планирую
Нет, но хочу попробовать
Да, но сейчас не имею
Да, пользуюсь root-правами
Проголосовали 127 пользователей.
Воздержались 9 пользователей.
Что же плохого происходит когда загрузчик разблокируется?
Загрузка системы начинается с загрузчика. Загрузчик – это небольшой бинарный компонент, который запускается непосредственно чипсетом и отвечает за загрузку и запуск ядра. Если в настольных дистрибутивах linux мы привыкли в основном к загрузчику grub, то на android смартфонах у нас загрузчиком является aboot. Процесс загрузки происходит следующим образом:
Таблица хэшей dm-verity
Весь этот процесс называется boot flow и отлично проиллюстрирован здесь:
У загрузки с avb может быть 4 конечных состояния, условно обозначаемых цветами:
Задача механизмов avb и dm-verity убедиться в том, что загружаемые ядро и система не были изменены и дошли до устройства пользователя в таком виде в каком их выпустил производитель устройства. Если пользователь решил установить root-права или альтернативную сборку ОС, то он неминуемо нарушит хэши партиций и чтобы система могла продолжить работу а не уходила сразу в «красное состояние» в котором откажется загружаться, ему придётся разблокировать загрузчик и с точки зрения avb перевести устройство в «оранжевое состояние» где android будет закрывать глаза на модификации системы. Этим пользуются и инструменты для получения root, и сторонние сборки, этим могут воспользоваться и злоумышленники, этим воспользуемся и мы.
Логическим следствием перехода в «оранжевое состояние» и отключения avb является возможность загружать образы с ядром не подписанные производителем устройства. Среди любителей модифицировать android самым популярным проектом такого рода является «Team Win Recovery Project» или просто TWRP. TWRP позволяет делать с устройством практически всё, в частности монтировать и модифицировать любые разделы не загружаясь в саму систему непосредственно. Именно эта возможность нам будет нужна для нашей задачи, но для начала надо разобраться с тем, как именно данные пользователя хранятся на устройстве.
Внедряемся в систему без установленных root-прав
Первое приходит на ум мысль о том, что мы можем просто взять устройство с которого хотим извлечь данные, прошить в него magisk используя TWRP, а затем, сразу же следом прошить наш бэкдор. Технически это сработает, т.к. вместе с magisk установятся и его политики SELinux, благодаря которым он сможет работать, но в этом случае, пользователь сразу же поймёт, что что-то не так. Он не устанавливал magisk, а magisk на устройстве есть. Значит, в то время как устройство было изъято злоумышленником, он что-то в него прошивал. Пользователь не сможет заметить этого до того как введёт код разблокировки, однако проблема в том что во время разблокировки интернет на устройстве пользователя может быть выключен, мы не получим удалённый доступ, а пользователь, обнаружив то что в его устройство пытались что-то прошить может удалить необходимую информацию, удалить magisk, начать разбираться что не так, обнаружить бэкдор, или просто сбросить телефон до заводских настроек вследствие чего интересующие нас данные будут уничтожены. Если на устройстве пользователя стоит какое-либо антивирусное решение, то оно может поднять тревогу, если обнаружит что в системе появились root-права полученные через magisk.
Нам нужно постараться любой ценой избежать обнаружения, поскольку от этого зависит получится у нас изъять данные или нет. По сути, нам, в общем-то, не нужны root-права в обычном понимании, нам не нужен терминал с uid=0 для того, чтобы вводить какие-то команды. Нам не нужен исполняемый файл su, т.к. uid=0 мы можем получить и от процесса init. Нам не нужны и сторонние инструменты, которые поставляются с magisk. Нам не нужно приложение MagiskManager. Всё что нас интересует – это контекст u:r:magisk:s0. Получим контекст – получим удалённый доступ.
Нам не только не нужно всё вышеперечисленное, нам очень желательно ничего из этого не устанавливать, т.к. это – маркеры компрометации. Если пользователь запустит какую-нибудь популярную проверку на root, то она нас обнаружит, это же может случиться и в одном из приложений, установленных на его устройстве, оно обнаружит что на телефоне установлены root-права и уведомит пользователя об этом.
Обнаружить root-права на устройстве, в частности magisk, можно по-разному. Можно банально проверить наличие установленного менеджера в системе или попытаться найти испоняемый файл su или magisk (magisk создаёт символическую ссылку su которая на самом деле указывает на исполняемый файл magisk)
Интересный факт: начиная с android 10 в системе появилась служба APEX отвечающая за более простой подход к доставке обновлений системных компонентов. Её идея в том, чтобы добавить в android возможность выборочно доставлять обновления частей системы: добавлять новые и заменять существующие системные библиотеки и части android фреймворка, и главное делать это небольшими пакетами, без необходимости загружать и устанавливать полные образы всех разделов целиком. Более того всё это ложится в стандартную модель управления пакетами в android. То есть идея в том, что это нечто вроде apk, но не для приложений, а для самой ОС. Это критически важно для безопасности, например для того, чтобы в случае обнаружения какой-нибудь новой серьёзной уязвимости в системной библиотеке, как это например случалось с libstagefright когда 95% устройств на рынке были подвержены уязвимости, а обновления до многих устройств шли долгие месяцы, Google мог в течение нескольких часов доставить обновление с заплаткой на 100% устройств которые поддерживают apex. Иронично то, что этот механизм ну очень сильно похож по принципу действия на работу модулей magisk, и на то, как они монтируются поверх системы через зеркала. Я могу только предполагать это, но не исключено, что ребята, которые игрались с безопасностью android устройств и «хакали» их по фану, вдохновили своими подходами системных разработчиков android, которые построили на этом систему обновлений, которая сделает каждое из наших устройств неприступнее для злоумышленников. По-моему, это прекрасно.
Возвращаясь к magisk, особенностью такого подхода является то, что magisk создаёт множество лишних точек монтирования, особенно если установлено много magisk-модулей.
Можно поискать в файловой системе файлы, содержащие в названии magisk, и обнаружить исполняемые файлы:
Ещё больше можно увидеть с root-правами:
Ещё magisk добавляет права на запись в некоторые места файловой системы, где этих прав явно быть не должно, и некоторые приложения для обнаружения root-прав обнаруживают его из-за этого.
Вообще-то, magisk очень хорошо умеет прятаться от других процессов с помощью сервиса MagiskHide, который умеет прятать все точки монтирования и даже заменять некоторые свойства в системе, однако от человека, который будет исследовать файловую систему устройства, особенно до загрузки системы, спрятаться не получится. Поэтому технически подкованный пользователь быстро обнаружит наличие magisk на своём устройстве. Для наших целей это не подходит, т.к. если мы будем обнаружены, данные будет не извлечь.
Это значит, что вместо грубой установки magisk нужно поступить красиво – необходимо разобраться с тем, как именно он закрепляется в системе и как заставляет init загрузить ненастоящие политики SELinux.
План таков: мы возьмём исходники magisk и соберём из них инструмент, который будет внедрять в систему всемогущий контекст u:r:magisk:s0, но больше не будет делать ничего. То есть наша задача сводится к тому, чтобы вместо magisk установить на устройство только политики magisk.
Для начала нам нужно понять как именно magisk внедряется в систему. Суть установки magisk в следующем:
По окончанию мы получаем раздел boot, в котором во время запуска системы, между тем как ядро вызывает запуск процесса init и реальным запуском процесса init появляется окно, в котором magisk подготавливает всё необходимое для своей работы во время уже запущенной системы.
Если очень грубо, то работает это так: magiskinit запускается, находит файл с политиками, патчит его добавляя в него политики необходимые для работы magisk после запуска системы, добавляет в init.rc записи которые запустят сервис magiskd во время загрузки системы после чего запускает оригинальный init, который загружает уже пропатченные политики вместо оригинальных, а далее загрузка происходит привычным образом. На деле, в этом процессе есть огромное множество нюансов.
Во-первых, ramdisk у нас доступен только на чтение. Мы не можем взять и переписать boot раздел по своему желанию, и применить изменения на постоянной основе, поэтому все манипуляции над файлами выполняются в ОЗУ, заново, при каждом запуске системы.
Во-вторых, начиная с android 9, и далее в 10 и 11 очень сильно менялся подход к организации файловой системы во время работы устройства, организации хранения файла с политиками и вообще самого процесса запуска.
До android 9 скомпилированные политики SELinux всегда упаковывались в boot раздел и лежали прямо рядом с ядром, затем появился механизм split-policy, когда для каждого из основных разделов (system, vendor, иногда бывает ещё product), политики компилируются и хранятся отдельно.
Для magiskinit это значит то, что при запуске ему нужно смонтировать все эти разделы, собрать оттуда отдельные файлы с политиками, распарсить, упаковать и сложить в единый файл, найти ему место в файловой системе (которое тоже зависит от многих факторов и версии android), после чего брутально пропатчить прямо в бинарном виде исполняемый файл init – найти место где в условной конструкции выбирается тип политики, принудительно заменить его со split-policy на mono-policy и заменить путь к файлу с политиками на тот что был получен в предыдущем шаге.
Бинарного файла init, пригодного для модификации может и не быть, потому что на некоторых устройствах есть 2SI – two-stage-init или двухэтапный запуск init. Это подход, в котором исходный init файл из ramdisk не запускает систему, вместо этого он монтирует раздел с системой и уже из него запускает /system/bin/init. В этом случае magiskinit придётся не менее брутально прямо в бинарном виде патчить libselinux в системном разделе.
А есть ещё в android подход system-as-root, который обязателен для сборок android 10+. От него зависит что именно будет корнем файловой системы ramdisk или system. И оба этих случая magiskinit обязан учитывать. А ещё в некоторых условиях на некоторых устройствах ramdisk может вообще отсутствовать.
Если интересно узнать подробнее, то разработчик magisk очень хорошо и доступно описал как устроены все эти хитросплетения с запуском init. Я полагаю, что для разработчиков magisk это чистая боль, если раньше процесс загрузки был достаточно единообразным и бесхитростным, то теперь разработчики magisk тратят огромные усилия чтобы подстраиваться под это, а учитывая темп выхода новых версий android, делать это очень непросто.
Тем не менее, для нашей задачи внутреннее устройство magiskinit интересует нас только для того, чтобы понять, как именно внедрить нужные нам изменения в скомпилированные политики и отбросить всё остальное.
В исходниках нас будут интересовать в основном только файлы из директории init. Вкратце, список изменений которые были внесены в код:
На выходе получаем нечто, что можно назвать magisk без magisk. Он будет патчить политики SELinux до запуска init, подкладывая туда всемогущий контекст u:r:magisk:s0, но на этом всё – никакого функционала root-прав и всего такого прочего.
Теперь можно начинать.
Способы получения root
Раньше, когда деревья были высокими а слоны мохнатыми, во времена Android ~4, существовали специальные утилиты как на само устройство так и на ПК, с помощью которых можно было получить root.
Если выражаться точнее, эти утилиты взламывали систему одним из множества способов и снисходительно делились с вами кусочком этого доступа.
Большая часть таких утилит была на китайском языке и тыкаться приходилось буквально вслепую. Вот самые яркие представители этого класса:
Преимущества такого способа получения очевидны — простота получения и относительно высокий шанс успеха. Однако такие недостатки как шпионаж, фоновая установка ПО и в целом непрозрачность схемы, как по мне, перекрывают это преимущество с лихвой. Тем более, что на последних версиях Android вероятность успеха получения прав с помощью этих утилит всё ниже. Не рекомендую данный способ к применению.
В определенный момент, как альтернатива этим утилитам, на арену рутирования выходит OpenSource-проект Magisk разработанный, несомненно, талантливым, программистом, под ником topjohnwu.
Главная особенность данного метода — возможность «внесистемного» внесения изменений с помощью подключаемых модулей. Это означает, что с выключением Magisk-модуля, отменялись изменения в системе, которые вносил этот модуль.
Работает это, на самом деле, проще чем можно подумать. В корне файловой системы создается «зеркало» раздела data (так и называется — data_mirror) и необходимые изменения вносятся в систему посредством создания символических ссылок на этот раздел.
Также, старые версии Magisk «из коробки» способны скрыть факт наличия root-прав от программ, которые не любят их (банковские приложения, например). Новые версии требуют установки дополнительных модулей.
Настройка Magisk или как пройти SafetyNet
В новых версиях (24+) Magisk на смену Magisk Hide пришел новый метод сокрытия root — Zygisk. Его название состоит из слов Zygote — материнского низкоуровнего процесса Android, с помощью которого происходит работа Magisk и собственно названия приложения.
По умолчанию этот режим отключен в настройках Magisk, но я рекомендую включить его при первой же возможности.
Сразу после этого необходимо установить два модуля из Github-репозиториев — Universal SafetyNet Fix и Shamico. Первый нужен для прохождения CTS-аттестации (сертификация устройства SafetyNet), а второй для корректной работы функции скрытия root и DenyList magisk. Установка модулей интуитивно понятна и не должна вызвать вопросов.
Не уходя далеко после установки модулей переходим в раздел «Настройка DenyList», не активируя пункт «Активировать DenyList».
В этом меню мы увидим список установленных приложений. Скрытие root по умолчанию применено к сервисам Google, отдельно включать не надо! В большинстве случаев достаточно проставить галочки рядом с приложениями, от которых вы хотите скрыть рут, но бывают случаи, когда это не работает (например, некоторые банковские приложения). Тогда я советую нажать на плашку с названием приложения. Откроется весь список компонентов, от которых скрывается рут и проставить переключатель возле каждого из них. Приложений, которые обходили бы этот метод я еще не видел.
Для закрепления рекомендую использовать функцию «Скрыть приложение Magisk», поскольку его наличие можно вычислить элементарно по списку установленных приложений (так, например, работает MirPay). MagiskManager пересоберется со случайным именем пакета и предложит себя установить.
Если есть возможность, можно ограничить конкретным приложениям доступ к списку приложений с помощью Xposed-модулей вроде Thanox или XPrivacy Lua и тогда скрывать Magisk Manager не обязательно.
После проделанных действий необходимо как можно скорее перезагрузить телефон. Загрузка может быть слегка дольше, чем обычно.
Без должной настройки сервисы Google вскоре заметят чужака в системе и забракуют устройство по CTS.
Скрытие root для приложения необходимо делать до первого запуска целевого приложения! Мне попадались довольно злопамятные программы, которые раз увидев root, сохраняли мой id на сервере, приходилось либо перешивать устройство, либо подсовывать им фейковый Android ID.
Постановка задачи
Итак, представим ситуацию, мы – злоумышленник, получивший на некоторое время в свои руки смартфон. Устройство – смартфон на базе android с разблокированным загрузчиком. Устройство имеет встроенное шифрование хранилища, его тип – аппаратный, т.е. ключи хранятся в TEE. Устройство заблокировано, для разблокировки необходимо ввести пин-код. Причём устройство находится в BFU (before-first-unlock) состоянии, это значит, что после включения устройства код разблокировки не вводился ни разу и файловая система зашифрована. На устройстве не включен режим отладки и подключиться по adb к нему невозможно. В нём содержатся данные, которые нам необходимо изъять. Устройство нужно будет вернуть владельцу, неповреждённое, в рабочем состоянии, причём владельцу не должно бросаться в глаза что его устройство было скомпрометировано.
Звучит как невыполнимая задача, и так бы оно и было, если бы нам любезно не открыл дверь сам владелец. Современные смартфоны очень хороши с точки зрения безопасности. Возможная поверхность атаки у них крайне мала. В последних версиях ОС android сделано очень многое для защиты данных пользователей. Защита системы выстроена в несколько уровней. Данные шифруются, подписи проверяются, ключи хранятся аппаратно. Везде используется подход «least privilege» – запрещено всё что не разрешено. Приложения работают в рамках серьёзных ограничений. Можно смело утверждать, что современные смартфоны являются одними из лучших примеров безопасных устройств, которые создавал человек.
Если пользователь не совершает явно странные действия вроде скачивания странных apk со странных ресурсов и не выдаёт им явно руками привилегий администратора устройства, то навредить пользователю или украсть его данные довольно затруднительно. И даже эти проблемы являются скорее не дырами в безопасности системы, а следствием свободы, которую android предоставляет пользователям, однако не все распоряжаются ей правильно. Прошли времена, когда безопасность android была поводом для шуток. На сайте известного брокера эксплоитов, компании Zerodium, FCP — full-chain with persistence или полная цепочка удалённой эксплуатации устройства с закреплением в системе в настоящий момент является самым дорогим эксплоитом, за который компания готова выложить до двух с половиной миллионов долларов.
Разблокированный загрузчик роняет уровень сложности этой задачи от невозможного до тривиального. Почему-то тема опасности открытых загрузчиков поднимается довольно редко, и, мне кажется, её значимость здорово недооценена, поэтому давайте разбираться.
Код с примером будет приведён довольно упрощённый и не в самом изощрённом варианте, но рабочий и явно демонстрирующий то, как именно это работает.
Все действия я проводил на устройствах на OnePlus 5T (он же dumpling по принятой в android device tree классификации) на стоковой OxygenOS и LineageOS с версиями соответствующими android 9 и 10, и XiaomiMI6 (он же sagit). Из-за этого некоторые нюансы структуры разделов, и выводы некоторых команд у вас могут отличаться, но общая суть происходящего не изменится.
Я буду часто ссылаться на ресурс source.android.com. Это примерно тоже самое что и developer.android.com но не для разработчиков приложений, а для разработчиков устройств. Там хорошо описана работа ОС, системных компонентов, и т.д. Очень рекомендую, вряд ли где-то можно найти более структурированную информацию по устройству системы.
Как получить root-права?
Мы, наконец, переходим от скучных лекций к решительным действиям.
Для получения таких прав, вы можете воспользоваться одной из перечисленных выше утилит, но только в том случае, если у вас есть возможность восстановить систему и нет возможности установить Magisk. В целом, я всё равно не рекомендую такие утилиты к применению.
Более подробно мы будем рассматривать установку Magisk на примере самой последней версии (25.2).
Предполагается, что вы уже разблокировали загрузчик и установили сторонний recovery. Устанавливать стороннюю прошивку необязательно, это не должно вызвать проблем.
Первым делом нам необходимо, как обычно, сделать полный бекап разделов системы на внешний носитель, вроде sd-карты, чтобы если что-то пойдет не так, вернуть как было.
Следующим шагом будет скачивание установочного файла Magisk (исключительно из официального репозитория!). Если ваш recovery позволяет устанавливать APK как zip-архивы, как, например, OrangeFox, то скачанный файл в исходном виде копируем на внешнюю память устройства, поскольку внутренняя зачастую шифруется и вы просто не найдете этот файл из recovery. В случае, если у вас другой recovery, файл Magisk.apk необходимо переименовать в Magisk.zip и таким же образом скопировать на устройство.
Далее необходимо загрузиться в recovery и сделать отдельно резервную копию раздела boot.img. Далее поясню, зачем.
В Magisk имеется возможность полного удаления root с помощью переименования файла установки в uninstall.zip и прошивки в recovery, НО, он не работает на системах с включенным шифрованием data.
Если вдруг какой-то модуль выведет систему из строя и у вас не будет возможности загрузиться в систему, будет очень проблемно этот самый модуль отключить или отключить весь Magisk.
Имея на руках boot исходной системы (без Magisk) мы сможем восстановить конкретно этот раздел и, в большинстве случаев, работоспособность системы.
После того, как бекапы сделаны, люки задраены, просто прошиваем установочный файл Magisk как любой другой архив через recovery. Всё.
В общем и целом, ничего сложного в самом процессе установки нет, после прошивки и загрузки системы, в меню приложений появится приложение «Magisk», которое при первом запуске обновится и будет работать. Самое важно и интересное кроется в настройке.
Шаги для рутирования Android без ПК
После того, как вы узнаете о рисках рутирования Android, вам следует уделить больше внимания выбору рутирующего инструмента. Здесь мы искренне рекомендуем мощный Kingo Root чтобы помочь вам напрямую рутировать Android на вашем устройстве. Вы можете следовать следующему руководству по root Android без компьютера.
Установите KingoRoot на Android
Рут андроид без компа
Запустите приложение «Kingo ROOT», нажмите кнопку «One Click Root», чтобы начать рутировать Android без ПК. Подождите несколько секунд, пока не появится экран результатов. Вы можете получить результат неудачного рутирования в первый раз, настоятельно рекомендуется попробовать несколько раз.
Зачем нужны root-права?
Честно говоря, когда мне задают вопрос, зачем я получал root-права на своем девайсе, я иногда впадаю в ступор, поскольку использую какое-то специфичное ПО, требующее таких разрешений достаточно редко и точечно.
Как хорошие примеры могу привести эффективное использование программ-firewalls, которые с помощью расширенных прав могут более гибко и эффективно контролировать траффик. Также, программы предназначенные для очистки «мусорных» файлов работают гораздо эффективнее, как и разнообразные файловые менеджеры, которые могут позволить вам редактировать системные файлы. Программы для резервного копирования приложений могут сохранять все данные приложения.
Отдельно хотелось бы упомянуть Xposed Framework — специализированное ПО в виде фреймворка, позволяющее одним приложениям изменять поведение системных функций Android в других приложениях и получать более полный доступ к их ресурсам. Например, именно на этом принципе основан Xposed-модуль для перевода текста на любой язык прямо в целевом приложении.
Стоит ли делать рут
Делать рут довольно опасно, да и рядовому пользователю абсолютно незачем
Следующий абзац будет полезен неопытным пользователям, которые беспечно решили, что им обязательно нужны root-права.
Обратной стороной любых прав, в том числе и root, является ответственность. Вы должны понимать, что, получая права супер-пользователя, вы берете на себя ответственность за все те неприятности, которые могут случится с вами и вашим устройством. А неприятностей это может доставить гораздо больше, нежели пользы, особенно, если вы плохо понимаете, как всё устроено.
Приложения, требующие рут-прав, требуют особых навыков взаимодействия с таким софтом. Естественно, им обладают не все, и разработчики включает в абсолютно безвредные с виду приложения вредоносный код и собрать ваши платёжные данные. Про приложения, которые оформляют платные подписки, я вообще молчу.
Как сделать звук в Яндекс.Станции лучше
Но хуже всего, что ведоносное ПО, имеющее доступ к рут-правам, с такими возможностями в теории может вмешиваться даже в работу антивирусных приложений, которые сами такими правами не обладают. Ну да, ладно, не буду пугать вас вирусами, ибо самый страшный вирус находится на расстоянии 20-30 см от девайса и чаще всего держит его в руке. Просто помните, что неопытность, незнание и нежелание разораться, пользователя может нанести больше вреда, чем сам рут.
С помощью root можно угробить телефон и превратить его в кирпич ещё в процессе получения прав супер-пользователя. А вредоносный софт попадает на устройство чаще всего по вине самого пользователя с взломанными игрушками или приложениями. Имея root-права, вредоносный софт способен творить страшные вещи. Поэтому прежде, чем получать их, тщательно взвесьте все плюсы и минусы и хорошенько подумайте, а надо ли оно вам?
Как получить рут-права?
Существует два способа получения прав суперпользователя:
Имея права суперпользователя, действуйте по принципу «не навреди». То есть, если вы не знаете, что это за параметр в меню, лучшее не менять ее значение. Если обычный пользователь при всем желании не может вывести смартфон из строя программным путем, то обладатель рут-прав — вполне. И не забывайте делать на ПК бекап всего важного на смартфоне, чтобы в случае проблем информация не исчезла безвозвратно.