Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
Herramientas/GitHubGitHub/icemoonhsv/tats
Seguridad WebPruebas de PenetraciónGestión de Identidad y Acceso (IAM)AutenticaciónAnálisis de Registros
GitHubicemoonhsv/tats

TATS

Analiza y rastrea tokens de OAuth 2.0, OIDC y Microsoft Entra ID desde capturas de Burp, mitmproxy o Chrome DevTools. Visualiza los ciclos de vida de los tokens, detecta scopes riesgosos y exporta tokens para su repetición mediante un panel interactivo.

Ver Repositorio
7128hace 16 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

TATS — Sistema de Análisis y Seguimiento de Tokens

Rastrea tokens de OAuth 2.0, OIDC y Microsoft Entra ID a través del tráfico de red capturado. Ingiere exportaciones XML de Burp Suite, archivos de flujo de mitmproxy o transmisiones en vivo del Protocolo Chrome DevTools en una única base de datos SQLite, y luego sirve un panel web interactivo para filtrar tokens, recorrer intercambios, detectar ámbitos riesgosos, exportar tokens para replay y visualizar ciclos de vida de tokens como gráficos Mermaid.

Estado: TATS es estable para uso personal / de engagement. Optimizado para el ecosistema Microsoft 365 / Entra (FOCI, BroCI/NAA, cookies de sesión ESTSAUTH, enriquecimiento de entrascopes.com) pero funciona contra cualquier tráfico OAuth/OIDC más o menos estándar.


Por qué existe

Cuando proxeas una sesión larga de Microsoft 365 o Azure a través de Burp / mitmproxy, la captura resultante es enorme y la mayoría de las herramientas:

  • Solo muestran un token a la vez (la extensión JWT de Burp), o
  • No siguen el dialecto OAuth de Microsoft (FOCI, BroCI, cookies ESTSAUTH), o
  • No rastrean tramas WebSocket, donde Teams / Skype / SignalR envían tokens, o
  • No te dicen qué tokens siguen siendo válidos en este momento.

Esta herramienta extrae cada token de acceso / refresco / id observado, les asigna huellas para poder correlacionar el mismo token entre fuentes, decodifica las claims JWT, resuelve los GUID de cliente / recurso de Microsoft contra entrascopes.com, y renderiza todo el panorama como un único panel — incluyendo una vista de cadenas de refresh-token que sigue los intercambios entre aplicaciones de FOCI y la emisión de tokens de aplicaciones anidadas de BroCI.

Este proyecto está destinado principalmente a fines de investigación y educación, pero proporciona opciones como la vista previa de comandos y funciones de exportación de tokens que pueden servir de apoyo a algunas herramientas ofensivas.


Características

Núcleo

  • Tres fuentes de ingesta en una sola herramienta:
    • ingest — exportación XML "Save items" de Burp Suite
    • mitm — archivo de flujo .mitm de mitmproxy (tramas HTTP y WebSocket)
    • cdp — conexión en vivo a Chrome / Edge mediante el Protocolo DevTools (en tiempo real, captura tramas HTTP y WebSocket descifradas por TLS sin una CA de proxy; rastrea cada pestaña existente Y cada pestaña abierta durante la ejecución mediante auto-attach a nivel de navegador)
  • Un único almacén SQLite canónico del que lee el panel. Cada pasada de ingesta puede ejecutarse con --append para fusionarse en una base de datos existente; los tokens se hacen upsert (el conteo de usos + el tiempo de vida observado se acumulan), los eventos y los intercambios se añaden, y el source_tag de la fila registra cada pasada que ha visto el token.
  • Panel web en vivo servido por un servidor HTTP de la stdlib. Sondea la base de datos cada 5 segundos y vuelve a renderizar cuando los datos subyacentes cambian — así una captura CDP en ejecución actualiza el panel casi en tiempo real.
  • Sin dependencias propietarias para las rutas principales. La ingesta de Burp, la capa de base de datos, la interfaz web y el attach CDP son todos solo stdlib. La importación de mitmproxy es la única dependencia opcional (pip install mitmproxy).

Clasificación y enriquecimiento de tokens

  • Claves del cuerpo OAuth (access_token, refresh_token, id_token) y heurísticas de nombres de cookies determinan el tipo de token.
  • Cookies de sesión de Microsoft (ESTSAUTH, ESTSAUTHPERSISTENT, ESTSAUTHLIGHT, SignInStateCookie) se reconocen explícitamente como tokens equivalentes a refresh (de lo contrario serían mal clasificados por la pista genérica de cookie "auth").
  • Claims JWT (cabecera + payload) decodificadas y almacenadas textualmente — nunca truncadas.
  • Microsoft FOCI (Family of Client IDs) detectado mediante el campo foci en las respuestas del endpoint de token.
  • Microsoft BroCI / Nested App Authentication detectado mediante brk_client_id, brk_redirect_uri y esquemas de redirección brk-<guid>:// en el cuerpo de la solicitud.
  • Flag opcional --enrich obtiene firstpartyscopes.json y resources.json de https://entrascopes.com/ y resuelve los GUID de appid / azp / aud en nombres amigables con enlaces clicables.

