Android remove device and

Remove device from Company Portal for Android

Remove an enrolled device so that it’s no longer managed by your organization. After you remove the device:

  • The device loses access to your organization’s internal apps and websites.
  • The device no longer appears in Company Portal.
  • You can’t install apps from Company Portal.
  • Any settings that were changed on your device when you added it (for example, disabling the camera or requiring a certain password length) no longer apply.
  • If your device was set up just so you can receive work emails, your device won’t appear in the Company Portal anymore.

You can’t unenroll or remove your corporate-owned device from the Microsoft Intune app. The device was enrolled during initial device setup and must be enrolled to access your organization’s resources.

Remove device in Company Portal app

Sign in to Company Portal.

Select Devices and then select the device you want to remove.

Select the menu > Remove Device.

Select OK to finish removing your device.

Disable Company Portal device management

Another way to remove your device from Intune is to disable the Company Portal app. After you disable the app, you can uninstall it. If you’re planning to disable the app temporarily, be aware that you’ll need to re-enroll your device when you’re ready to use the app again.

Sign in to Company Portal.

Tap the main menu.

Tap Remove Company Portal.

Tap OK to remove Company Portal and unenroll the device you’re on.

Uninstall the Company Portal app

Company Portal is a device management app and can’t be uninstalled until you remove your device from it. Once that’s done, tap and hold the Company Portal app icon until you see Uninstall. Tap Uninstall to remove the app.

Alternatively, you can go to Settings > Apps > Company Portal > Uninstall.

Remove the Company Portal app as a device administrator

As a last resort, you can remove your device and uninstall the app by removing Company Portal as device administrator.

For example, if you declined the Microsoft terms of use while initially trying to sign in to the Company Portal app, all subsequent sign-in attempts will be blocked. These steps will help you bypass the Company Portal to remove your device from management.

The actual names of each setting might vary on your Android device.

Option 1:

  1. Select Settings >Security >Additional Security Settings >Device Administrators.
  2. Clear the Company Portal selection.

Option 2:

  1. Select Settings >Lock screen and security >Other security settings >Device admin apps.
  2. Clear the Company Portal selection.

Remove data collected by the Company Portal app

To remove all data that the Company Portal app for Android stores on your device:

  • Clear app data by tapping Applications >[name of app] >Clear data.
  • Delete the following folder: \storage\internal storage\Android\data\com.microsoft.windowsintune.companyportal.

Effects of removing required apps

If you have a company-owned device, your organization might require that Company Portal be on your device at all times. If you uninstall it, you could lose access to protected company resources such as email, apps, Wi-Fi, or VPN, until the app is reinstalled. For more information about installing, updating, or removing required apps, see Add apps to Microsoft Intune.

Next steps

Still need help? Contact your company support. For contact information, check the Company Portal website.

Источник

Android remove device and

Platform-tools: r31.0.3
ADB: 1.0.41 (31.0.3-7562133)
Fastboot: 31.0.3-7562133
Make_f2fs: 1.14.0 (2020-08-24)
Mke2fs: 1.46.2 (28-Feb-2021)
Последнее обновление утилит в шапке: 01.08.2021

ADB (Android Debug Bridge — Отладочный мост Android) — инструмент, который устанавливается вместе с Android-SDK и позволяет управлять устройством на базе ОС Android.
Работает на всех Android-устройствах, где данный функционал не был намеренно заблокирован производителем.
Здесь и далее: PC — ПК, компьютер к которому подключено устройство.
ADB — консольное приложение для PC, с помощью которого производится отладка Android устройств, в том числе и эмуляторов.
Работает по принципу клиент-сервер. При первом запуске ADB с любой командой создается сервер в виде системной службы (демона), которая будет прослушивать все команды, посылаемые на порт 5037.
Официальная страница
ADB позволяет:

  • Посмотреть какие устройства подключены и могут работать с ADB.
  • Просматривать логи.
  • Копировать файлы с/на аппарат.
  • Устанавливать/Удалять приложения.
  • Удалять (очищать) раздел data.
  • Прошивать (перезаписывать) раздел data.
  • Осуществлять различные скрипты управления.
  • Управлять некоторыми сетевыми параметрами.

Поставляется ADB в составе инструментария разработчика Андроид (Android SDK), который, в свою очередь входит в состав Android Studio.

Если что-то неправильно, то в списке подключенных устройств (List of devices attached) будет пусто.

Скрытые команды ADB
adb -d Команда посылается только на устройство подключенное через USB.
Внимание: Выдаст ошибку, если подключено больше одного устройства.

adb -e Команда посылается на устройство в эмуляторе.
Внимание: Выдаст ошибку, если подключено больше одного эмулятора.

adb -s Команда посылается на устройство с указанным серийным номером:

adb -p Команда посылается на устройство с указанным именем:
Если ключ -p не указан, используется значение переменной ANDROID_PRODUCT_OUT.

adb devices Список всех подсоединенных устройств.

adb connect [: ] Подсоединиться к андроид хосту по протококу TCP/IP через порт 5555 (по умолчанию, если не задан).

