
一款轻量级的、基于 eBPF 的运行时安全追踪器,专为恶意软件分析沙箱而设计。将一个样本放入隔离容器中,Azazel 会捕获每一个系统调用、文件操作、网络连接和可疑行为,然后以清晰的 JSON 流形式呈现所发生的一切。
无论你是在构建自动化的恶意软件分析沙箱,还是需要为自主 AI 代理提供 7×24 小时运行时监控,Azazel 都能提供精准、隐蔽且 AI 友好的 JSON 遥测数据。
用法:
azazel [flags]
azazel [command]
命令:
run-sandbox 在隔离的 Docker 沙箱中运行恶意软件样本并进行追踪
list-containers 列出正在运行的容器
version 打印版本
全局标志:
-c, --container strings 要过滤的容器 ID(可指定多个)
-o, --output string 输出文件路径(默认:stdout)
--pretty 美化打印 JSON 输出
--stdout 设置 --output 后也输出到 stdout
-v, --verbose 详细日志
--no-summary 退出时不显示摘要
-h, --help 帮助

共 19 个钩子点 —— 系统调用入口处的 tracepoint 加上一个用于 DNS 检测的 kprobe。
vmlinux.h 一次编译,到处运行,无需重新编译即可跨内核版本工作jq、Elasticsearch、Splunk 或你自己的流水线配合使用/tmp 执行、敏感文件访问(/etc/shadow, /proc/self/mem)、ptrace、W+X mmap 以及内核模块加载CONFIG_DEBUG_INFO_BTF=y验证你的内核:
# BTF 支持(必需)
ls /sys/kernel/btf/vmlinux
# 内核版本
uname -r
# 克隆
git clone https://github.com/beelzebub-labs/azazel.git
cd azazel
# 构建开发容器
make docker-dev
# 进入开发容器(特权模式,使用宿主机 PID/cgroup 命名空间)
make docker-dev-run
# 在容器内:
make vmlinux # 生成内核类型定义
make generate # 编译 BPF C → Go 绑定
make build # 构建二进制文件
# 追踪所有事件,输出到 stdout
sudo ./bin/azazel
# 追踪所有事件,保存到文件并使用美化 JSON
sudo ./bin/azazel --output events.json --pretty
# 仅追踪特定容器
sudo ./bin/azazel --container <container_id> --output events.json
# 列出运行中的容器
sudo ./bin/azazel list-containers
# 在开发容器内
make test
这会构建二进制文件,启动追踪器,运行恶意软件行为模拟器,然后验证是否捕获了所有预期的事件类型。
每个事件都是单行 JSON(NDJSON):
{
"timestamp": "2025-01-15T14:30:22.123456789Z",
"event_type": "process_exec",
"pid": 12345,
"tgid": 12345,
"ppid": 12300,
"uid": 0,
"gid": 0,
"comm": "bash",
"cgroup_id": 6789,
"container_id": "a1b2c3d4e5f6",
"filename": "/tmp/suspicious_binary",
"args": "/tmp/suspicious_binary"
}
{
"timestamp": "2025-01-15T14:30:22.234567890Z",
"event_type": "net_connect",
"pid": 12345,
"tgid": 12345,
"ppid": 12300,
"uid": 0,
"gid": 0,
"comm": "curl",
"cgroup_id": 6789,
"container_id": "a1b2c3d4e5f6",
"sa_family": "AF_INET",
"dst_addr": "93.184.216.34",
"dst_port": 443
}
当追踪器关闭时(Ctrl+C 或 SIGTERM),它会向 stderr 打印一份摘要:
========================================
Azazel 摘要
========================================
总事件数:1847
各事件计数:
file_open 892
file_write 312
process_exec 47
net_connect 23
...
安全告警(3 条):
[中等] 来自可疑路径的执行:/tmp/suspicious_binary(pid=12345 comm=bash)
[中等] 敏感文件访问:/etc/shadow(pid=12346 comm=cat)
[严重] 内存映射为 WRITE+EXEC(可能的代码注入/解包)(pid=12347 comm=malware)
========================================
附带的 docker-compose.yml 搭建了一个完整的分析环境:

