Skip to main content

ProxyChains-NG : guide technique du proxy TCP au pivot CTF

··1804 words·9 mins
Offensive Security ProxyChains SOCKS SSH Pivoting Network Security CTF
Rai2en
Author
Rai2en
Securing infrastructure, validating attack paths, and documenting the evidence.
Table of Contents
Tools & Techniques - This article is part of a series.
Part : This Article

Pourquoi ProxyChains reste utile
#

ProxyChains-NG ne crée ni VPN ni tunnel par lui-même. Il intercepte les appels réseau d’un programme local et les redirige vers un ou plusieurs proxys SOCKS4a, SOCKS5 ou HTTP CONNECT. En pentest interne et en CTF, son usage le plus intéressant consiste à réutiliser un proxy SOCKS créé avec SSH pour atteindre un sous-réseau accessible uniquement depuis une machine de rebond.

Le projet ProxyChains-NG décrit l’outil comme un preloader qui intercepte les fonctions réseau de la libc dans les programmes liés dynamiquement. La version stable publique actuelle est 4.17, publiée en janvier 2024.

Utilisez les exercices uniquement dans un lab, un CTF ou un environnement pour lequel vous disposez d’une autorisation explicite.

Ce que l’outil fait et ne fait pas
#

FonctionSupport
Connexions TCP via connect()Oui
SOCKS4a, SOCKS5, HTTP CONNECTOui
Résolution DNS distanteOui, selon le mode configuré
Scan TCP Connect Nmap -sTGénéralement oui
Scan SYN -sS, ACK, FIN ou XmasNon
UDP et ICMPNon
Programmes statiques ou setuidGénéralement non
Chiffrement de bout en boutNon, dépend des protocoles utilisés
Anonymat garantiNon

Modèle mental : interception, proxy et destination
#

Sous Linux, le lanceur ajoute libproxychains4.so à l’environnement du processus avec LD_PRELOAD. La bibliothèque remplace des fonctions comme connect() et certaines fonctions de résolution de noms. L’application croit ouvrir une connexion directe, mais la bibliothèque négocie à sa place avec le proxy.

flowchart LR A[Application dynamique] -->|connect cible:port| B[libproxychains4.so] B --> C[Proxy SOCKS ou HTTP] C --> D[Destination TCP] E[Résolution de nom] --> F{proxy_dns actif} F -->|Oui| C F -->|Non| G[Résolveur local]

Cette architecture explique les limites : un paquet SYN forgé par Nmap, un datagramme UDP ou un ping ICMP ne passe pas par l’appel TCP standard que ProxyChains sait intercepter.

Installation et identification de la bonne version
#

Sur Kali Linux et Debian :

sudo apt update
sudo apt install proxychains4
proxychains4 --help

Sur certaines distributions, le paquet historique s’appelle proxychains tandis que ProxyChains-NG utilise la commande proxychains4. Vérifiez la bannière affichée au lancement. Le dépôt officiel précise que ProxyChains-NG continue l’ancien projet désormais non maintenu.

Le fichier de configuration est recherché dans cet ordre :

  1. chemin indiqué par PROXYCHAINS_CONF_FILE ou par -f ;
  2. ./proxychains.conf ;
  3. ~/.proxychains/proxychains.conf ;
  4. le fichier système, souvent /etc/proxychains4.conf ou /etc/proxychains.conf.

Pour un lab, préférez un fichier local versionné avec vos notes :

cp /etc/proxychains4.conf ./proxychains-lab.conf
proxychains4 -f ./proxychains-lab.conf curl http://TARGET/

Comprendre les quatre modes de chaîne
#

Une seule directive doit être active dans le fichier.

strict_chain
#

Tous les proxys sont utilisés dans l’ordre. Un seul proxy indisponible fait échouer la connexion.

Client -> Proxy A -> Proxy B -> Proxy C -> Cible

Ce mode est prévisible et adapté à un chemin de pivot imposé.

dynamic_chain
#

L’ordre est conservé, mais les proxys hors ligne sont ignorés. Au moins un proxy doit répondre. C’est souvent le meilleur choix pour un lab où certains relais sont temporaires.

round_robin_chain
#

Chaque nouvelle connexion commence après le dernier proxy utilisé. chain_len fixe la longueur de la chaîne. Le projet avertit que la sémantique n’est pas garantie avec les applications multithreadées.

random_chain
#

Les proxys sont sélectionnés aléatoirement, avec une longueur définie par chain_len. Ce mode peut servir à tester des règles de détection, mais complique fortement la reproductibilité.

Configuration minimale recommandée pour un pivot SSH unique :

dynamic_chain
proxy_dns
tcp_read_time_out 15000
tcp_connect_time_out 8000

[ProxyList]
socks5 127.0.0.1 1080

