Saltar al contenido
Red Team

La web por fuera

Lo que una web deja ver sin que entres: copias publicadas, carpetas que se listan, cabeceras que cantan la versión y un id que llega a la base.

35 min de lectura

El encargo de hoy es La Alacena, la tienda online de la despensa a domicilio. Vende a todas horas, así que la ventana se firma de noche —de las 22:00 a la 01:00, cuando hay poco tráfico— y el contrato trae su cláusula subrayada: la tienda no para. Tirar la web o la base dejaría a La Alacena sin vender, y ese es el daño que un auditor no puede causar.

Los temas anteriores miraban puertos y versiones. Hoy el objetivo es una web, y el tema es todo lo que una web deja ver sin que nadie entre: ficheros que no deberían estar publicados, carpetas que se listan solas, cabeceras que cantan de más, un panel de administración que contesta desde fuera y un parámetro que llega hasta la base de datos. Casi nada de esto es «entrar»; es mirar bien lo que ya está a la vista.

Lo que una web cuenta por fuera

Antes de tocar nada, una web se mira por fuera: con qué está hecha. El servidor (nginx, Apache), el lenguaje (PHP, y su versión), el gestor de contenidos, sus módulos. Una herramienta como whatweb hace justo eso: pide la portada y lee lo que la web cuenta de sí misma —en las cabeceras, en el HTML, en las rutas típicas de cada tecnología—. Es de las suaves: no prueba nada, solo lee, así que hace poco ruido.

Lo que whatweb canta —nginx/1.18.0 (Ubuntu), PHP/7.4— no abre nada por sí solo, pero le ahorra el trabajo a quien busque qué fallos tiene justo esa pila. Es un hallazgo de baja gravedad: la recomendación es tener el servidor y el lenguaje al día y quitar de las cabeceras el número de versión (Server, con server_tokens off, y X-Powered-By). Lo que cierra el hueco es la versión al día; quitar el número es un detalle de más. Poner versiones falsas para despistar, o quitar las cabeceras sin actualizar los paquetes, no arregla nada.

El listado de una carpeta

Cuando pides una carpeta (una ruta que acaba en /) y dentro no hay página de inicio, el servidor puede hacer dos cosas: negarse, o listar lo que guarda. Lo segundo —el autoindex— es cómodo para el que monta la web y un regalo para el que la audita: la carpeta enseña todos sus ficheros, con nombre, fecha y tamaño, aunque no haya ni un solo enlace que lleve a ellos.

curl 7.81 (captura)
auditor@pc-auditoria:~$ curl -sS http://198.51.100.18/copias/
<html>
<head><title>Index of /copias/</title></head>
<body>
<h1>Index of /copias/</h1><hr><pre><a href="../">../</a>
<a href="alacena-2026-10-27.sql">alacena-2026-10-27.sql</a>   27-Oct-2026 22:00    18234
<a href="fotos.zip">fotos.zip</a>                 27-Oct-2026 22:00      714
</pre><hr></body>
</html>

Ahí está, sin adivinar nada: una carpeta /copias/ abierta de par en par, y dentro una copia de la base. Es un hallazgo de gravedad alta: el listado no abre nada por sí solo, pero canta justo lo que no debería verse, y con poco más —pedir el fichero que enseña— se llega a los datos. La recomendación es apagar el listado automático (autoindex off): una carpeta sin página no debería enseñar lo que tiene. Poner un index.html vacío en cada carpeta o renombrarla a una que nadie adivine solo lo disimula; se apaga, no se disimula.

Ejercicio

La carpeta de copias se lista entera