adb disconnect [ [: ]] Отсоединиться от андроид подключенного через TCP/IP порт 5555 (по умолчанию, если не задан).
Если не задан ни один параметр, отключиться от всех активных соединений.

adb push Копировать файл/папку PC->девайс.

adb pull [ ] Копировать файл/папку девайс->PC.

adb sync [ ] Копировать PC->девайс только новые файлы.
Ключи:
-l Не копировать, только создать список.

adb shell Запуск упрощенного unix shell.
Примеры использования

adb emu Послать команду в консоль эмулятора

adb install [-l] [-r] [-s] Послать приложение на устройство и установить его.
Пример: adb install c:/adb/app/autostarts.apk Установить файл autostarts.apk лежащий в папке /adb/app/ на диске с:
Ключи:
-l Блокировка приложения
-r Переустановить приложение, с сохранением данных
-s Установить приложение на карту памяти
Установка split apk

adb uninstall [-k] Удаление приложения с устройства.
Ключи:
-k Не удалять сохраненные данные приложения и пользователя.

adb wait-for-device Ждать подключения устройства.

adb start-server Запустить службу/демон.

adb kill-server Остановить службу/демон.

adb get-state Получить статус:
offline Выключен.
bootloader В режиме начальной загрузки.
device В режиме работы.

adb get-serialno Получить серийный номер.

adb status-window Непрерывный опрос состояния.

adb remount Перемонтировать для записи. Требуется для работы скриптов, которые изменяют данные на.

adb reboot bootloader Перезагрузка в режим bootloader.

adb reboot recovery Перезагрузка в режим recovery.

adb root Перезапуск демона с правами root

adb usb Перезапуск демона, прослушивающего USB.

adb tcpip Перезапуск демона, прослушивающего порт TCP.

adb ppp [параметры] Запуск службы через USB.
Note: you should not automatically start a PPP connection. refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1
Параметры:
defaultroute debug dump local notty usepeerdns

FastBoot — консольное приложение для PC. Используется для действий над разделами

fastboot devices Список присоединенных устройств в режиме fastboot.
fastboot flash Прошивает файл .img в раздел устройства.

fastboot erase Стереть раздел.
Разделы: boot, recovery, system, userdata, radio
Пример: fastboot erase userdata Стирание пользовательских данных.

fastboot update Прошивка из файла имя_файла.zip

fastboot flashall Прошивка boot + recovery + system.

fastboot getvar Показать переменные bootloader.
Пример: fastboot getvar version-bootloader Получить версию bootloader.

fastboot boot [ ] Скачать и загрузить kernel.

fastboot flash:raw boot [ ] Создать bootimage и прошить его.

fastboot devices Показать список подключенных устройств.

fastboot continue Продолжить с автозагрузкой.

fastboot reboot Перезагрузить аппарат.

f astboot reboot-bootloader Перезагрузить девайсв режим bootloader.
Перед командами fastboot можно использовать ключи:
-w стереть данные пользователя и кэш
-s Указать серийный номер устройства.
-p

Указать название устройства.
-c Переопределить kernel commandline.
-i Указать вручную USB vendor id.
-b Указать в ручную базовый адрес kernel.
-n

Указать размер страниц nand. по умолчанию 2048.

Команду logcat можно использовать с машины разработки
$ adb logcat
или из удаленного shell
# logcat Каждое сообщение лога в Android имеет тэг и приоритет
Тэг – это строка указывающая компонент системы, от которого принято сообщение (например: View для системы view)
Приоритет – имеет одно из нижеследующих значений (в порядке от меньшего к большему):
V — Verbose (Низший приоритет).
D — Debug
I — Info
W — Warning
E — Error
F — Fatal
S — Silent (Наивысший приоритет, при котором ничего не выводится).

Получить список тэгов, используемых в системе, вместе с их приоритетами можно запустив logcat. В первых двух столбцах каждого из выведенных сообщений будут указаны / .
Пример выводимого logcat сообщения:
I/ActivityManager( 585): Starting activity: Intent

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

Пример ниже выводит в лог все сообщения с тэгом «ActivityManager» с приоритетом «Info» или выше, и сообщения с тэгом «MyApp» и приоритетом «Debug» или выше:
adb logcat ActivityManager:I MyApp:D *:S
Последний элемент в выражении фильтра *:S устанавливает приоритет «silent» для всех остальных тэгов, тем самым обеспечивая вывод сообщений только для «View» и «MyApp». Использование *:S – это отличный способ для вывода в лог только явно указанных фильтров (т.е. в выражении фильтра указывается «белый список» сообщений, а *:S отправляет все остальное в «черный список»).

Читайте также:  Конструктор электросхем для андроид

При помощи следующего выражения фильтра отображаются все сообщения с приоритетом «warning» или выше для всех тэгов:
adb logcat *:W

Если logcat запускается на машине разработчика (не через удаленный adb shell), можно также установить значение выражения фильтра по умолчанию задав переменную окружения ANDROID_LOG_TAGS:
export ANDROID_LOG_TAGS=»ActivityManager:I MyApp:D *:S»

