
Observador silencioso baseado em eBPF para runtimes conteinerizados, construído para sandboxes de análise de malware e monitoramento de IA Agentic.

Um rastreador de segurança leve baseado em eBPF, projetado especificamente para sandboxes de análise de malware. Coloque uma amostra em um contêiner isolado, e o Azazel captura cada chamada de sistema, toque em arquivo, conexão de rede e comportamento suspeito, e entrega um fluxo JSON limpo de tudo o que aconteceu.
Esteja você construindo uma Sandbox de Análise de Malware automatizada ou precise de Monitoramento em Tempo Real 24/7 para Agentes de IA autônomos, o Azazel fornece telemetria JSON cirúrgica, invisível e pronta para IA.
Uso:
azazel [flags]
azazel [comando]
Comandos:
run-sandbox Executar uma amostra de malware em uma sandbox Docker isolada e rastreá-la
list-containers Listar contêineres em execução
version Exibir versão
Flags Globais:
-c, --container strings ID(s) do contêiner para filtrar (pode especificar vários)
-o, --output string Caminho do arquivo de saída (padrão: stdout)
--pretty Exibir saída JSON formatada
--stdout Também imprimir no stdout quando --output estiver definido
-v, --verbose Log detalhado
--no-summary Desabilitar resumo na saída
-h, --help Ajuda

19 pontos de gancho no total — tracepoints na entrada de syscall + um kprobe para detecção de DNS.
vmlinux.h, funciona em diferentes versões de kernel sem recompilaçãojq, Elasticsearch, Splunk ou sua própria pipeline/tmp, acesso a arquivos sensíveis (/etc/shadow, /proc/self/mem), ptrace, mmap W+X e carregamento de módulo do kernelCONFIG_DEBUG_INFO_BTF=yVerifique seu kernel:
# Suporte a BTF (obrigatório)
ls /sys/kernel/btf/vmlinux
# Versão do kernel
uname -r
# Clonar
git clone https://github.com/beelzebub-labs/azazel.git
cd azazel
# Construir o contêiner de desenvolvimento
make docker-dev
# Entrar nele (privilegiado, com namespace PID/cgroup do host)
make docker-dev-run
# Dentro do contêiner:
make vmlinux # Gerar definições de tipos do kernel
make generate # Compilar BPF C → bindings Go
make build # Construir o binário
# Rastrear tudo, saída para stdout
sudo ./bin/azazel
# Rastrear tudo, salvar em arquivo com formatação JSON
sudo ./bin/azazel --output events.json --pretty
# Rastrear apenas um contêiner específico
sudo ./bin/azazel --container <container_id> --output events.json
# Listar contêineres em execução
sudo ./bin/azazel list-containers
# Dentro do contêiner de desenvolvimento
make test
Isso constrói o binário, inicia o rastreador, executa um simulador de comportamento de malware e valida que todos os tipos de evento esperados foram capturados.
Cada evento é uma única linha 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
}
Quando o rastreador é encerrado (Ctrl+C ou SIGTERM), ele imprime um resumo no stderr:
========================================
Resumo do Azazel
========================================
Total de eventos: 1847
Contagens de eventos:
file_open 892
file_write 312
process_exec 47
net_connect 23
...
Alertas de Segurança (3):
[MÉDIO] execução de caminho suspeito: /tmp/suspicious_binary (pid=12345 comm=bash)
[MÉDIO] acesso a arquivo sensível: /etc/shadow (pid=12346 comm=cat)
[CRÍTICO] memória mapeada como ESCRITA+EXEC (possível injeção de código/descompactação) (pid=12347 comm=malware)
========================================
O arquivo docker-compose.yml incluso configura um ambiente de análise completo:

