N0va-7/styx-mcp

GitHub: N0va-7/styx-mcp

一款基于 MCP 协议的内网渗透编排工具,通过 LLM 调度多级跳板、SOCKS 代理、端口转发和内网扫描等安全评估能力。

Stars: 2 | Forks: 0

styx-mcp

License: MIT Go 1.25+ MCP GitHub stars

English · 简体中文

styx-mcp architecture: LLM and local tools via controller to multi-hop agents

## 免责声明 **使用前请阅读本 README(特别是 [SOCKS vs forward vs backward vs scan](#socks-vs-forward-vs-backward-vs-scan))。** ## 功能 - 树状拓扑:主动 (`-c`) / 被动 (`-l`),多级跳板 - 双向 **HMAC** 预认证 + 可选 **TLS** - 控制端的 **SOCKS5** —— 本地工具通过选定的节点出口 - 基于流的 **字节窗口流控**(controller 与 agent 必须匹配) - **Forward**(在 agent 上监听)与 **backward**(在 controller 上监听) - **异步 `start_cmd`** —— 一次性远程命令 (`task_id`) - **异步 `start_scan`** —— 存活探测 → 端口扫描 → 轻量级指纹识别 + **refs** - **异步 `pull_file`** / `upload_file` - 异步任务 + `get_task_status`(包含阶段状态及用于长时间扫描的 `result.progress`) - **Agent 意外断开后自动重连**(保持 `node_id` 稳定重新上线;`SHUTDOWN` 会禁用此功能) - 交叉编译:Linux / Windows / macOS (`make build-all`) ## 目录 - [快速开始](#quick-start) - [Cursor / Codex MCP 设置](#cursor--codex-mcp-setup) - [MCP 工具](#mcp-tools) - [内网扫描 (`start_scan`)](#intranet-scan-start_scan) - [示例](#examples) - [CLI 参数](#cli-flags) - [安全说明](#security-notes) - [项目结构](#project-layout) - [致谢](#acknowledgments) - [许可证](#license) ## 快速开始 ``` git clone https://github.com/N0va-7/styx-mcp.git cd styx-mcp make build # → release/-/ ``` ``` # Terminal A — controller(保留 MCP 的 stdio;仅用于 CLI smoke) ./release/$(uname -s | tr A-Z a-z)-$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')/controller \ -s change-me -l 127.0.0.1:19137 # Terminal B — agent ./release/.../agent -s change-me -c 127.0.0.1:19137 ``` 更喜欢使用 **Cursor**?跳过终端 A 并使用下方的 [wrapper](#cursor-mcp-setup),然后只需启动 agent 即可。 ``` make build-all # linux-amd64 / windows-amd64 / darwin-arm64 make test ``` **预编译二进制文件:** 当维护者发布时,请参见 [Releases](https://github.com/N0va-7/styx-mcp/releases) (运行 `make build-all`,然后手动上传压缩包)。tag 触发 Release 的 CI **未**启用。 ## Cursor / Codex MCP 设置 1. 运行 `make build` 以生成 `release/-/controller`。 2. `~/.cursor/mcp.json`(或项目中的 `.cursor/mcp.json`): ``` { "mcpServers": { "styx-mcp": { "command": "/absolute/path/to/styx-mcp/scripts/styx-mcp-wrapper.sh", "env": { "STYX_SECRET": "change-me-to-a-strong-secret", "STYX_LISTEN": "127.0.0.1:19137", "STYX_LOG": "/tmp/styx-mcp-controller.log" } } } } ``` 3. Cursor → **Settings → MCP** → 启用 / 刷新 **styx-mcp**。 4. 在跳板机上: ``` ./agent -s change-me -c :19137 ``` | 环境变量 | 默认值 | 含义 | | :--- | :--- | :--- | | `STYX_SECRET` | *(必填)* | 共享密钥 (`-s`) | | `STYX_LISTEN` | `127.0.0.1:19137` | Controller 上的 agent 监听地址 | | `STYX_LOG` | `/tmp/styx-mcp-controller.log` | Controller 日志 | | `STYX_MCP_LOG` | *(未设置)* | 可选的原始 MCP stdio 日志路径 | | `STYX_BIN_DIR` | `release/-` | 二进制文件目录覆盖 | 切勿将真实密钥提交到公共配置中。 ### Codex 1. 运行 `make build` 以生成 `release/-/controller`。 2. 添加到 `~/.codex/config.toml`(需使用绝对路径;设置强密钥): ``` [mcp_servers.styx-mcp] command = "/absolute/path/to/styx-mcp/scripts/styx-mcp-wrapper.sh" enabled = true startup_timeout_sec = 45 [mcp_servers.styx-mcp.env] STYX_SECRET = "change-me-to-a-strong-secret" STYX_LISTEN = "127.0.0.1:19137" STYX_LOG = "/tmp/styx-mcp-controller.log" ``` 3. 重新加载 MCP / 启动新的 Codex 任务,使工具(`list_nodes`, …)出现。 4. 只能有 **一个** controller 绑定 `STYX_LISTEN`(不要在同一端口上同时运行 Cursor 和 Codex 的 wrapper)。 5. 在跳板机上:`./agent -s change-me -c :19137` ## MCP 工具 | 工具 | 功能 | 监听 / 操作位置 | | :--- | :--- | :--- | | `list_nodes` | 查看拓扑 | — | | `get_node_detail` | 查看详情 | — | | `add_node_memo` / `delete_node_memo` | 管理备注 | — | | `start_listener` | 等待子 agent 连入 | **Agent** | | `connect_node` | 拨号连接子节点 | **Agent** | | `start_socks` | 为本地工具提供 SOCKS5 | **Controller** → 通过节点出口 | | `start_forward` | 端口转发 | **Agent** 监听 → 目标 | | `start_backward` | 反向转发 | **Controller** → 经由节点 → 目标 | | `upload_file` | 上传文件 | Controller → agent | | `pull_file` | 拉取文件到 controller | Agent → controller 路径 | | `start_cmd` | 一次性远程命令 | Agent `sh -c` (异步 `task_id`) | | `start_scan` | 内网端口扫描 + 轻量级指纹识别 | **Agent** (异步 `task_id`) | | `get_task_status` | 轮询异步任务 | — | | `shutdown_node` | 终止节点 | — | 长时间运行的任务会返回 `task_id` → 可通过 `get_task_status` 进行轮询。 ### SOCKS vs forward vs backward vs scan | 需求场景 | 推荐工具 | | :--- | :--- | | 在 **controller 主机**上使用 `curl` / 扫描器访问内部网络 | `start_socks` | | 将 **controller** 的一个端口映射到某个内部的 `ip:port` | `start_backward` | | 在**跳板机**上开放一个端口用于向外部拨号 | `start_forward` | | 获取来自 **agent** 的结构化开放端口 / 指纹信息 | `start_scan` |

