Bonjour à tous ! Aujourd’hui je vous présente un article hors-série qui traite du réseau Tor et de son fonctionnement. L’objectif de celui-ci est de vous montrer comment par le biais de la technique de l’UDP hole punching, nous allons pouvoir « publier » un service « caché » (dans notre cas OpenSSH) sur le réseau Tor. Le but est d’éviter d’ouvrir un quelconque port pour y accéder, et de rester « caché » (Voilà tout l’intérêt de cette technique.)

Oui, je sais ce que vous êtes en train de vous dire : Comment cela est possible ? Et bien grâce à L’UDP hole punching, nous pouvons nous passer d’ouvrir un port, afin de réaliser ce que l’on appelle du Nat Traversal.

Avant toutes choses, quelques petits rappels sur le fonctionnement du réseau Tor

I. Rappel : Fonctionnement du réseau Tor

Directory Service :

Les directory services sont des nœuds spécifiques qui ont le rôle d’annuaire au sein du réseau. Ils sont redondants, et présentent les mêmes informations. Leur fonction est de référencer les nœuds Tor publics connus. Ces « descripteurs » regroupent des informations attachées aux nœuds nécessaire au fonctionnement interne de Tor.

Note : Toutes les heures, ces autorités d’annuaires gérées par des bénévoles votent et parviennent à un consensus sur les relais qui composent le réseau Tor.

Node : Aussi appelé relais, Un nœud Tor est un serveur d’un particulier ou d’une organisation soutenant le projet faisant partie intégrante du réseau de Tor et se chargeant de l’acheminement du routage du trafic. Il y en a plusieurs types à savoir :

  • Entry Node
  • Middle Node
  • Exit Node

II. Le principe de L’UDP Hole punching

Si je devais définir l’UDP Hole punching en une phrase pour rester synthétique : technique par laquelle il est possible de « traverser des réseaux NATé » et d’établir des connexions P2P entre un ou plusieurs hôtes.

Avantages

L’UDP hole punching vient complétement bouleverser les acquis techniques que vous avez en matière de réseau. En effet avec ce protocole, vous pouvez vous passer d’ouvrir un ou plusieurs ports correspondants aux services de votre serveur. Pourquoi ce nom ? Car cette technique « perce un trou » dans le pare-feu du réseau qui permet à un paquet d’un système extérieur d’atteindre avec succès le client souhaité qui se trouve derrière un réseau NATé. Toutefois, L’UDP Hole punching peut être bloqué par certains firewall d’entreprise correctement paramétrés et demande à ce que le client connaisse forcement l’adresse de connexion du serveur qu’il souhaite atteindre.

Bien que ce processus nécessite un hôte tiers (serveur Rendez-vous) pour établir une connexion entre les clients, des recherches récentes ont montrées que cela peut être fait sans utiliser d’hôtes tiers.

III. Comment atteindre un service caché, depuis le réseau tor ?

Les services cachés fonctionnent par l’intermédiaire de « point de rendez-vous » qui sont des relais Tor choisis pour accomplir cette mission.

Le client choisit un point de rendez-vous qui sera communiqué de manière indirecte au service caché, et les deux communiqueront via ce point de rendez-vous. Autrement dit, c’est comme si la communication entre Alice et Bob se faisait via une sorte de boite aux lettres, ni Alice ni Bob ne se connaissent, pourtant, ils peuvent communiquer.

Toutefois, un problème reste de mise : Comment fait un client pour atteindre un service caché, alors que les deux ne se connaissent pas ? Un service caché doit donc afficher son existence dans le « nuage Tor » avant que des clients puissent le contacter.

A. Naissance du service caché

Etape 1 : le service caché « Bob » choisit des routeurs oignons, construit des circuits vers eux, et leur demande de se comporter comme étant des points d’introduction en leur fournissant sa clé publique.

Note 1 : L’utilisation d’un circuit Tor rend difficile d’associer un serveur à ses points d’introduction. Et bien que les points d’introduction disposent de la clé publique identifiant le service caché, ils n’ont aucune idée de l’IP de ce même service.

Note 2 : Dans le schéma suivant, je me permet d’insister sur le fait que les liens en vert ne sont pas à comprendre comme des connexions directes entre chaque partie prenantes, mais comme des circuits « Probable » que « Bob » peut emprunter.

