AVILX

HACKER101 CTF · WEB · 2026

Micro CMS v1

XSS almacenado, IDOR y SQL Injection en un CMS minimalista

PlataformaHacker101 CTF
CategoríaWeb
DificultadEasy
Flags4 / 4
AnalistaJesús Ávila (Avilx)
Fecha07 de Septiembre 2026
Portafolioavilx.dev
4/4 FLAGS WEB · XSS · IDOR · SQLi · HACKER101

Documentación de aprendizaje ofensivo | Entorno de laboratorio autorizado

Contexto

Descripción del objetivo

Micro CMS v1 es un gestor de contenido minimalista expuesto en Hacker101 CTF como reto de nivel Easy. La aplicación permite crear, editar y visualizar páginas con soporte de Markdown y HTML. El objetivo es encontrar 4 flags ocultas explotando vulnerabilidades en la lógica de la aplicación.

Vulnerabilidades presentes

Nota
Las flags en Hacker101 tienen el formato ^FLAG^...hex...$FLAG$. No aparecen como popup externo — están embebidas en el HTML de la página cuando el exploit es correcto. Siempre revisar el source con Ctrl+U.

Reconocimiento de la Aplicación

Superficie de ataque inicial

Al acceder a la aplicación se identificaron las siguientes rutas y funcionalidades disponibles:

Hallazgos del reconocimiento

Hallazgo
La aplicación indica explícitamente “Markdown is supported, but scripts are not”. Al revisar el source del body de “Markdown Test” se encontró la etiqueta <button>Some button</button> renderizándose como HTML real — la app no solo procesa Markdown sino HTML directo en el body. Además, las páginas usan IDs numéricos secuenciales (/page/1, /page/2), lo que sugiere un vector de enumeración.

Vectores identificados

Del reconocimiento inicial se trazaron tres líneas de ataque:

  1. XSS en los campos Title y Body — el filtro es parcial

  2. IDOR — IDs numéricos secuenciales en la URL

  3. SQLi — parámetros numéricos que posiblemente alimentan queries SQL directamente

Flag 0 — IDOR en endpoint de edición

Identificación del vector

Hipótesis
Las páginas usan IDs numéricos secuenciales. Si existen páginas privadas con IDs que no aparecen en el listado público, podrían ser accesibles directamente manipulando el parámetro en la URL.

Se enumeró manualmente incrementando el ID en la URL. Al acceder a /page/6 la app retornó 403 Forbidden — la página existe pero su vista está protegida. Sin embargo, el control de acceso no estaba implementado en el endpoint de edición.

Explotación

Request:

GET /page/edit/6 HTTP/1.1
        Host: [lab-id].ctf.hacker101.com
Hallazgo
El endpoint /page/edit/6 no verifica si el usuario tiene permisos para editar esa página. La app implementa restricción en /page/ID pero olvidó aplicar la misma lógica en /page/edit/ID, exponiendo el contenido completo de páginas marcadas como privadas.
Hallazgo
Payload: GET /page/edit/6

Flag 1 — Stored XSS en body con bypass de filtro

Identificación del vector

Hipótesis
La app dice que scripts no están soportados pero renderiza HTML. Un filtro que solo bloquea <script> puede bypassearse con event handlers que ejecuten JavaScript sin usar esa etiqueta.
Hipótesis
Se probó <script>alert(1)</script> en el body. La app lo filtró y solo mostró el texto alert(1) — el filtro apunta específicamente a la etiqueta <script>.

Explotación

Se utilizó un event handler onerror en una etiqueta de imagen con src inválido para forzar la ejecución de JavaScript:

Hallazgo
Payload: <img src=x onerror=alert(document.cookie)>

La flag no apareció en el popup sino en el source de la página:

Hallazgo
El filtro bloquea <script> pero no sanitiza event handlers en otras etiquetas HTML. Hacker101 inyectó la flag como atributo flag en el elemento img generado. La flag no era visible en la página renderizada — solo en el source con Ctrl+U.

Flag 2 — Stored XSS en title renderizado en home

Identificación del vector

Hipótesis
El campo Title escapa HTML en /page/ID pero si el home lista los títulos sin sanitizar, el XSS se ejecutaría allí en lugar del punto de inserción.
Hipótesis
Se insertó <img src=x onerror=alert(1)> en el Title. Al visitar /page/ID el payload se mostró como texto plano — parecía que el campo no era vulnerable. El vector real no estaba donde se inserta el dato sino donde se consume.

Explotación

Se guardó el payload en el campo Title y al regresar al home el alert se ejecutó automáticamente:

Hallazgo
Payload: <img src=x onerror=alert(1)> en el campo Title
Hallazgo
El campo Title sanitiza correctamente en /page/edit/ID y en /page/ID, pero el home renderiza los títulos sin escapar el HTML. Un payload en el Title se ejecuta cada vez que cualquier usuario visita el home — Stored XSS con mayor impacto que el del body porque afecta a todos los visitantes.

Flag 3 — SQL Injection en parámetro ID

Identificación del vector

Hipótesis
Los IDs numéricos en /page/edit/ID posiblemente alimentan una query SQL sin sanitizar. Una comilla simple podría romper la sintaxis y generar un error visible.
Hipótesis
Se probó /page/1’ — retornó 404 genérico porque ese endpoint valida que el ID sea numérico antes de la consulta. El endpoint /page/edit/ tenía una lógica diferente.

Explotación

Request:

GET /page/edit/1' HTTP/1.1
        Host: [lab-id].ctf.hacker101.com
Hallazgo
El endpoint /page/edit/ no valida ni sanitiza el parámetro ID antes de usarlo en la query SQL. La comilla simple rompió la sintaxis y la app expuso la flag directamente en la respuesta. A diferencia de /page/1’ que retornaba 404, el endpoint de edición pasa el input directo a la base de datos.
Hallazgo
Payload: /page/edit/1’

Impacto

Resumen de severidad

Vulnerabilidad Confidenc. Integridad Disponib. Severidad
IDORAltoAltoNingunoHIGH
Stored XSS (body)AltoMedioNingunoHIGH
Stored XSS (title)AltoAltoNingunoCRITICAL
SQL InjectionAltoAltoAltoCRITICAL

Impacto técnico por vulnerabilidad

Impacto
IDOR: cualquier usuario puede acceder y modificar el contenido de páginas privadas simplemente incrementando el ID en la URL de edición. En un CMS real equivale a acceso no autorizado a información confidencial y capacidad de modificar contenido ajeno.
Impacto
Stored XSS (body): JavaScript malicioso almacenado que se ejecuta en el navegador de cualquier usuario que visite la página infectada. Permite robo de sesiones y ejecución de acciones en nombre de la víctima.
Impacto
Stored XSS (title): de mayor impacto porque el title se renderiza en el home — el payload se ejecuta en el navegador de todos los visitantes sin que accedan a una página específica.
Impacto
SQL Injection: acceso directo a la base de datos. En un escenario real permite extraer toda la información almacenada incluyendo credenciales. Dependiendo del motor puede escalar a ejecución de comandos en el servidor.

Remediación

Reflexión Final

Qué salió bien

Qué salió mal

Lecciones aprendidas

Resumen de flags


Flag 0 IDOR /page/edit/6 sin control de acceso Flag 1 Stored XSS <img onerror> en body Flag 2 Stored XSS <img onerror> en title, ejecuta en home Flag 3 SQL Injection comilla en /page/edit/1’


Tiempo total

Aproximadamente 1 Hora y 35 Minutos incluyendo investigación del mecanismo de flags de Hacker101 y investigacion de las vulnerabilidades.