Utiliser le réseau Tor via Python

Il peut être intéressant de faire transiter des données d’une application, d’un script via le réseau Tor pour x ou y raisons (non, je répète pas besoin de passer par Tor pour faire du téléchargement illégal. Excepté en Allemagne peut-être, rendez l’argent. Hein je m’égare ?).

Je me suis donc demandé quel était le point d’entré du réseau Tor en dehors du navigateur web et comment y accéder.

Le service tor

Il ne va pas suffir d’installer le navigateur Tor cette fois ci pour envoyer des données (c’est même inutile). Ce qu’il faut c’est le service tor c’est qui qui va se charger de transmettre vos données vers le premier noeud d’une longue liste

apt update
apt dist-upgrade
apt install tor

Une fois installé il est nécessaire d’éditer /etc/tor/torrc afin d’autoriser des connexions distantes. Ce n’est pas obligatoire mais pour mon cas c’est un PC qui fera tourner le service et un autre qui executera le code python

#SOCKSPort 127.0.0.1:9100

vers 

SOCKSPort 0.0.0.0:9050
switch :: ~ » sudo service tor restart
switch :: ~ » sudo netstat -lnptu | grep tor
tcp        0      0 0.0.0.0:9050            0.0.0.0:*               LISTEN      678/tor

Une simple connexion HTTP(s)

Pour cela utilisons encore une fois le module python requests. Le code est on ne peut plus basique, la seule particularité est l’utilisation d’un proxy sock5

#!/usr/bin/env python
#encoding: utf-8

import requests

proxy = {'http' : "socks5://172.16.0.3:9050", "https":"socks5://172.16.0.3:9050"}
print requests.get("https://api.ipify.org?format=json", proxies=proxy).text

SOCKS pour Secured Over Credential-based Kerberos (wat?) est un protocole réseau semblabe au fonctionnement d’un proxy ou VPN mais n’est lié qu’à une application. On fait passer uniquement le flux de cette application par l’intermédiaire contrairement au VPN ou tout le traffic de la machine est routée.

De plus contrairement à la plupart des VPN qui eux sont chiffrés, le protocole SOCK ne chiffre pas les données.

L’IP de sortie est bien celle d’un exit node. Cette IP sera toujours la même, pour changer de chemin dans le réseau il suffit de redémarrer le service service tor restart

Une connexion TCP (chiffrée TLS)

Envoyer des requêtes HTTP c’est bien sympa mais pourquoi ne pas directement envoyer des données via un autre protocole. Surtout que les libraires qui supportent les proxy HTTP sont légions tandis que celle pour faire du SOCKS sont moins présentes.

Le but de code va être de simplement faire une requête HTTP (basique)… Sans passer par une librairie … En passant par le serveur SOCK. Oui j’avais dit que je ne voulais pas faire de HTTP mais bon, ça sera ma propre implémentation.

#!/usr/bin/env python
#coding:utf-8
import requests
import socks
import ssl

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "172.16.0.3", 9050, True)
s = socks.socksocket()
s.connect(("check.torproject.org", 443))
secure_s = ssl.wrap_socket(s)

message = 'GET /?lang=fr HTTP/1.0\r\n\r\n'
secure_s.sendall(message)

msg =secure_s.recv(1024)
while msg:
        print msg
        msg = secure_s.recv(1024)

Le code est plutôt simple :

  • on défini un proxy de type SOCKS5 pour la socket qui va effectuer la connexion : socks.setdefaultproxy

  • on se connecte au serveur cible : s.connect

  • sssl.wrap_socket : permet simplement d’initialiser une connexion chiffré avec TLS avec le serveur

  • on envoie notre message : secure_s.sendall qui contient la requête GET HTTP

  • on attend gentillement la réponse : secure_s.recv

Le résultat est sans appel

Les données sont passées avec succès dans le réseau TOR, les rendant, dans une certaine mesure, anonymes.

PS : Sous Windows : pip install pysocks ça marche mieux avec