Etape 2 :

Le service caché construit ensuite un descripteur de service caché qui n’est autre qu’un fichier contenant :

  • sa clé publique
  • un résumé de chaque point d’introduction qu’il signe avec sa clé privée.

Il transfert ce descripteur à un ensemble de de serveurs d’annuaire. (Encore une fois en utilisant un circuit Tor complet afin de cacher le lien entre le serveur d’annuaire qui stocke le descripteur et l’adresse IP du service caché.)

Le descripteur sera trouvé par les clients qui recherchent le service caché par le biais de son nom DNS XYZ.onion. XYZ est un nom DNS qui est généré par l’intermédiaire d’un hash de sa clé publique, lors de l’instanciation du service caché.

B. Comment une liaison entre deux hôtes s’établie ?

Etape 3 : Reprenant le schéma ci-dessous, ci Alice souhaite atteindre Bob, elle devra le contacter par l’intermédiaire de son adresse DNS XYZ.onion. Après cela, le client peut lancer une tentative de connexion en téléchargeant le descripteur du service caché en provenance du serveur annuaire. S’il y a un descripteur pour XYZ.onion, le client crée alors un circuit vers un autre nœud au hasard et lui demande d’agir comme un point de rendez-vous en lui communiquant un secret partagé.

Qu-est-ce qu’un serveur rendez-vous ?

Serveur rendez-vous :  Nœud Tor tiré au hasard qui est chargé d’agir comme un point de rendez-vous qui agit comme entremetteur entre les 2 hôtes. Sans ce serveur « Rendez-vous », il est impossible d’initier une connexion entre les deux hôtes. Le but étant que chaque partie prenante ne soit jamais directement en contact.

Etape 4 :

Dès lors que le point de rendez-vous est créé, le client génère :

  • Un message de bienvenue incluant l’IP du point de rendez-vous et le secret partagé. (ce message est chiffré avec la clé publique du service caché, pour être sûr que lui seul puisse le lire)

Le client envoie ce message à l’un des points d’introduction en lui demandant de le délivrer au service caché par l’intermédiaire du point de rendez-vous.

Etape 5 :

Une fois que le message de bienvenue parvient au service caché, celui-ci déchiffre le message et y trouve l’adresse du point de rendez-vous ainsi que le secret partagé. Le Hidden service crée alors lui aussi un circuit vers le point de rendez-vous et lui envoie le secret partagé dans un message rendez-vous, afin de confirmé qu’il a bien pu déchiffrer et lire le contenu du message de bienvenue.

Etape 6 (Dernière étape) :

Une fois le message rendez-vous réceptionné, le serveur rendez-vous indique au client que la connexion a bien été mise en place. Après cela, le client comme le service caché peuvent utiliser leurs circuits jusqu’au point de rendez-vous pour communiquer l’un avec l’autre. Le point de rendez-vous relaye simplement (chiffré d’un bout à l’autre) les messages du client vers le service et vice-versa.


En l’espèce, la communication entre le client et le serveur se fait par l’intermédiaire de six relais, trois d’entre eux sont choisis par le client, avec le dernier comme point de rendez-vous, et les trois autres sont utilisés par le service caché. (Le schéma ci-dessous ne montre pas les 6 relais dans un soucis de clarté je pense)

III. Publication de notre premier service caché

En guise de démonstration, je vais vous présenter comment publier un serveur caché. Ne vous en faites pas si vous n’avez pas tout compris la partie précédente, elle n’est pas forcement nécessaire pour mettre en pratique le cas d’utilisation suivant. Cette partie est là pour ceux qui souhaite affiner leurs connaissances du fonctionnement interne du réseau Tor.

Ce dont vous aurez besoin

Deux machines sous linux. Dans mon cas :

  • Ubuntu (serveur distant). Pour les connexion SSH j’utiliserai uniquement le compte user.
  • Kali-Linux (client)

Les deux machines sont des VMs virtualisées via VMware Workstation 16, sur mon PC et elles accèdent au même réseau local, derrière un NAT classique. Même si elles sont sur le même réseau privé, lorsqu’elles vont communiquer ensemble, ce sera exclusivement via le réseau Tor (via le DNS xxxxxxxxx.onion de la machine Ubuntu)

