Las aplicaciones que ejecutan scripts en formato bat y cmd en la plataforma Windows utilizando funciones estándar de inicio de procesos son vulnerables a una amenaza que permite la ejecución de código propio si se pasan argumentos al iniciar sin un escape adecuado de caracteres especiales. Esta vulnerabilidad ha recibido el nombre en código BatBadBut y se manifiesta en aplicaciones que utilizan las bibliotecas estándar de lenguajes como Rust, PHP, Node.js, Python, Ruby, Go, Erlang y Haskell.
El problema se ha identificado como una vulnerabilidad porque afecta a las funciones de la biblioteca, como Command::arg y Command::args en Rust, que están diseñadas para pasar argumentos directamente al proceso sin que sean procesados por el intérprete de comandos. Se asume que el desarrollador de la aplicación puede no verificar los argumentos, ya que se pasan directamente al proceso que se está ejecutando. Mientras que en sistemas Unix, los argumentos se pasan al proceso por separado en un array, en Windows, al usar la API CreateProcess, los argumentos se presentan como una sola cadena, y su análisis recae en el proceso que se inicia.
Al ejecutar scripts bat y cmd en la plataforma Windows, la función CreateProcess() invoca implícitamente el archivo ejecutable cmd.exe, incluso si la aplicación no lo especifica en la llamada. El programa cmd.exe contiene su propia lógica compleja para separar los argumentos, diferenciando entre sus propios argumentos, los del script que se está ejecutando y los argumentos de ese script. Para protegerse contra la sustitución de argumentos en la plataforma Windows, las bibliotecas estándar de lenguajes de programación utilizan controladores de escape separados que, como se ha descubierto, se pueden eludir mediante la manipulación de comillas dobles.
Por ejemplo, en un programa que llama al script './test.bat' con un argumento basado en datos proporcionados por el usuario, un atacante puede pasar el valor '»&calc.exe', que al ejecutar el script se expandirá a la cadena 'C:\Windows\System32\cmd.exe /c .\test.bat «»&calc.exe»' y provocará el lanzamiento del proceso calc.exe. Este método también funciona en el caso de lanzamientos implícitos de scripts, cuando se ejecuta un archivo ejecutable llamado 'test' sin especificar la extensión, y en uno de los directorios mencionados en la variable de entorno PATH existe un archivo 'test.bat'.
Actualmente se ha lanzado una corrección (CVE-2024-24576) para la biblioteca estándar del lenguaje Rust, la cual forma parte de la actualización Rust 1.77.2. Se están preparando actualizaciones para abordar la vulnerabilidad en Node.js y PHP (ya se han establecido las etiquetas 8.2.18 y 8.3.5, pero los lanzamientos aún no se han anunciado). Los proyectos de Python, Ruby, Go, Erlang y Haskell, por ahora, solo han agregado un aviso en la documentación sobre la aparición de la vulnerabilidad en ausencia de un adecuado escape de caracteres especiales.
En Rust 1.77.2, se ha agregado una comprobación adicional a la biblioteca estándar que devuelve un error si el argumento del script ejecutable contiene caracteres especiales que no se pueden garantizar que sean seguros de escapar. Para los desarrolladores que implementan su propia lógica de escape, se proporciona el método CommandExt::raw_arg, que desactiva completamente el escape en las llamadas de la biblioteca.
La adición de protección se ve obstaculizada por el hecho de que un simple escape de comillas dobles no es suficiente, ya que el intérprete de comandos procesa y expone variables como '%PATH%'. Por ejemplo, una comilla se puede inyectar manipulando la variable de entorno '%CMDCMDLINE%', especificando en lugar de '"&calc.exe' — '%CMDCMDLINE:~-1%&calc.exe'.
Fuente: opennet.ru