Tarjetas del panel

  • Mosaicos de resumen — conteos de tokens, hosts, intercambios (con llamados a FOCI / BroCI) y un indicador de estado de enriquecimiento.
  • Usuarios — agrupación de tokens por upn / preferred_username / unique_name / email / name, con fallback a sub@iss o oid, y mostrando por separado los grupos de solo aplicación e identidad desconocida. Cada fila de identidad muestra una insignia de capturas cuando el usuario aparece en ≥2 source_tags (supervivencia entre capturas, la señal de investigación principal de --append) más un lapso first_seen → last_seen y un botón de timeline que resalta cada token de ese usuario en la pestaña de diagrama de secuencia.
  • Validez de tokens — conteos de tokens de acceso actualmente válidos vs expirados, estado de expiración de refresh-token (con "expiración desconocida" para tokens opacos), y una lista top-3 de "próximos a expirar" con auto-refresco cada 30 segundos.
  • Clientes — cada aplicación distinta (appid / azp / client_id del cuerpo del formulario / brk_client_id / brk_nested_id) que ha aparecido en intercambios, con insignias de FOCI / brokerable / broker / anidada.
  • Audiencias — cada claim aud observada, resuelta a nombres de recursos de entrascopes donde sea posible.
  • Inquilinos — valores tid distintos con conteos de tokens / usuarios / aplicaciones.
  • Hosts — eventos, destinatarios bearer distintos, emisores distintos y conteos de intercambios por host.
  • Ámbitos y roles privilegiados — verifica el scp / scope / roles de cada token contra una lista de vigilancia curada de permisos de Microsoft Graph de alto impacto y ámbitos de recursos de Azure.
  • Desajustes de audiencia / host — marca cada par (token, host) donde el token se usó en un host que no concuerda con su claim aud (sugiere fuga o mal uso de credenciales).
  • Métodos de autenticación (amr) — distribución de pwd / mfa / pop / smartcard.
  • Características de seguridad — marca Continuous Access Evaluation (xms_cc=CP1), vinculación proof-of-possession (claim cnf, con detección de kid compartido entre audiencias), requisitos de step-up auth (acrs) y el nivel de contexto de autenticación acr. Cada fila es clicable y filtra la pestaña Tokens para mostrar solo los tokens que llevan ese marcador.
  • Cadenas de refresh-token — recorre las aristas de intercambio para identificar linajes de rotación, longitud de cadena más larga y refresh tokens inactivos. Cada cadena muestra una columna Δ scopes (ámbitos añadidos / eliminados entre saltos, con el diff completo por salto al pasar el cursor) y marca las cadenas donde un ámbito añadido coincide con la lista de vigilancia de ámbitos privilegiados con una insignia ⚠ priv — la señal de investigación de expansión de privilegios al estilo FOCI / BroCI.
  • Fuentes — conteos de tokens por source_tag para que puedas ver cuántas filas provinieron de cada pasada de ingesta.

Pestañas Tokens / Exchanges

  • Haz clic en el encabezado de una columna para ordenar.
  • Las casillas de selección múltiple controlan una barra de herramientas:
    • Highlight in Graph — acento amarillo en los nodos seleccionados.
    • Isolate in Graph — redibuja el diagrama mostrando solo los tokens seleccionados más los tokens con los que intercambian.
    • Show in Sequence — diagrama de secuencia enfocado para el/los token(s) seleccionado(s).
  • Haz clic en una fila para expandir un panel en línea con la cabecera + payload JWT completos (JSON sin procesar), todos los eventos, intercambios relacionados, botones de exportación listos para replay (raw / Bearer / curl / JSON / caché de tokens de roadtx) y un bloque de vista previa de comandos con fragmentos para copiar y pegar de roadtx describe, roadtx auth, curl, requests de Python y Invoke-RestMethod de PowerShell.
  • Filtros: chips de tipo (access / refresh / id / unknown), chips de formato (jwt / opaque), menú desplegable used / unused, menú desplegable de validez (any / valid / expired / unknown expiry), solo FOCI, solo BroCI, has-app-match, has-resource-match, más una búsqueda de texto libre en fp / sample / claims / host / app / resource / source_tag / user.
  • Exportación CSV / JSON de las filas actualmente filtradas + ordenadas.
  • Persistencia en el hash de la URL — la pestaña activa y cada estado de filtro se serializan en el hash de la URL, para que los enlaces a vistas filtradas específicas sean compartibles.

Soporte de WebSocket

  • Las capturas de mitmproxy y CDP preservan cada payload de trama WebSocket de texto / binaria. El contenido de las tramas se escanea en busca de tokens con el mismo recorredor de JSON / formulario / JWT sin procesar que maneja los cuerpos HTTP.
  • Los tokens encontrados en tramas generan eventos con rol ws-frame-sent / ws-frame-received, origen ws[body_json[<key>]] y un ws_session_id que agrupa todas las tramas dentro de una conexión WebSocket.
  • El handshake se captura como un evento HTTP normal, por lo que las cookies / tokens bearer transportados hacia el upgrade también se rastrean.