Service caché – SSH

À titre d’exemple, je vais donc choisir de publier le service SSH (représenté par le paquet OpenSSH, identifié par le diminutif ssh, lors de l’installation du service via apt). SSH est de par sa conception, un moyen assez sécurisé d’accéder au shell d’une machine distante, si celui-ci est bien configuré. Prochainement, je vous fournirai un guide complet pour resserrer la sécurité de SSH, mais entre-temps, il en existe pleins sur internet ^^.

Nous allons donc publier le service caché de ma machine Ubuntu en transmuant OpenSSH en service caché, afin de pouvoir y accéder uniquement depuis le réseau Tor.

Note : Vous pouvez réaliser vos tests avec deux machines virtuelles côte à côte dans le même réseau. De toute manière, nous n’utiliserons pas les IPs privées de ses dernières pour se connecter.

A. Utilisation de la distrib’ Linux Ubuntu

Installez Tor et ssh, par le biais de la commande suivante :

apt install tor ssh
systemctl enable tor.service
systemctl enable ssh.service

Puis, éditez le fichier de configuration suivant :

nano /etc/tor/torrc

Décommentez/Ajoutez les lignes suivantes :

## Configuration file for a typical Tor user
## Last updated 9 October 2013 for Tor 0.2.5.2-alpha.
## (may or may not work for much older or much newer versions of Tor.)
##
## Lines that begin with "## " try to explain what's going on. Lines
## that begin with just "#" are disabled commands: you can enable them
## by removing the "#" symbol.
##
## See 'man tor', or https://www.torproject.org/docs/tor-manual.html,
## for more options you can use in this file.
##
## Tor will look for this file in various places based on your platform:
## https://www.torproject.org/docs/faq#torrc
## Tor opens a socks proxy on port 9050 by default -- even if you don't
## configure one below. Set "SocksPort 0" if you plan to run Tor only
## as a relay, and not make any local application connections yourself.
#SocksPort 9050 # Default: Bind to localhost:9050 for local connections.
#SocksPort 192.168.0.1:9100 # Bind to this address:port too.
## Entry policies to allow/deny SOCKS requests based on IP address.
## First entry that matches wins. If no SocksPolicy is set, we accept
## all (and only) requests that reach a SocksPort. Untrusted users who
## can access your SocksPort may be able to learn about the connections
## you make.
SocksPolicy accept 127.0.0.1
#SocksPolicy reject *
## Logs go to stdout at level "notice" unless redirected by something
## else, like one of the below lines. You can have as many Log lines as
## you want.
##
## We advise using "notice" in most cases, since anything more verbose
## may provide sensitive information to an attacker who obtains the logs.
##
## Send all messages of level 'notice' or higher to /var/log/tor/notices.log
Log notice file /var/log/tor/notices.log
## Send every possible message to /var/log/tor/debug.log
Log debug file /var/log/tor/debug.log
## Use the system log instead of Tor's logfiles
#Log notice syslog
## To send all messages to stderr:
#Log debug stderr
## Uncomment this to start the process in the background... or use
## --runasdaemon 1 on the command line. This is ignored on Windows;
## see the FAQ entry if you want Tor to run as an NT service.
RunAsDaemon 1
## The directory for keeping all the keys/etc. By default, we store
## things in $HOME/.tor on Unix, and in Application Data\tor on Windows.
#DataDirectory /var/lib/tor
## The port on which Tor will listen for local connections from Tor
## controller applications, as documented in control-spec.txt.
#ControlPort 9051
## If you enable the controlport, be sure to enable one of these
## authentication methods, to prevent attackers from accessing it.
#HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C
#CookieAuthentication 1
############### This section is just for location-hidden services ###
## Once you have configured a hidden service, you can look at the
## contents of the file ".../hidden_service/hostname" for the address
## to tell people.
##
## HiddenServicePort x y:z says to redirect requests on port x to the
## address y:z.
HiddenServiceDir /var/lib/tor/ssh/
HiddenServiceVersion 3
HiddenServicePort 8080 127.0.0.1:22
SafeLogging 0

