Si enumeramos las vulnerabilidades en aplicaciones web que mayor impacto han tenido debido al grado de gravedad que pueden ocasionar, sin duda alguna nos encontraremos con la SQL Injection. Esta vulnerabilidad puede llegar a permitir al atacante desde listar contenido de la base de datos hasta obtener acceso completo al servidor, veamos en que consite.
El término injection, se refiere a injectar o anexar sentencias SQL en una consulta que la aplicación ejecuta a la base de datos, esto se lleva a cabo aprovechando cualquier entrada de datos que la aplicación solicite directa o indirectamente desde el usuario, directamente nos referimos por ejemplo a campos de formularios donde el usuario ingresa ciertos datos, indirectamente podrían ser parámetros que son pasados por via URL (GET). El objetivo de injectar sentencias SQL en la consulta es modificar a conveniencia la lógica de dicha consulta o bien el resultado que sera devuelto por la base de datos.
Este es un típico formulario donde se pide un nombre de usuario y una contraseña para acceder a una zona privada. El código del lado del servidor que forma la consulta seria algo como lo siguiente:
$username = $_POST['username']; $password = $_POST['password']; $sql = " SELECT * FROM usuarios WHERE username = '$username' AND password = '$password' ";Como vemos, primeramente se almacenan el nombre de usuario y contraseña ingresadas en las variables username y password respectivamente, seguidamente se incluyen estos valores en la consulta que sera enviada a la base de datos para comprobar si existe dicho usuario. Supongamos que en nuestro ejemplo el usuario ingresa como nombre de usuario admin y contraseña pass123, al enviarse el formulario, la consulta formada sera la siguiente:
SELECT * FROM usuarios WHERE username = 'admin' AND password = 'pass123'Como vemos, al colocarse los datos de entrada, estos quedan entre las comillas simples para representar que se trata de una cadena de texto. Esta consulta sera enviada a la base de datos y devolverá un resultado con los datos de dicho usuario, si existe, y se permitirá el acceso a la zona privada, de lo contrario devolverá un resultado vacio y se denegara el acceso.
Como mencionamos anteriormente, SQL injection consiste en anexar código SQL a una consulta, y este formulario lo permite mediante los campos de entrada, de forma que tenemos una aplicación vulnerable a SQL injection.
El objetivo de explotar esta vulnerabilidad es conseguir acceso a la zona privada sin conocer ni el ususario ni contraseña correcto, y aprovechar la vulnerabilidad. De forma que lo que tenemos que lograr es injectar código SQL para formar una consulta que retorne un resultado valido .
Veamos como queda formada la consulta si injectamos el siguiente código SQL en el campo contraseña:
Al formarse la consulta, quedará de la siguiente manera:
SELECT * FROM usuarios WHERE username = 'hacker' AND password = '' or 1=1#'Hay que prestar importante atención en que el código insertado se encuentra entre las comillas simples que encierran el password, la comilla simple al inicio del código inserado se encarga de completar la comilla abierta en la parte de la consulta password = ' , de esta forma obtenemos temporalmente la siguiente consulta:
SELECT * FROM usuarios WHERE username = 'hacker' AND password = ''Esta consulta de momento no devolverá resultados pues no existe tal usuario con esas credenciales, sin embargo analicemos el resto del código insertado:
or 1=1#La sentencia or 1=1 cambia radicalmente la lógica de la consulta, ya que como sabemos en una consulta formada por el condicional OR devolvera verdadero al cumplirse al menos una de las dos expresiones, en nuestro caso la primera expresión es username = 'hacker' AND password = '' , y la segunda or 1=1 , esta última se cumple siempre, es decir 1 es siempre igual a 1, por que la consulta nos devolverá un resultado valido.
Por ultimo nos queda deshacernos de la comilla que cierra la sentencia, para esto podemos usar los comentarios utilizados en SQL: # , -- (doble guion), o bien /* */ . de esta forma la consulta completa es:
SELECT * FROM usuarios WHERE username = 'hacker' AND password = '' or 1=1#'Todo despues del # sera tomado en cuenta como comentario y no formara parte de la consulta.
Para conseguir obtener un resultado valido existen muchas otras variaciones en el código que podemos insertar, por ejemplo:
gracias por este tutorial, es perfecto y útil.
saludos.