Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
cyber-decoy — 实验性诱饵代理 | Kitploit
工具/GitHubGitHub/secdev02/cyber-decoy
防御工具容器安全网络安全威胁情报入侵检测日志分析
GitHubsecdev02/cyber-decoy

cyber-decoy

实验性诱饵代理

查看仓库
31个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

cyber-decoy

一个容器化的网络诱饵(蜜罐),它通告SSH、RDP和SMB,通过eBPF观察每个入站连接,并将每个会话反向代理到隔离的诱饵容器中。

该设计分离了两个关注点:

  1. 观察。 一个附加到代理接口的 eBPF TC 分类器记录每个入站 TCP SYN,包括针对诱饵未提供服务的端口进行的扫描。这提供了对探测活动的完全可见性。
  2. 交互。 代理中的用户空间反向代理接受在通告端口上的连接,并为该服务打开到诱饵容器的匹配连接,双向传输字节并记录完整会话。

这是一个用于检测和研究您拥有或获授权监控的网络上的未授权活动的防御工具。请仅在您拥有该权限的地方部署。

架构

root@kitploit:~
flowchart TB
    A["攻击者 / 扫描器"]

    subgraph host["诱饵主机"]
        direction TB

        NIC["代理 eth0<br/>发布端口: 22, 3389, 445"]

        subgraph brk["代理容器"]
            direction TB
            E["eBPF TC 分类器<br/>记录每个 SYN<br/>看到真实源 IP"]
            P["反向代理<br/>连接到后端"]
            L["结构化 JSON 日志"]
        end

        subgraph dec["decoynet (内部网络,无主机路由)"]
            direction LR
            S["ssh-诱饵<br/>OpenCanary ssh<br/>端口 2222"]
            D["rdp-诱饵<br/>OpenCanary rdp<br/>端口 3389"]
            M["smb-诱饵<br/>Impacket SMB 服务器<br/>端口 445"]
        end
    end

    A --> NIC
    NIC --> E
    NIC --> P
    E --> L
    P --> S
    P --> D
    P --> M

总共四个容器:

容器角色网络
broker公共前门:eBPF 观察 + 反向代理edge + decoynet
ssh-decoyOpenCanary ssh 模块(真实握手,捕获凭据)仅 decoynet
rdp-decoyOpenCanary rdp 模块(NLA 模拟,捕获用户名)仅 decoynet
smb-decoyImpacket SimpleSMBServer(真实 SMB2/3,捕获认证信息)仅 decoynet

诱饵位于一个内部 Docker 网络(decoynet)上,该网络没有到主机或外部世界的路由。只有代理可以访问它们。攻击者在诱饵内所做的任何事情都无法直接到达主机网络。

eBPF 路由工作原理

代理将端口 22、3389 和 445 发布到主机,因此入站数据包到达代理的 eth0。然后每个数据包发生两件事:

  • eBPF TC 入口程序 (broker/bpf/decoy.bpf.c) 解析以太网、IP 和 TCP 头部,对于每个新的连接尝试(SYN 设置,ACK 清除),将一个 conn_event 写入环形缓冲区:源 IP 和端口、目标端口、TCP 标志,以及该端口是否为通告服务。数据包被原样传递 (TC_ACT_OK)。
  • 用户空间代理 在匹配的监听器上接受连接,并执行等效于 CONNECT 到该服务的诱饵后端的操作,然后双向中继字节。

advertised_ports eBPF 映射在启动时从 config.yaml 填充,因此分类器可以标记探测是否命中了提供服务的端口还是未请求的端口。这使得水平端口扫描可见,即使只有三个端口被代理。

如果您想通告“一切开放”并将任意目标端口 funnel 到代理中,可以扩展分类器以重写目标端口,或使用 TPROXY / bpf_sk_assign 重定向。当前版本保持数据包路径不变,仅局限于观察,这是更安全的默认设置。

仓库布局

