====== Système de détection d'intrusion ====== ===== Prérequis ===== Disposer d'un serveur LAMP opérationnel: * [[Braveo:LAMP | Installation du serveur LAMP (Linux Apache Mysql PHP)]] ===== Introduction ===== En matière de sécurité informatique, si la mise en place d'un pare-feu est une chose indispensable pour prévenir les risques d'attaques du serveur, il est également essentiel d'être en mesure d'identifier la menace pour pouvoir le cas échéant mettre en place les contre-mesures nécessaires à la suppression d'une faille du système d'information. C'est le rôle d'un IDS (Intrusion Detection System). On peut distinguer 3 types d'IDS: * HIDS (Host IDS): ils sont capable de remonter des informations renvoyées par la machine ou le système d'exploitation. Ils utilisent pour cela les journaux systèmes créés par les différents applicatifs fonctionnant sur la machine à surveiller. * NIDS (Network IDS): ils récupèrent des informations renvoyées par le réseau en capturant les paquets qui traversent les différentes interfaces à surveiller. * IDS hybride: ils récupèrent les informations renvoyées par la machine ou le système d'exploitation mais aussi celles renvoyées par le réseau, cette solution combine donc les 2 solutions précédentes au sein d'un même framework. C'est donc cette dernière solution que nous allons implémenter. Un IDS hybride très répandu sur les systèmes Linux est Prelude-IDS, disponible sous licence GPL, il permet aussi bien de récupérer les informations renvoyées par le système d'exploitation que celles renvoyées par le réseau. Pour cela, Prelude tire partie de multiples sondes dont le rôle est de récupérer les informations provenant d'une ou plusieurs sources pour permettre une comparaison avec une base de donnée contenant des signatures d'attaques connues. L'installation décrite ci-dessous reçoit ses alertes à l'aide des 2 sondes suivantes: * une sonde réseau (NIDS): snort * une sonde système (HIDS): prelude-lml A ces 2 sondes, nous pouvons en ajouter une troisième dont le but est de permettre la corrélation entre les alertes remontées par les précédentes sondes. Le moteur de corrélation actuellement proposé avec prelude est toujours en cours de développement, pour cette raison so configuration reste en l'état très basiques. Dans une dernière étape, il est possible d'accéder aux alertes détectées par l'intermédiaire de l'interface web d'administration de prelude: prewikka. Cette interface permet à l'administrateur de visualiser les différentes alertes renvoyées par les sondes. Schéma de principe du fonctionnement de l'IDS: {{:server:schema_de_principe.png?650}} ===== Récupérer les sources ===== Dans cette installation j'ai choisi de ne pas utiliser les paquets prépackagés pour lenny mais d'utiliser directement la dernière version de prelude-ids car cette dernière dispose de fonctionnalités supplémentaires permettant par exemple d'accéder à des graphiques de statistiques. Nous devons donc commencer par récupérer les sources sur le site officiel: mkdir prelude && cd ./prelude URI="http://www.prelude-technologies.com/download/releases" VERSION="1.0.0" PACKAGES="libprelude libpreludedb prelude-lml prelude-manager prewikka prelude-correlator" for SOURCE in $PACKAGES; do wget ${URI}/${SOURCE}/${SOURCE}-${VERSION}.tar.gz; done ===== Compiler les sources ===== Pour compiler nos différents paquets, nous devons installer un compilateur sur la machine: apt-get install g++ make Ensuite on peut passer à la compilation des sources: * paquets nécessaires à la compilation de libprelude: apt-get install libgnutls-dev python-dev pkg-config * compilation de libprelude tar xvpf libprelude-1.0.0.tar.gz cd libprelude-1.0.0/ ./configure [...] *** Dumping configuration *** - Generate documentation : no - LUA binding : no - Perl binding : yes - Python binding : yes - Ruby binding : no - Easy bindings : yes make make check make install cd ../ Après chaque installation on recharge ldconfig: /sbin/ldconfig /usr/local/lib * paquets nécessaires à la compilation de libpreludedb (support mysql): apt-get install libmysqlclient15-dev * compilation de libpreludedb tar xvpf libpreludedb-1.0.0.tar.gz cd libpreludedb-1.0.0/ ./configure --with-postgresql=no --with-mysql=yes *** Dumping configuration *** - Generate documentation : no - Enable MySQL plugin : yes - Enable PostgreSQL plugin : no - Enable SQLite3 plugin : no - Perl binding : yes - Python binding : yes make make check make install /sbin/ldconfig /usr/local/lib cd ../ * Création de la base de donnéee et de son utilisateur: mysql -u root -p mysql> CREATE database prelude_database; mysql> GRANT ALL PRIVILEGES ON prelude_database.* TO prelude_user@'localhost' IDENTIFIED BY 'password'; mysql> exit; mysql -u prelude_user -p prelude_database < /usr/local/share/libpreludedb/classic/mysql.sql * paquets nécessaires à la compilation de prelude-manager (Lenny): apt-get install libwrap-dev * compilation de prelude-manager tar xvpf prelude-manager-1.0.0.tar.gz cd prelude-manager-1.0.0/ ./configure *** Dumping configuration *** - TCP wrapper support : no - XML plugin support : no - Database plugin support: yes make make check make install /sbin/ldconfig /usr/local/lib cd ../ * paquets nécessaires à la compilation de prewikka: apt-get install python-cheetah gettext python-cairo * compilation de prewikka tar xvpf prewikka-1.0.0.tar.gz mkdir -p /usr/share/prewikka/htdocs/{css,js,images} mkdir -p /usr/share/prewikka/{database,cgi-bin} cd prewikka-1.0.0 cp -rf htdocs/ /usr/share/prewikka/ cp -rf database/ /usr/share/prewikka/ cp -rf cgi-bin/ /usr/share/prewikka/ cp -rf locale/fr/LC_MESSAGES/prewikka.mo /usr/share/locale/fr/LC_MESSAGES/ python setup.py install cd ../ * Création de la base de donnéee et de son utilisateur: mysql -u root -p mysql> CREATE database prewikka_database; mysql> GRANT ALL PRIVILEGES ON prewikka_database.* TO prewikka_user@'localhost' IDENTIFIED BY 'password'; mysql> exit; mysql -u prewikka_user -p prewikka_database < /usr/share/prewikka/database/mysql.sql * paquets nécessaires à la compilation de prelude-lml: apt-get install libpcre3 libpcre3-dev * compilation de prelude-lml tar xvpf prelude-lml-1.0.0.tar.gz cd prelude-lml-1.0.0/ ./configure --enable-unsupported-rulesets *** Dumping configuration *** - Favor libICU over Iconv : no - Enable unsupported rulesets: yes make make check make install /sbin/ldconfig /usr/local/lib cd ../ L'erreur suivante peut-être ignorée lors de la phase de tests: Making check in tests make[1]: entrant dans le répertoire « /root/prelude/prelude-lml-1.0.0/tests » ./loggrep.py ../plugins/pcre/ruleset/*.rules | ../src/prelude-lml --quiet --dry-run --metadata=nowrite,head --batch-mode --no-resolve --pcre --dump-unmatched --config ./prelude-lml.conf 2>&1 | /bin/grep -Fvf ./ignored Invalid option -- "pcre" (0). Invalid option -- "dump-unmatched" (0). ./prelude-lml.conf:52: invalid section : "Pcre". ./prelude-lml.conf:53: invalid option "ruleset" in "global" section. 24 Feb 18:58:57 (process:2938) ERROR: couldn't open config file /usr/local/etc/prelude-lml/plugins.rules. (regex.c:168 get_regex_table) 24 Feb 18:58:57 (process:2938) WARNING: error while setting option 'file'. Traceback (most recent call last): File "./loggrep.py", line 29, in print i[:-1] IOError: [Errno 32] Broken pipe * paquets nécessaires à la compilation de prelude-correlator: apt-get install python-setuptools * compilation de prelude-correlator tar xvpf prelude-correlator-1.0.0.tar.gz cd prelude-correlator-1.0.0 python setup.py install A ce stade tous les paquets nécessaires au framework sont installés. ===== Configurer le framework ===== L'étape suivante va consister à configurer l'ensemble de nos paquets pour qu'ils fonctionnent et intéragissent correctement. * Configuration de prelude-manager: nous devons indiquer sur quelle interface le manager doit écouter pour recevoir les messages des sondes. Ici le manager écoute sur l'interface eth0 d'adresse IP 10.10.1.30. nano /usr/local/etc/prelude-manager/prelude-manager.conf include = /usr/local/etc/prelude/default/global.conf listen = 10.10.1.30 [db] type = mysql host = localhost port = 3306 name = prelude_database user = prelude_user pass = password * Création de l'utilisateur administrateur du manager: prelude-admin add prelude-manager --uid 0 --gid 0 * Configuration de l'interface web prewikka: prewikka permet la définition de commandes spécifiques qui peuvent êtres lancés sur les hôtes sources et destinations nano /etc/prewikka/prewikka.conf external_link_new_window [interface] software: Prewikka place: Maison du libre 29. title: Intrusion Detection System [host_commands] whois: /usr/bin/whois $host traceroute: /usr/bin/traceroute $host [idmef_database] type: mysql host: localhost user: prelude_user pass: password name: prelude_database [database] type: mysql host: localhost user: prewikka_user pass: password name: prewikka_database [auth loginpassword] expiration: 60 initial_admin_user: admin initial_admin_pass: admin * Commandes utilisables par prewikka: ces commandes peuvent êtres utilisées pour récupérer des informations supplémentaires sur les hôtes sources et destinations. apt-get install whois traceroute * Configuration du serveur web nano /etc/apache2/sites-enabled/000-default [...] Alias /prewikka/prewikka/ /usr/share/prewikka/htdocs/ ScriptAlias /prewikka/ /usr/share/prewikka/cgi-bin/prewikka.cgi Options None AllowOverride None Order allow,deny Allow from all AllowOverride None Options ExecCGI AddHandler cgi-script .cgi Order allow,deny Allow from all /etc/init.d/apache2 restart ===== Configurer et enregistrer les sondes ===== L'enregistrement d'une sonde auprès du manager se fait en utilisant 2 shells, le premier envoie la demande d'enregistrement tandis que le second fournis un password et valide l'enregistrement de la sonde. Les 2 captures d'écran suivantes montrent les infos importantes à repérer dans chacun des 2 shells: * Premier shell (la capture montre l'ajout d'une sonde snort): {{:server:sonde_1.png|}} * Second shell: {{:server:sonde_2.png|}} * Configuration de la sonde prelude-lml: nano /usr/local/etc/prelude-lml/prelude-lml.conf include = /usr/local/etc/prelude/default/idmef-client.conf [prelude] server-addr = 10.10.1.30 [format=syslog] time-format = "%b %d %H:%M:%S" prefix-regex = "^(?P.{15}) (?P\S+) (?:(?P\S+?)(?:\[(?P[0-9]+)\])?:$ file = /var/log/archive/*/messages [format=apache] time-format = "%d/%b/%Y:%H:%M:%S" prefix-regex = "(?P\S+) \S+ \S+ \[(?P.{20}) [+-].{4}\] " file = /var/log/archive/apache.mdl29/02/apache-access.log file = /var/log/archive/syslog.mdl29/02/apache-access.log [format=apache-error] time-format = "%a %b %d %H:%M:%S %Y" prefix-regex = "^\[(?P.{24})\] \S+ (\[client (?P\S+)\] )?" file = /var/log/archive/apache.mdl29/02/apache-error.log file = /var/log/archive/syslog.mdl29/02/apache-error.log [Pcre] ruleset=/usr/local/etc/prelude-lml/ruleset/pcre.rules Notez bien l'adresse IP du serveur (10.10.1.30), elle correspond à l'adresse à laquelle écoute le manager (cf /usr/local/etc/prelude-lml/prelude-lml.conf) * Enregistrement de la sonde prelude-lml: * Premier shell prelude-admin register prelude-lml "idmef:w admin:r" 10.10.1.30 --uid 0 --gid 0 * Second shell prelude-admin registration-server prelude-manager L'adresse IP indiquée dans le premier shell doit correspondre avec celle à laquelle écoute le manager (cf /usr/local/etc/prelude-manager/prelude-manager.conf) * Configuration du moteur de corrélation prelude-correlator: nano /etc/prelude-correlator/prelude-correlator.conf [BruteForcePlugin] disable = false [BusinessHourPlugin] disable = true [OpenSSHAuthPlugin] disable = false [EventScanPlugin] disable = false [EventStormPlugin] disable = false [EventSweepPlugin] disable = false [WormPlugin] disable = false repeat-target = 5 [DshieldPlugin] disable = false reload = 604800 server = www.dshield.org uri = /ipsascii.html?limit=10000 timeout = 10 [FirewallPlugin] disable = True flush-protected-hosts = 3600 Contrairement au fichier de config de la sonde prelude-lml, ici nous n'avons pas renseigné l'adresse IP sur laquelle écoute le manager, nous allons le faire dans le fichier de configuration global des clients: nano /usr/local/etc/prelude/default/client.conf server-addr = 10.10.1.30 * Enregistrement de la sonde prelude-correlator: la manipulation est similaire à celle précédente. * Premier shell prelude-admin register prelude-correlator "idmef:w admin:r" 10.10.1.30 --uid 0 --gid 0 * Second shell prelude-admin registration-server prelude-manager ===== Lancement des services ===== Nous allons devoir créer plusieurs scripts de démarrage pour chacun de nos services: * /etc/init.d/prelude-manager nano /etc/init.d/prelude-manager #! /bin/sh PRELUDEMANAGER=/usr/local/bin/prelude-manager PROGNAME=prelude-manager manager_start() { echo "Starting ${PROGNAME}..." start-stop-daemon --start --quiet --exec ${PRELUDEMANAGER} -- ${OPTIONS} -d &> /dev/null echo $? } manager_stop() { echo "Stopping ${PROGNAME}..." start-stop-daemon --stop --quiet --exec ${PRELUDEMANAGER} &> /dev/null echo $? } case "$1" in start) manager_start || exit 1 ;; stop) manager_stop || exit 1 ;; restart) manager_stop manager_start || exit 1 ;; *) echo "Usage: /etc/init.d/$PROGNAME {start|stop|restart}" >&2 exit 1 ;; esac exit 0 * /etc/init.d/prelude-lml nano /etc/init.d/prelude-lml #! /bin/sh PRELUDELML=/usr/local/bin/prelude-lml PROGNAME=prelude-lml lml_start() { echo "Starting ${PROGNAME}..." start-stop-daemon --start --quiet --exec ${PRELUDELML} -- ${OPTIONS} -d &> /dev/null echo $? } lml_stop() { echo "Stopping ${PROGNAME}..." start-stop-daemon --stop --quiet --exec ${PRELUDELML} &> /dev/null echo $? } case "$1" in start) lml_start || exit 1 ;; stop) lml_stop || exit 1 ;; restart) lml_stop lml_start || exit 1 ;; *) echo "Usage: /etc/init.d/$PROGNAME {start|stop|restart}" >&2 exit 1 ;; esac exit 0 * /etc/init.d/prelude-correlator nano /etc/init.d/prelude-correlator #! /bin/sh CORRELATOR=/usr/local/bin/prelude-correlator PROGNAME=prelude-correlator correlator_start() { echo "Starting ${PROGNAME}..." start-stop-daemon --start --quiet --exec ${CORRELATOR} -- ${OPTIONS} -d &> /dev/null echo $? } correlator_stop() { echo "Stopping ${PROGNAME}..." start-stop-daemon --stop --quiet --exec ${CORRELATOR} &> /dev/null echo $? } case "$1" in start) correlator_start || exit 1 ;; stop) correlator_stop || exit 1 ;; restart) correlator_stop correlator_start || exit 1 ;; *) echo "Usage: /etc/init.d/$PROGNAME {start|stop|restart}" >&2 exit 1 ;; esac exit 0 Voila, il ne reste plus qu'à rendre ces scripts exécutables et à lancer les services: for i in manager lml correlator; do chmod +x /etc/init.d/prelude-$i /etc/init.d/$i start done L'interface d'administration est accessible à l'url: http://localhost/prewikka/ ===== Installation de la sonde NIDS ===== La sonde snort sera installée de préférence à un endroit stratégique de notre réseau, ici nous l'installons sur chaque machine offrant un service extérieur. apt-get install snort Le script de démarrage fourni semble ne pas fonctionner correctement avec prelude, on en fait une sauvegarde: /etc/init.d/snort stop mv /etc/init.d/snort /etc/snort/snort.init.d/bak Voici le nouveau script de démarrage: nano /etc/init.d/snort #! /bin/sh DAEMON=/usr/sbin/snort PROGNAME=snort PIDPATH="/var/run" PIDFILE="snort_eth0.pid" CONFIG="/etc/snort/snort.conf" IFACE="eth0" start() { echo "Starting ${PROGNAME}..." set +e start-stop-daemon --start --quiet --exec \ ${DAEMON} -- --nolock-pidfile \ --pid-path ${PIDPATH} \ -i $IFACE -c $CONFIG >/dev/null 2>&1 & set -e } stop() { echo "Stopping ${PROGNAME}..." start-stop-daemon --stop --quiet --pidfile ${PIDPATH}/${PIDFILE} &> /dev/null sleep 15 } case "$1" in start) start || exit 1 ;; stop) stop || exit 1 ;; restart) stop start || exit 1 ;; *) echo "Usage: /etc/init.d/$PROGNAME {start|stop|restart}" >&2 exit 1 ;; esac exit 0 On passe à la configuration du démon, on va modifier la façon dont snort renvoie ses alertes et désactiver les règles relatives au protocoles snmp et rpc pour éviter d'avoir trop d'alertes liées au fonctionnement normal de la plateforme: nano /etc/snort/snort.conf [...] #output log_tcpdump: tcpdump.log [...] output alert_prelude: profile=snort [...] #include $RULE_PATH/rpc.rules [...] #include $RULE_PATH/snmp.rules [...] On passe à la configuration pour prelude: nano /etc/prelude/default/client.conf server-addr = 10.10.1.30 nano /etc/prelude/default/global.conf node-name = vm_1.domain.tld address = 10.10.1.41 netmask = 255.255.255.0 vlan-name = vm_1.domain.tld On termine par l'enregistrement de la sonde; sur le client: prelude-admin register snort "idmef:w admin:r" 10.10.1.30 --uid 0 --gid 0 sur le serveur: prelude-admin registration-server prelude-manager **//That's All Folks ;)//**