Pídele a la web el contenido de la carpeta de copias (http://198.51.100.18/copias/). La carpeta no tiene página, así que el servidor **lista lo que guarda**: ahí canta una copia de la base de la tienda.

Preparando la máquina…

Ficheros que no deberían estar publicados

Esa copia es lo gordo del encargo. Una carpeta pública de la web es un sitio cómodo para dejar una copia de la base de anoche… y servirla a cualquiera que dé con ella. No hay que entrar en ningún sitio: se descarga como una página más.

curl 7.81 (captura)
auditor@pc-auditoria:~$ curl -sS http://198.51.100.18/copias/alacena-2026-10-27.sql
-- Copia de la base de datos de La Alacena
-- marcador de la copia: SQ{copia-expuesta-…}
CREATE TABLE pedidos (id int, ref text, total numeric);
INSERT INTO pedidos VALUES (1, 'pedido-00001', 46.50);

Ese SQ{…} es la flag: el marcador que prueba que llegaste a la copia. Es el hallazgo crítico del encargo —la base entera de la tienda, al alcance de cualquiera—, y la única recomendación que lo cierra es sacar las copias de donde la web las sirve. No vale esconderlas con otro nombre: lo que no debe estar publicado, no se publica.

Ejercicio

La copia de la base, servida sin más

Descárgate la copia que viste en el listado (http://198.51.100.18/copias/alacena-2026-10-27.sql). Es la base de la tienda, servida para cualquiera que dé con la carpeta: dentro está su marcador.

Preparando la máquina…

Cabeceras y páginas por defecto

Dos cosas pequeñas que se ven de paso. La primera, las cabeceras: la línea Server dice la versión exacta del servidor, y X-Powered-By, la del lenguaje. No abren nada, pero cantan la pila —lo mismo que whatweb, por otra vía—.

curl 7.81 (captura)
auditor@pc-auditoria:~$ curl -sS -D - http://198.51.100.18/
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Content-Type: text/html
Content-Length: 75

La segunda, las páginas por defecto: la de «Welcome to nginx!» que trae el servidor recién instalado, un phpinfo olvidado, una carpeta de pruebas. Ninguna abre nada, pero dicen que ahí hubo pruebas y que a esa parte no la mira nadie: un sitio donde buscar lo que se quedó a medias. Es un hallazgo de gravedad baja, y la recomendación es quitar las páginas de ejemplo y las carpetas de pruebas que quedaron publicadas. Cambiarle el texto, taparla con un índice vacío o moverla a otra ruta igual de pública no cuenta: se quita, no se maquilla.

Ejercicio

Lo que cantan las cabeceras

Pídele a la web sus cabeceras (curl -I o curl -D -). La línea «Server» dice el programa y la versión exacta del servidor sin que nadie le pregunte: eso no abre nada, pero ahorra trabajo a quien busque sus fallos.

Preparando la máquina…

El panel de administración, desde fuera

Una tienda tiene su panel de administración: la página desde la que se cambian los pedidos, los productos y las promociones. Esa puerta es para el personal, y lo normal es que solo abra desde la oficina. La pregunta del auditor es sencilla: desde fuera —desde tu portátil, que no está en la oficina—, ¿contesta? Se le piden las cabeceras y la página, como haría un navegador:

curl 7.81 (en la sala del tema, recortada)
auditor@pc-auditoria:~$ curl -sS -D - http://198.51.100.18/admin/
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Content-Type: text/html
Content-Length: 157

<!doctype html>
<title>Administracion - La Alacena</title>
<h1>La Alacena - administracion</h1>
<p>Panel de la tienda: pedidos, productos y promociones.</p>

Un 200 OK con la página de administración, pedido desde Internet: el panel llega desde fuera. Si estuviera bien cerrado, desde tu portátil verías un error —un 403 de «aquí no entras», o un 404 si ya no se sirve hacia fuera—, no el panel. Esa salida, con el 200 y el título, es la evidencia; no hace falta pulsar nada dentro para demostrarlo, y no se pulsa.

Es un hallazgo de gravedad alta: lo que se ve es el menú del panel, no los pedidos, pero es la puerta de servicio de la tienda abierta a cualquiera, y con poco más —una contraseña floja, un fallo del panel— se llega a mandar en ella. La recomendación es dejar el panel solo para la IP de la oficina y la VPN (en nginx, un allow para la oficina y un deny para el resto) y pedir cuenta además. Lo que no vale: confiar en que la contraseña del panel aguante, pedir cuenta pero seguir abierto a Internet, cambiar /admin/ por otra ruta o quitar el enlace de la portada. Un panel abierto a Internet es un panel que cualquiera encuentra: lo que lo cierra es limitar de dónde se entra.

La inyección: cuando el dato llega a la base

El listado de productos de la tienda lleva un parámetro en la URL: /productos?id=1. La pregunta del tema es si lo que se escribe en ese id llega tal cual a la consulta que la web le hace a la base de datos. Si llega sin filtrar, se puede torcer para que la consulta haga otra cosa: eso es una inyección SQL.

Comprobarlo es el trabajo de sqlmap: prueba el parámetro con valores normales y con valores «rotos» y mira si la web responde distinto. Es de las intrusivas —puede escribir en la base y tumbar la aplicación—, así que lleva su cláusula de ventana de mantenimiento y solo lectura, y hace mucho ruido. Su informe, en esta tienda, dice lo justo:

informe de sqlmap (acción abstracta)
auditor@pc-auditoria:~$ # el botón del puesto: «probar si el parámetro id llega a la base»
el parámetro «id» filtra la base: la consulta responde distinto a un valor normal y a uno roto
con eso la base queda al alcance: 4213 registros accesibles en la tabla de pedidos
no se vuelca ningún dato: solo se demuestra que el parámetro llega sin filtrar

Es un hallazgo de gravedad alta: no se ha sacado nada, pero con poco más —torcer la consulta— la base de la tienda queda al alcance. La recomendación es usar consultas con parámetros (que la base trate el id como un dato, no como parte de la consulta) y validar lo que entra.

Cuando la auditoría entra, la flag

Como en el tema anterior: cuando la evidencia es lo que contestó la máquina (una cabecera, un listado, el informe de una herramienta), se pega esa salida tal cual. Cuando la auditoría llega a algo restringido —aquí, la copia de la base—, la evidencia es una flag: un marcador (SQ{…}) que solo está donde solo llega quien dio con ello. Se pega en el tablero y queda demostrado, sin poder falsearlo desde fuera.

Es la misma idea de los CTF y de plataformas como Hack The Box: demostrar el acceso con el gesto justo —leer el marcador— y parar ahí. Lo que haría alguien con malas intenciones después (sacar la base, tocar los pedidos) no es parte del trabajo ni de este juego.

En la sala del tema

Estás en el mismo puesto de la auditoría, de noche: la ventana va de las 22:00 a la 01:00. El alcance es el servidor de la tienda, 198.51.100.18, y de su bloque público 198.51.100.16/29 solo se puede barrer para ver quién vive. Excluido, como siempre, el router del proveedor (198.51.100.17). Y la cláusula de este cliente, bien presente: la tienda no para; nada que la tire, ni la web ni la base.

En el puesto, además de la terminal con curl, tienes un cajón con las dos herramientas del tema: whatweb, para mirar la pila por fuera (suave), y sqlmap, para probar el parámetro id (cara y ruidosa, con su cláusula). Cada hallazgo va al tablero con su evidencia —la salida o la flag—, su gravedad y su recomendación, y al final entregas el informe y te llevas la nota en estrellas.