Crie um IDS simples usando o SWATCH

De Wiki Hackstore
Security-Firewall-IDS graphic.jpg


Compile o sistema SWATCH

Existe uma ferramenta de monitoramento de logs que executa determinadas funções de acordo com regras específicas. Em um sistema Gentoo based é natural utilizar o servidor SSH com logs sendo enviados para o syslog-ng. Logo basta compilar a ferramenta Swatch [1] para ter tal funcionalidade em seu sistema.

emerge app-admin/swatch

Entenda como funcionam as regras

Basicamente em um arquivo de configuração do swatch, em cada regra existem ítens a serem configurados: "watchfor, threshold, exec".

watchfor

São os registros a serem encontrados nos logs para que sejam executadas as funções "threshold" e "exec". Note que é possível utilizar expressões regulares:

watchfor /([aA]uthentication [fF]ailure for [iI]llegal [uU]ser)(.*)( from )(.*)$/

Dessa forma, caso alguém realize tentativa de login usando um usuário ilegal no sistema é executada uma função especificada no arquivo de configuração. É importante observar que cada espaço de variável a serem usados nas funções seguintes é definida pelo swatch como "(.*)". Dessa forma o ip do dito cujo que é a informação a ser obtida dos logs se torna a variável $4. Esse valor não é regra, e a cada regra pode ser diferente, como $1 $2 $3 e daí por diante.

threshold

Essa função caso seja acionada define uma condição para que a função "exec" seja acionada. No exemplo abaixo é definido que caso seja realizada tentativa de acesso ao sistema ao total de duas vezes em um intervalo de 15 minutos é executada função "exec" em si.

threshold track_by=$4,type=both,count=2,seconds=900

exec

Executa um comando no sistema. Pode ser usado repetidas vezes. Com o exemplo abaixo, o ip de origem da tentativa de acesso ilegal é inserido na tabela criada anteriormente no firewall.

exec "/sbin/iptables -A swatch_rejects -s $4 -m comment --comment "Bloqueio por tentativa indevida de acesso SSH" -j DROP"

Com o comando abaixo inserimos o ip em uma lista negra no sistema:

exec "echo '$4' >> /opt/yax/firewall/listas/ips-blocked-swatch-ssh.txt"

É possível também enviar emails de notificação:

exec "echo -e 'IP $4 adicionado à tabela "swatch_rejects" por sucessivas tentativas incorretas de login via SSH.\n\nLogin utilizado: $2\nIP origem: $4\n\nGenerated by SWATCH - Yaxkin Firewall' | mail root -s 'Login ilegal - Regra DROP de Iptables Adicionada'"


Crie a tabela necessária no firewall

Caso a política do seu firewall seja a de bloqueio total de todos os pacotes na tabela INPUT, utilize o exemplo abaixo. Caso sua política seja diferente, modifique ao seu bel prazer. ;)

# Criando tabelas para swatch (proteção SSH e outros)
iptables -P INPUT DROP
iptables -N swatch_rejects
iptables -I INPUT 5 -j swatch_rejects

Adicione o script ao firewall para que sejam inseridos os IPs no ato de início do mesmo.

# Bloqueando IPs contidos na black-list
bash /opt/yax/firewall/script-listas-ips-blocked-swatch.sh


Crie um arquivo de configuração básico

vi /opt/yax/firewall/conf/firewall.conf
ROOTDIR="/opt/yax/firewall"

# Yax fw-Blocked
DROPDIR="${ROOTDIR}/blocked"
LISTA_IPS="${DROPDIR}/ips-blocked-swatch-ssh.txt"
LISTA_DROPED="${DROPDIR}/ips-blocked-swatch-ssh.txt"
WHITELIST="${DROPDIR}/ips-whitelist-swatch-ssh.txt"


Crie um script para leitura de Black List

Crie o diretório necessário para as listas, e crie um script que automatize a inserção de ips na tabela criada no firewall.

