
Двойное освобождение
CVE-2020-25637
*** Описание ***
В API libvirt, в версиях до 6.8.0, отвечающей за запрос информации о сетевых интерфейсах работающего домена QEMU, произошла ошибка двойного освобождения памяти. Эта уязвимость затрагивает драйвер контроля доступа polkit. В частности, клиенты, подключающиеся к сокету с правами чтения-записи и ограниченными разрешениями ACL, могут использовать эту уязвимость для аварийного завершения демона libvirt, что приводит к отказу в обслуживании, или потенциально повысить свои привилегии в системе. Наибольшая угроза от этой уязвимости касается конфиденциальности и целостности данных, а также доступности системы.
Наиболее значимые угрозы от этой уязвимости:
Оценки уязвимости:
Умеренная уязвимость от RedHat со средним баллом 6.4
Умеренная уязвимость от NVD со средним баллом 6.7
*** Различные инструменты и важные предварительные требования для эксплуатации этой уязвимости ***
Прежде всего необходимо проверить совместимость нашей операционной системы, достаточно выполнить эту команду:
grep -E -c "vmx|svm" /proc/cpuinfo
Если команда отвечает ok, можно приступать к установке:
sudo apt-get -y install qemu-kvm libvirt-bin virt-top outils-libguestfs virtinst bridge-utils
2) Установка vagrant:
Для установки vagrant достаточно выполнить эту команду:
sudo apt -y install vagrant
После установки Vagrant и KVM вы должны быть готовы установить плагин libvirt, чтобы начать управлять виртуальными машинами KVM с помощью Vagrant.
vagrant plugin install vagrant-libvirt
Вы можете подтвердить, что плагин установлен:
vagrant plugin list
3) Vagrant box (vagrant box):
Можно использовать готовый шаблон напрямую из Vagrant; в нашем случае мы используем образ Ubuntu 20.04.
Чтобы добавить наш образ в хранилище vagrant, достаточно выполнить эту команду:
vagrant box add generic / ubuntu1804 --provider = libvirt
Для просмотра списка локально доступных образов:
vagrant box list
4) Отладка
Два варианта отладки:
GDB, если инструмент не доступен в вашей операционной системе, выполните команду:
sudo apt-get install gdb
Valgrind, если инструмент не доступен в вашей операционной системе, выполните команду:
sudo apt-get install valgrind
*** Выполнение кода ***
Запустить виртуальную машину через vagrant:
vagrant up
Прежде всего установите библиотеку:
sudo apt-get install -y libvirt-dev
Компиляция:
gcc -g -Wall info1.c -o info1 -lvirt
Выполнение кода:
./info1 qemu:///system vagrant-vms_ubuntu-01
Выполнение с отладкой:
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind-out.txt ./info1 qemu:///system vagrant-vms_ubuntu-01
*** Активация уязвимости ***
Перед активацией уязвимости важно понимать работу функции, вызывающей проблему в libvirt.
Предположим, что злоумышленник может вызвать использование освобождённой области памяти через qemuAgentGetInterfaces() из libvirt, а именно в области памяти переменной ifname, чтобы вызвать отказ в обслуживании и, возможно, выполнить код.
Долгожданный момент настал:
Как только файл vagrant запущен, необходимо запустить код info1.c внутри виртуальной машины, которая сама запущена через Qemu/KVM. То есть запускать виртуальные машины внутри виртуальной машины, то есть выполнять код в виртуальной машине, созданной Vagrant.
*** Исправление этой уязвимости ***
Достаточно установить переменную ifname в NULL в функции qemuAgentGetInterfaces() из libvirt, то есть переменная ifname должна быть освобождена для каждого интерфейса.
*** Демонстрация ***
Вы найдёте простую демонстрацию проблемы (двойное освобождение) в файле PowerPoint.
*** Важно ***
Проект не завершён до конца по причинам сложности уязвимости, аппаратных ограничений, а также нехватки времени.