
Formato NDJSON de grafo de ataque neutro em relação ao fornecedor, com taxonomia de nós/arestas, mapeamentos AWS/GCP/Azure, regras de derivação e um banco de dados de exposição para ferramentas de segurança ofensiva.
Um grafo de ataque que você pode realmente entregar a outra pessoa.
Todo produto de segurança baseado em grafos mantém seu grafo de ataque trancado dentro de um armazenamento proprietário. Você não pode exportá-lo, comparar dois scans, colocá-lo em controle de versão ou consultá-lo com qualquer coisa que não seja a própria UI do fornecedor. Quando o engajamento termina, o grafo vai embora com ele.
RAGE é um formato de arquivo neutro em relação a fornecedores para grafos de segurança ofensiva, além do corpus aberto que lhe dá significado: a taxonomia de nós e arestas, os mapeamentos e receitas de coleta AWS/GCP/Azure, e as regras de derivação de arestas. Um arquivo. Qualquer linguagem. Pegue e use.
Status: rascunho inicial (spec_version: 0.1). Ainda não estável; feedback e pull requests são bem-vindos.
Um grafo RAGE é um único arquivo NDJSON (um objeto JSON por linha). A linha 1 é o manifesto; todas as outras linhas são um registro marcado com kind.
{"kind":"manifest","spec_version":"0.1"}
{"kind":"node","node_id":"gcp|proj-a|gcp:iam:service-account|sa-deploy","node_type":"ServiceAccount"}
{"kind":"node","node_id":"gcp|proj-a|gcp:iam:service-account|sa-admin","node_type":"ServiceAccount"}
{"kind":"node","node_id":"gcp|proj-a|gcp:storage:bucket|bucket-crown","node_type":"ObjectStorage"}
{"kind":"edge","type":"CanImpersonate","source":"gcp|proj-a|…|sa-deploy","target":"gcp|proj-a|…|sa-admin"}
{"kind":"edge","type":"CanReadData","source":"gcp|proj-a|…|sa-admin","target":"gcp|proj-a|…|bucket-crown"}
{"kind":"finding","resource_id":"gcp|proj-a|…|bucket-crown","severity":"critical"}
Uma cadeia de dois saltos que respeita a taxonomia: sa-deploy pode se passar por sa-admin (uma aresta de identidade para identidade), que pode ler o bucket de joias da coroa (identidade para armazenamento).
Leia em três linhas de qualquer linguagem:
for line in open("graph.rage.ndjson"): rec = json.loads(line) # switch on rec["kind"]
jq 'select(.kind=="edge" and .type=="CanImpersonate")' graph.rage.ndjson
| kind | campos obrigatórios | propósito |
|---|---|---|
manifest | spec_version | linha 1: versão + contagens/escopo/produtor opcionais |
node | node_id, node_type | um recurso ou identidade |
edge | source, target, type | uma capacidade ou relacionamento |
fact | fact_id | uma observação normalizada a partir da qual o grafo foi construído |
evidence | evidence_id, content_hash | recibo à prova de adulteração (uma operação de API/coleta) |
finding | resource_id, severity | uma exposição |
surface / path | - | tipos de extensão opcionais |
A cadeia de proveniência é evidence (API) então fact então edge/finding, ligados por ids. node_type e o type da aresta vêm dos registros abertos em vocab/. Todo o resto é enriquecimento opcional. Veja spec/format.md.
O formato é apenas metade do RAGE. A outra metade é o corpus compartilhado que dá significado aos tipos, para que duas ferramentas independentes concordem sobre o que é CanImpersonate e onde uma credencial pode vazar:
vocab/): 105 tipos de nó em 10 classes, 80 tipos de aresta em 9 categorias.providers/): 219 tipos de recurso nativos em AWS, GCP e Azure, cada um mapeado para um tipo de nó genérico com as chamadas que o enumeram.rules/): o contrato em rules/derivation.json mais 2.400+ regras executáveis match/where/emit para como as arestas são derivadas.exposure-db/): 1.049 sites de vazamento de credenciais mapeados, cada um vinculado à aresta RAGE que ele emite e à receita que o lê.O corpus inteiro, legível por humanos, está em TAXONOMY.md.
RAGE é projetado para que qualquer pessoa possa produzi-lo ou consumi-lo. O formato é o contrato; as ferramentas são intercambiáveis, e a lista é aberta.
RAGE é o formato, Thunderstorm o produz, Blaze o explora.
| implementação | papel | onde |
|---|---|---|
| Thunderstorm | produtor: coletor de nuvem somente leitura + motor de derivação | github.com/ustayready/thunderstorm |
| sua ferramenta aqui | produtor ou consumidor | emita ou leia .rage.ndjson e ele interoperará |
Qualquer coisa que leia ou escreva o formato fala RAGE. Produtores e motores em conformidade seguem os registros neste repositório; RAGE não depende de nenhum deles. Veja COMPATIBILITY.md para como as implementações se fixam a um spec_version.
spec/format.md - o formato de transmissão (registros, gramática de node_id, .rage.zip, escopo).spec/edges.md - semântica de arestas: direção/travessia, state, weight/walkable, canonicalização.spec/rules.md - semântica de avaliação de regras: ponto fixo, merge de estado, o catálogo de funções.schemas/ - JSON Schema para todos os 8 tipos de registro.vocab/ - node-types.json + edge-types.json + conditions.json.rules/derivation.json - o contrato de derivação de arestas (por aresta: condições + permissões/gatilhos por nuvem).rules/{derived,explicit}/** - o corpus executável de 2.400+ regras match/where/emit.providers/{aws,gcp,azure}.json - mapeamentos nativos para genéricos + receitas de nós + receitas de fatos.exposure-db/{aws,gcp,azure}.json + vocabulary.json - o Exposure DB (1.049 sites de vazamento).TAXONOMY.md - o corpus inteiro, legível por humanos (gerado a partir dos registros acima).tools/rage_engine.py - o motor de regras de referência: executa o corpus de regras derivadas sobre um grafo até um ponto fixo.validate/ - validadores de registro (JSON Schema completo), de registro de vocabulário, de string de permissão e de corpus de regras.examples/ - um grafo válido mínimo exercitando todos os 8 tipos de registro.python3 -m venv .venv && ./.venv/bin/pip install -r requirements.txt
./.venv/bin/python validate/rage_validate.py examples/minimal.rage.ndjson # full JSON Schema + refs
./.venv/bin/python validate/check_registries.py # registry integrity
./.venv/bin/python validate/check_rules.py # rule corpus vs vocab
A CI executa tudo o que foi acima, além de um portão de não-deriva do gen_taxonomy.
Apache-2.0 (veja LICENSE).