Por: @jonasc
Publicado em: 2021-04-11

Snort IPS

O Snort é o maior software Open Source de IDS/IPS (Intrusion Detection System / Intrusion Prevention System) no mundo. O sistema de detecção de intrusão usa uma série de regras para definir tráfegos maliciosos na rede e usa essas regras para comparar com os pacotes de rede e gerar alertas para o usuário quando as regras casarem o padrão. Em conjunto, o sistema de prevenção de intrusão pode ser implementado no software para barrar o tráfego malicioso.

O código fonte do Snort Engine (motor IDS/IPS) e da Community Snort Rules são regidos pela licença GNU GPLv2. Já o uso das regras proprietárias do Snort (disponível para assinantes) é regido pela licença Non-Commercial Use License for the Proprietary Snort Rules.

O Snort conta com um amplo time de desenvolvedores e contribuidores, como pode ser visto na área de contato no site. A empresa por trás do projeto Snort é a Cisco Systems e o grupo responsável pela atualização das listas de regras proprietárias do Snort é o Cisco Talos Intelligence Group, um dos maiores times de inteligência contra ameaças e ciberataques no mundo.

Este laboratório irá focar na implementação do Snort 3 como IPS.

Topologia

Topologia de rede padrão com FWFLEX sobre CentOS 8 e IDS funcional, seguindo o labratório Snort IDS.

Instalação

O Snort 3 já possui recurso de IPS nativo e nenhum pacote adicional será necessário.

Configuração do IPS

Configurando mode inline para ativar o IPS na seção ips em /usr/local/snort/etc/snort/snort.lua:

ips =
{
    mode = inline,
    -- use this to enable decoder and inspector alerts
    --enable_builtin_rules = true,

    -- use include for rules files; be sure to set your path
    -- note that rules files can include other rules files
    --include = 'snort3-community.rules',

    variables = default_variables,

    rules = [[
        include $RULE_PATH/snort3-community.rules
        include $RULE_PATH/itflex-custom.rules
    ]]
}

Configurando a biblioteca DAQ para usar IPS na seção daq em /usr/local/snort/etc/snort/inline.lua:

daq =
{
    module_dirs =
    {
        '/usr/local/lib/daq/',
    },
    modules =
    {
        {
            name = 'afpacket',
            mode = 'inline',
            variables =
            {
                'fanout_type=hash'
            }
        }
    },
    inputs =
    {
        'ens18:ens19',
    }
}

OBS: No modo IPS, é necessário passar pelo menos 2 devices (entrada e saída).

Ativando o IPS no módulo normalizer em /usr/local/snort/etc/snort/snort.lua:

normalizer =
{
    tcp =
    {
        ips = true,
    }
}

Testando pela linha de comando:

snort -c snort.lua --daq-dir /usr/local/lib/daq --daq afpacket --daq-var fanout_type=hash -i ens18:ens19 -Q

Ajustando unit do systemd:

[Unit]
Description=Snort 3 Intrusion Detection and Prevention service
After=syslog.target network.target

[Service]
Type=simple
ExecStart=/usr/local/snort/bin/snort -c /usr/local/snort/etc/snort/snort.lua --plugin-path /usr/local/snort/extra -l /var/log/snort -D -u snort -g snort --create-pidfile -k none
ExecReload=/bin/kill -SIGHUP $MAINPID
User=snort
Group=snort
Restart=on-failure
RestartSec=5s
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_IPC_LOCK
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_IPC_LOCK

[Install]
WantedBy=multi-user.target

OBS: Foi removido apenas o parâmetro de device de rede, pois todas as opções foram especificadas nos arquivos de configuração.

Ativando o IPS:

systemctl daemon-reload
systemctl restart snort

Configuração de Regras

Por padrão, as regras marcadas com alert já passam a descartar os pacotes no IPS. Porém o Snort permite configurar regras com ações específicas:

  1. alert - Gera o alerta e log do pacote
  2. log - gera log do pacote
  3. pass - ignora o pacote (deixa passar)
  4. drop - Descarta e gera log do pacote
  5. reject - Bloqueia, gera log e envia um TCP reset (para TCP) ou ICMP port unreachable (para UDP)
  6. sdrop - Descarta o pacote, mas não gera log (silent drop)

Testes

Regras usadas para simulação em itflex-custom.rules:

drop icmp any any -> 1.1.1.1 any (
    msg:”TESTE ICMP”;
    sid:1000003;
    rev:1;
    classtype:icmp-event;
)

Testes executados:

$ ping 1.1.1.1

Log comum gerado:

04/14-11:17:09.118653 [**] [1:1000003:1] ”TESTE ICMP” [**] [Classification: Generic ICMP event] [Priority: 3] [AppID: ICMP] {ICMP} 172.28.60.63 -> 1.1.1.1
04/14-11:17:10.134211 [**] [1:1000003:1] ”TESTE ICMP” [**] [Classification: Generic ICMP event] [Priority: 3] [AppID: ICMP] {ICMP} 172.28.60.63 -> 1.1.1.1

Log no formato JSON:

{ "timestamp" : "04/14-11:15:09.007385", "iface" : "ens18:ens19", "src_addr" : "172.28.60.63", "dst_addr" : "1.1.1.1", "proto" : "ICMP", "action" : "allow", "msg" : ”TESTE ICMP”, "priority" : 3, "class" : "Generic ICMP event", "sid" : 1000003 }
{ "timestamp" : "04/14-11:15:12.080434", "iface" : "ens18:ens19", "src_addr" : "172.28.60.63", "dst_addr" : "1.1.1.1", "proto" : "ICMP", "action" : "allow", "msg" : ”TESTE ICMP”, "priority" : 3, "class" : "Generic ICMP event", "sid" : 1000003 }

OBS: A doc informa que o alert apenas gera alerta, mas nos testes ele se comportou igual ao drop.

Resultados

Algumas considerações importantes:

  • O Snort se mostrou eficaz como recurso de IPS
  • Ao ativar o IPS, o tráfego foi bloqueado como esperado
  • Nenhum outro log foi gerado além dos de alerta
  • Não gera log no iptables
  • Não cria regras diretamente no iptables

Outros plugins de IPS foram avaliados (SnortSam e Guardian), mas ambos possuem atualizações no repositório somente de 2015 e não passaram confiança de que estão recebendo manutenção.

O recurso nativo do Snort atendeu as expectativas para o IPS.