Ejecutamos código arbitrario en Vim y Neovim
Hoy hablaremos sobre la vulnerabilidad en el editor de Vim y su hermana Neovim. Para su funcionamiento, no se necesitan privilegios; el usuario solo necesita abrir un archivo especialmente generado que ejecutará código arbitrario en el sistema de destino.
Vim es interminable entorno personalizable que es adecuado para resolver una gran lista de tareas. Alguien simplemente edita archivos con ellos, y alguien los modifica hasta que obtienen un IDE para algunos de los lenguajes de programación. Gracias a esta flexibilidad, Vim sigue siendo uno de los editores más populares. Está preinstalado en la mayoría de las distribuciones de Linux modernas, por lo que la vulnerabilidad es potencialmente interesante.
La vulnerabilidad fue descubierta por Armin Razmjou a mediados de este año. Se le asignó el número CVE-2019-12735: «Vim y Neovim vulnerabilidad de ejecución de código arbitrario». Las versiones de Vim que no contienen el parche 8.1.1365 y las versiones de Neovim inferiores a 0.3.6 estaban en riesgo.
La razón del error es que la función source
procesa archivos fuera del entorno protegido. Esto permite que un atacante ejecute cualquier comando que esté disponible en Vim.
Pararse
Primero, elevemos el stand con versiones vulnerables de Vim y Neovim. Usaremos el contenedor Docker con Debian.
$ docker run --rm --hostname vimrce --name vimrce --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -it debian /bin/bash
Instale todas las dependencias necesarias.
$ apt update && apt install -y nano build-essential cmake wget unzip pkg-config libtool libtool-bin gettext git gdb libncurses5-dev libncursesw5-dev strace ltrace
Este tipo de calzado es necesario porque compilaremos las distribuciones de los editores desde la fuente. Descarga de versiones vulnerables: para Vim, esto es todo lo que es inferior a la versión 8.1.1365, y para Neovim, no es superior a 0.3.5.
$ cd ~
$ git clone https://github.com/vim/vim.git --depth=1 --branch=v8.1.1364
$ git clone https://github.com/neovim/neovim.git --depth=1 --branch=v0.3.5
Compila e instala Vim. Active las banderas para agregar información de depuración.
$ cd ~/vim
$ sed -i 's@#STRIP = /@STRIP = /@' src/Makefile
$ CFLAGS="-g -DDEBUG" ./configure
$ make
$ make install
Hacemos lo mismo para Neovim.
$ cd ~/neovim
$ make CMAKE_EXTRA_FLAGS="-g"
$ make install
Ahora necesitamos crear archivos de configuración en los que se debe activar modeline. Para Vim, esto está .vimrc
en el directorio de inicio, y para Neovim está init.vim
.
$ echo "set modeline" > ~/.vimrc
$ mkdir -p ~/.config/nvim/
$ echo "set modeline" > ~/.config/nvim/init.vim
El stand está listo. Puede ejecutar los editores y verificar su rendimiento.
Stand listo con versiones vulnerables de Vim y Neovim
Detalles de vulnerabilidad
Para comenzar, descubramos qué es modeline
. Hay cuatro modos principales de operación en Vim: modo normal, modo de inserción, modo de comando y modo visual.
Visualización del modo Vim Editor
Para cambiar al modo normal, debe presionar Esc
, y con la ayuda :
puede ingresar el comando. En él, puede ejecutar comandos integrados en Vim o proporcionados por complementos. Esto puede ser una variedad de acciones: configurar el entorno y los archivos de trabajo, funciones relacionadas con el procesamiento de textos, comandos de shell y similares.
El archivo ayuda a no prescribir comandos cada vez de forma manual y a configurar el entorno Vim para satisfacer sus necesidades .vimrc
. Por analogía .bashrc
, se ejecuta cada vez que se inicia Vim. Si dicho archivo se encuentra en el directorio raíz del usuario actual, se descargará automáticamente.
Todo esto es, por supuesto, conveniente, pero ¿qué pasa si necesita anular algunas configuraciones para un tipo particular de archivo o incluso dentro del mismo documento? Aquí modeline viene al rescate. Este modo le permite definir opciones para editarlo en el archivo abierto. La configuración se establece directamente en el archivo, de forma predeterminada se interpretan la primera y la última línea. Si coinciden con el patrón, entonces Vim los ejecuta.
En algunas distribuciones modernas de Linux, este modo está habilitado de forma predeterminada. Si la versión de su editor está en riesgo, escriba el comando :set modeline?
. Verá la respuesta nomodeline
: considere que está seguro y que la vulnerabilidad no se aplica a usted.
Hay dos formatos para especificar opciones en modeline. El primero es corto.
[любой_текст]{пробел_или_таб}{vi:|vim:|ex:}[пробел_или_таб]{опции}
Como опций
se indica la lista de configuraciones necesarias, separadas por un espacio o dos puntos. Cada parte antes de los dos puntos es un argumento a favor :set
. Por ejemplo, a menudo especifican anchos de línea personalizados, tamaños de pestaña y reemplazo de pestañas con espacios.
vim:tw=80 ts=4 et
El segundo formato es avanzado.
[любой_текст]{пробел_или_таб}{vi:|vim:|ex:}[пробел_или_таб]se[t] {опции}:[любой_текст]
En este formato, las mismas opciones se verán así:
/* vim: set textwidth=80 tabstop=4 expandtab: */
Por supuesto, por razones de seguridad, no todas las configuraciones se pueden usar en modeline.
No todas las opciones son editables a través de modeline.
Por ejemplo, intentemos cambiar la codificación en la que trabaja el editor. La opción es responsable de esto enc
.
/* vim: set enc=foo: */
La opción enc no está disponible para cambiar a través de modeline
/src/option.c
4544: /* Disallow changing some options from modelines. */
4545: if (opt_flags & OPT_MODELINE)
4546: {
4547: if (flags & (P_SECURE | P_NO_ML))
4548: {
4549: errmsg = _("E520: Not allowed in a modeline");
4550: goto skip;
4551: }
Además de las opciones habituales, se permite el uso de expresiones.
/* vim: set fdm=expr fde=getline(v:lnum)=~'{'?'>1':'1': */
Todas las expresiones se ejecutan en modo sandbox.
Expresiones de modeline ejecutadas en un sandbox
Permite el uso de las «operaciones seguras» más simples.
Pasemos a los géneros. Comprueba si se puede ejecutar una expresión sandbox, una función check_secure
.