DNS : éviter la fuite et comprendre les adresses 224.x
#

Avec proxy_dns, ProxyChains associe les noms demandés à des adresses synthétiques dans un sous-réseau réservé, 224.x.x.x par défaut. Lors de la connexion suivante, la bibliothèque retrouve le nom associé et demande au proxy de le résoudre.

Trois méthodes existent dans la configuration 4.17 :

  • proxy_dns, méthode moderne avec un thread interne ;
  • proxy_dns_old, qui dépend de proxyresolv et d’un dig lié dynamiquement ;
  • proxy_dns_daemon, service séparé visant une meilleure compatibilité avec les applications complexes.

Testez séparément la sortie IP et la résolution DNS :

proxychains4 -f ./proxychains-lab.conf curl -s https://ifconfig.me
proxychains4 -f ./proxychains-lab.conf curl -I https://example.org

Une adresse de sortie différente ne garantit pas l’absence de fuite DNS, WebRTC, télémétrie applicative ou identification par un compte connecté.

Exercice 1 : créer un proxy SOCKS avec SSH
#

Le manuel officiel OpenSSH ssh(1) définit -D comme un transfert dynamique local : SSH écoute sur un port local et agit comme serveur SOCKS4/5.

Topologie du lab
#

Kali                 Bastion Linux              Serveur interne
10.10.14.5  ------>  10.10.10.20               172.16.20.15
                      172.16.20.10  ---------->  TCP 22,80,445
flowchart LR K[Kali 10.10.14.5] -->|SSH| B[Bastion 10.10.10.20] K -->|SOCKS5 127.0.0.1:1080| B B --> I[Réseau interne 172.16.20.0/24] I --> T[Cible 172.16.20.15]

Créer le proxy :

ssh -N -D 127.0.0.1:1080 user@10.10.10.20
  • -N évite de lancer une commande distante ;
  • -D 127.0.0.1:1080 crée un proxy SOCKS local uniquement accessible depuis la machine de test ;
  • l’authentification et le trafic entre Kali et le bastion sont protégés par SSH.

Vérifier l’écoute :

ss -lntp | grep 1080

Tester ensuite un service interne connu :

proxychains4 -q -f ./proxychains-lab.conf \
  curl -I http://172.16.20.15/

Exercice 2 : énumération TCP contrôlée avec Nmap
#

Nmap doit utiliser l’appel système connect(). Le profil adapté est donc :

proxychains4 -q -f ./proxychains-lab.conf \
  nmap -sT -Pn -n --max-retries 2 --host-timeout 90s \
  -p 22,80,443,445,3306,8080 172.16.20.15

Pourquoi ces options :

  • -sT utilise la connexion TCP du système ;
  • -Pn évite une phase de découverte ICMP impossible à transporter ;
  • -n évite les interactions imprévisibles avec la résolution DNS ;
  • une liste de ports courte limite la latence cumulée ;
  • --max-retries et --host-timeout empêchent un scan bloqué indéfiniment.

Les profils -sS, -sU, -O et une grande partie des fonctions basées sur des paquets bruts ne fonctionneront pas à travers ProxyChains. Un -p- avec plusieurs proxys sera lent, bruyant et souvent moins fiable qu’une énumération ciblée.

Validation manuelle des résultats
#

proxychains4 -q nc -nv 172.16.20.15 22
proxychains4 -q curl -sS http://172.16.20.15/ | head
proxychains4 -q smbclient -L //172.16.20.15 -N

Chaque outil doit être compatible avec des sockets TCP dynamiques. Si un programme implémente sa propre pile réseau, utilise des paquets bruts ou lance un binaire non proxifié, le trafic peut contourner la chaîne.

Exercice 3 : découverte d’un vhost interne sans fuite DNS
#

Supposons que la cible réponde uniquement au nom intranet.lab. Lorsque le DNS du lab n’est joignable que depuis le bastion, proxy_dns permet au proxy SOCKS5 de résoudre le nom.

proxychains4 -q curl -I http://intranet.lab/

Si la résolution distante n’est pas prise en charge par le proxy ou l’application, utiliser une adresse numérique et forcer l’en-tête HTTP :

proxychains4 -q curl -I \
  -H 'Host: intranet.lab' \
  http://172.16.20.15/

Cette seconde méthode est souvent plus déterministe dans un CTF.

Exercice 4 : chaîne à deux proxys
#

Une chaîne n’est utile que si chaque proxy peut atteindre le suivant. Exemple :

strict_chain
proxy_dns

[ProxyList]
socks5 127.0.0.1 1080
socks5 172.16.20.20 1080

Le chemin devient :

Application locale
  -> SOCKS 127.0.0.1:1080
  -> SOCKS 172.16.20.20:1080
  -> destination finale

