Защита памяти и ядра в ОС ROSA — различия между версиями

Материал из Rosalab Wiki
Перейти к: навигация, поиск
м (оформление)
Строка 72: Строка 72:
 
=== Защита от просмотра адресов указателей ===
 
=== Защита от просмотра адресов указателей ===
  
Переменная ядра ОС, отвечающая за доступ к интерфейсам ядра <code>/proc/kallsyms</code> и <code>/proc/modules</code> — это <code>kernel.kptr_restrict<code>. Просматривая эти файлы, можно получать значения адресации памяти для указателей ядра. То есть можно, например, узнать, на какой адрес в памяти ссылается указатель той или иной программы, или загруженного модуля ядра. Переменная может принимать значения <code>0</code>, <code>1</code> и <code>2</code>. Более подробное описание рисков, связанных с атакой на адреса указателей и прототип эксплойта, демонстрирующий такую возможность, приведены по ссылке: https://kernsec.org/wiki/index.php/Bug_Classes/Kernel_pointer_leak
+
Переменная ядра ОС, отвечающая за доступ к интерфейсам ядра <code>/proc/kallsyms</code> и <code>/proc/modules</code> — это <code>kernel.kptr_restrict</code>. Просматривая эти файлы, можно получать значения адресации памяти для указателей ядра. То есть можно, например, узнать, на какой адрес в памяти ссылается указатель той или иной программы, или загруженного модуля ядра. Переменная может принимать значения <code>0</code>, <code>1</code> и <code>2</code>. Более подробное описание рисков, связанных с атакой на адреса указателей и прототип эксплойта, демонстрирующий такую возможность, приведены по ссылке:
 +
 +
https://kernsec.org/wiki/index.php/Bug_Classes/Kernel_pointer_leak
  
 
Если для переменной <code>kernel.kptr_restrict</code> определено значение <code>0</code>, то просматривать значения адресов в памяти может любой пользователь ОС. Если задано значение <code>1</code>, то просматривать адресацию функций может только <code>root</code>. Если значение равно <code>2</code>, то никто не получит информацию об адресации. Рекомендуемое значение — два. При значении единица — отображение адресов заменяется на нули для всех пользователей, кроме <code>root</code>. При значении два — отображение адресов заменяется на нули для всех пользователей, включая <code>root</code>.
 
Если для переменной <code>kernel.kptr_restrict</code> определено значение <code>0</code>, то просматривать значения адресов в памяти может любой пользователь ОС. Если задано значение <code>1</code>, то просматривать адресацию функций может только <code>root</code>. Если значение равно <code>2</code>, то никто не получит информацию об адресации. Рекомендуемое значение — два. При значении единица — отображение адресов заменяется на нули для всех пользователей, кроме <code>root</code>. При значении два — отображение адресов заменяется на нули для всех пользователей, включая <code>root</code>.
Строка 85: Строка 87:
 
<code># sysctl -w kernel.kptr_restrict=2</code>
 
<code># sysctl -w kernel.kptr_restrict=2</code>
  
<code>echo 'kernel.kptr_restrict = 2' >> /etc/sysctl.conf</code>
+
<code># echo 'kernel.kptr_restrict = 2' >> /etc/sysctl.conf</code>
  
 
=== Отключение трассировки процессов ===
 
=== Отключение трассировки процессов ===
pass
 
  
 +
На первом этапе нужно проверить, есть ли в выполняющемся ядре LSM модуль YAMA. Для этого можно выполнить поиск нужной опции в конфигурационном файле ядра, например:
 +
 +
<code>$ cat /boot/config-5.10.118-generic-2rosa2021.1-x86_64 | grep YAMA</code>
 +
 +
<code>CONFIG_SECURITY_YAMA=y</code>
 +
 +
Если есть, то в ОС может использоваться настройка, позволяющая производить ограничения на трассировку процессов. Если нет (выдано значение <code>CONFIG_SECURITY_YAMA is not set</code>), то можно пропустить эту настройку.
 +
 +
Для проверки текущих значений трассировки выполнить (от имени администратора <code>root</code>):
 +
 +
<code># sysctl -a | grep ptrace</code>
 +
 +
<code>kernel.yama.ptrace_scope = 2</code>
 +
 +
