Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
Ferramentas/GitHubGitHub/icemoonhsv/tats
Segurança WebTestes de PenetraçãoGerenciamento de Identidade e Acesso (IAM)AutenticaçãoAnálise de Logs
GitHubicemoonhsv/tats

TATS

Analise e rastreie tokens OAuth 2.0, OIDC e Microsoft Entra ID a partir de capturas do Burp, mitmproxy ou Chrome DevTools. Visualize ciclos de vida de tokens, detecte escopos de risco e exporte tokens para replay por meio de um painel interativo.

Ver Repositório
7128há 16 diasAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

TATS — Token Analysis and Tracking System

Rastreia tokens OAuth 2.0, OIDC e Microsoft Entra ID em tráfego de rede capturado. Ingere exportações XML do Burp Suite, arquivos de fluxo do mitmproxy ou streams ao vivo do Chrome DevTools Protocol em um único banco de dados SQLite, e então serve um dashboard web interativo para filtrar tokens, percorrer trocas, identificar escopos de risco, exportar tokens para replay e visualizar ciclos de vida de tokens como grafos Mermaid.

Status: TATS é estável para uso pessoal / em engajamentos. Otimizado para o ecossistema Microsoft 365 / Entra (FOCI, BroCI/NAA, cookies de sessão ESTSAUTH, enriquecimento entrascopes.com) mas funciona contra qualquer tráfego OAuth/OIDC razoavelmente padrão.


Por que existe

Quando você faz proxy de uma longa sessão do Microsoft 365 ou Azure através do Burp / mitmproxy a captura resultante é enorme e a maioria das ferramentas ou:

  • Mostra apenas um token por vez (extensão JWT do Burp), ou
  • Não segue o dialeto OAuth da Microsoft (FOCI, BroCI, cookies ESTSAUTH), ou
  • Não rastreia frames WebSocket, onde Teams / Skype / SignalR enviam tokens, ou
  • Não informa quais tokens ainda são válidos agora.

Esta ferramenta extrai cada access / refresh / id token observado, cria fingerprints para correlacionar o mesmo token entre fontes, decodifica claims JWT, resolve GUIDs de client / resource da Microsoft contra entrascopes.com, e renderiza o quadro completo como um único dashboard — incluindo uma visão de cadeia de refresh-token que segue trocas FOCI entre aplicativos e emissão de tokens de aplicativos aninhados BroCI.

Este projeto destina-se principalmente a fins de pesquisa e educação, mas fornece opções como pré-visualização de comandos e recursos de exportação de tokens que podem apoiar algumas ferramentas ofensivas.


Recursos

Núcleo

  • Três fontes de ingestão em uma ferramenta:
    • ingest — exportação XML "Save items" do Burp Suite
    • mitm — arquivo de fluxo .mitm do mitmproxy (frames HTTP e WebSocket)
    • cdp — anexação ao vivo ao Chrome / Edge via DevTools Protocol (em tempo real, captura frames HTTP e WebSocket descriptografados por TLS sem um proxy CA; rastreia cada aba existente E cada aba aberta durante a execução via auto-attach em nível de navegador)
  • Um armazenamento SQLite canônico do qual o dashboard lê. Cada passagem de ingestão pode ser executada com --append para mesclar em um banco de dados existente; tokens são upserted (contagem de usos + tempo de vida observado acumulam), eventos e trocas são anexados, e o source_tag da linha registra cada passagem que viu o token.
  • Dashboard web ao vivo servido por um servidor HTTP da stdlib. Consulta o banco de dados a cada 5 segundos e re-renderiza quando os dados subjacentes mudam — então uma captura CDP em execução atualiza o dashboard em quase tempo real.
  • Sem dependências proprietárias para os caminhos principais. Ingestão do Burp, a camada de banco de dados, a UI web e a anexação CDP são todas apenas stdlib. A importação do mitmproxy é a única dependência opcional (pip install mitmproxy).

Classificação e enriquecimento de tokens

  • Chaves de corpo OAuth (access_token, refresh_token, id_token) e heurísticas de nome de cookie determinam o tipo de token.
  • Cookies de sessão da Microsoft (ESTSAUTH, ESTSAUTHPERSISTENT, ESTSAUTHLIGHT, SignInStateCookie) são explicitamente reconhecidos como tokens equivalentes a refresh (caso contrário seriam mal classificados pela dica genérica de cookie "auth").
  • Claims JWT (header + payload) decodificadas e armazenadas literalmente — nunca truncadas.
  • Microsoft FOCI (Family of Client IDs) detectado via o campo foci nas respostas do token-endpoint.
  • Microsoft BroCI / Nested App Authentication detectado via brk_client_id, brk_redirect_uri, e esquemas de redirecionamento brk-<guid>:// no corpo da requisição.
  • Flag opcional --enrich busca firstpartyscopes.json e resources.json de https://entrascopes.com/ e resolve GUIDs de appid / azp / aud em nomes amigáveis com links clicáveis.