################ This section is just for relays #####################
#
## See https://www.torproject.org/docs/tor-doc-relay for details.
## Required: what port to advertise for incoming Tor connections.
#ORPort 9001
## If you want to listen on a port other than the one advertised in
## ORPort (e.g. to advertise 443 but bind to 9090), you can do it as
## follows.  You'll need to do ipchains or other port forwarding
## yourself to make this work.
#ORPort 443 NoListen
#ORPort 127.0.0.1:9090 NoAdvertise
## The IP address or full DNS name for incoming connections to your
## relay. Leave commented out and Tor will guess.
#Address noname.example.com
## If you have multiple network interfaces, you can specify one for
## outgoing traffic to use.
# OutboundBindAddress 10.0.0.5
## A handle for your relay, so people don't have to refer to it by key.
#Nickname ididnteditheconfig
## Define these to limit how much relayed traffic you will allow. Your
## own traffic is still unthrottled. Note that RelayBandwidthRate must
## be at least 20 KB.
## Note that units for these config options are bytes per second, not bits
## per second, and that prefixes are binary prefixes, i.e. 2^10, 2^20, etc.
#RelayBandwidthRate 100 KB  # Throttle traffic to 100KB/s (800Kbps)
#RelayBandwidthBurst 200 KB # But allow bursts up to 200KB/s (1600Kbps)
## Use these to restrict the maximum traffic per day, week, or month.
## Note that this threshold applies separately to sent and received bytes,
## not to their sum: setting "4 GB" may allow up to 8 GB total before
## hibernating.
##
## Set a maximum of 4 gigabytes each way per period.
#AccountingMax 4 GB
## Each period starts daily at midnight (AccountingMax is per day)
#AccountingStart day 00:00
## Each period starts on the 3rd of the month at 15:00 (AccountingMax
## is per month)
#AccountingStart month 3 15:00
## Administrative contact information for this relay or bridge. This line
## can be used to contact you if your relay or bridge is misconfigured or
## something else goes wrong. Note that we archive and publish all
## descriptors containing these lines and that Google indexes them, so
## spammers might also collect them. You may want to obscure the fact that
## it's an email address and/or generate a new address for this purpose.
#ContactInfo Random Person <nobody AT example dot com>
## You might also include your PGP or GPG fingerprint if you have one:
#ContactInfo 0xFFFFFFFF Random Person <nobody AT example dot com>
## Uncomment this to mirror directory information for others. Please do
## if you have enough bandwidth.
#DirPort 9030 # what port to advertise for directory connections
## If you want to listen on a port other than the one advertised in
## DirPort (e.g. to advertise 80 but bind to 9091), you can do it as
## follows.  below too. You'll need to do ipchains or other port
## forwarding yourself to make this work.
#DirPort 80 NoListen
#DirPort 127.0.0.1:9091 NoAdvertise
## Uncomment to return an arbitrary blob of html on your DirPort. Now you
## can explain what Tor is if anybody wonders why your IP address is
## contacting them. See contrib/tor-exit-notice.html in Tor's source
## distribution for a sample.
#DirPortFrontPage /etc/tor/tor-exit-notice.html
## Uncomment this if you run more than one Tor relay, and add the identity
## key fingerprint of each Tor relay you control, even if they're on
## different networks. You declare it here so Tor clients can avoid
## using more than one of your relays in a single circuit. See
## https://www.torproject.org/docs/faq#MultipleRelays
## However, you should never include a bridge's fingerprint here, as it would
## break its concealability and potentionally reveal its IP/TCP address.
#MyFamily $keyid,$keyid,...
## A comma-separated list of exit policies. They're considered first
## to last, and the first match wins. If you want to _replace_
## the default exit policy, end this with either a reject *:* or an
## accept *:*. Otherwise, you're _augmenting_ (prepending to) the
## default exit policy. Leave commented to just use the default, which is
## described in the man page or at
## https://www.torproject.org/documentation.html
##
## Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses
## for issues you might encounter if you use the default exit policy.
##
## If certain IPs and ports are blocked externally, e.g. by your firewall,
## you should update your exit policy to reflect this -- otherwise Tor
## users will be told that those destinations are down.
##
## For security, by default Tor rejects connections to private (local)
## networks, including to your public IP address. See the man page entry
## for ExitPolicyRejectPrivate if you want to allow "exit enclaving".
##
#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports but no more
#ExitPolicy accept *:119 # accept nntp as well as default exit policy
#ExitPolicy reject *:* # no exits allowed
## Bridge relays (or "bridges") are Tor relays that aren't listed in the
## main directory. Since there is no complete public list of them, even an
## ISP that filters connections to all the known Tor relays probably
## won't be able to block all the bridges. Also, websites won't treat you
## differently because they won't know you're running Tor. If you can
## be a real relay, please do; but if not, be a bridge!
#BridgeRelay 1
## By default, Tor will advertise your bridge to users through various
## mechanisms like https://bridges.torproject.org/. If you want to run
## a private bridge, for example because you'll give out your bridge
## address manually to your friends, uncomment this line:
# PublishServerDescriptor 0

