
macnoise v0.5.0
可扩展的 macOS 系统遥测生成器。
MacNoise
MacNoise 生成真实的 macOS 遥测数据:网络连接、文件写入、进程派生、plist 变更、TCC 探测等。将其指向运行 EDR、SIEM 或防火墙栈的机器,观察实际触发的行为——而非厂商数据表所声称会触发的行为。
关于动机和设计的背景,请参阅发布博客文章。
快速开始
# Build (add build-amd64 / build-arm64 to cross-compile for Darwin, or release for both)
make build
# List available modules
./macnoise list
# Run a single module
./macnoise run net_connect --param target=127.0.0.1 --param port=8080
# Preview without executing
./macnoise run svc_launch_agent --dry-run
# Run all network modules
./macnoise run --category network
# Run a scenario
./macnoise scenario configs/scenarios/edr_validation.yaml
# Emit structured JSONL output
./macnoise scenario configs/scenarios/file_flow.yaml --format jsonl --output /tmp/events.jsonl
遥测类别
| 类别 | 描述 |
|---|---|
network | TCP 连接、HTTP、监听器、反向 shell、DNS 和 TLS |
process | 精确执行、信号传递、dylib 注入、Gatekeeper 绕过和 osascript |
file | 有界发现、字面读取/复制、创建、修改、归档、隐藏和诱饵加密 |
tcc | TCC 权限探测,具有精确的完全磁盘访问、通讯录、辅助功能或屏幕录制要求 |
credential | 原生凭据存储访问 |
volume | 磁盘映像创建和挂载卷生命周期 |
service | Launchd 枚举、LaunchAgent/Daemon 持久化、cron、shell 配置文件和登录项 |
plist | Plist 创建和修改 |
evasion | 日志清除、时间戳篡改、历史记录删除和伪装 |
有关每个模块、参数、输出、事件类型、权限和 ATT&CK 映射,请参阅生成的模块目录。
命令
macnoise run <module> [--param key=val ...] Run a specific module
macnoise run --category <cat> Run all modules in a category
macnoise run --all Run all modules
macnoise list [--category <cat>] List modules
macnoise info <module> Show module details, params, MITRE
macnoise scenario <file.yaml> [--input key=val] [--report report.json]
Run a YAML scenario
macnoise categories List categories with counts
macnoise version Print version
全局标志
| 标志 | 默认值 | 描述 |
|---|---|---|
--format | human | 输出格式:human 或 jsonl |
--output | (无) | 将输出写入文件(除 stdout 之外) |
--verbose | false | 详细输出,包括清理错误 |
--dry-run | false | 预览操作而不执行 |
--no-cleanup | false | 保留模块产物(见下文) |
--timeout | 30 | 每个模块的超时时间(秒) |
--audit-log | (无) | 将 OCSF 1.7.0 审计记录写入 JSONL 文件 |
--config | (无) | 从 YAML 配置文件加载默认值 |
--run-id | 自动生成 | 设置本次运行的关联标识符 |
场景数据流
场景文件使用 version: 1。输入和模块输出是类型化的,后续步骤通过显式映射而非字符串插值来引用它们:
version: 1
name: Archive one generated artifact
on_error: stop
inputs:
content:
type: string
required: true
steps:
# Custom modules declare these outputs through OutputSpecs.
- id: create
module: custom_create
params:
content:
input: content
- id: archive
module: custom_archive
params:
source:
output: create.path
outputs:
archive:
output: archive.path
只有模块声明的输出才能被引用。本地场景可以通过 include 步骤复用;include 是相对路径,不能遍历到根场景目录之上,会进行循环检查,并且限制为八层。MacNoise 在执行前验证完整图,为运行提供一个私有工作区,并按相反顺序清理调用的模块。使用 --input content=value 提供输入,使用 --report report.json 获取版本化的执行报告。
保留产物
默认情况下,每个模块在完成时会自行还原。这通常是你想要的,但这意味着检测只能看到安装事件。要验证你的栈是否能检测到持久化本身——一个位于 ~/Library/LaunchAgents 中的 LaunchAgent、一个 cron 条目、一个修改过的 shell 配置文件——当扫描运行时,产物必须仍然存在:
./macnoise run svc_launch_agent --no-cleanup
每个跳过清理的模块都会打印一行标明自身,审计日志记录 cleanup_result: skipped 而非 ok,因此留下持久化的运行绝不会被误认为已清理的运行。使用 macnoise info <module> 查看给定模块创建的内容。
你有责任自行移除这些内容。 在没有该标志的情况下重新运行同一模块只会清理该次运行创建的内容,而不会清理之前 --no-cleanup 运行留下的内容。
审计日志
MacNoise 写入两个独立的流。遥测事件——你的 EDR/SIEM 实际看到的内容——发送到 stdout 或 --output。第二个可选的流记录 MacNoise 自身做了什么:哪些模块运行了、前置条件/清理结果以及 MITRE 映射,采用 OCSF 1.7.0 JSONL 格式。
./macnoise scenario configs/scenarios/amos_atomic_stealer.yaml --audit-log /tmp/audit.jsonl
每个遥测事件都携带一个权威的 outcome 和一个类型化的 subject(schema 2.0)。outcome 说明 MacNoise 尝试的操作发生了什么,而 subject 标识涉及的文件、进程、网络端点、服务或资源:
outcome | 含义 | 人类可读标记 |
|---|---|---|
executed | 操作运行了,并且做了模块声称的事情 | [+] |
denied | 操作运行了,但环境拒绝了它 | [-] |
indeterminate | 操作运行了,但无法得出任何结论 | [?] |
error | MacNoise 自身未能执行该操作 | [!] |
被拒绝的 TCC 探测或指向失效 C2 的信标正是此工具存在的目的——生成这类遥测,因此它与 error 不同,后者意味着 MacNoise 自身失败了。审计日志在 unmapped.outcome 处记录相同的值。声明为敏感的参数在托管审计记录和命令行身份中会被替换为 [REDACTED]。
审计日志以追加模式打开,因此多次运行的记录会堆积在一个文件中,便于批量分析。如果你正在添加模块,并想了解新事件类型如何分类到 OCSF,请参阅 CONTRIBUTING.md。
模块参考
生成的模块目录是名称、参数、输出、事件类型、权限和 ATT&CK 映射的权威参考。类别说明解释了平台行为和操作边界:
| 类别 | README |
|---|---|
network | modules/network/README.md |
process | modules/process/README.md |
file | modules/file/README.md |
tcc | modules/tcc/README.md |
credential | modules/credential/README.md |
volume | modules/volume/README.md |
service | modules/service/README.md |
plist | modules/plist/README.md |
evasion | modules/evasion/README.md |
场景
场景将模块链接成有序序列——一个 YAML 文件即可针对你的检测重放多阶段入侵模式。
| 文件 | 描述 |
|---|---|
network_only.yaml | 组合的 TCP、监听器、DNS、HTTP 信标和 HTTP 外泄操作 |
edr_validation.yaml | 全面的 EDR 检测覆盖 |
full_sweep.yaml | 所有类别 |
lazarus_group.yaml | Lazarus Group:dylib 注入、服务发现、反向 shell、LaunchAgent 持久化 |
amos_atomic_stealer.yaml | AMOS / Atomic Stealer:MaaS 信息窃取器、Gatekeeper 绕过、钥匙串转储、ZIP 外泄、后门持久化 |
clickfix.yaml | ClickFix:粘贴到 Terminal 的混淆单行命令、base64 解码、第二阶段获取、LaunchAgent 持久化 |
ransomware.yaml | 勒索软件影响:放置明文诱饵、加密它们,然后投放勒索信 |
discovery.yaml | 组合的基于 argv 的系统、账户、网络和安全软件发现配方 |
process_chain.yaml | 由显式参数向量构建的三进程 shell 链 |
file_flow.yaml | 连接的创建、修改、有界发现、读取、复制和归档流程 |
mounted_execution.yaml | 从观察到的磁盘映像挂载点创建并执行有效载荷 |
两个 APT 场景逐技术地遵循真实记录的入侵序列——每个 YAML 文件都引用了其构建所依据的实际威胁情报,并为每一步标注了它演练的 MITRE 技术,因此请从那里开始获取完整分解,而非在此重述。
先进行试运行:
./macnoise scenario configs/scenarios/<scenario>.yaml --dry-run
与你的 SIEM/EDR 交叉引用: 每个步骤注释都标明了它应触发的技术。真实运行后没有匹配的告警就是你覆盖范围的缺口。
编写你自己的:
version: 1
name: My Custom Scenario
on_error: stop
steps:
- module: net_connect
params:
target: "192.168.1.1"
port: 443
- module: file_create
params:
base_dir: "/tmp/test"
参数在预览或执行前会根据每个模块声明的字符串、整数、布尔值、路径或列表类型进行检查。未知名称和无效值会被拒绝。on_error 默认为 stop。仅当覆盖扫描应在失败后尝试后续模块调用时,才将其设置为 continue。
从场景模板开始,了解类型化输入、输出和连接的数据流。
版本 1 兼容性
版本 1.0 定义了受支持的 CLI 命令和标志、模块名称和契约、场景 schema 1、遥测 schema 2.0 以及场景报告 schema 1.0。未来对这些接口的不兼容更改需要新的主版本发布。
现有用户应阅读从 v0.6.0 迁移到 v1.0.0。它映射了每个被移除的模块,并描述了场景、JSONL 和 Go API 的更改。
贡献
有关原始模块、场景和核心更改的路径,请参阅 CONTRIBUTING.md。
发布是自动化的——release-please 直接从你的约定式提交 PR 标题生成新版本,因此 feat: add net_tls module 或 fix: correct beacon jitter 既是你的 PR 标题,也是你的变更日志条目。
免责声明
MacNoise 旨在用于授权的安全测试、EDR 验证和检测工程,仅限你拥有或获得明确书面许可进行测试的系统。作者对滥用不承担任何责任。
AI 代码政策
AI 代码贡献是可以的,但请记住,代码审查目前将是一个人工主导的过程,这意味着我们能审查的代码量有限。请将 PR 限制为特定的修复或新的遥测模块。包含大量更改的 PR 很可能会被关闭。