
Doble liberación
CVE-2020-25637
*** Descripción ***
Se produjo un problema de doble liberación de memoria en la API libvirt, en versiones anteriores a la versión 6.8.0, encargada de solicitar información sobre las interfaces de red de un dominio QEMU en ejecución. Esta falla afecta al controlador de control de acceso polkit. Específicamente, los clientes que se conectan al socket en modo lectura-escritura con permisos ACL limitados podrían usar esta falla para bloquear el demonio libvirt, provocando una denegación de servicio, o potencialmente aumentar sus privilegios en el sistema. La mayor amenaza de esta vulnerabilidad es para la confidencialidad e integridad de los datos, así como para la disponibilidad del sistema.
La amenaza más importante de esta vulnerabilidad es:
Puntuaciones de la falla:
Una falla moderada por RedHat con una puntuación media de 6.4
Una falla moderada por NVD con una puntuación media de 6.7
*** Diferentes herramientas y requisitos importantes para explotar esta falla ***
Antes que nada, es necesario verificar la compatibilidad de nuestro sistema operativo, basta con ejecutar este comando:
grep -E -c "vmx|svm" /proc/cpuinfo
Si el comando responde ok, puede proceder a la instalación:
sudo apt-get -y install qemu-kvm libvirt-bin virt-top outils-libguestfs virtinst bridge-utils
2) Instalación de Vagrant:
Para instalar Vagrant, basta con ejecutar este comando:
sudo apt -y install vagrant
Una vez que haya instalado Vagrant y KVM, debería estar listo para instalar un complemento libvirt para poder comenzar a gestionar las máquinas virtuales KVM usando Vagrant.
vagrant plugin install vagrant-libvirt
Puede confirmar que el complemento se ha instalado:
vagrant plugin list
3) Caja Vagrant (box vagrant):
Es posible usar una plantilla ya preparada directamente con Vagrant; en nuestro caso se usará una imagen de Ubuntu 20.04.
Para agregar nuestra imagen a la caja Vagrant, basta con ejecutar este comando:
vagrant box add generic / ubuntu1804 --provider = libvirt
Para consultar la lista de cajas presentes localmente:
vagrant box list
4) Depuración
Dos posibilidades de depuración:
GDB: Si la herramienta no está disponible en su sistema operativo, ejecute este comando:
sudo apt-get install gdb
Valgrind: Si la herramienta no está disponible en su sistema operativo, ejecute este comando:
sudo apt-get install valgrind
*** Ejecución del código ***
Iniciar una VM mediante Vagrant:
vagrant up
Antes que nada, instalar la biblioteca:
sudo apt-get install -y libvirt-dev
Compilación:
gcc -g -Wall info1.c -o info1 -lvirt
Ejecución del código:
./info1 qemu:///system vagrant-vms_ubuntu-01
Ejecución con depuración:
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind-out.txt ./info1 qemu:///system vagrant-vms_ubuntu-01
*** Activar la falla ***
Antes de activar la falla, es primordial conocer el funcionamiento de la función que presenta el problema en libvirt.
Supongamos que un atacante puede provocar el uso de una zona de memoria liberada a través de qemuAgentGetInterfaces() de libvirt, precisamente en la zona de memoria de la variable ifname para causar una denegación de servicio y, eventualmente, ejecutar código.
El momento esperado ha llegado.
Una vez que el archivo Vagrant está en marcha, hay que ejecutar el código info1.c en una máquina virtual que a su vez está lanzada por Qemu/KVM. Por lo tanto, hacer VMs dentro de una VM, es decir, ejecutar el código en la VM creada por Vagrant.
*** Corrección de esta falla ***
Basta con pasar la variable ifname a null en la función qemuAgentGetInterfaces() de libvirt, es decir, la variable ifname debe ser liberada para cada interfaz.
*** Demostración ***
Encontrará una demostración simple del problema (doble liberación) en el archivo PowerPoint.
*** Importante ***
El proyecto no está terminado hasta el final por razones de complejidad de la falla y de hardware, así como la falta de tiempo.