Como Automatizar a Monitorização de Integridade (FIM) e Resposta Ativa em Tempo Real com Wazuh

Como Automatizar a Monitorização de Integridade (FIM) e Resposta Ativa em Tempo Real com Wazuh

Depender de verificações de integridade de ficheiros agendadas uma vez por noite via cron ou de simples recolha passiva de logs deixa a tua infraestrutura vulnerável durante horas: se um atacante injetar uma webshell às dez da manhã, tem o dia inteiro para exfiltrar credenciais e encriptar dados antes que qualquer relatório seja gerado.

Em setores como Fintech Startups (Neobanks) e Astroturismo e Viagens Estratosféricas, um script malicioso demora menos de noventa segundos desde o upload até comprometer o sistema operativo.

No Webxtek Studio, ligamos o Wazuh SIEM diretamente ao subsistema de auditoria do kernel Linux (auditd) com o modo whodata="yes". Isto permite não só detetar a criação de scripts maliciosos em milissegundos, mas também identificar exatamente qual foi o processo e o utilizador responsável, acionando de imediato scripts de Resposta Ativa que movem o ficheiro para quarentena e bloqueiam o IP do atacante na firewall nftables.

Esta postura de deteção em tempo real e resposta ativa operacionaliza o fecho de perímetro exigido no nosso Alerta CISA, NSA e FBI: Blindagem PHP, Node e Portas Expostas.

Abaixo tens o guia prático para configurares o FIM e os playbooks de resposta ativa nos teus servidores Linux.


1. Da Prancheta Noturna ao Kernel auditd: Como Funciona o FIM com whodata no Wazuh

Para detetares e neutralizares webshells e alterações não autorizadas de binários em milissegundos no Linux, tens de configurar o módulo syscheck do Wazuh com o atributo whodata="yes" apoiado pelo serviço auditd do kernel, criar regras de deteção de criação de scripts em diretórios web e acionar um playbook de Resposta Ativa que isole o ficheiro e bloqueie o IP em nftables.

Para perceberes porque é que as ferramentas clássicas de monitorização de integridade de ficheiros falham contra ataques modernos, tens de distinguir os três modos de operação do motor syscheck, documentados no manual oficial de File Integrity Monitoring do Wazuh:

  1. Modo Agendado (Scheduled Scan): O agente varre o disco rígido a cada 12 horas à procura de hashes SHA-256 diferentes. Se um atacante injetar uma webshell às 10:05, executar os seus comandos e apagar a webshell às 10:08, o varrimento das 22:00 não vê absolutamente nada!
  2. Modo Tempo Real (realtime="yes" via inotify): O agente subscreve eventos IN_MODIFY, IN_CREATE e IN_DELETE do subsistema inotify do kernel Linux. O alerta dispara no próprio segundo, mas há um ponto cego forense: a API inotify do Linux diz-te qual ficheiro mudou (/var/www/app/public/uploads/shell.php), mas não te diz que utilizador nem que processo do sistema criou esse ficheiro.
  3. Modo Who-Data (whodata="yes" via Kernel auditd): Este é o padrão de elite que implementamos em produção. Em vez de usar o inotify básico, o Wazuh injeta regras dinâmicas no subsistema Linux Audit (auditd) ao nível das chamadas de sistema do kernel (sys_openat, sys_write, sys_unlink, sys_chmod).
Fluxo Forense em Tempo Real: Wazuh FIM (whodata="yes") + Resposta Ativa

1. Invasao:
   Um exploit web faz o processo php-fpm8.4 gravar '/var/www/html/uploads/backdoor.php'.

2. Intercecao no Kernel:
   O subsistema Linux Audit (auditd) captura a syscall write() no VFS.

3. Rastreio Who-Data:
   O Wazuh Agent recebe do socket auditd os metadados irrefutaveis:
   - Ficheiro: /var/www/html/uploads/backdoor.php (Novo Hash SHA-256 calculado)
   - Utilizador Efetivo (euid): www-data (UID 33) | Audit UID (auid): 4294967295
   - Processo Responsavel: /usr/sbin/php-fpm8.4 (PID 14820 | PPID 1102)

4. Decisao no SIEM (50ms):
   O Wazuh Manager avalia a regra critica (Ex.: Regra 100554: Script PHP criado em pasta de uploads).