Cards do dashboard

  • Tiles de resumo — contagens de tokens, hosts, trocas (com destaques FOCI / BroCI), e um indicador de status de enriquecimento.
  • Usuários — agrupamento de tokens por upn / preferred_username / unique_name / email / name, com fallback para sub@iss ou oid, e exibindo buckets de identidade app-only e desconhecida separadamente. Cada linha de identidade mostra um badge de capturas quando o usuário aparece em ≥2 source_tags (sobrevivência entre capturas, o principal sinal de pesquisa do --append) mais um intervalo first_seen → last_seen e um botão timeline que destaca cada token daquele usuário na aba de diagrama de Sequência.
  • Validade de token — contagens de access tokens atualmente válidos vs expirados, status de expiração de refresh-token (com "expiração desconhecida" para tokens opacos), e uma lista top-3 "próximos a expirar" com auto-refresh de 30 segundos.
  • Clients — cada app distinto (appid / azp / client_id no corpo do formulário / brk_client_id / brk_nested_id) que apareceu em trocas, com badges FOCI / brokerable / broker / nested.
  • Audiences — cada claim aud observada, resolvida para nomes de recursos do entrascopes onde possível.
  • Tenants — valores tid distintos com contagens de token / usuário / app.
  • Hosts — eventos, destinatários bearer distintos, emissores distintos, e contagens de trocas por host.
  • Escopos e roles privilegiados — verifica o scp / scope / roles de cada token contra uma watchlist curada de permissões de alto impacto do Microsoft Graph e escopos de recursos do Azure.
  • Incompatibilidades de audience / host — sinaliza cada par (token, host) onde o token foi usado em um host que discorda de sua claim aud (sugere vazamento ou uso indevido de credencial).
  • Métodos de autenticação (amr) — distribuição de pwd / mfa / pop / smartcard.
  • Recursos de segurança — sinaliza Continuous Access Evaluation (xms_cc=CP1), vinculação proof-of-possession (claim cnf, com detecção de kid compartilhado entre audiences), requisitos de step-up auth (acrs), e o nível de contexto de autenticação acr. Cada linha é clicável e filtra a aba Tokens para apenas os tokens que carregam aquele marcador.
  • Cadeias de refresh-token — percorre arestas de troca para identificar linhagens de rotação, comprimento da cadeia mais longa, e refresh tokens ociosos. Cada cadeia mostra uma coluna Δ scopes (escopos adicionados / removidos entre hops, com o diff completo por hop no hover) e sinaliza cadeias onde um escopo adicionado corresponde à watchlist de escopos privilegiados com um badge ⚠ priv — o sinal de pesquisa de expansão de privilégios no estilo FOCI / BroCI.
  • Fontes — contagens de tokens por source_tag para que você veja quantas linhas vieram de cada passagem de ingestão.

Abas Tokens / Exchanges

  • Clique em um cabeçalho de coluna para ordenar.
  • Checkboxes de seleção múltipla acionam uma barra de ferramentas:
    • Highlight in Graph — destaque amarelo nos nós selecionados.
    • Isolate in Graph — redesenha o diagrama mostrando apenas os tokens selecionados mais os tokens com os quais eles trocam.
    • Show in Sequence — diagrama de sequência focado para o(s) token(s) selecionado(s).
  • Clique em uma linha para expandir um painel inline com header + payload JWT completos (JSON bruto), todos os eventos, trocas relacionadas, botões de exportação prontos para replay (raw / Bearer / curl / JSON / cache de token roadtx), e um bloco de pré-visualização de comando com snippets copiáveis para roadtx describe, roadtx auth, curl, Python requests, e PowerShell Invoke-RestMethod.
  • Filtros: chips de tipo (access / refresh / id / unknown), chips de formato (jwt / opaque), dropdown usado / não usado, dropdown de validade (any / valid / expired / unknown expiry), apenas FOCI, apenas BroCI, has-app-match, has-resource-match, mais uma busca de texto livre em fp / sample / claims / host / app / resource / source_tag / user.
  • Exportação CSV / JSON das linhas atualmente filtradas + ordenadas.
  • Persistência no hash da URL — a aba ativa e cada estado de filtro é serializado no hash da URL, então links para visões filtradas específicas são compartilháveis.

Suporte a WebSocket

  • Capturas mitmproxy e CDP preservam cada payload de frame de texto / binário WebSocket. O conteúdo dos frames é escaneado em busca de tokens com o mesmo walker de JSON / form / raw-JWT que lida com corpos HTTP.
  • Tokens encontrados em frames geram eventos com role ws-frame-sent / ws-frame-received, source ws[body_json[<key>]], e um ws_session_id que agrupa todos os frames dentro de uma conexão WebSocket.
  • O handshake é capturado como um evento HTTP normal para que cookies / bearer tokens carregados no upgrade também sejam rastreados.