Privacidad

  • La base de datos almacena huellas SHA-256 (primeros 12 caracteres hex) y un prefijo de 12 caracteres de cada token observado. Las cadenas de token completas nunca salen del archivo de entrada.

  • El contenido de las claims JWT decodificadas (cabecera + payload, incluyendo oid, sub, upn, email, tid, listas de ámbitos, etc.) se almacena textualmente por defecto porque es el objetivo central del análisis. Trata la base de datos y cualquier URL de panel compartida como sensibles siempre que haya JWTs presentes.

  • --redact-claims (disponible en ingest, mitm y cdp) reemplaza los valores de claims listados con marcadores de posición hash estables antes de que lleguen a la base de datos. La lista de campos predeterminada cubre sub, oid, upn, email, name, unique_name, preferred_username, emails, mail, ipaddr, given_name, family_name. Pasa una lista explícita separada por comas (p. ej. --redact-claims sub,upn,oid) para sobrescribir la predeterminada. La misma entrada siempre se asigna al mismo marcador de posición, por lo que la agrupación de Usuarios / Inquilinos del panel sigue funcionando sin revelar el usuario.

  • --store-tokens (disponible en ingest, mitm y cdp, desactivado por defecto) opta por escribir la cadena de token completa en la base de datos para que el panel pueda ofrecer:

    • Acciones Copy raw / Copy Bearer / Copy curl.
    • Descargar JSON del token (raw + claims + eventos observados).
    • Copiar / Descargar como caché de tokens de roadtools (coloca el archivo en .roadtools_auth y cualquier subcomando de roadtx lo tomará).
    • Un bloque de Command preview por token que pre-rellena las invocaciones de replay más comunes — roadtx describe, roadtx auth, curl, requests de Python, Invoke-RestMethod de PowerShell — usando las claims reales de tid, y del token.

Instalación

Requisitos

  • Python 3.10+ (usa sintaxis de tipos compatible con match-statement y dataclasses modernos). Probado en 3.12.
  • Sin paso de compilación. Clona el repositorio y ejecuta python -m tats directamente.

Dependencias opcionales

NecesidadInstalación
Subcomando mitmpip install mitmproxy
Captura en vivo desde Chrome / EdgeNinguna — usa un cliente WebSocket de la stdlib
--enrich (entrascopes.com)Ninguna — usa urllib.request

Instalación rápida

Ejecutar desde un checkout (sin instalación):```bash git clone tats cd tats python -m tats --help

root@kitploit:~
El HTML / CSS / JS del panel se encuentran en `tats/static/` y se cargan
en la primera importación, por lo que no se requiere un paso de compilación — simplemente ejecuta el módulo
directamente desde el checkout.

**Instalar como paquete (te proporciona el script de consola `tats`):**```bash
pip install .                # core only
pip install .[mitm]          # + mitmproxy flow file support
pip install .[test]          # + pytest for the test suite
pip install .[all]           # everything

Después de instalar, puedes llamar a la herramienta por su nombre corto:```bash tats ingest engagement.xml -o tokens.db --enrich tats serve tokens.db

root@kitploit:~
Si solo necesitas las rutas de Burp / CDP, el archivo es completamente autónomo
con la biblioteca estándar de Python — no se requiere instalación ni extras.

---

## Inicio rápido

**Analizar una exportación XML de Burp y abrir el panel:**```bash
tats ingest examples/fixture.xml -o tokens.db --enrich
tats serve tokens.db

Combinar una captura de Burp con un archivo de flujo de mitmproxy en una sola base de datos:```bash tats ingest engagement.xml -o tokens.db --enrich tats mitm chat-session.mitm -o tokens.db --enrich --append tats serve tokens.db

root@kitploit:~
**Captura en vivo desde un navegador Chrome (ve HTTP descifrado por TLS + tramas WebSocket, no se necesita CA de proxy) — dejando que la herramienta lance el navegador:**```bash
# Terminal 1 — auto-launch Chrome / Edge / Chromium / Brave
tats cdp -o tokens.db --enrich --launch-chrome

# Terminal 2 — open the dashboard (auto-refreshes every 5 s)
tats serve tokens.db

El navegador lanzado se termina y su perfil temporal se elimina cuando pulsas Ctrl-C en el comando cdp.

Si prefieres conectarte a un navegador que ya está en ejecución, inícialo con --remote-debugging-port=9222 --user-data-dir=/tmp/cdp-profile y ejecuta cdp sin --launch-chrome.

Sanitizar una base de datos antes de compartirla (redacción de PII):```bash tats ingest engagement.xml -o tokens.db
--enrich --redact-claims

every sub / oid / upn / email / name / unique_name / preferred_username

(and a few related claims) is replaced with a stable hash placeholder

root@kitploit:~
La redacción es estable en cuanto al contenido: valores idénticos se asignan a marcadores de posición idénticos, por lo que la agrupación por usuario del panel sigue funcionando sin mostrar el usuario.

La cabecera del panel muestra `live · updated <time>` una vez que los datos empiezan a fluir.

---

## Subcomandos

Cada subcomando acepta `--help` para obtener la lista canónica de opciones. Las notas a continuación explican *cuándo* y *cómo* recurrirías a cada uno.

### Flags globales

Estos se aplican a todos los subcomandos y van *antes* del nombre del subcomando:

* `-v` / `--verbose` — añade líneas de log INFO (estado del enriquecimiento, recuentos de redacción de la ingesta). `-vv` añade DEBUG (cada petición al servidor).
* `-q` / `--quiet` — silencia las líneas de log INFO; solo aparecen WARNINGs y ERRORs. La línea final de salida al usuario (p. ej. `wrote tokens.db (...)`) y cualquier diagnóstico `error: …` no se ven afectados, así que seguirás viendo lo importante desde un script.
* `--version` — imprime la versión de la herramienta y sale.

### `ingest` — Exportación XML de Burp Suite

Lee un XML de "Save items" (Proxy → HTTP history → clic derecho → Save items). Los archivos de proyecto binarios `.burp` **no** son compatibles — el formato es propietario e inestable entre versiones de Burp; exportar los elementos que te interesan es el flujo de trabajo soportado.```bash
tats [-v|-q] ingest <burp_items.xml> -o tokens.db \
    [--enrich] [--enrich-cache-dir DIR] [--no-enrich-cache] \
    [--append] [--source-tag TAG] [--no-progress] \
    [--redact-claims [CLAIMS]] [--no-serve-hint]