5. Resposta Ativa Automatica:
   O agente executa o playbook 'webxtek-quarantine.sh':
   - Move backdoor.php para /var/ossec/quarantine/ com permissoes 0000 (neutraliza a execucao!).
   - Bloqueia o IP do atacante na tabela nftables do kernel Linux.

Repara no poder forense do campo whodata: se um administrador humano entrar por SSH com o utilizador pedro (UID 1002), fizer sudo su - para passar a root (UID 0) e alterar secretamente uma linha no ficheiro /etc/ssh/sshd_config, o registo whodata do Wazuh mostra:

  • user_name: root (quem fez a escrita efetiva)
  • audit_uid: pedro (1002) (quem iniciou a sessão original no servidor, porque o auid do kernel Linux é imutável mesmo após escalada de privilégios!)
  • process_name: /usr/bin/nano
  • E, graças à diretiva report_changes="yes", mostra o diff exato da linha de texto que foi alterada!

2. Configuração de Produção: auditd e /var/ossec/etc/ossec.conf Blindado

Vamos configurar o teu servidor Debian 12 ou Ubuntu 24.04 LTS para ativar a auditoria whodata nas pastas críticas do sistema operativo e nas pastas das tuas aplicações web, protegendo simultaneamente os teus ficheiros de segredos com a etiqueta <nodiff>.

Passo 1: Instalar e Dimensionar o Daemon auditd no Servidor Linux

Por defeito, muitas imagens cloud vêm sem o pacote auditd instalado ou com um buffer de eventos minúsculo que perde pacotes sob carga elevada. Instala e afina o auditd no teu terminal:

# 1. Instalar o subsistema Linux Audit e plugins
sudo apt-get update && sudo apt-get install -y auditd audispd-plugins jq

# 2. Aumentar o buffer da fila do kernel (-b 8192) para evitar perda de eventos em picos de I/O
cat << 'EOF' | sudo tee /etc/audit/rules.d/10-wazuh-buffer.rules
-b 8192
-f 1
EOF

sudo augenrules --load
sudo systemctl enable --now auditd

Passo 2: Configurar o Bloco <syscheck> no Agente Wazuh (/var/ossec/etc/ossec.conf)

Edita o ficheiro /var/ossec/etc/ossec.conf no teu servidor monitorizado e substitui a secção <syscheck> por esta configuração cirúrgica, alinhada com as melhores práticas de documentation.wazuh.com sobre FIM:

<!-- ==========================================================================
/var/ossec/etc/ossec.conf (Bloco <syscheck> nos Servidores Linux)
Monitorização em Tempo Real + Rastreio Who-Data (auditd) + Proteção Nodiff
========================================================================== -->
<syscheck>
  <disabled>no</disabled>

  <!-- Varrimento completo de baseline a cada 6 horas; whodata atua em milissegundos -->
  <frequency>21600</frequency>
  <scan_on_start>yes</scan_on_start>
  <alert_new_files>yes</alert_new_files>
  <auto_ignore frequency="10" timeframe="3600">no</auto_ignore>

  <!-- 1. Binários Críticos do Sistema: Detetar trojanização ou rootkits com whodata -->
  <directories check_all="yes" whodata="yes">/bin,/sbin,/usr/bin,/usr/sbin,/usr/local/bin</directories>

  <!-- 2. Configurações Críticas (/etc): Capturar quem alterou e qual foi a linha exata modificada -->
  <directories check_all="yes" whodata="yes" report_changes="yes">/etc/ssh,/etc/pam.d,/etc/sudoers.d,/etc/nginx,/etc/php,/etc/cron.d,/etc/systemd/system</directories>
  <directories check_all="yes" whodata="yes" report_changes="yes">/etc/passwd,/etc/group,/etc/hosts,/etc/resolv.conf,/etc/nftables.conf</directories>

  <!-- 3. Diretórios de Aplicações Web: Vigiar injeção de scripts executáveis (.php, .py, .sh, .mjs, .pth) -->
  <directories check_all="yes" whodata="yes" report_changes="yes" restrict="\.php$|\.phtml$|\.phar$|\.py$|\.pth$|\.sh$|\.mjs$|\.js$|\.htaccess$">/var/www</directories>

  <!-- 4. Diretórios de Uploads de Utilizadores: NUNCA deve nascer código aqui; vigiar tudo em whodata -->
  <directories check_all="yes" whodata="yes">/var/www/app_producao/storage/app/public,/var/www/app_producao/public/uploads</directories>

  <!-- 5. Exclusões de Performance (Ignorar caches voláteis, logs e pastas .git/objects) -->
  <ignore>/var/www/app_producao/storage/framework/cache</ignore>
  <ignore>/var/www/app_producao/storage/framework/views</ignore>
  <ignore>/var/www/app_producao/storage/logs</ignore>
  <ignore type="sregex">\.log$|\.swp$|\.tmp$|/node_modules/|/\.git/objects/</ignore>

  <!-- 6. SEGURANÇA DE SEGREDOS (<nodiff>): Calcular hash SHA-256 se mudar, mas NUNCA enviar o texto da password para o SIEM! -->
  <nodiff>/etc/shadow</nodiff>
  <nodiff>/etc/gshadow</nodiff>
  <nodiff type="sregex">\.env$|wp-config\.php$|\.pem$|\.key$|id_ed25519$|users\.acl$</nodiff>

  <!-- Limites de proteção de disco para cópias de diff -->
  <disk_quota enabled="yes">1G</disk_quota>
  <file_size enabled="yes">50M</file_size>
