Содержание статьи
Казалось бы, мы рассказали о песочницах уже всё. И про Docker написали во всех подробностях, и обзор инструментов для «быстрой» изоляции приложении сделали, даже собрали песочницу собственными руками. Но, как выяснилось, нет предела человеческой изобретательности. Встречай Cappsule — систему изоляции приложений на базе полноценной виртуализации. Надежная, как IBM ThinkPad, удобная, как iPhone, эффективная, как Core i7.
Введение
В основе работы почти всех применяемых сегодня песочниц для изоляции приложений, будь то песочницы Firejail, песочницы iOS, Android или даже системы Docker, лежит один простой принцип: запереть приложение в его каталоге и отрезать ему доступ к информации об остальной части системы и ее API. Как это реализуется — с помощью chroot, пространств имен и seccomp-bpf, как в большинстве песочниц Linux, или с помощью запуска каждого приложения с правами созданного специально для него юзера и своей собственной системы ограничения прав, как в Android, — неважно. А важно то, что в каждом из этих случаев за изоляцию приложений отвечает ядро ОС, общее для всех них.
Благодаря использованию встроенных в ядро механизмов изоляции такие песочницы очень дешевы в создании и обслуживании, они не приводят к существенному увеличению расхода оперативной памяти, не съедают место на диске и вообще отличаются высокой эффективностью. Однако платить, как известно, приходится за все, и в данном случае расплата бьет по тому самому месту, которое песочницы и призваны охранять, — безопасности основной системы.
Запуская софт в песочнице, мы рассчитываем оградить его от других песочниц и операционной системы, просто для того, чтобы взлом этой софтины или наличие в ней малвари не привели к компрометации всех остальных данных. И в большинстве случаев это работает, но ровно до тех пор, пока взломщик не найдет способ из нее выбраться. А способ этот в грамотно спроектированной песочнице обычно один — уязвимость в ядре ОС. Почти вся малварь для Android, способная получить права root, и большинство джейлбрейков iOS эксплуатируют дыры в ядре. А ядро настольного Linux почти ничем не отличается от ядра того же Android. И дыры в нем находят хоть и чуть реже (благодаря меньшему количеству блобов от производителей железа), но регулярно.
Разработчикам песочниц и операционных систем, запускающих софт в песочницах, это хорошо известно, как и последствия. Поэтому Apple и Google, все операционки которых используют идею песочниц, борются с этой угрозой при помощи апдейтов: появилась информация о дыре — быстро ее исправляем и выкатываем обновление. У Apple это получается хорошо, у Google плохо, но в любом случае, если информации о дыре нет, не будет исправления. И если на твоем смартфоне оно не так уж и важно, то в Linux-системе, где хранится твой Bitcoin-кошелек и куча другой конфиденциальной информации, взлом системы через запущенный в песочнице браузер может привести к очень печальным последствиям.
Один из способов борьбы с 0day-уязвимостями в ядре — виртуальная машина, такая как VirtualBox, QEMU или Parallels. Запускаем небезопасное приложение внутри виртуальной машины вместо классической песочницы, и вуаля — взлом самого приложения и возможный взлом ядра никак не затрагивают основную ОС. В таком подходе уязвимым местом оказывается не ядро, а гипервизор и код, эмулирующий различные железные подсистемы: сетевую карту, USB- и SATA-контроллеры. И если посмотреть на статистику уязвимостей того же VirtualBox, то становится ясно, что в целом критических уязвимостей здесь намного меньше, чем, например, в ядре Linux. Но что более интересно: почти все из них находят именно в коде эмуляции железа.
И здесь мы подходим к самому интересному вопросу: а можно ли создать настолько простую виртуальную машину (в идеале вообще без кода эмуляции железа), чтобы она была практически неуязвима, но тем не менее способна запускать стандартный пользовательский софт?
Виртуалка без эмуляции
Несмотря на то что Cappsule использует в своей работе механизмы виртуализации Intel VT-x и EPT, назвать ее полноценной виртуальной машиной крайне сложно. Это система изоляции, построенная на технологиях виртуализации. Она использует простой и компактный гипервизор (всего 15 тысяч строк кода), позволяющий запустить копию ядра Linux основной ОС и выбранное приложение внутри виртуального окружения с полной интеграцией приложения в текущий графический интерфейс.
Cappsule не эмулирует железо и не оперирует полноценными виртуальными машинами с собственным ядром, виртуальными дисками, сетевой картой и другими компонентами обычного ПК, как это делает VirtualBox или QEMU. Она действует намного хитрее: сразу после своей загрузки загружает в ядро текущей ОС модуль с гипервизором и отдает ему управление. Гипервизор в свою очередь создает новое виртуальное окружение и размещает внутри него текущую ОС. Этот метод называется Blue Pill (он был описан Йоанной Рутковской в 2006 году) и нужен для того, чтобы получить контроль над исполнением текущей ОС.
![Как Blue Pill перехватывает управление](https://xakep.ru/wp-content/uploads/2016/11/1479712303_edf0_bluepill.jpg)
После этого гипервизор Cappsule останавливает исполнение ядра ОС, переводит в офлайн все ядра процессора, кроме текущего, делает снимок памяти, занимаемой ядром ОС, затем возвращает ядру управление. Позднее, получив запрос на запуск приложения в песочнице, гипервизор создает еще одно виртуальное окружение с копией памяти ядра, запускает в нем несколько служебных процессов и указанное приложение.
Для приложения такая виртуальная система выглядит настоящей. Оно может работать с файловой системой, выполнять сетевые запросы, выводить на экран картинку и выполнять системные вызовы ядра. Но так как Cappsule не эмулирует железные компоненты классической виртуальной машины и не предоставляет доступ к реальному железу (фактически запрещены любые операции ввода-вывода), для того чтобы дать приложению возможность доступа к файловой системе, сетевому адаптеру и GUI-подсистеме, Cappsule запускает внутри виртуального окружения три специальных процесса:
- Fsclient для проброса файловой системы (точнее, иерархии) основной системы внутрь виртуальной. Fsclient имеет клиент-серверную архитектуру и общается с демоном fsserver, запущенным в хост-системе. При доступе к тому или иному файлу fsclient отправляет запрос fsserver, а тот в ответ выдает результат запроса или ошибку доступа, если доступ к этому файлу запрещен в настройках. Естественно, виртуальное окружение может выполнять запись файлов, поэтому, чтобы не скомпрометировать хост-систему, fsserver модифицирует файлы в режиме copy-on-write (для этого он использует технологию OverlayFS ядра Linux, ту же, на которой построена система слоев в Docker). Другими словами, все модификации файлов из виртуального окружения будут уникальны только для этого виртуального окружения; изменить файлы напрямую оно не может.
- Netclient для проброса внутрь виртуального окружения сетевого интерфейса. В этом случае используется схожая схема: netclient создает внутри виртуального окружения сетевой интерфейс tun0, все операции чтения и записи в который отправляются демону netserver, работающему в хост-системе. С помощью настроек брандмауэра netserver перенаправляет эти данные на реальный физический сетевой интерфейс машины, опять же консультируясь с настройками.
- Guiclient для доступа приложения к графической подсистеме хоста. Принцип работы примерно тот же. Guiclient запускает внутри окружения виртуальный X-сервер, запросы к которому перенаправляются в guiserver на хост-системе, а тот, в свою очередь, перенаправляет эти запросы настоящему X-серверу. Guiclient создан на базе графической подсистемы операционной системы Qubes OS и так же, как последняя, позволяет бесшовно вписать окно запущенного внутри песочницы приложения в графический интерфейс хост-системы.
Благодаря такой архитектуре Cappsule реализует очень простые и устойчивые к взлому песочницы. По факту для взломщика (или малвари), оказавшегося внутри такой песочницы, есть только четыре возможности из нее выбраться: через уязвимость гипервизора или уязвимость в одном из трех компонентов — fsserver, netserver и guiserver. Причем последние три работают с правами создавшего песочницу пользователя.
Где взять?
Исходный код Cappsule открыт, поэтому скачать и скомпилировать ее может любой желающий. Однако есть довольно серьезные ограничения. Первое: система требует процессор с поддержкой Intel VT-x и EPT, так что древние процессоры и AMD не подойдут. Второе: официально поддерживается единственный дистрибутив — Ubuntu 16.04 с ядром 4.4.0. Но протестировать систему можно и в виртуалке. Для этого разработчики подготовили образы VMware и VirtualBox.
Вся документация доступна в отдельном Git-репозитории. Из нее можно узнать, как установить Cappsule и пользоваться ею, создавать файлы политик для ограничения приложений в доступе к файлам или сетевому взаимодействию. В целом все довольно просто. В случае с Ubuntu 16.04 достаточно установить пакет:
$ wget https://irma.quarkslab.com/cappsule/cappsule-1.0.deb
$ sudo dpkg --force-confnew -i cappsule-1.0.deb
$ export PATH=$PATH:/usr/local/cappsule/usr/bin
Затем запустить демон:
$ sudo /usr/local/cappsule/usr/bin/daemon
И можно работать с приложениями в песочницах:
$ virt exec --no-gui --policy unrestricted bash
На экране должно появиться приглашение интерпретатора bash, запущенного в песочнице. Опция --policy unrestricted здесь означает, что будут использованы политики unrestricted, разрешающие доступ к любым файлам и любым сетевым хостам по протоколам UDP и TCP. Сами политики размещаются в JSON-файлах в каталоге /usr/local/cappsule/etc/cappsule/policies/. Кроме unrestricted, в нем можно найти политики для Firefox, Irssi, Evince и Apache. Причем, если имя приложения совпадает с именем файла политик, они будут загружены автоматически:
$ virt exec firefox
Графические приложения запускаются в своих собственных окнах, но поддержка копирования и вставки, а также вывода и записи аудио пока не реализованы.
![Политики доступа Firefox](https://xakep.ru/wp-content/uploads/2016/11/1479712321_716b_firefox-profile.png)
Выводы
Cappsule еще слишком молодой проект, чтобы говорить о его будущем. Но одно ясно точно: это самая интересная и в теории надежная реализация песочниц для Linux из всех существующих на данный момент. Cappsule представляет намного более узкий attack surface в сравнении с песочницами уровня ОС или полноценными виртуальными машинами.
Из песочницы Cappsule невозможно сбежать, взломав ядро или найдя баг в реализации виртуальных устройств, как это уже было в случае с багами в драйвере флоппи-привода и OpenGL-драйвере VirtualBox. Система крайне проста и эффективна, она требует лишь свежее ядро Linux и поддержку технологий виртуализации в процессоре.