Web API penetration testing

Web Application Firewall (WAF)
wafw00f <URL>
nuclei -u <URL> -t dns/dns-waf-detect.yaml,http/technologies/secui-waf-detect.yaml,http/technologies/waf-detect.yaml -H "Authorization: Bearer <token>" -ts -silent
HTTP security headers
shcheck.py -i -k <URL>
nuclei -u <URL> -t http/misconfiguration/http-missing-security-headers.yaml -H "Authorization: Bearer <token>" -ts -silent

No HTTP headers con divulgación de información.

  • Server

  • X-Powered-By

  • X-AspNet*

Expresión regular para identificar HTTP security headers recomendados.

Strict-Transport-Security|Content-Security-Policy|X-Content-Type-Options|Content-Type|X-Frame-Options|Referrer-Policy
HTTP methods (verbs)

Utilizar el método HTTP apropiado para cada operación y responder con un error 405 Method Not Allowed si el método de la petición no es el apropiado.

Content-Type

Validar los Content-Type enviados (request) contra los Content-Type aceptados (response).

Incluir en la respuesta (response) el HTTP header X-Content-Type-Options.

X-Content-Type-Options: nosniff
Redireccionamiento estricto de HTTP a HTTPS
nmap -sV -p 80,443 -n -Pn <target>
curl -I -l <HTTP-URL> -H "Authorization: Bearer <token>"
curl <HTTPS-URL> -H "Authorization: Bearer <token>"
SSL/TLS y algoritmos de cifrados
sslscan <target>
nuclei -u <URL> -t ssl -ts -silent
Fuzzing

Fuzzing de paths.

kr scan http://<target>/ -w routes-large.kite
ffuf -u http://<target>/api/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt:FUZZ -H "Authorization: Bearer <token>" -c -mc all -fc 404 -o ffuf-fuzzing-paths.html -of html

Fuzzing de versiones (v1, v2, v3...).

Fuzzing parámetros GET.

arjun -u http://<target>/api.php --headers "Authorization: Bearer <token>"
ffuf -u http://<target>/api.php?FUZZ=test -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -H "Authorization: Bearer <token>" -c -mc all -fc 301,404 -fs <size> -o ffuf-fuzzing-get-parameters.html -of html

Fuzzing valor de parámetros GET.

ffuf -u http://<target>/api.php?<parameter>=FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt:FUZZ -H "Authorization: Bearer <token>" -c -mc all -fc 301,404 -fs <size> -o ffuf-fuzzing-get-parameters-values.html -of html

Fuzzing parámetros POST.

arjun -u http://<target>/api.php --headers "Authorization: Bearer <token>" -m <POST|JSON|XML>
ffuf -u http://<target>/api.php -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -X POST -d "FUZZ=test" -H "Authorization: Bearer <token>" -H "Content-Type: application/x-www-form-urlencoded" -c -mc all -fc 301,404 -fs <size> -o ffuf-fuzzing-post-parameters.html -of html

Fuzzing valor de parámetros POST.

ffuf -u http://<target>/api.php -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt:FUZZ -X POST -d "<parameter>=FUZZ" -H "Authorization: Bearer <token>" -H "Content-Type: application/x-www-form-urlencoded" -c -mc all -fc 301,404 -fs <size> -o ffuf-fuzzing-post-parameters-values.html -of html

Fuzzing de archivos (según contexto de revisión).