root@kitploit:~
cyber-decoy/
├── README.md
├── docker-compose.yml         # 4 容器栈
├── docker-compose.override.yml # 本地 macOS 开发:无 eBPF 能力,端口 22 重映射
├── Makefile                   # build / up / down / bpf 辅助命令
├── LICENSE
├── scripts/
│   └── setup.sh               # 主机预检检查
├── broker/
│   ├── Dockerfile             # 编译 eBPF 对象 + Go 二进制文件
│   ├── config.yaml            # 通告的服务(可配置)
│   ├── go.mod
│   ├── main.go                # 入口点
│   ├── bpf/
│   │   └── decoy.bpf.c        # eBPF TC 分类器
│   └── internal/
│       ├── config/config.go   # 配置加载器
│       ├── proxy/proxy.go     # TCP 反向代理
│       └── bpf/loader.go      # 加载 + 附加 eBPF,流式处理事件
└── decoys/                     # 全部三个都运行 OpenCanary
    ├── ssh/
    │   ├── Dockerfile
    │   └── opencanary.conf     # ssh 模块,端口 2222
    ├── rdp/
    │   ├── Dockerfile
    │   └── opencanary.conf     # rdp 模块,端口 3389
    └── smb/
        ├── Dockerfile          # 单个 Python 进程,非 root
        ├── smb_decoy.py        # Impacket SimpleSMBServer + JSON 日志记录
        └── requirements.txt    # impacket(固定版本)

需求

  • Linux 主机,内核版本 6.6 或更高,用于 TCX eBPF 附加路径。在内核较旧的情况下,代理仍然运行;仅 eBPF 观察被跳过(代理会记录警告并继续)。
  • 带有 Compose 插件的 Docker Engine(如果使用附带的 docker-compose.override.yml,需要 v2.24+,因为它依赖于 !reset / !override 标签)。
  • 已挂载的 BPF 文件系统:sudo mount -t bpf bpf /sys/fs/bpf。

架构

代理镜像会检测其构建架构,并将匹配的 __TARGET_ARCH_* 宏传递给 clang,因此它可以在 x86_64 和 aarch64(Apple Silicon、Graviton)上构建。请注意,gcc-multilib 故意未安装:它是一个仅适用于 x86 的软件包,没有 arm64 候选版本,包含它会在 arm64 上导致 apt 退出代码 100 从而破坏构建。编译 eBPF 对象仅需要 clang 和 libbpf-dev。

在 macOS 上开发

macOS 上的 Docker Desktop 在 LinuxKit VM 内运行容器,而不是在您的宿主机内核上运行,因此 TC/TCX eBPF 附加通常无法在那里工作。但这并非致命:eBPF 被设计为尽力而为,因此代理会记录 ebpf disabled: attach failed,而反向代理和所有三个诱饵会正常运行并记录日志。您可以在本地开发和测试整个代理路径,然后在部署到 Linux 主机时获得真正的 eBPF 观察。

docker-compose.override.yml 会被自动加载,让这变得愉快:它删除 eBPF 能力(在 VM 中无用)并将主机端口 22 重映射到 2022,因为 Mac 自己的 sshd 占用了 22。

root@kitploit:~
docker compose up --build                    # 本地开发,覆盖应用
docker compose -f docker-compose.yml up -d   # 真实部署,绕过覆盖

首先运行预检检查:

root@kitploit:~
./scripts/setup.sh

快速开始

root@kitploit:~
# 1. 构建所有四个镜像(在代理镜像内编译 eBPF 对象)
make build

# 2. 启动栈
make up

# 3. 查看发生了什么
make logs

然后从另一台机器(或本地主机进行冒烟测试)探测它:

root@kitploit:~
ssh -p 22 user@DECOY_HOST          # 命中 SSH 诱饵
nc DECOY_HOST 3389                 # 命中 RDP 诱饵
nc DECOY_HOST 445                  # 命中 SMB 诱饵
nc DECOY_HOST 8080                 # 未通告:被 eBPF 观察,无代理

代理会为 eBPF 探测事件和代理会话输出 JSON;每个诱饵会输出 OpenCanary JSON 事件。要查看凭据落地:

root@kitploit:~
docker compose logs -f ssh-decoy | grep 4002

与仅显示横幅的桩程序不同,ssh -p 22 user@DECOY_HOST 现在完成真实的密钥交换并提示输入密码。每次尝试都会被捕获。验证服务指纹在版本检测下是否成立:

root@kitploit:~
nmap -sV -p 22,3389,445 DECOY_HOST

使用以下命令拆除:

root@kitploit:~
make down

配置

服务在 broker/config.yaml 中定义。每个条目可独立启用和重新映射:

root@kitploit:~
services:
  - name: ssh
    enabled: true
    listen_port: 22
    backend: ssh-decoy:2222

要添加服务,在此处添加条目,在 docker-compose.yml 中发布端口,并添加一个诱饵容器。要禁用一个,设置 enabled: false(并可选择删除其发布的端口)。

请注意,主机端口 22 通常被主机的真实 SSH 守护进程占用。对于实验室,您可以在 docker-compose.yml 中重新映射已发布的一侧,例如 "2022:22",然后将扫描器指向那里。

诱饵后端

所有三个诱饵都运行 OpenCanary(Thinkst),每个容器配置为仅启用一个模块。日志以 JSON 格式输出到 stdout,因此 docker compose logs 和任何 SIEM 发送器都可以无需额外管道工作。

事件类型

OpenCanary 为每个事件标记一个数字 logtype。您在此处将看到的事件:

捕获的 SSH 凭据如下所示:

root@kitploit:~
{"dst_port": 2222, "logtype": 4002, "node_id": "decoy-ssh",
 "src_host": "10.0.0.66", "src_port": 42958,
 "logdata": {"USERNAME": "admin", "PASSWORD": "Passw0rd123"}}

重要:诱饵无法看到攻击者的 IP

这是代理架构的直接后果,也是理解这些日志最重要的一个点。

代理终止了攻击者的 TCP 连接,并打开了一个新的连接到诱饵。因此,从 OpenCanary 的角度来看,客户端是代理。诱饵事件中的每个 src_host 都是代理在 decoynet 上的地址,而不是真正的源地址。

真正的源 IP 仍然被捕获,只是位置不同:

因此,归因需要关联代理日志和诱饵日志,通过时间戳和服务进行连接。代理为每个会话记录 remote(真实的攻击者地址)和 backend,这使得关联成为可能:

root@kitploit:~
docker compose logs broker    | grep 'session opened'   # 谁
docker compose logs ssh-decoy | grep '"logtype": 4002'  # 他们尝试了什么

如果您需要在诱饵内部获取真实 IP,选项包括发送 PROXY 协议(诱饵不解析它,因此这意味着需要修补它们),或者将用户空间代理替换为保留原始源地址的透明重定向(TPROXY 或 eBPF bpf_sk_assign)。两者都在路线图中列出。在此之前,将代理视为“谁”的事实来源,将诱饵视为“什么”的事实来源。

SMB 诱饵(Impacket,非 Samba)

与 SSH 和 RDP 不同,此诱饵不使用 OpenCanary。OpenCanary 的 smb 模块只是一个日志监视器:它 tail 一个文件并解析真实 Samba 服务器发出的 smbd_audit 行,这意味着要在 supervisord 下运行 Samba 加 rsyslog 加 opencanaryd,这是一个五链式链接,其中任何一环都可能静默失效。

smb-decoy 将所有这一切替换为基于 Impacket 的 SimpleSMBServer 的单个 Python 进程,这是一个 SMB1/2/3 的纯 Python 实现。它绑定 445,提供只读诱饵共享,应答 SMB2/3 协商(因此 nmap -sV 看到真实服务),并将连接和 NTLM 认证尝试作为每行一个 JSON 对象记录到 stdout。攻击者认证消息中捕获的用户名、域名和工作站是凭据捕获的回报。

安全说明:Impacket 的 smbserver 存在一个关键的路径遍历漏洞 CVE-2021-31800,该漏洞特别影响蜜罐。该漏洞已在 0.9.23 中修复。requirements.txt 固定了一个当前版本,并且不得降级到该版本以下。该容器还以非 root、只读方式运行,并且除了 NET_BIND_SERVICE 之外的所有能力都被删除。

配置诱饵

每个诱饵拥有一个 opencanary.conf(安装到 /etc/opencanaryd/)。有用的旋钮:

  • SSH 横幅:decoys/ssh/opencanary.conf 中的 ssh.version。它目前声称 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.1。让它与您假装的操作系统匹配;在声称是 Windows 的盒子上显示 Ubuntu 横幅是一个破绽。
  • SMB 共享名称:decoys/smb/smb_decoy.py 中的 addShare(...) 调用,以及 decoys/smb/Dockerfile 中创建的诱饵文件。共享名称和文件名是诱饵。
  • 端口:确保这些与 broker/config.yaml 中的 backend 对齐。