# 启动沙箱
docker compose up -d
# 将样本复制到沙箱中
docker cp ./samples/malware.elf sandbox:/tmp/sample
# 执行样本
docker exec sandbox /tmp/sample
# 事件写入 ./output/events.json
cat output/events.json | jq .
# 端到端分析一个样本:哈希 → 追踪 → 报告
sudo ./analyze.sh ./samples/malware.elf 30
这将产生:
output/events_<timestamp>.json — 原始事件流output/report_<timestamp>.md — 包含哈希值、事件摘要、网络连接和安全告警的 Markdown 报告用法:
azazel [flags]
azazel [command]
命令:
list-containers 列出运行中的容器
version 打印版本
标志:
-c, --container strings 要过滤的容器 ID(可指定多个)
-o, --output string 输出文件路径(默认:stdout)
--pretty 美化打印 JSON 输出
--stdout 设置 --output 后也输出到 stdout
-v, --verbose 详细日志
--no-summary 退出时不显示摘要
-h, --help 帮助
azazel/
├── main.go # 入口点
├── cmd/root.go # CLI(cobra)
├── bpf/tracer.bpf.c # 所有 eBPF 程序(单个文件)
├── internal/
│ ├── tracer/
│ │ ├── tracer.go # 核心:加载、附加、读取环形缓冲区
│ │ └── events.go # 事件类型、结构体、解析
│ ├── container/
│ │ └── resolver.go # cgroup → 容器 ID 解析
│ └── output/
│ └── writer.go # JSON 输出 + 启发式告警
├── test/
│ ├── simulate_malware.sh # 恶意软件行为模拟器
│ └── run_tests.sh # 自动化测试套件
├── Dockerfile # 生产多阶段构建
├── Dockerfile.dev # 包含构建依赖的开发容器
├── docker-compose.yml # 完整沙箱环境
├── analyze.sh # 自动化分析脚本
└── Makefile # 构建系统
Azazel 自动标记可疑行为:
所有构建和运行都在一个包含 Go、clang、libbpf 和 bpftool 的 Docker 容器中完成:
make docker-dev # 构建开发镜像
make docker-dev-run # 进入开发容器(特权模式 + 宿主机命名空间)
# 在开发容器内:
make vmlinux # 从宿主机内核 BTF 生成 vmlinux.h
make generate # bpf2go:编译 BPF C → Go 绑定
make build # 构建 Go 二进制文件
make test # 完整测试流程
make check-kernel
欢迎贡献。请先创建一个 issue 讨论你想要改动的内容。
# Fork、克隆,然后:
make docker-dev
make docker-dev-run
# 修改代码
make test
GPL-2.0 — 详情见 LICENSE。
BPF 程序使用 GPL-2.0 许可证(eBPF 辅助函数访问需要)。用户空间 Go 代码同样使用 GPL-2.0。
| 分类 | 事件 | 详情 |
|---|
| 进程 | process_exec, process_exit, process_clone | 完整进程树:文件名、argv、退出码、clone 标志、父 PID |
| 文件 | file_open, file_write, file_read, file_unlink, file_rename | 路径名、标志、字节数 |
| 网络 | net_connect, net_bind, net_listen, net_accept, net_sendto, net_dns | IPv4/IPv6 地址、端口,通过 udp_sendmsg 上的 kprobe 进行 DNS 检测 |
| 安全 | mmap_exec, ptrace, module_load | W+X 内存映射、进程注入尝试、内核模块加载 |
| 告警 | 严重级别 | 触发条件 |
|---|
| 可疑执行路径 | 中等 | 从 /tmp/、/dev/shm/、/var/tmp/ 执行 |
| 可疑工具 | 中等 | wget、curl、nc、python、base64、memfd: |
| 敏感文件访问 | 中等 | /etc/passwd、/etc/shadow、/etc/sudoers、/etc/ssh/、/proc/self/maps、/proc/self/mem、/etc/ld.so.preload |
| Ptrace | 高 | 任何 ptrace 系统调用(进程注入/调试) |
| 内核模块加载 | 高 | 任何 finit_module 系统调用 |
| W+X mmap | 严重 | 内存同时映射为 WRITE+EXEC(代码注入、解包) |
| 问题 | 解决方案 |
|---|
加载 BPF 时出现 operation not permitted | 容器必须使用 --privileged --pid=host --cgroupns=host 运行 |
vmlinux.h: No such file | 运行 make vmlinux(需要 /sys/kernel/btf/vmlinux) |
kernel doesn't support BTF | 宿主机内核需要 CONFIG_DEBUG_INFO_BTF=y — 使用 ls /sys/kernel/btf/vmlinux 检查 |
| 环形缓冲区映射创建失败 | 内核必须是 5.8+,使用 uname -r 检查 |
failed to attach tracepoint | 某些 tracepoint 并非所有内核都有 — 追踪器会记录警告并继续运行 |
| 未捕获到事件 | 验证追踪器正在运行(`ps aux |
| 组件 | 技术 |
|---|
| 语言 | Go 1.24+ |
| eBPF 库 | cilium/ebpf v0.17+ |
| BPF 代码生成 | bpf2go(CO-RE,基于 BTF) |
| BPF 程序 | C,使用 clang 编译,采用 vmlinux.h |
| CLI | cobra |
| 输出 | NDJSON(每行一个 JSON 对象) |
| 容器 | Docker,配合 docker-compose 进行沙箱编排 |