mkdir -p /opt/yax/firewall/listas
vi /opt/yax/firewall/bin/script-listas-ips-blocked-swatch.sh
#!/bin/bash
########################################################################
#                                                                      #
# Bloqueia vários ips via tabela "swatch_rejects" utilizando listas    #
# geradas pelo Swatch.                                                 #
#                                                                      #
# Blocks via multiple ips table "swatch_rejects" using lists generated #
# by Swatch.                                                           #
#                                                                      #
# Autor: Raphael Bastos aka coffnix                                    #
#                                                                      #
########################################################################
#
# Crie a tabela necessária para o Swatch (proteção SSH e outros) e
# inclua este script em /etc/init.d/firewall:
#
# ----->> iptables -N SWATCH
# ----->> iptables -I INPUT 5 -j SWATCH
# ----->> bash /opt/yax/firewall/script-listas-ips-blocked-swatch.sh
#
########################################################################
# Carrega variaveis do script:
source /opt/yax/firewall/conf/firewall.conf

########################################################################
# Cria diretórios e arquivos básicos caso seja necessário:
if [ ! -d ${DROPDIR} ];then
        mkdir -p ${DROPDIR}
fi

if [ ! -e ${LISTA_IPS} ];then
        touch ${LISTA_IPS}
fi

########################################################################
# Libera ips contidos na lista branca via iptables
while IFS=\= read IP_WHITELIST DESCRICAO;do
        if [ -n ${IP_WHITELIST} ];then

                # Libera apenas IPs reais - RFC1918
                IP_VALIDO=$(echo ${IP_WHITELIST}| egrep '^(((1[0-9]|[1-9]?)[0-9]|2([0-4][0-9]|5[0-5]))\.){3}((1[0-9]|[1-9]?)[0-9]|2([0-4][0-9]|5[0-5]))$')
                ######## MASCARA_VALIDA=$(echo ${IP_WHITELIST}| egrep '^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$')
                if [ -n "${IP_VALIDO}" ];then
                        /sbin/iptables -I INPUT -s ${IP_VALIDO} -m comment --comment "Liberado via whitelist - ${DESCRICAO}" -j ACCEPT
                fi
        fi
done < ${WHITELIST}

########################################################################
# Remove ips contidos na lista branca da lista negra
while IFS=\= read IP_WHITELIST DESCRICAO;do
        if [ ! -z ${IP_WHITELIST} ];then
                sed -i /"$IP_WHITELIST"/d ${LISTA_IPS}
        fi
done < ${WHITELIST}

########################################################################
# Adiciona país de origem do IP utilizando GEOIP:
${ROOTDIR}/bin/geoip-lista.sh

########################################################################
# realiza limpeza da lista (ips repetidos)
${ROOTDIR}/bin/clean-lista-block-swatch.sh

########################################################################
# Bloqueia permanentemente IPs via tabela SWATCH:
while IFS=\= read IP ORIGEM;do
        if [ ! -z ${IP} ];then
                /sbin/iptables -A SWATCH -s ${IP} -m comment --comment "Bloqueio por tentativa indevida de acesso SSH | Origem: ${ORIGEM}" -j DROP
        fi
done < ${LISTA_IPS}

#########################################################################

# Corrige permissão de arquivos
chown apache. -R ${DROPDIR}

# Fim

Crie um script para inserir os ips em um arquivo de texto

vi /opt/yax/firewall/bin/insert-block-swatch.sh

#!/bin/bash

LISTA_BLOCKED="/opt/yax/firewall/blocked/ips-blocked-swatch-ssh.txt"

if [ -z $1 ];then
        echo "Insira um IP"
        exit 1
else
        if [ -z $2 ];then
                echo "Insira um LOGIN"
                exit 1
        fi