</syscheck>

Reinicia o agente do Wazuh e verifica imediatamente se as regras de auditd (wazuh_fim) foram injetadas no kernel:

sudo systemctl restart wazuh-agent

# Confirmar que o Wazuh injetou os watches whodata diretamente no kernel auditd
sudo auditctl -l | grep wazuh_fim

3. Regras de Deteção e Playbook de Resposta Ativa: Quarentena Automática de Webshells

Detetar que um ficheiro shell.php acabou de ser criado dentro da pasta /public/uploads/ às três da manhã é ótimo, mas se ninguém estiver acordado a olhar para o painel, o atacante tem a noite inteira para agir.

Esta deteção é especificamente desenhada para travar ataques de injeção em cadeia como os documentados no nosso alerta sobre o Pânico nos Fóruns de cPanel, Plesk e HestiaCP: Mitigação PHP2Shell.

Vamos configurar a Resposta Ativa (Active Response), seguindo a arquitetura oficial de Active Response do Wazuh, para que o próprio servidor neutralize o ficheiro em menos de 100 milissegundos.

Passo 1: Criar a Regra de Alta Severidade no Wazuh Manager (/var/ossec/etc/rules/local_rules.xml)

No teu servidor central do Wazuh Manager, adiciona esta regra personalizada que eleva para Nível 14 (Emergência Crítica) qualquer criação ou modificação de ficheiro .php, .phtml, .py ou .sh dentro de diretórios de uploads ou escritas feitas pelo processo php-fpm / www-data:

<!-- Ficheiro no Wazuh Manager: /var/ossec/etc/rules/local_rules.xml -->
<group name="syscheck,webxtek_fim_defense,">

  <!-- Regra 100550: Detetar criação de ficheiro PHP/Script em pasta de uploads ou pelo utilizador www-data -->
  <rule id="100550" level="14">
    <if_sid>554,550</if_sid>
    <field name="file" type="pcre2">(?i)/uploads/.*\.(php\d?|phtml|phar|py|sh|pl|cgi|pth)$|(?i)/storage/.*\.(php\d?|phtml|phar|pth)$</field>
    <description>[CRITICO FIM] Webshell ou script executavel injetado em diretorio de dados: $(file) pelo processo $(audit.process.name) (UID:$(audit.euid.name)).</description>
    <mitre>
      <id>T1505.003</id>
    </mitre>
    <group>webshell_detected,pci_dss_11.5,gdpr_IV_35.7.d,</group>
  </rule>

  <!-- Regra 100551: Detetar se o processo php-fpm ou node escreveu um novo ficheiro .php no codigo-fonte fora de um deploy -->
  <rule id="100551" level="13">
    <if_sid>554</if_sid>
    <field name="audit.process.name" type="pcre2">php-fpm|lsphp|apache2|nginx|node</field>
    <field name="file" type="pcre2">(?i)\.(php\d?|phtml|phar|pth|py|sh)$</field>
    <description>[ALERTA RCE FIM] O runtime web ($(audit.process.name)) gravou um novo script no disco: $(file). Possivel exploracao RCE / PHP2Shell!</description>
    <mitre>
      <id>T1190</id>
      <id>T1505.003</id>
    </mitre>
  </rule>