Ejemplos:```bash

fresh DB, with Microsoft enrichment

tats ingest burp.xml -o tokens.db --enrich

add another Burp export to an existing DB without losing the first one

tats ingest day2.xml -o tokens.db --append
--source-tag burp:day2

root@kitploit:~
### `mitm` — archivo de flujo `.mitm` de mitmproxy

Lee un archivo de flujo producido por `mitmdump`, `mitmproxy` o `mitmweb`. Esta
es la única ruta de ingesta que captura **tramas WebSocket** sin una sesión
de navegador en vivo — los archivos de flujo preservan cada payload de trama de texto / binaria.```bash
tats [-v|-q] mitm <flow_file.mitm> -o tokens.db \
    [--enrich] [--enrich-cache-dir DIR] [--no-enrich-cache] \
    [--append] [--source-tag TAG] [--no-progress] \
    [--redact-claims [CLAIMS]] [--no-serve-hint]

Requiere pip install mitmproxy. La herramienta emitirá un error claro si falta el paquete.

Captura un archivo de flujo con mitmproxy:```bash mitmdump -w session.mitm

... drive the browser ...

Ctrl-C to stop

tats mitm session.mitm -o tokens.db --enrich

root@kitploit:~
### `cdp` — conexión en vivo a Chrome / Edge

Se conecta a un navegador de la familia Chromium en ejecución a través del DevTools Protocol
y transmite eventos `Network.*` a la base de datos. Captura solicitudes /
respuestas HTTP (con cuerpos obtenidos mediante `Network.getResponseBody`), actualizaciones
de WebSocket y cada frame de WebSocket en ambas direcciones. El búfer se vacía a
la base de datos cada N eventos (por defecto 25), por lo que el sondeo de 5 segundos del
dashboard detecta nuevos tokens en cuestión de segundos desde que el navegador realiza la
solicitud.```bash
tats [-v|-q] cdp [-o tokens.db] \
    [--host 127.0.0.1] [--port 9222] [--target ID] \
    [--launch-chrome [PATH]] [--flush-every N] \
    [--enrich] [--append] [--redact-claims [CLAIMS]]

Permitir que la herramienta lance el navegador (--launch-chrome)```bash

auto-detect Chrome / Edge / Chromium / Brave

tats cdp -o tokens.db --launch-chrome

explicit path (useful for non-default installs / sandboxed builds)

tats cdp -o tokens.db
--launch-chrome /opt/google/chrome-canary/chrome

root@kitploit:~
El navegador lanzado se ejecuta con `--remote-debugging-port=<port>` y un
user-data-dir temporal nuevo. Cuando detienes el comando `cdp` (Ctrl-C),
el navegador se termina y el perfil temporal se elimina.

### Adjuntarse a un navegador ya en ejecución

Inicia el navegador tú mismo, con un perfil nuevo, y luego ejecuta `cdp` sin
`--launch-chrome`:```bash
# Windows
"C:\Program Files\Google\Chrome\Application\chrome.exe" ^
    --remote-debugging-port=9222 ^
    --user-data-dir="%TEMP%\cdp-profile"

# macOS
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
    --remote-debugging-port=9222 --user-data-dir=/tmp/cdp-profile

# Linux
google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/cdp-profile

Un user-data-dir separado evita adjuntarse a un perfil personal y evita que el navegador en ejecución rechace el flag de depuración.

Por defecto, cdp se adjunta a nivel del navegador y rastrea cada pestaña que existe cuando se inicia Y cada pestaña abierta durante la ejecución (window.open, Ctrl-click, botón de nueva pestaña). Todas las pestañas comparten el único WebSocket a través del multiplexor de sesiones del protocolo plano de CDP, por lo que abrir o cerrar pestañas mientras la captura está en ejecución es totalmente compatible. Cada adjuntar / desadjuntar de pestaña imprime una nota de una línea en stderr a nivel INFO.

Si prefieres fijarte a una sola pestaña y que la conexión termine cuando esa pestaña se cierre, lista los objetivos disponibles:```bash curl http://127.0.0.1:9222/json/list

root@kitploit:~
…luego pasa `--target <id>`.

Pulsa Ctrl-C para detener. La cola de cualquier búfer en vuelo se vuelca a la
base de datos antes de que el proceso finalice.

### `serve` — panel web

Lee una base de datos existente y sirve una interfaz web de página única en
`127.0.0.1:8765`. El servidor es de solo lectura; nunca escribe en la
base de datos, por lo que es seguro ejecutarlo junto a una ingesta `cdp` o `mitm`
en curso.```bash
tats serve <tokens.db> \
    [--host 127.0.0.1] [--port 8765] [--no-browser]

