Este artículo forma parte de una serie donde veremos distintas vulnerabilidades que nos podemos encontrar en nuestra página Web. Vamos a ver como un ciberdelincuente es capaz de explotarlas y conseguir su objetivo y también veremos unas pautas que podemos seguir para corregir la vulnerabilidad. En esta ocasión vamos a ver en qué consisten las vulnerabilidades de ejecución de código o ejecución de comandos a través de páginas Web, más conocidas como Command Injection.
Artículo elaborado por José Arroyo Viana, administrador de sistemas y experto en ciberseguridad de Extra Software.
¿Qué es?
Las vulnerabilidades de Command Injection permiten ejecutar código arbitrario o no controlado por el desarrollador en el sistema operativo donde está almacenada la Web.
Ejemplo de Command Injection
A continuación, vamos a ver paso a paso cómo hacernos con el servidor que está detrás de una página web publicada aprovechando uno de los servicios que da.
En ocasiones hay Webs que permiten ejecutar un comando o una herramienta a través de ellas. Por ejemplo, nos encontramos con la siguiente web que permite hacer un ping a la dirección que pongamos en el recuadro de texto del formulario.
La herramienta Ping nos permite, indicando una dirección IP o un nombre de dominio como Facebook.com, saber si es accesible o no. Esto lo hace enviando un paquete de información desde el equipo origen mediante el protocolo ICMP y espera una contestación del equipo destino.
Si nosotros ponemos el dominio Facebook.com en el recuadro y pulsamos en el botón de enviar (submit). Vemos que se envían una serie de paquetes y se obtiene una respuesta
Este comando realmente se está ejecutando en el equipo donde está almacenada la página Web, nosotros sabemos previamente que la Web está almacenada en un equipo Linux y que la salida del comando ping que se ha ejecutado corresponde con la salida que se espera obtener en un equipo Linux. Hacemos la misma prueba y verificamos que es la misma salida. Por lo tanto, el formulario web le está pasando al comando ping lo que nosotros pongamos en el campo de texto, en este caso facebook.com.
Sabemos que en Linux podemos concatenar varios comandos separándolos por punto y coma (;). Por lo tanto, si a la misma línea del comando ping anterior le añadimos un comando que nos identifique el usuario con el que se está interactuando en la consola nos mostrará la salida de los dos comandos. En este caso el comando que podemos usar es whoami.
Vemos que después de la salida del comando ping nos muestra la salida del comando whoami que es root (Es decir, root es el usuario superadministrador de Linux y con el que estoy ejecutando estos comandos)
Siguiendo este mismo proceso y sabiendo que la Web está ejecutando el comando Ping y coge el valor que le pasemos nosotros mediante el formulario de texto, intentamos hacer la misma concatenación de comandos que habíamos probado en la máquina Linux. Le pasamos primero el dominio Facebook.com como valor del comando ping, seguido del punto y coma (;) y el comando whoami:
Si esto lo ejecutamos, podemos ver que nos muestra el usuario que está ejecutando los comandos a través del servicio Web, que es www-data
En este momento sabemos que la página Web es vulnerable a una ejecución de comandos. Podemos ejecutar cualquier comando después del ping y nos lo va a ejecutar en el servidor web que aloja la página. Los ciberdelincuentes pueden utilizar esta vulnerabilidad para ganar acceso a la máquina donde está alojada la Web o modificar la Web en su propio beneficio.
Una vez que tengan acceso a la máquina pueden intentar acceder a otras máquinas dentro de la misma red o pivotar hacía otras redes internas a las que desde el exterior no se tenga acceso.
Una vez que se tenga ejecución de comandos, básicamente el servidor está comprometido al 100%
Solución para el Command Injection
Hay que evitar el uso de funciones o el paso de valores a las funciones que permitan a un usuario ejecutar código en el servidor.
En el ejemplo que hemos visto seguramente el comando se guarde en una variable tipo $comando y luego se imprime por pantalla su valor.
Esto no se debería hacer así, tenemos que verificar que la entrada es lo que se espera. En este caso se espera una dirección IP y nada más. Por lo que podemos usar expresiones regulares para validar el valor a introducir. Por ejemplo, podríamos validar que solo acepte 4 dígitos separamos por un punto, que no acepte punto y coma (;), que no acepte otros valores de concatenación como & o | y que no acepte espacios. Otra forma es crear una expresión regular únicamente con los valores válidos a introducir.
Esto son formas de hacerlo más seguras, pero lo mejor es evitar este tipo de funciones.
Las vulnerabilidades de este tipo se pueden dar también en los gestores de contenidos CMS, a veces son desconocidos incluso por el propio fabricante (vulnerabilidades Zero Day). Por tanto, es importante, cuanto menos, mantener el propio CMS y los plugins o componentes actualizados para corregir las vulnerabilidades que ya ha conseguido corregir el fabricante.
En este artículo hemos explicado cómo funciona el ataque llamado Command Injection o ejecución de código. Es el primero de una serie sobre vulnerabilidades en las páginas web, que continuaremos el mes que viene con la técnica del Reconocimiento Web. Esperamos seguir contando con tu interés.