</group>

Passo 2: O Script de Resposta Ativa de Quarentena no Servidor Linux

No teu servidor Linux monitorizado (onde corre o wazuh-agent), vamos criar o executável /var/ossec/active-response/bin/webxtek-quarantine-file.sh. Quando a regra 100550 ou 100551 dispara, este script recebe o JSON do alerta via stdin, extrai o caminho exato do ficheiro malicioso, move-o instantaneamente para uma pasta de quarentena isolada (/var/ossec/quarantine), retira-lhe todas as permissões (chmod 0000) para que o Nginx/PHP nunca mais o consiga executar, e preserva uma cópia forense para análise:

#!/usr/bin/env bash
# ============================================================================
# /var/ossec/active-response/bin/webxtek-quarantine-file.sh
# Playbook de Resposta Ativa Wazuh: Isolamento Instantaneo de Webshells
# ============================================================================

set -uo pipefail

QUARANTINE_DIR="/var/ossec/quarantine"
LOG_FILE="/var/ossec/logs/active-responses.log"

mkdir -p "$QUARANTINE_DIR"
chmod 0700 "$QUARANTINE_DIR"

# 1. Ler o payload JSON enviado pelo Wazuh Agent via STDIN
read -r INPUT_JSON

COMMAND=$(echo "$INPUT_JSON" | jq -r '.command // empty')
FILENAME=$(echo "$INPUT_JSON" | jq -r '.parameters.alert.syscheck.path // empty')
RULE_ID=$(echo "$INPUT_JSON" | jq -r '.parameters.alert.rule.id // empty')
PROC_NAME=$(echo "$INPUT_JSON" | jq -r '.parameters.alert.syscheck.audit.process.name // "unknown"')
PROC_PID=$(echo "$INPUT_JSON" | jq -r '.parameters.alert.syscheck.audit.process.id // "0"')
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

