IDS/Prelude

De TartareFR
Aller à la navigation Aller à la recherche

Introduction

Ce document décrit le déroulement pas à pas de l'installation d'un serveur de détection d'intrusion.

Nous utiliserons <package>prelude</package> comme aggrégateur, <package>snort</package> ou <package>suricata</package> pour la partie NIDS, <package>ossec</package> pour la partie HIDS, <package>prelude-lml</package> pour parser les fichiers de log locaux et <package>prewikka</package> pour l'affichage des données.

Prelude est un système de détection d’intrusion hybride composé de plusieurs plugins, sondes. Prelude a été conçu dans le but d’être modulaire, souple, et résistant aux attaques. Sa modularité permet notamment de lui rajouter facilement de nouveaux types de détecteurs d’intrusion, d’analyseurs de logs et d’une solution de corrélation, le tout au format et à la norme IDMEF (Intrusion Detection Message Exchange Format), bien que de nombreux autres formats de logs sont compatibles.

On prendra soin d'installer soit snort soit suricata, mais il est conseillé d'en avoir qu'un seul actif par hôte.

Prérequis :

  • CentOS fresh install.
  • Dépôt yum b2pweb.

Installation du système de détection d'intrusion

Installation des dépendances

Nous aurons besoin d'un serveur de base de données MySQL, d'un serveur web ( avec les modules mod_ssl et mod_python ) et de php.

yum install mysql-server httpd mod_ssl mod_python php php-mysql

Installation de la suite prelude

Avec les RPM, ça se résume à :

yum install libprelude libprelude-devel libpreludedb-mysql prelude-manager mysql-client prelude-manager-xml-plugin prelude-manager-db-plugin prelude-lml

On créer la base de données

mysql -e "create database prelude;" 
mysql -e "grant all privileges on prelude.* to prelude@localhost identified by 'prelude';" 

sed -i -e "/InnoDB/ s/TYPE/ENGINE/g" /usr/share/libpreludedb/classic/mysql.sql
mysql -u prelude -p prelude < /usr/share/libpreludedb/classic/mysql.sql

On enregistre prelude-manager et on démarre le manager

prelude-admin add "prelude-manager" --uid 0 --gid 0
/etc/init.d/prelude-manager start
Important.png
Enregistrement des sondes
L'enregistrement nécessite l'ouverture de deux shells en parallèle:
  • un shell pour fournir un mot de passe one-shot à la connexion avec le prelude-manager
  • un autre pour enregistrer la sonde

Installation de prewikka

yum install prewikka

On créer sa base de données

mysql -e "create database prewikka;" 
mysql -e "grant all privileges on prewikka.* to prewikka@localhost identified by 'prewikka';" 
mysql -u prewikka -p prewikka < /usr/share/prewikka/database/mysql.sql

on créer le virtual host

<VirtualHost *:80>
   ServerAdmin webmaster@localhost
   ServerName vmdidier1.b2pweb.com
 
   Alias /prewikka /usr/share/prewikka/htdocs
   ScriptAlias /ids /usr/share/prewikka/cgi-bin/prewikka.cgi
 
   <Directory "/usr/share/prewikka">
     AllowOverride FileInfo AuthConfig Limit Indexes 
     Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
     <Limit GET POST OPTIONS>
       Order allow,deny
       Allow from all
     </Limit>
     <LimitExcept GET POST OPTIONS>
       Order deny,allow
       Deny from all
     </LimitExcept>
   </Directory>
</VirtualHost>

Installation ossec

yum install ossec-hids-server

enregistrement d'ossec comme sonde prelude

Ouverture de deux shells en parallèle

# prelude-admin registration-server prelude-manager
The "app4yb0m" password will be requested by "prelude-admin register" 
in order to connect. Please remove the quotes before using it.

Generating 1024 bits Diffie-Hellman key for anonymous authentication...
Waiting for peers install request on :::5553...
Waiting for peers install request on 0.0.0.0:5553...

Connection from ::ffff:127.0.0.1:34094...
Registration request for analyzerID="1008635719879802" permission="idmef:w admin:r".
Approve registration? [y/n]: y
::ffff:127.0.0.1:34094 successfully registered.
# prelude-admin register ossec "idmef:w admin:r" 127.0.0.1 --uid 0 --gid 0

You now need to start "prelude-admin" registration-server on 127.0.0.1:
example: "prelude-admin registration-server prelude-manager" 

