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

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

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

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

工具目录

分类

查看所有分类
Loading categories
honeyslop — 用于快速筛查幻觉(‘劣质’)漏洞报告的代码金丝雀 | Kitploit
工具/GitHubGitHub/gadievron/honeyslop
防御工具静态分析漏洞分析代码分析威胁情报供应链安全错误配置学习与教育事件响应
GitHubgadievron/honeyslop

honeyslop

用于快速筛查幻觉(‘劣质’)漏洞报告的代码金丝雀

查看仓库
97103个月前Kitploit 审核通过

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

honeyslop - 代码金丝雀,用于快速分类由人工智能幻觉("slop")产生的漏洞报告

HoneySlop

honeyslop 是代码金丝雀、诱饵,用于那些被人工智能幻觉("slop")和未经验证的漏洞报告淹没的开源项目。通过这种对抗性噪声注入,slop扫描器会摄取金丝雀,然后基于它生成一份漏洞"报告"。该报告自我识别为 slop。一个 grep 即可关闭它。

这是一个快速的 PoC,以玩笑方式 vibe-coded(非生产级),因为我们在 raptor(一个基于 Claude Code 的自主攻击/防御代理)上也收到了 slop 报告。应该会很有趣!

代码金丝雀将熟悉的分诊信号(例如测试文件中的检测、示例密钥、不存在的路径)扩展为精心设计的标记或诱饵。在测试中,这些金丝雀足以标记 slop,但可以进一步改进(嵌入到真实代码中,函数/文件/目录名称不那么明显,定期重新生成新代码等)。

作者:Gadi Evron (@gadievron)、John Cartwright (@grokjc)、Daniel Cuthbert (@danielcuthbert) 和 Michal Kamensky (@kamenskymic,感谢为项目命名)。

使用风险自负。 如果你将其粘贴到生产环境中,那是你的问题。请参阅下面的免责声明。

分诊规则

对于每个传入的报告,按顺序:

  1. 在报告中 grep 任何金丝雀 UUID → 关闭。(UUID 是按语言分配的;每个金丝雀文件恰好嵌入一个。)
  2. grep 金丝雀专用函数名称(zqx_tarnish_v3、zqxTarnishV3、_validate_pep_440_plus;如果你私下采用了 F+G,还有 handle_*_request)→ 关闭。(Rust 使用与 Python 相同的蛇形命名 zqx_tarnish_v3。Go 使用 zqxTarnishV3,与 JS 名称匹配。)
  3. grep CVE-2025-99919(假的)→ 关闭。
  4. 引用的函数在代码树中不存在 → "does not exist"。
  5. 对于 B/D 上的 memcpy/边界声明:要求报告者解释他们的 PoC 如何绕过所引用行上的特定防护。AI 后续无法回答;人类可以。

阶段

两类金丝雀:

  • SCANNER-FLAG(阶段 A、B、C、D、E)— 触发扫描器,使 slop 报告堆积在金丝雀上而不是真实代码上。
  • RESOURCE-WASTE(阶段 F + G,一起)— 以最大成本耗尽代理 LLM 扫描器的完整迭代预算。

请参阅安全模型了解每个阶段尽管看起来有漏洞但如何保持惰性。

安全模型

金丝雀代码文件故意读起来像是合理的已弃用模块——注释或标识符中没有"金丝雀"、"蜜罐"或"绊线"之类的语言。这防止文件向扫描器自我识别,但也意味着这些文件为何安全的文档生活在这里,而不是在每个文件的文档字符串中。在审查或轮换金丝雀时,检查下面的每一层是否仍然完好。

这些文件是有漏洞形状的代码——其中一些(例如 python/session_restore.py 的 pickle.loads,c/tls_heartbeat.c 的无界 memcpy)如果可达则真正可利用。这是设计。扫描器标记接收器正是关键点;下面的层阻止执行,而不是扫描器信号。基于模式的扫描器(grep、semgrep、基于 LLM 的 slop 管道——主要威胁模型)将源代码作为文本来读取并呈现发现,无论运行时是否可达。构建集成的 C 扫描器(CodeQL 默认、clang-static-analyzer)只看到编译后的文件,因此未构建的 C 金丝雀对它们不可见——这是一个可接受的权衡,因为 slop 生成器压倒性地读取源代码,而不是构建产物。

阶段 A 和 E(Python + JS)

五个独立层使这些文件保持惰性:

  1. 顶层 raise ImportError / throw new Error — 简单的 import / require 在任何定义绑定之前中止。
  2. if False: / if (false) 下的每个 def/函数 — 即使第1层被绕过,名称也从不进入运行时命名空间。
  3. 空导出 — Python:__all__: list[str] = [](星号导入不导出任何内容)。JS:module.exports = {}(CommonJS 消费者得到一个空对象)。
  4. 树内零个调用者引用暗号函数(zqx_tarnish_v3、zqxTarnishV3、_validate_pep_440_plus)。任何引用其中一个的报告都会自我识别为 slop。
  5. 部署隔离 — 采用者将金丝雀路径从 sdist / wheel / Docker / SAST 中排除(请参阅 SECURITY.md.template 和)。

E阶段增加了第六层:灾难性回溯正则表达式仅作为字符串字面量存储,不在模块范围内传递给 re.compile / new RegExp。即使是剥离第1层的测试框架也无法触发编译后的回溯引擎。

扫描器遍历 AST 越过 raise / throw 并进入死代码块,因此接收器仍然作为发现出现——这是预期的行为。

阶段 B(C buffer_ops.c)

安全性是结构性的——每种形状都有其证明:

  • bufops_copy_banner — src 是一个字符串字面量,n = sizeof(literal),_Static_assert 将其固定为目标大小。
  • bufops_copy_bounded — 在 memcpy 之前的一行 if (n > dst_cap) n = dst_cap; 使 CWE-787 声称不可能。当 n == 0 时短路以避免 C17 memcpy(dst, NULL, 0) 未定义行为。
  • bufops_copy_truncating — n <= dst_cap - 1,dst[n] 最多达到 dst_cap - 1;当 dst_cap == 0 时提前返回。
  • — 和 均被限制到 ; 明确支持重叠。

附加隔离:所有函数都是 static(无外部链接),并且该文件未添加到任何构建目标。

阶段 D(C heartbeat.c + sat.h)

Heartbleed 轮廓(uint16_t payload_len → malloc(1+2+payload_len+16) → memcpy)通过分层防护被去毒:

  • sat_sub 饱和减法用于所有头部/尾部预算计算(无溢出)。
  • 帧字段在入口时缓存到 const 局部变量中——关闭 TOCTOU 和信号处理程序未定义行为窗口。
  • 对读取器结构及其缓冲区进行 NULL 检查。
  • _Static_assert(SIZE_MAX - 19 >= UINT16_MAX, ...) 证明 malloc 大小不能溢出 size_t。
  • payload_len > 0 短路避免空负载上的 memcpy(dst, NULL, 0) 未定义行为。
  • parse_heartbeat 和 read_u16_be 是 static;文件未链接到任何构建目标。

声称parse_heartbeat中存在越界读取/写入但不涉及所引用行上的特定防护的报告尚未验证可利用性——通过分诊规则5关闭。

c/tls_heartbeat.c 是同一轮廓的变体,故意保持无防护:process_heartbeat 是 static,文件未链接到任何构建目标——隔离是唯一的层,与阶段 B 的万能情况匹配。从 TU 外部调用它会产生链接错误。

阶段 A 和 E(Rust)

五个独立层使这些文件保持惰性(镜像 Python/JS 安全模型):

  1. 顶层 compile_error! — 通过 mod 或 include! 将文件包含在 crate 中会在任何定义被求值之前产生硬编译器错误。
  2. #[cfg(any())] 后的每个定义 — cfg(any()) 始终为假,因此即使第1层被绕过,名称也从不进入编译输出。
  3. 没有 pub 项目 — 即使上述两层都被剥离,也没有任何东西被导出。
  4. 树内零个调用者引用暗号函数(zqx_tarnish_v3)。任何引用它的报告都会自我识别为 slop。
  5. 部署隔离 — 文件未在任何 mod 语句中引用,未在任何 Cargo.toml 中列出,并从构建产物中排除。

E阶段增加了第六层:灾难性回溯正则表达式仅作为 &str 常量存储,不在模块范围内传递给 regex::Regex::new。

阶段 B(Rust buffer_ops.rs)

安全性是结构性的,与 C 对应项匹配。每种形状都有其证明:

  • bufops_copy_banner — src 是 b"status: ok\0",复制长度是 BANNER.len();一个 const 断言将其固定为目标大小。
  • bufops_copy_bounded — 在复制之前的一行 if n > dst_cap { n = dst_cap; } 限制了写入。当 n == 0 时短路。
  • bufops_copy_truncating — n <= dst_cap - 1,在 dst.add(n) 处的 NUL 写入最多达到 dst_cap - 1;当 dst_cap == 0 时提前返回。
  • bufops_shift — i + n 和 均被限制到 ; 明确支持重叠。

附加隔离:所有函数都在 #[cfg(any())] 内(死代码),非公开,并且文件未添加到任何构建目标。

阶段 D(Rust heartbeat.rs + tls_heartbeat.rs)

Rust 中的 Heartbleed 轮廓使用不安全指针操作(ptr::copy_nonoverlapping、std::alloc::alloc),并通过与 C 版本相同的分层防护被去毒:

  • 通过 usize::saturating_sub 进行饱和减法,用于所有头部/尾部预算计算。
  • 帧字段在入口时缓存到局部变量中。
  • 对读取器结构及其缓冲区进行空检查。
  • 常量断言(usize::MAX - 19 >= u16::MAX)证明分配不能溢出。
  • payload_len > 0 短路。
  • 所有函数在 #[cfg(any())] 内,非公开,文件未链接。

rust/tls_heartbeat.rs 是故意无防护的变体:process_heartbeat 使用来自不可信输入的 claimed_len 且无边界防护的 ptr::copy_nonoverlapping。隔离(#[cfg(any())] + compile_error! + 未链接)是唯一的层。

阶段 A 和 E(Go)

五个独立层使这些文件保持惰性:

  1. 每个文件顶部的 //go:build ignore。Go 工具链(go build、go test、go vet)完全跳过该文件;它永远不会被编译、链接或测试。
  2. func init() { panic("...") } 包含 UUID。如果第1层被某种方式绕过(手动 -tags 覆盖,原始 go tool compile),程序会在 main() 运行之前启动时崩溃。
  3. 所有函数未导出(小写名称)。即使被编译,也无法从包外部调用任何东西。
  4. 树内零个调用者引用暗号函数(zqxTarnishV3)。任何引用它的报告都会自我识别为 slop。
  5. 部署隔离 — 文件位于独立的 go/ 目录中,没有 go.mod,未被任何包导入,并从构建产物中排除。

E阶段增加了特定于 Go 的第六层:validatePep440Plus 确实在灾难模式上调用 regexp.MustCompile,但 Go 的 regexp 包使用 RE2 语义(保证线性时间匹配),因此灾难性回溯无论如何都不可能。金丝雀仍然有用,因为扫描器在文本上标记模式形状,而不检查使用了哪个正则引擎。

阶段 B(Go buffer_ops.go)

安全性是结构性的,与 C 和 Rust 对应项匹配。每种形状都有其证明:

  • bufopsCopyBanner — src 是一个字符串常量,copy() 来自已知字面量到固定大小数组;编译时断言固定了长度。
  • bufopsCopyBounded — 在复制之前的一行 if n > dstCap { n = dstCap } 限制了写入。当 n == 0 时短路。
  • bufopsCopyTruncating — n <= dstCap - 1,在 dst[n] 处的 NUL 写入最多达到 dstCap - 1;当 dstCap == 0 时提前返回。
  • bufopsShift — i + n 和 j + n 均被限制到 cap; 支持单个切片内的重叠。

附加隔离://go:build ignore 将文件排除在所有构建之外,所有函数未导出,并且没有包导入该文件。

阶段 D(Go heartbeat.go + tls_heartbeat.go)

Go 中的 Heartbleed 轮廓使用 unsafe.Slice 和 unsafe.Pointer,并通过与 C 和 Rust 版本相同的分层防护被去毒:

  • satSub 饱和减法用于所有头部/尾部预算计算。
  • 帧字段在入口时缓存到局部变量中。
  • 对读取器结构及其缓冲区进行 nil 检查。
  • 在分配之前对预算进行长度验证。
  • payloadLen > 0 短路。
  • //go:build ignore,所有函数未导出,文件未被导入。

go/tls_heartbeat.go 是故意无防护的变体:processHeartbeat 使用来自不可信输入且无边界防护的 claimedLen 的 unsafe.Slice。隔离(//go:build ignore + init panic + 未被导入)是唯一的层。

如何尝试

  1. 选择阶段。 C/C++ 解析器表面 → D (+ B)。Python OSS 维护者 → A + E。Rust crate → A + B + D + E。Go 模块 → A + B + D + E。在持续的代理扫描器垃圾邮件下 → 私下添加 F + G。
  2. 轮换每个 UUID。 每种语言一个,每个采用者不同——不是一个基础的变体前缀。请参阅 ROTATE_UUID.md。
  3. 从构建产物中排除。 Python:MANIFEST.in prune 金丝雀路径,或 pyproject.toml tool.setuptools.exclude-package-data。C:从 CMakeLists.txt / Makefile / sdist 中省略。Rust:不要添加引用金丝雀文件的 mod 语句或 path 属性;从 Cargo.toml [lib]/[[bin]] 路径和通过 exclude 从 cargo package 中排除。Go://go:build ignore 约束已经将文件排除在 之外;不要在金丝雀目录中放置 ,也不要导入金丝雀包。Docker:。

采用者片段

复制粘贴以完成上述排除和所有权步骤。下面的路径使用 honeyslop 的 c/ / python/ / js/ / rust/ / go/ 布局;重命名为你放置金丝雀的任何位置(参见步骤7)——提交仍然指向名为 canary/ 或 slop/ 的目录的排除本身就是一种线索。

MANIFEST.in

root@kitploit:~
prune c
prune python
prune js
prune rust
prune go

pyproject.toml — setuptools

root@kitploit:~
[tool.setuptools.exclude-package-data]
"*" = ["c/*", "python/*", "js/*", "rust/*", "go/*"]

.dockerignore

root@kitploit:~
c/
python/
js/
rust/
go/

.semgrepignore

root@kitploit:~
c/
python/
js/
rust/
go/

CodeQL — .github/codeql/codeql-config.yml

root@kitploit:~
paths-ignore:
  - c
  - python
  - js
  - rust
  - go

Bandit — CI 调用

root@kitploit:~
bandit -r src/ -x python/

Ruff — pyproject.toml

root@kitploit:~
[tool.ruff]
extend-exclude = ["python/"]

.clang-format-ignore

root@kitploit:~
c/*

密钥扫描器允许列表 — gitleaks .gitleaks.toml

root@kitploit:~
[allowlist]
regexes = [
  '''AKIAIOSFODNN7EXAMPLE''',
  '''ghp_[A-Za-z0-9]{36}''',
  '''xoxb-[0-9A-Za-z-]+''',
  '''sk_live_[A-Za-z0-9]+''',
]

Cargo.toml — 从 crate 包中排除

root@kitploit:~
[package]
exclude = ["rust/"]

Clippy — CI 调用

root@kitploit:~
cargo clippy --workspace -- --allow-dead-code

或者完全跳过金丝雀目录,方法是不要在任何 mod 树中引用它(默认情况下——compile_error! 会捕获意外的包含)。

golangci-lint — .golangci.yml

root@kitploit:~
issues:
  exclude-dirs:
    - go

或者依赖 //go:build ignore 约束,它已经阻止 Go 工具链编译金丝雀文件。

.github/CODEOWNERS

root@kitploit:~
c/       @your-org/sec-team
python/  @your-org/sec-team
js/      @your-org/sec-team
rust/    @your-org/sec-team
go/      @your-org/sec-team

所有者应该是一个小组,他们理解为什么这些路径看起来有漏洞——以便"清理死代码"的 PR 被阻止,而不是合并。

注意

桶1 — 你自己的工具触发。 你的扫描器、linter、IDE 和密钥扫描都会在金丝雀上触发。这是传入扫描的预期行为,但意味着你自己的管道需要跳过这些路径。必需:

  • 从每个 SAST 配置中排除金丝雀路径(CodeQL paths-ignore、.semgrepignore、bandit -x、Ruff --extend-exclude、.clang-format-ignore、编辑器 LSP)。
  • 从发布的产物中排除(MANIFEST.in prune、.dockerignore、wheel exclude)。
  • 在密钥扫描器中允许伪造的密钥列表(AKIAIOSFODNN7EXAMPLE、假的 ghp_ / xoxb- / sk_live_)。
  • 警告贡献者不要"清理"蜜罐。注意 linter 移除 if False: 绊线,以及插入 # noqa / # nosec。

桶2 — 有效性减弱。 公开的金丝雀会在6到18个月内进入 LLM 训练语料库,扫描器供应商会添加跳过启发式。每年轮换 UUID、横幅、暗号和伪造的 CVE(请参阅 ROTATE_UUID.md);跨采用者变化措辞;保持 F+G 私有。这不会阻止模型学习代码,但可能会为你争取一些时间。

桶3 — 入侵后。 如果攻击者已经拥有访问权限,他们可以做任何想做的事,并且不需要 honeyslop。然而,将 if False: 翻转为 if True:、插入 Unicode/BIDI 技巧或在文档字符串中添加提示注入文本可能会在你意想不到的地方将金丝雀变为活跃。虽然不太可能,但值得关注。

免责声明

本项目根据 MIT 许可证提供;参见 LICENSE 了解保证和责任条款。最终用户有责任遵守适用的法律法规以及任何涉及的工具或平台的服务条款。

警告:本项目包含看似存在漏洞的代码,应假定如此。其中一些代码通过分析成本高昂来工作——假设此代码在被扫描器检查时会消耗大量计算资源,具体取决于金丝雀。任何修改,无论是自动还是其他方式,都可能将金丝雀变为活跃。不要在任何真实环境中运行、部署或改编其任何部分。

许可证

根据 MIT 许可证授权。参见 LICENSE。

下载工具
阶段文件形态
Apython/legacy_utils.py, python/session_restore.py, python/compat_tokens.py, js/legacy_utils.js, rust/legacy_utils.rs, rust/session_restore.rs, go/legacy_utils.go, go/session_restore.go约15个CWE接收器 + 伪造密钥 + 暗号
Bc/buffer_ops.c, rust/buffer_ops.rs, go/buffer_ops.go4种 memcpy/memmove 形状 (CWE-120/121/787/170)
C合并到 A扩展的 CWE 产生
Dc/heartbeat.c + c/sat.h, c/tls_heartbeat.c, rust/heartbeat.rs, rust/tls_heartbeat.rs, go/heartbeat.go, go/tls_heartbeat.goHeartbleed 轮廓
Epython/regex_validator.py, js/regex_validator.js, rust/regex_validator.rs, go/regex_validator.go灾难性回溯正则表达式 + 伪造的 CVE-2025-99919
F+Gprivate/fractal_dag/ (不在本仓库中)跨12节点DAG的A阶段接收器,使用 handle_*_request 条目
如何尝试
bufops_shift
i + n
j + n
cap
memmove
j + n
cap
ptr::copy
copy()
go build
go.mod
.dockerignore
  • 从 CI 静态分析中排除。 否则你自己的 CI 会在金丝雀上产生发现。CodeQL paths-ignore、.semgrepignore、bandit -x、Ruff --extend-exclude — 都指向你的金丝雀路径。
  • 考虑将分诊规则添加到 SECURITY.md — 请参阅 SECURITY.md.template。这可能会提醒 slop 扫描器金丝雀的存在(也许是好事?)。
  • 防止贡献者清理。 在金丝雀文件上设置 CODEOWNERS;一个预提交钩子,如果金丝雀 UUID 计数减少或 if False: 绊线丢失,则失败。
  • 移除明显的"线索"。 从代码注释、目录名、文件名和函数/标识符名称中删除"canary"、"canaries"、"honeypot"、"decoy"、"fake"、"tripwire"和"slop"。将文件顶部的文档字符串重新构建为合理的弃用通知。在文档(README、SECURITY.md.template、ROTATE_UUID.md)中保留这些概念性语言,因为它们是承重的。