← Volver al listado de tecnologías
Capítulo 3: Captura y Análisis de Tráfico HTTP/HTTPS
Capítulo 3: Captura y Análisis de Tráfico HTTP/HTTPS
En este capítulo aprenderás las técnicas fundamentales para interceptar, analizar y modificar el tráfico HTTP/HTTPS en tiempo real, una habilidad esencial para la auditoría de seguridad.
🎯 Objetivos del Capítulo
Al finalizar este capítulo serás capaz de:
- ✅ Interceptar peticiones y respuestas HTTP/HTTPS
- ✅ Modificar requests y responses en tiempo real
- ✅ Analizar headers, cookies y parámetros
- ✅ Decodificar y manipular payloads
- ✅ Identificar patrones de comunicación
- ✅ Detectar información sensible en el tráfico
🚦 Modos de Interceptación
Break Points (Puntos de Interrupción)
ZAP ofrece varios modos para interceptar tráfico:
# Modos de Break Points:
1. Break on all requests - Detener todas las peticiones
2. Break on all responses - Detener todas las respuestas
3. Break on specific URLs - Detener URLs específicas
4. Step through - Avanzar paso a paso
5. Continue - Continuar sin interrupción
Configuración de Break Points
// Activar Break Points
// Botón verde en la barra de herramientas o:
// Break → Break on all requests
// Configuración específica por URL
// Break → Add custom break point
URL Pattern: https://api.ejemplo.com/users/*
Method: POST
Break on: Request & Response
🔍 Interceptación de Peticiones
Interceptar Request Básico
# Ejemplo de request interceptado
GET /api/v1/users/profile HTTP/1.1
Host: api.ejemplo.com
User-Agent: Mozilla/5.0 (Android 11; Mobile)
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Accept: application/json
X-API-Key: abc123xyz789
Cookie: session_id=a1b2c3d4e5f6; user_pref=dark_mode
# Modificaciones posibles:
- Cambiar método (GET → POST)
- Modificar headers
- Alterar parámetros
- Inyectar payloads
Modificación de Peticiones
// Ejemplos de modificaciones comunes
interface RequestModifications {
// 1. Bypass de validación cliente
changeUserRole(): void {
// Original: {"role": "user"}
// Modificado: {"role": "admin"}
}
// 2. Manipulación de precios
modifyPrice(): void {
// Original: {"price": 100.00}
// Modificado: {"price": 0.01}
}
// 3. IDOR (Insecure Direct Object Reference)
accessOtherUser(): void {
// Original: /api/users/123
// Modificado: /api/users/456
}
// 4. SQL Injection testing
injectSQL(): void {
// Original: ?id=1
// Modificado: ?id=1' OR '1'='1
}
}
Manipulación de Headers
# Headers de seguridad importantes
Authorization: Bearer [TOKEN] → Bearer [MODIFIED_TOKEN]
X-Forwarded-For: 127.0.0.1 → X-Forwarded-For: 192.168.1.100
Origin: https://trusted.com → Origin: https://evil.com
Referer: https://app.com → Referer: https://attacker.com
X-API-Version: 1.0 → X-API-Version: 2.0
Content-Type: application/json → Content-Type: application/xml
📊 Interceptación de Respuestas
Análisis de Response
# Ejemplo de response interceptado
HTTP/1.1 200 OK
Content-Type: application/json
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src 'self'
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Strict
{
"user": {
"id": 12345,
"email": "[email protected]",
"role": "standard",
"api_key": "secret_key_12345",
"balance": 1000.00
}
}
# Análisis de seguridad:
- ✅ Headers de seguridad presentes
- ⚠️ API key expuesta en response
- ✅ Cookie con flags de seguridad
- ⚠️ Información sensible sin cifrar
Modificación de Respuestas
// Casos de uso para modificar respuestas
// 1. Bypass de restricciones del cliente
const bypassLimits = (response) => {
// Original
const original = {
"premium": false,
"max_downloads": 5,
"features_enabled": ["basic"]
};
// Modificado
const modified = {
"premium": true,
"max_downloads": 999,
"features_enabled": ["basic", "advanced", "premium"]
};
return modified;
};
// 2. Revelar funcionalidad oculta
const revealHiddenFeatures = (response) => {
response.ui_elements.admin_panel = true;
response.ui_elements.debug_mode = true;
return response;
};
// 3. Modificar validaciones
const alterValidation = (response) => {
response.validation_rules.min_password_length = 1;
response.validation_rules.require_2fa = false;
return response;
};
🔐 Análisis de Autenticación y Sesiones
Tokens JWT
// Decodificar y analizar JWT
interface JWTAnalysis {
header: {
alg: string; // HS256, RS256, none (vulnerabilidad)
typ: string;
};
payload: {
sub: string; // Subject (user ID)
iat: number; // Issued at
exp: number; // Expiration
role: string; // User role
permissions: string[];
};
signature: string;
}
// Herramienta de análisis en ZAP
const analyzeJWT = (token: string): void => {
// Encode/Decode tab → Base64 Decode
const parts = token.split('.');
const header = atob(parts[0]);
const payload = atob(parts[1]);
console.log('Header:', JSON.parse(header));
console.log('Payload:', JSON.parse(payload));
// Verificar vulnerabilidades comunes
checkAlgorithmConfusion(header);
checkExpirationBypass(payload);
checkPrivilegeEscalation(payload);
};
Análisis de Cookies
// Inspección de cookies de sesión
const analyzeCookies = (cookies) => {
cookies.forEach(cookie => {
console.log(`Cookie: ${cookie.name}`);
console.log(`Value: ${cookie.value}`);
console.log(`Flags:`);
console.log(` HttpOnly: ${cookie.httpOnly}`); // Previene XSS
console.log(` Secure: ${cookie.secure}`); // Solo HTTPS
console.log(` SameSite: ${cookie.sameSite}`); // CSRF protection
console.log(` Domain: ${cookie.domain}`);
console.log(` Path: ${cookie.path}`);
console.log(` Expires: ${cookie.expires}`);
// Detectar problemas
if (!cookie.httpOnly) {
console.warn('⚠️ Cookie sin HttpOnly - Vulnerable a XSS');
}
if (!cookie.secure) {
console.warn('⚠️ Cookie sin Secure - Puede enviarse por HTTP');
}
if (cookie.sameSite === 'None') {
console.warn('⚠️ SameSite=None - Vulnerable a CSRF');
}
});
};
🔍 Análisis de Parámetros
Identificación Automática
# Script Python para ZAP
from zapv2 import ZAPv2
import json
zap = ZAPv2(apikey='tu-api-key')
def analyze_parameters(url):
# Obtener todos los parámetros de una URL
params = zap.params.params(site=url)
for param in params:
print(f"Parámetro: {param['name']}")
print(f"Tipo: {param['type']}") # URL, POST, Cookie, Header
print(f"Valores observados: {param['values']}")
# Analizar el tipo de dato
if looks_like_id(param['value']):
test_idor(url, param)
elif looks_like_sql(param['value']):
test_sql_injection(url, param)
elif looks_like_command(param['value']):
test_command_injection(url, param)
def looks_like_id(value):
# Detectar IDs numéricos o UUIDs
import re
return re.match(r'^\d+$', value) or \
re.match(r'^[a-f0-9-]{36}$', value)
Fuzzing de Parámetros
// Configuración de Fuzzer en ZAP
const fuzzingConfig = {
// Payloads para diferentes tipos de pruebas
sqlInjection: [
"' OR '1'='1",
"1' AND '1'='2",
"' OR '1'='1' --",
"admin'--",
"' UNION SELECT NULL--"
],
xss: [
"<script>alert('XSS')</script>",
"<img src=x onerror=alert('XSS')>",
"javascript:alert('XSS')",
"<svg onload=alert('XSS')>",
"'\"><script>alert('XSS')</script>"
],
pathTraversal: [
"../../../etc/passwd",
"..\\..\\..\\windows\\system32\\config\\sam",
"....//....//....//etc/passwd",
"%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd"
],
commandInjection: [
"; ls -la",
"| whoami",
"& net user",
"`id`",
"$(whoami)"
]
};
// Aplicar fuzzing
function applyFuzzing(request, payloadType) {
const payloads = fuzzingConfig[payloadType];
payloads.forEach(payload => {
// Reemplazar parámetro con payload
const modifiedRequest = request.replace(
/param=([^&]*)/,
`param=${encodeURIComponent(payload)}`
);
// Enviar request modificado
sendRequest(modifiedRequest);
});
}
📦 Decodificación y Encoding
Herramientas de Encoding/Decoding
// Funciones de encoding/decoding disponibles en ZAP
interface EncodingTools {
// Base64
base64Encode(text: string): string;
base64Decode(encoded: string): string;
// URL
urlEncode(text: string): string;
urlDecode(encoded: string): string;
// HTML
htmlEncode(text: string): string;
htmlDecode(encoded: string): string;
// Hex
hexEncode(text: string): string;
hexDecode(hex: string): string;
// Hash
md5(text: string): string;
sha1(text: string): string;
sha256(text: string): string;
}
// Ejemplo de uso
const decodeChain = (encodedData: string) => {
// Datos con múltiples capas de encoding
let decoded = encodedData;
// 1. URL decode
decoded = decodeURIComponent(decoded);
console.log('After URL decode:', decoded);
// 2. Base64 decode
decoded = atob(decoded);
console.log('After Base64 decode:', decoded);
// 3. Parse JSON
const data = JSON.parse(decoded);
console.log('Final data:', data);
return data;
};
Análisis de Payloads Complejos
// Análisis de payloads serializados
const analyzeSerializedData = (data) => {
// PHP serialized
if (data.match(/^a:\d+:{/)) {
console.log('PHP serialized object detected');
// Buscar posible object injection
}
// Java serialized
if (data.startsWith('rO0AB')) {
console.log('Java serialized object detected');
// Posible deserialización insegura
}
// .NET ViewState
if (data.match(/^\/wEP/)) {
console.log('.NET ViewState detected');
// Verificar MAC validation
}
// Python pickle
if (data.includes('pickle')) {
console.log('Python pickle detected');
// Riesgo de RCE
}
};
🎯 Identificación de Vulnerabilidades
Patrones de Vulnerabilidades Comunes
interface VulnerabilityPatterns {
// Información sensible en respuestas
sensitiveData: RegExp[];
// Headers inseguros
insecureHeaders: string[];
// Errores que revelan información
informationDisclosure: RegExp[];
}
const patterns: VulnerabilityPatterns = {
sensitiveData: [
/api[_-]?key/i,
/password/i,
/secret/i,
/token/i,
/private[_-]?key/i,
/ssn|social[_-]?security/i,
/credit[_-]?card/i
],
insecureHeaders: [
'Server', // Revela versión del servidor
'X-Powered-By', // Revela tecnología
'X-AspNet-Version', // Revela versión de .NET
'X-Debug-Token' // Información de debug
],
informationDisclosure: [
/stack[_-]?trace/i,
/sql[_-]?error/i,
/exception/i,
/at line \d+/i,
/mysql_fetch/i,
/ORA-\d{5}/i // Oracle errors
]
};
Script de Análisis Automático
# Script para análisis automático en ZAP
import re
from zapv2 import ZAPv2
class TrafficAnalyzer:
def __init__(self, zap):
self.zap = zap
self.vulnerabilities = []
def analyze_message(self, msg_id):
# Obtener mensaje completo
msg = self.zap.core.message(msg_id)
request_header = msg['requestHeader']
request_body = msg['requestBody']
response_header = msg['responseHeader']
response_body = msg['responseBody']
# Analizar request
self.check_authentication(request_header)
self.check_injection_points(request_body)
# Analizar response
self.check_security_headers(response_header)
self.check_sensitive_data(response_body)
self.check_error_messages(response_body)
return self.vulnerabilities
def check_sensitive_data(self, body):
patterns = [
(r'api[_-]?key["\']?\s*:\s*["\']([^"\']+)', 'API Key expuesta'),
(r'password["\']?\s*:\s*["\']([^"\']+)', 'Password en texto plano'),
(r'\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b', 'Posible tarjeta de crédito'),
(r'\b\d{3}-\d{2}-\d{4}\b', 'Posible SSN'),
(r'Bearer\s+([A-Za-z0-9\-_=]+\.[A-Za-z0-9\-_=]+\.?[A-Za-z0-9\-_.+/=]*)', 'JWT Token')
]
for pattern, description in patterns:
matches = re.findall(pattern, body, re.IGNORECASE)
if matches:
self.vulnerabilities.append({
'type': 'Information Disclosure',
'description': description,
'evidence': matches[0] if len(matches[0]) < 50 else matches[0][:50] + '...'
})
🔄 Repetición y Modificación de Requests
Replay de Peticiones
// Función para replay con modificaciones
async function replayWithModifications(originalRequest) {
const modifications = [
// Test de autorización
{ header: 'Authorization', value: 'Bearer invalid_token' },
{ header: 'Authorization', value: '' },
// Test de IDOR
{ path: '/users/123', newPath: '/users/999' },
// Test de método HTTP
{ method: 'GET', newMethod: 'DELETE' },
{ method: 'POST', newMethod: 'PUT' },
// Test de Content-Type
{ header: 'Content-Type', value: 'application/xml' }
];
for (const mod of modifications) {
const modifiedRequest = applyModification(originalRequest, mod);
const response = await sendRequest(modifiedRequest);
// Analizar diferencias
analyzeResponse(response, originalRequest);
}
}
// Resender en ZAP
// Click derecho en request → Open/Resend with Request Editor
// Modificar y enviar múltiples variaciones
Comparación de Respuestas
// Comparar respuestas para detectar diferencias
interface ResponseComparison {
statusCode: {
original: number;
modified: number;
different: boolean;
};
contentLength: {
original: number;
modified: number;
difference: number;
};
responseTime: {
original: number;
modified: number;
difference: number;
};
keywords: {
added: string[];
removed: string[];
};
}
function compareResponses(original: string, modified: string): ResponseComparison {
// Extraer información relevante
const comparison: ResponseComparison = {
statusCode: {
original: extractStatusCode(original),
modified: extractStatusCode(modified),
different: false
},
contentLength: {
original: original.length,
modified: modified.length,
difference: 0
},
responseTime: {
original: 0,
modified: 0,
difference: 0
},
keywords: {
added: [],
removed: []
}
};
// Calcular diferencias
comparison.statusCode.different =
comparison.statusCode.original !== comparison.statusCode.modified;
comparison.contentLength.difference =
comparison.contentLength.modified - comparison.contentLength.original;
// Detectar cambios significativos
if (comparison.statusCode.different) {
console.log('⚠️ Cambio en status code - posible bypass');
}
if (Math.abs(comparison.contentLength.difference) > 100) {
console.log('⚠️ Gran diferencia en tamaño - contenido diferente');
}
return comparison;
}
📊 WebSockets y Tráfico Especial
Interceptación de WebSockets
// Configuración para WebSockets
const wsInterception = {
// Habilitar en ZAP
enable: () => {
// Tools → Options → WebSockets
// ☑ Forward all WebSocket messages
// ☑ Break on all WebSocket messages
},
// Análisis de mensajes
analyzeMessage: (message) => {
const parsed = JSON.parse(message.data);
// Buscar datos sensibles
if (parsed.token || parsed.sessionId) {
console.warn('Token/Session en WebSocket');
}
// Modificar mensaje
parsed.role = 'admin';
return JSON.stringify(parsed);
},
// Inyección en WebSocket
injectMessage: () => {
return JSON.stringify({
type: 'command',
action: 'elevate_privileges',
user: 'current'
});
}
};
GraphQL Interception
# Interceptar queries GraphQL
query GetUser {
user(id: "123") {
id
email
role
# Modificar para obtener más datos
password # Añadir campo no autorizado
apiKey # Información sensible
}
}
# Modificar mutations
mutation UpdateUser {
updateUser(
id: "123",
# Cambiar role no autorizado
role: "admin" # De "user" a "admin"
) {
success
user {
id
role
}
}
}
🛠️ Herramientas Avanzadas de Análisis
Scripts Personalizados
# Script para análisis personalizado
from zapv2 import ZAPv2
import json
import base64
class CustomAnalyzer:
def __init__(self):
self.zap = ZAPv2(apikey='tu-api-key')
self.alerts = []
def analyze_traffic(self, target):
# Obtener todo el tráfico
messages = self.zap.core.messages(target)
for msg in messages:
self.analyze_authentication(msg)
self.analyze_encryption(msg)
self.analyze_business_logic(msg)
self.analyze_rate_limiting(msg)
def analyze_authentication(self, msg):
# Verificar métodos de autenticación
auth_header = self.extract_header(msg, 'Authorization')
if not auth_header:
self.alert('Sin autenticación', 'high')
elif 'Basic' in auth_header:
# Decodificar Basic Auth
encoded = auth_header.split(' ')[1]
decoded = base64.b64decode(encoded).decode()
if ':' in decoded:
user, password = decoded.split(':', 1)
self.alert(f'Basic Auth detectado: {user}', 'medium')
elif 'Bearer' in auth_header:
token = auth_header.split(' ')[1]
self.analyze_jwt(token)
def analyze_jwt(self, token):
try:
# Decodificar JWT sin verificar
parts = token.split('.')
header = json.loads(base64.b64decode(parts[0] + '=='))
payload = json.loads(base64.b64decode(parts[1] + '=='))
# Verificar algoritmo
if header.get('alg') == 'none':
self.alert('JWT sin firma (alg: none)', 'critical')
elif header.get('alg') in ['HS256', 'HS384', 'HS512']:
self.alert('JWT con clave simétrica', 'info')
# Verificar expiración
import time
if 'exp' in payload:
if payload['exp'] < time.time():
self.alert('JWT expirado', 'medium')
else:
self.alert('JWT sin expiración', 'medium')
except Exception as e:
self.alert(f'Error analizando JWT: {e}', 'low')
Exportación de Datos
// Exportar tráfico filtrado
function exportFilteredTraffic(filter) {
const messages = zap.search.messages(filter);
const exportData = [];
messages.forEach(msg => {
exportData.push({
timestamp: msg.timestamp,
method: msg.method,
url: msg.url,
statusCode: msg.statusCode,
requestHeaders: parseHeaders(msg.requestHeader),
requestBody: msg.requestBody,
responseHeaders: parseHeaders(msg.responseHeader),
responseBody: msg.responseBody,
alerts: msg.alerts
});
});
// Exportar a diferentes formatos
saveAsJSON(exportData, 'traffic_analysis.json');
saveAsCSV(exportData, 'traffic_summary.csv');
generateHTMLReport(exportData, 'report.html');
}
🔍 Casos de Uso Prácticos
Caso 1: Bypass de Autenticación
// Técnicas de bypass
const authBypassTechniques = {
// 1. Eliminar header de autenticación
removeAuth: (request: string): string => {
return request.replace(/Authorization:.*\r\n/, '');
},
// 2. Usar token expirado
useExpiredToken: (request: string): string => {
const expiredToken = 'Bearer eyJ....[token_expirado]';
return request.replace(/Authorization:.*/, `Authorization: ${expiredToken}`);
},
// 3. Modificar user ID en token
modifyUserId: (token: string): string => {
const decoded = decodeJWT(token);
decoded.payload.user_id = 'admin';
return encodeJWT(decoded);
},
// 4. Method override
methodOverride: (request: string): string => {
return request.replace('POST', 'GET')
.replace('Content-Type: application/json',
'X-HTTP-Method-Override: POST');
}
};
Caso 2: Escalación de Privilegios
// Intentos de escalación
const privilegeEscalation = {
// Modificar role en request
modifyRole: (body) => {
const data = JSON.parse(body);
data.role = 'admin';
data.permissions = ['read', 'write', 'delete', 'admin'];
return JSON.stringify(data);
},
// Añadir headers administrativos
addAdminHeaders: (headers) => {
headers['X-Admin-Token'] = 'true';
headers['X-Privileged-User'] = '1';
headers['X-Internal-Request'] = 'true';
return headers;
},
// Manipular IDs de grupo
changeGroup: (request) => {
// De user_group=2 a user_group=1 (admin)
return request.replace(/user_group=\d+/, 'user_group=1');
}
};
📋 Checklist de Análisis
Lista de Verificación de Seguridad
Request Analysis:
☐ Autenticación presente y válida
☐ Autorización verificada
☐ Parámetros validados
☐ Sin información sensible en URL
☐ Headers de seguridad apropiados
☐ Método HTTP correcto
☐ Content-Type apropiado
Response Analysis:
☐ Status code apropiado
☐ Headers de seguridad presentes
☐ Sin información sensible expuesta
☐ Sin mensajes de error detallados
☐ Cookies con flags de seguridad
☐ CORS configurado correctamente
☐ Sin headers que revelen tecnología
Data Validation:
☐ Input sanitizado
☐ Output encoded
☐ Sin datos sensibles en logs
☐ Sesiones con timeout
☐ Tokens con expiración
☐ Rate limiting implementado
🎯 Ejercicios Prácticos
Ejercicio 1: Interceptación Básica
- Configura break points para todas las peticiones
- Navega a http://testphp.vulnweb.com
- Intercepta y modifica el User-Agent
- Cambia el método de GET a POST
- Analiza la diferencia en las respuestas
Ejercicio 2: Análisis de Autenticación
- Intercepta un login request
- Identifica el mecanismo de autenticación
- Modifica las credenciales
- Intenta bypass con técnicas comunes
- Documenta los hallazgos
Ejercicio 3: Fuzzing de Parámetros
- Identifica todos los parámetros de una aplicación
- Configura el fuzzer con payloads de XSS
- Ejecuta fuzzing en campos de entrada
- Analiza las respuestas para detectar vulnerabilidades
- Genera un reporte de los hallazgos
Ejercicio 4: WebSocket Analysis
- Encuentra una aplicación con WebSockets
- Intercepta los mensajes
- Modifica mensajes en tiempo real
- Intenta inyectar comandos
- Documenta el flujo de comunicación
🚨 Troubleshooting
Problema: “No se interceptan peticiones HTTPS”
# Verificar:
1. Certificado ZAP instalado correctamente
2. Proxy configurado en navegador/app
3. Break points activados
# Solución:
- Regenerar certificado
- Verificar configuración de proxy
- Revisar logs de ZAP
Problema: “Respuestas truncadas o corruptas”
# Causas comunes:
- Encoding incorrecto
- Compresión no manejada
- Timeout en la conexión
# Solución:
Tools → Options → Connection
- Aumentar timeouts
- Deshabilitar compresión
- Verificar encoding
📚 Resumen
En este capítulo aprendiste:
- ✅ Cómo interceptar y modificar tráfico HTTP/HTTPS
- ✅ Análisis de headers, cookies y tokens
- ✅ Técnicas de bypass y escalación
- ✅ Fuzzing y testing de parámetros
- ✅ Decodificación de payloads complejos
- ✅ Identificación de vulnerabilidades en el tráfico
- ✅ Uso de scripts para análisis automatizado
🚀 Próximo Capítulo
En el siguiente capítulo aprenderás sobre Auditoría de Apps Android, incluyendo:
- Configuración con emuladores
- Bypass avanzado de SSL Pinning
- Análisis de APIs móviles
- Herramientas específicas para Android
← Capítulo 2: Proxy Móvil | Volver al Índice | Siguiente: Auditoría Android →