Algo viejo, pero todavía relevante de conocer para evitar una simple vía de escalada de privilegios son los shell escapes.
¿Qué son los Shell Escapes?
Los shell escapes son una característica de muchos programas basados en texto que te permiten salir temporalmente de la interfaz del programa para ejecutar comandos de shell sin cerrar la aplicación.
El problema es que los shell escapes no solo te dan acceso a un shell, te dan acceso a un shell con los permisos y el entorno del programa padre, así que si estás ejecutando vim con sudo, cualquier shell escape que actives se ejecuta con privilegios de root, creando un potencial vector de escalada de privilegios.
Esto no es un bug, solo una característica que ha existido durante años pero que puede ser peligrosa si no se gestiona.

Cómo Funcionan los Shell Escapes
Así es como funcionan los shell escapes:
- Un usuario ingresa al editor de texto
vim. - En la interfaz de
vim, el usuario activa un shell escape (por ejemplo,!/bin/sh) que instruye avim(el proceso padre) a invocar la llamada al sistemafork()para crear un nuevo proceso hijo (el nuevo shell). - Este proceso hijo es una copia exacta del proceso padre (
vim), incluyendo su estado actual, entorno de ejecución y privilegios:- Variables de entorno (PATH, HOME, USER, etc.)
- Directorio de trabajo (ubicación actual en el sistema de archivos)
- Permisos del proceso (UID/GID, grupos suplementarios)
- Descriptores de archivo (archivos abiertos, conexiones de red)
- Límites de recursos (memoria, CPU, manejadores de archivo)
- El proceso hijo luego invoca la llamada al sistema
execve()para reemplazarse a sí mismo con un shell (por ejemplo,/bin/sh). - El shell luego comienza la ejecución con el entorno y permisos heredados. Entonces, si el proceso padre (por ejemplo,
vim) fue ejecutado con privilegiossudo, el shell hereda estos privilegios elevados también. - Cuando el usuario sale del shell (mediante
exitoCtrl+D), el proceso del shell termina y el control regresa al proceso padre (vim). - El proceso padre continúa la ejecución como si nada hubiera pasado.
Programas con Shell Escapes
Ejemplos Comunes en Linux
En una instalación regular de Linux, los shell escapes se pueden realizar en:
- Editores de texto como vim y emacs soportan shell escapes. En vim, puedes usar
:shellpara abrir un shell interactivo completo,:!commandpara ejecutar comandos individuales, o incluso:read !commandy:write !commandpara pasar contenido a través de comandos de shell. Cada uno de estos puede ser abusado si vim se está ejecutando con privilegios elevados. - Programas paginadores como less y more tienen sus propios mecanismos de shell escape. En less, la sintaxis
!commandejecuta comandos de shell, la teclavabre tu $EDITOR (que podría en sí mismo soportar shell escapes), y la sintaxis| commandpasa contenido a través de comandos de shell. - Clientes de base de datos como mysql, psql y sqlite3 a menudo tienen características de shell escape. Muchos te permiten ejecutar comandos del sistema desde dentro de sus interfaces interactivas, lo cual se convierte en un problema cuando estos clientes se ejecutan con privilegios elevados o tienen acceso a datos sensibles.
El Repositorio GTFOBins
El GTFOBins es un repositorio genial de binarios de Linux que soportan shell escapes y técnicas similares de escalada de privilegios.
Es un buen recurso para conocer, por ejemplo muestra que puedes usar shell escapes de less así. Ahora eres root, porque less ejecutó el shell con sus privilegios.
sudo less /etc/hosts
# Dentro de less, presiona ! seguido del comando (sintaxis: !command)
!/bin/sh
sh-5.3 # Nuevo prompt
Container Escapes
Algo que pienso como una evolución de los shell escapes son los container escapes. Ambos involucran romper el aislamiento para alcanzar un entorno más privilegiado. En lugar de un breakout de shell como vim, los container escapes rompen el aislamiento del contenedor para acceder al host.
Los contenedores son comunes hoy en día y muchos de ellos ejecutan cargas de trabajo AI/ML, lo que los hace un buen objetivo para exploits, ya que algunos necesitan acceso privilegiado a recursos de hardware como GPU, requieren montajes de socket, o algunas capacidades peligrosas del kernel para funcionar como se pretende.
Defenderse Contra los Shell Escapes
Volviendo a los shell escapes… Defenderse contra los shell escapes es directo pero importante, hay muchos enfoques para estar protegido.
Principio de Mínimo Privilegio
Siempre otorga el acceso mínimo necesario a los usuarios para realizar las tareas.
Para acceso sudo, otorga acceso a comandos específicos con argumentos específicos, no acceso amplio a programas interactivos. Por ejemplo, en el archivo sudoers, otorga acceso solo a sudoedit para tareas de edición de archivos en lugar de otorgar acceso general sudo a editores de texto. Usa la etiqueta NOEXEC para prevenir la ejecución de comandos cuando no sea necesario.
Para contenedores, ejecuta con las capacidades mínimas necesarias. Elimina todas las capacidades y agrega de vuelta solo lo que se requiere. Nunca ejecutes contenedores privilegiados, usa contenedores rootless en su lugar.
sudoedit
Para edición de archivos, otorga acceso a sudoedit a los usuarios en lugar de sudo simple:
# En /etc/sudoers - incorrecto:
user ALL=(ALL) /usr/bin/vim /etc/ssh/sshd_config
# Forma correcta:
user ALL=(ALL) sudoedit /etc/ssh/sshd_config
sudoedit crea una copia temporal del archivo objetivo propiedad del usuario. Abre esa copia en el editor de texto del usuario ejecutándose con los privilegios normales del usuario. Cuando guardas y sales, sudoedit copia el archivo modificado de vuelta a la ubicación original con privilegios de root.
Dado que el editor nunca se ejecuta como root, los shell escapes solo te dan acceso a tu propia cuenta de usuario.
NOEXEC
En sudoers, usa la etiqueta NOEXEC para comandos que necesitan ejecutarse con privilegios elevados pero no deberían poder ejecutar otros programas:
# Contenido de /etc/sudoers
user ALL=(ALL) NOEXEC: /usr/bin/vim /etc/config
user ALL=(ALL) NOEXEC: /usr/bin/less /var/log/syslog
NOEXEC establece la variable de entorno LD_PRELOAD para cargar una librería que intercepta llamadas a execve(). Cuando un shell escape intenta generar un nuevo proceso, la llamada es bloqueada.
Algunos programas podrían usar llamadas al sistema que no son interceptadas, y puede romper programas que legítimamente necesitan ejecutar otros comandos. Pero para muchos casos de uso, proporciona una buena protección contra los shell escapes.
Conclusión
Los shell escapes no son nuevos, pero siguen siendo relevantes ya que representan cómo la escalada de privilegios puede ocurrir a través de características cotidianas. A veces una funcionalidad conveniente puede llevar a consecuencias peligrosas.
El principio de mínimo privilegio siempre es bienvenido. Previene la explotación de sudo otorgando acceso a comandos específicos, usa sudoedit para edición de archivos, aplica NOEXEC donde sea apropiado, y piensa en qué necesitan realmente los usuarios y contenedores. La mayoría de los ataques de escalada de privilegios tienen éxito porque alguien otorgó más acceso del necesario.
Temas relacionados: