SubWeb v1.0 Stephane Aubert kotao HSC security research labs Hervé Schauer Consultants Téléchargement: http://www.hsc-labs.com/tools/subweb/ Description =========== SubWeb est un relais (ou relais inverse) permettant de travailler sur les flux HTTP dans la lignée de HTTPush, RFProxy ou Achilles. Il devient possible avec SubWeb de manipuler et visualiser à la volée les requêtes HTTP, les entêtes et les pages HTML. Le principal objectif de SubWeb est d'aider aux tests d'applications dites Web, reposant sur le protocole HTTP. HTTPS n'est pas directement géré dans SubWeb, il faut, pour tester un serveur HTTPS, utiliser le programme stunnel, par exemple. SubWeb possède 3 modes de fonctionnement : * proxy (relais HTTP classic) /--------\ Request /--------\ /--------\ | Client |------------->| SubWeb |-------------->| Server | | |<-------------| proxy |<--------------| | \--------/ \--------/ Answer \--------/ * midproxy (relais HTTP qui demande les pages à un autre relais) /--------\ Req. /--------\ /--------\ /--------\ | Client |------>| SubWeb |---->| HTTP |------>| Server | | |<------|midproxy|<----| proxy |<------| | \--------/ \--------/ \--------/ Ans.\--------/ * rproxy (relais inverse, SubWeb se fait passer pour un serveur) /--------\ /--------\ Request /--------\ | Server |<-------------| SubWeb |<--------------| Client | | |------------->| rproxy |-------------->| | \--------/ Answer \--------/ \--------/ Virtual Web ----------- Une autre fonctionnalité, nommé virtual web, permet à SubWeb de répondre à certaines requêtes (en fontion de mots clefs contenus dans ces requêtes) sans rien demander au serveur. /--------\ Request /--------\ /--------\ | Client |------------->| SubWeb | | Server | | |<-------------| proxy | | | \--------/ Answer \--------/ \--------/ VirtualWeb se configure avec $virtual_web pour activer le "module" et la table de hachage %vweb_config pour lui fournir les actions en fonction des mots clefs. Les actions disponibles pour VirtualWeb sont : . envoyer un fichier lu sur disque, avec file:/tmp/foo . envoyer une chaine de caractère, avec html: ... . envoyer une redirection HTTP, avec redirect:http://www.hsc.fr/ L'exemple fournit : si SubWeb trouve le mot 'redirect' dans l'URL il redirige le client sur http://www.hsc.fr/ Visualisation du trafic ----------------------- Il est possible de visualiser tout le trafic entre les clients et les serveurs. Il y a plusieurs options de visualisation (seulement les entêtes, les pages binaires peuvent être affichées en Hexa, afficher seulement les requêtes ou seulement les réponses ...) Exemple de visualisation : -------------------------- Directement connecté à Internet, exécuter : ./subweb Ou via un relais http, éxécuter : ./subweb 8080 midproxy corporate_proxy 3128 Configurer le champ 'proxy' de votre navigateur sur localhost:3128 Aller sur http://www.google.com/ Resultat : ---------- [Fri Aug 10 16:32:59 2001: connection from localhost [ 127.0.0.1 ] at port 45929] GET http://www.google.com/ HTTP/1.0 User-Agent: Mozilla/5.0 (Linux 2.4.4 i686; U) Opera 5.0 [en] Host: www.google.com Accept: text/html, image/png, image/jpeg, image/gif, image/x-xbitmap, */* Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0 Coockie: NO-COOKIE-PLEASE:NO-COOKIE-PLEASE:NO-COOKIE-PLEASE:NO-COOKIE-PLEASE Cookie2: $Version="1" Pragma: no-cache Cache-Control: no-cache -- HTTP/1.0 200 OK Date: Fri, 10 Aug 2001 14:36:13 GMT Server: GWS/1.11 Set-Cookie: PREF=ID=1253841f47eb7ec4:TM=997454173:LM=997454173; \ domain=.google.com; path=/; expires=Sun, 17-Jan-2038 19:14:07 GMT Content-Type: text/html Content-Length: 2184 Cache-Control: private X-Cache: MISS from carbone.hsc.fr Proxy-Connection: close Filtrage -------- Dans les trois modes il est possible d'appliquer du filtrage à tous les niveaux, cad dans les URL, les entêtes et le corps des pages, dans les requêtes et dans les réponses. Le filtrage est actif si la variable $static_filters est non nulle. Un autre type de filtrage, nommé dynamique, est activable en ajoutant la chaine de caractère subweb=on dans les URL. Ces filtres dynamiques sont par exemple intéressant pour changer des champs comme un cookie ou un identifiant de session après authentification sur un serveur de commerce électronique (par exemple). Le filtrage statique et dynamique se configure dans les fonctions : FilterIN, FilterOUT, DynamicFilterIN et DynamicFilterOUT. FilterIN(), DynamicFilterIN() ^ | | v /--------\ Request /--------\ /--------\ | |------------->| |-------------->| | | Client | | SubWeb | | Server | | |<-------------| |<--------------| | \--------/ \--------/ Answer \--------/ ^ | | v FilterOUT(), DynamicFilterOUT() Exemple de fonction de filtrage : --------------------------------- sub FilterIN { my $request = shift; ## Put your filters here - from client to server ## ## Change the user-agent $request =~ s/^User-Agent:\s+\S+$/User-Agent: SubWeb/gm; # Trivial anti-ads $request =~ s/\.doubleclick\.net/xxx/g; # Cookie stuff # Don't send coockies # $request =~ s/^Cookie:\s+.*\r\n//gm; # activism ;) $request=~s/Cookie:\s+.*\r\n/sprintf("Cookie: %s\r\n","NO-COOKIE:"x5)/egm; return $request; } Les fonctions de filtrage sont ainsi implémentées pour permettre à l'utilisateur de développer ses propres filtres sans aucune restriction. Modification des requêtes GET en POST ------------------------------------- SubWeb permet de transformer toutes les requêtes GET en POST de manière automatique et recalcule le Content-length. Forcer/modifier l'authentification HTTP --------------------------------------- Il est possible avec $force_auth et $http_auth de forcer ou remplacer l'authentification HTTP de manière transparente ainsi plusieurs utilisateurs peuvent utiliser un relais qui authentifie toutes les requêtes sur un autre relais ou sur un serveur web. Test des logiciels de détection d'attaque (IDS) ----------------------------------------------- SubWeb dispose de 6 modes permettant de rendre illisibles les URL. Avec : $anti_ids_modes = '1523' la requête GET /fr.yahoo.com/ devient : GET http://fr.yahoo.com/%2e/%76%7a%73%78%74%69%66%67%64%68%78%6e %73%6a%6f%7a%67%77%68%78%6e%6b%79%7a%70%6a%68%66%6b%65%76%77%65%61 %63%65%68%6e%63%78%75%73%72%68%66%72%70%75%79%66%64%79%70%75%62%65 %77%66%6f%6c%63/%2e/%2e%2e/%2e/ Chiffrement des chanps hidden en mode relais inverse ---------------------------------------------------- Un fonctionnalité expérimentale a été ajoutée au mode relais inverse. Elle permet de chiffrer le contenu des champs envoyé par le serveur aux différents clients et de les déchiffrer lorsque les clients les renvoyent au serveur dans des requêtes GET ou POST. Ce mécanisme interdit aux utilisateurs de modifier les valeurs des champs hidden, ce qui permet de les protéger et de les utiliser par exemple pour gérer par exemple l'ordre des requêtes demandées par un client. Un tel mécanisme permet peut rendre très difficile le piratage des applications basées sur HTTP. Il est activé lorsque la variable $cypher_hidden_field est non nulle et que le mode est rproxy. L'algorithme de chiffrement utilisé est Blowfish fournit dans le module Crypt::Blowfish. La clef de chiffrement peut être fournit dans la variable $passphrase_hidden et doit avoir une longueur de 32 caractères héxadécimaux, si elle n'est pas fournit SubWeb en tire une au "hasard" en début de programme. Syntaxe ======= Par défaut, SubWeb écoute sur le port 8080/tcp et est en mode 'midproxy' sur l'adresse localhost et le port 3128/tcp. C'est à dire que SubWeb attend des requêtes de votre navigateur sur le port 8080 et essaye des les envoyer sur votre relais squid local. Pour changer le port sur lequel SubWeb se met en écoute il faut le lancer avec un premier paramètre, exemple sur le port 8081 : % ./subweb 8081 Pour changer le mode il faut ajouter un deuxième paramètre au choix : % ./subweb 8081 [ proxy | midproxi | rproxy ] Par défaut le serveur et le port distant sont localhost et 3128/tcp. Pour changer ce serveur et ce port il faut ajouter 2 autres paramètres : % ./subweb 8081 rproxy webserver 80 ou encore : % ./subweb 8080 proxy ou encore : % ./subweb 8081 midproxy httproxy 8080 Options ======= my $signature = 1; # 0 pour désactivé la signature de SubWeb my $convert_get_to_post = 0; # 1 pour activer la transformation des GET en POST my $force_auth = 0; # 1 pour forcer l'authentification à base64($http_auth) my $http_auth = "aubert:kotao"; # permet de fournir le login:mot_de_passe my $anti_ids_modes = ''; # '1523' permet d'activer le mode de test des IDS my $accept_gzipped_pages = 0; # 1 permet d'autoriser le serveur a compresser les réponses my $static_filters = 1; # 0 pour désactiver le filtrage statique my $show_only_url = 0; # 1 permet de n'afficher que les URL dans les requêtes my $dump_text_body = 0; # 1 permet d'afficher le contenu des pages texte my $dump_binary_body = 0; # 1 permet d'afficher le contenu des pages binaires my $showIN = 1; # 0 permet de désactiver l'affichage des requêtes my $showOUT = 1; # 0 permet de désactiver l'affichage des réponses my $showUNFILTERED = 0; # 1 permet d'activer les req. et les réponses avant filtrage my $showFILTERED = 1; # 1 permet d'activer les req. et les réponses après filtrage Liste de choses à faire ======================= . améliorer la configuration du filtrage . améliorer les filtres avec des références sur les requêtes plutôt que de passer des buffers