Следует обратить внимание что задав переменную окружения ANDROID_LOG_TAGS она не будет работать в эмуляторе/устройстве, если вы будете использовать logcat в удаленном shell или используя adb shell logcat.
Вышеописанная команда export работает в ОС *nix и не работает в Windows.

Контроль формата вывода лога

Сообщения лога в дополнение к тэгу и приоритету содержат несколько полей метаданных. Можно изменять формат вывода сообщений показывая только конкретные поля метаданных. Для этого используется параметр -v и указывается один из ниже перечисленных форматов вывода.

brief Показывать приоритет/тэг и PID процесса (формат по умолчанию).
process Показывать только PID.
tag Показывать только приоритет/тэг.
thread Показывать только процесс:поток и приоритет/тэг.
raw Показать необработанное сообщение, без полей метаданных.
time Показывать дату, время вызова, приоритет/тэг и PID процесса.
long Показывать все поля метаданных и отдельно сообщения с пустыми строками.

При запуске logcat можно указать формат вывода используя параметр -v:
adb logcat [-v

Источник

Ломаем Android. Как глубока кроличья нора?

Мой первый Android телефон Galaxy Note N7000 был приобретен сразу после анонса в октябре 2011 года. Благодаря одному немецкому умельцу под ником bauner, у меня была возможность использовать последнюю версию CyanogenMod (ныне LineageOS). До тех пор, пока полтора года назад телефон не умер от китайской автомобильной зарядки.

Замену искал долго и остановился на Kyocera (да, они и телефоны выпускают) KC-S701. Он отличается брутальным внешним видом и отсутствием сенсорных кнопок. О root доступе к телефону я тогда даже и не задумывался, полагая, что нынче каждый телефон тем или иным способом имеет возможность получения root. И найдется умелец, который сможет под него портировать CyanogenMod. Я ошибался.

За полтора года было выпущено всего одно обновление — фикс падения ядра от специально сформированного ping пакета. А Android KitKat уже год назад был не первой свежести. Root доступ на этот телефон так никто и не получил, и никакой информации о нем не было. Отмечу, что тоже самое железо используется в американской версии телефона Kyocera Brigadier E6782, в котором по-умолчанию активизирован режим fastboot и нет ограничения на запуск неподписанных ядер (именно запуск, а не прошивку, и только при использовании непропатченного bootloader’а, CVE-2014-4325) и присутствует возможность загружаться в эти режимы путём зажатия кнопок телефона. Стараниями Verizon (а может Kyocera?) версия Android на Brigadier была обновлена до Lollipop.

Итак, я решил разобраться с процессом получения root на Android самостоятельно.

Два месяца назад я ничего не знал об устройстве Android (а сейчас я еще больше не знаю). Большую часть знаний пришлось добывать изучением исходных кодов и экспериментами, т.к. информации о взломе Android в интернете очень мало. Последующее описание справедливо для Android 4.4 KitKat, но не исключено, что оно заработает и на более новых версиях.

Хочу обратить ваше внимание на то, что в данном обзоре описан исключительно мой конкретный опыт взлома Android на конкретной модели телефона, поэтому будьте предельно осторожны с его применением в своей практике, если не хотите внезапно получить мертвый телефон. Перед началом исследований я рекомендую забыть о том, что вы пользуетесь взламываемым телефоном в повседневной жизни и сделать backup с последующим hard reset. Это обезопасит ваши данные при совершении ошибки.

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

Все исследования проводились в Linux окружении.

Dirtycow (CVE-2016-5195)

Простыми словами dirtycow (рабочий эксплойт под Android) позволяет заменить память любого процесса (полезно, если хорошо знаешь ASM) или любой доступный для чтения файл, даже если он находится на readonly файловой системе. Желательно, чтобы подменяемый файл был меньше либо равен по размеру заменяемому. Основная атака в dirtycow для Android — подмена /system/bin/run-as — подобие sudo для отладки приложений. Начиная с API android-19 (таблица соответствия версий API и Android) /system/bin/run-as имеет CAP_SETUID и CAP_SETGID capabilities флаги (в старых версиях используется обычный suid bit — 6755).

Если файловая система будет примонтирована в режиме read-write, то всё, что dirtycow подменяет, окажется на файловой системе. Потому необходимо сделать backup оригинального файла и восстановить его после получения доступа, либо не перемонтировать файловую систему в режиме read-write. Как правило раздел /system в Android по умолчанию примонтирован в режиме read-only.

Не зря dirtycow считается одной из серьезнейших уязвимостей, обнаруженных в Linux. И при наличии знаний с помощью dirtycow можно обойти все уровни защиты ядра, в том числе и SELinux.

SELinux

Если коротко, то:

  • контекст процесса SELinux менять можно, если подобная операция описана в правилах sepolicy. В версии Android 4.4 (KitKat) есть возможность повысить привилегии, изменяя контекст. Но начиная с 5.x это уже сделать нельзя.
  • существуют контексты файлов.
  • Кроме контекста файлов и процессов в Android реализованы контексты для параметров property_contexts.

adbd и консоль

Единственный доступный способ получения относительно привилегированного shell в production устройствах Android — developer mode. Developer mode запускает демон adbd, который может выступать в том числе и как аналог ssh/telnet. В Android KitKat он находится в initramfs по пути /sbin/adbd и не доступен для чтения для не-root пользователей. Изначально adbd запускается под пользователем root и работает в SELinux контексте/домене init (используется процессом init и как правило имеет больше привилегий, чем другие домены). Если в /init.rc явно указан контекст процесса, например seclabel u:r:adbd:s0, то процесс запускается сразу в указанном контексте. При инициализации adbd в зависимости от параметров компиляции (user, userdebug или eng и параметров Android (properties) понижает привилегии, а именно меняет текущего пользователя с root на shell, устанавливает SELinux context в shell и урезает все системные capabilities кроме CAP_SETUID и CAP_SETGID (что требуется для отладки приложений через run-as ). Так называемый Capability Bounding Set не позволяет дочерним приложениям повышать capabilities, только понижать. Эти привилегии позволяют делать на телефоне чуть больше, чем ничего. Просмотреть capabilities текущего процесса можно командой cat /proc/self/status | grep CapBnd . А расшифровать их можно с помощью команды capsh (не доступна на Android), например:

Текущий SELinux context можно просмотреть командой id или cat /proc/self/attr/current . Предыдущий контекст процесса можно просмотреть командой cat /proc/self/attr/prev .

Просмотр context’а файлов: ls -Z
Просмотр context’а запущенных процессов: ps -Z

Получаем root доступ

root, да не тот

Первое, что я сделал это использовал dirtycow по прямому назначению — подменил /system/bin/run-as , который задал UID/GID в 0 (тоже самое делает su). Однако монтировать файловую систему я не мог, даже tmpfs. Загружать модули ядра я тоже не мог. Просматривать dmesg — нет. Я даже не мог просматривать директории, которые имели права 700 и принадлежали другим системным пользователям. Я мог лишь читать и писать в блочные устройства, а просмотр файлов или директорий был возможен благодаря заданию UID/GID определенного пользователя (написал свой велосипед — аналог su, который мог задавать selinux context и пользователя/группу).

Первым делом я сделал дамп всей прошивки, boot и recovery:

Изучить дамп можно утилитами kpartx и unpackbootimg . Команда kpartx -a mmbblk0.img создает виртуальное блочное устройство, доступное по пути /dev/mapper/loop0 . С ним можно работать как с любым другим блочным устройством. Дампы разделов boot и recovery распаковал утилитой unpackbootimg .

Потом попробовал записать в recovery /dev/zero , проверить и сразу восстановить из дампа.

Раз я мог писать в блочные устройства, значит я мог записать custom recovery. Нашел TWRP от Brigadier, прошил в recovery и перезагрузился в него adb reboot recovery . TWRP я не увидел, а лишь иконку Android’а с восклицательным знаком. Так выглядит стандартный recovery, а значит TWRP не прошился.

Перезагружаюсь в обычный режим, запускаю эксплойт, проверяю hash recovery раздела — hash соответствует оригинальному. Пробую записать данные опять — hash поменялся! Вспоминаю про page cache, чищу ( echo 3 > /proc/sys/vm/drop_caches ) — hash старый. Т.е. всё, что я пишу в блочное устройство улетает без ошибок в /dev/null и иногда оседает в Linux cache. Но обновление прошивки ведь как-то происходит? И пользовательские данные как-то записываются во внутреннюю память. Надо копать дальше.

Пробуем отключить SELinux

На тот момент я думал, что все ошибки об отсутствии привилегий вызваны SELinux (я полностью забыл о том, что могут быть урезаны capabilities). Логов dmesg я не видел, logcat ничего релевантного не показывал. И я начал думать как отключить SELinux.

Первая зацепка, которую я смог найти:

Исходники говорят о том, что при изменении этой опции, init перезагружает политики SELinux из файла /sepolicy .

Т.е. я при помощи dirtycow могу перезаписать /sepolicy и командой setprop selinux.reload_policy 1 загрузить обновленную политику.

Для начала нужно выяснить что из себя представляет /sepolicy . Изучить его можно с помощью команды sesearch (пакет setools в Debian).

В моём случае /sepolicy содержал только allow, что значит — при enforcing режиме SELinux в Android разрешено делать только то, что объявлено в политике. А процессу init разрешалось только загружать политику, но не отключать:

Моей задачей было — разрешить init контексту задать selinux->enforce в permissive (setenforce 0).

Первое, что я сделал — собрал стандартную политику стокового Android, подменил оригинальный /sepolicy , загрузил (под root пользователем setprop selinux.reload_policy 1 ) и получил сообщение в статусной строке, что телефон находится в незащищенном режиме. После этого телефон отказывался запускать приложения, стал очень задумчив, задать permissive режим мне тоже не удалось и в конечном итоге телефон перезагрузился. Отрицательный результат тоже результат, замена /sepolicy сработала.

Первая же мысль: стоковая политика не подходит этому телефону и он при отсутствии прав начинает тупить.

Я собрал новую политику, в которой просто описал все существующие SELinux context и объявил их permissive. Тоже не помогло.

Потом я решил пересобрать политику и по возможности добавить привилегии для shell контекста.

Я нашел статью, в которой говорится как «декомпилировать» политику. Немного повозившись я смог собрать все зависимости и запустить утилиту sedump . На выходе я получил текстовый файл, который я смог собрать обратно (для KitKat checkpolicy -M -c 26 -o sepolicy.new policy.conf ) и даже получить файл с точно таким же размером что и оригинальный sepolicy , но разным hex содержимым. Загрузка новой политики вызвала точно такие же результаты, что и ранее — телефон через какое-то время перезагружался.

Читайте также:  Что такое ics прошивка android

Я решил собрать две политики: из policy.conf , который я получил и из policy.conf , в котором добавлены все привилегии для allow init kernel : security , в том числе и setenforce. Сравнить файлы в hex и по аналогии заменить байты в оригинальном sepolicy .

Как выяснилось две пересобранные политики отличались всего парой байт. Я начал искать похожие совпадения в оригинальном sepolicy, но не нашёл. Затем я просто написал brute force скрипт, который в заданном диапазоне смещений заменяет два байта на «0xFF,0xFF», запускает sesearch —allow | grep «нужный результат» . Таким образом я нашел необходимое смещение в оригинальной политике, заменил байты, подменил оригинальную политику и ничего. Отключить selinux опять не удалось.

Чуть позже я нашел утилиту sepolicy-inject, которая добавляет привилегии в уже скомпилированный sepolicy файл. Если правило уже существует, то добавление максимальных привилегий не увеличивает конечный размер политики. К сожалению запуск утилиты добавляет всего одно правило за раз. Написал скрипт, который добавляет максимальные привилегии для каждого правила. Результатом был файл с политикой, в которой каждое правило содержало максимальные привилегии. Размер файла совпадал с оригинальным. И это опять не помогло.

Потом я узнал, что в Android есть команда load_policy , которая перезагружает политику по любому пути. Танцы с бубном оказались лишними.

Можно было добавить любой permissive домен, загрузить новую политику и работать в контексте этого домена (кстати, supersu от chainfire для новых версий Android так и работает). Но даже это не дало возможности отключить SELinux. Я решил копать в другом направлении.

Копаем recovery

Проверяю разницу между boot и recovery разделами. Все идентично кроме initramfs. В initramfs раздела recovery изучаю init.rc, в котором описан лишь один сервис, который запускает /sbin/recovery . Изучаю strings sbin/recovery | less , затем исходники оригинального recovery. Как видно, по умолчанию recovery просто отображает логотип Android. А если необходимо что-то сделать, то в штатном режиме в раздел /cache записывается файл /cache/recovery/command , который может содержать параметры запуска recovery. Если в этот файл записать —show_text то мы должны увидеть меню.

Запускаю dirtycow exploit, выставляю UID/GID, записываю файл и запускаю adb reboot recovery . Телефон перезагружается и я попадаю в меню стандартного recovery. Уже что-то. Пробую прошить ZIP файл с supersu через adb sideload . Операция прерывается с ошибкой. Толком не смотрю на ошибку, а лезу в код recovery и ищу место, отвечающее за проверку цифровой подписи ZIP файла.

Выясняю, что initramfs содержит публичный ключ res/keys в формате minicrypt, которым проверяется цифровая подпись ZIP файла. Оказалось это стандартный тестовый ключ Android, и что я могу подписать этим ключём любой архив. Проверить это можно следующим образом:

Попробовал установить ZIP напрямую с sdcard, но в recovery при монтировании sdcard возникала ошибка. Изучил etc/recovery.fstab , оказалось что в режиме recovery sdcard монтируется как vfat:

Моя 64Gb флэшка была отформатирована в exfat. Нашел старую sdcard на 2Gb, отформатировал её как vfat, записал ZIP, вставил её в телефон. Recovery в этот раз смог примонтировать карточку и я мог просматривать её содержимое на телефоне. Однако при установке ZIP опять возникла ошибка: E:failed to set up expected mounts for install; aborting.

Команда strings recovery показала, что этот recovery отличается от стокового, по крайней мере там присутствовали строки, относящиеся к Kyocera, и скорее всего к чистке раздела /data . Покопавшись в оригинальных исходниках я выяснил, что интересующая меня ошибка возникает в функции setup_install_mounts в файле roots.cpp .

Т.е. перед тем как применить ZIP, recovery отмонтирует все разделы, но в моём случае что-то идёт не так.

Копаем исходники ядра

Лицензия GPL обязывает производителей смартфонов выкладывать исходники ядра. Спасибо Линусу и Столлману за это. Иногда производители выкладывают что-то левое, иногда правильные исходники, но без defconfig файла, иногда правильные и очень редко с инструкцией как их собирать (например LG).

В моём случае были исходники с правильным defconfig но без инструкции. Немного попотев я смог собрать ядро и убедился, что это не полная липа.

Через продолжительное время я остановился на двух файлах:

hooks

Kyocera долго не думала, а просто запилила хуки на потенциально опасные операции в Android: mount , umount , insmod (к загрузке разрешен всего один модуль — wlan и только если его загрузит init процесс), и прочее. Вот где крылась проблема recovery. Он не мог отмонтировать файловую систему /system ! Эти операции позволялись только init процессу. В том числе я не мог отключить SELinux потому что эта возможность была отключена при компиляции ядра. Обойти эти хуки можно было только, если ядро загружено с определенными параметрами (kcdroidboot.mode=f-ksg или androidboot.mode=kcfactory, о них чуть позже).

restart

Тоже интересный для изучения файл. В нем описываются возможные варианты загрузки телефона:

  • adb reboot bootloader — режим fastboot, в моём телефоне не доступен ( 0x77665500 — hex метка 00556677 в разделе sbl1)
  • adb reboot recovery — режим recovery ( 0x77665502 — hex метка 02556677 в разделе sbl1)
  • adb reboot rtc — так называемый ALARM_BOOT. Так и не понял для чего, метки в sbl1 нет. Возможно имеется в виду https://developer.android.com/reference/android/app/AlarmManager.html
  • adb reboot oem-X (в моём случае oem-1, 0x6f656d01 — hex метка 016d656f в разделе sbl1). Что происходит во время этого режима устанавливается производителем. Судя по исходникам, в этот режим телефон перезагружается при ошибке аутентификации прошивок из раздела modem.
  • adb reboot edl — emergency download, переводит телефон в штатный qualcomm’овский download mode. Телефон определяется как QHSUSB__BULK COM port, по которому можно передать подписанный загрузчик (если не ошибаюсь, то каждый загрузчик предназначен для одного типа SoC и производителя телефонов) и выполнять низкоуровневые операции с телефоном, в том числе и прошить. Обычно используется вкупе с QPST. Для некоторых телефонов загрузчики утекают в сеть, например для Kyocera KYL22. Откуда они берутся — мне неизвестно.
  • Некий download mode, в который через adb reboot не зайти. Вот тут интересно… Но об этом позже.

Немного о том, как происходит загрузка на телефонах с процессором Qualcomm:

Встроенный ROM загрузчик Qualcomm (pbl — primary bootloader) загружает раздел sbl1 (secondary bootloader). sbl1 загружает tz (trust zone), затем aboot (android boot, little kernel, lk). Aboot в свою очередь загружает boot, recovery или fota.

Описание разделов, участвующих при загрузке:

  • tz — Qualcomm Trust Zone. Выполняет низкоуровневые операции, в том числе работает с QFuses (раздел rpmb).
  • rpm — Resource and Power Manager firmware. Прошивка для специализированного SoC, отвечающего за ресурсы и питание.
  • sdi — trust zone storage partition. Данные, которые используются Trust Zone.

Все эти разделы подписаны цепочкой сертификатов.

В некоторых случаях полезно игнорировать обновления прошивки.

FOTA — firmware over the air. В отличие от boot и recovery, fota — это неофициальный режим загрузки Android. Задача fota — обновить прошивку. В Kyocera для этого используется решение от компании Red Bend, которое в 35Mb умещает обновление не только ядра но и раздела /system . Потому запись в раздел /system запрещена, иначе наложение патча на неправильные данные может окирпичить телефон.

На мой телефон имелось обновление. Отважиться на него я мог потому, что я уже имел возможность писать в /cache и прервать обновление в любой момент.

Изучив исходники отвечающего за обновление Java приложения, мне стало ясно как оно происходит:

  • Java приложение скачивает специальный файл /cache/delta/boot_delta.bin , создает файл /cache/delta/Alt-OTA_dlcomplete , подтверждающий успешную загрузку файла, и другие файлы с header’ами.
  • При подтверждении обновления еще раз проверяется наличие этих файлов.
  • Если файлы на месте, то через библиотеку libjnialtota.so происходит модификация раздела fotamng .
  • Происходит перезагрузка.

Перезагрузка происходит не моментально, значит у меня есть возможность удалить файл перед перезагрузкой и посмотреть что происходит с разделом fotamng.

Пишу команду, которая непрерывно делает дамп раздела и переименовывает /cache/delta/boot_delta.bin . Запускаю её сразу после соглашения о перезагрузки телефона. Телефон перезагружается в режим FOTA, рапортует об отсутствии обновления и перезагружается в обычный режим.

Начинаю изучать данные, которые сдампил. В разделе /cache бонусом получаю логи fota, в которых даже есть логи dmseg! Сама перезагрузка в fota инициализируется байтами «1» в разделе fotamng:

После перезагрузки они обнуляются. В dmesg я обратил внимание на наличие параметра ядра kcdroidboot.mode=f-ksg. Вот оно! Т.е. загрузчик снимает защиту для fota. И чисто теоретически, если я запишу раздел boot в fota и перезагружу телефон в этот режим, то я получу ядро с отключенной защитой Kyocera. Но писать в системные разделы я всё еще не могу.

Изучение исходников little kernel (lk)

То, что находится в разделе aboot — загрузчик Android, ванильные исходники которого находятся по адресу: https://source.codeaurora.org/quic/la/kernel/lk/

Там можно найти и информацию как происходит загрузка в некоторые из режимов. Например я нашел информацию о том, что если в раздел misc записать «boot-recovery», то перезагрузиться в recovery можно без adb reboot recovery. При загрузке в recovery эта метка обнуляется. И если recovery загрузиться не может, то телефон попадёт в boot loop и вы его потеряете. Так что будьте осторожны, а лучше избегайте этого варианта перезагрузки.

Там же можно найти код, который переводит системную область emmc в режим read-only. Ответ на вопрос, почему невозможно перезаписать recovery. Эту защиту можно отключить из ядра Linux , если написать соответствующий модуль ядра . Уже всё написано товарищем из страны восходящего солнца, который, похоже, тоже неровно дышит к телефонам компании Kyocera. Модуль с первого раза не сработал, иногда подвешивает mmc в claim mode. Возможно не всё так однозначно и требуется детальное исследование.

Первые успехи

dmesg

Google мне помог ответить на вопрос, почему я не могу прочитать логи ядра: /proc/sys/kernel/dmesg_restrict . Значение этого параметра задается в 1 во время загрузки телефона. Если у пользователя нет CAP_SYS_ADMIN capability, то логи ему не доступны.

uevent_helper

В моём случае, на удивление, была возможность задать /sys/kernel/uevent_helper . Если в этот параметр записать путь до executable файла (shell script тоже сойдёт), то он с определенным интервалом будет запускаться от процесса init в контексте init и что самое важное с full capabilities.

Читайте также:  Звонилка для смартфона андроид

Я написал скрипт:

Загрузил его на телефон и записал его путь в /sys/kernel/uevent_helper . У меня появилась возможность видеть dmesg!

Патченный adbd

Т.к. мне надоело иметь доступ к урезанной консоли Android, а патчить бинарник adbd мне лень, то я решил собрать свой adbd с блэкджеком и шлюхами . Для этого пришлось скачать 70 Gb исходников Android, чтобы не возиться с каждой зависимостью по отдельности. Убрал проверку при которой происходит урезание capabilities, скомпилировал, подменил /sbin/adbd и получил полноценную root консоль. Теперь я могу монтировать файловые системы, смотреть dmesg без отключения dmesg_restrict, спокойно просматривать и редактировать файлы, которые не принадлежат root и многое другое. Но я пока не могу монтировать /system раздел и загружать модули в ядро.

Кстати, этой процедуры можно избежать, скомпилировав lsh и подставить его путь в /sys/kernel/uevent_helper . Желательно обернув запуск lsh в скрипт, который задаёт PATH environment, иначе придется задавать полный путь к каждой команде.

WiFi в моем телефоне работает через модуль ядра. WiFi включен — модуль загружен. WiFi выключен — модуль выгружен. Если подменить модуль на свой, то при включении WiFi должен загрузиться подставной модуль. На моё счастье цифровая подпись модулей не проверялась. Первое, что я попробовал, это собрать и загрузить модуль, который отключает SELinux путем замены памяти ядра на Amazon Fire Phone: https://github.com/chaosmaster/ford_selinux_permissive

Чтобы собрать модуль, требуется более-менее соответствующие исходники ядра и файл Module.symvers. Если исходники точно соответствуют тому ядру, что используется на телефоне, то Module.symvers , сгенерированный автоматически при сборке ядра должен подойти.

Если при загрузке модуля ядро будет ругаться (disagrees about version of symbol module_layout), то потребуется извлечь Module.symvers из boot раздела. Это можно сделать, используя скрипт https://github.com/glandium/extract-symvers:

Нельзя просто так взять и собрать свой модуль для телефона Kyocera.

Помните список доступных для загрузки модулей? Модуль должен называться wlan и никак иначе. Решается это просто:

  • создаю symlink wlan.c на исходник модуля
  • правлю Makefile

Модуль на удивление загрузился (память, которую занимает модуль wlan сократилась, проверяется командой lsmod), но SELinux не отключился.

В dmesg не было никакой информации от подставного модуля. А всё потому, что у ядра есть еще один параметр: /proc/sys/kernel/printk , который фильтрует INFO логи, в том числе модулей. Я понизил порог всех логов: echo ‘8 8 8 8’ > /proc/sys/kernel/printk . Перезагрузил модуль и увидел, что модуль просто не нашел требуемой маски, потому отключить SELinux не удалось.

Единственное, что я не уяснил, как программно вызвать отключение и включение WiFi. Мне приходится выключать/включать WiFi вручную через интерфейс Android.

Пишем свой модуль

Снимаем защиту

SELinux отключить не удалось, но по аналогии с модулем https://github.com/chaosmaster/ford_selinux_permissive можно попробовать сделать тоже самое, но с Kyocera hooks. Мне нужно лишь задать переменную kc_bootmode или kc_kbfm в единицу.

В ядре Linux есть возможность получить адреса указателей всех функций и переменных: cat /proc/kallsyms . По умолчанию эти адреса отображаются как 0. Это работает очередная защита ядра. Отключить её можно так: echo 0 > /proc/sys/kernel/kptr_restrict .

Получив адрес нужной функции, я мог передать в неё параметр и функция задаст переменную в 1. Опытным путем выяснил, что не все ядра отображают kallsyms для переменных (тип d или D, регистр говорит глобальная переменная или нет), поэтому в примерах я использую указатели на функции. Возможно это определяется опцией CONFIG_KALLSYMS_ALL при компиляции ядра.

Описываю функцию в модуле:

Можно адреса найти динамически:

Загрузка подставного модуля отключила встроенную защиту! Теперь я могу монтировать /system и загружать любой модуль ядра независимо от его имени.

Системная область emmc всё еще доступна только для чтения и не позволяет редактировать /system раздел на постоянной основе. Файлы редактируются, но при очистке cache все возвращается в исходное состояние.

Всё-таки отключаем SELinux

Из спортивного интереса я всё-таки решил отключить SELinux. Заменить defined значение selinux_enabled мы не можем, но мы можем разыменовать структуру с hooks функциями security_ops .

Это делается вызовом функции reset_security_ops :

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

Перезагружаемся в download mode

Та же операция работает и с download_mode , о котором я писал выше. После загрузки модуля телефон перезагружается в спец режим, который работает как usb mass storage device. Т.е. я имею доступ ко всем разделам телефона без защиты от чтения! Попробовал записать свой recovery.

Пришлось ограничить скорость записи, иначе телефон отваливается и запись прекращается. Возможно это результат переполнения кэша mass storage загрузчика. Пришлось написать хак:

Загрузил телефон, выполнил adb reboot recovery и ничего. Только вибрация с последующей обычной загрузкой. Помните про раздел misc , не стоит проверять recovery через запись в этот раздел.

При помощи этого же способа я примонтировал /system раздел к компьютеру и вручную записал на него supersu. Первоначальная задача выполнена: перманентный root доступ получен. Осталось автоматизировать загрузку подставного WiFi модуля, который отключает hooks. И хорошо бы, чтобы WiFi после этого оставался работоспособным. А еще лучше разблокировать загрузчик, чтобы загружать своё ядро.

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

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

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

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

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

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

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

Эксперименты с загрузчиками

Для проведения экспериментов я заказал из штатов за символическую сумму Kyocera Brigadier с разбитым экраном.

Я проверил цифровые подписи aboot загрузчиков. Subject’ы сертификатов оказались идентичными, следовательно они могут быть взаимозаменяемыми. Решился на эксперимент: прошить aboot от KC-S701 в Brigadier. Загрузчик заработал. На удивление, защита emmc от записи с этим загрузчиком не включилась и я смог спокойно восстановить загрузчик от Brigadier. Понимая все риски, я решил прошить загрузчик от Brigadier на KC-S701. Я бы получил возможность загружать любое неподписанное ядро и использовать fastboot. В этот раз телефон не загрузился.

Тут история могла бы закончиться, но «телефон не загрузился» — это черный экран. И на моё счастье это был черный экран не Qualcomm QHSUSB__BULK , который требует специального подписанного загрузчика для восстановления телефона, а тот самый download mode, который представляет телефон как USB mass storage. Телефон был восстановлен. На сегодняшний день это последнее, что я предпринял.

То, что еще требует работы или выяснить не удалось

Загрузка Fota

Почему boot раздел не грузится из раздела fota? Ведь они подписаны одним ключём. Если бы загрузка произошла, то я бы получил разлоченный телефон, в котором не пришлось бы подменять модули.

Расшифровка Kyocera properties

Kyocera наряду с android system properties использует свой внутренний механизм properties, который мне тоже не удалось выяснить. Наверняка там хранятся интересные опции, которые могут влиять в том числе и на снятие защиты bootloader’а. В телефоне есть библиотека libkcjprop_jni.so и демон kcjprop_daemon. Библиотеку можно подключить и использовать её функции, но у меня пока не нашлось времени этого сделать.

Опции пишутся на файловую систему, внутри бинарные данные:

Kexec

Kexec позволяет из ядра Linux загрузить другое ядро. По умолчанию в production релизах ядер отключают поддержку Kexec, но его можно включить через модуль ядра. Затем из user-end можно загрузить любое ядро, которое заменит текущее. Это выглядит как хак, но если хочется загружать своё ядро — этот вариант имеет своё место под солнцем.

Уязвимость в QSEE

QSEE — защита в процессорах Qualcomm, в которой недавно уже достаточно давно обнаружили уязвимость. Суть уязвимости — полный доступ к выполнению команд на уровне Trust Zone. Вплоть до загрузки любого ядра.

Пока еще разбираюсь в этом вопросе. Насколько я понял мне необходимо получить доступ к области emmc, называющейся RPMB. Этого можно добиться отправкой специально сформированной SCM командой. В области RPMB (Replay Protected Memory Block) содержатся биты, которые отвечают за lock/unlock статус.

Заключение

Код модулей, aboot загрузчики и библиотека для работы с Kyocera Propertiies находятся в моём репозитории на github: https://github.com/kayrus/break_free.

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

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

Источник

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