Contenido
- 1) Base rápida: anatomía de una request con curl
- 2) Opciones clave (las que usarás todo el rato)
- 3) Plantilla de trabajo “A01-ready” (para evidencias)
- 4) OWASP A01: qué probar con curl (y cómo)
- 5) Autenticación práctica con curl (cookies, sesiones, CSRF)
- 6) Subidas de archivo y pruebas de acceso (muy común en A01)
- 7) Reporting: sacar “pruebas bonitas” para un informe
- 8) Performance y timing (cuando el comportamiento cambia)
- 9) “Modo alumno”: 10 comandos que deberían saberse sí o sí
- 10) Errores típicos (y cómo no volverte loco)
- 11) Tratamiento de sesiones.
- Flujo completo (plantilla mental)
- CASO PRACTICO
curl es un cliente de línea de comandos para hacer peticiones a URLs (HTTP/HTTPS y más). En ciberseguridad sirve para:
- Reproducir una request exacta (sin navegador, sin JS, sin “magia”).
- Cambiar headers, cookies, método (GET/POST/PUT/DELETE…), body, redirects, TLS, etc.
- Guardar evidencias: headers, cuerpo, tiempos, códigos, trazas.
- Automatizar pruebas: loops, wordlists, comparación de respuestas.
En OWASP A01, curl es ideal para comprobar:
“¿Puedo acceder a algo que no debería si cambio un ID, un rol, un método, una ruta o un header?”
1) Base rápida: anatomía de una request con curl
1.1 GET simple
curl https://ejemplo.com/
1.2 Ver solo headers (respuesta)
curl -I https://ejemplo.com/
1.3 Ver request + response (debug)
-vmuestra el intercambio HTTP (ideal para auditoría).
curl -v https://ejemplo.com/
1.4 Seguir redirecciones
Muchas apps redirigen a /login.
curl -L https://ejemplo.com/zona-privada
2) Opciones clave (las que usarás todo el rato)
Salida y verbosidad
-iincluye headers de respuesta en la salida-Ihace HEAD (solo headers)-vverbose (request/response)-ssilent (menos ruido)-Smuestra errores aunque uses-s-D <file>guarda headers de respuesta en un fichero-o <file>guarda el cuerpo en fichero-w "<fmt>"imprime métricas (código, tiempos, etc.)
Ejemplo “limpio pero con datos útiles”:
curl -sS -D headers.txt -o body.html -w "STATUS=%{http_code}\nTIME=%{time_total}\n" https://ejemplo.com/
Método HTTP
-X GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD
Ojo nerd: curl elige método según uses -d (si usas -d, por defecto es POST). A veces conviene ser explícito con -X.
Headers y autenticación
-H "Header: valor"añade header(s)-u user:passBasic Auth-b "cookie=valor"envía cookies-c cookies.txtguarda cookies en “cookie jar”-b cookies.txtreutiliza cookies guardadas
Datos (body)
-d "a=1&b=2"envía body tipo form-url-encoded--data-urlencodecodifica bien caracteres especiales-H "Content-Type: application/json" -d '{"x":1}'JSON-F "f=@archivo"multipart/form-data (subidas)
TLS y certificados (útil en auditoría)
--tlsv1.2fuerza versión TLS--ciphers ...fuerza cifrados (avanzado)--cert,--key(mTLS)-kignora validación del certificado (solo pruebas controladas, jamás en producción como “solución”)
3) Plantilla de trabajo “A01-ready” (para evidencias)
Esto te deja una salida reproducible, guardando pruebas:
curl -sS -i -L \
-w "\n\n---\nSTATUS=%{http_code}\nSIZE=%{size_download}\nTIME=%{time_total}\nIP=%{remote_ip}\nURL=%{url_effective}\n" \
https://objetivo.tld/ruta
Para separar headers y body en ficheros:
curl -sS -D evidencias_headers.txt -o evidencias_body.txt \
-w "STATUS=%{http_code}\nTIME=%{time_total}\n" \
https://objetivo.tld/ruta
4) OWASP A01: qué probar con curl (y cómo)
4.1 IDOR (Insecure Direct Object Reference) — cambiar el ID
Caso típico: /api/users/123 te devuelve tu usuario. ¿Qué pasa con /api/users/124?
curl -sS -i https://victima.tld/api/users/123
curl -sS -i https://victima.tld/api/users/124
Qué buscar:
- Si cambia el contenido y sigue devolviendo 200 OK, mala pinta.
- Si debería ser 403 Forbidden (autorización) o 404 (no revelar existencia), depende del diseño, pero 200 para todo suele ser alarma.
4.2 Bypass por método HTTP (GET vs PUT/DELETE)
Muchas apps protegen el “ver” pero se olvidan del “modificar”.
# ver
curl -sS -i https://victima.tld/api/orders/55
# intentar modificar
curl -sS -i -X PUT -H "Content-Type: application/json" \
-d '{"status":"CANCELLED"}' \
https://victima.tld/api/orders/55
# intentar borrar
curl -sS -i -X DELETE https://victima.tld/api/orders/55
Señal A01: endpoints sensibles aceptan métodos peligrosos sin chequear rol/propiedad.
4.3 Acceso a rutas “admin” sin ser admin
curl -sS -i https://victima.tld/admin
curl -sS -i https://victima.tld/api/admin/users
4.4 Cambiar rol en el cliente (cabeceras “de pega”)
Si una app confía en algo como X-Role: admin (error grave), lo detectas así:
curl -sS -i -H "X-Role: admin" https://victima.tld/api/me
Nota: Esto no debería funcionar jamás si el backend está bien (el rol debe venir de sesión/token firmado).
4.5 Probar endpoints con y sin cookie (autenticación vs autorización)
Primero sin login:
curl -sS -i https://victima.tld/api/profile
~~`
Luego con cookie de sesión (simulando usuario normal):
1) Logueas una vez y guardas cookies:
~~~bash
curl -sS -c cookies.txt -d "user=alumno&pass=1234" https://victima.tld/login
- Accedes con cookie:
curl -sS -b cookies.txt -i https://victima.tld/api/profile
- Intentas un endpoint que debería ser solo admin:
curl -sS -b cookies.txt -i https://victima.tld/api/admin/dashboard
A01 clásico: usuario normal consigue 200 donde debería ser 403.
4.6 Tokens Bearer (JWT / API tokens)
curl -sS -i \
-H "Authorization: Bearer TU_TOKEN" \
https://victima.tld/api/orders
Pruebas A01 típicas:
- Usar token de usuario A para pedir recursos de usuario B (IDOR).
- Ver si el backend solo valida “token válido” pero no valida “dueño del recurso”.
4.7 Enumeración y filtrado: parámetros peligrosos
Algunos endpoints aceptan filtros como ?userId=...:
curl -sS -i "https://victima.tld/api/invoices?userId=10"
curl -sS -i "https://victima.tld/api/invoices?userId=11"
4.8 CORS mal configurado (pista de exposición)
CORS no es “A01 puro”, pero a veces se mezcla con acceso indebido desde otros orígenes.
curl -sS -i \
-H "Origin: https://malicioso.tld" \
https://victima.tld/api/profile
~~`
Busca en respuesta:
- `Access-Control-Allow-Origin: *` o refleja el Origin sin control
- `Access-Control-Allow-Credentials: true` combinado con cosas raras
### 4.9 OPTIONS y descubrimiento de métodos permitidos
~~~bash
curl -sS -i -X OPTIONS https://victima.tld/api/orders/55
Mira Allow: o los headers CORS.
5.1 Mantener sesión con cookies
# login
curl -sS -c cookies.txt -d "username=alumno&password=1234" https://victima.tld/login
# usar sesión
curl -sS -b cookies.txt -i https://victima.tld/mi-cuenta
5.2 CSRF token (patrón general)
Muchas apps: primero GET a formulario para obtener token, luego POST con token + cookie.
Ejemplo conceptual (depende del sitio):
# 1) cargar formulario y guardar cookies
curl -sS -c cookies.txt https://victima.tld/form > form.html
# 2) extraer token (si está en HTML; esto es un ejemplo típico)
grep -oP 'name="csrf"\s+value="\K[^"]+' form.html > token.txt
# 3) enviar POST con token + cookie
curl -sS -b cookies.txt -d "csrf=$(cat token.txt)&campo=valor" https://victima.tld/submit
En A01, CSRF no es el centro, pero aparece en flujos reales al automatizar.
6) Subidas de archivo y pruebas de acceso (muy común en A01)
6.1 Subir con multipart
curl -sS -i \
-b cookies.txt \
-F "file=@prueba.txt" \
https://victima.tld/upload
6.2 Acceder al archivo de otro usuario
Si el sistema guarda en /uploads/ID/archivo, prueba el ID (solo en entorno controlado):
curl -sS -i https://victima.tld/uploads/10/prueba.txt
curl -sS -i https://victima.tld/uploads/11/prueba.txt
7) Reporting: sacar “pruebas bonitas” para un informe
7.1 Guardar todo + métricas
curl -sS -i -L \
-o respuesta.txt \
-w "\nSTATUS=%{http_code}\nTIME=%{time_total}\nSIZE=%{size_download}\n" \
https://victima.tld/api/orders/55
7.2 Solo el código HTTP (útil para scripts)
curl -s -o /dev/null -w "%{http_code}\n" https://victima.tld/admin
7.3 Comparar respuestas rápidamente (cambia ID y mira tamaño)
curl -s -o /dev/null -w "ID=55 CODE=%{http_code} SIZE=%{size_download}\n" https://victima.tld/api/orders/55
curl -s -o /dev/null -w "ID=56 CODE=%{http_code} SIZE=%{size_download}\n" https://victima.tld/api/orders/56
Si los tamaños cambian de forma consistente… probablemente estás viendo datos distintos.
8) Performance y timing (cuando el comportamiento cambia)
--max-time 10corta si tarda más de 10s--connect-timeout 3timeout de conexión--retry 3 --retry-all-errorsreintentos (ojo en auditorías para no “machacar”)
curl -sS --connect-timeout 3 --max-time 10 https://victima.tld/
9) “Modo alumno”: 10 comandos que deberían saberse sí o sí
curl -v https://host/ruta
curl -I https://host/
curl -L https://host/ruta
curl -i https://host/api/recurso
curl -H "Authorization: Bearer TOKEN" https://host/api
curl -c cookies.txt -d "u=a&p=b" https://host/login
curl -b cookies.txt https://host/privado
curl -X PUT -H "Content-Type: application/json" -d '{"x":1}' https://host/api/x/1
curl -X DELETE https://host/api/x/1
curl -s -o /dev/null -w "%{http_code}\n" https://host/admin
10) Errores típicos (y cómo no volverte loco)
- 403 vs 401
401 Unauthorized: no autenticado (falta login/token).403 Forbidden: autenticado pero sin permiso.- A01 suele ser “debería ser 403 y me dan 200”.
- curl “no hace lo mismo que el navegador”
- El navegador añade cookies, headers, y sigue redirects.
- Usa
-L, y si necesitas replicar, usa-vy añade-Hy-b.
- El endpoint requiere JSON
- Añade
-H "Content-Type: application/json".
- Añade
- El servidor redirige a login
- Mira
Location:con-io sigue con-L.
- Mira
11) Tratamiento de sesiones.
Si una web usa sesión, curl solo verá la respuesta correcta si:
- primero creas la sesión (login)
- luego reenvías la cookie de sesión en las peticiones siguientes
El navegador lo hace solo. curl, no.
Qué es realmente una sesión (visión backend)
Cuando haces login:
- El servidor valida usuario/contraseña
- Crea una sesión en servidor
- Envía una cookie al cliente, por ejemplo:
Set-Cookie: PHPSESSID=abc123; Path=/; HttpOnly
A partir de ahí:
- la cookie es tu identidad
- sin cookie → eres un desconocido
Método correcto con curl (cookie jar)
Paso 1️⃣ – Login y guardar la sesión
Usamos -c para guardar cookies.
curl -i \
-c cookies.txt \
-d "username=usuario1&password=1234" \
http://servidor/login.php
Comprueba el fichero:
cat cookies.txt
Verás algo tipo:
PHPSESSID abc123
Eso es tu sesión.
Paso 2️⃣ – Reutilizar la sesión para ver la respuesta real
Usamos -b para enviar la cookie.
curl -i \
-b cookies.txt \
http://servidor/api/profile.php
Ahora verás:
- la respuesta real
- no el redirect al login
- no el “no autorizado”
📌 Sin -b cookies.txt, curl siempre será anónimo.
Flujo completo (plantilla mental)
Siempre que una web use sesión:
curl -c cookies.txt→ crear sesióncurl -b cookies.txt→ usar sesión- Repetir paso 2 para cada endpoint protegido
Ver exactamente qué devuelve el servidor
Para auditoría, conviene ver headers + body:
curl -i -b cookies.txt http://servidor/api/orders.php
Si quieres guardar evidencias:
curl -b cookies.txt \
-D headers.txt \
-o body.txt \
-w "STATUS=%{http_code}\n" \
http://servidor/api/orders.php
Caso real típico: “me redirige al login”
Si haces esto:
curl http://servidor/api/profile.php
y ves:
HTTP/1.1 302 Found
Location: /login.php
No es que curl “no funcione”:
es que no llevas la sesión.
Solución:
curl -L -b cookies.txt http://servidor/api/profile.php
¿Y si el login es JSON (API REST)?
Muy común en APIs modernas.
Login:
curl -c cookies.txt \
-H "Content-Type: application/json" \
-d '{"user":"usuario1","pass":"1234"}' \
http://servidor/api/login
Acceso protegido:
curl -b cookies.txt \
http://servidor/api/orders
Alternativa: tokens (Bearer)
Si en vez de sesión usa token:
curl -H "Authorization: Bearer TOKEN_AQUI" \
http://servidor/api/orders
Aquí no hay cookie, el token es la identidad.
curl no tiene memoria
si no le pasas la sesión, no eres nadie
CASO PRACTICO
Vamos un caso clásico:
login en PHP con session_start() + usuario y contraseña.
Sin suposiciones raras, sin frameworks, sin magia.
Voy a explicarlo como piensa el servidor PHP, que es la clave para que curl tenga sentido.
Qué hace PHP cuando haces login (lo importante)
En un login típico en PHP ocurre esto:
session_start();- PHP crea (o reanuda) una sesión
- Si el usuario es correcto:
$_SESSION['user_id'] = 3; $_SESSION['role'] = 'user'; - PHP envía al navegador:
Set-Cookie: PHPSESSID=abc123
📌 Ese PHPSESSID es la identidad real del usuario
No el usuario, no la contraseña: la cookie.
Cómo reproducir eso con curl (paso a paso real)
Hacer login con curl y guardar la sesión
Supongamos:
- Login:
/login.php - Campos POST:
usernameypassword
Comando correcto
curl -i \
-c cookies.txt \
-d "username=usuario1&password=1234" \
http://servidor/login.php
Qué hace cada cosa
-d→ envía el POST (login)-c cookies.txt→ guarda la cookie PHPSESSID-i→ ves headers (para comprobar que haySet-Cookie)
Si todo va bien, verás algo como:
Set-Cookie: PHPSESSID=abc123; path=/; HttpOnly
📌 Eso significa: sesión creada correctamente
PASO 1.1 – Ver la cookie (para que lo entiendan)
cat cookies.txt
Contenido típico:
# Netscape HTTP Cookie File
servidor FALSE / FALSE 0 PHPSESSID abc123
Esto es la sesión PHP.
Acceder a una página protegida usando la sesión
Ahora reenvías la cookie:
curl -i \
-b cookies.txt \
http://servidor/privado.php
Si el login fue correcto:
- verás el contenido real
- no redirige a
/login.php - no dice “no autorizado”
Cada vez que vean PHP + sesión:
curl -c cookies.txt→ crear sesióncurl -b cookies.txt→ usar sesión- Repetir paso 2 tantas veces como haga falta
CASO REAL: “me redirige al login”
Si haces:
curl http://servidor/privado.php
y ves:
HTTP/1.1 302 Found
Location: login.php
👉 No es un error
👉 Es que no llevas la sesión
Solución:
curl -L -b cookies.txt http://servidor/privado.php
SIMULAR DOS USUARIOS DISTINTOS (muy A01)
Usuario normal
curl -c cookies_user.txt \
-d "username=user&password=1234" \
http://servidor/login.php
Admin
curl -c cookies_admin.txt \
-d "username=admin&password=admin123" \
http://servidor/login.php
Comparar accesos
curl -b cookies_user.txt http://servidor/admin.php
curl -b cookies_admin.txt http://servidor/admin.php
📌 Si ambos ven lo mismo → Broken Access Control
PROBAR IDOR CON SESIÓN REAL
curl -b cookies_user.txt \
"http://servidor/order.php?id=1"
curl -b cookies_user.txt \
"http://servidor/order.php?id=2"
Si cambia el contenido → IDOR confirmado
GUARDAR EVIDENCIA (modo auditor)
curl -b cookies_user.txt \
-D headers.txt \
-o body.txt \
-w "STATUS=%{http_code}\n" \
http://servidor/order.php?id=2
Eso es evidencia técnica válida.




![1.2 - [Herramientas] - Postman Is-Apidog-Better-Than-Postman-27](https://laaventuradeaprender.com/wp-content/uploads/2026/01/Is-Apidog-Better-Than-Postman-27.webp)
![1.3.1 [Reto] - curl como herramienta de auditoría Auditoria-Seguridad-web](https://laaventuradeaprender.com/wp-content/uploads/2026/01/Auditoria-Seguridad-web.webp)



![2.1.2 - [Reto] PROTOCOLO DE SEGURIDAD DE LA FEDERACIÓN 0177662c-95af-437b-bf31-1887f2445879](https://laaventuradeaprender.com/wp-content/uploads/2026/02/0177662c-95af-437b-bf31-1887f2445879-150x150.png)
![2.1.3 - [Reto] Cifrado Asimétrico con Clave Pública y Privada 104eb7cf-f928-41d0-a5e6-93c1313f5507](https://laaventuradeaprender.com/wp-content/uploads/2026/02/104eb7cf-f928-41d0-a5e6-93c1313f5507-150x150.png)