Enter the one-shot password provided on 127.0.0.1: 
Confirm the one-shot password provided on 127.0.0.1: 

Connecting to registration server (127.0.0.1:5553)... Authentication succeeded.
Successful registration to 127.0.0.1:5553.

On modifie la configuration d'ossec, dans le fichier <path>/var/ossec/etc/ossec.conf</path>, rajouter à la balise <global>

<global>
...

<prelude_output>yes</prelude_output>
<prelude_profile>ossec</prelude_profile>
<prelude_log_level>6</prelude_log_level>

...
</global>

redémarrage d'ossec

/etc/init.d/ossec-hids start

Installation de oinkmaster

C'est le script perl de mise à jour des règles officielles VTR de snort ( qui fonctionne aussi avec suricata )

yum install oinkmaster

on récupère le "oink code" sur le site de snort ( après enregistrement )

d5f57c7ff55b8e103893eb2f9aa1a933f36ea424

et on remplace dans /etc/oinkmaster.conf

url = http://www.snort.org/pub-bin/oinkmaster.cgi/d5f57c7ff55b8e103893eb2f9aa1a933f36ea424/snortrules-snapshot-2900.tar.gz

Téléchargement des règles officiellespetit script pour wrapper le script perl

Fichier <path>/usr/bin/oinkmaster</path>

#!/bin/sh

BIN_PATH="/usr/bin" 
RULES_PATH="/etc/snort/rules" 
RULES_BACKUP_PATH="/etc/snort/rules-backup" 
OINKMASTER_CONF_FILE="/etc/oinkmaster.conf" 
LOG_FILE="/var/log/oinkmaster.log" 

${BIN_PATH}/oinkmaster.pl -o ${RULES_PATH} -b ${RULES_BACKUP_PATH} -C ${OINKMASTER_CONF_FILE} 1>${LOG_FILE} 2>&1

Et voilà, pour mettre à jour les règles, il suffit de taper ( plus facile pour le cron )

oinkmaster
Idea.png
Suricata
Pour l'utilisation avec suricata, il suffit de modifier les variables RULES_PATH et RULES_BACKUP_PATH pour coller avec l'installation.

Installation de snort

Ici on installe snort, THE détecteur d'intrusion.

yum install snort

dans le fichier /etc/snort/snort.conf, dé-commenter les lignes

output unified2: filename merged.log, limit 128, nostamp, mpls_event_types, vlan_event_types
output alert_prelude profile=snort

On enregistre snort dans prelude, l'uid et le gid peuvent être trouvé avec la commande

SNORT_UID=`cat /etc/passwd | grep "^snort" | awk -F ':' '{print $3}'` ; SNORT_GID=`cat /etc/group | grep "^snort" | awk -F ':' '{print $3}'` ; echo "snort: uid=${SNORT_UID}, gid=${SNORT_GID}" 

Ouverture de deux shells en parallèle

# prelude-admin registration-server prelude-manager
The "105g5ukk" password will be requested by "prelude-admin register" 
in order to connect. Please remove the quotes before using it.

Generating 1024 bits Diffie-Hellman key for anonymous authentication...
Waiting for peers install request on :::5553...
Waiting for peers install request on 0.0.0.0:5553...

Connection from ::ffff:127.0.0.1:44183...
Registration request for analyzerID="2107009181484785" permission="idmef:w admin:r".
Approve registration? [y/n]: y
::ffff:127.0.0.1:44183 successfully registered.
# prelude-admin register snort "idmef:w admin:r" 127.0.0.1 --uid 500 --gid 500
Generating 1024 bits RSA private key... This might take a very long time.
[Increasing system activity will speed-up the process].
Generation in progress... X.+++++O.+++++O

You now need to start "prelude-admin" registration-server on 127.0.0.1:
example: "prelude-admin registration-server prelude-manager" 

Enter the one-shot password provided on 127.0.0.1: 
Confirm the one-shot password provided on 127.0.0.1: 

Connecting to registration server (127.0.0.1:5553)... Authentication succeeded.
Successful registration to 127.0.0.1:5553.

On Commente ALERTMODE dans /etc/sysconfig/snort ( sinon prelude ne reconnaît pas snort ) et on le démarre

sed -i -e "/ALERTMODE/ s|^|#|" /etc/sysconfig/snort

/etc/init.d/snortd start

Installation de suricata

L'outsider des sniffeurs.

yum install suricata

On enregistre suricata dans prelude, l'uid et le gid peuvent être trouvé avec la commande

