Содержание статьи
- Как я делал доверенную вычислительную среду на основе «гипердрайвера»
- О концепте
- Оперативная память, аппаратный сброс и немного паранойи
- Что это такое
- Способы реализации доверенного ввода/вывода
- Какие методы используются?
- Защита ДС и общей оперативной памяти
- Изолированное ядро
- Его величество гипердрайвер
- Intel и безопасность
Как я делал доверенную вычислительную среду на основе «гипердрайвера»
Как сделать «компьютер в компьютере»? Например, можно взять какую-нибудь систему виртуализации, типа VMware, запустить виртуальную машину и получить искомое.
Но с точки зрения информационной безопасности такое решение несостоятельно: этот компьютер будет виртуальным, реально в кремнии его не будет, со всеми вытекающими из этого последствиями. А последствия самые печальные для безопасности выполнения программ: в этом виртуальном компьютере все «как на ладони», корневая ОС «сидит высоко и глядит далеко», не спрятаться.
Нужно, чтобы этот «виртуальный» компьютер был весь абсолютно реальным, из кремния, и на все 100% контролировался только пользователем. Желательно, чтобы он состоял из минимального количества компонентов, и тогда его проверка на недекларированные возможности будет сведена к минимуму. Кроме того, нужно гарантировать его изоляцию от основного недоверенного оборудования.
До недавних пор «распилить» реальный компьютер на работоспособные части было невозможно, не говоря уже об обеспечении полной независимости одной из таких частей, но все течет, все меняется. В настоящее время это вполне реально, и эта статья именно о таком «распиле» компьютера и новых подходах к концепции безопасных вычислений с использованием выделенных частей железа.
О концепте
К сожалению, должен признаться, что термин «компьютер в компьютере» и концепцию доверенной вычислительной среды (далее просто доверенной среды — ДС) на базе реального компьютера в компьютере, о которой пойдет речь далее, придумал не я. Автор термина — президент фирмы «Информзащита» Петр Ефимов. Я только реализовывал ее в конкретных технических решениях, моих силенок на всю задачу не хватило бы, работала команда. Причем не только из моих коллег, но и из сотрудников отдела перспективных разработок «Кода Безопасности» во главе с Максимом Шипиловым.
Так что и архитектура, и технические решения, реализующие концепцию «компьютер в компьютере» для организации ДС, — это плод коллективного труда, и, когда я буду по привычке писать от первого лица, нужно понимать, что это не вполне соответствует действительности.
Концепция доверенных вычислений
Предположим, тебе нужно выполнить на компьютере некую программу так, чтобы никто не смог вмешаться в ее работу и, более того, не мог подсмотреть, как и что она делает. Кроме этого, ввод/вывод информации на рабочем месте (через клавиатуру, монитор, мышь, съемные носители) во время работы этой программы также должен быть надежно защищен. Назовем такой вариант абсолютно защищенного выполнения программ режимом «доверенной среды» (ДС).
Здесь чрезвычайно важны два положения: во-первых, аппаратура, используемая в доверенных вычислениях, должна быть полностью проверена. Во-вторых, все программы, написанные для работы на этом доверенном оборудовании, должны быть также полностью проверены либо написаны самостоятельно.
До недавних пор это было фантастикой: в реальных условиях мы работаем на аппаратуре и ОС, которую доверенной назвать нельзя. Кроме того, на любом компьютере крутятся сотни программ непонятного происхождения, которые с легкостью могут вмешаться в нашу работу.
Доверенная среда
Концептуально для создания ДС достаточно всего лишь щепотки памяти и кусочка процессора на обычной вычислительной системе, избыточность только создает проблемы. Этого уже хватит, чтобы создать свой небольшой доверенный компьютер, сделать «компьютер в компьютере».
Но этого мало: в доверенном компьютере, находящемся внутри недоверенной вычислительной системы, должен работать проверенный, а еще лучше написанный собственноручно монитор (маленькая ОС), обеспечивающий работоспособность аппаратуры и приложений, функционирующих на нем.
Другими словами, доверенная среда состоит из доверенного компьютера в компьютере и программного монитора (микроОС), обеспечивающего функционирование приложений, требующих приватного выполнения.
Естественно, щепотка памяти и выделенное ядро должны быть изолированы от остального оборудования вычислительной системы, причем не только программно (этого мало), но и аппаратно. Сказано — сделано. Вот как это выглядит в реальности (рис. 1).
![Рис. 1. Обычная машина и машина с активированной доверенной средой](https://xakep.ru/wp-content/uploads/post/61483/1.png)
![](https://xakep.ru/wp-content/uploads/2013/08/cover-1-215x280.jpg)
Хакер #175. 100 программ для хакера
Скриншоты одного и того же компьютера, слева обычная машина, справа машина с активированной доверенной средой. Разница очевидна, ОС лишилась процессорного ядра и десяти мегабайт оперативной памяти.
Этим фокусам уже лет пять, и ничего нового в этом нет, просто технология не доходила до коммерческого использования и применялась только в исследовательских целях.
Теперь немного конкретизируем понятия. Изолированное ядро процессора — это одно из вычислительных ядер процессора, на работу которого невозможно повлиять извне, то есть никакое оборудование вычислительной установки не должно иметь возможности вмешаться в его работу. Вмешаться может только выключение питания и кнопка аппаратного сброса (сигнал Reset).
Соответственно, изолированное адресное пространство оперативной памяти должно быть недоступно на чтение и модификацию основному оборудованию вычислительной установки — процессорным ядрам, работающим под ОС, и внешним устройствам.
Итак, у нас есть личное процессорное ядро и изолированная память для его работы, следовательно, на базе этого оборудования можно уже запускать программный код. Можно написать для них даже собственную операционную систему, вот только нам это ни к чему. Достаточно сотворить небольшой программный монитор с минимальным набором поддерживаемых функций, только для обеспечения работоспособности и изоляции приватного ПО пользователя.
Оперативная память, аппаратный сброс и немного паранойи
Изолированная для нужд ДС память имеет один принципиальный изъян: после аппаратного сброса изолированный участок оперативной памяти перестанет быть изолированным, к нему сможет обращаться любая программа на любом процессорном ядре. Но информация, хранившаяся в нем, останется, и во многих случаях после аппаратного сброса можно получить к ней доступ. Поэтому критически важную информацию в изолированном адресном пространстве размещать нельзя, там может находиться только программный код ДС, локальные переменные и системные таблицы.
Следовательно, хранить секретную информацию (ключи шифрования как минимум) можно только в регистрах изолированного процессорного ядра, поскольку они гарантированно обнуляются при выполнении аппаратного сброса, предшествующего процедуре перезагрузки системы.
Пользовательское ПО доверенной среды
В доверенной среде желательно предельно минимизировать затраты на программирование и выполнять только операции, требующие приватности, а весь остальной функционал программ — на основном, недоверенном компьютере.
В ДС должны выполняться только критические секции (с точки зрения безопасности) программ, функционирующих на основном компьютере, типа процедур шифрования, идентификации, контроля за основной ОС (обнаружения вторжений), сбора статистики, ведения логов, доверенного ввода/вывода. Соответственно, объем программного кода для таких задач не велик, и его можно написать с относительно небольшими трудозатратами.
Теперь об ограничениях и возможностях программ доверенной среды, функционирующих на изолированном процессорном ядре. Естественно, они должны размещаться в изолированной области адресного пространства ОП и работать без использования каких-либо внешних программных модулей типа API, функций BIOS, вызовов прочего внешнего ПО.
Функциональные возможности программ ДВС неограниченны, все программные и аппаратные ресурсы вычислительной установки к их услугам, нужно только уметь этим распорядиться.
Доверенный ввод/вывод
Что это такое
Для выполнения доверенных вычислений сначала нужно предоставить данные и быть уверенным в том, что они не искажены на этапе ввода, а если они конфиденциальны, то еще убедиться в том, что их никто не «подсмотрел». Обработанные в доверенной среде данные также нужно выгрузить доверенным образом с обеспечением их целостности и приватности. То же самое требуется обеспечить для визуализации процесса вычислений и его результатов на экране монитора. Следовательно, нужно сделать доверенным не только процесс обработки данных, но и процессы ввода/вывода этих данных, да еще и визуализацию неких критически важных параметров. Фактически нужно этот доверенный «компьютер в компьютере» оснастить собственным доверенным периферийным оборудованием.
Способы реализации доверенного ввода/вывода
Существует несколько способов реализации доверенного вывода. Самый очевидный — это поступить так же, как и с процессорным ядром: выделить из аппаратных ресурсов, используемых ОС, необходимые контроллеры и работать с ними только из доверенной среды. Недостаток этого лобового решения — моделезависимость. Нужно писать собственные драйверы для работы с выделенным периферийным оборудованием, а типов этого оборудования слишком много.
Более простым способом будет организация «сеансового» захвата любого из необходимых контроллеров, а чтобы ОС и сторонние программы в это время не «путались под ногами», на время этого сеанса все процессорные ядра, принадлежащие ОС, нужно останавливать (у нас используется термин «заморозить»). Но опять возникает вопрос моделезависимости: как и в первом варианте, нужно писать собственные драйверы под все имеющиеся контроллеры, а это просто нереально. Поэтому эффективней использовать комбинированный метод. Штатный драйвер ОС инициализирует контроллер до уровня активации буфера обмена данными, и только после активации этого буфера происходит «заморозка» процессоров основной ОС. В этом замороженном состоянии контроллер Пишет в буфер обмена/читает из него (его)через DMI, процессор доверенной среды контролирует заполнение буфера и, когда операция завершается, забирает из него данные, а после этого «размораживает» процессоры ОС.
Последний и самый элегантный способ — это работа на лету, когда с внешним устройством работает ОС, ничего не тормозится, не захватывается, но буферы обмена данных гарантировано подменяются, и реальная информация из них идет по каналам ДС, а не основной ОС.
Какие методы используются?
Там, где оборудование хорошо стандартизировано и важна гарантированная надежность (обеспечение сетевого доступа, например), применяется метод выделения контроллеров.
Там, где нет даже намека на стандартизацию протоколов доступа к оборудованию и полно недокументированных возможностей (пример — современные видеоадаптеры), применен метод заморозки ОС на время чтения/записи буферов данных.
В более простых случаях реализуется метод подмены/съема информации на лету, к примеру, так реализована работа с клавиатурным вводом.
Жизненный цикл доверенной среды
В нашем мире все имеет начало и все имеет конец, в случае с ДС назовем этот краткий миг «между прошлым и будущим» жизненным циклом ДС. В момент рождения она, естественно, слаба и беззащитна, любой ее может «обидеть» (подменить параметры) либо «угнать» (заменить программный код). Поэтому для активации доверенной среды выбирается момент, когда рядом никого нет, то есть доверенная среда активируется ДО загрузки ОС. Сразу после инициализации системы через BIOS/UEFI управление передается на загрузчик ДС, активирующий доверенную среду на «чистой» машине, и только после активации передает управление на штатный загрузчик ОС.
Таким образом, ОС с момента своей инициализации даже не догадывается о наличии на вычислительной установке скрытых от нее аппаратных и программных ресурсов.
Спрашивается, как организовать взаимодействие ОС и ДС, например вызвать функцию, реализованную в ДС? Поскольку ОС ничего не знает о ДС, единственный способ начать им общаться — это использовать публичный ресурс — оперативную память общего доступа.
Для этого приложение, функционирующее в ОС, выставляет сигнатуру в оперативной памяти, которую обнаруживает ДС. Затем, в рамках протокола обмена, в оперативной памяти инициализируются некие переменные, служащие интерфейсом между ДС и приложением, которое захочет воспользоваться услугами ДС.
Защита ДС и общей оперативной памяти
Любое приложение может воспользоваться услугами ДС. Для этого ему нужно знать только сигнатуры и протокол обмена данными. Конечно, можно придумать множество вариантов защиты от нелегального использования функций ДВС, но на каждый вариант защиты найдется с десяток вариантов, как пробить такую защиту.
Единственный надежный вариант — это двухфакторная идентификация. Ее можно организовать по-разному, но пока реализован простейший способ — контроль использования функций ДС с визуализацией и ручным подтверждением с клавиатуры оператора.
Поскольку исходные данные и результаты работы ДС передаются через ОП общего пользования, их также могут «подсмотреть» и модифицировать. Но в большинстве случаев это не проблема, поскольку их можно зашифровать либо напрямую выдать в сеансе доверенного выполнения на какой-то аппаратный контроллер, к примеру на экран монитора либо в сетевой адаптер.
И вот система славно поработала, «караул устал», оператору захотелось покурить, и он «усыпляет» систему. Такой вариант ДС не устраивает, потому что в режимах сна критические данные и коды могут выгружаться на внешние носители и, соответственно, там в беззащитном состоянии их можно анализировать и модифицировать.
Поэтому в доверенной вычислительной среде используется принцип «умерла так умерла». Если запускается процедура сна или гибернации, то система вместо этого выключается, данные и программы ДС не выгружаются на устройство долговременного хранения, — конечно, неудобно, но безопасность превыше всего….
Техническая реализация
Для технической реализации нашей ДС мы будем использовать аппаратуру виртуализации. Главная проблема использования аппаратуры виртуализации — это написать два абсолютно разных гипервизора, для Intel и AMD соответственно. Это очень большой и сложный объем работы, который пришлось проделать с нуля. Тяжелым, но вынужденным решением стал отказ от поддержки начальных ревизий систем виртуализации для Intel. Пришлось в целях надежности и функциональности ограничиться поддержкой начиная с версий 13, а это значит, что без поддержки технологии EPT (расширенное страничное преобразование) в процессорах Intel доверенная среда работать не будет.
У процессоров AMD проблем с ранними версиями аппаратуры виртуализации нет, все их ревизии работают с ДВС, и вообще мне их система виртуализации нравится больше (и не мне одному).
В результате родилась комбинированная технология, когда процессорное ядро для монопольного использования в доверенной среде изолировалось стандартным образом, одинаковым для процессоров AMD и Intel, а все защитные и контрольные функции выполнялись при помощи аппаратуры виртуализации на остальных ядрах, функционирующих под управлением ОС.
Изолированное ядро
Это ядро должно быть ядром с последним номером, оно может быть логическим (при включенном гипертрейдинге), но всегда забирается в первозданном, не запятнанном работой с разными непроверенными программами состоянии. Его только проинициализировал BIOS, а после этого оно сразу попадает в ДС и там остается до выключения питания.
Этим гарантируется надежность и предсказуемость поведения этого ядра в ДС: его состояние не модифицировано сторонними программами, а если его кто и «попортил», то только BIOS, и все вопросы уже к его авторам. А если оно проходило проверку на НДВ — то к экспертам и методикам этих проверок.
Его величество гипердрайвер
Обычно программу, использующую аппаратуру виртуализации, называют гипервизор. Но это — большие программные комплексы с мегабайтами кода. В нашем случае задача попроще и кода-то всего ничего — не больше десяти килобайт. Так что гипервизором назвать его язык не поворачивается, это не гипервизор, это «гипердрайвер» — так и будем его далее называть.
Гипердрайвер на процессорных ядрах, используемых ОС и прикладными программами, предназначен только для двух задач: во-первых, он должен обеспечить дополнительную защиту процессорного ядра и памяти доверенной среды, а во-вторых, выделять аппаратуру необходимых контроллеров ввода/вывода для сеансов доверенного обмена информацией.
Пример работы гипердрайвера приведен на рис. 2.
![Рис. 2. Пример работы гипердрайвера](https://xakep.ru/wp-content/uploads/post/61483/2.png)
Скриншот участка ОП для обычного режима работы ОС, ДС не активирована, и в этом месте памяти размещены таблицы ОС. На рис. 3 приведен скриншот этого же участка памяти, но с включенной ДС.
![Рис. 3. Включена ДС и Гипердрайвер](https://xakep.ru/wp-content/uploads/post/61483/3.png)
В этой области памяти включена защита от доступа/модификации и ничего не видно, хотя по этим адресам реально находятся системные таблицы процессорного ядра доверенной среды.
Но можно отключить защиту, и тогда в этих адресах ОП увидим фактически расположенную там корневую запись системной таблицы (PG) ДС (рис. 4).
![Рис. 4. Фактически расположенная в памяти корневая запись системной таблицы (PG) ДС](https://xakep.ru/wp-content/uploads/post/61483/4.png)
Сейчас ДС будет доступна для модификации и просмотра, но это только в отладочном режиме, естественно.
Ограничения применения
Работоспособность доверенной среды поддерживается, естественно, не на всех аппаратных платформах — слишком технически сложное решение и не везде есть необходимое для этого оборудование. Обязательным условием является наличие аппаратуры виртуализации и хотя бы двух процессорных ядер.
Для оборудования AMD этим ограничения и кончаются, с Intel все гораздо сложнее: там стабильные и полнофункциональные версии аппаратуры виртуализации появились только года три-четыре тому назад и старые процессоры поддерживать работу ДС в полном объеме не будут.
Кроме аппаратных ограничений, есть и ограничения на BIOS в части загрузчика UEFI, пока в образ загрузчика ОС не включен активатор ДС, это дело будущего.
Из ограничений с программными компонентами есть одно: официальные системы виртуализации совместимы с гипердрайвером, только если они не используют аппаратную виртуализацию.
Гипердрайвер, по праву «первой ночи», захватывает контроль над аппаратурой виртуализации и, естественно, больше никому ее не отдает, поэтому официальным гипервизорам приходится работать либо в режиме паравиртуализации, либо в режиме эмуляции нулевого уровня привилегий, что даже хорошо с точки зрения безопасности и контроля.
Intel и безопасность
После инициализации BIOS на платформе Intel мы получаем машину с уже настроенными системами безопасности. Во многих случаях нет даже возможности посмотреть, как они настроены. А если и есть, то ничего изменить уже нельзя: выполнена аппаратная блокировка попыток модификации параметров. Так что надежность системы на платформе Intel — это вопрос к сборщикам BIOS и архитекторам Intel, я тут, как говорится, умываю руки…
«День сурка»
Гипердрайверы, которыми я занимаюсь, пока не применялись в масштабных коммерческих проектах, но это не значит, что они вообще не использовались. Отнюдь, технология отработана, она надежна, но иногда встречаются аномалии.
Это неудивительно, гипердрайвер в первую очередь работает с кремнием, и разные «беспределы» в нем (этому посвящены статьи цикла «Кремневый беспредел») гипердрайвером сразу выявляются. Это, можно сказать, «лакмусовая бумажка» — засунул в материнскую плату и сразу видишь, «что такое хорошо, а что такое плохо».
Чтобы не быть голословным, приведу конкретный пример. Вот снимки того, что называется «хорошо» (рис. 5).
![Рис. 5. Это хорошо!](https://xakep.ru/wp-content/uploads/post/61483/5.png)
На фотографии — экран тестовой программы замера времени выполнения команд и обработки исключений. Время считается в машинных тактах, замер произведен на эталонной машине без гипердрайвера — реально чистая машина, вопросов к ней нет.
А вот эта же эталонная машина, но с загруженным гипердрайвером (рис. 6).
![Рис. 6. Эталонная машина с загруженным гипердрайвером](https://xakep.ru/wp-content/uploads/post/61483/6.png)
Гипердрайвер «честный», он не пытается замаскировать свое присутствие в системе (к слову, таких возможностей у систем виртуализации множество, но здесь все по-честному, на честной машине).
Видно, что время выполнения команд и исключений увеличивается при загрузке гипердрайвера, и это нормально.
Увеличение времени выполнения бывает двух типов. Первый тип, самый очевидный, — время увеличивается из-за входа в хост гипервизора, на снимке это команда CPUID, XSETBV и RDMSR с некорректным номером регистра. Циклы выполнения этих команд всегда увеличиваются на 1200–1500 тактов, в зависимости от архитектуры и прошивки микрокода процессора.
Второй тип увеличения длительности команд — появление дополнительных стадий выполнения команды без выхода в хост гипервизора. Примером может служить левая часть экрана, где выведены значения MSR-регистров и время доступа к ним. Время под гипервизором увеличилось в среднем на 30 тактов, эти такты тратятся на проверку соответствия номера текущего регистра со списком номеров регистров, требующих выхода в хост. То же самое касается доступа к памяти и обработки исключений, но там, естественно, увеличение длительности выполнения будет другим. Можешь посмотреть сам, на сколько тактов увеличивается время выполнения этих операций.
Короче говоря, это чистая эталонная машина. А теперь посмотри на снимки экрана той же программы замера времени выполнения на машине, в которой все «плохо» (рис. 7).
![Рис. 7. Подозрительная машина](https://xakep.ru/wp-content/uploads/post/61483/7.png)
Даже без гипердрайвера сразу видны проблемы: команда XSETBV не выполняется, но вполне возможно, что это отрабатывается исключение UD — недействительный код команды. Теперь об однозначных проблемах:
- команда CPUID с недействительным номером запроса выполняется слишком долго;
- запредельное время доступа к MSR-регистрам с номерами 3F8h–3FEh;
- не отключилось кеширование ОП, MemAcc показывает время доступа к ОП через кеш, а не время прямой транзакции в контроллер памяти.
Запускаем на этой плохой машине гипердрайвер, теперь все стало совсем плохо (рис. 8).
![Рис. 8. Проблемная машина с загруженным гипердрайвером](https://xakep.ru/wp-content/uploads/post/61483/8.png)
Во-первых, на этой машине гипердрайвер установил мировой рекорд: он умудрился зайти в хост и выйти из него при обработке команды CPUID за 750 тактов. Я такое вижу впервые, объяснение одно: счетчик тактов работает неправильно, чудес на свете не бывает…
Во-вторых, установлен и антирекорд: при выполнении команды RDMSR с недействительным номером регистра вход в хост и выход занял практически 3000 тактов. Диагноз тот же, опять счетчик тактов отработал неправильно…
В-третьих, не увеличилось время доступа к MSR-регистрам, наблюдается полный хаос, но в среднем оно практически не изменилось…
В-четвертых, опять не отработал доступ к оперативной памяти, время увеличилось только на 300 тактов — это время для теневой трансляции, но физический доступ все равно идет в кеш…
Можно только гадать, что за чудеса творятся на этой машине. Вариантов несколько: это может быть особенность реализации режима системного менеджмента, специфика прошивки микрокода, необычная активность сервисного процессора, но может быть и встроенный в BIOS гипервизор, по типу того, что был описан в статье «Китайские закладки».
Естественно, на такой «паленой» машине ни о какой доверенной среде говорить не приходится, да она и не загружается, виснет в середине загрузки ОС….
«А напоследок я скажу…»
И скажу без лишней скромности: в муках родилась абсолютно новая концепция информационной безопасности.
Она не просто родилась как абстрактный фантом, а реализована в виде программной платформы. На эту платформу можно «навешивать» различные полезные нагрузки, но пока, насколько мне известно, владелец технологии (фирма «Код Безопасности») планирует внедрять ее в области ДБО. Что будет дальше — посмотрим.