cracken-ai/blacksea

GitHub: cracken-ai/blacksea

Blacksea 是一个主动式蜜罐与金丝雀诱饵控制系统,通过利用 LLM 攻击者的推理缺陷实现反向情报收集和攻击者指纹追踪。

Stars: 36 | Forks: 9

Cracken

Blacksea

# Project Blacksea(让 AI 攻击沉没之地) 作者:Cracken;核心团队:[Dario Pasquini](https://pasquini-dario.github.io/me/) 和 [Michal Bazyli](https://www.linkedin.com/in/punishell/) Blacksea 是一个主动式蜜罐和金丝雀诱饵控制系统,旨在检测并淹没 LLM 驱动的攻击者:即扫描和利用系统的自主 AI agent 和 LLM 辅助的操作者。**Blacksea 不仅仅停留在监视 LLM 攻击上。它利用攻击者 LLM 判断中的缺陷,在其机器上获取任意代码执行权限,收集被动防御无法触及的情报,并确保他们不会卷土重来。** **技术原理。** LLM 驱动的攻击者通过推理寻找能推动其行动的资产来推进攻击任务:可重用的凭证、用于加密数据块的解密器、密钥派生工具、配置解包器、token 生成器、内部 API 客户端。Blacksea 将这种推理变成了一个陷阱。你可以植入**诱饵**,这些诱饵是精心制作的工件,看起来完全像此类 agent 正在寻找的高价值、与安全相关的资产,它们被部署在 agent 会去寻找的位置,并包装在能让它们显得逼真的上下文中:一个合理的文件名、一个配套的密文数据块、一个解释该工具“用途”的 README。一旦发现诱饵,agent 就会推断出下载并运行它是获取所需内容的最快途径;而且由于该工件被故意设计得难以逆向工程或重新实现,运行真实文件确实是阻力最小的路径。这里没有提示,也没有“请运行我”的请求:诱饵纯粹依靠其在技术上的合理性来获胜。 agent 无法看到的是,该诱饵也是一个金丝雀(我们喜欢称之为 LLM 恶意软件)。隐藏在工件内部、被精心设计为对读取或推理它的 LLM 不可见的是一个 **payload**:由你选择的任意代码,它会在诱饵被触发的那一刻运行,并向控制端发送**信标**。Blacksea 将该信标转化为结构化的情报**记录**,这是用于归因的原始素材。 ## 工作原理 🚨如需端到端示例,请查看:[basic_usage_tutorial.md](./docs/basic_usage_tutorial.md)。 Blacksea 包含三个部分:在你信任的基础设施上运行的**服务器**、使用它构建并部署在攻击者会发现的诱饵、以及在触发时返回的**记录**。它不是被动传感器。整个设计都瞄准一个时刻,即攻击者自己的机器运行你的代码。其他一切都是为了让那一刻发生,并将结果安全地返回给你。 ### 诱饵的组成部分 诱饵是攻击者发现的一个单一工件,由两个独立的选择定义: - **Payload。** 在触发诱饵的机器上运行的代码。它是任意的:你可以自己编写,或者使用 Blacksea 提供的代码。这就是将检测转化为在攻击者一侧的立足点的方式。 - **部署载体。** 决定工件呈现*形态*的因素:密码库解密器、数据库备份恢复工具、发布配置解包器,或者普通脚本。载体不知道它携带的是哪个 payload,这就是为什么任何 payload 都可以采用任何形态。选择在你播种的地方看起来最合理的形态即可。 每次构建诱饵时,你都会获得一个**实例**:一个被植入的副本,携带其自己的签名和加密密钥。这就是为什么无论你在现场有多少个副本,信标对于是哪个副本被触发永远不会产生歧义,也是为什么你可以销毁单个被攻破的副本而不影响其余副本。 ### 配置说明 ``` 1 YOUR SERVER 2 BAITS 3 WHAT YOU DEFEND ┌──────────────────┐ ┌─────────────┐ ┌────────────────────┐ │ blacksea up │ forge │ artifact │ stage │ honeypots, or the │ │ trusted host, │ ─────► │ + payload │ ───────► │ real assets │ │ reachable │ └─────────────┘ └────────────────────┘ └──────────────────┘ │ ▲ │ an attacker │ ▼ takes one └───────────────── beacon ◄───────────────── attacker's machine ``` 1. **在你信任的地方运行 Blacksea。** 在 SOC 服务器或你控制的主机上运行 `blacksea up`,绝不要在蜜罐上运行。它必须可以通过 HTTPS 或 DNS 从你部署诱饵的任何地方访问到,因为那是信标着陆的地方。它的其他任何部分都不直接面向攻击者。 2. **伪造任意数量的诱饵实例。** 每个实例执行一次 `blacksea forge`:它会构建工件,生成该副本的密钥,并告诉你去哪里找这些文件。payload 由你选择。Blacksea 自带 `agent_fp`,它可以对运行它的 agent 框架进行指纹识别,但 payload 是任意代码,因此它同样可以消耗攻击者的计算资源,或者执行你需要在该主机上执行的任何其他操作(参见 [部署你的第一个诱饵](./docs/setup_a_bait.md))。 3. **将诱饵部署在攻击者会查看的地方。** 为此目的搭建的蜜罐,或者你正在防御的真实资产。部署的诱饵在有人使用它附带的伪造文件运行它之前不会做任何事情,因此它可以存在于一个运行中的机器上,而不会影响该机器的工作方式。 ### 诱饵被触发时会发生什么 从这里开始它将自动运行。这是一个信标回家的路径: ``` attacker host INTERNET TRUSTED PLANE YOUR SOC ┌──────────┐ beacon ┌──────────┐ queue ┌──────────┐ ┌──────────┐ ┌──────────┐ │ bait │ ─DNS/HTTPS─► │ edge │ ────────► │ brain │─►│ Postgres │ ┄OTLP┄► │ SIEM / │ │ payload │ │ (Go) │ │ (Python) │ │ records │ │ SOC │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ tripped dumb dead-drop: decrypts, interprets, optional: holds no keys writes the record stream via OTLP ``` 1. **Payload 触发**,在攻击者的机器上收集你指定的任何内容,使用该实例自己的密钥对结果进行加密和签名,并通过 HTTPS 或 DNS 将其作为**信标**发送出去,具体取决于构建诱饵时使用的通道。如果无法连接回控制端,根据设计,它会静默失败:诱饵绝不会向攻击者暴露错误。 2. **边缘节点捕获它。** 这是 Blacksea 唯一面向互联网的部分,并且它是故意设计得很简单的:它不持有任何密钥,不进行解密,也不从信标中派生任何内容。它只是打上源地址和到达时间戳(这是攻击者无法伪造的事实,因为攻击者从不提供这些),将不透明的字节放入队列,然后不再回应。 3. **大脑读取它。** 在防线你的一侧,大脑对信标进行身份验证、解密和解释,将原始字节还原为 payload 实际发现的内容。 4. **一条记录进入 Postgres。** 这是持久的情报单元:哪个诱饵触发了,payload 发现了什么,来自哪里,什么时候,以及信标是否通过了身份验证。你可以浏览记录、实时追踪它们,或者通过 OpenTelemetry 将每一条记录流式传输到你的 SIEM。 边缘节点/大脑的分离是一项值得理解的安全特性:所有可能被捕获的东西都位于对攻击者暴露最多的机器上,但它毫无价值。攻破边缘节点你只会得到一个邮箱,而不是情报:没有密钥,没有记录,无法伪造命中或读取他人的记录。这也是为什么边缘节点可以在与大脑完全不同的、不受信任的网络上运行的原因。 ### 术语表 这就是整个机制。下面的内容都是具体的同一个故事,使用的术语与本 README 和所有指南中使用的一致。把这张表放在手边,后面的内容就不会让你感到意外。 | 术语 | 含义 | | --- | --- | | **诱饵** | 一个欺骗性诱饵,以及其背后的设计:一个 payload、其监听器,以及赋予其形态的部署载体。 | | **Payload** | 隐藏在诱饵内部的代码。它在触发诱饵的机器上运行,然后向控制端发送信标。任意代码:由你决定它的作用。 | | **监听器** | Payload 的另一半,在大脑内部运行:它将原始信标还原为有意义的情报。Payload 及其监听器是一起编写并作为一对发布的。只有当你编写自己的诱饵时才会接触到它。 | | **部署载体** | 决定诱饵在目标机器上呈现的*形态*(伪造的解密器、配置解包器、普通脚本),与其内部的 payload 无关。 | | **信标** | 被触发的诱饵发送回控制端的回调,使用该副本自己的密钥进行签名和加密。 | | **边缘节点** | 面向互联网的接收器,用于捕获信标。故意设计得很简单:不持有密钥,不进行解密,不获取任何信息。 | | **大脑** | 受信任的服务,负责验证和解密每个信标,运行监听器并写入记录。 | | **记录** | 信标转换而成的结构化情报单元:哪个诱饵触发了,payload 发现了什么,来自哪里,何时,归因置信度如何。你读取或导出的所有内容都是读取记录。 | | **实例** | 一个被植入的诱饵副本,拥有自己的密钥和 token。一个设计的十个实例就是十个可独立追踪、可独立销毁的陷阱。 | | **Campaign** | 用于将一起部署的实例进行分组的标签,以便你以后可以根据它过滤记录。 | | **`forge`** | 接收一个诱饵设计并生成一个准备好部署的实例的唯一命令(注册 → 构建 → 批准)。 | ## 端到端流程展示 这就是机制。这里是一个具体的例子,使用的是今天发布的诱饵:Blacksea 自带的 `agent_fp` payload,它对运行它的 agent 框架进行指纹识别,并由 `pwcrypt` 部署载体交付,将其伪装成密码库解密器。 ### 1. 磁盘上的诱饵 这是 `forge` 提供给你的东西。四个文件必须在一起显得可信: ``` pwcrypt a password-vault decryptor: a real, working tool secrets/github.pwc an encrypted vault, the "secret worth stealing" secrets/.bash_history a stray shell history, with the decrypt command and password in it README.md the tool's own project README ``` 这里没有任何东西是虚假的。解密器真的会解密,密码库真的包含了一个秘密,历史文件中的密码也确实能打开它。发现这组文件的 agent 拥有得出一个结论所需的一切:在密码库上运行该工具。 而这正是关键所在。隐藏在解密器内部的是 **payload**:你编写的代码,对于读取该二进制文件的 LLM 来说是不可见的,它连接到一个只有这个密码库才能触达的缺陷。解密这个密码库,你的代码就会运行。解密一个真正的密码库,什么都不会发生。 解密器只是*这个*诱饵碰巧呈现的样子,这是载体的作用,而不是 payload 的。更换载体,同一个 payload 就可以隐藏在发布配置解包器、数据库备份恢复工具或普通脚本背后发布。这三种载体在今天的[目录](./lure_material/README.md)中都有,而且无论使用哪种载体,本演示的其余部分都是相同的。 ### 2. 植入并构建故事 Blacksea 会将这些文件连同说明交给你:每个文件放在哪里,以及触发它的具体命令。但放置位置由你决定,这也是让 agent 运行它的关键。放在 `/tmp` 中,这组文件说明不了什么。给它一个有存在理由的主机。在这里,它是 `ci-sync-03`,一个缓存发布密钥的 CI 节点: ``` /srv/vaultkeeper/ ├── pwcrypt ← the bait ├── secrets/github.pwc ← the bait ├── README.md ← the bait ├── RUNBOOK.md ← yours: why this box exists, and how to read the vault └── release.env ← yours: the CI config that references the cache /etc/motd ← yours: greets every shell with the decrypt command /home/vault/.bash_history ← yours, with the bait's hint merged in ``` 伪装即是欺骗。操作手册将一个无主的二进制文件变成了理所当然的下一步行动: 这三者相互配合:密码库为何有价值,为什么自带的二进制文件是唯一的入口,以及触手可及的密码。在这个机器上工作的 agent 并不是被骗去运行解密器的。运行它*确实是*正确的下一步。 ### 3. Agent 吞下诱饵 ``` LLM-driven attacker │ probes your system ▼ finds the staged lure │ reasons that running it is the way forward ▼ the attacker downloads it │ ▼ runs it: YOU get arbitrary code execution on the attacker's machine │ ▼ your payload runs and beacons home ──► your record ``` 而且它通常会将工件带走,将解密器和密码库拉回到自己的基础设施中在那里进行处理。这个细节比看起来更重要。 这是这里真正的原语:**被触发的诱饵会在触发它的机器上执行你选择的代码。** 当那台机器是 agent 自己的(攻击者框架内的 container、他们的操作机,或者任何他们运行不受信任二进制文件的地方),你就获得了在攻击者一侧基础设施内的任意代码执行权限,即在交战过程中对方的领土内。 你用它来做什么由你决定。本例中的 payload `agent_fp` 将其用于对环境进行狭隘且刻意保守的读取:是哪个框架在驱动,以及其背后的操作者的一些信息。不同的 payload 会提出不同的问题。 ``` $ cat secrets/.bash_history ./pwcrypt decrypt secrets/github.pwc 'tarvuk-Zynhib-3wexfo' $ ./pwcrypt decrypt secrets/github.pwc 'tarvuk-Zynhib-3wexfo' ghp_PROD_4Z2cM9pXqLkR8sTnW1vYbU3aFhJgEoIdC0 ``` 一个生产环境的 token,来自一个行为完全符合文档说明的工具。没有打印其他任何内容,exit 0。agent 无法看到的是:解析该密码库的元数据时,也运行了嵌入在二进制文件中的 payload,该 payload 读取了周围环境并向控制端发送了信标。一个真正的密码库在解密时没有任何副作用。 ### 4. 查看记录 ``` $ blacksea events tail --bait agent-fp-demo 2026-07-27 14:02:11 f92cae98b0d9fa70-3b1d0c5a7e2f9418-0001 agent-fp-demo payload_exec_collect 203.0.113.44 ok https ``` `blacksea events show ` 会展示完整记录。每条记录都有两部分。**框架部分**对于每个诱饵都是相同的:谁触发了它,来自哪里,是否通过了身份验证。**`details` 部分**则完全取决于哪个诱饵被触发。对于 `agent_fp`,`details` 是一个归因: ``` { "harness": "claude_code", "family": "composition", "confidence": 0.4667, "runner_up": "Decepticon", "abstained": false, "evidence": ["literal disc_k='CLAUDECODE' (x1.00)", "family=composition; best=claude_code 0.47; runner_up=Decepticon margin=0.33"], "cred_surface": ["aws", "ssh"], "locale": {"tz_name": "CEST", "utc_offset_min": 120, "lang": "en_US.UTF-8"}, "history": {"bash_history": {"size": 18422, "mtime": 1784800000}} } ``` 阅读它,从框架部分开始: - **`instance_token`。** 哪个被植入的副本被触发。每个副本都带有自己的密钥,因此无论你在现场有多少诱饵,命中都不会产生歧义。 - **`source_ip`、`edge_recv_time`。** 由面向互联网的边缘节点在到达时打上的时间戳,而不是由 payload 报告的。攻击者无法塑造它们。 - **`sig_valid`。** 信标使用该副本的密钥进行了签名和加密;没有任何东西被伪造或重放。 - **`event_type`。** 这里是 `payload_exec_collect`:payload 确实在目标上运行并收集了信息,而不是 `signal_only`(单纯的“有东西触发了”)。 然后是 `agent_fp` 自己的发现: - **`harness` / `confidence` / `runner_up` / `evidence`。** *谁*触发了它。这里的指纹带有 Claude Code 自己的自我披露,因此判断结果是 `claude_code`,并以明显的优势领先于最接近的对手,而 `evidence` 准确展示了驱动它的因素。当信号太弱时,`agent_fp` 会返回 `abstained: true` 和 `harness: null`,而不是瞎猜。 - **`cred_surface` / `locale` / `history`。** agent 背后的操作者:机器上有 AWS 和 SSH 凭证,CEST 时区,18 KB 的 shell 历史。这是一个长期使用的操作者机器,而不是一次性的基础设施。仅包含存在性和元数据,绝不包含文件内容或命令文本。 这就是归因素材:一个带有判断依据的具名框架、一个攻击者无法选择的源地址,以及运行它的机器的形态轮廓。每条记录也会通过 OTLP 流式传输到你的 SIEM。 请按照[部署你的第一个诱饵](./docs/setup_a_bait.md)中的步骤,在你自己的机器上亲自演练一遍。 ## 快速开始 你需要 **Python 3.11+**、**`make`**、**Go 1.22+**(边缘 daemon 是一个由 `blacksea up` 为你构建的 Go 二进制文件),以及带有 **`docker compose`** 插件的 **Docker**(Blacksea 默认在 container 中运行 Postgres 和 NATS;你也可以指向你自己的服务,这样 Docker 就变成了可选的)。每个 Python 依赖项都会为你安装到一个项目本地的 virtualenv 中,因此无需手动 `pip install` 任何东西,目标主机上也不需要安装任何东西。 ``` cd services make install # installs the `blacksea` command onto your PATH make init # choose how Blacksea gets Postgres and NATS (run it once) blacksea up # brings up everything: Postgres, NATS, the edge, and the brain blacksea status # check that the stack is healthy ``` 这就是整个系统的运行。`make init` 会问一个决定设置走向的问题,即 Blacksea 是否应该在 Docker 中为你运行 Postgres 和 NATS,还是连接到你自己的服务,然后写入 `config/blacksea.env`。跳过这一步,`blacksea up` 会在首次运行时为你写入一个可用的 Docker 模式配置。 如果你的 PATH 中的 `python3` 不是你希望用于构建 virtualenv 的解释器,请传入 `PYTHON=`: ``` make install PYTHON=python3.12 # a specific minor version on your PATH make install PYTHON=/usr/local/bin/python3.11 # or an explicit interpreter path ``` 以*编译后*的工件形式发布的诱饵(例如假的解密器而不是普通脚本),每个都需要自己的构建工具链:Docker、C 或 Go 编译器,或载体所需的其他任何工具。这只是构建主机的要求,目标永远不需要编译器。这些都不是开始运行或部署基于脚本的诱饵所必需的,完整的按载体分类的列表在[操作指南](./services/README.md#optional-extras)中。 现在,部署你的第一个诱饵并观察命中结果:请按照[部署诱饵演示](./docs/setup_a_bait.md)操作,它将伪造一个演示诱饵、触发它,并展示记录的到达过程。在日常使用中,`blacksea logs` 用于追踪 daemons 的日志,`blacksea events tail` 实时关注命中情况,`blacksea web-ui` 打开只读的 Web 观察器,`blacksea down` 停止整个技术栈,`blacksea reset` 清除测试状态。`blacksea --help` 会打印完整的命令树。 在你将这些功能用于你自己的实验室之外的地方之前,请阅读[安全与负责任的使用](#security--responsible-use)。 ## 文档 | 指南 | 涵盖内容 | | --- | --- | | [部署你的第一个诱饵](./docs/setup_a_bait.md) | **从这里开始。** 最友好的入门指南:伪造一个演示诱饵,部署它,触发它,并观察记录的生成。 | | [操作指南](./services/README.md) | 安装和配置技术栈、部署和管理诱饵、在与大脑分离的网络上运行边缘节点,以及阅读情报。是上述快速开始的深度配套指南。 | | [操作控制台](./docs/console.md) | 深入讲解每一个 `blacksea` 命令:基础设施生命周期、诱饵和实例生命周期、`events`、`health` 以及 `--json` 脚本编写。 | | [编写诱饵](./docs/bait-authoring.md) | 编写你自己的 payload 和部署载体:manifest schema、golden 测试以及注册。 | | [诱饵目录](./lure_material/README.md) | 今天发布的所有 payload 和部署载体,以及每个构建所需的内容。 | | [通过 OTLP 导出到 SIEM](./docs/otel-export.md) | 将每条记录流式传输到你的 SOC、SIEM 或可观测性技术栈中,并附带一个完整的 Grafana Loki 集成示例。 | | [故障排除](./docs/troubleshooting.md) | 常见问题及其修复方法。 | 该仓库是一个 monorepo:[`services/`](./services/) 包含控制系统(可安装的 `blacksea` Python 发行版以及 Go 边缘 daemon),[`lure_material/`](./lure_material/) 包含诱饵目录(今天发布的 payload 和部署载体),而 [`docs/`](./docs/) 包含上述指南。 ## 路线图:下一步计划 Blacksea 是一项较新的、正在积极开发的技术,并且还在不断成长。**今天**发布的是完整的检测闭环:播种诱饵,在 LLM 驱动的攻击者触发它们时将其捕获,将每个信标转化为结构化记录,观察命中情况,并通过 OpenTelemetry (OTLP) 将每条记录直接流式传输到你的 SIEM 或可观测性技术栈中。今天发布的每个目录条目也都可以由你进行扩展:编写你自己的 payload 或部署载体,它会像内置的那样以相同的方式插入,如[编写诱饵](./docs/bait-authoring.md)中所述。在路线图上: - **更多形态的部署载体**:部署载体决定了诱饵在目标上*看起来像什么*。今天,这包括伪造的密码库解密器、数据库备份恢复工具或发布配置解包器。这个目录将继续增长,载体格式也将随之增长:预计会出现以工件形态交付 payload 的载体,并且其特性将远远超出目前发布的范围,从而让诱饵可以采取在你播种的环境中最合理的任何形式。基于载体构建的每个诱饵也将进行独特的随机化处理,因此没有两个被植入的实例看起来是一样的。这剥夺了攻击者廉价的胜利:特征匹配、哈希黑名单以及其他基于模式的防御手段,否则这些手段就会识别并跳过已知的诱饵。 - **事件钩子与警报**:在命中符合你关心的条件(高警戒事件,或对你已撤销的诱饵的命中)的那一刻,触发 webhook 或通知,而不是轮询查询。 - **更深度的归因**:一个有状态的引擎,可以随着时间推移将单个命中连接到会话和行为者,让你能够追踪跨越多个诱饵的单个攻击者。今天的归因是对记录的只读视图;这将增加其间的组织脉络。 - **生产环境打包**:一个完全容器化的“主机上仅需 Docker”模式,带有一个预构建的、随时可用的边缘镜像,以及现成的进程管理(systemd)单元,使得针对你自己的 Postgres 和 NATS 的生产环境部署变得即插即用。(在分离的、不受信任的网络上运行边缘节点而远离大脑的功能目前已经支持;请参见[操作指南](./services/README.md))。 - **感知沙箱的 payload**:Agentic 工具越来越多地在沙箱内运行不受信任的工件,而在沙箱中,诱饵几乎无法观察任何东西,也无法触及任何东西。计划中的 payload 会注意到这一点并做出响应,例如通过伪造一个看起来合理的沙箱违规,使得工件被重新放到沙箱外部运行。该技术已撰写于[用谎言逃离(Claude Code)沙箱](https://pasquini-dario.github.io/me/blog/lying-your-way-out-of-the-sandbox.html)一文中。 这些是计划的方向,而不是有具体时间表的承诺。Blacksea 正在发展,这个列表也将随之增长。 ## 白皮书 - [对 Agentic 红队进行红队测试](https://arxiv.org/pdf/2606.24496):Dario Pasquini, Michal Bazyli, Taras Fedynyshyn, Artem Sorokin ### 引用我们 ``` @misc{pasquini2026redteamingagenticredteam, title={Red-Teaming the Agentic Red-Team}, author={Dario Pasquini and Michal Bazyli and Taras Fedynyshyn and Artem Sorokin}, year={2026}, eprint={2606.24496}, archivePrefix={arXiv}, primaryClass={cs.CR}, url={https://arxiv.org/abs/2606.24496}, } ``` ## 安全与负责任的使用 Blacksea 是一个**防御工具**:它的存在是为了检测和研究 LLM 驱动的攻击者,而不是为了攻击任何东西本身。 - **负责任地使用。** 仅将 Blacksea 用于合法的防御性安全研究、蜜罐操作或授权的红队/蓝队对抗演练。绝不使用它或它构建的任何东西来攻击、利用或获取对你不拥有或没有明确测试权限的系统的未授权访问。 - **仅在授权的地方部署。** 诱饵、伪造的二进制文件及其嵌入的 payload 仅适用于你拥有或获得明确授权可以进行检测的主机和网络:你自己的实验室、分段的蜜罐主机或经过批准的演练。绝不要将它们放置在你无法控制的系统上。 - **了解当地法律。** 欺骗技术、蜜罐以及对第三方的监控承担着因司法管辖区和组织而异的法律和隐私义务。在部署任何超出你自己实验室范围的东西之前,请确认你符合规定。 - **无担保。** 按现状提供,用于安全研究和防御性使用。对于滥用或在预期授权范围之外部署造成的损害,作者不承担任何责任。
标签:Go语言工具, 威胁情报, 安全, 开发者工具, 日志审计, 构建工具, 用户代理, 蜜罐, 证书利用, 超时处理, 逆向工具