# Iniciar a sandbox
docker compose up -d
# Copiar uma amostra para a sandbox
docker cp ./samples/malware.elf sandbox:/tmp/sample
# Executá-la
docker exec sandbox /tmp/sample
# Os eventos são escritos em ./output/events.json
cat output/events.json | jq .
# Analisar uma amostra do início ao fim: hash → rastreamento → relatório
sudo ./analyze.sh ./samples/malware.elf 30
Isso produz:
output/events_<timestamp>.json — fluxo bruto de eventosoutput/report_<timestamp>.md — relatório em Markdown com hashes, resumo de eventos, conexões de rede e alertas de segurançaUso:
azazel [flags]
azazel [comando]
Comandos:
list-containers Listar contêineres em execução
version Exibir versão
Flags:
-c, --container strings ID(s) do contêiner para filtrar (pode especificar vários)
-o, --output string Caminho do arquivo de saída (padrão: stdout)
--pretty Exibir saída JSON formatada
--stdout Também imprimir no stdout quando --output estiver definido
-v, --verbose Log detalhado
--no-summary Desabilitar resumo na saída
-h, --help Ajuda
azazel/
├── main.go # Entry point
├── cmd/root.go # CLI (cobra)
├── bpf/tracer.bpf.c # All eBPF programs (single file)
├── internal/
│ ├── tracer/
│ │ ├── tracer.go # Core: load, attach, read ring buffer
│ │ └── events.go # Event types, structs, parsing
│ ├── container/
│ │ └── resolver.go # cgroup → container ID resolution
│ └── output/
│ └── writer.go # JSON output + heuristic alerts
├── test/
│ ├── simulate_malware.sh # Malware behavior simulator
│ └── run_tests.sh # Automated test suite
├── Dockerfile # Production multi-stage build
├── Dockerfile.dev # Dev container with build deps
├── docker-compose.yml # Full sandbox environment
├── analyze.sh # Automated analysis script
└── Makefile # Build system
O Azazel sinaliza automaticamente comportamentos suspeitos:
Tudo é construído e executado dentro de um único contêiner Docker com Go, clang, libbpf e bpftool:
make docker-dev # Construir a imagem de desenvolvimento
make docker-dev-run # Entrar nela (privilegiado + namespaces do host)
# Dentro do contêiner de desenvolvimento:
make vmlinux # Gerar vmlinux.h a partir do BTF do kernel host
make generate # bpf2go: compilar BPF C → bindings Go
make build # Construir o binário Go
make test # Ciclo completo de testes
make check-kernel
Contribuições são bem-vindas. Por favor, abra uma issue primeiro para discutir o que você gostaria de alterar.
# Fork, clone, depois:
make docker-dev
make docker-dev-run
# hack hack hack
make test
GPL-2.0 — veja LICENSE para detalhes.
Os programas BPF são licenciados sob GPL-2.0 (obrigatório para acesso a helpers eBPF). O código Go em userspace também é GPL-2.0.
| Categoria | Eventos | Detalhes |
|---|
| Processo | process_exec, process_exit, process_clone | Árvore completa de processos: nome do arquivo, argv, códigos de saída, flags de clone, PID pai |
| Arquivo | file_open, file_write, file_read, file_unlink, file_rename | Caminhos, flags, contagens de bytes |
| Rede | net_connect, net_bind, net_listen, net_accept, net_sendto, net_dns | Endereços IPv4/IPv6, portas, detecção de DNS via kprobe em udp_sendmsg |
| Segurança | mmap_exec, ptrace, module_load | Mapeamentos de memória W+X, tentativas de injeção de processo, carregamento de módulo do kernel |
| Alerta | Severidade | Gatilho |
|---|
| Caminho de execução suspeito | Médio | Execução de /tmp/, /dev/shm/, /var/tmp/ |
| Ferramenta suspeita | Médio | wget, curl, nc, python, base64, memfd: |
| Acesso a arquivo sensível | Médio | /etc/passwd, /etc/shadow, /etc/sudoers, /etc/ssh/, /proc/self/maps, /proc/self/mem, /etc/ld.so.preload |
| Ptrace | Alto | Qualquer syscall ptrace (injeção de processo / depuração) |
| Carregamento de módulo do kernel | Alto | Qualquer syscall finit_module |
| mmap W+X | Crítico | Memória mapeada como ESCRITA+EXEC simultaneamente (injeção de código, descompactação) |
| Problema | Solução |
|---|
operation not permitted ao carregar BPF | O contêiner deve ser executado com --privileged --pid=host --cgroupns=host |
vmlinux.h: No such file | Execute make vmlinux (requer /sys/kernel/btf/vmlinux) |
kernel doesn't support BTF | O kernel host precisa de CONFIG_DEBUG_INFO_BTF=y — verifique com ls /sys/kernel/btf/vmlinux |
| Falha na criação do mapa de ring buffer | O kernel deve ser 5.8+, verifique com uname -r |
failed to attach tracepoint | Alguns tracepoints não existem em todos os kernels — o rastreador registra um aviso e continua |
| Nenhum evento capturado | Verifique se o rastreador está em execução (ps aux | grep azazel), certifique-se de que a atividade de teste ocorre após a inicialização do rastreador |
| Componente | Tecnologia |
|---|
| Linguagem | Go 1.24+ |
| Biblioteca eBPF | cilium/ebpf v0.17+ |
| Geração de código BPF | bpf2go (CO-RE, baseado em BTF) |
| Programas BPF | C, compilados com clang, usando vmlinux.h |
| CLI | cobra |
| Saída | NDJSON (um objeto JSON por linha) |
| Contêiner | Docker, com docker-compose para orquestração da sandbox |