
Reconocimiento en vivo y auditoría de postura para la infraestructura de agentes de IA: escanea configuraciones de MCP, registros de sesión y APIs en busca de secretos, catálogos envenenados y fugas de CoT.
Mascarada renacentista. Siéntate en el asiento del agente.
Siéntate en el asiento del agente.
Una CLI que habla MCP y OpenAI-compat como lo hace el modelo, y luego informa como linpeas. Hallazgos más remediaciones. Sin payloads de explotación. Sin descifrado de CoT.
| Qué | Reconocimiento en vivo de la infraestructura del agente: configuraciones MCP, listeners, registros de sesión, eco de cadena de pensamiento cifrada, APIs sin autenticación, envenenamiento de catálogo, árboles de habilidades. |
| Para quién | Operadores de Hermes, Grok, Claude, Cursor, VS Code, Codex y stacks de modelos locales que necesitan ver lo que el agente puede ver. |
| Lo que no es | No es un generador de jailbreaks. No es el decodificador de modelos más débiles arXiv:2608.09867. No es una puerta de enlace en tiempo de ejecución. |
| Estado | Beta. El cargo test offline es la puerta pública. El --lab en vivo es para hosts que posees. |
| Licencia | MIT |
Los escáneres estáticos de MCP (Invariant mcp-scan, mcp-security-scan) hacen lint de esquemas y configuraciones. Los chequeos de salud hacen ping a initialize. El hueco está en el asiento:
initialize, eres el agente.:11434, :8000) suelen vincularse a 0.0.0.0 sin bearer.Usamos ruedas existentes, no las reescribimos: detectores de catálogo existentes + pin/check, netstat, ureq solo-GET, OWASP MCP Top 10 como taxonomía de hallazgos. No clonamos mcp-scan ni mcp-security-scan.
git clone https://gitlab.com/WattoCyber/masq.git
cd masq
cargo install --path .
# binary: masq
cargo test
# expect: exit 0
Suite mundial (binario contra fixtures, mocks locales, reconocimiento de este host):
python scripts/world_suite.py
# field = ~/.grok/sessions lab = allowlisted hosts bench = frozen-corpus wall
python scripts/world_suite.py --lanes all
Máquina remota estilo Kali, desde el escritorio:
MASQ_REMOTE_HOST=user@host bash scripts/deploy_kali.sh
# on the box:
~/.local/bin/masq --plain
MASQ_LAB_HOSTS=... ~/.local/bin/masq --lab --plain
masq # live stream + posture report (includes skills)
masq --lab # same, plus allowlisted homelab hosts
masq tui # boxed TUI, stays until Ctrl+C
masq --plain # report only, no live stream
masq --json # machine report
masq recon # same dump, recon only
masq sniff ~/.grok/sessions # CoT / secrets in session logs
masq sniff --timeline PATH # file-order blob/secret/reason lines (no decrypt)
masq api # GET /v1/models on local (and --lab) ports
masq sit --url http://127.0.0.1:4443/mcp
masq chameleon --url http://127.0.0.1:4443/mcp -o /tmp/chameleon
masq chameleon --url ws://127.0.0.1:9000/mcp -o /tmp/chameleon
masq chameleon --url unix:///tmp/mcp.sock -o /tmp/chameleon
masq chameleon --token-file ~/.secrets/mcp.txt --url http://127.0.0.1:9/mcp -o /tmp/chameleon
masq chameleon -- python -m their_mcp -o /tmp/chameleon
# then: npx -y @copilotkit/aimock --config /tmp/chameleon/aimock.json
masq discover # find VS Code / Cursor / Claude / Grok / Hermes MCP configs
masq proxy --upstream http://127.0.0.1:4443/mcp --block
masq sast ./server # local sinks (semgrep if present)
masq classify --url http://127.0.0.1:4443/mcp --lab
masq overnight --lab --hours 6
masq map --from reports/overnight-YYYYMMDD/latest.json
# catalog
masq fixtures/t3_line_jump.json
masq fixtures/clean_calculator.json --trusted
masq pin fixtures/clean_calculator.json -k calc
masq check fixtures/clean_calculator.json -k calc
masq detectors
Salida: 0 limpio · 2 hallazgos ≥ --fail-on (por defecto high) · 1 error.
La TUI es opt-in (masq tui o --tui). En una tty el valor por defecto es un stream en vivo estilo linpeas y luego el informe. Cron usa --plain / --no-color.
Alias: doctor / audit → scan. chameleon → mimic. posture → seat.
sit / chameleon hablan:
http://)ws://unix: y npipe:--framing auto prueba NDJSON y luego Content-Length)Autenticación (nunca se vuelca al informe):
--token-file PATH (la primera línea se convierte en Authorization: Bearer …)--token-env VAR--header "Name: value" (repetible)wss:// no está integrado. Stunnel a ws:// o usa HTTP. HTTP sigue cero redirecciones.
El initialize de stdio no publicita sampling. Marca el sampling / elicitation del servidor. Las URLs de documentación (model-catalog.json, /docs/) se ignoran a propósito.
Raíces de config + skills bajo $HOME / %USERPROFILE%:
VS Code, Cursor, Windsurf, Claude Desktop, Claude Code, Grok, Hermes, Codex, Continue, Gemini CLI, Amp, Kiro, OpenCode, Amazon Q, Antigravity, OpenClaw.
Además, .mcp.json en el cwd y MASQ_EXTRA_CONFIG (lista de rutas del SO).
--lab)--lab es una lista de permitidos, no un escaneo /24. Está configurada por el operador. Nada está compilado más allá del loopback.
MASQ_LAB_HOSTS: host:port o hosts separados por coma, espacio o nueva línea..masq/lab-hosts: un host por línea, comentarios #.Ejemplo:
export MASQ_LAB_HOSTS="192.0.2.10,192.0.2.11"
masq --lab
MASQ_LAB_HOSTS se lee para las sondas de API y la consolidación de flota de la TUI. MASQ_SIT_URLS (o un --mcp-url) suministra URLs MCP sobre las que tomar asiento con --lab.
sit --url fuera de loopback necesita --lab y un host en la lista de permitidos. El initialize sin autenticar en loopback es High. Fuera de la máquina es Critical.
No apuntes proxy a un host en el que no te sentarías.
Prioridad de sniff: primero chat_history.jsonl, luego request_dump_* de Hermes, después otros jsonl. El walk termina. No conserva los primeros 300 resultados de WalkDir. Usa masq sniff <one-session-dir> para ir más a fondo.
masq overnight --lab --hours 6 --interval-mins 20
# writes <cwd>/reports/overnight-YYYYMMDD/{latest.json,latest.md,latest.txt,delta.txt}
No muta configuraciones. No hace tools/call al servidor en vivo. delta.txt es baseline / no_change / CHANGE más + título de severidad y - título de severidad.
classify --llm y el complemento de triaje de la TUI son los únicos POST de completions (Grok /v1/chat/completions, confirmación del operador). Sin clave: solo remediaciones locales. La clave proviene de XAI_API_KEY o ~/.secrets/xai.txt. Nunca se vuelca.
CLI (clap) masq
→ seat | recon | sniff | api | sit | chameleon
→ discover | proxy | sast | classify | overnight | map
→ scan | multi | pin | check | detectors | tui
→ client (HTTP / SSE / ws / unix / npipe / stdio)
→ normalize (full-schema walk, caps)
→ detectors + sniff + recon + sit findings
→ report (text / JSON / Markdown) + optional TUI
Crate de librería: masq (scan_from_tools_list, scan_stdio, run_seat, PostureReport).
No vuelques ~/.secrets. Recon cuenta archivos. Ruta + "loaded".
cargo test
cargo clippy --all-targets -- -D warnings
Se espera salida 0.
Fixtures: T1 envenenamiento de descripción, T3 line-jump, T6 nombres de parámetros, T8 ANSI, T13 nombres duplicados, rugpull de pin, multi-lista, mock NDJSON en vivo en tests/mock_mcp_server.py.
Los secretos se mantienen fuera de git (reports/, data/, .env, *.key, secrets/, .masq/).
MIT. Copyright 2026 SamsonCyber.
| Comando | Qué hace |
|---|
seat (por defecto) | Postura completa: recon + sniff + api + skills + sit opcional. |
recon | Archivos de configuración, listeners, shadow URLs, argv de sudo, npx/uvx sin pin. |
sniff | Registros de sesión en busca de secretos, razonamiento en texto plano, eco de CoT cifrado. |
sniff --timeline | Líneas T0001 en orden de archivo. Sin descifrado. Tope de 200 eventos/archivo. |
api | Solo-GET /v1/models (y similares) en loopback; --lab añade peers de la lista de permitidos. |
sit | Habla MCP: initialize, notifications/initialized, tools/list, prompts/list, resources/list. Nunca origina tools/call. |
chameleon / mimic | Toma asiento en un catálogo en vivo o de archivo, escribe catalog.json + aimock.json + calls.json. Los sobres de ejemplo de tools/call son solo para aimock. |
discover | Imprime las rutas conocidas de configs MCP de agentes. Sin spawn. |
proxy | Reenvía el JSON-RPC del agente. --block rechaza parámetros/resultados de tools/call con forma de secreto. Listen por defecto 127.0.0.1:9877. |
sast | Sinks locales de código fuente. Usa semgrep si está instalado. |
classify | Revisión local de IPI / envenenamiento de un tools/list en vivo. --llm pregunta a Grok (clave del operador). |
overnight | Repite seat hasta que transcurran --hours. Escribe informes. No muta configuraciones. |
map | Consultas de texto de rutas de ataque sobre un JSON de postura guardado. Sin diagrama. |
scan / multi | Lint estático de catálogo (las rutas .json desnudas se reescriben a este comando). |
pin / check | Almacén de pines por hash de contenido (.masq/pins.json) para CI anti rug-pull. |
detectors | Imprime el paquete de reglas del catálogo. |
tui | Seat en modo caja. Permanece hasta Ctrl+C. |
| Módulo | Cubre |
|---|
| recon | MCP01 ruta de secretos, MCP04 npx/uvx sin pin, MCP07/09 listeners y shadow URLs, MCP05 argv de sudo |
| catalog | MCP03 envenenamiento / sombreado / rugpull de esquema |
| skills | Los mismos detectores de catálogo en SKILL.md (Hermes, Grok, Claude, Cursor, Codex, Gemini, Amp, Kiro, OpenCode, OpenClaw). Sin Snyk cloud. |
| sit | MCP02 ampliación del alcance (scope creep), MCP03 tools/list en vivo, MCP07 initialize sin autenticar, publicidad de sampling/elicitation por el servidor, Streamable HTTP (2025-06-18) y luego HTTP+SSE (2024-11-05), Origin DNS-rebinding |
| sniff | MCP01 + MCP10 + eco de CoT cifrado arXiv:2608.09867 (incluido thinkingSignature) |
| api | MCP07 /v1/models sin autenticar, MCP09 bind LAN |
| watch | pin-diff en .masq/pins.json + skills. Overnight lo activa. No es un proxy. |
| fleet | Consolidación de la lista de permitidos de lab en una sección FLEET |
| map | Consultas de texto de rutas sobre un informe de postura |
| Límite | Valor |
|---|
| Archivo tools/list | 8 MiB |
| Archivo sniff | 8 MiB (se muestrean los primeros 2 MiB si es mayor) |
| Archivos sniff / raíz | 300 (mtime más reciente dentro de la prioridad) |
| Eventos de timeline / archivo | 200, luego timeline truncated |
| Líneas T del timeline | 500 (inspect y collapse siguen ejecutándose) |
| Profundidad de recorrido del esquema | 64 |
| Herramientas por inventario | 5_000 |
| Sonda HTTP | Solo GET, 2s API / 5s sit |
| Handshake de sit | timeout + kill |
| Esta herramienta | Lo que no es |
|---|
| Tomar asiento como el cliente del agente (initialize + list) | Originar tools/call contra un servidor en vivo |
| Detectar eco de CoT cifrado en los registros | Descifrar CoT o reproducirlo en un modelo más débil |
GET /v1/models | POST de completions (excepto el triaje opcional de la TUI / classify --llm) |
| Rugpull por pin-hash en un catálogo | PKI firmada / bóveda de pines empresarial |
Reenviar el tools/call del agente en proxy --block | Puerta de enlace DLP completa en tiempo de ejecución / plano de control SaaS |
| Lint local del árbol de habilidades | Snyk / SCA en la nube |
| Comprobación | Esperado |
|---|
masq fixtures/clean_calculator.json --trusted | exit 0 |
masq fixtures/t3_line_jump.json | exit 2 |
masq fixtures/t13_duplicate_names.json | exit 2 (sombreado de herramientas) |
masq sniff --timeline fixtures/ (sin TTY / --json) | solo T0001 con la bandera |
masq chameleon fixtures/clean_calculator.json -o <tmpdir> | catalog.json, aimock.json, calls.json |
masq --no-color en vivo | tokens redactados (…, no el sk- completo) |