Inyección de SQL con pase MD5

1

Quiero saber, si en mi formulario de inicio de sesión hay alguna inyección SQL posible. Si existe, ¿cómo podría ser la entrada del formulario web del exploit? Envío nombre de usuario y contraseña por formulario html (POST). El código de la función de inicio de sesión es:


$username = $_POST['user'];
$password = $_POST['pwd'];
$password = md5(password);

$sql = "SELECT id_user, name FROM 'TAB_USER' WHERE user = '$username' AND passwd = '$password' AND enable='Y'";

$result = mysql_query($sql,$dbCon);
$check = mysql_num_rows($result);
mysql_free_result($result);

if ($check ==  '1') {
  $result = mysql_query($sql,$dbCon);
  $array = mysql_fetch_array($result);

  $id = $array['id_user'];
  $name = $array['name'];

  $_SESSION['SES_id_user']= $id;
  $_SESSION['SES_name']= $name;

  return $id;
}
else return false;

    
pregunta stefano 13.09.2013 - 16:59
fuente

4 respuestas

15

Respuesta corta: es muy vulnerable.

¿Por qué? Usted está concatenando los valores dados por POST que provienen directamente de lo que escribió el usuario. Por lo tanto, es muy sencillo manipular su consulta. Además, está utilizando la extensión mysql que está en desuso. Debería usar mysqli o PDO para crear declaraciones preparadas para proteger contra la inyección.

Aquí hay una pregunta de Stackoverflow que explica el asunto. En profundidad y cómo resolverlo.

En una nota al margen, no deberías utilizar MD5 para cifrar las contraseñas, ya que es un algoritmo roto. Considere usar bcrypt o PBKDF2 como se explica aquí .

    
respondido por el Simon 13.09.2013 - 17:11
fuente
10

Usted escribe esto:

$sql = "SELECT id_user, name FROM 'TAB_USER' WHERE user = '$username'
                                                           ^^^^^^^^^
                                                    SQL injection is here

El chico malo enviará como "nombre de usuario" algo que, después del reemplazo, hará que su comando SQL se vea así:

SELECT id_user, name FROM 'TAB_USER' WHERE user = 'Admin'; -- (some stuff here)

es decir, el atacante establecerá el "nombre de usuario" en la cadena: Admin'; --

¿Ver el carácter de comillas ingenioso? Esa es la palanca para el ataque. Dado que su código reemplaza brutalmente a $username en el comando SQL, con "lo que sea que proporcione el cliente", el cliente puede proporcionar un carácter de comillas de cierre, que termina la constante de cadena, luego un punto y coma, que termina el comando, luego un -- que le dice a la base de datos "todo lo demás en la línea es un comentario, simplemente ignórelo". ¡E ignórelo que hace la base de datos!

Esto le permite al atacante iniciar sesión como administrador sin importar la contraseña que usó. Esto es inyección de SQL para libros de texto . Tome nota: puede sentirse tentado a llegar a la conclusión de que los problemas provienen del carácter "comilla", y simplemente filtrarlos sería suficiente para evitar el ataque. Esto no es así. Hay varias (muchas) formas de abusar de un sustituto brutal como el que haces, y es muy difícil atraparlas a todas; como Pokemons, cada nueva versión del software de base de datos SQL introduce nuevas especies. La gente intentó pensar en la inyección de SQL como un problema de "escapar de los problemas de los personajes"; así que diseñaron esta función . Luego, intentaron nuevamente . Y todavía falló. Sólo el dolor te espera en este camino; no lo camines No espere un mysql_really_escape_string_this_time_i_said_please() . En su lugar, use declaraciones preparadas .

    
respondido por el Thomas Pornin 13.09.2013 - 17:42
fuente
4

Solo la entrada del usuario es vulnerable y pwd es seguro.

Ejemplos de su patrón de inyección de SQL de consulta (deben usarse para la entrada del usuario).

'or'1'='1 and enable='Y'--
user'or 1=1--
'or 1=1--

Un atacante no puede inyectar con el parámetro pwd porque es un MD5 hexadecimal, y el patrón de salida MD5 hexadecimal es ([a-fA-F \ d] {32}) y no es controlable para la inyección de consultas.

Además, si la totalidad de sus cookies funciona con SES_id_user y SES_name para verificar el inicio de sesión de los usuarios, ¡su mecanismo no es seguro!

-------

Actualización:

Los atacantes no pueden ejecutar consultas apiladas como DROP y ETC, debido a PHP el método mysql_query no admite múltiples Consultas (apiladas) .

    
respondido por el Sajjad Pourali 13.09.2013 - 17:37
fuente
3

Esto sería vulnerable incluso a ataques automatizados básicos. Una entrada como "'; Drop Table' TAB_USER '; SELECT id_user, nombre FROM' TAB_USER 'WHERE user =' someuser" (exclusivo de las "s) hará que se ejecuten tres comandos desde su script. El primero sería una selección válida , la segunda eliminaría la tabla por completo y la tercera realizaría otra selección (está bien, la tercera consulta fallaría, ya que la tabla ya no está, pero da una idea general).

Debe validar cualquier entrada del usuario antes de ir a una consulta y / o usar SQL parametrizado. Por ejemplo, para un nombre de usuario, realmente debería ser alfanumérico sin puntuación, lo que lo haría seguro contra la inyección. SQL parametrizado es una buena línea de defensa secundaria ya que la declaración SQL entiende que es un valor de usuario y no debe contener comandos.

Como han mencionado otros, el mecanismo de almacenamiento de contraseñas también es muy inseguro, ya que no se ha modificado y es un algoritmo rápido, por lo que existen grandes tablas de arco iris que podrían usarse para buscar un valor de texto sin formato que produzca lo que sea hash está en el DB. Estos se combinan para hacer que sea trivial no solo abusar de su base de datos, sino también para iniciar sesión en otro usuario sin tener que alterar la base de datos (seleccionando el HASH para la sesión y luego descargándolo más tarde y luego buscando la contraseña en un tabla arcoiris existente para MD5.

    
respondido por el AJ Henderson 13.09.2013 - 17:36
fuente

Lea otras preguntas en las etiquetas