lunes, 27 de febrero de 2012

Técnicas de ataque - SQL Injection (Inyección SQL)

Aunque se trata de un tema, bastante antiguo, y que no será facil de reproducir, aunque seguro que quedan sitios, que son vulnerables a este tipo de cosas. SQL Injection es una técnica de ataque a paginas, que intentan colar codigo SQL, dentro de codigo SQL de la aplcación destino, para romper o acceder a información. Con esto se quiere decir, que por ejemplo, si suponemos que una pagina web, tiene en su pagina de login, dos campos, usuario y contraseña, muy habitual, y para buscarlo hace lo siguiente:

SELECT * FROM Users WHERE Username='usuario' AND Password='contraseña'

Si hicieramos que tanto el usuario, como la contraseña valieran 1' OR '1'='1'

La sentencia quedaría de la siguiente manera:

SELECT * FROM Users WHERE Username='1' OR '1' = '1'  AND Password='1' OR '1' = '1'

Lo que técnicamente devolvería una lista con todos los usuarios, y podría en algunos casos, concedernos acceso a la página en cuestión. Curioso cuanto menos.

Si queremos ser un poco más destructivos, y conocemos el nombre de una tabla, o podemos intuir el nombre, se puede hacer algo como esto, a través de SQL Injection.

Si por ejemplo, se le da el valor al password de: x'; DROP TABLE users; -- y al usuario, por ejemplo 1 (este valor es indiferente para este caso)

el resutaldo sería, cogiendo la SQL arriba citada, el siguiente:

SELECT * FROM Users WHERE Username='1' OR '1' = '1' AND Password='x'; DROP TABLE users; --'

El -- final, es importante, porque se trata de dejar en comentario, el final de la SQL, paa que no falle, la comilla, que nos habran puesto, para parametrizar la String SQL de la contraseñá, en este caso el resultado, es que si la SQL se está ejecutando con permisos de borrado, y la tabla USERS existe, no exisitirá más.

Una vez explicado, como es SQL Injection, haciendo el mal, un par de ideas, para evitarlo, sin que sean muy complicadas de implementar.

Si por ejemplo, en vez de almancenar las contraseñas de los usuarios, lo que se almancena es un HASH de las contraseñas, como pueden ser SHA1 o MD5, entonces, al comparar las contraseñas, lo que se enviará a SQL para comprar no será el texto escrito por el usuario, sino el HASH que se genera, lo que en ningún caso será una SQL Injection.

Por otro lado, otra opción de baja tecnología, para solucionar este problema, quizá mucho menos fiable, pero si mucho más sencilla, es prohibir ciertos caracteres reservados de SQL en los textos, como pueden ser, las comillas simples, el OR, el AND, lo que viene a ser una lista negra de textos prohibidos, para que no ataquen al sistema.

Curiosidad final, si pusieramos este valor a la contraseña,

1; update users set password = 'password'; select *

Esto haría que las contraseñas de todos los usuarios, pasasen a valer "password" lo que tiene gracia, al menos si no le pasa a tu aplicación.

No hay comentarios:

Publicar un comentario