Ejemplos:```bash

default — opens a browser tab automatically

tats serve tokens.db

bind to a different port without auto-launching the browser

tats serve tokens.db --port 9000 --no-browser

(do this only on a trusted network — no auth)

tats serve tokens.db --host 0.0.0.0

root@kitploit:~
> **Advertencia:** la interfaz web expone payloads JWT decodificados (claims), huellas de tokens, la línea de tiempo de actividad y gráficos Mermaid a cualquiera que pueda alcanzar la dirección de bind. Si se ingirió con `--store-tokens`, también expone los **tokens en bruto completos** a través de `/api/token/<fp>` y `/api/export?fps=...`. **No hay autenticación**. Mantenga `--host` en `127.0.0.1` a menos que se pretenda lo contrario específicamente.

#### Exportación lista para replay

Cuando la base de datos se construyó con `--store-tokens`, cada token expandido en la pestaña Tokens obtiene una fila de acciones de un clic:

* **Copy raw** — la cadena completa del token al portapapeles.
* **Copy Bearer header** — `Authorization: Bearer <token>`, listo para pegar.
* **Copy curl example** — un one-liner que apunta al `aud` del token (o su host emisor) con la cabecera bearer adjunta.
* **Download JSON** — un archivo JSON de un solo token que contiene raw, claims, eventos observados e intercambios.
* **Copy as roadtx** — la forma JSON de una caché de tokens de roadtools (`tokenType`, `accessToken` / `refreshToken` / `idToken`, `expiresOn`, `tenantId`, `_clientId`, `resource`, `foci`, `scope`). Pegue directamente en un archivo `.roadtools_auth`.
* **Download .roadtools_auth** — el mismo payload, descargado como archivo. Renómbrelo a `.roadtools_auth` (o páselo vía `roadtx <cmd> --tokens-file`) y cualquier subcomando de roadtx lo recogerá.

La barra de herramientas de la pestaña Tokens también tiene **Export selected for replay**, que llama a `/api/export?fps=fp1,fp2,...` y descarga un único documento JSON con hasta 200 tokens (raw, claims, eventos) en un solo paquete. Sin `--store-tokens`, los mismos botones muestran una sugerencia para re-ingerir antes de que la exportación lista para replay sea posible.

#### Vista previa de comandos

Cada token expandido también tiene un bloque colapsable **Command preview** que pre-rellena las invocaciones más comunes de replay / inspección usando los claims reales del token (y el valor en bruto completo cuando `--store-tokens` está activado). Cada fragmento tiene un botón Copy de un clic. La mezcla exacta depende del tipo de token:

* **Cualquier JWT:** `roadtx describe -t '<token>'` (decodificar sin red).
* **Refresh tokens:**
  * `roadtx auth --refresh-token '...' -c <client_id> -t <tenant_id>` — intercambiar un refresh token por access tokens nuevos.
  * `curl -X POST .../oauth2/v2.0/token` — el equivalente OAuth para usuarios que no ejecutan roadtx.
* **Access / id / tokens desconocidos:**
  * `curl -H 'Authorization: Bearer ...' '<aud>'`
  * Python `requests.get(...)` con la cabecera bearer establecida.
  * PowerShell `Invoke-RestMethod` con la misma cabecera.
* **Siempre:** el objeto JSON para colocar en `.roadtools_auth`.

Cuando `--store-tokens` está desactivado, los fragmentos se renderizan con `<TOKEN>` como marcador de posición para que el panel siga siendo útil como referencia de documentación.

---

## La interfaz web en detalle

### Navegación superior

`Summary | Tokens | Exchanges | FOCI | BroCI | Graph | Sequence`

Cada pestaña se renderiza de forma independiente a partir de la misma instantánea en memoria de `/api/data`. Cambiar de pestaña es instantáneo; los diagramas de grafo y secuencia se re-renderizan bajo demanda y respetan la selección actual en la pestaña Tokens.

### Summary

Mosaicos de estadísticas en la parte superior (tokens / access / refresh / id / unknown / used / unused / events / exchanges / FOCI exchanges / BroCI exchanges / hosts) seguidos de una cuadrícula de tarjetas descritas en [Features → Dashboard cards](#dashboard-cards).

Haga clic en cualquier fila de cualquier tarjeta para saltar a una pestaña Tokens pre-filtrada — por ejemplo, hacer clic en una fila de tenant filtra el inventario a los tokens que llevan ese `tid`.

### Tokens

Inventario filtrable y ordenable. La selección múltiple controla los botones de highlight / isolate / sequence. La expansión de fila muestra el JWT decodificado completo (header + payload como JSON en bruto), cada evento que involucra ese token, y cada intercambio donde fue una entrada o salida.

### Exchanges

Lista ordenable de cada intercambio token-por-token detectado — rotaciones de refresh-token, cross-redemptions de FOCI, e intercambios de apps anidadas de BroCI. La columna BroCI muestra el broker + los client IDs anidados lado a lado con la evidencia que desencadenó la detección.

### FOCI

Dos tablas: cada refresh token etiquetado con una familia FOCI (actualmente Microsoft solo emite `"1"`), y cada intercambio cuya respuesta llevaba el campo `foci`.

### BroCI

Los intercambios de Nested App Authentication. Para cada uno: la app broker (`brk_client_id`), el cliente anidado (`client_id`), la evidencia que desencadenó la detección (`brk_client_id`, `brk_redirect_uri`, URI de redirección `brk-<guid>://`), y las huellas de los tokens de entrada / salida.

