Définitions

Dans la suite de l'article je vais utiliser le terme « client » pour désigner la machine qui va réaliser le contrôle, et « serveur » pour la machine à administrer. Comme nous fonctionnerons en VNC inversé, ça sera le serveur qui demandera la connexion au client qui écoutera les demandes de connexion.

Prérequis

  • La machine « cliente », celle qui contrôlera la première, doit être sous Linux, ou un autre système intelligent. Il est aussi possible je pense d'avoir un truc comme cygwin, ou alors un moyen efficace de créer des tubes SSH.
  • La machine relais doit avoir un accès SSH, avec la bonne configuration de ce dernier pour qu'il autorise les tunnels à ressortir, mais nous y reviendrons.

Problématique

Comment mettre en place un contrôle à distance sachant que :

  • Les deux machines sont derrière un NAT qui nous empêche d'entrer.
  • Que nous n'avons pas accès aux NAT pour forwarder des ports.
  • La prise de contrôle doit être décidée par le client, sans avoir besoin que le serveur intervienne, ou que l'utilisateur lance le serveur.

Nous avons ici un triple problème : le NAT du serveur nous empêche de rentrer, on ne peut pas ouvrir de ports, et le NAT du client nous empêche aussi de rentrer, nous empêchant de créer la connexion « inversée » (où c'est le client qui écoute et le serveur qui connecter).

Heureusement nous avons sous la main un serveur tiers pour faire relais, et la machine cliente implémente la norme POSIX (comprendre : l'OS est un unix et il est intelligent).

Solution

Voici comment on va procéder :

  • Mettre en place un VNC inversé sur le client, mais qui écoute ... en local.
  • Créer un tube SSH du port d'écoute local vers le serveur relais.
  • Expliquer au serveur relais de faire sortir le tube.
  • Faire se connecter la machine à administrer sur le port ouvert du relais, forwardé par nos soins.
Ce dessin réalisé par mes soins devrait vous aider à y voir plus clair :
vnc-inverse-relais.png

Installation du client et du serveur

  • Le serveur : la machine serveur étant sous windows, on va utiliser UltraVNC, disponible ici : http://www.uvnc.com/download/index.html
  • Le client : la machine cliente est sous Linux, on va utiliser vnc4viewer, qui est dans les paquets de la plupart des distributions

Vérification de la configuration du relais

Alors là je suis désolé pour ceux qui n'ont pas d'accès root sur le relais, il leur sera impossible de vérifier à moins de créer le tube SSH et de vérifier qu'il ressort (en lui parlant dedans avec netcat par exemples).

Le serveur SSH doit en effet posséder le GatewayPorts activé, pour que les sockets SSH puissent être bindés vers l'extérieur et non pas accessibles seulement en local. Il doit bien y avoir un moyen de crée un second tube pour faire sortir la socket locale pour contourner ce problème, mais ici j'ai fait au plus simple : j'ai rajouté GatewayPorts yes dans la configuration, et relancé le serveur SSH.

Vérifiez donc la présence de la ligne suivante dans votre /etc/ssh/sshd_config :
GatewayPorts yes

Lancement du client et essai du tube

Si tout s'est bien déroulé, vous avez installé vnc4viewer sur le client linux, et vous êtes prêt à le lancer.

Donc, lancez le avec la commande vncviewer -listen

Lançons maintenant le tube, la commande est ésotérique mais je vais essayer de l'expliquer :
ssh -f -R*:5500:localhost:550 monlogin@serveurrelais.com sleep 3600

  • Le -f indique que nous voulons créer un tube SSH
  • -R indique le sens du tube, même si les sockets sont bidirectionnelles, il faut indiquer où est l'entrée (qui écoute) et où est la sortie (qui envoie des données en réponse)
  • Le * signifie qu’on écoute tous les hôtes en sortie, et pas seulement localhost, c’est nécessaire dans notre cas pour que le serveur windows puisse s'y connecter (mais il agit alors comme un client, puisque on est en inversé, c'est pour ça qu'il va se connecter sur l'entrée, vous suivez ?)
  • localhost indique l'endroit où brancher l'entrée, ici localhost c'est le serveur relais, on s'y connecte et au lieu de rediriger le tube vers un éventuel autre serveur, on crée le tube local 4le trait vert du dessin5 pour router sur la bonne sortie sur la même machine
  • ensuite 5500 c'est le port de sortie, de l'autre côté, c'est la machine linux avec le client qui écoute (puisque on est en inversé)
  • La suite indique à quel serveur on va se connecter et avec quel login
  • Enfin, le sleep 3600 est la commande à faire exécuter par le serveur pour maintenir le tube ouvert ; en effet, le client SSH permet de créer un tube à usage unique, juste pour une commande, comme on veut y faire passer plein de trucs dedans, on va lancer cette commande qui ne fait rien mais qui permet au tube de rester ouvert. La valeur 3600 correspond à 1h.
En résumé, cette commande s'utilise ainsi :
  • ssh -f -Rportdistant:hoteacontacter:portlocal moi@machinedistante commandealancer dans un sens
  • ssh -f -Fportlocal:hoteacontacter:portdistant moi@machinedistante commandealancer dans l' autre sens

Lancez la commande précédemment décrite, et essayez le tube. Pour essayer le tube, faites simplement :

netcat serveurrelais.com 5500

Si tout fonctionne, vous devriez voir le client en écoute vous dire qu'il a reçu de la visite :
Sat Jul  3 18:17:12 2010
 CConn:       Accepted connection from 0.0.0.0::45907

Lancement automatique du serveur vers le client en écoute

J'ai choisit de créer une « Tâche planifée » Windows pour que le serveur sous windows tente de contacter le client à travers le tube.

La commande à lancer est toute simple : "c:\Program Files\UltraVNC\winvnc.exe" -connect ipserveurrelais::5500

Conclusion

Nous avons mit en place un système particulier : le serveur est client, le client est serveur, le serveur contacte le client à intervalles réguliers, et c'est le client qui décide quand le serveur va être contacté. Ce branchement peut servir à mettre en place une backdoor sur l'ordinateur serveur, cependant le changement de résolution et de fond d'écran lors de l'établissement de la connexion avec le client devrait faire tiquer celui qui utilise le serveur à ce moment là.

Notes, références, etc