LinkFinder: extrayendo endpoints de bundles JavaScript
LinkFinder · MIT
LinkFinder parsea archivos JavaScript y extrae cualquier cosa que parezca un endpoint. Los front-ends modernos envían toda su tabla de rutas al navegador, lo que significa que el bundle es una descripción bastante completa de la API — incluidas rutas que la UI nunca llama.
Instalación
git clone https://github.com/GerbenJavado/LinkFinder.git
cd LinkFinder && pip install -r requirements.txt
python linkfinder.py -h Comandos principales
# un archivo JS, salida simple
python linkfinder.py -i https://example.com/static/app.js -o cli
# todo script de una página
python linkfinder.py -i https://example.com -d -o cli
# un dominio entero desde el corpus de Wayback
python linkfinder.py -i "https://example.com/*" -o results.html
# un bundle local
python linkfinder.py -i ./app.bundle.js -o cli -o cli imprime en stdout, que es lo que quieres en un pipeline; el valor por defecto escribe un informe HTML.
Salida
Un endpoint candidato por línea:
/api/v2/users
/api/v2/admin/impersonate
/internal/healthz Dónde encaja en Tandera
LinkFinder se ejecuta en la fase de analyze de recon_web_lite y recon_web_full, contra el JavaScript que katana recuperó durante el crawl. Se sitúa junto a jxscout y retirejs, que leen los mismos bundles para cosas distintas — secretos y dependencias vulnerables, respectivamente.
Los endpoints que recupera vuelven al corpus de URLs y se convierten en objetivos de sondeo.
Uso en un pentest
Las rutas de admin se envían a todo usuario. Un front-end que oculta un panel de admin no renderizando el botón sigue conteniendo la ruta. /api/v2/admin/impersonate en un bundle servido a usuarios anónimos merece probarse de inmediato — si no está autorizado en el lado del servidor, ese es tu crítico.
Espera ruido. La regex casa con cadenas parecidas a paths, así que obtendrás fragmentos de CSS, tipos MIME y números de versión. Filtra, luego sondea:
python linkfinder.py -i https://example.com -d -o cli
| grep -E '^/' | sort -u
| sed 's|^|https://example.com|' | httpx -silent -status-code Los source maps son mejores cuando existen. Si se sirve app.js.map, obtienes las fuentes originales en lugar de la salida minificada. Comprueba siempre.