Privacidade

  • O banco de dados armazena fingerprints SHA-256 (primeiros 12 caracteres hex) e um prefixo de 12 caracteres de cada token observado. Strings completas de token nunca saem do arquivo de entrada.

  • O conteúdo das claims JWT decodificadas (header + payload, incluindo oid, sub, upn, email, tid, listas de escopo, etc.) é armazenado literalmente por padrão porque é exatamente o objetivo da análise. Trate o banco de dados e qualquer URL de dashboard compartilhada como sensível sempre que JWTs estiverem presentes.

  • --redact-claims (disponível em ingest, mitm, e cdp) substitui valores de claims listados por placeholders de hash estáveis antes que cheguem ao banco de dados. A lista padrão de campos cobre sub, oid, upn, email, name, unique_name, preferred_username, emails, mail, ipaddr, given_name, family_name. Passe uma lista explícita separada por vírgulas (ex.: --redact-claims sub,upn,oid) para sobrescrever o padrão. A mesma entrada sempre mapeia para o mesmo placeholder, então o agrupamento de Usuários / Tenants do dashboard ainda funciona sem revelar o usuário.

  • --store-tokens (disponível em ingest, mitm, e cdp, desativado por padrão) opta por escrever a string completa do token no banco de dados para que o dashboard possa oferecer:

    • Ações Copy raw / Copy Bearer / Copy curl.
    • Download do JSON do token (raw + claims + eventos observados).
    • Copy / Download como cache de token roadtools (coloque o arquivo em .roadtools_auth e qualquer subcomando roadtx o reconhece).
    • Um bloco de Command preview por token que pré-preenche as invocações de replay mais comuns — roadtx describe, roadtx auth, curl, Python requests, PowerShell Invoke-RestMethod — usando as claims reais de tid, appid, e do token.

Instalação

Requisitos

  • Python 3.10+ (usa sintaxe de tipos compatível com match-statement e dataclasses modernas). Testado em 3.12.
  • Sem etapa de build. Clone o repositório e execute python -m tats diretamente.

Dependências opcionais

NecessidadeInstalação
Subcomando mitmpip install mitmproxy
Captura ao vivo do Chrome / EdgeNenhuma — usa um cliente WebSocket da stdlib
--enrich (entrascopes.com)Nenhuma — usa urllib.request

Instalação rápida

Executar a partir de um checkout (sem instalação):```bash git clone tats cd tats python -m tats --help

root@kitploit:~
O HTML / CSS / JS do dashboard ficam em `tats/static/` e são carregados
na primeira importação, portanto nenhuma etapa de build é necessária — basta executar o módulo
diretamente a partir do checkout.

**Instalar como pacote (fornece o script de console `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

Após a instalação, você pode chamar a ferramenta pelo seu nome curto:```bash tats ingest engagement.xml -o tokens.db --enrich tats serve tokens.db

root@kitploit:~
Se você precisa apenas dos caminhos Burp / CDP, o arquivo é totalmente autossuficiente
com a biblioteca padrão do Python — nenhuma instalação ou extras são necessários.

---

## Início rápido

**Analise uma exportação XML do Burp e abra o dashboard:**```bash
tats ingest examples/fixture.xml -o tokens.db --enrich
tats serve tokens.db

Combine uma captura do Burp com um arquivo de fluxo do mitmproxy em um único DB:```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 ao vivo de um navegador Chrome (vê HTTP descriptografado por TLS + frames WebSocket, sem necessidade de CA de proxy) — deixando a ferramenta iniciar o 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

O navegador iniciado é encerrado e seu perfil temporário é excluído quando você pressiona Ctrl-C no comando cdp.

Se você preferir se conectar a um navegador já em execução, inicie-o com --remote-debugging-port=9222 --user-data-dir=/tmp/cdp-profile e execute cdp sem --launch-chrome.

Sanitize um banco de dados antes de compartilhá-lo (redação 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:~
A redação é estável em termos de conteúdo: valores idênticos mapeiam para
placeholders idênticos, pelo que o agrupamento por utilizador do dashboard
continua a funcionar sem mostrar o utilizador.

O cabeçalho do dashboard mostra `live · updated <time>` assim que os dados
começam a fluir.

---

## Subcomandos

Cada subcomando aceita `--help` para a lista canónica de opções. As notas
abaixo explicam *quando* e *como* recorreria a cada um.

### Flags globais

Estas aplicam-se a todos os subcomandos e vão *antes* do nome do subcomando:

* `-v` / `--verbose` — adiciona linhas de log INFO (estado de enriquecimento,
  contagens de redação na ingestão). `-vv` adiciona DEBUG (cada pedido ao
  servidor).
* `-q` / `--quiet` — silencia as linhas de log INFO; apenas WARNINGs e ERRORs
  aparecem. A linha final de output para o utilizador (por exemplo,
  `wrote tokens.db (...)`) e quaisquer diagnósticos `error: …` não são
  afetados, pelo que continuará a ver o que importa a partir de um script.
* `--version` — imprime a versão da ferramenta e sai.

### `ingest` — exportação XML do Burp Suite

Lê um XML "Save items" (Proxy → HTTP history → clique com o botão direito →
Save items). Ficheiros de projeto binários `.burp` **não** são suportados — o
formato é proprietário e instável entre versões do Burp; exportar os itens
que lhe interessam é o fluxo de trabalho suportado.```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]