### Graph

`flowchart LR` de Mermaid de las relaciones token ↔ servicio. Los refresh tokens se dibujan como cilindros, los access / id tokens como estadios. Las aristas muestran emisión, presentación, intercambio y rotación. El resaltado (desde la pestaña Tokens) añade un acento amarillo; el aislamiento re-renderiza el grafo con solo los tokens seleccionados y los tokens con los que intercambian.

### Sequence

Diagrama de secuencia Mermaid de cada evento en orden de captura. Seleccionar un solo token muestra solo su secuencia; seleccionar varios mantiene la vista completa pero marca con estrella los tokens seleccionados. Límite máximo de eventos configurable (por defecto 200; los diagramas de secuencia Mermaid se vuelven ilegibles pasados unos cientos de mensajes).

---

## Soporte específico de Microsoft

### Family of Client IDs (FOCI)

Microsoft permite que un refresh token emitido para una app de una "familia" sea canjeado en el endpoint de token por **cualquier otra app** de la misma familia. La herramienta detecta FOCI en el tráfico analizando el JSON de respuesta del endpoint de token en busca de un campo `foci` (actualmente siempre `"1"` para la única familia conocida). Los refresh tokens emitidos en dicha respuesta se etiquetan con el id de familia y se muestran en la pestaña dedicada **FOCI**.

Si `--enrich` está habilitado, la columna de app del inventario también muestra el flag `foci: true/false` de `firstpartyscopes.json` — tenga en cuenta que esto puede discrepar con la detección en el tráfico (el dataset de entrascopes a veces es conservador). El campo `foci` en el tráfico es siempre la señal autoritativa.

### Brokered Client Init / Nested App Authentication (BroCI / NAA)

Los complementos de Office, las apps de Teams y el Azure Portal usan NAA para adquirir tokens para un cliente anidado a través de una app broker. La herramienta detecta esto en el lado de la petición mediante:
* el parámetro de formulario `brk_client_id` (GUID de la app broker),
* el parámetro de formulario `brk_redirect_uri` (URI de redirección real del broker),
* un `redirect_uri` de la forma `brk-<guid>://...` (donde `<guid>` es el broker).

El claim `appid` / `azp` del access token resultante es el cliente anidado; el broker solo aparece en el tráfico — nunca como claim JWT. El dashboard muestra ambos lados claramente.

### Cookies de sesión `ESTSAUTH`

`ESTSAUTH`, `ESTSAUTHPERSISTENT`, `ESTSAUTHLIGHT` y `SignInStateCookie` son cookies de sesión de Microsoft Entra que no viajan en `Authorization: Bearer` pero son usadas por el navegador para acuñar nuevos access tokens mediante flujos de autenticación silenciosa. La herramienta las etiqueta como `refresh` (su rol funcional) en lugar de dejar que la regla genérica de subcadena `auth` las clasifique erróneamente como `access`.

### Enriquecimiento de entrascopes.com (`--enrich`)

Obtiene y cachea `firstpartyscopes.json` (~2.8 MB; 504 apps first-party con su flag FOCI, URIs de redirección, scopes y capacidad de broker) y `resources.json` (~170 KB; más de 1,750 mapeos de recurso → nombre para mostrar) desde <https://entrascopes.com/>. La caché vive en:

| Variable | Por defecto |
|---|---|
| `$TATS_CACHE` | (máxima prioridad; `$BURP_TOKEN_TRACKER_CACHE` se acepta como fallback para migración de una release) |
| `$XDG_CACHE_HOME/tats` | (Linux/macOS) |
| `%LOCALAPPDATA%\tats\cache` | (Windows) |
| `~/.cache/tats` | (fallback) |

El TTL es de 7 días. Use `--no-enrich-cache` para forzar un re-fetch. La caché se reutiliza como fallback obsoleto cuando la herramienta se ejecuta sin conexión.

Cuando `--enrich` está activado, cada GUID de `appid` / `azp` / `client_id` y cada claim `aud` que sea GUID o URL se resuelve a un nombre amigable con un enlace clicable `https://entrascopes.com/?appId=<guid>`.

---

## Arquitectura

### One-shot: archivo → DB → interfaz web```
  burp.xml ─┐
   .mitm   ─┼─→ Tracker ─→ ingest_to_db ─→ tokens.db ─→ Store ─→ /api/data ─→ dashboard
   CDP WS  ─┘                  ▲                                       │
            (live, repeated)   └───── --append upserts on every flush ─┘

Cada ruta de origen produce el mismo objeto Tracker. ingest_to_db lo convierte en filas de la base de datos. Store lee la base de datos para el servidor HTTP, que expone JSON a través de /api/data, /api/meta, /api/token/<fp>, /api/export, /api/graph y /api/sequence.