When to use start_socks, start_backward, start_forward, start_scan

## 内网扫描 (`start_scan`) 在选定的 **agent** 上运行(流量从该主机发出)。

start_scan pipeline: discover, port scan, fingerprint, refs

**存活探测(混合模式,默认开启):** 如果 **ICMP 探测成功或者**任何 TCP 探测端口开放,则判定主机存活。 如果没有存活主机,任务将**回退**到扫描所有目标,并设置 `warnings`(以避免出现无提示的空结果)。 **端口扫描方式:** `auto`(默认)在 agent 拥有原始 IPv4 TCP 权限(Linux 下的 root / CAP_NET_RAW)时使用 **SYN**,否则使用 **TCP connect**。可以通过 `method=connect` 或 `method=syn` 强制指定。 | 参数 | 默认值 | 说明 | | :--- | :--- | :--- | | `node_id` | 必填 | 通过该 agent 作为出口 | | `targets` | 必填 | IPv4 IP / CIDR / 逗号分隔列表 | | `mode` | `fast` | `fast` \| `normal` \| `full` \| `custom` (`full` 的开销很大) | | `ports` | — | `custom` 模式下必填 (`22,80,8000-8100`) | | `fingerprint` | `true` | 仅对开放端口进行指纹识别 | | `discover` | `true` | 优先进行混合存活探测 | | `method` | `auto` | `auto` \| `connect` \| `syn` | | `concurrency` | `200` | 最大 500 | | `timeout_ms` | `500` | 单次探测超时时间 | **阶段**(通过 `get_task_status` 获取):`discovering` → `scanning` → `fingerprinting` → `done`。 在探测阶段,`result.progress` 可能包含 `stage`、`icmp_done` / `icmp_total`、`icmp_alive`、`alive_n`、`tcp_probes`。 **重构注意:** 协议变更(SCAN*)后,controller 和 agent 必须基于**同一个 commit** 进行构建。 实验助手(仅限授权网段;使用端口 **19139** 以免占用 MCP 的 `:19137`): ``` STYX_SECRET=… STYX_CALLBACK= ./scripts/lab-scan-e2e.sh ``` ## 示例
SOCKS5 ``` { "name": "start_socks", "arguments": { "node_id": 0, "address": "127.0.0.1:10801" } } ``` ``` curl --socks5-hostname 127.0.0.1:10801 http:/// export ALL_PROXY=socks5h://127.0.0.1:10801 ```
两级拓扑 ``` ./agent -s change-me -l 127.0.0.1:19138 # child, passive ``` ``` { "name": "connect_node", "arguments": { "node_id": 0, "address": "127.0.0.1:19138" } } ```
Forward / backward / upload ``` { "name": "start_forward", "arguments": { "node_id": 0, "listen_address": "127.0.0.1:19141", "target_address": "10.0.0.5:80" } } ``` 连接到 **agent 主机上**的 `listen_address`。 ``` { "name": "start_backward", "arguments": { "node_id": 0, "local_address": "127.0.0.1:19142", "target_address": "10.0.0.5:80" } } ``` 连接到 **controller 主机上**的 `127.0.0.1:19142`。 ``` { "name": "upload_file", "arguments": { "node_id": 0, "local_path": "/path/to/tool", "remote_path": "/tmp/tool" } } ```
内网扫描 ``` { "name": "start_scan", "arguments": { "node_id": 0, "targets": "172.16.23.0/24", "mode": "fast", "discover": true, "method": "auto", "fingerprint": true } } ``` ``` { "name": "get_task_status", "arguments": { "task_id": "start_scan-1" } } ``` 有用的结果字段:`stats`、`open[]`、`summary.interesting[]`,可选的 `warnings[]` / `refs`。
## CLI 参数
controller | 参数 | 说明 | | :--- | :--- | | `-s` | 共享密钥 | | `-l` | 监听 agent 连入 `[ip]:port` | | `-c` | 可选的主动连接 | | `-down` | 仅限 `raw`(拒绝 `ws`) | | `-tls-enable` | 在节点链路上启用 TLS | | `-domain` | TLS SNI / WS 域名 | | `-heartbeat` | 发送至首个节点的心跳 | | `-reconnect-max` | 最大主动 (`-c`) 拨号尝试次数(默认 `3`;`0` = 仅尝试一次) |
agent | 参数 | 说明 | | :--- | :--- | | `-s` | 共享密钥 | | `-c` | 连接到父节点 / controller | | `-l` | 被动监听 | | `-up` / `-down` | 仅限 `raw`(拒绝 `ws`) | | `-tls-enable` / `-domain` | TLS | | `-reconnect` | 意外断开后的基础重连延迟秒数(默认 `10`;`0` = 关闭) | | `-reconnect-max` | 断开后的最大重连尝试次数(默认 `3`) | | `-socks5-proxy` / `-socks5-proxyu` / `-socks5-proxyp` | 通过 SOCKS5 连接父节点 | | `-http-proxy` | 通过 HTTP proxy 连接父节点 |
controller 和 agent 必须共享**相同的密钥**(以及匹配的 TLS/WS 选项)。在更改了重连/重新上线握手逻辑后,请基于同一个 commit 重新构建**两端**的二进制文件。 ## 安全说明 - 像对待密码一样对待 `-s` / `STYX_SECRET`;在共享实验环境后请轮换密钥。wrapper **强制要求** `STYX_SECRET`(不存在弱默认值)。 - Payload 加密使用由 **HKDF-SHA256** 派生的 AES-256-GCM 密钥(controller 和 agent 必须运行匹配的版本)。 - 可选的 TLS(`-tls-enable`)会从共享密钥派生出稳定的证书并验证对端(仍需使用强密钥)。 - wrapper 默认监听 `127.0.0.1:19137`;仅在需要为远程 agent 提供服务时设置 `STYX_LISTEN=0.0.0.0:…`。 - 除非有意暴露,否则请将 SOCKS 绑定到 `127.0.0.1`。 - 上传路径允许绝对路径目标,但会拒绝 `..`;单文件最大传输限制为 32 MiB。 - MCP stdio 日志默认**关闭**;仅在调试时设置 `STYX_MCP_LOG=/path`(可能包含密钥信息)。 - 协议变更后,请基于同一个 commit 重新构建 controller **和** agent。 ## 项目结构 ``` cmd/controller/ controller + MCP entrypoint cmd/agent/ agent entrypoint scripts/ MCP wrapper, lab-scan-e2e.sh, lab_scan_smoke.go pkg/controller/ control plane, SOCKS / backward / scan tasks pkg/mcp/ MCP tools pkg/node/ agent handlers (incl. scan job) pkg/scan/ targets, discover, connect/SYN port check pkg/fingerprint/ light fingerprint + vuln ref table pkg/protocol/ wire protocol pkg/share/preauth/ HMAC mutual preauth ``` ## 致谢 - [Stowaway](https://github.com/ph4ntonn/Stowaway) - [fscan](https://github.com/shadow1ng/fscan) - [mcp-go](https://github.com/mark3labs/mcp-go) ## 许可证 [MIT](LICENSE)
标签:EVTX分析, Go语言, MCP协议, PE 加载器, SOCKS5代理, 内网穿透, 底层编程, 插件系统, 数据统计, 日志审计, 横向移动, 程序破解, 端口扫描, 编程规范