Exemplos:```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` — arquivo de fluxo `.mitm` do mitmproxy

Lê um arquivo de fluxo produzido por `mitmdump`, `mitmproxy` ou `mitmweb`. Este
é o único caminho de ingestão que captura **frames WebSocket** sem uma sessão
de navegador ativa — os arquivos de fluxo preservam cada payload de frame de texto / binário.```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]

Requer pip install mitmproxy. A ferramenta emitirá um erro claro se o pacote estiver ausente.

Capture um arquivo de fluxo com mitmproxy:```bash mitmdump -w session.mitm

... drive the browser ...

Ctrl-C to stop

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

root@kitploit:~
### `cdp` — conexão ao vivo com Chrome / Edge

Conecta-se a um navegador da família Chromium em execução através do DevTools Protocol
e transmite eventos `Network.*` para o banco de dados. Captura requisições /
respostas HTTP (com corpos obtidos via `Network.getResponseBody`), upgrades de WebSocket,
e cada frame de WebSocket em ambas as direções. O buffer é descarregado para
o banco de dados a cada N eventos (padrão 25), para que a sondagem de 5 segundos do dashboard
capte novos tokens em segundos após o navegador fazer a
requisição.```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]]

Permitindo que a ferramenta inicie o 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:~
O navegador iniciado é executado com `--remote-debugging-port=<port>` e um
user-data-dir temporário novo. Quando você interrompe o comando `cdp` (Ctrl-C),
o navegador é encerrado e o perfil temporário é excluído.

### Anexando a um navegador já em execução

Inicie o navegador você mesmo, com um perfil novo, e então execute `cdp` sem
`--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

Um user-data-dir separado evita anexar a um perfil pessoal e impede que o navegador em execução recuse a flag de depuração.

Por padrão, o cdp anexa no nível do navegador e rastreia cada aba que existe quando ele inicia E cada aba aberta durante a execução (window.open, Ctrl-click, botão de nova aba). Todas as abas compartilham o único WebSocket através do multiplexador de sessão do protocolo flat do CDP, portanto, abrir ou fechar abas enquanto a captura está em execução é totalmente suportado. Cada anexação / desanexação de aba imprime uma nota de uma linha no stderr no nível INFO.

Se você preferir fixar em uma única aba e ter a anexação encerrada quando essa aba fechar, liste os alvos disponíveis:```bash curl http://127.0.0.1:9222/json/list

root@kitploit:~
…então passe `--target <id>`.

Pressione Ctrl-C para parar. A cauda de qualquer buffer em trânsito é descarregada para a
base de dados antes de o processo terminar.

### `serve` — painel web

Lê uma base de dados existente e serve uma interface web de página única em
`127.0.0.1:8765`. O servidor é apenas de leitura; nunca escreve na
base de dados, por isso é seguro executá-lo em paralelo com uma ingestão
`cdp` ou `mitm` em curso.```bash
tats serve <tokens.db> \
    [--host 127.0.0.1] [--port 8765] [--no-browser]