# Executar apenas na acao 'add' e se o ficheiro existir dentro de /var/www
if [[ "$COMMAND" == "add" && -n "$FILENAME" && "$FILENAME" == /var/www/* && -f "$FILENAME" ]]; then
    SAFE_BASENAME=$(basename "$FILENAME")
    QUARANTINE_TARGET="${QUARANTINE_DIR}/${TIMESTAMP}_rule${RULE_ID}_${SAFE_BASENAME}.malicious"

    # 2. Mover atomicamente a webshell para fora do diretorio web e trancar permissoes (0000)
    mv -f "$FILENAME" "$QUARANTINE_TARGET"
    chmod 0000 "$QUARANTINE_TARGET"
    chown root:root "$QUARANTINE_TARGET"

    echo "${TIMESTAMP} [WEBXTEK_ACTIVE_RESPONSE] SUCESSO: Ficheiro suspeito '${FILENAME}' criado por '${PROC_NAME}' (PID ${PROC_PID}) movido para quarentena em '${QUARANTINE_TARGET}' (Regra ${RULE_ID})." >> "$LOG_FILE"
else
    echo "${TIMESTAMP} [WEBXTEK_ACTIVE_RESPONSE] Ignorado ou ficheiro ja removido: '${FILENAME}'." >> "$LOG_FILE"
fi

exit 0

Define as permissões estritas exigidas pelo Wazuh para scripts de resposta ativa:

sudo chown root:wazuh /var/ossec/active-response/bin/webxtek-quarantine-file.sh
sudo chmod 0750 /var/ossec/active-response/bin/webxtek-quarantine-file.sh

Por fim, regista o comando e o gatilho de resposta ativa no /var/ossec/etc/ossec.conf do Wazuh Manager:

<!-- Adicionar no /var/ossec/etc/ossec.conf do Wazuh Manager -->
<command>
  <name>webxtek-quarantine-file</name>
  <executable>webxtek-quarantine-file.sh</executable>
  <timeout_allowed>no</timeout_allowed>
</command>

<active-response>
  <disabled>no</disabled>
  <command>webxtek-quarantine-file</command>
  <location>local</location>
  <rules_id>100550,100551</rules_id>
</active-response>

Pensa na eficácia desta defesa em camadas: mesmo que um atacante descubra uma falha de upload num plugin de terceiros e consiga gravar exploit.php na pasta /uploads/, no milissegundo em que o ficheiro toca no disco o auditd avisa o Wazuh, a regra 100550 dispara e o script webxtek-quarantine-file.sh arranca o ficheiro da pasta pública antes que o atacante consiga fazer o pedido HTTP GET /uploads/exploit.php para abrir a shell!


4. Comparativo Técnico: Logs Passivos vs. Wazuh FIM (whodata + Resposta Ativa)

Na tabela seguinte comparo a monitorização tradicional encontrada na maioria das empresas com a arquitetura de defesa ativa que implementamos nos servidores geridos pelo Webxtek Studio:

Dimensão de Segurança / Resposta Monitorização Tradicional (Cron / inotify Básico) Padrão Blindado Webxtek (Wazuh whodata + Active Response) Impacto Real na Tua Infraestrutura
Tempo até à Deteção (MTTD) 12 a 24 horas (varrimento noturno) < 50 milissegundos (evento direto do kernel auditd) Deteta a intrusão no exato momento da escrita em disco
Identificação do Culpado (Who-Data) Desconhecido (sabe que o ficheiro mudou, mas não quem o fez) Atribuição Completa (auid, euid, pid e binário exato) Sabes imediatamente se foi um humano por SSH ou um processo web
Visibilidade da Alteração (Diff) Apenas alerta que o hash SHA-256 mudou Mostra a linha exata de código alterada (report_changes) Triagem de incidentes 90% mais rápida
Proteção de Ficheiros de Segredos Risco de enviar .env ou senhas para o servidor de logs Bloqueado criptograficamente na origem via <nodiff> Conformidade total com RGPD, PCI-DSS v4.0 e ISO 27001
Tempo de Contenção (MTTR) Horas (espera que um analista acorde e entre por SSH) Automático (< 200 ms) via quarentena de ficheiro e drop de IP A webshell é neutralizada antes de poder ser executada

Quando lideras operações exigentes em Fintech Startups (Neobanks) ou plataformas de missão crítica em Astroturismo e Viagens Estratosféricas, onde o desenvolvimento de Web Apps transaciona dados de elevado valor e campanhas de Produção de Vídeo para Impacto Digital geram picos massivos de tráfego internacional, apoiar toda a operação no nosso serviço de Alojamento Gerido para Websites e Aplicações com Wazuh ativo dá-te a tranquilidade de ter um guarda robótico a vigiar cada chamada de sistema 24 horas por dia.


5. Checklist Prática de 5 Passos Para Produção

Antes de dares a tua implementação do Wazuh SIEM por concluída, valida estes cinco pontos fundamentais no teu terminal:

  1. Testa o Gatilho whodata com um Canário Inofensivo: Cria um ficheiro de teste vazio como o utilizador web (sudo -u www-data touch /var/www/app_producao/public/uploads/teste_canario.php) e verifica em /var/ossec/logs/active-responses.log se o ficheiro foi movido para /var/ossec/quarantine/ em menos de um segundo e se o alerta surgiu no painel do Wazuh com audit.euid.name: www-data.
  2. Protege Contra Autobloqueio (Allowlist de IPs na Resposta Ativa): No bloco <global> do /var/ossec/etc/ossec.conf do Wazuh Manager, declara obrigatoriamente nas tags <white_list> os endereços IP do teu escritório, da tua VPN WireGuard, dos nós da CDN (Cloudflare) e dos servidores de DNS (1.1.1.1, 8.8.8.8), impedindo que um atacante forje pacotes para bloquear os teus próprios sistemas na firewall.
  3. Audita a Lista de <nodiff>: Confirma segundo as diretrizes de documentation.wazuh.com que nenhum ficheiro contendo chaves privadas ou palavras-passe (.env, wp-config.php, /etc/shadow) está a enviar diffs de texto para o indexador OpenSearch do Wazuh.
  4. Silencia Pastas de Cache durante Deploys Oficiais: Para evitares que a regra 100551 dispare falsos positivos quando a tua própria pipeline de CI/CD faz deploy de código novo, faz os teus deploys correrem com um utilizador dedicado (deployer) e restringe a regra de bloqueio automático a escritas originadas pelos binários de servidor web (php-fpm, nginx, apache2).
  5. Ativa a Monitorização de Imutabilidade no Agente: Monitoriza o próprio ficheiro /var/ossec/etc/ossec.conf e o serviço wazuh-agent com systemd (Restart=always) para garantires que qualquer tentativa de parar o agente dispara um alerta imediato de perda de batimento cardíaco (agent disconnected) no servidor central. Além da resposta a incidentes ao nível do host com o Wazuh, testes contínuos de invasão de código antes do deploy podem ser automatizados via agentes dedicados, como na nossa arquitetura de agentes Caçador e Verificador com sandboxing.

A cibersegurança moderna decide-se na fração de segundo entre o momento em que um atacante toca no teu disco e o momento em que o teu sistema reage. No Webxtek Studio, unimos engenharia de sistemas Linux e defesa ativa automatizada para proteger infraestruturas empresariais de topo. Através das nossas soluções de Alojamento Gerido para Websites e Aplicações, desenvolvimento à medida de Web Apps e criação de ativos visuais com Produção de Vídeo para Impacto Digital, garantimos que a tua operação digital escala com segurança inviolável, visibilidade forense total e performance de excelência.

[+] [ INDEX_DIRECTORY ] 17 tópicos ▼
[ SYSTEM.FAQ ]

Perguntas Frequentes

Qual é a diferença técnica entre o modo realtime='yes' (inotify) e o modo whodata='yes' (auditd) no File Integrity Monitoring (FIM) do Wazuh?

O modo realtime='yes' utiliza a API inotify do kernel Linux para detetar instantaneamente que um ficheiro foi criado ou modificado, mas o inotify não informa qual foi o utilizador ou processo responsável pela alteração. Já o modo whodata='yes' liga o Wazuh diretamente ao subsistema Linux Audit (auditd), capturando em tempo real o Audit UID (auid), o utilizador efetivo (euid), o PID, o nome do binário executável e o processo pai que tocou no ficheiro.

Como é que o atributo Audit UID (auid) do auditd impede que um atacante esconda o seu rasto depois de escalar privilégios para root?

Quando um utilizador entra por SSH com a conta 'dev_externo' (UID 1005) e depois executa 'sudo su -' para se tornar 'root' (UID 0), as ferramentas normais passam a mostrar apenas 'root'. Contudo, o kernel Linux preserva de forma imutável o Login UID original no campo auid=1005. Com whodata='yes' no Wazuh, ficas a saber exatamente que conta inicial originou a alteração no ficheiro, mesmo através de múltiplos saltos sudo.

Como funciona o módulo Active Response do Wazuh para neutralizar uma webshell e bloquear o atacante em milissegundos?

Quando o motor de análise do Wazuh Manager recebe o evento FIM de criação de um ficheiro .php suspeito ou tentativa de exploração web e dispara uma regra de severidade crítica, envia um comando assinado de volta ao agente Linux. O agente executa imediatamente um script local em /var/ossec/active-response/bin/ que move o ficheiro malicioso para quarentena sem permissões de execução e adiciona o IP de origem a um conjunto de bloqueio (drop) no nftables.

Que cuidados de segurança deves ter com a diretiva report_changes='yes' no Wazuh para não expor senhas nos logs do SIEM?

A diretiva report_changes='yes' guarda uma cópia local dos ficheiros de texto monitorizados para calcular e enviar o diff exato das linhas alteradas para o painel do Wazuh. Para evitares que chaves privadas TLS, ficheiros .env ou /etc/shadow fiquem expostos em texto limpo nos índices do SIEM, tens obrigatoriamente de declarar esses ficheiros sensíveis dentro de tags no ficheiro ossec.conf.

> INICIAR_PROJETO

Precisa de um website que transmita confiança, apareça na pesquisa e dê mais força à sua presença digital? Comece a conversa aqui.