В Часть 1 этой серии из двух статей о бреши в безопасности я в основном писал об атаке Spectre. Я также дал вам основательное введение, чтобы вы могли лучше понять эту тему. Если вы пропустили это, прочитайте это здесь, прежде чем погрузиться в сегодняшнюю часть.

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

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

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

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

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

Мы объяснили основные вопросы, так что мы можем перейти к самому Meltdown и тому, как он работает. Ниже вы можете увидеть, как выглядит базовый код атаки.

  1. ; rcx = адрес ядра
  2. ; rbx = массив зондов
  3. повторить:
  4. mov al, байт[rcx]
  5. шл ракс, 0xc
  6. jz повторить попытку
  7. mov rbx, qword[rbx+rax]

Правильная логика начинается со строки номер 4 — инструкция mov загружает один байт из адреса rcx, который принадлежит памяти в режиме ядра. Разумеется, доступ к этой памяти в пользовательском режиме запрещен, и, как я уже писал ранее, вызовет исключение.

Однако, если эта инструкция вызывается заранее процессором в режиме Out-Of-Order, процессор не будет проверять никаких мер безопасности в целях оптимизации и разрешит обращение к этой ячейке памяти.

В следующих строках кода мы сохраняем значение этой ячейки в реестре «rax». В последней строке нашего кода мы обращаемся к таблице «rbx», загружая элемент этой таблицы. Индекс этого элемента равен значению, которое мы читаем из памяти, которое должно быть доступно только для процессов в режиме ядра.

Эта ссылка приведет к тому, что данный элемент таблицы будет сохранен в памяти процессора, и мы сможем добиться значения его индекса (который также является значением байта памяти режима ядра) так же, как и в случае с Спектр.

Конечно, процессор должен выполнить все вышеперечисленные шаги в режиме Out-Of-Order заранее, прежде чем реальное выполнение перейдет к строке номер 4, вызывая исключение, которое завершит программу. Эта квази-гонка позволяет нам читать память, которая не будет доступна в стандартных условиях.

Как защищаться?

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

Во-первых, мы должны обновить наше программное обеспечение. И я имею в виду не только операционные системы, но и программное обеспечение для визуализации, контейнеры, такие как докер, и интернет-браузеры. Firefox, Chrome и Internet Explorer представили обновления, защищающие нас от атак, описанных в этой статье. Кроме того, пользователям Chrome следует включить параметр «Строгая изоляция сайтов», который изолирует отдельные веб-сайты в отдельных процессах, таким образом защищая нас от атаки Spectre.

KASLR (рандомизация адресного пространства ядра) был представлен для уменьшения опасных последствий атаки Meltdown. Как я уже говорил, виртуальная память состоит из двух частей: пользовательской и ядерной. Атака возможна, если мы знаем адрес памяти, которую хотим прочитать.

До сих пор источник памяти, доступной для системных процессов, всегда был в одном и том же месте, поэтому атака была упрощена. Из-за KASLR смещение для памяти ядра каждый раз берется случайным образом, и это усложняет проведение атаки (но все же возможно!).

Патч KAISER был представлен, чтобы сделать защиту от атаки Meltdown максимально эффективной. Это позволяет лучше изолировать память, доступную для процессоров в режиме ядра, от памяти пользователя. KAISER не отображает память ядра в виртуальной памяти, предоставленной для пользовательских процессов, за исключением нескольких фрагментов, необходимых для правильного функционирования каждого процесса, т. е. обработчиков прерываний. В этом случае поломке подвергается только небольшая часть памяти ядра. Комбинируя KASLR с KAISER, можно значительно уменьшить последствия атаки типа Meltdown.

Следует сказать, что настоящая проблема кроется в самом процессоре и методах его работы. Из-за этого любая попытка устранить эту проблему с помощью программного обеспечения — это борьба с симптомами, а не устранение причины. Устранить проблему можно только на уровне ЦП установкой микрокодов, нового ПО или, в худшем случае, изменением архитектуры процессоров.

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

Первоначально опубликовано на softwarehut.com 29 марта 2018 г.