SURICATA_UID=`cat /etc/passwd | grep "^suricata" | awk -F ':' '{print $3}'` ; SURICATA_GID=`cat /etc/group | grep "^suricata" | awk -F ':' '{print $3}'` ; echo "suricata: uid=${SURICATA_UID}, gid=${SURICATA_GID}"

Ouverture de deux shells en parallèle

# prelude-admin registration-server prelude-manager
The "105g5ukk" password will be requested by "prelude-admin register" 
in order to connect. Please remove the quotes before using it.

Generating 1024 bits Diffie-Hellman key for anonymous authentication...
Waiting for peers install request on :::5553...
Waiting for peers install request on 0.0.0.0:5553...

Connection from ::ffff:127.0.0.1:44183...
Registration request for analyzerID="2107009181484785" permission="idmef:w admin:r".
Approve registration? [y/n]: y
::ffff:127.0.0.1:44183 successfully registered.
# prelude-admin register suricata "idmef:w admin:r" 127.0.0.1 --uid 105 --gid 105
Generating 1024 bits RSA private key... This might take a very long time.
[Increasing system activity will speed-up the process].
Generation in progress... X.+++++O.+++++O

You now need to start "prelude-admin" registration-server on 127.0.0.1:
example: "prelude-admin registration-server prelude-manager" 

Enter the one-shot password provided on 127.0.0.1: 
Confirm the one-shot password provided on 127.0.0.1: 

Connecting to registration server (127.0.0.1:5553)... Authentication succeeded.
Successful registration to 127.0.0.1:5553.

Création d'un script de démarrage et d'un fichier sysconfig

Le fichier <path>/etc/init.d/suricata</path>

#!/bin/bash
#
# suricata      This shell script takes care of starting and stopping suricata.
#
# chkconfig: 345 55 45
# description: suricata Intrusion Detection and Prevention Engine.
# probe: false
# processname: suricata
# pidfile: /var/run/suricata.pid
# config: /etc/sysconfig/suricata
### BEGIN INIT INFO
# Provides: suricata
# Required-Start: $network
# Required-Stop: $network
# Default-Start: 3 4 5
# Short-Description: suricata.
# Description: Open Source Next Generation Intrusion Detection and Prevention Engine.
### END INIT INFO

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 0

[ -f /usr/bin/suricata ] || exit 0

[ -f /etc/sysconfig/suricata ] || exit 0

. /etc/sysconfig/suricata
if  "${SURICATA_CONF_FILE}" == "" 
then
		echo -n "No conf file in /etc/sysconfig/suricata" 
		failure
		echo
		exit 1
fi

SURICATA_OPTIONS="-c ${SURICATA_CONF_FILE} -D" 

if [[ "${SURICATA_IFACE}" != "" ]]
then
		SURICATA_OPTIONS="${SURICATA_OPTIONS} -i ${SURICATA_IFACE}" 
fi
if  [[ "${SURICATA_LOG_DIR}" != "" ]]
then
		SURICATA_OPTIONS="${SURICATA_OPTIONS} -l ${SURICATA_LOG_DIR}"
		SURICATA_START=${SURICATA_LOG_DIR}/start.log
fi
if [[  "${SURICATA_PID_FILE}" != "" ]]
then
		SURICATA_OPTIONS="${SURICATA_OPTIONS} --pidfile ${SURICATA_PID_FILE}" 
fi
if [[  "${SURICATA_RULES}" != "" ]]
then
		SURICATA_OPTIONS="${SURICATA_OPTIONS} -s ${SURICATA_RULES}" 
fi
if [[  "${SURICATA_QID" != "" ]]
then
		SURICATA_OPTIONS="${SURICATA_OPTIONS} -q ${#SURICATA_QID}" 
fi
if [[  "${SURICATA_USER}" != "" ]] 
then
		SURICATA_OPTIONS="${SURICATA_OPTIONS} --user ${SURICATA_USER}" 
fi
if [[ "${SURICATA_GROUP}" != "" ]]
then
		SURICATA_OPTIONS="${SURICATA_OPTIONS} --group ${SURICATA_GROUP}" 
fi
if [[ "${SURICATA_PCAP_BUFFER_SIZE}" != "" ]]
then
		SURICATA_OPTIONS="${SURICATA_OPTIONS} --pcap-buffer-size ${SURICATA_PCAP_BUFFER_SIZE}" 
fi

