History of SELinux
SELinux was originally developed by the NSA to demonstrate the value of MAC and how it can be applied to Linux. It was merged in Linux 2.6 on Aug 2003. Red Hat, and McAfee Corp. are some of the significant contributors to the development of SELinux. Later on, a separate project called Security Enhancements (SE) for Android was led by the NSA to integrate SELinux into Android. This project resulted in SELinux becoming a core part of Android. It was introduced defaulting to Permissive mode in Android 4.3, optionally Enforcing in Android 4.4, and was required by Google’s CTS to be Enforcing in Android 5.0 and above.
Macros
By default, there are several macros available to use while writing the SELinux policy. These macros not only make writing SELinux policy easier but are also recommended to use for various reasons, such as granting a lot of permissions to a certain initiator, granting a specific set of permission for a specific task to an initiator, etc. They reduce the amount of code a developer has to write, group a specific set of rules for specific use cases, and make it easier for fellow developers to read, among many more benefits.
An example of using macros while writing SELinux policy to allow permissions would be:
Example 1: Macros used: r_file_perms
Without macros:
With macros:
Example 2: Macros used: r_dir_file
Without macros: and
With macros:
Notice how using macros shortens the amount of code and still granted the necessary permissions. You can check the available macros in global_macros and te_macros present in platform/system/sepolicy repository of AOSP.
Настройка SELinux
Система SELinux предустановлена вместе с дистрибутивом в системах ,основанных на Red Hat, скорее всего, там уже все компоненты установлены, но в Ubuntu и других подобных дистрибутивах придется все делать самому. Для установки SELInux в Ubuntu выполните команду:
После завершения установки, систему необходимо будет перезагрузить для применения всех настроек, поскольку будет перезаписан файл конфигурации Grub, для передачи необходимых параметров ядру.
После перезагрузки мы можем посмотреть состояние SELinux:
Здесь мы видим, что система включена SELinux status: enabled, Текущий режим Current mode — permissive, то есть мы будем только получать сообщения о нарушениях в логе. Используемая сейчас политика — Ubuntu.
Сейчас давайте включим активный режим, для этого выполните команду:
Отключить активный режим можно передав в ту же команду 0:
Посмотреть используемый сейчас режим тоже можно подобной командой:
Вся основная настройка SELinux выполняется через файл /etc/selinux/config. Здесь можно как полностью отключить selinux, так и настроить используемую политику безопасности.
Этот параметр означает режим работы SELinux, вы можете указать здесь один из трех параметров enforce, permissive и disabled
Используйте disabled чтобы полностью отключить SELinux или любой другой, чтобы включить SELinux обратно. Этот режим будет применяться по умолчанию при старте системы.
Настройка SELinux политик выполняется тоже в этом файле. За политику отвечает параметр SELINUXTYPE:
Вы можете ссылаться на любую политику, расположенную в каталоге /etc/selinux.
Могут использоваться три основные политики:
- targeted (или здесь ubuntu) защищает основные системные сервисы, например, веб-сервер, DHCP, DNS, но не трогает все остальные программы.
- minimum — это политика для экспериментов, основана на targeted, но ее правила не включены по умолчанию, вы можете включать и отключать когда нужно также часто используется на мобильных устройствах.
- strict — самая строгая политика, управляет не только сетевыми службами, но и программами пользователя.
- mls — содержит не только правила, но и различные уровни безопасности. Она позволяет реализовать многоуровневую систему безопасности на основе SELinux.
Политики в Ubuntu необходимо устанавливать отдельно, для targeted и strict установите пакет:
Для применения политики необходимо перезагрузить компьютер, и желательно чтобы SELinux во время этой перезагрузки был в режиме аудита (permissive). Также, чтобы система обновила все метки в файловой системе, возможно, придется создать пустой файл в корне:
Хотите почувствовать всю мощь и заодно недостатки SELinux? Установите значение SELINUXTYPE в strict, и перезагрузите систему:
Только смотрите, чтобы SELinux работал в режиме permissive, иначе быть беде. Политика default реализует и targeted и strict, чтобы получить strict необходимо просто выгрузить модуль unconfined:
Затем запускаем активный режим:
Ну а теперь можете попробовать почитать системные журналы, или включить обратно режим аудита. Ничего не работает? Правильно SELinux блокирует любые неразрешенные действия. У меня окно терминала сразу было закрыто и я больше не мог управлять своей системой. Чтобы получить обратно управление над своим компьютером его необходимо перезагрузить.
Теперь вы знаете как включить, отключить SELinux, а также как поменять политику или режим работы программы. Все остальное выходит за рамки нашей небольшой статьи.
SELinux — это относительно новая подсистема ядра, разработанная агентством национальной безопасности США для улучшения безопасности операционных систем на базе ядра Linux. SELinux создаёт свои атрибуты контроля доступа для файлов и папок, а также позволяет указывать, каким программам можно иметь к ним доступ.
Политика MLS/MCS
Специальная политика основанная на механизме мандатного доступа. Всем
субъектам и объектам присваиваются уровни доступа. В дальнейшем разрешение
или запрет на операцию выдается по соотношению уровней доступа у субъекта и
объекта. Предмет разрешения только две операции — чтение из файла и запись в
файл
Важное отличие этой схемы заключается в том, что разрешения выдаются
не на файлы, а на потоки данных связанных с этими файлами
Правило такое — поток данных не может проходить в направлении понижения
уровня доступа. То есть от более высокого уровня к более низкому уровню. Это
приводит, на первый взгляд, к нелогичному запрету чтения или доступа в
случае если субъект и объект имеют разные уровни доступа. Например субъект с
уровнем доступа «секретно» не может писать в файл с уровнем «несекретно». И
этот же субъект с правом доступа «секретно» не может читать из файла с
уровнем «совершенно секретно», но может писать в этот файл.
Странно?
Однако, логика тут есть, просто она другая. Если субъект, имеющий уровень «секретно», запишет данные
в файл с уровнем «несекретно» то этот файл станет (потенциально) содержать
данные уровня «секретно», но при этом будет доступен субъектам уровня
«несекретно». То есть станет возможна утечка информации. Поэтому в MLS
запись в файлы разрешена только с нижних уровней на верхние.
Эту особенность нужно понимать при присвоении меток уровней доступа.
Помимо уровней, доступ дополнительно регулируется категориями. Субъект не
имеющий права доступа к категории «ВМС», не может получить доступ к данным
которые имеют метку этой категории. Даже если этот субъект имеет самый
высокий уровень доступа.
В контексте SELinux запись об уровнях и категориях выглядит так: «s0-s0:c0.c1023»
где «s0-s0» допустимые уровни, а «c0.c1023» допустимые
категории. Конкретно такая запись — «s0-s0:c0.c1023» означает высший уровень
доступа к любой категории объектов.
Эта часть контекста используется только в специальных политиках MLS/MCS.
В общих политиках типа targeted или strict эта часть контекста просто
установлена в максимальный уровень разрешений и таким образом не влияет на
доступ.
restart
Тоже интересный для изучения файл. В нем описываются возможные варианты загрузки телефона:
- adb reboot bootloader — режим fastboot, в моём телефоне не доступен ( — hex метка 00556677 в разделе sbl1)
- adb reboot recovery — режим recovery ( — hex метка 02556677 в разделе sbl1)
- adb reboot rtc — так называемый ALARM_BOOT. Так и не понял для чего, метки в sbl1 нет. Возможно имеется в виду https://developer.android.com/reference/android/app/AlarmManager.html
- adb reboot oem-X (в моём случае oem-1, — 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.
Все эти разделы подписаны цепочкой сертификатов.
Glossary
- AOSP: Short for Android Open Source Project.
- AVC: Short for Access Vector Cache, the cache used by SELinux to store its decisions regarding access control.
- comm: Short for Communication.
- CTS: Compatibility Test Suite, Google’s test suite for device wishing to ship GMS.
- LSM: Short for Linux Security Modules, a framework which is part of Linux, allows supporting various security implementations.
- MAC: Short for Mandatory Access Control, a type of access control via which an OS constrains the ability of the initiator to perform the action in question.
- macros: A single instruction that expands into a set of instructions when called.
- NSA: Short for National Security Agency of the United States of America.
- regex: Short for Regular Expression.
- scontext: Short for Source Context, also referred to as Domain.
- SELinux: Short for Security-Enhanced Linux.
- SELinux policy: Policy used by SELinux which specifies a set of permissions.
- SoC: Short for System on Chip.
- tclass: Short for Target Class.
- tcontext: Short for Target Context.
Политика SELinux (SELinux Policy)
Совокупность всех описанных в системе соотношений пользователь — роль —
тип (домен) — уровень и категория. Все типы пользователей, все роли, все
типы/домены. Используется два типа политик:
- Type Enforcment (TE) — Roles Based Access Control (RBAC).
Targeted и strict —
наиболее широко используемые TE — RBAC политики SELinux. - Bell-La Padula Model Multi-Level Security (MLS) — Multi-Category
Security (MCS).
Политика targeted — все процессы не внесенные в специальные
ограниченные домены, работают в неограниченном домене unconfined_t. Таким
образом осуществляется возможность выполнения процессов которые еще не
описаны в политике. Но такие процессы фактически выполняются почти с
административными правами. В этом слабое место политики targeted.
Политика strict — все процессы работают в специальных ограниченных
доменах, в неограниченном домене unconfined_t никто не работает. Политика
strict используется узкоспециально, поскольку требуется ее ручная настройка
для каждого конкретного случая. Ведь процессы не описанные в этой политике
просто не будут работать. Но зато эта политика обеспечивает полную защиту в
рамках тех возможностей которые есть в SELinux.
fota
В некоторых случаях полезно игнорировать обновления прошивки.
FOTA — firmware over the air. В отличие от boot и recovery, fota — это неофициальный режим загрузки Android. Задача fota — обновить прошивку. В Kyocera для этого используется решение от компании Red Bend, которое в 35Mb умещает обновление не только ядра но и раздела . Потому запись в раздел запрещена, иначе наложение патча на неправильные данные может окирпичить телефон.
На мой телефон имелось обновление. Отважиться на него я мог потому, что я уже имел возможность писать в и прервать обновление в любой момент.
Изучив исходники отвечающего за обновление Java приложения, мне стало ясно как оно происходит:
- Java приложение скачивает специальный файл , создает файл , подтверждающий успешную загрузку файла, и другие файлы с header’ами.
- При подтверждении обновления еще раз проверяется наличие этих файлов.
- Если файлы на месте, то через библиотеку происходит модификация раздела .
- Происходит перезагрузка.
Перезагрузка происходит не моментально, значит у меня есть возможность удалить файл перед перезагрузкой и посмотреть что происходит с разделом fotamng.
Пишу команду, которая непрерывно делает дамп раздела и переименовывает . Запускаю её сразу после соглашения о перезагрузки телефона. Телефон перезагружается в режим FOTA, рапортует об отсутствии обновления и перезагружается в обычный режим.
Начинаю изучать данные, которые сдампил. В разделе бонусом получаю логи fota, в которых даже есть логи dmseg! Сама перезагрузка в fota инициализируется байтами «1» в разделе fotamng:
После перезагрузки они обнуляются
В dmesg я обратил внимание на наличие параметра ядра kcdroidboot.mode=f-ksg. Вот оно! Т.е
загрузчик снимает защиту для fota. И чисто теоретически, если я запишу раздел boot в fota и перезагружу телефон в этот режим, то я получу ядро с отключенной защитой Kyocera. Но писать в системные разделы я всё еще не могу.
/etc/security/sepermit.conf File
The sepermit.conf(5) file is used by the pam_sepermit.so module to allow or deny a user login depending on whether SELinux is enforcing the policy or not. An example use of this facility is the Red Hat kiosk policy where a terminal can be set up with a guest user that does not require a password, but can only log in if SELinux is in enforcing mode.
The entry is added to the appropriate /etc/pam.d configuration file, with the example shown being the /etc/pam.d/gdm file (the PAM Login Process section describes PAM in more detail):
#%PAM-1.0 auth <nowiki> pam_selinux_permit.so auth required pam_succeed_if.so user != root quiet auth required pam_env.so auth substack system-auth auth optional pam_gnome_keyring.so account required pam_nologin.so account include system-auth password include system-auth session required pam_selinux.so close session required pam_loginuid.so session optional pam_console.so session required pam_selinux.so open session optional pam_keyinit.so force revoke session required pam_namespace.so session optional pam_gnome_keyring.so auto_start session include system-auth
The usage is described in pam_sepermit(5), with the following example that describes the configuration:
# /etc/security/sepermit.conf # # Each line contains either: # - an user name # - a group name, with @group syntax # - a SELinux user name, with %seuser syntax # Each line can contain an optional argument: # exclusive - only single login session will be allowed for # the user and the user's processes will be # killed on logout # # ignore - The module will never return PAM_SUCCESS status # for the user. # An example entry for 'kiosk mode': xguest:exclusive
Previous | |
|
WiFi
WiFi в моем телефоне работает через модуль ядра. WiFi включен — модуль загружен. WiFi выключен — модуль выгружен. Если подменить модуль на свой, то при включении WiFi должен загрузиться подставной модуль. На моё счастье цифровая подпись модулей не проверялась. Первое, что я попробовал, это собрать и загрузить модуль, который отключает SELinux путем замены памяти ядра на Amazon Fire Phone: https://github.com/chaosmaster/ford_selinux_permissive
Чтобы собрать модуль, требуется более-менее соответствующие исходники ядра и файл Module.symvers. Если исходники точно соответствуют тому ядру, что используется на телефоне, то , сгенерированный автоматически при сборке ядра должен подойти.
Если при загрузке модуля ядро будет ругаться (disagrees about version of symbol module_layout), то потребуется извлечь из раздела. Это можно сделать, используя скрипт https://github.com/glandium/extract-symvers:
Нельзя просто так взять и собрать свой модуль для телефона Kyocera.
Помните доступных для загрузки модулей? Модуль должен называться wlan и никак иначе. Решается это просто:
- создаю symlink на исходник модуля
- правлю Makefile
Модуль на удивление загрузился (память, которую занимает модуль wlan сократилась, проверяется командой lsmod), но SELinux не отключился.
В dmesg не было никакой информации от подставного модуля. А всё потому, что у ядра есть еще один параметр: , который фильтрует INFO логи, в том числе модулей. Я понизил порог всех логов: . Перезагрузил модуль и увидел, что модуль просто не нашел требуемой маски, потому отключить SELinux не удалось.
Единственное, что я не уяснил, как программно вызвать отключение и включение WiFi. Мне приходится выключать/включать WiFi вручную через интерфейс Android.
Встречается в статьях
Инструкции:
- Как установить и настроить связку Asterisk + FreePBX на CentOS 8
- Настройка веб-сервера на CentOS 7 со всем необходимым для правильной работы
- Настройка веб-сервера на CentOS 8 со всем необходимым для правильной работы
- Настройка кластера Ceph на Linux CentOS 7
- Использование связки Elasticsearch + Kibana + Logstash на Linux
- Инструкция по установке и использованию GLPI на Linux CentOS
- Установка, настройка и использование системы по сбору логов Grafana Loki на Linux
- Сервер радиовещания на базе Icecast под Windows и Linux
- Настройка L2TP VPN-сервера на CentOS 8 для возможности подкючения стандартными средствами Windows
- Как настроить почту для корпоративной среды на CentOS 8
- Трансляция видео с веб-сервера с помощью NGINX + rtmp
- Установка XMPP-сервера Openfire на CentOS для мгновенного обмена сообщениями
- Инструкция по установке и настройке сервера OpenVPN на Linux CentOS
- Как установить и использовать OpenVZ на CentOS
- Как настроить почту на базе Postfix для корпоративной среды
- Установка и настройка сервера ProFTPd на Linux CentOS 7
- Установка и настройка системы мониторинга Prometheus на Linux
- Установка и настройка файлового сервера Samba на CentOS 8
- Настройка портала TeamPass для совместного хранения паролей
- Как установить и настроить панель управления виртуальными машинами VMmanager
- Установка и настройка FTP-сервера vsFTPd на CentOS 7
- Установка и настройка почтового сервера Zimbra на Linux
- Установка и запуск менеджера управления проектами Taiga на Rocky Linux
Мини-инструкции:
- Отключение Selinux в системе Linux
- Как настроить систему безопасности с SELinux в CentOS
- Шпаргалка по настройке SELinux для различных программ
- Способы отключения использования IP версии 6 в Linux CentOS
- Настройка защиты DNS ответов от BIND при помощи DNSSEC
- Установка и настройка OwnCloud на CentOS 7 или 8
- Инструкция по установке и настройке phplist
- Настройка проксирования почты с NGINX для IMAP, POP3 и SMTP
- Настройка сервера мониторинга Zabbix на Linux CentOS
- Как настроить мониторинг репликации MySQL/MariaDB с помощью Zabbix
- Настройка потоковой репликации СУБД PostgreSQL
- Как наблюдать за репликацией в PostgreSQL с помощью Zabbix
- Установка и настройка своего локального репозитория CentOS
- Установка панели управления ISPmanager на Ubuntu или CentOS
- Как создать свой собственный образ для Docker
- Отправка логов на удаленный сервер с помощью journald
- Настройка rsyslog для хранения логов на удаленном сервере Linux
- Установка и настройка LDAP сервера FreeIPA на Linux CentOS
- Установка и настройка CRM Битрикс24 от 1С на Linux CentOS
- Настройка мониторинга RAID LSI MegaRaid на Linux с помощью Zabbix
- Как установить и настроить сервер OpenVPN на CentOS 8
- Установка и использование сервера Freeradius на Linux CentOS 8
- Настройка сервера видеоконференцсвязи OpenMeetings на Linux CentOS 8
- Как установить и настроить telegraf + InfluxDB для хранения метрик
- Установка и настройка сервера NextCloud на CentOS 8
- Установка и использование почтового клиента WebMail Lite на Linux CentOS
- Настройка сервера мониторинга Zabbix 5 на Linux CentOS 8
- Организация сервиса календаря и адресной книги на базе Baikal
- Установка и настройка STUN/TURN сервера на базе coturn под Linux CentOS
- Как установить Jenkins на операционную систему Linux CentOS
- Установка и запуск в качестве сервера на Linux CentOS приложения Jupyter Notebook
- Примеры настройки сервисов и их установки с помощью ролей в Ansible
- Настройка Runner в GitLab CI/CD для загрузки изменений проекта на веб-серверы после коммита
- Как настроить прозрачную аутентификацию в NGINX через LDAP
- Установка и настройка сервера Freeradius для проверки подлинности через сервер FreeIPA
- Установка второго сервера FreeIPA с настройкой репликации
root, да не тот
Первое, что я сделал это использовал dirtycow по прямому назначению — подменил , который задал UID/GID в 0 (тоже самое делает su). Однако монтировать файловую систему я не мог, даже tmpfs. Загружать модули ядра я тоже не мог. Просматривать dmesg — нет. Я даже не мог просматривать директории, которые имели права 700 и принадлежали другим системным пользователям. Я мог лишь читать и писать в блочные устройства, а просмотр файлов или директорий был возможен благодаря заданию UID/GID определенного пользователя (написал свой велосипед — аналог su, который мог задавать selinux context и пользователя/группу).
Первым делом я сделал дамп всей прошивки, boot и recovery:
Изучить дамп можно утилитами и . Команда создает виртуальное блочное устройство, доступное по пути . С ним можно работать как с любым другим блочным устройством. Дампы разделов boot и recovery распаковал утилитой .
Потом попробовал записать в recovery , проверить и сразу восстановить из дампа.
Раз я мог писать в блочные устройства, значит я мог записать custom recovery. Нашел TWRP от Brigadier, прошил в recovery и перезагрузился в него . TWRP я не увидел, а лишь иконку Android’а с восклицательным знаком. Так выглядит стандартный recovery, а значит TWRP не прошился.
Перезагружаюсь в обычный режим, запускаю эксплойт, проверяю hash recovery раздела — hash соответствует оригинальному. Пробую записать данные опять — hash поменялся! Вспоминаю про page cache, чищу () — hash старый. Т.е. всё, что я пишу в блочное устройство улетает без ошибок в /dev/null и иногда оседает в Linux cache. Но обновление прошивки ведь как-то происходит? И пользовательские данные как-то записываются во внутреннюю память. Надо копать дальше.
Where should my sepolicy go?
Since the advent of Project Treble, sepolicy has moved from one file in the boot image, to various files on the partition relevant to those policies. For example, in device/lineage/sepolicy, under the “common” folder, we have system, vendor, public, private, and dynamic folders.
- system: Stores sepolicies for any system based modules
- vendor: Stores sepolicies for any vendor based modules
- public: Stores sepolicies accessible to both system and vendor
- private: Stores platform specific sepolicies accessible to system based modules
- dynamic: Stores sepolicies which will be included in vendor image if the target device builds (/system)/vendor inline, otherwise ends up in the system image, e.g. our own Trust HAL
После включения SELinux и перезагрузки все процессы запущены от kernel_t / В логах много ошибок про доступ к kernel_t
Как происходит включение SELinux?
- Создание файла /.autorelabel
- Перезагрузка, ядро видит этот файл и запускает autorelabeling
- Перезагрузка еще раз и запуск ядра с контекстом kernel_t.
Проблемы наступают на этапе два: ядро знает только о контекстах модулей, которые были явно включены до перезагрузки. Например, если не был включен модуль systemd, то:
- Ядро запущено с контекстом kernel_t
- Правил перехода контекста от kernel_t к systemd не срабатывают, т.к. relabel не назначил ему контекст init_exec_t, systemd наследует контекст kernel_t
- Для демонов, которые запускает systemd, тоже не срабатывают правила перехода контекста, поскольку правила написаны для контекста init_t, а не kernel_t. Все демоны запущены от kernel_t.
- ….
- FAIL
Решение
- Перед созданием /.autorelabel вручную включить все нужные модули командой semodule -e $module, или
- Сделать restorecon -R / после перезагрузки и перезагрузить систему еще раз, или
- Сделать systemctl daemon-reexec и перезапустить всех демонов вручную, если вторая перезагрузка неприемлима
- Воспользоваться утилитой offrestorecon* вместо /.autorelabel