Exemplos:```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:~
> **Aviso:** a interface web expõe payloads JWT descodificados (claims), impressões digitais de tokens, a linha temporal de atividade e gráficos Mermaid a qualquer pessoa que consiga alcançar o endereço de bind. Se ingeriu com `--store-tokens`, também expõe os **tokens brutos completos** através de `/api/token/<fp>` e `/api/export?fps=...`. **Não existe autenticação**. Mantenha `--host` em `127.0.0.1` a menos que pretenda especificamente o contrário.

#### Exportação pronta para replay

Quando a base de dados foi construída com `--store-tokens`, cada token expandido no separador Tokens obtém uma linha de ações de um clique:

* **Copy raw** — a string completa do token para a área de transferência.
* **Copy Bearer header** — `Authorization: Bearer <token>`, pronto a colar.
* **Copy curl example** — um one-liner que aponta para o `aud` do token (ou o seu host emissor) com o cabeçalho bearer anexado.
* **Download JSON** — um ficheiro JSON de token único contendo raw, claims, eventos observados e exchanges.
* **Copy as roadtx** — a forma JSON de uma cache de tokens roadtools (`tokenType`, `accessToken` / `refreshToken` / `idToken`, `expiresOn`, `tenantId`, `_clientId`, `resource`, `foci`, `scope`). Cole diretamente num ficheiro `.roadtools_auth`.
* **Download .roadtools_auth** — o mesmo payload, descarregado como ficheiro. Renomeie-o para `.roadtools_auth` (ou passe-o via `roadtx <cmd> --tokens-file`) e qualquer subcomando roadtx irá capturá-lo.

A barra de ferramentas do separador Tokens também tem **Export selected for replay**, que acede a `/api/export?fps=fp1,fp2,...` e descarrega um único documento JSON com até 200 tokens (raw, claims, eventos) num só pacote. Sem `--store-tokens`, os mesmos botões mostram uma dica para re-ingerir antes que a exportação pronta para replay se torne possível.

#### Pré-visualização de comandos

Cada token expandido também tem um bloco recolhível **Command preview** que pré-preenche as invocações de replay / inspeção mais comuns usando os claims reais do token (e o valor bruto completo quando `--store-tokens` está ativo). Cada snippet tem um botão Copy de um clique. A mistura exata depende do tipo de token:

* **Qualquer JWT:** `roadtx describe -t '<token>'` (descodificar sem rede).
* **Refresh tokens:**
  * `roadtx auth --refresh-token '...' -c <client_id> -t <tenant_id>` — trocar um refresh token por access tokens novos.
  * `curl -X POST .../oauth2/v2.0/token` — o equivalente OAuth para utilizadores que não usam roadtx.
* **Access / id / tokens desconhecidos:**
  * `curl -H 'Authorization: Bearer ...' '<aud>'`
  * Python `requests.get(...)` com o cabeçalho bearer definido.
  * PowerShell `Invoke-RestMethod` com o mesmo cabeçalho.
* **Sempre:** o objeto JSON para colocar em `.roadtools_auth`.

Quando `--store-tokens` está desativado, os snippets são renderizados com `<TOKEN>` como placeholder para que o painel continue a ser útil como referência de documentação.

---

## A interface web em detalhe

### Navegação superior

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

Cada separador é renderizado independentemente a partir do mesmo snapshot em memória de `/api/data`. Alternar entre separadores é instantâneo; os diagramas de grafo e sequência são re-renderizados a pedido e respeitam a seleção atual no separador Tokens.

### Summary

Blocos de estatísticas no topo (tokens / access / refresh / id / unknown / used / unused / events / exchanges / FOCI exchanges / BroCI exchanges / hosts) seguidos por uma grelha de cartões descritos em [Features → Dashboard cards](#dashboard-cards).

Clique em qualquer linha em qualquer cartão para saltar para um separador Tokens pré-filtrado — por exemplo, clicar numa linha de tenant filtra o inventário para tokens que transportam esse `tid`.

### Tokens

Inventário filtrável e ordenável. A seleção múltipla controla os botões highlight / isolate / sequence. A expansão de linha mostra o JWT descodificado completo (cabeçalho + payload como JSON bruto), todos os eventos que envolvem esse token e todas as exchanges onde foi uma entrada ou saída.

### Exchanges

Lista ordenável de todas as exchanges token-for-token detetadas — rotações de refresh-token, cross-redemptions FOCI e exchanges de aplicações aninhadas BroCI. A coluna BroCI mostra broker + IDs de cliente aninhados lado a lado com a evidência que despoletou a deteção.

### FOCI

Duas tabelas: todos os refresh tokens marcados com uma família FOCI (atualmente a Microsoft só emite `"1"`), e todas as exchanges cuja resposta transportava o campo `foci`.

### BroCI

As exchanges de Nested App Authentication. Para cada uma: a aplicação broker (`brk_client_id`), o cliente aninhado (`client_id`), a evidência que despoletou a deteção (`brk_client_id`, `brk_redirect_uri`, URI de redirecionamento `brk-<guid>://`) e as impressões digitais dos tokens de entrada / saída.

### Graph

Mermaid `flowchart LR` das relações token ↔ serviço. Os refresh tokens são desenhados como cilindros, os access / id tokens como estádios. As arestas mostram emissão, apresentação, exchange e rotação. O realce (a partir do separador Tokens) adiciona um acento amarelo; o isolamento re-renderiza o grafo apenas com os tokens selecionados e os tokens com que estes fazem exchange.

### Sequence

Diagrama de sequência Mermaid de todos os eventos por ordem de captura. Selecionar um único token mostra apenas a sua sequência; selecionar vários mantém a vista completa mas destaca os tokens selecionados. Limite máximo de eventos configurável (predefinição 200; os diagramas de sequência Mermaid tornam-se ilegíveis após algumas centenas de mensagens).