fi
CHECK_LISTED=$(grep ${1} ${LISTA_BLOCKED} | wc -l)

        /sbin/iptables -A SWATCH -s $1 -m comment --comment "Bloqueio por tentativa indevida de acesso SSH" -j DROP
        # Se o IP foi valido.... (caso não ocorra erro na regra do iptables)
        if [ $? -eq 0 ]; then

                # Se não existir na lista de bloqueio....
                if [ ${CHECK_LISTED} -eq 0 ]; then

                        # ...adiciona o IP a lista de bloqueio
                        echo "${1}=geoip" >> /opt/yax/firewall/blocked/ips-blocked-swatch-ssh.txt

                        # ...envia email
                        echo -e "Olá,\n\nDevido a tentativas de acesso não autorizadas via SSH, o IP  $1  foi adicionado à tabela "SWATCH" do Firewall.\n\nEm: $(date)\nLogin utilizado:  $2\nIP:  $1\nPaís de origem:  $(geoiplookup ${1}|sed s/'GeoIP Country Edition: '//g)\n\n\nGenerated by SWATCH - Hackstore." |  mail root -s "[SWATCH] Regra DROP de Iptables Adicionada para IP $1"
                        /etc/init.d/firewall restart
                        echo "IP ${1} bloqueado com sucesso!"
                fi
        # caso contrário
        else
                echo "Insira um endereço IP valido"
                # sai do script
                exit 1
        fi

Crie um script para interpretar a origem via ip (GEOIP)

vi /opt/yax/firewall/bin/geoip-lista.sh
#!/bin/bash
#########################################################################
#                                                                       #
# Obtem pais de cada ip utiliando geoip                                 #
# by Swatch.                                                            #
#                                                                       #
# Autor: Raphael Bastos aka coffnix                                     #
#########################################################################

# Obtem variaveis de ambiente:
source /opt/yax/firewall/conf/firewall.conf

########################################################################

# Cria diretórios e arquivos básicos caso seja necessário:
if [ ! -d ${ROOTDIR} ];then
        mkdir -p ${ROOTDIR}
fi

if [ ! -e ${LISTA_DROPED} ];then
        touch ${LISTA_DROPED}
fi

# Função que remove espaços vazios
crunch () {
       read STRING;
       echo $STRING
        }


# Remove linhas repetidas:
sort ${LISTA_DROPED} | uniq > /tmp/ips-blocked-swatch-ssh.new && mv ${LISTA_DROPED} /tmp/ips-blocked-swatch-ssh.old && mv /tmp/ips-blocked-swatch-ssh.new ${LISTA_DROPED}
sed -i /'IP Address not found'/d ${LISTA_DROPED}

sed -i s,'geoip',,g ${LISTA_DROPED}

########################################################################

