10. ЗАЩИТА ПАМЯТИ
10.1. Защита оперативной памяти в ОС МСВСфера
Операционная система МСВСфера ОС основана на базе ядра GNU/Linux, соответственно, защита оперативной памяти и ограничение прав доступа к страницам памяти реализовано на базе стандартных механизмов ядра, компилятора GCC и функций аппаратного обеспечения.
10.2. Аппаратная защита от переполнения буфера
Начиная с версии ядра GNU/Linux 2.6.8, выпущенной в 2004 году, на центральных процессорах архитектуры x86 поддерживается аппаратная защита от переполнения буфера путём выполнения кода в страницах памяти, помеченных как данные — NX-Bit (No Execute Bit) в терминологии AMD или XD-Bit (Execute Disable Bit) в терминологии Intel. Эта технология так же реализована в современных ARM-процессорах.
Проверить, задействован ли этот механизм можно с помощью одной из следующих команд:
$ dmesg | grep 'Execute Disable'
[ 0.000000] NX (Execute Disable) protection: active
Или
$ sudo journalctl | grep "protection: active"
Oct 08 10:10:25 localhost kernel: NX (Execute Disable) protection: active
Если защита не активна, то, возможно, в настройках BIOS/UEFI вашего оборудования есть настройка для её включения.
10.3. Программная защита от переполнения буфера
Использование современных компиляторов позволяет применять в МСВСфера ОС различные методы защиты от переполнения буфера.
Уже классическим методом защиты стека от переполнения является «канарейка» (canary stack protection), названный так в честь птиц,
которых когда-то шахтёры использовали в шахтах в качестве примитивных газоанализаторов: если птица умирала, значит находиться в шахте было небезопасно.
Суть метода заключается в том, что при каждом запуске программы генерируется некое секретное число, которое затем записывается в память перед адресом возврата из функции и
проверяется при выходе из функции.
Если оно не соответствует ожидаемому, то программа немедленно завершает свою работу.
При переполнении буфера данное значение, соответственно, затирается, что и приводит к срабатыванию защиты.
В пакеты МСВСфера ОС данная защита добавляется автоматически через использование опции компилятора -fstack-protector-strong
.
Ещё одной возможностью компилятора, применяемой для сборки пакетов, является FORTIFY_SOURCE
,
которая добавляет проверку на переполнение буфера для различных функций, выполняющих операции с памятью и со строками.
Также при сборке пакетов используется опция компилятора -fstack-clash-protection
, которая реализует защиту от атак типа «stack clash».
Соответствующая защита реализована в ядре ОС и в библиотеке glibc.
Смысл такой атаки заключается в том, чтобы вызвать выполнение вредоносного кода или повысить привилегии одним из следующих способов:
пересечение (clashing) — вызвать пересечение стека с другой областью памяти путём выделения памяти, пока стек не достигнет другой области памяти или пока другая область памяти не достигнет стека.
прыжок (jumping) — позволяет переместить указатель стека в другую область памяти, не затрагивая сторожевую страницу памяти.
разбиение (smashing) — выполнить перезапись стека содержимым другой области памяти или выполнить перезапись другой области памяти содержимым стека.
ASLR (address space layout randomization) или рандомизация размещения адресного пространства — ещё одна технология защиты памяти, применяемая в МСВСфера ОС. Суть защиты ASLR сводится к использованию случайных адресов для размещения сегментов кода и данных в адресном пространстве процесса, что усложняет эксплуатацию различных уязвимостей, связанных с переполнением буфера, так как атакующему сначала потребуется «угадать» по каким адресам расположены те или иные структуры данных процесса (стек, куча и т.п.).
Защита ASLR включена по умолчанию и какие-либо дополнительные действия по её настройке не требуются. Проверить статус можно с помощью следующей команды:
$ sudo sysctl -a | grep kernel.randomize_va_space
kernel.randomize_va_space = 2
Опция kernel.randomize_va_space
может принимать следующие значения:
0 — защита ASLR отключена, рандомизация адресного пространства не происходит;
1 — защита ASLR включена, случайные адреса используются для разделяемых библиотек, стека, VDSO и системного вызова
mmap()
;2 — (по умолчанию в МСВСфера ОС) защита ASLR включена, в дополнение к предыдущим пунктам случайные адреса также будут использоваться для кучи и системного вызова
brk()
.
Также в данном разделе стоит упомянуть технологию KASLR (Kernel Address Space Layout Randomization), которая затрудняет реализацию некоторых атак путём размещения структур данных ядра по случайному адресу при каждой загрузке операционной системы. Эта защита включена по умолчанию и не требует какой-либо дополнительной настройки.
10.4. Принудительная очистка оперативной памяти
В ядре МСВСфера ОС доступна функция принудительной очистки (перезаписи нулями) оперативной памяти во время её выделения и/или освобождения, что может значительно осложнить атаки, связанные с утечкой информации при повторном использовании памяти.
Эта функция отключена по умолчанию, поскольку приводит к некоторому замедлению операций, связанных с управлению страницами памяти, однако её включение может иметь смысл для повышения безопасности многопользовательских или критически важных систем.
Для включения принудительной очистки памяти используются следующие опции ядра:
init_on_alloc=1
— заполнять выделяемые страницы памяти и объекты кучи нулями.init_on_free=1
— заполнять освобождаемые страницы памяти и объекты кучи нулями.
В своих рекомендациях по безопасной настройке операционных систем Linux
ФСТЭК рекомендует использовать только опцию init_on_alloc=1
, но технически возможно использование обеих опций одновременно или по отдельности.
Для включения опции init_on_alloc=1
для всех установленных в системе ядер выполните следующую команду:
$ sudo grubby --update-kernel=ALL --args="init_on_alloc=1"
И перезагрузите компьютер.
После перезагрузки вы можете проверить содержимое файла /proc/cmdline
, чтобы убедиться в том, что функция очистки памяти активна:
$ grep -oP 'init_on_alloc\S+' /proc/cmdline
init_on_alloc=1
Чтобы отключить функцию принудительной очистки памяти для всех ядер используйте следующую команду:
$ sudo grubby --update-kernel=ALL --remove-args="init_on_alloc=1"
После которой также потребуется перезагрузить компьютер для применения изменений.