---

## Suporte específico da Microsoft

### Family of Client IDs (FOCI)

A Microsoft permite que um refresh token emitido para uma aplicação numa "família" seja resgatado no endpoint de token por **qualquer outra aplicação** da mesma família. A ferramenta deteta FOCI na rede ao analisar o JSON de resposta do endpoint de token à procura de um campo `foci` (atualmente sempre `"1"` para a única família conhecida). Os refresh tokens emitidos nessa resposta são marcados com o id da família e apresentados no separador dedicado **FOCI**.

Se `--enrich` estiver ativado, a coluna de aplicação do inventário também apresenta a flag `foci: true/false` do `firstpartyscopes.json` — note que esta pode discordar da deteção na rede (o conjunto de dados entrascopes é por vezes conservador). O campo `foci` na rede é sempre o sinal autoritativo.

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

Os suplementos do Office, as aplicações Teams e o Portal Azure usam NAA para adquirir tokens para um cliente aninhado através de uma aplicação broker. A ferramenta deteta isto no lado do pedido através de:
* o parâmetro de formulário `brk_client_id` (GUID da aplicação broker),
* o parâmetro de formulário `brk_redirect_uri` (URI de redirecionamento real do broker),
* um `redirect_uri` da forma `brk-<guid>://...` (onde `<guid>` é o broker).

O claim `appid` / `azp` do access token resultante é o cliente aninhado; o broker só aparece na rede — nunca como claim JWT. O dashboard apresenta ambos os lados claramente.

### Cookies de sessão `ESTSAUTH`

`ESTSAUTH`, `ESTSAUTHPERSISTENT`, `ESTSAUTHLIGHT` e `SignInStateCookie` são cookies de sessão do Microsoft Entra que não viajam em `Authorization: Bearer` mas são usados pelo navegador para emitir novos access tokens através de fluxos de autenticação silenciosa. A ferramenta rotula-os como `refresh` (o seu papel funcional) em vez de deixar a regra genérica da substring `auth` classificá-los incorretamente como `access`.

### Enriquecimento entrascopes.com (`--enrich`)

Obtém e coloca em cache `firstpartyscopes.json` (~2,8 MB; 504 aplicações first-party com a sua flag FOCI, URIs de redirecionamento, scopes e capacidade de broker) e `resources.json` (~170 KB; mais de 1.750 mapeamentos recurso → nome de apresentação) de <https://entrascopes.com/>. A cache reside em:

| Variável | Predefinição |
|---|---|
| `$TATS_CACHE` | (prioridade máxima; `$BURP_TOKEN_TRACKER_CACHE` é aceite como fallback para migração de uma versão) |
| `$XDG_CACHE_HOME/tats` | (Linux/macOS) |
| `%LOCALAPPDATA%\tats\cache` | (Windows) |
| `~/.cache/tats` | (fallback) |

O TTL é de 7 dias. Use `--no-enrich-cache` para forçar uma nova obtenção. A cache é reutilizada como fallback obsoleto quando a ferramenta é executada offline.

Quando `--enrich` está ativado, cada GUID de `appid` / `azp` / `client_id` e cada claim `aud` de GUID-ou-URL é resolvido para um nome amigável com um link clicável `https://entrascopes.com/?appId=<guid>`.

---

## Arquitetura

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

Todo caminho de origem produz o mesmo objeto Tracker. ingest_to_db transforma-o em linhas na base de dados. Store lê a base de dados para o servidor HTTP, que expõe JSON em /api/data, /api/meta, /api/token/<fp>, /api/export, /api/graph e /api/sequence.

Esquema da base de dados (v4)

  • tokens (chave primária fp) — fingerprint, prefixo da amostra, tipo, formato, tempo de vida observado, cabeçalho / payload JWT como JSON, campos de enriquecimento, campos derivados (user_identity, exp_unix, tenant_id, scopes_text), source_tag separado por vírgulas, raw (string completa do token, NULL a menos que ingerido com --store-tokens) e security_features (JSON compacto que descreve marcadores CAE / PoP / step-up detetados — ver o cartão Security features). Bases de dados v2 / v3 mais antigas migram automaticamente quando reabertas em modo append: v2 → v3 adiciona a coluna raw anulável; v3 → v4 adiciona a coluna security_features anulável e preenche-a a partir do jwt_payload_json armazenado de cada token na primeira abertura. Linhas pré-existentes mantêm ambas as colunas nos seus valores anteriores.
  • events — cada interação de token observada: pedido / resposta HTTP ou frame WebSocket. Papéis: issued / returned / presented / used / exchanged-in / ws-frame-sent / ws-frame-received. Transporta ws_session_id para agrupar frames dentro de uma ligação.
  • exchanges — quando um pedido portador de token a um endpoint de token produziu novos tokens na sua resposta. Regista metadados FOCI / BroCI.
  • exchange_inputs, exchange_outputs — fingerprints de tokens em cada lado de cada exchange.
  • hosts — etiquetas host:port distintas.
  • meta — versão do esquema, lista de origens, generated_at, last_modified (usado pelo poll em direto do dashboard), contagens.

