Inyección SQL

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 7

INYECCIÓN SQL: MANUAL BÁSICO

Conocimientos previos:
Saber nociones básicas sobre SQL.
Definición de SQL Injection: El SQL Injection es un tipo de ataque a una base de datos en el cual,
por la mala filtración de las variables se puede inyectar un código creado por el atacante al propio
código fuente de la base de datos.
Listado de comandos básicos en SQL:
Grant Utilizado para otorgar privilegios
Revoke Utilizado para eliminar privilegios
Create Utilizado para crear nuevos elementos(tablas, indices…)
Drop Utilizado para eliminar elementos
Alter Utilizado para alterar campos de las tablas
Select Utilizado para consultar registros de una tabla y comprobar que satisfagan una condición
determinada
Insert Utilizado para cargar lotes de datos en la base de datos
Update Utilizado para cambiar valores de registros y campos
Delete Elimina registros de una tabla de la base de datos
Lista de cláusulas básicas en SQL:
From Selecciona la tabla sobre la cual se va a operar (o sobre sus registros)
Where Especifica las condiciones que se deben cumplir los registros que se seleccionan
Group by Utilizado para separar registros en grupos
Having Especifica las condiciones que cumple cada grupo
Order by Ordena registros seleccionados
Instalación del programa
El programa viene configurado y preparado para funcionar sin ningún tipo de instalación previa.
Sólo se debe copiar todo el programa (ejecutable y asociado) y la base de datos en la misma carpeta,
sea cual sea, manteniendo el nombre de la base de datos intacto.
Ejecutar insertarHorariosTrabajadores.exe y se verá el programa de inicio.
Descargar programa Inyección SQL
Introducción
Antes de nada aclarar la razón de por qué estos ataques son tan peligrosos: pueden no solo sacar
información de la base de datos (usuarios, contraseñas, etc.), sino también pueden borrar la base de
datos, dejarla inservible o aplicarse a ataques DDOS entre otros.
Introducción al método error y comprobación de la vulnerabilidad del servidor
Previo paso al comienzo del manual, que quede claro que esta información es puramente informativa
y va enfocada al conocimiento y preparación del desarrollador para evitar errores, nunca a la
realización de prácticas ilegales.
Bien, empecemos a analizar la vulnerabilidad de nuestro objetivo, en cuanto a ataques SQL.
Base de datos para probar SQL Injection:
http://www.redeszone.net/app/uploads/cdn/down/soft/seginf/sql_inyeccion/inyeccion%20sql.rar
Comencemos: lo primero que necesitamos es buscar algún indicio de que la web o el programa son
vulnerable. Enfoquemos este apartado a sitios web.
SQL Injection a páginas web.
Imaginad que estáis diseñando una página web, es muy bonita, al cliente le gusta, se pone en marcha
y a los 5 minutos es hackeada por algún indeseable que ha borrado la base de datos, sería un
desastre. Es de recibo que, actualmente, los diseñadores de páginas deben tener en mente un poco de
seguridad informática para que su página no resulte vulnerable, al menos en los casos típicos. Es lo
que se pretende con este manual: que el diseñador tenga nociones de seguridad típicas.
Veamos primero si la web en cuestión tiene este tipo de sentencias en su url: “celebraciones.asp?
ID=”, “libros.php?view=”, o cualquier otro tipo parecido. En muchas ocasiones, introduciendo ahí
nuestro código inyectado empieza el ataque, pero esto lo explicaremos más adelante.
Nota1: no siempre que tenga este tipo de sentencias es vulnerable
Nota2: si ves ASP, ASPX, etc., piensa en que en un elevado tanto por ciento de los casos, la base de
datos será SQL.
Nota3: Para comenzar el ataque, también podemos buscar formularios ligados a una consulta a una
base de datos SQL.
Si, con SQL Injection podemos “saltarnos” algunos logueos pero el SQL Injection es mucho más,
como se explicó al comienzo: podemos borrar una base de datos, cambiarle el nombre a las tablas o
hacer mil maldades. Imaginad por ejemplo una página de venta de teléfonos móviles, podemos hacer
que la persona que se nos ocurra de la BD compre 1000 teléfonos, por ejemplo.
2. Ataque blind SQL Injection.
El BLIND SQL Injection se considera un ataque a ciegas, es decir, sin conocer nada sobre el server
(Versión de SQL, nombre de las tablas, numero de tablas, etc., que deberemos saber para concluir el
ataque y para saber defendernos.)
2.1-. Sacando el número de columnas de la BD
Bien para sacar el número de columnas de la base de datos (BD, DB), vamos a inyectar un código
que cause un conflicto al llegar a un numero de columna, el cual no se encuentra en la base de datos.
Bien para esto vamos a utilizar la cláusula order by. Este tipo de ataque se basa en ordenar columnas
hasta llegar a la última. Así al poner la siguiente, al no existir, nos devolverá un error tipo:
Unknown column ‘numerodecolumna’ in ‘order clause’
El error puede sufrir variaciones pero lo que nos interesa es que nos devuelva el unknown column y
el número que es lo que nos indica que columna es la que no está definida (no existe).
Este no es el único método para sacar el número de columnas (si el que me parece más fácil), pero
hay varios si no les funciona con unos, estudien un poco de SQL y piensen como hacerlo es simple
fíjense de este método y sabrán cómo sacar errores con otras cláusulas.
Pongo un ejemplo sencillo, para que se vea una parábola de lo anteriormente dicho.
2.2.- Sacando el nombre de la tabla.
Imaginad una web con este tipo de enlace:
http://www.soyunaweb.com/soyunapagina.extension?id_pregunta=2
Es muy común encontrar este tipo de enlaces en casi cualquier web y también es muy común pensar
que detrás de este enlace, existe una sentencia SQL que determina que mostraremos o el contenido
de dicha página, por ejemplo.
El formato de la sentencia SQL que podría estar detrás de ese enlace sería algo parecido a esto:
“SELECT * FROM pregunta WHERE id_pregunta=” + parámetro
Viendo el enlace, es lógico presuponer que la tabla se llame pregunta y el campo id_pregunta. Este
podría ser un fallo de seguridad. Al diseñar Webs con ese tipo de enlaces, debemos intentar
asegurarnos de que el nombre del parámetro no sea tan explicativo. Simplemente con haber puesto
id_p se soluciona el problema, por ejemplo, acabándose así nuestro ataque de Blind SQL Injection.
(Salvo utilizar la fuerza bruta, por supuesto).
Hemos pensado que la sentencia SQL podría ser válida, pero no sabemos a ciencia si lo es,
tendremos que comprobarlo (podría ser también un simple código escrito dentro de la página).
Para comprobarlo, podemos hacer lo siguiente, poner una condición que nos devuelva siempre
cierto, a ver si lo que evalúa la condición es un pedazo de código o una sentencia SQL. Se nos ocurre
probar con algo como esta sentencia:
SELECT * FROM pregunta WHERE id_pregunta=2 AND 1=1
Que traducido a un enlace:
http://www.soyunaweb.com/ soyunapagina.extension?id_pregunta=2 and 1=1
Si por defecto aparece la página de la pregunta 2, bingo, hemos acertado, es una sentencia SQL. (En
realidad podría ser un switch por ejemplo, pero supondremos que se trata de una sentencia SQL sin
más preámbulos).
A partir de aquí, tendríamos que demorarnos en conseguir más información (nombre de las tablas,
por ejemplo). Yo aconsejo atacar a los servidores más comunes, Access o SQL Server, por ejemplo,
con sus tablas de sistema. Lo que nos indica otro fallo importante de seguridad: al diseñar, debemos
prohibir la lectura a este tipo de tablas. Al intentar atacar, el atacante verá que o bien no existen o
bien no tiene permiso para leerlas y esa vía queda descartada.
Inyección SQL en aplicaciones de Escritorio.
Imaginemos el siguiente escenario: tenemos una red local, con una aplicación que accede a
diferentes sitios de una intranet o de archivos de configuración de un servidor o cualquier otra tarea
que se requiera.
Supongamos que detrás de esa aplicación hay una base de datos de Access, que controla todo el
proceso de la identificación del usuario sirviendo de apoyo a una aplicación construida con Visual
Studio 2008, en Visual Basic.
Este será nuestro escenario de ataque. Para este manual se ha construido un programa de ejemplo
con un acceso por usuario y contraseña que constituye nuestra herramienta para el aprendizaje. La
base de datos sobre la que se sustenta la aplicación está creada en Access XP, una herramienta
común en el mundo de las Pymes.
La inyección de SQL de una Web con un servidor SQL Server es ligeramente distinta a la de un
programa de escritorio con base de datos Access, pero, en esencia, no difiere demasiado.
El carácter que permite inyectar SQL es la comilla simple. Este carácter es interpretado por SQL
como el inicio de una instrucción y podemos concatenar nuestras instrucciones si lo hacemos con
habilidad.
Imaginad que somos un usuario malicioso que ha quedado muy descontento con el gerente de la
empresa TodoAdsl porque no le ha dado un día de asuntos propios para ver el Madrid-Barça (por
ejemplo). En el trabajo, tenemos un programa que funciona para insertar el Horario de los
Trabajadores, las tareas que han realizado al cabo del día y en qué franja del día. Se nos ocurre, que,
si podemos saltarnos la contraseña, podemos hacer grandes destrozos en la empresa.
Vamos a trabajar, encendemos el ordenador y arrancamos el programa.
Tenemos esto:
Un simple formulario de entrada con un usuario y una contraseña, con la imagen de la persona
elegida en el combobox de nombre de usuario a la derecha. (Se ha dejado el control pero se han
omitido las imágenes, para que la BD no pese más de lo necesario para el manual).
Lo primero que se nos ocurre es poner un usuario y una contraseña al azar para saber que ocurre.
Ponemos de contraseña la palabra “contraseña” y como usuario el que aparece en la imagen:

Al pulsar sobre el botón “Entrar”, aparece una ventana que se ha creado específicamente para que
veáis la sentencia SQL que el programa tiene detrás para controlar el acceso.
Obviamente, esta ventana no se muestra en ningún programa que precise de usuario y contraseña,
sería un error de seguridad imperdonable, se muestra aquí para facilitar la comprensión del manual.
Como podéis ver, la sentencia SQL es muy sencilla.
Tenemos una tabla “TRABAJADOR”, un campo “clave personal” que sería el campo donde se
almacena la clave y un campo “TRABAJADOR” que sería el usuario. En este caso, el nombre de la
tabla y el nombre del campo coinciden, pero no es lo habitual.
Lo primero que debemos probar es a poner entradas extrañas, como el usuario vacío o la contraseña
vacía, a ver qué ocurre. Probamos y nos sale la siguiente ventana:

En este caso, hemos errado: el programador ha sido lo suficientemente inteligente como para capar
esos casos extraños y no dejar posibilidad al error.
La siguiente treta será intentar la Inyección de SQL. (Ya era hora).
Ahora necesitamos saber cómo inyectar SQL en una base de datos Access. Los motores de SQL
tienen un carácter de escape que sirve para delimitar qué es sentencia SQL de qué no lo es.
En este caso, tenemos ya que la sentencia SQL que realiza la consulta el del tipo:
“SELECT * FROM TRABAJADOR WHERE [clave personal]='” & pass & “‘AND
TRABAJADOR='” & usuario & “‘”
Ahora hemos de pararnos a pensar durante un minuto. ¿Cómo podemos insertar código SQL en la
sentencia de forma que podamos burlar el logueo?
Podemos probar con lo más sencillo que se nos ocurre: introducir una condición lógica que siempre
sea verdadera. O sea: ‘1=1
Probamos esa sentencia en la contraseña, con cualquier usuario de la base de datos y tenemos esto:

