___ ___ ____ ___ __ _______ __ __ ______ | | | | | ; | | | |___ | |___ | | | .------. | | .- ---' , '-----'------'-----'--- ----'------- - -- - - - - ' _|________|__ ¦ | mkd.04 Les problèmes dans les filtres Perl : aka 'Comment SeriousMan a réussi à traduire un texte d'une langue qu'il ne la parle pas' ' _ ___ __ ____ : | | '-----.------- .-----.------.-----| |----- - ------- - - - ---- - - - ____| |____ |______| ____| |____ | | | | |___ _ ________ ___|___ ____|_________ _______ | I-intro: Salut tt le monde ,j'en ai pas envie d'ecrie une intro alors bye . (ptet que j'aurai envie d'ecrire une outro) II-La traduction: par b0iler : b0iler@hotmail.com : une conference donnée le 17 en irc.unixhideout.con #bsrf Ecrit pour : http://b0iler.eyeonsecurity.net/ - mon site remplis d'autres tutorials cool http://blacksun.box.sk/ - un site legendaire remplis de tutorial original --- b0iler has changed the topic to: Blacksun Research Facility - http://blacksun.box.sk - lecture in progress: "Problems in Perl Filters" - msg questions during lecture to b0iler. --- b0iler sets modes [#bsrf +m] Les problemes communs de filtrage en Perl --intro Cette conference peut etre utile aussi pour les autres languages, mais les syntax et les idees exact sont pour Perl Cette conference sera en mode +m et toutes les questions seront pose en me /msg'an, messagez moi vos questions quand vous voulez , et je repondrez au même instant , ou je les garderai pour la fin. -- Les principales problemes de filtrage en Perl sont: Le manques complet de filtres Les filtres qui oublient des caracteres Les filtres avec des faux ordre Les filtres qui filtre les précédant filtre (ou se filtre eux même! j'expliquerai ça plus tard) Et multiple variable d'entrée oublie dans les filtres -- Le "qu'est ce que" et le "pourquoi" des filtres Perl: Allons voir qu'est ce que sont les filtres Perl et pourquoi ils sont tellement important en termes de sécurité. Les filtres sont des façons pour Perl de arrêter les mauvaises choses de se passer. Par exemple si vous faisiez ça : $blah = `cat $ENV{'QUERY_STRING'}`; alors l'attaquant peut facilement entrée; quelquchose de ce genre: script.cgi?/etc/password Ce qui lira votre fichier de mot de passe, ou il pourra même être plus astucieux et fera quelque chose qui aura cet effet: script.cgi?file.txt;rm -rf anything/ (vous aurez besoins de l'url pour encoder quelque caractère) Tellement de programmeurs de Perl filtre les caractère qui font ces mauvaise choses. Ceci est une bonne idée et il faudra presque à chaque script avoir un système de filtrage. Quoique même un defaut dans le système de filtrage pourra avoir comme effet beaucoup de problème de sécurité. -- Types de filtrage: Il y'a deux grand type de filtrage , ce sont: Filtrage d'entrée Filtrage de sortie Le filtrage des entrée est le plus utilise, et generallement le plus sérieux pour la sécurité Il vient avant qu'aucune action ne soit pris sur l'entrée de l'utilisateur. ce qui arrêtera tout les caractère suspect de faire des actions sur le script Beaucoup de gens font l'erreur de ne filtrer que les entrée. quoique pas toujours nécessaire, le filtrage des sorties est très utile pour arrêter les File Reading Vulnerabilities, Cross Site Scriptting, et autres attaques Les filtrage des sorties c'est de filtrée les choses avant quel soit envoyer vers le client, base de donne,fichier ou autres sorties -- Les méthodes de filtrage: Il y'a deux grandes façons de filtrer : Filtrer les mauvaises entrées Autoriser les bonnes entrée Il y'a aussi beaucoup d'autre façons pour filtrer, comme la vérification de taille (ndt:length checking), le pattern checking (ndt: pas de traduction a ma connaissance) , et quelque autres méthodes bizarres. Le filtrage des mauvaises entrée est le plus utilise, et aussi celui ou les programmeurs commet le plus de fautes En filtrant les mauvaises entrée il est extrêmement facile d'oublier quelque chose ou ne pas connaître une caractéristique en Perl ou une caractéristique d'un programme externe que le script utilise. Ces filtres oublié peuvent aboutir a des vulnérabilités très facilement. Elles ne feront que prendre quelque seconde de réflexion à l'attaqueur pour chercher des façons créatifs pour s'évader des filtre ou d'appliquer des vieilles méthodes en une autre façon - Si une méthode est filtré essayer de le faire dans une autre façons qui ne l'ai pas Autoriser les bonnes entrée est la méthode préfère pour arrêter les mauvaise entrée de devenir un problème de sécurité Ceci parce que vous ne permettez qu'au bons caractère d'entrer , et donc vous arrêtez toutes autres mauvaises combinaisons possible, qui seront dur a filtrer avec la méthode de filtrage des mauvaises entrée Mais parfois permettre les entres est impossible si vous voulez de donner au usagers de la flexibilité. vous ne pourrez pas toujours les limiter à un ensemble de caractère, Vous serez obligé de faire une décision sur combien d'importance devra aller à la sécurité est combien à l'utilisabiliter Ceci est un exemple de filtrage des mauvaises entrées : $blah = $ENV{'QUERY_STRING'}; $blah =~ s/\;//; print `cat $blah`; Ceci arrêtera les gens de faire 'cat fichier.txt;touch fichier2.txt' (utilisant ; pour émettre une autre commande) Mais si vous lisiez mon tutorial : "Hacking CGI - Security and Exploitation" ( http://b0iler.eyeonsecurity.net/tutorials/hackingcgi.htm ) vous saurez le nombre de méthodes à utiliser des différentes méthodes pour faire des choses dans les commandes de système. Il est extrêmement dur de arrêter tout les combinaison possible des mauvaises entrées individuellement. Donc allons faire un coup d'oeuil sur comment juste autorisé les bonnes entrées: $blah = $ENV{'QUERY_STRING'}; $blah =~ s/[^a-zA-Z0-9\.\-_]//g; print `cat $blah`; print `cat $blah`; #* Ceci arrêtera tout ce qui pourra ne pas être bon dans le 'Filename' d'être cat'é (ndt:originalement cat'd). Mais il y'a une autre méthode pour l(autorisation des bon entrées que je préfère: Cette méthode consiste à denier l'accès à tout si l'utilisateur entre un caractère non permis: $blah = $ENV{'QUERY_STRING'}; if($blah =~ m/[^a-zA-Z0-9\.\-_]/){ die "mauvais caractères, il n'est permis que a-zA-Z0-9 . - et _\n"; } print `cat $blah`; Ok, assez pour les infos de contexte (ndt:background info). Allons apprendre comment pourra-t-on casser ces protection ? -- Mon procèdes d'exploit de filtre: La méthode que j'utilise est de chercher en premier les fautes communes dans les filtres. Je ne pense pas réellement sur ce qu'il faut être permis ou pas. Je vois premièrement si c'est un filtrage de mauvaise entrées ou juste une permission des bonnes entrées. si c'est qu'une autorisation des bonnes entrées alors mon test sera normalement court. Je verrai ce que je peut faire avec les caractères permis , (probablement pas grand chose). Puis je regarderai le reste du script pour voir si quelque chose de particulier peut servir avec les caractères autorise. Mais si ils filtrent les mauvaises entrées, les choses seront un peu plus de fun =) Avant même de voir ce que fait le script je chercherai si ils ont oublie un des basiques : Ont-ils oublie un mauvais caractère? Pourra t'on s'évader du filtre par l'insertion de caractère? Est ce qu'ils filtrent avec le bon ordre? Ont-t-ils oublie de filtrer une entrée d'utilisateur? Je note tout problèmes possible puis je vais voir ce que le script fait en détail. Apres je vais voir la structure du script ,je cherche des calls spécifique qui pourront être abuse. Puis je revient aux filtres et je vois si aucun combo de caractère autorise pourra abuser ces call. Si je ne trouve rien , j'irai m'asseoir et je penserai à une méthode pour s'évader du filtre. Parfois je fait beaucoup de test pour voir commement le filtre travail dans certaines situations et si rien ne peut s'y glisser dedans. J'ai beaucoup appris en contrôlant des filtres à la recherche des failles quand j'était nouveau dans Le monde de Perl. C'est une bonne idée de savoir beaucoup de choses sur les autres facteurs en jouant. Parfois vous pouvez trouvé une petite/inconnue caractéristique dans quelque chose que le script ne filtre pas. Si le programmeur ne connaît pas qu'un certain caractère peut faire quelque chose il y a beaucoup de chance qu'il ne le filtre pas. -- L'exploitation des filtres en pratique: Cette parti sera le noyau de la conférence (ndt: donc la plus importante), et ou vous apprenderez les plus importantes informations. ceci ne sera en aucun cas une liste complète ou quelque chose de ça, j'espère que vous trouverai des nouvelle méthode pour s'évader des filtres et que vous les partagé avec moi ( b0iler@hotmail.com ) (ndt: parlais le en anglais bien sûr). Je ne voudrez pas 'd'alimenter' (ndt: On peu faire des blagues en traduisant, non? ;) les script kiddies ici, on les donnant les recettes exact pour exploiter les filtres, mais ça serai nécessairement méchant contre ceux qui veulent apprendre la sécurité. Je commencerai par les filtres contre la "directory transversal" faille (ndt: pas de traduction a ma connaissance, mais mot par mot ça serai , faille de traversement de dossier), les basics sont: $blah =~ s/\.\.//g; $blah =~ s/\.\.\///g; $blah =~ s/\.//; $blah =~ s/[^\w\._\-]//; il y a d'autre, mais ceux-ci sont quelque uns. Le premier est pour le caractère '..'donc pour s'évader de ceci vous pourrai faire quelque chose comme: $blah = '.\./'; Ce qui passera par le filtre et reviendra dans un dossier. Ce truc marche aussi pour le deuxieme, qui filtre les '../' Mais ce dernier a un autre problème. Il sorte de toute les chaîne le caractère '../' dedans ce qui signifie que 'ab../cd' deviendra 'abcd' et quelque chose comme: $blah = '.../...//'; Donc après que le filtre efface tout les '../' de $blah, il deviendra un '../' (ndt: abacadraba!!! magique non )donc pour réparer tout ceci nous aurons a ajouter une boucle dans le filtre, denier les entrées utilisateur, ou de ne pas remplacer les chaînes par rien. Voici un exemple de boucle : while($blah =~ /\.\.\//){ $blah =~ s/\.\.\///; } Un example de denie des entrées de l'utilisateur : if($blah =~ /\.\.\//){ die "Caractere interdit en entrées.\n"; } Et enfin un exemple pour replacer le caractère par quelque chose d'autre: $blah =~ s/\.\.\//_/; Tout ceux la arrêteront les attaques du type '.../...//'. Le dernier retournera le '.../...//' en un '._._/' Le 3eme travail bien pour se débarrasser une des reverse directory transversales ('../'), mais il ne pourra pas être utilise si on a besoin de '.' dans l'entrée. Il n'y a réellement aucun méthode contre cela à moins que vous spécifier le chemin complet commencent par la racine , par exemple '/etc/passwd' qui n'a pas de '.' dedans. Le 4eme est le meilleur de ces filtres, il n'autorise que ce que nous savons bon. Pas de surprise que nous n'avons pas penser d'entrer la bas. Ca serait une bonne idée de filtrer les '..' avec celui ci ,juste au cas ou. Maintenant changions de sujet et discutons des techniques principale utilise pour vaincre les filtres . +Manque complet de filtres Ceci est une bonne méthode évidente pour passer des les filtres , s'ils n'existe pas ils ne pourrons pas vous arrêter. ;) Beaucoup de fois les programmeurs n'ont aucune connaissance en matière de sécurité et ne met aucun filtre ou il oublie un ou deux filtres requis. Toujours prenez du temps à penser sur tout ce que l'usager peu entrées et si il faut que vous le filtrez ou non. Quand vous doutez je dirais qu'il soit mieux que vous le filtrer qu moins pour les caractère permis juste pour être safe. +Filtres qui oublient des caractères: Ceci est un peu comme oublié tout le filtre, mais cette fois le programmeur à essayé d'être secure, mais a oublié un caractère/chaîne importante. La plus pars du temps c'est parce que le programmeur ne connaît pas que la chaîne qu'il a oublie peut être utilise pour causer des dommages. Par exemple, une newbie de Linux peut ne pas savoir ce que && peut être utilisé pour émettre des commandes supplémentaires. Alors ils oublient ce filtre même quand ils filtrent pour les '|' et autre ';' desolé, utilisateur de *nix. print `cat /etc/passwd && less /etc/hosts`; #pour démontrer comment la multiplication des commandes peut être utilise avec '&&'. Pour jouer avec un des types de Shell commandes, je suggeste que vous soyez un expert dans le Shell, apprendre beaucoup sur les différentes méthodes de Perl pour ouvrir un Shell, et de filtrer très bien (n'autorise que ce qui est bon). Allez voir mon tutorial: http://b0iler.eyeonsecurity.net/tutorials/hackingcgi.htm pour plus d'exemples sur cet technique (ndt:en anglais bien sur). +Les filtres qui sont dans un mauvais ordre: C'est une bonne idée de prendre un peu du temps et de penser dans quelle ordre faut-il que vos filtres viennent. Si vous filtrez quelque chose dans le mauvais ordre les problèmes pourront arrive. The most widely avalible example of this would be something like: Le plus con des exemples qui soit valable sera quelque chose comme: $blah =~ s/aa//g; $blah =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; #Convertie l'encodage de l'url en ascii La méthode pour vaincre ce filtre de 'aa' sera d'encoder votre 'aa' dans l'url en '%61%61'. Le prochain problème de filtrage sera a peu près le même que celui ci. +Les filtres qui filtrent précèdent filtres (ndt: !!!) This is a strange one I found pretty earily in my perl journey. This one is simular to the '.../...//' trick discribed eariler. Celle la est une bonne étrange que j'ai trouvé un peut tôt de mon voyage Perl. elle est similaire au truc de '.../...//' qu'on l'a décrit précédemment. Ce qui se passe c'est qu'un filtre cherche une chaîne, tant que l'autre change cette même chaîne un peu plus tard. So an attacker can get a string to pass the first filter, and then have the next filter(s) change the string into a dangerous one. Donc un attaquant pourra prendre le caractère pour passer le premier filtre ,puis verra le second filtre le changeant en un caractère dangereux. Un example sera plus facile a suivre: $blah =~ s///g; $blah =~ s/javascript//ig; Ci-dessus on a le filtre commun le plus utilisé pour se prévenir des ssi et pour filtrer les 'javascript'. La methode de passer de ce filtre est d'utiliser le filtre de 'javascript' en ordre pour changer le caractere en un ssi. donc si: $blah = ''; Alors $blah passera du premier filtre sans changer, puis tournera en '' qui un mauvais caractère, qu'il est sensé être filtrer par le premier filtre. Cette technique pourra aussi être utiliser avec juste un filtre. Vous l'avez déjà vu ceci avec l'exemple de '.../...//'. +Multiples variables entrer oublié dans le filtres Cette technique est plus utilisé dans les sorties (html, base de donnes, etc...), ou avec les chemain de fichier. Mais je l'ai deja vu marcher dans d'autres places, donc garder vos yeux ouvert pour elle. Voila un exemple avec les chemin de fichier (ndt: filepath) (prétendez que tout les directory transversal sont impossible): $blah =~ s/\.\./; oups $blah =~ s/\.\.//; $file =~ s/\.\.//; open(FILE "/home/user/${blah}$file"); Si $blah = '.'; et $bleh = './unautreutilisateur/file'; le chemin complet du fichier sera alors : '/home/user/../unautreutilisateur/file' Ce problème est beaucoup vu quand les filtres essaye d'arrêter les ssi ou les cross site scriptting. Si deux variables sont afficher en html, alors il vous faudra d'être sûr qu'elles ne sont pas évades de vos filtres. Effectivement, c'est un probléme difficile a reparer. Peut etre que mettre tout les resultat dans une seul variable puis filtrer la sortie est la meilleur solution. -- C'est pas mal du tout pour cette conférence, je vais juste ajouter une autre technique d'évasion de ce pauvre filtre Perl qui est utilisé tout le temps . $blah =~ s///g; J'ai déjà dis que ce filtre est utilisé pour arrêter les ssi. Mais d'après mes essais il y a une méthode pour tourner autour ce filtre. qui est if: $blah = '