viernes, 27 de abril de 2012

Introducción al Sql Injection en MySql

Después de leer este comentario "Eso con MySql no pasaría. Esas cosas solo le pasan al Sql Server porque es de Microsoft..." en mi artículo sobre Introducción al Sql Injection en Sql Server no me he quedado más remedio que realizar el mismo experimento pero esta vez sobre MySql. Voy a dejar fuera del artículo como instalar las cosas que se necesitan para probar el código pero básicamente son
También nos lo podemos bajar todo junto de aquí.

Bien, con todo montado y funcionando lo primero que haremos será crear una tabla User similar a la anterior e insertar un registro. Podemos hacerlo usando las siguientes sentencias SQL
CREATE  TABLE `test`.`User` (
  `IdUser` INT NOT NULL AUTO_INCREMENT ,
  `Username` VARCHAR(50) NOT NULL ,
  `Password` VARCHAR(200) NOT NULL ,
  `Name` VARCHAR(50) NOT NULL ,
  PRIMARY KEY (`IdUser`) ,
  UNIQUE INDEX `IX_Username` (`Username` ASC) );

INSERT INTO `test`.`User` (`Username`, `Password`, `Name`) VALUES ('admin', 'admin', 'Administrador');
Y montaremos una aplicación con el mismo aspecto que la que usamos en el anterior artículo.


Tras esto pondremos este código en el manejador del evento Click del botón
try
{
 string connectionString = ConfigurationManager.ConnectionStrings["Foo"].ConnectionString;
 using (MySqlConnection connection = new MySqlConnection(connectionString))
 {
  connection.Open();
  string cmdText = "SELECT * FROM User WHERE Username='" + textUsername.Text + "' AND Password='" + textPassword.Text + "'";
  MySqlCommand command = new MySqlCommand(cmdText, connection);
  MySqlDataReader dataReader = command.ExecuteReader();
  if (dataReader.HasRows)
  {
   dataReader.Read();
   string name = dataReader["Name"].ToString();
   labelStatus.Text = "Bienvenido al sistema " + name;
  }
  else
   labelStatus.Text = "Nombre de usuario o contraseña incorrectos";
 }
}
catch (Exception ex)
{
 labelStatus.Text = ex.Message;
}
Bien, ahora es el momento de hacer las mismas pruebas que hicimos con el Sql Server.
Si ponemos el usuario y la contraseña de manera correcta


Y si la ponemos de manera incorrecta


Ahora toca hacer el Sql Injection, pero como no uso normalmente MySql no me queda más remedio que buscar como comentar una linea a partir de un carácter (o caracteres). La solución está aquí y es usando el carácter #. Con esto usaremos ' OR 1=1 #  como nombre de usuario y el resultado es el siguiente


Como vemos, hemos accedido al sistema simplemente conociendo un nombre de usuario, al igual que ocurría con el Sql Server. Para corregir este fallo de seguridad usaremos parámetros tal y como hicimos en el anterior artículo
try
{
    string connectionString = ConfigurationManager.ConnectionStrings["Foo"].ConnectionString;
    using (MySqlConnection connection = new MySqlConnection(connectionString))
    {
        connection.Open();
        string cmdText = "SELECT * FROM User WHERE Username=?Username AND Password=?Password";
        MySqlCommand command = new MySqlCommand(cmdText, connection);
        command.Parameters.Add(new MySqlParameter("?Username", textUsername.Text));
        command.Parameters.Add(new MySqlParameter("?Password", textPassword.Text));
        MySqlDataReader dataReader = command.ExecuteReader();
        if (dataReader.HasRows)
        {
            dataReader.Read();
            string name = dataReader["Name"].ToString();
            labelStatus.Text = "Bienvenido al sistema " + name;
        }
        else
            labelStatus.Text = "Nombre de usuario o contraseña incorrectos";
    }
}
catch (Exception ex)
{
    labelStatus.Text = ex.Message;
}
En este caso si usáramos el mismo nombre de usuario obtendríamos el siguiente resultado


Como vemos del Sql Injection no se escapa "casi nadie" sobre todo si somos nosotros mismos los que hacemos las cosas mal y no validamos la información introducida por el usuario.

No hay comentarios:

Publicar un comentario