Etiquetagem de origem e modo append

Cada linha escrita na BD transporta um source_tag — por predefinição burp:<filename>, mitm:<filename> ou cdp:<host>:<port>, mas sobreponível via --source-tag. Quando o mesmo fingerprint é visto por mais do que uma passagem de ingestão, o campo source_tag acumula como uma lista separada por vírgulas, para que o cartão Sources do dashboard possa mostrar a proveniência de cada token.

--append mantém uma BD existente e faz merge nela via UPSERT para tokens (contagens de utilizações + tempo de vida observado acumulam, tipos desconhecidos são atualizados) e INSERT para events / exchanges (com os seus números seq deslocados para além do máximo existente, para que a linha temporal de atividade se mantenha monotónica). Incompatibilidade de versão do esquema recusa o merge para evitar perda silenciosa de dados.

Atualizações em direto

O endpoint /api/meta do servidor web devolve a tabela meta (~200 bytes). O dashboard faz poll a cada 5 segundos e só volta a obter o /api/data completo quando last_modified muda. O caminho de ingestão cdp descarrega o seu tracker em memória para a BD a cada 25 eventos por predefinição, pelo que a latência de relógio de parede desde um pedido do browser até uma atualização do dashboard é tipicamente < 10 segundos.


Limitações

  • Ficheiros de projeto .burp do Burp não são suportados. Use Save items para produzir o XML que a ferramenta consome.
  • Sem gestão de CA de proxy. Esta ferramenta não interceta TLS por si própria. Use-a a jusante do Burp / mitmproxy, ou use o caminho CDP que vê tráfego desencriptado de TLS a partir de dentro do browser.
  • O attach CDP cobre alvos de página de topo. Iframes fora de processo (OOPIFs) e workers dedicados não são auto-anexados recursivamente, pelo que eventos que fluem através desses tipos de alvo podem ser perdidos. Para os fluxos Microsoft / OAuth em torno dos quais esta ferramenta foi construída, o attach à página de topo captura tudo o que importa.
  • Sem verificação de assinatura em JWTs. A ferramenta descodifica claims para exibição; verificação de assinatura, alg=none e ataques de confusão de chaves estão fora do âmbito. Use um auditor de JWT dedicado para esses casos.
  • Falsos positivos de tokens opacos. A heurística "isto é um token?" trata qualquer string URL-safe de 20+ caracteres em contextos com forma de OAuth como um token. IDs aleatórios longos podem ser incorretamente sinalizados. Tokens cujo tipo não pode ser inferido acabam como unknown e são ocultados por predefinição a menos que --include-unknown esteja definido na flag mais antiga (apenas Burp).
  • --enrich faz pedidos HTTP de saída para https://entrascopes.com/. Ignore a flag se o seu ambiente não o permitir.
  • A UI web não tem autenticação. Vincule-a a localhost a menos que tenha colocado outra camada de autenticação à frente.

Resolução de problemas

SintomaCausa provávelCorreção
error: could not parse <file> as XMLTentar ingerir um ficheiro de projeto .burp binárioNo Burp: Proxy → HTTP history → selecionar itens → clicar com o botão direito → Save items
error: no <item> elements foundO XML não foi produzido pelo Save items do BurpReexporte do Burp; o elemento raiz deve ser <items>
error: cannot append to DB with schema_version 1A BD foi criada por uma build anteriorElimine a BD e volte a ingerir as origens originais; a migração de esquema intencionalmente não é automática
error: the 'mitm' source needs the mitmproxy Python packagemitmproxy não instaladopip install mitmproxy
error: cannot reach Chrome at 127.0.0.1:9222O Chrome não foi iniciado com --remote-debugging-portVeja a fórmula de lançamento em cdp subcommand
O CDP anexa mas não fluem eventosA página ainda não fez quaisquer pedidos de rede, ou toda a atividade está num OOPIF / worker (não auto-anexado)Recarregue a página; confirme que os separadores foram registados (procure linhas de log tab attached: … no stderr)
no browser-level webSocketDebuggerUrl at /json/versionA versão do Chrome é demasiado antiga para CDP ao nível do browser, ou devolveu a forma erradaAtualize o Chrome, ou passe --target <id> para usar o attach legado de separador único
target … has no webSocketDebuggerUrlOutro depurador (por exemplo, janela DevTools) já está anexadoFeche o DevTools, ou anexe a um alvo diferente
O dashboard mostra Failed to load /api/dataO servidor não consegue ler o ficheiro da base de dadosVerifique se o caminho da BD está correto, se o ficheiro é legível e se a versão do esquema corresponde
As atualizações em direto deixam de chegarO processo cdp terminou ou o flush do buffer de rede ainda não disparouVerifique o terminal do cdp para erros; reduza para atualizações mais rápidas