Esquema de base de datos (v4)

  • tokens (clave primaria fp) — huella, prefijo de muestra, tipo, formato, tiempo de vida observado, cabecera / payload JWT como JSON, campos de enriquecimiento, campos derivados (user_identity, exp_unix, tenant_id, scopes_text), source_tag separado por comas, raw (cadena de token completa, NULL a menos que se ingiera con --store-tokens) y security_features (JSON compacto que describe los marcadores CAE / PoP / step-up detectados — véase la tarjeta Security features). Las bases de datos v2 / v3 más antiguas se migran automáticamente al reabrirse en modo append: v2 → v3 añade la columna raw anulable; v3 → v4 añade la columna security_features anulable y la rellena desde el jwt_payload_json almacenado de cada token en la primera apertura. Las filas preexistentes mantienen ambas columnas con sus valores anteriores.
  • events — cada interacción de token observada: petición / respuesta HTTP o frame WebSocket. Roles: issued / returned / presented / used / exchanged-in / ws-frame-sent / ws-frame-received. Lleva ws_session_id para agrupar frames dentro de una conexión.
  • exchanges — cuando una petición con token a un endpoint de token produjo nuevos tokens en su respuesta. Registra metadatos FOCI / BroCI.
  • exchange_inputs, exchange_outputs — huellas de token en cada lado de cada intercambio.
  • hosts — etiquetas host:port distintas.
  • meta — versión del esquema, lista de fuentes, generated_at, last_modified (usado por el sondeo en vivo del dashboard), recuentos.

Etiquetado de fuentes y modo append

Cada fila escrita en la BD lleva un source_tag — por defecto burp:<filename>, mitm:<filename> o cdp:<host>:<port>, pero sobrescribible mediante --source-tag. Cuando la misma huella es vista por más de una pasada de ingesta, el campo source_tag se acumula como una lista separada por comas, de modo que la tarjeta Sources del dashboard puede mostrar la procedencia de cada token.

--append conserva una BD existente y fusiona en ella mediante UPSERT para tokens (el recuento de usos + el tiempo de vida observado se acumulan, los tipos desconocidos se actualizan) e INSERT para eventos / exchanges (con sus números seq desplazados más allá del máximo existente, para que la línea temporal de actividad se mantenga monótona). La discrepancia de versión del esquema rechaza la fusión para prevenir la pérdida silenciosa de datos.

Actualizaciones en vivo

El endpoint /api/meta del servidor web devuelve la tabla meta (~200 bytes). El dashboard lo sondea cada 5 segundos y solo vuelve a obtener el /api/data completo cuando last_modified cambia. La ruta de ingesta cdp vuelca su tracker en memoria a la BD cada 25 eventos por defecto, por lo que la latencia de reloj de pared desde una petición del navegador hasta una actualización del dashboard es típicamente < 10 segundos.


Limitaciones

  • Los archivos de proyecto .burp de Burp no son compatibles. Use Save items para producir el XML que consume la herramienta.
  • Sin gestión de CA de proxy. Esta herramienta no intercepta TLS por sí misma. Úsela aguas abajo de Burp / mitmproxy, o use la ruta CDP que ve tráfico descifrado por TLS desde dentro del navegador.
  • La conexión CDP cubre los targets de página de nivel superior. Los iframes fuera de proceso (OOPIFs) y los workers dedicados no se conectan automáticamente de forma recursiva, por lo que los eventos que fluyen a través de esos tipos de target pueden perderse. Para los flujos de Microsoft / OAuth en torno a los cuales está construida esta herramienta, la conexión de página de nivel superior captura todo lo que importa.
  • Sin verificación de firma en los JWT. La herramienta decodifica las claims para mostrarlas; la comprobación de firmas, alg=none y los ataques de confusión de claves quedan fuera del alcance. Use un auditor de JWT dedicado para eso.
  • Falsos positivos de tokens opacos. La heurística de "¿es esto un token?" trata cualquier cadena segura para URL de 20+ caracteres en contextos con forma de OAuth como un token. Los IDs aleatorios largos pueden marcarse incorrectamente. Los tokens cuyo tipo no puede inferirse acaban como unknown y se ocultan por defecto a menos que se establezca --include-unknown en el flag más antiguo (solo para Burp).
  • --enrich realiza peticiones HTTP salientes a https://entrascopes.com/. Omita el flag si su entorno no lo permite.
  • La interfaz web no tiene autenticación. Vincúlela a localhost a menos que haya puesto otra capa de autenticación delante.

Solución de problemas

SíntomaCausa probableSolución
error: could not parse <file> as XMLIntentar ingerir un archivo de proyecto .burp binarioEn Burp: Proxy → HTTP history → seleccionar elementos → clic derecho → Save items
error: no <item> elements foundEl XML no fue producido por Save items de BurpReexportar desde Burp; el elemento raíz debería ser <items>
error: cannot append to DB with schema_version 1La BD fue creada por una compilación anteriorEliminar la BD y volver a ingerir las fuentes originales; la migración de esquema intencionadamente no es automática
error: the 'mitm' source needs the mitmproxy Python packagemitmproxy no está instaladopip install mitmproxy
error: cannot reach Chrome at 127.0.0.1:9222Chrome no se inició con --remote-debugging-portVéase el conjuro de lanzamiento en cdp subcommand
CDP se conecta pero no fluyen eventosLa página aún no ha realizado ninguna petición de red, o toda la actividad está en un OOPIF / worker (no conectado automáticamente)Recargue la página; confirme que las pestañas se registraron (busque líneas de log tab attached: … en stderr)
no browser-level webSocketDebuggerUrl at /json/versionLa versión de Chrome es demasiado antigua para CDP a nivel de navegador, o devolvió la forma incorrectaActualice Chrome, o pase --target <id> para usar la conexión heredada de una sola pestaña
target … has no webSocketDebuggerUrlOtro depurador (p. ej. la ventana de DevTools) ya está conectadoCierre DevTools, o conéctese a un target diferente
El dashboard muestra Failed to load /api/dataEl servidor no puede leer el archivo de base de datosCompruebe que la ruta de la BD es correcta, que el archivo es legible y que la versión del esquema coincide
Las actualizaciones en vivo dejan de llegarEl proceso cdp terminó o el volcado del búfer de red aún no se ha disparadoCompruebe la terminal de en busca de errores; reduzca para actualizaciones más ágiles