De nuevo, nuestra suposición era equivocada, no puede ser algo tan simple como eso, pero nos ha
dejado una idea de cómo sacar la sentencia SQL en un caso normal (en el caso que nos ocupa, el
programa, muy amablemente, se encarga de hacerlo por nosotros, pero repetimos que eso no sucede
nunca.
Si podemos introducir valores que den como resultado una sentencia SQL equivocada, entonces
podríamos saber la consulta que se realiza. ¿Cuál ha sido el error del programador en este caso?
Simplemente, no filtrar la entrada. Si tan sólo hubiera aplicado un filtro para no permitir caracteres
extraños, el error nunca sucedería, y el malintencionado usuario (nosotros en este caso) se queda con
un palmo de narices.
No desesperemos. Probemos con otra cosa. La sentencia SQL que ejecuta la consulta es de este
modo:
SELECT * FROM TRABAJADOR WHERE [clave personal]='” & pass & “‘AND
TRABAJADOR='” & usuario & “‘”
¿Y si probamos a introducir una sentencia lógica siempre a cierto en el campo trabajador?
Probamos con esto:
Pepe ‘OR ‘a’=’a en el campo trabajador y esto otro, contraseña en el campo contraseña.
Esperanzados vamos a pulsar el botón de entrar y nos muestra esta ventana:

Observamos la consulta y ya vemos que no funcionará: el programador ha filtrado los contenidos del
campo usuario para permitir tan sólo los usuarios que el programador eligió en el combobox.
Pulsamos Aceptar y nos encontramos con la ventana siguiente:

De nuevo hemos fracasado. Nos ponemos a pensar y se nos ocurre otra estrategia: probar a
introducir una sentencia lógica que de cierto sólo con que uno de los valores sea cierto.
Sería algo así:
SELECT * FROM TRABAJADOR WHERE [clave personal]= ‘loqueseteocurra’ OR ‘a’=’a’ AND
TRABAJADOR='” & usuario & “‘”
¿Qué realiza esta sentencia? Compara el valor de la clave con Or a=a y realiza un AND con el
trabajador. ¿Qué va a ocurrir? ¡Pues que OR a=a siempre devuelve cierto, sea cual sea el valor de la
contraseña puesta!, realizando un AND con el trabajador (que en este caso sirve cualquiera que
pongamos y que el programador haya permitido).
Nos vamos al programa y ponemos las siguientes valores:
En contraseña: loqueseteocurra’ OR ‘a’=’a
En usuario: cualquiera que el combobox tenga almacenado.
Pulsamos en entrar y tenemos esto como salida:

Bingo. Hemos dado con la sentencia correcta, el programa nos ha permitido insertarla y ahora, con
todo el placer de nuestras malévolas mentes pulsamos en aceptar. Efectivamente, nos muestra la
ventana de insertar el horario del trabajador. Hemos logrado ingresar con un usuario cualquiera sin
conocer la contraseña.
Y ya estaríamos dentro del programa, podríamos hacer lo que nos apeteciera con ese usuario, desde
insertar horarios falsos, a números de expedientes falsos, etc., etc.
El programa ya no realizará más acciones, los botones insertar y sacar horario no hacen nada.
Conclusiones
Se puede abstraer lo visto en el manual para intentar otro tipo de sentencias que provoquen un daño
irreparable a la base de datos. Por ejemplo, podríamos intentar realizar un drop table y borrar una
tabla o eliminar la base de datos. Como se explicó antes, este tipo de problemas son muy peligrosos
y vale más prevenirlos cuanto antes.
Lo más sensato que debemos tener en cuenta al prevenir estos ataques es filtrar el carácter ‘(comilla
simple), si hablamos a nivel de web, hacerlo siempre en cliente y servidor, si hablamos en un
entorno de red local, filtrar la entrada del campo en el programa.
A nivel de web, si sólo se filtra en el cliente, es fácil saltarse la validación y provocar un fallo del
estilo de los que hemos visto, para extraer información, de ahí la necesidad de hacerlo en el cliente.
Para seguir avanzando en el tema os recomiendo la lectura de dos documentos que son de obligada
lectura para el que esté aprendiendo SQL Injection:
Inyección de SQL
http://www.redeszone.net/content/uploads/Tecnicas-de-SQL-Injection.pdf
Inyección de SQL avanzada:
http://www.redeszone.net/content/uploads/advanced_sql_injection.pdf
Manual realizado por Ethiel para REDESZone.net
Publicado por David García Martín el 06 octubre 2010, actualizado el 22 septiembre 2014

También podría gustarte