Desenvolvimento

Fixtures de smoke-test

Dois construtores de fixtures residem em 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:~
Após ambas as execuções, `tokens.db` tem 15 tokens (11 do Burp + 4 do
mitmproxy), 23 eventos, incluindo um evento de frame WebSocket, e 3
trocas.

### Suíte de testes```bash
pip install .[test]
pytest

A suíte cobre extração de token, parsing de JWT, classificação de session-cookie da Microsoft, detecção de FOCI / BroCI, resumo de claims, redação de PII, o caminho de ingestão de XML do Burp com semântica de UPSERT em modo append, e o caminho de ingestão de frames WebSocket do mitmproxy (ignorado automaticamente quando a dependência opcional mitmproxy está ausente).```text $ pytest tests/ ============================= test session starts ============================= … ======================== 62 passed in 1.4s =================================

root@kitploit:~
### Executando o servidor em primeiro plano```bash
tats serve tokens.db --no-browser

…e abra http://127.0.0.1:8765 manualmente. O servidor registra cada requisição e quaisquer erros de handler em stderr.

Estrutura de arquivos

CaminhoFinalidade
tats/__init__.pyA ferramenta inteira — parsers, camada de BD, servidor HTTP, cliente CDP; carrega o dashboard de tats/static/
tats/__main__.pyPonto de entrada para python -m tats; mesma lógica do script de console tats instalado
tats/static/index.htmlEsqueleto HTML do dashboard com placeholders {{CSS}} / {{JS}}
tats/static/style.cssEstilização do dashboard — edite com suas ferramentas CSS normais
tats/static/app.jsLógica do dashboard — edite com suas ferramentas JS normais (LSP / lint / formatter)
pyproject.tomlMetadados de empacotamento, extras opcionais ([mitm], [test], [all]), ponto de entrada do console
LICENSEGNU General Public License v3
README.mdEste arquivo
examples/Capturas sintéticas + scripts de construção de fixtures (veja examples/README.md)
examples/make_fixture.pyGerador sintético de XML do Burp
examples/make_mitm_fixture.pyGerador sintético de arquivo de fluxo do mitmproxy
examples/fixture.xmlFixture XML do Burp pré-construída
examples/fixture.mitmFixture de fluxo do mitmproxy pré-construída
tests/Suíte pytest (execute com pytest)

O layout de arquivo único é intencional: a ferramenta foi feita para ser lida, auditada e inserida em investigações por qualquer pessoa com Python instalado. Não há configuração oculta, nenhuma árvore de dependências para avaliar e nenhuma superfície além do próprio arquivo.

Mantendo este README

Se você alterar subcomandos, schema, cards do dashboard ou a superfície pública da API (flags da CLI, endpoints /api/*), atualize as seções relevantes deste arquivo na mesma alteração. As seções com maior probabilidade de desatualização:

  • Features — ao adicionar fontes de ingestão ou cards do dashboard
  • Subcommands — ao alterar flags
  • Microsoft-specific support — quando a lógica de detecção muda
  • Architecture — quando o schema ou o fluxo de atualização ao vivo muda
  • Troubleshooting — quando uma nova mensagem de erro é adicionada

Licença

GNU General Public License v3.0 ou posterior — texto completo no arquivo LICENSE na raiz do repositório. O código-fonte do script carrega o cabeçalho curto padrão apontando para o mesmo.

Você pode redistribuir e/ou modificar a ferramenta sob os termos da GPL v3 (ou qualquer versão posterior, a seu critério). Ela é distribuída sem qualquer garantia; consulte a LICENSE para os termos completos.

Baixar ferramenta
aud
  • /api/export?fps=... retornando até 200 tokens (raw, claims, eventos, trocas) em um único bundle JSON para ferramentas downstream.
  • Ativar isso transforma o banco de dados em uma credencial completa — cada byte necessário para reproduzir qualquer sessão capturada está nele. Combine com --redact-claims para limpar a visão decodificada do JWT, mas esteja ciente de que o token bruto ainda carrega as claims não redigidas codificadas dentro dele. Quando a flag está desativada, o bloco de pré-visualização de comando do dashboard ainda é renderizado, apenas com <TOKEN> como placeholder para funcionar como uma referência de sintaxe; os botões de exportação renderizam uma dica para re-ingerir.

    --flush-every