Testez d’abord chaque segment séparément. Ajouter des proxys publics aléatoires ne renforce pas automatiquement la sécurité : chaque intermédiaire augmente la surface de confiance, la latence et les risques d’altération du trafic non chiffré.

Tor et ProxyChains : ce qu’il faut réellement comprendre
#

Tor expose généralement un service SOCKS local. Selon l’installation, le port peut être 9050, tandis que Tor Browser utilise souvent un port différent géré par son propre environnement. Vérifiez l’écoute plutôt que de supposer :

ss -lntp | grep -E '9050|9150'

Exemple de configuration :

dynamic_chain
proxy_dns

[ProxyList]
socks5 127.0.0.1 9050

ProxyChains ne remplace pas les protections de Tor Browser. Lancer un navigateur classique avec LD_PRELOAD peut conserver WebRTC, extensions, cookies, cache, comptes connectés et autres surfaces d’identification. Pour la navigation web via Tor, Tor Browser reste une architecture plus cohérente.

Applications compatibles et alternatives natives
#

BesoinApproche recommandée
curl, nc, client MySQL, SMBProxyChains convient souvent
Nmap-sT -Pn -n et ports ciblés
FirefoxParamétrage SOCKS natif de préférence
MetasploitOption native Proxies si le module la supporte
SSHProxyJump, ProxyCommand ou transfert natif
UDPVPN, tunnel de niveau IP ou outil spécialisé
Application statiqueProxy natif ou tunnel réseau

Une fonction native connaît mieux le protocole de l’application et produit généralement des erreurs plus lisibles que l’interception générique.

Dépannage méthodique
#

La configuration utilisée n’est pas la bonne
#

Lancer sans -q permet de voir le chemin du fichier chargé :

proxychains4 -f ./proxychains-lab.conf curl http://172.16.20.15/

socket error ou chaîne bloquée
#

  1. vérifier que le premier proxy écoute avec ss ;
  2. tester le proxy directement avec curl --socks5-hostname ;
  3. réduire la chaîne à un seul proxy ;
  4. utiliser dynamic_chain pour identifier un relais mort ;
  5. augmenter temporairement les timeouts avec mesure.
curl --socks5-hostname 127.0.0.1:1080 http://172.16.20.15/

Le programme contacte directement la cible
#

Causes fréquentes :

  • binaire lié statiquement ;
  • programme setuid ignorant LD_PRELOAD ;
  • sous-processus qui nettoie son environnement ;
  • protocole UDP ou paquets bruts ;
  • application utilisant une API réseau non interceptée.

Capturez sur l’interface locale pendant un test bénin :

sudo tcpdump -ni any 'host 172.16.20.15 or port 1080'

La machine de test devrait parler au proxy, pas directement à une cible inaccessible.

Nmap renvoie des erreurs liées aux adresses 224.x
#

Le README officiel documente une interaction entre proxy_dns, les adresses synthétiques et certaines versions de Nmap. Solutions possibles : utiliser une IP numérique, désactiver temporairement proxy_dns, ou préférer le support proxy natif lorsqu’il couvre le besoin.

Lecture défensive d’un pivot
#

Un proxy SOCKS ne rend pas le mouvement invisible. Les défenseurs peuvent observer :

  • une session SSH longue avec peu d’activité interactive ;
  • de nombreuses connexions sortantes depuis un bastion vers des ports variés ;
  • une concentration de connexions TCP initiées par le processus sshd ;
  • des écarts entre la source réseau observée et l’identité applicative ;
  • des tentatives successives sur plusieurs services internes.

La segmentation doit limiter ce que le bastion peut joindre. Les journaux SSH, EDR et pare-feu doivent être corrélés plutôt que lus séparément.

Checklist opérationnelle
#

Avant un test :

  • autorisation et périmètre confirmés ;
  • fichier de configuration dédié ;
  • proxy lié à 127.0.0.1 quand il est local ;
  • résolution DNS testée ;
  • absence de connexion directe vérifiée ;
  • ports et cibles limités au besoin ;
  • timeouts adaptés à la latence ;
  • commandes et résultats consignés.

Conclusion
#

ProxyChains-NG est surtout une couche d’adaptation pour des applications TCP qui ne savent pas utiliser un proxy. Sa force vient de sa simplicité, mais ses limites découlent directement de son architecture LD_PRELOAD : pas d’UDP, pas de paquets bruts, compatibilité imparfaite et aucune garantie d’anonymat.

Dans un pentest interne, le workflow le plus robuste est souvent : créer un proxy SOCKS avec ssh -D, utiliser un fichier ProxyChains minimal, lancer des connexions TCP ciblées, puis valider chaque résultat manuellement.

Références
#

Tools & Techniques - This article is part of a series.
Part : This Article