# See how we were called.
case "$1" in
        start)
		if [ -n "`/sbin/pidof suricata`" ]; then
			echo -n "suricata: already running" 
			RETVAL=$?
			echo
			exit $RETVAL
		fi
		echo -n "Starting suricata: " 
		suricata ${SURICATA_OPTIONS} 1>${SURICATA_START-"/var/log/suricata/start.log"} 2>&1
		RETVAL=$?
		[ $RETVAL -eq 0 ] && success || failure
		echo
		[ $RETVAL -eq 0 ] && touch /var/lock/subsys/suricata
		;;
        stop)
		echo -n "Stopping suricata: " 
		killproc suricata
		RETVAL=$?
		echo
		[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/suricata
		;;
        status)
		status suricata
		RETVAL=$?
		;;
        restart|reload)
		$0 stop
		$0 start
		RETVAL=$?
		;;
        *)
		echo "Usage: suricata {start|stop|status|restart}" 
		exit 1
esac

exit $RETVAL

Le fichier <path>/etc/sysconfig/suricata</path>

# suricata sysconfig file

# path to configuration file
SURICATA_CONF_FILE=/etc/suricata/suricata.yaml

# run in pcap live mode
#SURICATA_IFACE=eth0

# default log directory
SURICATA_LOG_DIR=/var/log/suricata

# write pid to this file
SURICATA_PID_FILE=/var/run/suricata.pid

# path to signature file
SURICATA_RULES=/etc/suricata/rules

# run in inline nfqueue mode
SURICATA_QID=0

# run suricata as this user after init
SURICATA_USER=suricata

# run suricata as this group after init
SURICATA_GROUP=suricata

# size of the pcap buffer value from 0 - 2147483647
#SURICATA_PCAP_BUFFER_SIZE=

Comparatif snort - suricata

snort suricata
dépendances facile facile
installation facile moyen
configuration moyen moyen+
règles facile moyen
Intégration avec prelude moyen facile

dépendances

On trouve facilement des RPM pour CentOS. Ils sont de facture maison sur le repo b2pweb

installation

RPM créer facilement pour les deux NIDS.suricata ne dispose pas de script d'init.

configuration

La documentation de suricata est mieux faites ( au niveau de l'index ), mais celle de snort est énorme.

règles

Les règles snort (officielles ou emerging ) ne sont pas supportées à 100% par suricata. Les deux softs ont un système de mise à jour des règles officielles via oinkmaster.

intégration dans prelude

La conf par défaut de suricata contient toutes les entrées nécessaires ( en commentaire ), alors qu'il faut fouiller dans la doc et les wiki pour que snort puisse être une sonde de prelude.

Les deux NIDS ont des besoins similaires :

  • écouter l'intégralité du réseau, ce qui fait que le déploiement sur la plateforme publique ne pourra que se cantonner au LAN.
  • machine dédiée
  • carte réseau dédiée sinon les sniffeurs ne détectent rien du tout.

Configuration de la carte réseau dédiée

DEVICE=eth1
BOOTPROTO=static
ONBOOT=yes
HWADDR=52:54:00:12:34:58

Comme on le constate, la carte est activée au boot, avec une adresse statique mais non renseignée. En fait elle va prendre l'adresse 0.0.0.0 MASK 0.0.0.0Elle est invisible sur le réseau et peut capturer tout le trafic réseau qui est routé sur la branche réseau ( donc le trafic du switch ou de l'hôte dans le cas de VM )

Problèmes connus

Prelude

Une sonde lancé avec un utilisateur différent de root n'envoie pas de heartbeat à prelude.

Ex : suricata est lancé avec l'utilisateur suricata et le groupe suricata.

Il faut vérifier que la sonde a été enregistrée avec les droit de l'utilisateur actuel.

Sinon réinscrire la sonde ( prelude détecte que c'est juste un changement d'uid et de gid )

Mais il peut arriver que le premier lancement de la sonde soit fait en tant que root, et il faut donc fixer les droits du répertoire spool de prélude ( /var/spool/prelude/suricata ).

# prelude-admin chown suricata --uid suricata --gid suricata 

Suricata / snort

La sonde ne détecte rien du tout :

affecter une adresse IP ( non attribuée dans le plan IP de préférence Face-wink.png)

ifconfig eth1 inet 192.168.0.131 netmask 255.255.255.0 -promisc

repassé en mode sniffer.

ifconfig eth1 inet 0.0.0.0 promisc

La commande lancée depuis un hôte quelconque du réseau devrait maintenant être détectée.

nmap -PN 192.168.0.130