Banner de MySQL & PHP Blue Team

Análisis Forense Informático, Ciberseguridad, Formación

MySQL & PHP Blue Team

3 Mar , 2022  

Cómo bastionar un sitio web en PHP y MySQL frente a inyecciones SQL.

Cuando publicamos un sitio web en internet dinámico con PHP y MySQL estamos abriendo la puerta a que cualquier persona del mundo pueda ver la información que presentamos, pero también nos exponemos a todo tipo de ataques del exterior. Hoy vamos a ver cómo protegernos de la tercera vulnerabilidad más atacada del mundo según OWASP 2021: las inyecciones de código, en concreto, de SQL.

El Blue Team

En este caso práctico nos situamos en el equipo de seguridad encargado de defender el servidor de los atacantes, el denominado Blue Team.

Las principales funciones del blue team son realizar evaluaciones de las distintas amenazas que puedan afectar a las organizaciones, monitorizar la red, los sistemas, etc. y recomendar planes de actuación para mitigar los riesgos.

Qué es una inyección de SQL

La inyección SQL es un tipo de ataque encubierto en el cual un hacker inserta código propio que se ejecutará en la base de datos del servidor web, pudiendo conseguir información sensible de la base de datos o incluso llegando a borrar contenidos de la misma.

Si un desarrollador web no es meticuloso, al crear un sitio podría dejar un resquicio que alguien con malas intenciones podría usar para provocar efectos inesperados en su base de datos. Las inyecciones de SQL (o SQLI) se producen cuando el hacker introduce o inyecta en el sitio web código SQL malicioso, un tipo de malware que se conoce como la carga útil, y consigue subrepticiamente que envíe ese código a su base de datos como si de una consulta legítima se tratara.

Caso práctico – Entorno

Entorno Debian 11 del caso práctico
Captura de la configuración en VirtualBox de la máquina en la que se desarrolla el caso práctico

Para esta práctica se ha utilizado como entorno una máquina virtual Debian 11 con un Stack LEMP sobre el que realizaremos una instalación de una versión antigua de PHP, 5.6, para ser inicialmente vulnerables a las inyecciones de código SQL.

Después veremos cómo bastionar nuestro código para evitar este tipo de ataques.

PHP 5.6

Aunque la última versión disponible de PHP en la fecha de realización de esta entrada es 8.1, para este caso práctico utilizaremos la descontinuada versión 5.6 ya que es la última que contiene las funciones de PHP que utilizaremos para crear un sitio web vulnerable a inyecciones SQL, como por ejemplo mysql_connect para establecer la conexión con nuestra base de datos.

El ataque por inyección SQL POST

Cuando hemos desplegado nuestros sitios web en PHP y MySQL, como vemos en el video, éstos son vulnerables a los ataques por inyección SQL. Veamos por ejemplo cómo atacar el formulario de acceso POST con una simple instrucción que introduciremos en el campo de nombre de usuario:

' OR 1=1 -- -

Para entender por qué esto funciona analizaremos el código PHP del formulario de recepción, viendo el extracto de las líneas de código que hacen que la inyección funcione:

$username = $_POST['username'];
$passwd = $_POST['passwd'];

$result = mysql_query("SELECT nombre,apellidos,password 
                       FROM usuarios 
                       WHERE nombre='" . $username . "' and password='" . $passwd . "';");

Como podemos ver, se está concatenando directamente el valor recibido en los campos del formulario en la sentencia SQL que se va a ejecutar. El problema viene cuando alguien escribe en el formulario el cierre de la condición y añade otra, provocando que el código SQL que realmente se ejecute en MySQL sea el siguiente:

SELECT nombre,apellidos,password
FROM usuarios
WHERE NOMBRE='' OR 1=1 -- -

Como vemos, la condición 1=1 siempre se cumple, por lo que automáticamente ganaremos acceso al sitio web.

El ataque por inyección SQL GET

En el caso de la página web de tipo GET, lo que está recreando aquí nuestro PHP es una página en la que se muestran contenidos buscados por el identificador que los almacena en MySQL, como puede ser una página de información de usuarios. En este caso vamos a utilizar una inyección SQL que hace uso de UNION para combinar los resultados y no obtener la información de un solo usuario, si no de todos a la vez:

-1 UNION SELECT GROUP_CONCAT(idusuario),
                GROUP_CONCAT(nombre),
                GROUP_CONCAT(apellidos),
                GROUP_CONCAT(password) 
                FROM% usuarios #

Nuevamente, vamos a observar el código PHP para entender qué está ocurriendo aquí y por qué nuestra inyección tiene éxito sobre MySQL:

$id = $_GET['id'];

$result = mysql_query("Select * from usuarios where idusuario=" . $id . ";");

Al igual que ocurría en la web con POST, nuestra sentencia SQL está concatenando directamente el valor de la variable recogida en la URL, por lo que la inyección tiene éxito. En este caso empiezamos con un valor negativo para que la primera parte de la sentencia SQL no devuelva ningún resultado y así el resultado renderizado por PHP sea el de nuestro UNION.

MySQL & PHP Blue Team en vídeo

Conclusiones finales

Como hemos visto en el vídeo, siendo conscientes de las amenazas de nuestro entorno y cuidadosos a la hora de desarrollar podemos protegernos fácilmente frente a amenazas como las inyecciones SQL.

Es crucial tratar de mantener nuestro software actualizado para evitar en gran medida las amenazas: si actualizáramos nuestra instalación de PHP 5.6 a una versión actual dejaríamos de ser vulnerables a las inyecciones SQL porque el propio motor de PHP ha eliminado las funciones que podían explotar estas vulnerabilidades.

Contenido adicional

Puesta en Producción Segura

, , , , , ,

By  -        
Soy un Full Stack Developer que vive en Valladolid. Actualmente trabajo en la empresa Ilunion Tecnología y Accesibilidad. Soy un apasionado de la informática, la tecnología, aficionado a la fotografía y enamorado del diseño eficiente.



Deja un comentario