Уязвимости Meltdown и Spectre

2

Четвертого января 2018 года стало известно о масштабной концептуальной уязвимости, которая присутствует в большинстве процессоров Intel и позволяет любой непривилегированный программе получить доступ к данным, которые хранятся в оперативной памяти компьютера. Эта уязвимость получила название Meltdown. Чуть позже был обнаружен способ эксплуатации этой уязвимости почти на всех процессорах, который получил название уязвимость Spectre.

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

С чего все началось?

Нет, история началась не четвертого января. Еще в 2008 году на securitylab появилась новость о том, что российский специалист по информационной безопасности Крис Касперски обнаружил критическую уязввимость в процессорах Intel, которая позволяет взломать систему удаленно с помощью скрипта на JavaScript или просто через TCP/IP независимо от операционной системы. Исследователь собирался представить работающий код для Windows и Linux и сделать его общедоступным. Но затем все стихло на целых десять лет. Таким образом, можно предположить, что обнаружены уязвимости spectre и meltdown были еще в 2008 году.

Второй раз уязвимость была обнаружена несколькими независимыми группами исследователей, а именно Google Project Zero, Cyberus Technology, и Грацского технического университета летом 2017 года. Все это время данные оставались засекреченными, чтобы разработчики успели придумать и выпустить патчи для защиты от этих уязвимостей. Все это время разработчики Windows и Linux работали вместе над исправлением этих проблем. Публикация данных об уязвимости Meltdown была запланирована на 9 января 2018, но данные утекли в сеть чуть раньше — 4 января. Журналисты из The Register каким-то образом узнали об уязвимости из рассылки разработчиков ядра Linux об исправлении KAISER, которое добавляет изоляцию адресации процессов.

Уязвимости Meltdown и Spectre

Давайте попытаемся разобраться в чем же состоит суть уязвимости Meltdown и Spectre и чего нам стоит бояться. Действительно ли все так страшно, как везде пишут. Сначала нужно понять как работают процессоры. Процессору часто нужно извлекать значения из оперативной памяти или ожидать ввода от пользователя, а это занимает время. Во всех современных процессорах есть блок прогнозирования, который пытается определить какая инструкция будет выполнена дальше. И процессор выполняет эту инструкцию, сохраняя данные в кэше. Давайте рассмотрим небольшой пример. У нас есть переменная с именем «данные», и мы пытаемся прочитать в переменную «данные» какую-либо информацию, к которой у нас нет доступа, например, из ядра системы. Для повышения производительности виртуальная память ядра находится в том же адресном пространстве, что и память процесса:

данные = информация ядра

Естественно, что мы получаем ошибку. А теперь пробуем использовать предсказательное выполнение инструкций. Нам понадобится еще одна переменная, например «размер архива», она будет храниться в оперативной памяти и процессору нужно будет тратить много времени, на то, чтобы ее прочитать. Рассмотрим такой код:

Если (размер архива < 1000) выполнить
данные = информация ядра

Процессору каждый раз приходиться извлекать переменную «размер архива» из памяти, это долго. Поэтому когда мы повторим выполнение этого кода очень много раз, то блок предсказаний будет думать, что и в следующий раз сравнение вернет положительный результат. И уже наперед станет выполнять нашу команду. И тут кроется еще одна проблема. Обычно, процессор сразу проверяет, имеет ли программа право читать данные, от туда, откуда она пытается это делать. Но это долго, поэтому для выполняемых наперед операций эта проверка не успевает выполниться и команда выполняется в любом случае. Результат выполнения команды успешно сохраняется в кэше, а процессор помнит адрес. Далее, приходит значение переменной «размер архива» из памяти и приходит результат проверки полномочий может ли программа читать данные из того адреса. Если да, то все хорошо и данные используются, если же нет, то процессор возвращает ошибку и просто забывает адрес.

Но проблема в том, что в кэше данные все равно остаются. И программе остается только извлечь их оттуда. Что она имеет полное право сделать не вызвав никаких ошибок доступа, останется только узнать по какому адресу расположены данные. А это можно сделать просто замерив время доступа к адресам. Это все может быть реализовано даже на JavaScript, что делает проблему очень глобальной.

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

Это что касается Meltdown, которой присвоен номер CVE-2017-5754, уязвимость Spectre, обнаруженная в процессорах AMD имеет похожий принцип работы. Ей присвоены два идентификатора: CVE-2017-5753 и CVE-2017-5715. Там тоже процессор предугадывает какая инструкция будет выполнена и сохраняет результат в кэше. Но Spectre позволяет только обойти ограничение на доступ к памяти других приложений, к ядру системы доступа нет и реализовать ее сложнее. Этой уязвимости подвержено намного больше процессорных архитектур, не только Intel и AMD, но и ARM. Защититься от Spectre невозможно просто добавив изоляцию, для этого необходимо чтобы каждое приложение само защищало свою память или постоянно сбрасывать кэш. Что, во-первых, требует перекомплирования всех приложений, а во-вторых, снижает производительность. Универсального патча от Spectre пока не существует. Более подробная информация есть на

Далее, еще можно обновить видео драйвер NVIDIA до версии 384.111. Это пока что все, что доступно для защиты.

Как проверить уязвимость системы

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

grep CONFIG_PAGE_TABLE_ISOLATION=y /boot/config-`uname -r` && echo "patched :)" || echo "unpatched :("

Если команда выдает unpatched — значит вы все еще уязвимы. Другая команда для той же цели — посмотреть конфигурационный файл запущенного ядра:

zgrep CONFIG_PAGE_TABLE_ISOLATION /proc/config.gz

 

Или посмотреть в лог dmesg:

dmesg | grep "Kernel/User page tables isolation: enabled"

Опять же, если такой строчки нет — значит изоляция отключена и вы в опасности. Также существует скрипт, который можно использовать для проверки как Spectre, так и Meltdown. Для его загрузки вам понадобится git:

git clone https://github.com/speed47/spectre-meltdown-checker.git
cd spectre-meltdown-checker/
chmod +x spectre-meltdown-checker.sh
sudo ./spectre-meltdown-checker.sh

Проверить уязвим ли ваш браузер для Spectre и Meltdown вы можете с помощью этого

Выводы

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

Видео с объяснением сути уязвимости от Дмитрия Бачило:

Источник: losst.ru