Après avoir fait les changements dans le fichier torrc, redémarrez le service Tor.

systemctl restart tor

Naviguez dans le dossier du service caché SSH :

cd /var/lib/tor/ssh/ && ls -alt

Affichez l’adresse .onion (DNS) de votre service caché.

cat /var/lib/tor/ssh/hostname

Et devinez quoi… C’est tout côté service caché. Nous venons de faire les étapes 1 et 2. (cf partie précédente III.A – Naissance du service caché)

IV. Atteindre ce service caché depuis une autre machine (via Kali linux)

Installez le service Tor depuis le gestionnaire APT, puis démarrez le service Tor et activez le au démarrage de l’OS :

apt install tor
systemctl start tor
systemctl enable tor.service

Pour nous connecter au service caché de la machine Ubuntu, nous devons encapsuler notre commande ssh, par l’intermédiaire de la commande torify qui va encapsuler le trafic dans le réseau tor.

Essayez de vous connecter au service ssh, de votre machine par le biais du réseau Tor :

torify ssh -p 8080 [email protected]

Patientez quelques secondes…

Comme vous allez le constater, il y a un léger temps de décalage entre le moment ou vous saisissez du texte avec votre clavier. Normal ! Etant donné que vous traversé le réseau Tor.

A. Authentification SSH par clé privée/publique (Optionelle)

Afin de durcir la configuration SSH, nous allons faire en sorte que la connexion par clé privée/publique soit le seul moyen de connexion que l’on pourra utiliser pour se connecter au service caché.

torify ssh-copy-id -p 8080 [email protected]

Note : Si-vous n’avez pas de couple de clé publique/privée, utilisez la commande suivante : ssh-keygen

Voila, vous avez copié la clé publique de l’utilisateur root vers le fichier /home/user/.ssh/authorized_keys. Vous devriez maintenant pouvoir vous connecter sans entrer le mot de passe du compte user distant :

La connexion sans mot de passe (ssh password-less) fonctionne !

Je vous invite maintenant à désactiver l’authentification classique avec « prompt » du mot de passe. Pour cela, veuillez éditer le fichier de configuration suivant : /etc/ssh/sshd_config

Puis redémarrez le service ssh.

systemctl restart ssh

Pour preuve, que seule l’authentification par clé publique/privée est autorisée, je vous invite à changer de compte côté client. Je vais tenter de me connecter au service caché par l’intermédiaire de mon compte utilisateur kali

Comme vous pouvez le constater, je reçois l’erreur suivante : Permission Denied (publickey). Ce qui signifie que le serveur SSH distant accepte bien seulement l’authentification par couple de clé, à condition d’avoir copié votre clé publique en amont sur le serveur Ubuntu.

Voilà votre hidden-service SSH est maintenant en place, vous pouvez donc y accéder de partout à la seul condition d’avoir un appareil qui soit connecté au réseau Tor.

En espérant que cet article vous aura plus ^^

++

Geoffrey

Sources

Plus d’information « théorique » sur le principe de base de l’udp hole punching :

Pour plus d’information concernant la sécurité des services cachés : https://blog.torproject.org/nine-questions-about-hidden-services


Geoffrey Sauvageot-Berland

Ingénieur diplômé par l’état en Informatique et Cybersécurité. Généraliste, à l'origine administrateur systèmes et réseaux, j’occupe actuellement un poste d’auditeur en sécurité offensive. J’apprécie également la programmation/automatisation. Fondateur du blog : "Le Guide du SecOps", anciennement "Le Guide du SysOps"