Рекомендуется установить запрет трассировки, используя значение <code>2</code> для переменной  <code>kernel.yama.ptrace_scope</code>, или более строгое. Значение <code>2</code> определяет, что трассировку процессов может осуществлять только <code>root</code>. Значение \commandbox{3} полностью отключает трассировку, для всех пользователей, в том числе и для <code>root</code>. В описанной ниже конфигурации трассировка разрешается только пользователю <code>root</code>:
 +
 +
<code># sysctl -w kernel.yama.ptrace_scope=2</code>
 +
 +
<code># echo 'kernel.yama.ptrace_scope = 2' >> /etc/sysctl.conf</code>
 +
 +
=== Ограничения на просмотр сообщений ядра ===
 +
 +
Команда <code>dmesg</code> является очень популярной в ОС Linux. Она выводит на экран сообщения ядра ОС. По умолчанию эту команду может использовать любой пользователь в системе, следовательно её может применять злоумышленник, чтобы получить информацию о системе и некоторых её характеристиках. Соответственно, любой пользователь ОС сможет или напрямую обратиться к этому файлу (<code>$ cat /dev/kmsg</code>), или использовать программы чтения кольцевого буфера аудита ядра, такие как <code>dmesg</code> или <code>rsyslog</code>. Рекомендуется ограничивать пользователей в возможности получать сообщения кольцевого буфера аудита ядра, чтобы снизить вероятность получения информации о работающей системе или ее параметрах.
 +
 +
Переменная ядра ОС <code>kernel.dmesg_restrict</code> отвечает за доступ к интерфейсу кольцевого буфера аудита ядра (файлу <code>/dev/kmsg</code>). По умолчанию доступ пользователей к этому интерфейсу не запрещен. Значение <code>1</code> предписывает, что обращаться к нему может только <code>root</code>. Если установлено значение <code>0</code>, то доступ пользователей к буферу аудита ядра не ограничивается.
 +
 +
Проверить текущее значение политики доступа к интерфейсу кольцевого буфера аудита ядра можно так:
 +
 +
<code># sysctl -a | grep dmesg</code>
 +
 +
<code>kernel.dmesg_restrict = 1</code>
 +
 +
Если при проверке значение отличается от единицы, то нужно выполнить настройку запрета чтения из этого интерфейса всем, кроме <code>root</code>:
 +
 +
# sysctl -w kernel.dmesg_restrict=1
 +
 +
# echo 'kernel.dmesg_restrict = 1' >> /etc/sysctl.conf
 +
 +
=== Противодействие уязвимостям типа Meltdown и Spectre ===
 +
 +
Использование уязвимостей типа Meltdown или Spectre заключается в возможности несанкционированного выполнения кода в пространстве ядра. Например, возникающих при спекулятивном выполнении инструкций процессора (уязвимости типа Meltdown), и/или связанных с особенностями функционирования модуля прогнозирования ветвлений (уязвимости типа Spectre). Эти уязвимости были обнаружены в 2017 году, но все еще продолжают появляться различные их варианты.
 +
 +
Современные процессоры семейства x86 (производства компаний Intel и AMD) предоставляют возможность параллельного использования нескольких «нитей» или «потоков» на каждом процессорном ядре. Такая возможность называется SMT (Symmetric Multi-Threading, симметричная многопоточность). Поскольку «нити» или «потоки» (исходя из конструктивных особенностей ЦП) сохраняют возможности обмена информацией между собой, то это потенциально может привести к несанкционированному обмену информацией между процессами, выполняющимися в разных потоках, но на одном ядре ЦП. Либо может привести к нежелательному раскрытию информации в памяти и т.п. Поэтому в защищаемой системе опции процессора, отвечающие за SMT желательно отключить. При этом настоятельно рекомендуется использовать комплексный подход -- отключать поддержку SMT как на уровне системы ввода-вывода, так и на уровне операционной системы. Данный подход обеспечивает бОльшую уверенность в том, что уязвимости, связанные с недостатками SMT не будут проэксплуатированы, например в том случае, если производитель оборудования предоставит ошибочное обновление системы ввода-вывода, повторно включающее SMT после отключения.
 +
 +
Уязвимости типа Meltdown и Spectre могут привести к реализации атак, при которых злоумышленник сможет получить доступ к защищенной памяти из программы, не обладающей соответствующими привилегиями (путём анализа данных, записываемых в кэш процессора).
 +
 +
