Двойная осевая против уязвимости

22 январь, 2018 - 18:35Михаил Закусило

Анализ инициатив компании Intel, реализуемых в рамках технологии Control Flow Enforcement Technology, направленной на повышение защищенности программного кода информационных систем и пользовательской информации.

Уязвимости, о которых уже столько сказано, хотя и «не могут привести к повреждению, изменению или удалению данных», доставляют немало хлопот всем производителям компьютерной техники, но в первую очередь, конечно, — компании Intel. Комизм ситуации в том, что о проблемах в Intel знали давно и не сидели сложа руки. Есть основания предполагать, что планомерная работа по защите систем и пользовательских данных/кода велась еще с 2016 года (если не раньше). Новый 2018 год оказался для кого-то оптимальным в медийном плане моментом для обнародования информации? Пока ответ на этот вопрос остается открытым, можно спокойно проанализировать ход «антивирусных прививок», которыми Intel планирует закрыть зияющие вершины процессорного дизайна.

Если отложить до лучших времен обсуждение «дырки», существующей уже почти лет сорок и связанной с доступностью адресов привилегированных объектов (ее наличие будет весьма кстати при построении зловредного кода, реализующего уязвимости Meltdown и Spectre), то в центре внимания инженеров Intel оказался механизм управления программными вызовами. Их перехват — одна из краеугольных технологий вирусов. Поэтому блокирование источника проблемы в зародыше куда как более продуктивно, чем всегда опаздывающая борьба с последствиями. Сегодня мы обсудим защиту классического механизма вызова подпрограмм от атак, основанных на искажении адреса возврата. Напомним, этот адрес записывается в стек командой CALL и восстанавливается из него по команде RET.

Одна из инициатив, разработанных в рамках технологии Control Flow Enforcement Technology (CET) сводится к тому, чтобы контролировать вызовы подпрограмм и возвраты из них, используя теневой стек (shadow stack) аппаратно защищенный специальным статусом страниц памяти. Теневой стек дублирует содержимое основного программного стека (его теперь нужно называть data stack). Адреса возврата, находящиеся в теневом стеке, не могут быть программно изменены злоумышленником, либо ему это будет сделать значительно сложнее. Классический стек, доступный для программного чтения и записи, остается в обеспечение совместимости.

Двойная осевая

Рис 1. Фрагмент из документации Intel в рамках инициативы «Control-flow Enforcement Technology Preview», Rev 2.0 от июня 2017, Document Number: 334525-002

Прочертив своеобразную «двойную осевую», Intel для достижения совместимости и защищенности приносит в жертву производительность, в меру возможностей расточительствуя оперативной памятью. Теперь при вызове подпрограммы, процессор одновременно использует оба стека, сохраняя в каждом из них одну и ту же информацию — адрес возврата. Выполнение подпрограммы завершается извлечением адреса воз-врата из обоих стеков. При их несовпадении принимается решение о зловредной модификации содержимого классического стека — процессор генерирует исключение, обработка которого выполняется операционной системой. Так предотвращается передача управления по искаженному (ложному) адресу.

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

Про переполнение стека — одну из самых известных проблем современного программного обеспечения — не хочется даже думать...

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

Двойная осевая

Рис 2. Структура 16-битного сегмента состояния задачи (TSS), определенная в рамках архитектуры Protected Mode процессора 80286, с дифференциацией стеков по уровням привилегий

Похоже, Intel реанимировал хорошо забытое старое: еще в 16-битном сегменте состояния задачи Task State Segment для процессора 80286 предусматривалось несколько адресов стеков, представленных парами селектора и смещения SS:SP. Тогда в каждый момент времени процессором использовался только один из них. Этот древний метод был призван обеспечить выбор одного из стеков в зависимости от уровня привилегий и (в теории) не позволял приложению исказить или разрушить стек операционной системы. Сегодня же метод «грубой силы» теряет свою популярность, уступая место изощренным приемам на основе спекулятивных механизмов в сочетании с косвенными формам передачи управления.