# Wordlist
ffuf -u http://<target>/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-large-files.txt:FUZZ -c -mc all -fc 404 -o ffuf-fuzzing-files.html -of html
# Wordlist + extensiones (.html, .js, .php, .jsp, .aspx)
ffuf -u http://<target>/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt:FUZZ -e .html,.js,.php,.jsp,.aspx -c -mc all -fc 404 -o ffuf-fuzzing-extensions.html -of html
# Wordlist + extensiones (ocultos / .txt, .config, .old, .bak, .inc)
ffuf -u http://<target>/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt:FUZZ -e .txt,.config,.old,.bak,.inc -c -mc all -fc 404 -o ffuf-fuzzing-extensions-hidden.html -of html
# Wordlist crawling + extensiones
ffuf -u http://<target>/FUZZ -w <wordlist-crawling.txt>:FUZZ -e .html,.js,.php,.jsp,.aspx,.txt,.config,.old,.bak,.inc -c -mc all -fc 404 -o ffuf-fuzzing-crawling-extensions.html -of html
Autenticación y autorización
  • Consumo de API con token de autenticación incorrecto.

  • Consumo de API con HTTP header de autenticación, pero sin valor.

  • Consumo de API sin HTTP header de autenticación.

  • Consumo de API con token de autenticación expirado.

  • No utilizar Basic Authentication.

  • Insecure Direct Object References (IDOR).

Exposición de datos
  • Divulgación de datos sensibles.

  • Exposición de datos confidenciales a través del "query strings" en URL.

  • Entrega de información excesiva.

Input data validation

Fuzzing y consumo de API con parámetros de entrada inválidos.

!@#$%^&~_-+=*.,:;'"\|/?<XSS>[{()}]
!@#$%^&~_-+=*.,:;'\|/?<XSS>[{()}]
!@#$%^&~_-+=*.,:;'|/?<XSS>[{()}]

Manejo de errores.

  • Mensajes de errores genéricos.

  • No revelar detalles del error innecesariamente.

  • No entregar detalles técnicos referente al error.

Cross-origin resource sharing (CORS)
curl -I -X OPTIONS -H "Origin: https://web-maliciosa-atacante.com" -H "Authorization: Bearer <token>" <URL>
Restricciones de consumo
  • Rate Limit: garantiza un número total de solicitudes en un intervalo de tiempo determinado. Comprueba si el número de solicitudes se encuentra dentro del intervalo de tiempo configurado, independientemente del tiempo entre cada solicitud. Cuando finaliza el intervalo, comienza uno nuevo y también se reinicia el recuento de solicitudes.

  • Spike Arrest: garantiza una distancia de tiempo mínima entre dos solicitudes. Si no se respeta el tiempo entre dos solicitudes, no se aceptará la segunda y el código de error HTTP devuelto será 429.

  • Caching: almacenamiento en caché.

  • Batching attack (GraphQL).

Escaneo automatizado
  • Burp Suite Professional.

  • Nuclei.

nuclei -u <URL> -H "Authorization: Bearer <token>" -ts -silent
  • Burp Bounty Pro.

  • OWASP Zed Attack Proxy (ZAP).

Vulnerabilidades
# General
sqlmap -r request-general-1.txt --random-agent --threads=10 --batch --flush-session --hostname --proxy=http://127.0.0.1:8080
sqlmap -r request-general-2.txt --level=5 --risk=3 --random-agent --threads=10 --batch --flush-session --hostname --proxy=http://127.0.0.1:8080

# Parámetros GET
sqlmap -r request-get-1.txt --method GET -p "<param1>,<param2>,<param3>" --random-agent --threads=10 --batch --flush-session --hostname --proxy=http://127.0.0.1:8080
sqlmap -r request-get-2.txt --method GET -p "<param1>,<param2>,<param3>" --level=5 --risk=3 --random-agent --threads=10 --batch --flush-session --hostname --proxy=http://127.0.0.1:8080

# HTTP Headers
sqlmap -r request-headers-1.txt --header="<header1>: <value1>*" --header="<header2>: <value2>*" --header="<header3>: <value3>*" --random-agent --threads=10 --batch --flush-session --hostname --proxy=http://127.0.0.1:8080
sqlmap -r request-headers-2.txt --level=5 --risk=3 --header="<header1>: <value1>*" --header="<header2>: <value2>*" --header="<header3>: <value3>*" --random-agent --threads=10 --batch --flush-session --hostname --proxy=http://127.0.0.1:8080

Última actualización