Одним из наиболее эффективных способов противостояния атакам семейств Meltdown и Spectre является отключение SMT (помимо обновлений инструкций самих процессоров и разнообразных патчей к ядру Linux и компиляторам). Для этого ядро ОС Linux имеет нужные параметры, которые позволяют отключить SMT.
 +
 +
С другой стороны, минусом этого решения является снижение производительности. Отключение SMT (любым способом, программным или аппаратным), приведет к тому, что количество виртуальных процессорных ядер (vCPU) уменьшится кратно числу потоков в каждом ядре ЦП (то есть, не менее, чем вдвое). Наличие большого количества ядер vCPU особенно важно при необходимости использовать виртуальные машины. 
 +
 +
Но если без SMT все же можно обойтись -- то лучше отключить эту функциональность. Желательно планировать покупку оборудования с учетом того, что SMT будет отключаться.
 +
 +
Для проверки того, используется ли технология SMT, требуется от имени любого пользователя выполнить следующую команду:
 +
 +
<code>$ cat /sys/devices/system/cpu/smt/active</code>
 +
 +
<code>0</code>
 +
 +
Где <code>0</code> свидетельствует об отсутствии поддержки.
 +
 +
Иначе, если вывод <code>1</code>, то рекомендуется отключить поддержку SMT, сначала в BIOS/UEFI, если это поддерживается оборудованием. А затем выключить её и в ядре операционной системы.
 +
 +
Для отключения поддержки SMT в ОС, требуется от имени <code>root</code> выполнить изменение строки <code>GRUB_CMDLINE_LINUX_DEFAULT</code> конфигурационного файла <code>/etc/default/grub</code>, дописав в ее конец следующие директивы:
 +
 +
<code>GRUB_CMDLINE_LINUX_DEFAULT='splash smem=1 mitigations=auto,nosmt'</code>
 +
 +