Desarrollo

Fixtures de prueba de humo

Hay dos constructores de fixtures en examples/:```bash

Burp XML fixture (HTTP-only, includes FOCI + BroCI exchanges)

python examples/make_fixture.py examples/fixture.xml tats ingest examples/fixture.xml -o tokens.db --enrich

mitmproxy flow fixture (HTTP + WebSocket frames carrying tokens)

python examples/make_mitm_fixture.py examples/fixture.mitm tats mitm examples/fixture.mitm -o tokens.db --enrich --append

root@kitploit:~
Después de ambas ejecuciones, `tokens.db` tiene 15 tokens (11 de Burp + 4 de
mitmproxy), 23 eventos incluyendo un evento de trama WebSocket, y 3
intercambios.

### Suite de pruebas```bash
pip install .[test]
pytest

La suite cubre la extracción de tokens, el análisis de JWT, la clasificación de cookies de sesión de Microsoft, la detección de FOCI / BroCI, el resumen de claims, la redacción de PII, la ruta de ingesta de XML de Burp con semántica UPSERT en modo append, y la ruta de ingesta de frames WebSocket de mitmproxy (omitida automáticamente cuando la dependencia opcional mitmproxy no está presente).```text $ pytest tests/ ============================= test session starts ============================= … ======================== 62 passed in 1.4s =================================

root@kitploit:~
### Ejecutar el servidor en primer plano```bash
tats serve tokens.db --no-browser

…y abre http://127.0.0.1:8765 manualmente. El servidor registra cada petición y cualquier error del manejador en stderr.

Estructura de archivos

RutaPropósito
tats/__init__.pyLa herramienta completa — parsers, capa de BD, servidor HTTP, cliente CDP; carga el dashboard desde tats/static/
tats/__main__.pyPunto de entrada para python -m tats; misma lógica que el script de consola tats instalado
tats/static/index.htmlEsqueleto HTML del dashboard con marcadores {{CSS}} / {{JS}}
tats/static/style.cssEstilos del dashboard — edítalos con tus herramientas CSS habituales
tats/static/app.jsLógica del dashboard — edítala con tus herramientas JS habituales (LSP / lint / formatter)
pyproject.tomlMetadatos de empaquetado, extras opcionales ([mitm], [test], [all]), punto de entrada de consola
LICENSEGNU General Public License v3
README.mdEste archivo
examples/Capturas sintéticas + scripts generadores de fixtures (ver examples/README.md)
examples/make_fixture.pyGenerador sintético de XML de Burp
examples/make_mitm_fixture.pyGenerador sintético de archivos de flujo de mitmproxy
examples/fixture.xmlFixture XML de Burp preconstruido
examples/fixture.mitmFixture de flujo de mitmproxy preconstruido
tests/Suite de pytest (ejecutar con pytest)

La estructura de archivo único es deliberada: la herramienta está pensada para ser leída, auditada y usada en investigaciones por cualquiera que tenga Python instalado. No hay configuración oculta, ni árbol de dependencias que evaluar, ni ninguna superficie más allá del propio archivo.

Mantener este README

Si cambias subcomandos, esquema, tarjetas del dashboard o la superficie de API pública (flags de CLI, endpoints /api/*), actualiza las secciones relevantes de este archivo en el mismo cambio. Las secciones con más probabilidad de quedar desactualizadas:

  • Features — al añadir fuentes de ingesta o tarjetas del dashboard
  • Subcommands — al cambiar flags
  • Microsoft-specific support — cuando cambia la lógica de detección
  • Architecture — cuando cambia el esquema o el flujo de actualización en vivo
  • Troubleshooting — cuando aparece un nuevo mensaje de error

Licencia

GNU General Public License v3.0 o posterior — texto completo en el archivo LICENSE en la raíz del repositorio. El código fuente del script incluye el encabezado corto estándar que apunta al mismo.

Puedes redistribuir y/o modificar la herramienta bajo los términos de la GPL v3 (o cualquier versión posterior, a tu elección). Se distribuye sin ninguna garantía; consulta la LICENSE para los términos completos.

Descargar herramienta
appid
aud
  • /api/export?fps=... devolviendo hasta 200 tokens (raw, claims, eventos, intercambios) en un único paquete JSON para herramientas posteriores.
  • Activar esto convierte la base de datos en una credencial al por mayor — cada byte necesario para reproducir cualquier sesión capturada está en ella. Combínalo con --redact-claims para limpiar la vista JWT decodificada, pero ten en cuenta que el token sin procesar aún lleva las claims sin redactar codificadas dentro de él. Cuando el flag está desactivado, el bloque de vista previa de comandos del panel aún se renderiza, solo que con <TOKEN> como marcador de posición para que funcione como referencia de sintaxis; los botones de exportación muestran una pista para re-ingerir.

    cdp
    --flush-every