Last update: 29/05/2007


EtatStable
Version2.00
Mise à jour05/09/2005

Projet Connect Tunnel
"CONNECT TUNNEL" est un petit outil pemettant de créer des tunnels à travers les proxys web via la méthode CONNECT de HTTPS.

Principe
Principe du contrôle des flux sortant généralement utilisé en entreprise
La quasi totalité des entreprises filtrent les flux sortants de leur réseau interne vers Internet.
La méthode la plus courante étant de placer un firewall en coupure et de le configurer pour qu'il interdise tout flux sortant direct depuis un poste client vers Internet.
Les accès web se font alors en passant par un proxy situé dans une DMZ, qui lui est bien sur autorisé à accéder à Internet.
Les navigateurs des postes client doivent alors être configurés pour passer par ce proxy (il est également possible d'utiliser la notion de proxy transparent pour éviter cette configuration).
Cette architecture permet de contrôler les flux à différentes couches du modèle OSI:
  • 3 et 4 car vous allez pouvoir interdire certains protocoles. Ainsi l'utilisateur ne pourra pas forcément pinger un serveur sur Internet, et il ne pourra pas faire du ssh sur son serveur personnel chez lui.
  • 7 car vous allez pouvoir en plus filtrer les URL en fonction de leur contenu, et interdire les accès à certains sites.
Alors tout est parfait ?
Et non, rien n'est parfait en ce bas monde: si ce principe fonctionne bien dans le cas d'accès non-sécurisés (HTTP), il pose en revanche problème lors de l'usage de HTTPS.
En effet, prenons le cas d'un accès HTTPS direct: le client va initialiser une connexion TCP classique avec le serveur, puis négocier la connexion cryptée (algorithme, présentation de certificats, ...). A partir de là, tous les échanges seront encryptés (du moins la partie de la trame au delà du niveau 4).
Que se passe t-il maintenant si nous ajoutons un proxy au milieu ?
Il est absolument impensable que deux tunnels HTTPS soient initialisés (Un entre le client et le proxy et un autre entre le proxy et le serveur): Le client ne verrait pas le certificat du serveur mais celui du proxy et ne pourrait pas le vérifier, de plus cette méthode serait parfaitement contraire avec l'esprit point-à-point de SSL (ce serait même du MITM...).
Alors quelle est la solution ?
Pour résoudre cela, les proxys implémentent une méthode CONNECT. Voici, brièvement, les étapes effectuées lors d'une transaction HTTPS via un proxy:
  • Le client initialise une connexion TCP avec le proxy
  • Le client envoie une requête HTTP CONNECT qui précise le nom et le port du serveur à contacter
  • Le proxy initialise une connexion TCP avec le serveur
  • Le proxy renvoie au client un message de confirmation de connexion
  • Toutes les données envoyées par le client au proxy dans cette connexion sont désencaspulées, puis renvoyées tel quel dans la connexion proxy-serveur, et inversement. Le proxy n'effectue aucun contrôle sur les données transmises, puisqu'elles sont normalement chiffrées.
Le principe du tunneling CONNECT
La création de tunnel est dès lors très aisée : il suffit d'envoyer une requête CONNECT au proxy, puis d'envoyer les paquets désirés à travers cette connexion.
Il faut également remarquer qu'il est possible de construire des tunnels sur HTTP avec les outils adéquats. Cette méthode requiert cependant un faux serveur HTTP qui désencapsule les données et les transferts au véritable serveur. L'avantage de cette méthode basée sur CONNECT est que la connexion est directement établie sur le serveur final.
Le principe de ConnectTunnel
Le principe de ConnectTunnel est relativement simple:
  • il se met en écoute sur un port que vous lui indiquez
  • à chaque connexion vers ce port, il initialise une connexion vers le proxy et demande la création d'une connexion vers le serveur demandé
  • il forwarde ensuite toutes les trames via ce tunnel
Dans cette nouvelle version, j'ai réécris le code de manière un peu plus propre, mais il faut noter que ConnectTunnel reste plus un petit outil "preuve de concept" ou qu'un développement accompli...
J'ai également ajouté la gestion du mode passif dans les transactions FTP. Il est donc maintenant possible d'effectuer des transactions FTP.
J'ai effectué quelques tests avec FilleZilla et le client ftp de Linux.
A noter qu'il faut absolument passer en mode passif, car en mode actif votre poste fait office de serveur, or dans l'architecture décrite ci-dessus, le serveur FTP ne pourra jamais établir de connexion vers votre poste (ou alors il y a un sérieux problème dans l'architecture réseau...).
Démonstration
Voici la méthode pour se connecter sur le serveur free:
  • Lancez un shell (cmd.exe sous Windows ou shell sous Linux) et exécutez ConnectTunnel avec les paramètres adéquats:
    • -l suivit du [@IP locale]:[port ecoute]
    • -p suivit de [@IP proxy]:[port]
    • -c suivit de [@IP servr]:[port] (212.27.40.252:21)
  • Lancez un client ftp à partir du même ou d'un autre poste
  • Vous avez accès au serveur ftp :)
  • Loggez vous
  • Passez en mode passif
  • Exécutez la commande "ls". Voici le résultat obtenu sur mon poste:
$ ftp localhost
Connected to XXXXXXXX.
220 Serveur de mise a jour des pages perso de Free.fr version [Feb  7 2005 13:55:51]
Name (localhost:caillat): benjamin.caillat
331 Password required for benjamin.caillat.
Password:
230 User benjamin.caillat logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> passive
Passive mode on.
ftp> ls
227 Entering Passive Mode (XXX,XXX,XXX,XXX,240,197).
150 Opening ASCII mode data connection for file list
drwxr-xr-x   9 web site     1512 Aug 31 08:04 .
drwxr-xr-x   9 web site     1512 Aug 31 08:04 ..
-rw-r--r--   1 web site      609 May  6  2004 Arcanoid.htm
-rw-r--r--   1 web site      609 May  6  2004 CV.htm
...
	
Voici les traces générées lors de ce test:
Au niveau de la fenêtre où est lancé ConnectTunnel:
# ./ConnectTunnel -l XX.XX.XX.XX:21 -p YY.YY.YY.YY:443 -c 212.27.40.252:21
   ============================================
        x90re Connect Tunnel tool 2.0

                        ---

     Open CONNECT tunnel in HTTPS PROXY.
     Support FTP transaction in PASSIVE mode.

     site: http://benjamin.caillat.free.fr
     mail: b.caillat@security-labs.org

   ============================================
[DEBUG] : Connection parameter:
[DEBUG] : Proxy:  IP=YY.YY.YY.YY        Port=443
[DEBUG] : Server: IP=212.27.40.252      Port=21
[DEBUG] : Initializing server
[DEBUG] : Waiting for connection on port 21
[DEBUG] : New thread created: 1084558256
[DEBUG] : [THREAD 1084558256] Connection through proxy OK
[DEBUG] : PASV Port: 61637
[DEBUG] : Initializing server
[DEBUG] : Waiting for connection on port 61637
[DEBUG] : New thread created: 1092946864
[DEBUG] : New thread created: 1101335472
[DEBUG] : [THREAD 1101335472] Connection through proxy OK
[DEBUG] : [THREAD 1101335472] End of thread
[DEBUG] : [THREAD 1084558256] End of thread
	
Installation
Plateforme
ConnectTunnel est disponible sur Linux et sur Windows. Il est constitué d'un unique fichier, source compatible pour ces 2 OS.
Procédure
  • Télécharger et décompressez l'archive "Connect Tunnel" dans un répertoire quelconque: ConnectTunnel
  • L'archive contient des versions compilés qui sont opérationnelles
  • Pour le recompiler sous Linux, utilisez la commande suivante : '$ g++ ConnectTunnel.cpp -o ConnectTunnel -l pthread'
Ressources
Archive ConnectTunnel (sources+executables Windows&Linux) : ConnectTunnel
Accès direct au code source : ConnectTunnel.cpp
Une remarque/un bug ?
Connect Tunnel est plus un petit proof-of-concept, n'hésitez cependant pas à me contacter si vous avez des questions ou des remarques: Benjamin CAILLAT