ATAQUES POR INYECCION DE CODIGO SQL SQL es un lenguaje textual utilizado para interactuar con bases de datos relacionales. La unidad típica de ejecución de SQL es la consulta "query", conjunto de instrucciones que permiten modificar la estructura de la base de datos (mediante instrucciones del tipo Data Definition Language) o manipular el contenido de la base de datos (mediante instrucciones del tipo Data Manipulation Language). En los servidores Web se utiliza este lenguaje para acceder a bases de datos y ofrecer páginas dinámicas o nuevas funcionalidades a los sistemas. Se conoce como Inyección SQL, indistintamente, al tipo de vulnerabilidad, al método de infiltración, al hecho de incrustar código SQL intruso y a la porción de código incrustado. El ataque por inyección de código SQL se produce cuando no se filtra de forma adecuada la información enviada por el usuario. Un usuario malicioso podría incluir y ejecutar textos que representen nuevas sentencias SQL que el servidor no debería aceptar. Este tipo de ataque es independiente del sistema de bases de datos subyacente, ya que depende únicamente de una inadecuada validación de los datos de entrada. Como consecuencia de estos ataques y dependiendo de los privilegios del usuario de base de datos bajo el cual se ejecutan las consultas, se podría acceder no solo a las tablas relacionadas con la operación de la aplicación del servidor Web, sino también a las tablas de otras bases de datos alojadas en el mismo servidor Web. También pueden propiciar la ejecución de comandos arbitrarios del sistema operativo del equipo del servidor Web. Ejemplos Así, como ejemplos de ataques de inyección de código SQL podríamos considerar las siguientes: Ejemplo 1: Si en el servidor se va a ejecutar una sentencia SQL del tipo: UPDATE tabla set PASSWORD='$INPUT[password]' WHERE user='$INPUT[user_id]'; pensada en principio para actualizar la contraseña de un determinado usuario registrado en el sistema, se podría llevar a cabo un ataque por inyección de código SQL con una dirección URL preparada de forma maliciosa tal y como sigue: http://www.servidor.com/script?pwd=clave%uid=1'+or+uid+like'%"admin%'; la cual tendría como consecuencia que el atacante conseguiría acceder a la base de datos con el perfil de administrador. Ejemplo 2: Si en el servidor se va a ejecutar una sentencia SQL del tipo: SELECT nombre FROM productos WHERE id LIKE '%$INPUT[cod_prod]%'; pensada para devolver el nombre de un producto a partir de su código identificador, se podría producir un ataque por inyección de código SQL con una dirección URL preparada así: http://www.servidor.com/script?' EXEC+ master..xp_cmdshell(cmd.exe+/c)" la cual tendría como consecuencia que el atacante podría ejecutar una aplicación del sistema operativo del equipo, en este caso el propio interprete de comandos Ejemplo 3: Si en el servidor se va a ejecutar una sentencia SQL del tipo: SELECT * FROM usuarios WHERE username = " + username + "AND password=" + password +"; se podría producir un ataque si el usuario especifica lo siguiente: username: ; drop table users ; password: ya que entonces la tabla 'usuarios' seria borrada de la base de datos, denegando el acceso a todos los demás usuarios (ataque de denegación de servicio). Ejemplo 4: Por ejemplo, asumiendo que el siguiente código reside en una aplicación web y que existe un parámetro "nombreUsuario" que contiene el nombre de usuario a consultar, una inyección SQL se podría provocar de la siguiente forma: El código SQL original y vulnerable es: consulta := "SELECT * FROM usuarios WHERE nombre = '" + nombreUsuario + "';" Si el operador escribe un nombre, por ejemplo "Alicia", nada anormal sucederá, la aplicación generaría una sentencia SQL similar a la siguiente, que es perfectamente correcta, en donde se seleccionarían todos los registros con el nombre "Alicia" en la base de datos: SELECT * FROM usuarios WHERE nombre = 'Alicia'; Pero si un operador malintencionado escribe como nombre de usuario a consultar: Alicia'; DROP TABLE usuarios; SELECT * FROM datos WHERE nombre LIKE '% se generaría la siguiente consulta SQL, (el color verde es lo que pretende el programador, el azul es el dato, y el rojo, el código SQL inyectado): SELECT * FROM usuarios WHERE nombre = 'Alicia'; DROP TABLE usuarios; SELECT * FROM datos WHERE nombre LIKE '%'; En la base de datos se ejecutaría la consulta en el orden dado, se seleccionarían todos los registros con el nombre 'Alicia', se borraría la tabla 'usuarios' y finalmente se seleccionaría toda la tabla "datos", que no debería estar disponible para los usuarios web comunes. En resumen, cualquier dato de la base de datos puede quedar disponible para ser leído o modificado por un usuario malintencionado. Nótese por qué se llama "Inyección" SQL. Si se observa el código malicioso, de color rojo, se notará que está insertado en el medio del código bueno, el verde. Así, el código rojo ha sido "inyectado" dentro del verde. Ejemplo 5: Si se tiene la siguiente pagina web Simula una aplicación que requiere identificación de usuario y password. Si se intenta entrar un usuario y password al azar la aplicación dirá “Acceso denegado” El login y password correcto son: “admin” y “admin1234”. Se puede comprobar introduciéndolo. Ahora se va a conseguir acceso PERMITIDO usando inyección SQL, sin conocer ni el Login ni el Password. ¿Por qué permite la entrada? Otras variantes a usar en el campo login podrían ser: Y variantes de consultas: Ejemplos de ataques: -Obtención de la base de datos completa usando sentencias SELECT -Modificación o inserción de datos usando INSERT o UPDATE -Borrado de la base de datos usando DELETE -Ejecución de comandos del sistema operativo usando EXEC master.dbo.xp_cmdshell por ejemplo, el valor de pass sería pass=hack' EXEC master.dbo.xp_cmdshell'cmd.exe dir c:'--Apagado remoto del servidor pass=hack' EXEC master.dbo.xp_cmdshell'cmd.exe shutdown'-- ¿Qué Bases de datos son susceptible a Inyección SQL? La más susceptible a ataques en MS SQL, dado que permite explotar el fallo más fácilmente y además posee opciones que facilitan el acceso al sistema, como la ejecución de comandos. En la lista siguiente se detalla una relación de posibilidades de explotación de cada base de datos. MySQL Se ejecuta con privilegios de 'root' por defecto Volcado a ficheros con INTO OUTFILE La ejecución de sentencias múltiples es POCO PROBABLE, pocos módulos lo permiten Oracle La ejecución de sentencias múltiples NO está permitida Anidamiento de consultas SELECT Uso de UNION posible Uso de procedimientos invocables desde la inyección DB2 Igual que Oracle Postgres La ejecución de sentencias múltiples SI está permitida Anidamiento de consultas SELECT Uso de UNION posible Uso de procedimientos invocables desde la inyección Uso de COPY posible como superusuario MS SQL La ejecución de sentencias múltiples SI está permitida Anidamiento de consultas SELECT Uso de UNION posible Uso de procedimientos invocables desde la inyección (mencion especial de 'xp_cmdshell' ) SEGURIDAD CONTRA SQL INJECTION ¿QUE HACER CONTRA ESTA VULNERABILIDAD? Es muy difícil desarrollar una aplicación segura a la primera. Ni siquiera las grandes aplicaciones escritas por programadores expertos están libres de fallos. La falta de tiempo y el número de programadores implicados en la aplicación son factores habituales que juegan en contra de la seguridad. Por este motivo son necesarias las auditorías de código, para localizar vulnerabilidades en el código. En general, la auditoría de código se considera la tarea más difícil y compleja a la que puede enfrentarse un programador. Actualmente existen empresas de seguridad informática que ofrecen servicios de auditoría de código a precios extremadamente altos, dependiendo de la aplicación. Sin embargo, en lo que respecta a la inyección SQL, la labor es mucho más fácil que con otros tipos de vulnerabilidades. La auditoría puede realizarse manualmente o mediante herramientas existentes para tales fines. Auditoría de código mediante herramientas - Ofrecen resultados satisfactorios en la detección de vulnerabilidades fáciles de identificar, y cuando nos enfrentamos a una inmensa cantidad de código, usar estas herramientas nos ahorrarán mucho tiempo. - Sin embargo hay muchos errores de lógica que estas herramientas son incapaces de hallar - Herramientas de auditoría de inyección SQL tenemos Acunetix Web Vulnerability Scanner y Netcraft, ambas de pago pero con versión de demostración de 30 días 1. Magic_quotes Es una variable que se encuentra en el fichero .ini de configuración de PHP. Cuando su valor es On, todas las entradas por parámetros sufrirán la adición de la barra invertida delante de la comilla simple. Es lo mismo que realiza la función addslashes. Si entra user=pe'dro se convertirá en pe\'dro , de forma que el interprete SQL no tomará la comilla como parte sintáctica, sino como dato carácter. La función inversa es stripslashes. Estas prácticas son una medida de seguridad habitualmente recomendada por autores de código. Sin embargo, NO ACONSEJA DEL TODO SU USO, pues a menudo lleva a errores una mala gestión de las barras. En su lugar se propone usar la siguiente función. 2. Mysql_real_scape_string( $cadena) Evita todos los caracteres especiales de la $cadena argumento, teniendo en cuenta el juego de caracteres usado en la conexión, de forma que sea segura usarla con Mysql_query. Coloca barras en los siguientes 7 caracteres:\x00 \n \r \ ' “ \x1a que se consideran peligrosos pues pueden ser usados para varios tipos de ataques. La función retorna la cadena con barras, pero la variable original $cadena entrada no se modifica. Algo parecido a esta función se puede realizar colocando comillas dobles de la forma $sql=”SELECT * FROM tabla WHERE usuario =' “ $_POST[“usuario” ] ” ' “; 3. Delimitar siempre los valores en las consultas. Aunque el valor de la consulta sea un entero, delimitarlo siempre entre comillas simples. Una sentencia del estilo SELECT user FROM table WHERE iduser= $id es mucho más fácilmente inyectable que SELECT user FROM table WHERE iduser= ' $id ' 4. Verificar siempre los datos que introduce el usuario Si se espera recibir un entero, no confiar en que lo sea, es mejor verificar con is_int(). Igualmente si es un long con is_long(), o un char, un varchar, o cualquier tipo con gettype(). Si se prefiere también se puede convertir al tipo de dato que se espera con intval() ó settype(). Comprobar también la longitud de las cadenas con strlen() o su formato con strpos(). Con esto se evitará posibles técnicas avanzadas de inyección SQL. 5. Crear librerías propias Es muy pesado programar vigilando y revisando constantemente cada variable, cada tipo, cada caracter. Es mejor crear librerías propias, una clases que actúen como capa de abstracción de todas estas ideas necesarias a tener en cuenta constantemente. Se programará más rápido, se evitarán descuidos, y simplemente se usa la seguridad que ya se programó. 6. PEAR Package DB - Paquete Bases de Datos PEAR El paquete DB del grupo PEAR va más allá de la seguridad. Es una capa de abstracción para bases de datos. El inconveniente es que se depende siempre de sus paquetes. Pero la ventaja es la despreocupación. 7. Filtrando los datos enviados por el usuario antes de que estos sean procesados por el servidor, para evitar que se puedan incluir y ejecutar textos que representen nuevas sentencias SQL. 8. Así mismo, es conveniente no utilizar las consultas SQL basadas directamente en cadenas de texto enviadas desde el navegador del usuario, sino que se deberían construir todas las consultas en el servidor con sentencias preparadas y/o procedimientos almacenados parametrizados, que encapsulen los parámetros que deberían evitar los caracteres especiales que hubieran podido ser introducidos dentro de ellos por un usuario malicioso. Es, de hecho, un error de una clase más general de vulnerabilidades que puede ocurrir en cualquier lenguaje de programación o script que esté embebido dentro de otro. 9. Valide siempre los datos especificados por el usuario mediante comprobaciones de tipo, longitud, formato e intervalo. A la hora de implementar medidas de precaución frente a la especificación de datos dañinos, tenga en cuenta la arquitectura y los escenarios de implementación de la aplicación. Recuerde que los programas diseñados para ejecutarse en un entorno seguro pueden copiarse en un entorno no seguro. Las sugerencias que se muestran a continuación deben considerarse prácticas recomendadas: No haga suposiciones sobre el tamaño, tipo o contenido de los datos que recibirá la aplicación. Por ejemplo, debe hacer la siguiente evaluación: Cómo se comportará la aplicación si un usuario (malicioso o no) especifica un archivo MPEG de 10 megabytes cuando la aplicación espera un código postal. Cómo se comportará la aplicación si se incrusta una instrucción DROP TABLE en un campo de texto. Compruebe el tamaño y el tipo de los datos especificados y aplique unos límites adecuados. Esto puede impedir que se produzcan saturaciones deliberadas del búfer. Compruebe el contenido de las variables de cadena y acepte únicamente valores esperados. Rechace las especificaciones que contengan datos binarios, secuencias de escape y caracteres de comentario. Esto puede impedir la inyección de scripts y puede servir de protección frente a explotaciones de saturación del búfer. Cuando trabaje con documentos XML, valide todos los datos con respecto a su esquema a medida que se vayan indicando. No cree nunca instrucciones Transact-SQL directamente a partir de datos indicados por el usuario. Utilice procedimientos almacenados para validar los datos indicados por el usuario. En entornos de varios niveles, todos los datos deben validarse antes de que se admitan en la zona de confianza. Los datos que no superen el proceso de validación deben rechazarse, y debe devolverse un error al nivel anterior. Implemente varias capas de validación. Las precauciones que tome contra usuarios malintencionados ocasionales pueden resultar ineficaces contra piratas informáticos con determinación. Lo más recomendable es validar los datos especificados por el usuario en la interfaz de usuario y, después, en todos los puntos posteriores en que atraviesen un límite de confianza. Por ejemplo, la validación de datos en una aplicación de cliente puede evitar la inyección de scripts. Sin embargo, si en el siguiente nivel se asume que ya se ha validado la entrada, cualquier usuario malintencionado que sea capaz de eludir un cliente puede disfrutar de un acceso sin restricciones a un sistema. No concatene nunca datos especificados por el usuario que no se hayan validado. La concatenación de cadenas es el punto de entrada principal de una inyección de scripts. No acepte las siguientes cadenas en campos a partir de los que puedan construirse nombres de archivo: AUX, CLOCK$, COM1 a COM8, CON, CONFIG$, LPT1 a LPT8, NUL y PRN. Si es posible, rechace los datos que contengan los siguientes caracteres: HERRAMIENTAS http://www.taringa.net/posts/linux/15058932/Miedo-a-una-injeccion-SQL_-_-8-Tool_s-paraenfrentarlas.html SQLiHelper 2.7: SQL Injection http://www.hacktimes.com/sqlihelper_2_7_sql_injection/ Se trata de una aplicación cuyo objetivo es facilitar la extracción de información procedente de bases de datos, utilizando técnicas de inyección de SQL. La última versión, 2.7, cuenta con soporte para motores de bases de datos SQL Server, Mysql y access. Aunque no se trata de una herramienta tan sólida y potente como, por ejemplo, Pangolin, sí que tiene multitud de ventajas sobre todo para bases de datos MySQL Pangolín: Automatización de inyección SQL http://www.hacktimes.com/pangolin_automatizaci_n_de_inyecci_n_sql/ Pangolín es una herramienta gráfica para plataformas win32 programada en C++ destinada a explotar vulnerabilidades del tipo inyección SQL e inyección SQL ciega (Blind SQL) muy fácil de usar y muy rápida. En aquellos motores donde la vulnerabilidad lo permita, la herramienta implementa explotación para conseguir información y datos del servidor, ejecución de shell, acceso al registro, escritura o descarga de ficheros del servidor, navegador de archivos, etc. Las consultas y peticiones a la base de datos pueden efectuarse via Proxy y utilizar métodos de evasión contra firewalls e IDS. SQLMap http://sqlmap.org/ SQLMap es una herramienta para pruebas de acceso, de código abierto que automatiza el proceso de detección y explotación de vulnerabilidades SQL, y control de los servidores de bases de datos. Posee un poderoso motor de detección, características para pruebas de acceso y un amplio rango de interruptores de duración que van desde bases de datos con toma de huellas dactilares, sobre captación de datos, hasta el acceso a archivos del sistema subyacentes y la ejecución de comandos en el sistema operativo vía conexiones fuera de banda. Enema: SQL Injection and Web Attack Framework http://code.google.com/p/enema/ Enema no es un software de auto-hackeo. Es una herramienta dinámica para testers de intrusión profesionales. Versión estable actual: 1.7 MultiInjector – Herramienta Automática de Inyección SQL http://www.dragonjar.org/multiinjector-herramienta-automatica-de-inyeccion-sql.xhtml MultiInjector es una herramienta para realizar automáticamente SqlInjection en un sitio especificado, al ingresarle una url o una serie de estas, automáticamente comprobara si es/son vulnerable/s. Videos de Interés http://www.youtube.com/watch?v=PB7hWlqTSqs&feature=related http://www.youtube.com/watch?v=-uqotuscuQE&feature=related