while IFS=\= read IP ORIGEM;do
        if [ -z "${ORIGEM}" ];then
                        NOVA_ORIGEM=$(geoiplookup ${IP}|sed s/'GeoIP Country Edition: '//g|grep -v 'GeoIP ASNum Edition')
                        sed -i s/${IP}=/"${IP}=${NOVA_ORIGEM}"/g $LISTA_DROPED
                        echo "Adicionada nova origem ${IP} - ${NOVA_ORIGEM}"
        fi
done < ${LISTA_DROPED}

# Remove linhas repetidas:
sort ${LISTA_DROPED} | uniq > /tmp/ips-blocked-swatch-ssh.new && mv ${LISTA_DROPED} /tmp/ips-blocked-swatch-ssh.old && mv /tmp/ips-blocked-swatch-ssh.new ${LISTA_DROPED}
########################################################################
# Fim


Crie um script para limpar as sujeiras e ips repetidos da lista

vi /opt/yax/firewall/bin/clean-lista-block-swatch.sh
#!/bin/bash

DATE_UNIX=$(date +%s)

########################################################################

# Carrega variaveis do script:
source /opt/yax/firewall/conf/firewall.conf

########################################################################


# função que remove espaços em branco:
crunch() {
        while read FOO ; do
                echo $FOO
        done
        }

########################################################################

# Remove ips duplicados
cat ${LISTA_IPS} |crunch | sort | uniq > /tmp/yaxfw-${DATE_UNIX}.tmp

# faz backup
cp ${LISTA_IPS} "${DROPDIR}/bkp/ips-blocked-swatch-ssh.txt-${DATE_UNIX}"
gzip "${DROPDIR}/bkp/ips-blocked-swatch-ssh.txt-${DATE_UNIX}"

# Remove linhas vazias
sed -i '/^[\ ]\+\?$/d' /tmp/yaxfw-${DATE_UNIX}.tmp
#sed -i '/^[\ ]\+\?$/d' ${WHITELIST}

# Remove itens duplicados:
sort /tmp/yaxfw-${DATE_UNIX}.tmp | uniq > /tmp/yaxfw-${DATE_UNIX}.tmp2

# Substitui lista
if [ -s "/tmp/yaxfw-${DATE_UNIX}.tmp2" ];then
        cp /tmp/yaxfw-${DATE_UNIX}.tmp2 ${LISTA_IPS}
fi

########################################################################

# Corrige permissão de arquivos
chown apache. -R ${DROPDIR}

Configure as regras

Crie um arquivo de configuração para o SWATCH.

mv /etc/swatch/swatch.conf /etc/swatch/swatch.conf.ori
touch /etc/swatch/swatch.conf

Crie o arquivo /etc/swatch/swatch.conf como no exemplo abaixo: Com atenção para o início das regras, sempre são ignoradas redes locais. Inclua outras redes caso seja necessário.

# Global swatch filter file
#
ignore /127\.0\.0\./
ignore /localhost/
ignore /192\.168\./
ignore /10\.0\./
ignore /start\-stop\-daemon\:session/


# Bloqueia o ip caso o usuário seja bloqueado no sistema, logo na primeira tentativa:
watchfor /([aA]uthentication [fF]ailure for [iI]llegal [uU]ser)(.*)( from )(.*)$/
threshold track_by=$4,type=both,count=1,seconds=900
# executa bloqueio
exec "/opt/yax/firewall/bin/insert-block-swatch.sh ${4} ${2}"
# gera log
exec "echo -e "\n`date +"%d/%m/%Y %H:%M"` - IP ${4} bloqueado pois a tentativa de login utilizando usuário ${2} foi ilegal. Bloqueio logo na primeira tentativa." >> /opt/yax/firewall/logs/swatch.log"

################################################################################################################
# Bloqueia o ip caso o usuário não exista no sistema, logo na primeira tentativa:
watchfor /([aA]uthentication [fF]ailure for [iI]nvalid [uU]ser)(.*)( from )(.*)$/
threshold track_by=$4,type=both,count=1,seconds=900
# executa bloqueio
exec "/opt/yax/firewall/bin/insert-block-swatch.sh ${4} ${2}"
# gera log
exec "echo -e "\n`date +"%d/%m/%Y %H:%M"` - IP ${4} bloqueado pois o usuário ${2} não existe. Bloqueio logo na primeira tentativa." >> /opt/yax/firewall/logs/swatch.log"

################################################################################################################
# Bloqueia o ip caso o usuário não esteja autorizado para acesso SSH (AllowUsers), logo na primeira tentativa:
watchfor /(User(.*)from (.*) not allowed because not listed in AllowUsers)$/
threshold track_by=$3,type=both,count=3,seconds=900
# executa bloqueio
exec "/opt/yax/firewall/bin/insert-block-swatch.sh ${3} ${2}"
# gera log
exec "echo -e "\n`date +"%d/%m/%Y %H:%M"` - IP ${3} bloqueado pois o usuário ${2} não tem autorização para login via SSH. Bloqueio na terceira tentativa." >> /opt/yax/firewall/logs/swatch.log"


Inicie o Swatch, adicione ao boot e seja feliz

Inicie o daemon do swatch:

/etc/init.d/swatch start

Adicione ao boot:

rc-update add swatch default