
eBPF-powered silent observer for containerized runtimes, built for malware analysis sandboxes and Agentic AI monitoring.

Лёгкий трассировщик безопасности на основе eBPF, специально созданный для песочниц анализа вредоносного ПО. Поместите образец в изолированный контейнер, и Azazel захватывает каждый системный вызов, каждое обращение к файлу, сетевое соединение и подозрительное поведение, предоставляя чистый поток JSON всего, что произошло.
Независимо от того, строите ли вы автоматизированную Песочницу для анализа вредоносного ПО или нуждаетесь в круглосуточном мониторинге для автономных AI-агентов, Azazel предоставляет точную, незаметную и готовую для AI телеметрию в формате JSON.
Usage:
azazel [flags]
azazel [command]
Commands:
run-sandbox Run a malware sample in an isolated Docker sandbox and trace it
list-containers List running containers
version Print version
Global Flags:
-c, --container strings Container ID(s) to filter (can specify multiple)
-o, --output string Output file path (default: stdout)
--pretty Pretty-print JSON output
--stdout Also print to stdout when --output is set
-v, --verbose Verbose logging
--no-summary Disable summary on exit
-h, --help Help

19 точек перехвата всего — tracepoints на входе системных вызовов + kprobe для обнаружения DNS.
vmlinux.h, работает на разных версиях ядра без перекомпиляцииjq, Elasticsearch, Splunk или вашего собственного конвейера/tmp, доступе к конфиденциальным файлам (/etc/shadow, /proc/self/mem), ptrace, W+X mmap и загрузке модулей ядраCONFIG_DEBUG_INFO_BTF=yПроверьте ваше ядро:
# BTF support (required)
ls /sys/kernel/btf/vmlinux
# Kernel version
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
# Трассировка всего, сохранение в файл с pretty 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 Summary
========================================
Total events: 1847
Event counts:
file_open 892
file_write 312
process_exec 47
net_connect 23
...
Security Alerts (3):
[MEDIUM] execution from suspicious path: /tmp/suspicious_binary (pid=12345 comm=bash)
[MEDIUM] sensitive file access: /etc/shadow (pid=12346 comm=cat)
[CRITICAL] memory mapped as WRITE+EXEC (possible code injection/unpacking) (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 с хэшами, сводкой событий, сетевыми соединениями и оповещениями безопасностиUsage:
azazel [flags]
azazel [command]
Commands:
list-containers List running containers
version Print version
Flags:
-c, --container strings Container ID(s) to filter (can specify multiple)
-o, --output string Output file path (default: stdout)
--pretty Pretty-print JSON output
--stdout Also print to stdout when --output is set
-v, --verbose Verbose logging
--no-summary Disable summary on exit
-h, --help 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 автоматически отмечает подозрительное поведение:
Всё собирается и запускается внутри одного Docker-контейнера с Go, clang, libbpf и bpftool:
make docker-dev # Сборка образа для разработки
make docker-dev-run # Вход в него (привилегированный + пространства имён хоста)
# Внутри контейнера разработки:
make vmlinux # Генерация vmlinux.h из BTF ядра хоста
make generate # bpf2go: компиляция привязок BPF C → Go
make build # Сборка Go-бинарного файла
make test # Полный цикл тестирования
make check-kernel
Вклад приветствуется. Пожалуйста, сначала откройте issue, чтобы обсудить, что вы хотите изменить.
# Форкните, клонируйте, затем:
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, коды завершения, флаги клонирования, PPID |
| Файлы | file_open, file_write, file_read, file_unlink, file_rename | Пути, флаги, количество байт |
| Сеть | net_connect, net_bind, net_listen, net_accept, net_sendto, net_dns | IPv4/IPv6 адреса, порты, обнаружение DNS через kprobe на udp_sendmsg |
| Безопасность | 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 (внедрение кода, распаковка) |
| Проблема | Решение |
|---|
operation not permitted при загрузке BPF | Контейнер должен запускаться с --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 | Некоторые tracepoints не существуют во всех ядрах — трассировщик записывает предупреждение и продолжает работу |
| События не захватываются | Убедитесь, что трассировщик запущен (`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 для оркестрации песочницы |