Conocemos el término DoS o denegación de servicio como una acción en la cual un servicio o software en general deja de funcionar por culpa de algún atacante o en su defecto, un usuario común que realiza una acción sin saber que esto puede afectar al servicio. En este artículo explicaremos como es posible a través de una vulnerabilidad DoS ejecutar código de forma remota, acción también conocida como RCE en informática.
Un ejemplo simple de ello es ubicarnos en un caso hipotético en el cual, un programa recibe 2 números, para luego calcular la suma de ellos, y así devolver el resultado.
Si este programa recibe, por ejemplo, una palabra como infinity y un numero como 13. El programa no va a saber cómo tratar estos datos de entrada, ya que no tiene idea de cómo sumar números con palabras.
En esta situación, el programa sufre un error de ejecución por lo cual deja de funcionar y se cierra. Esto es lo que conocemos como Denegación de Servicio (DoS).
Existen muchas otras formas de denegar un servicio, una de ellas es realizando más solicitudes de las que un programa puede recibir al mismo tiempo, o excediendo un límite de solicitudes definido por el mismo programa.
Fujo de un programa
Todo programa tiene una función principal en donde inicia y sigue ciertas instrucciones.
Hay instrucciones las cuales llaman a funciones, que vendrían a ser como un sub-programa. Luego que el flujo del programa realiza todas las instrucciones de la función, debe retornar a la siguiente instrucción de la función principal, luego del llamado de la función. Esto lo podemos observar en el siguiente gráfico.
Para que este flujo se realice, debe de almacenarse, al entrar a la función, la información de a donde debe retornar el programa luego de ejecutar la función, a esta dirección se le llama dirección de retorno.
Esta dirección de retorno es primordial, puesto que si se corrompe de una u otra forma, el programa no va a completar el flujo correcto y puede estropearse, generando así una denegación de servicio (DoS).
Buffer
Un buffer es un espacio de almacenamiento determinado que se define para guardar información en él. Por ejemplo, un buffer para almacenar el nombre de un usuario, con longitud 8.
Si ingresamos otro nombre por ejemplo maximiliana. Este nombre tiene más de 8 caracteres, por ende, esto terminará excediendo la longitud del buffer y por lo tanto generará un desbordamiento del buffer.
Buffer Overflow
Como vemos en la imagen anterior, el desbordamiento de buffer, permite que el texto ingresado, exceda la longitud del buffer y termine escribiendo mas allá del espacio reservado para el nombre.
De esta forma, en algunos casos, cuando el texto ingresado es muy largo, puede llegar a alcanzar el espacio de memoria donde se almacena la dirección de retorno. De esta manera, termina corrompiendo la dirección de retorno y estropeando el flujo del programa generando un ataque DoS.
Hasta este momento hemos visto que un desbordamiento de buffer puede generar una denegación de servicio, pero ahora nos preguntamos… ¿Se puede aprovechar el cambio de la dirección de retorno? La respuesta es SÍ.
Un atacante podría cambiar la dirección de retorno por una dirección de alguna otra función que no forma parte del flujo original del programa, como por ejemplo, una función responsable de la asignación de permisos de usuario o gestión de estos.
¿Qué es un RCE en informática?
Otra acción que podría realizar un atacante sería agregar instrucciones maliciosas en la memoria para que luego, al cambiar la dirección de retorno, el programa se dirija a estas instrucciones ejecutándolas (RCE en informática). Este grupo de instrucciones maliciosas están escritas en lenguaje ensamblador y se les conoce como shellcode.
Un ejemplo de shellcode puede ser el siguiente:
char code[] = \ "\x89\xe5\x83\xec\x20\x31\xdb\x64\x8b\x5b\x30\x8b\x5b\x0c\x8b\x5b" "\x1c\x8b\x1b\x8b\x1b\x8b\x43\x08\x89\x45\xfc\x8b\x58\x3c\x01\xc3" "\x8b\x5b\x78\x01\xc3\x8b\x7b\x20\x01\xc7\x89\x7d\xf8\x8b\x4b\x24" "\x01\xc1\x89\x4d\xf4\x8b\x53\x1c\x01\xc2\x89\x55\xf0\x8b\x53\x14" "\x89\x55\xec\xeb\x32\x31\xc0\x8b\x55\xec\x8b\x7d\xf8\x8b\x75\x18" "\x31\xc9\xfc\x8b\x3c\x87\x03\x7d\xfc\x66\x83\xc1\x08\xf3\xa6\x74" "\x05\x40\x39\xd0\x72\xe4\x8b\x4d\xf4\x8b\x55\xf0\x66\x8b\x04\x41" "\x8b\x04\x82\x03\x45\xfc\xc3\xba\x78\x78\x65\x63\xc1\xea\x08\x52" "\x68\x57\x69\x6e\x45\x89\x65\x18\xe8\xb8\xff\xff\xff\x31\xc9\x51" "\x68\x2e\x65\x78\x65\x68\x63\x61\x6c\x63\x89\xe3\x41\x51\x53\xff" "\xd0\x31\xc9\xb9\x01\x65\x73\x73\xc1\xe9\x08\x51\x68\x50\x72\x6f" "\x63\x68\x45\x78\x69\x74\x89\x65\x18\xe8\x87\xff\xff\xff\x31\xd2" "\x52\xff\xd0";
Podemos ver el código en ensamblador de esta shellcode en el siguiente enlace:
https://packetstormsecurity.com/files/156478/Windows-x86-Null-Free-WinExec-Calc.exe-Shellcode.html
En este caso, la shellcode ejecuta una calculadora (calc.exe), provocando el siguiente flujo:
En lugar de un shellcode que solo ejecuta una calculadora, un atacante podría generar una shell reversa y conseguir acceso total a un servidor comprometido.
Conclusión de un DoS a un RCE en informática
- En los ataques de Buffer Overflow podemos entender cómo es que una vulnerabilidad puede escalar desde un impacto bajo, a comprometer un servidor completo.
- Un RCE en informática permite la ejecución de cualquier tipo de código, el cual se le conoce como shellcode.
- Es recomendable mantener los programas actualizados, ya que de encontrarse con programas que tengan un desbordamiento de buffer y que no tenga actualizaciones o parches para reparar la vulnerabilidad, un atacante podría aprovecharse de este vector de ataque y comprometer una organización entera.