После чего нужно обновить конфигурацию загрузчика (<code># update-grub</code>) и перезагрузить ОС.
  
 
[[Категория:Безопасность]]
 
[[Категория:Безопасность]]

Версия 14:28, 11 декабря 2023

Idea.png
Примечание
Статья в процессе написания. Переносится из написанного ранее документа PDF.

Защита памяти и ядра в ОС ROSA. Свод требований

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

Сводная информация с рекомендуемыми настройками для ядра ОС и проекция к Методическому документу ФСТЭК «Рекомендации по обеспечению безопасной настройки операционных систем Linux» от 25 декабря 2022 г. — приведена в таблице ниже:

№ п/п Параметр и рекомендуемое значение Интерфейс См. документ ФСТЭК См. раздел Значение по умолчанию
1 kernel.dmesg_restrict=1 /etc/sysctl.conf 2.4.1 Текст ячейки 0
2 kernel.kptr_restrict=2 /etc/sysctl.conf 2.4.2 Текст ячейки 0
3 init_on_alloc=1 /etc/default/grub 2.4.3 Текст ячейки Неактивно
4 slab_nomerge /etc/default/grub 2.4.4 Текст ячейки Неактивно
5 iommu=force
iommu.strict=1
iommu.passthrough=0
/etc/default/grub 2.4.5 Текст ячейки Неактивно
6 randomize_kstack_offset=1 /etc/default/grub 2.4.6 Текст ячейки
7 mitigations=auto,nosmt /etc/default/grub 2.4.7 Текст ячейки Неактивно
8 net.core.bpf_jit_harden=2 /etc/sysctl.conf 2.4.8 Текст ячейки 0
9 vsyscall=none /etc/default/grub 2.5.1 Текст ячейки Неактивно
10 kernel.perf_event_paranoid=3 /etc/sysctl.conf 2.5.2 Нет 2
11 debugfs=no-mount /etc/default/grub 2.5.3 Текст ячейки Неактивно
12 kernel.kexec_load_disabled=1 /etc/sysctl.conf 2.5.4 Текст ячейки 0
13 user.max_user_namespaces=0 /etc/sysctl.conf 2.5.5 Текст ячейки 509894
14 kernel.unprivileged_bpf_disabled=1 /etc/sysctl.conf 2.5.6 Текст ячейки 2
15 vm.unprivileged_userfaultfd=0 /etc/sysctl.conf 2.5.7 Текст ячейки 1
16 dev.tty.ldisc_autoload=0 /etc/sysctl.conf 2.5.8 Текст ячейки 1
17 tsx=off /etc/default/grub 2.5.9 Текст ячейки Неактивно
18 vm.mmap_min_addr=4096 /etc/sysctl.conf 2.5.10 Текст ячейки 65536
19 kernel.randomize_va_space=2 /etc/sysctl.conf 2.5.11 Текст ячейки 2
20 kernel.yama.ptrace_scope=3 /etc/sysctl.conf 2.6.1 Текст ячейки 1

Защита памяти и ядра ОС

В чем опасность?

Опасность заключается в возможности получения доступа к данным, обрабатывающимся ядром. Данные, которые обрабатывает ядро носят критическую ценность для ОС и её пользователей. Если они неправомочно доступны, то с их помощью можно реализовать атаки любого вида. По умолчанию в Linux имеются возможности загрузки другого ядра (подмены), или использовании потенциально опасных модулей (драйверов) ядра, в том числе без перезагрузки. Это может привести к обходу механизмов защиты и любой другой опасной активности.

Что можно сделать для повышения безопасности?

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

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

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

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

Подробная информация об известных техниках эксплуатации уязвимостей в ядре ОС Linux приведена по ссылке: https://github.com/xairy/linux-kernel-exploitation

Защита от просмотра адресов указателей

Переменная ядра ОС, отвечающая за доступ к интерфейсам ядра /proc/kallsyms и /proc/modules — это kernel.kptr_restrict. Просматривая эти файлы, можно получать значения адресации памяти для указателей ядра. То есть можно, например, узнать, на какой адрес в памяти ссылается указатель той или иной программы, или загруженного модуля ядра. Переменная может принимать значения 0, 1 и 2. Более подробное описание рисков, связанных с атакой на адреса указателей и прототип эксплойта, демонстрирующий такую возможность, приведены по ссылке:

https://kernsec.org/wiki/index.php/Bug_Classes/Kernel_pointer_leak

Если для переменной kernel.kptr_restrict определено значение 0, то просматривать значения адресов в памяти может любой пользователь ОС. Если задано значение 1, то просматривать адресацию функций может только root. Если значение равно 2, то никто не получит информацию об адресации. Рекомендуемое значение — два. При значении единица — отображение адресов заменяется на нули для всех пользователей, кроме root. При значении два — отображение адресов заменяется на нули для всех пользователей, включая root.

Для проверки текущего значения этой переменной выполнить:

# sysctl -a | grep kptr kernel.kptr_restrict = 2

Если значение отличается, то выполнить установку этой переменной:

# sysctl -w kernel.kptr_restrict=2

# echo 'kernel.kptr_restrict = 2' >> /etc/sysctl.conf

Отключение трассировки процессов

На первом этапе нужно проверить, есть ли в выполняющемся ядре LSM модуль YAMA. Для этого можно выполнить поиск нужной опции в конфигурационном файле ядра, например:

$ cat /boot/config-5.10.118-generic-2rosa2021.1-x86_64 | grep YAMA

CONFIG_SECURITY_YAMA=y

Если есть, то в ОС может использоваться настройка, позволяющая производить ограничения на трассировку процессов. Если нет (выдано значение CONFIG_SECURITY_YAMA is not set), то можно пропустить эту настройку.

Для проверки текущих значений трассировки выполнить (от имени администратора root):

# sysctl -a | grep ptrace

kernel.yama.ptrace_scope = 2

Рекомендуется установить запрет трассировки, используя значение 2 для переменной kernel.yama.ptrace_scope, или более строгое. Значение 2 определяет, что трассировку процессов может осуществлять только root. Значение \commandbox{3} полностью отключает трассировку, для всех пользователей, в том числе и для root. В описанной ниже конфигурации трассировка разрешается только пользователю root:

# sysctl -w kernel.yama.ptrace_scope=2

# echo 'kernel.yama.ptrace_scope = 2' >> /etc/sysctl.conf

Ограничения на просмотр сообщений ядра

Команда dmesg является очень популярной в ОС Linux. Она выводит на экран сообщения ядра ОС. По умолчанию эту команду может использовать любой пользователь в системе, следовательно её может применять злоумышленник, чтобы получить информацию о системе и некоторых её характеристиках. Соответственно, любой пользователь ОС сможет или напрямую обратиться к этому файлу ($ cat /dev/kmsg), или использовать программы чтения кольцевого буфера аудита ядра, такие как dmesg или rsyslog. Рекомендуется ограничивать пользователей в возможности получать сообщения кольцевого буфера аудита ядра, чтобы снизить вероятность получения информации о работающей системе или ее параметрах.

Переменная ядра ОС kernel.dmesg_restrict отвечает за доступ к интерфейсу кольцевого буфера аудита ядра (файлу /dev/kmsg). По умолчанию доступ пользователей к этому интерфейсу не запрещен. Значение 1 предписывает, что обращаться к нему может только root. Если установлено значение 0, то доступ пользователей к буферу аудита ядра не ограничивается.

Проверить текущее значение политики доступа к интерфейсу кольцевого буфера аудита ядра можно так:

# sysctl -a | grep dmesg

kernel.dmesg_restrict = 1

Если при проверке значение отличается от единицы, то нужно выполнить настройку запрета чтения из этого интерфейса всем, кроме root:

  1. sysctl -w kernel.dmesg_restrict=1
  1. echo 'kernel.dmesg_restrict = 1' >> /etc/sysctl.conf

Противодействие уязвимостям типа Meltdown и Spectre

Использование уязвимостей типа Meltdown или Spectre заключается в возможности несанкционированного выполнения кода в пространстве ядра. Например, возникающих при спекулятивном выполнении инструкций процессора (уязвимости типа Meltdown), и/или связанных с особенностями функционирования модуля прогнозирования ветвлений (уязвимости типа Spectre). Эти уязвимости были обнаружены в 2017 году, но все еще продолжают появляться различные их варианты.

Современные процессоры семейства x86 (производства компаний Intel и AMD) предоставляют возможность параллельного использования нескольких «нитей» или «потоков» на каждом процессорном ядре. Такая возможность называется SMT (Symmetric Multi-Threading, симметричная многопоточность). Поскольку «нити» или «потоки» (исходя из конструктивных особенностей ЦП) сохраняют возможности обмена информацией между собой, то это потенциально может привести к несанкционированному обмену информацией между процессами, выполняющимися в разных потоках, но на одном ядре ЦП. Либо может привести к нежелательному раскрытию информации в памяти и т.п. Поэтому в защищаемой системе опции процессора, отвечающие за SMT желательно отключить. При этом настоятельно рекомендуется использовать комплексный подход -- отключать поддержку SMT как на уровне системы ввода-вывода, так и на уровне операционной системы. Данный подход обеспечивает бОльшую уверенность в том, что уязвимости, связанные с недостатками SMT не будут проэксплуатированы, например в том случае, если производитель оборудования предоставит ошибочное обновление системы ввода-вывода, повторно включающее SMT после отключения.

Уязвимости типа Meltdown и Spectre могут привести к реализации атак, при которых злоумышленник сможет получить доступ к защищенной памяти из программы, не обладающей соответствующими привилегиями (путём анализа данных, записываемых в кэш процессора).

Одним из наиболее эффективных способов противостояния атакам семейств Meltdown и Spectre является отключение SMT (помимо обновлений инструкций самих процессоров и разнообразных патчей к ядру Linux и компиляторам). Для этого ядро ОС Linux имеет нужные параметры, которые позволяют отключить SMT.

С другой стороны, минусом этого решения является снижение производительности. Отключение SMT (любым способом, программным или аппаратным), приведет к тому, что количество виртуальных процессорных ядер (vCPU) уменьшится кратно числу потоков в каждом ядре ЦП (то есть, не менее, чем вдвое). Наличие большого количества ядер vCPU особенно важно при необходимости использовать виртуальные машины.

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

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

$ cat /sys/devices/system/cpu/smt/active

0

Где 0 свидетельствует об отсутствии поддержки.

Иначе, если вывод 1, то рекомендуется отключить поддержку SMT, сначала в BIOS/UEFI, если это поддерживается оборудованием. А затем выключить её и в ядре операционной системы.

Для отключения поддержки SMT в ОС, требуется от имени root выполнить изменение строки GRUB_CMDLINE_LINUX_DEFAULT конфигурационного файла /etc/default/grub, дописав в ее конец следующие директивы:

GRUB_CMDLINE_LINUX_DEFAULT='splash smem=1 mitigations=auto,nosmt'

После чего нужно обновить конфигурацию загрузчика (# update-grub) и перезагрузить ОС.