要启用另一个 OpenCanary 模块(ftp、telnet、mysql、vnc、redis 等均可使用),设置 <module>.enabled 和 <module>.port,添加一个诱饵容器,并在 broker/config.yaml 中添加一个匹配的服务。

SSH 主机密钥持久化

ssh-decoy 在 /var/lib/opencanary 挂载了一个命名卷(ssh.key_path),因此生成的主机密钥在重启后保持不变。没有它,OpenCanary 会在每次启动时生成新密钥,不断变化的指纹是一个明显的破绽。

SMB 诱饵故障排除

SMB 诱饵现在是一个单个进程,因此故障排除非常直接。

root@kitploit:~
docker compose logs -f smb-decoy

每一行都是 JSON。启动时应该看到一条 smb_decoy_start 消息,然后随着客户端交互,会看到 smb_connect、smb_auth_attempt 和 smb_tree_connect 事件。从主机使用任何 SMB 客户端测试:

root@kitploit:~
# macOS Finder: 前往 > 连接到服务器
open 'smb://guest@localhost/HR-Payroll'
# 或从 Linux
smbclient -L //localhost -p 445 -N

常见问题:

  • 没有 smb_decoy_start 行且容器退出:检查 requirements.txt 是否安装干净。Impacket 需要 Python 3.8+;镜像使用 3.12。
  • 可以连接但没有 smb_auth_attempt:某些客户端匿名枚举共享而不进行身份验证。这仍然会产生 smb_connect 和 smb_tree_connect。通过使用用户名映射共享来强制身份验证。
  • 与其他诱饵一样,src_host 是代理的地址,而不是真正的攻击者。通过时间戳与代理日志关联。

安全说明

  • 能力。 代理需要 NET_ADMIN(以及较新内核上的 BPF / PERFMON)来加载和附加 eBPF 程序。Compose 文件请求了这些范围的能力。如果您的主机或 Docker 版本拒绝它们,后备方案是在代理服务上使用 privileged: true,这更宽泛,应仅在范围能力不起作用时使用。
  • 隔离。 诱饵位于一个没有主机路由的 internal 网络上。请保持这种状态。将每个诱饵容器视为可能已被攻破。
  • 爆炸半径。 将整个栈运行在与生产环境隔离的主机上。诱饵是诱饵;假设攻击者会与之交互。
  • 法律。 仅在您拥有或获授权防御的基础设施上进行监控和欺骗。

路线图想法

  • 通过 TPROXY 或 bpf_sk_assign 保留攻击者的源 IP 到诱饵中,消除关联代理和诱饵日志的需要。
  • 通过 eBPF 目标重写或 TPROXY 实现全端口 funnel。
  • 每个连接的会话捕获到 PCAP。
  • 将事件发送到 SIEM(JSON 日志已经为此结构化)。
  • 代理中的速率限制和连接配额。

许可

MIT。请参阅 LICENSE。

下载工具
容器OpenCanary 模块监听端口实际功能
ssh-decoyssh2222通过 twisted.conch 进行真实 SSH 密钥交换。捕获每个用户名/密码对。
rdp-decoyrdp3389模拟启用 NLA 的服务器,总是返回登录失败,提取 mstshash 用户名。
smb-decoyImpacket445纯 Python SMB2/3 服务器。提供诱饵共享并以 JSON 格式记录连接和 NTLM 认证尝试。
logtypeopencanary/logger.py 中的常量含义
1000LOG_BASE_BOOT守护进程启动
4000LOG_SSH_NEW_CONNECTIONSSH 连接已打开
4001LOG_SSH_REMOTE_VERSION_SENT客户端发送其版本字符串
4002LOG_SSH_LOGIN_ATTEMPTSSH 登录尝试(包含 USERNAME 和 PASSWORD)
5000LOG_SMB_FILE_OPENSMB 文件已打开(包含 USER、SHARENAME、FILENAME)
14001LOG_RDPRDP 连接 / 登录尝试
层知道真实源 IP?知道尝试了什么?
eBPF 分类器(probe observed)是否,仅 SYN 元数据
代理代理(session opened)是否,仅字节计数
OpenCanary 诱饵(logtype 4002)否是,凭据/文件