Тео де Раадт (Theo de Raadt) представил на конференции Hackfest 2015 новый механизм изоляции системных вызовов Pledge, продолжающий развитие идей, реализованных в появившейся в OpenBSD 5.8 подсистеме tame. Pledge уже интегрирован в ветку OpenBSD-CURRENT и будет доступен в релизе OpenBSD 5.9. В настоящее время механизмы защиты Pledge задействованы в 70% утилит базовой системы, к релизу OpenBSD 5.9 планируется обеспечить полный охват всех утилит.

По своей сути Pledge напоминает множество других механизмов ограничения доступа к системным вызовам, таких как seccomp, capsicum и systrace, но в отличие от них разработан с оглядкой на максимальное упрощение применения. Из-за усложнений, связанных с необходимости построения правил, включающих отдельные вызовы, прошлые попытки повсеместного применения изоляции системных вызовов при помощи systrace оказались безрезультатны. Единицы программ были защищены, но основная масса так и осталась без изменений. Для решения данной проблемы решено было создать новый метод формирования политик безопасности, который мог бы был легко применён ко всем приложениям базовой системы, без необходимости вникать в детали. В итоге за шесть месяцев существования Pledge на его использование переведено более 400 утилит OpenBSD.

Pledge требует внесения в приложения специальных аннотаций, определяющих уровень привилегий на текущем этапе выполнения приложения. Вместо детализации на уровне отдельных системных вызовов, Pledge манипулирует классами доступа. Аннотации выставляются через указание функции pledge(), первым аргументом которой является список разрешённых классов системных вызовов, а вторым - массив файловых путей, куда разрешён доступ. После сборки и запуска модифицированного приложения, ядро берёт на себя работу по контролю соблюдения заданных правил. При этом вместо традиционной блокировки доступа к неразрешённым системным вызовов применён иной подход - в случае выявления несанкционированного поведения приложение принудительно завершается. По замыслу разработчиков подобный подход заметно усложняет исследование возможных путей обхода ограничений в процессе атаки.

Анализ закономерностей обращения к системным вызовам в штатных утилитах OpenBSD показал, что имеется типичный сценарий использования системных вызовов: достаточно большое число системных вызовов используется на этапе инициализации, после чего обращение к ним существенно сокращается. Обычно для обеспечения защиты достаточно добавить вызов pledge() в участок кода после инициализации, но до начала основного цикла.

Классы системных вызовов включают stdio (ввод/вывод), rpath (только чтение файлов), wpath (запись файлов), cpath (создание файлов), tmppath (работа со временными файлами), inet (сетевые сокеты), unix (unix-сокеты), dns (резолвинг в DNS), getpw (доступ на чтение к базе пользователей), ioctl (вызов ioctl), proc (управление процессами), exec (запуск процессов), id (управление правами доступа) и т.п.

Например, для программы cat, которая только читает файлы, можно указать pledge("stdio rpath", NULL), для mkdir - pledge("stdio rpath cpatch wpatch fattr", NULL), а для patch - pledge("stdio rpath cpatch wpatch tmpath fattr", NULL). Подобные ограничения позволят работать с файлами, но не дадут создавать сокеты и запускать другие приложения. Насколько pledge более прост для внедрения можно судить по утилите file: при использовании systrace для лимитирования системных вызовов требовалось 300 строк кода, в то время как pledge позволяет обойтись двумя вызовами pledge.



Источник: http://www.opennet.ru/opennews/art.shtml?num=43295