- Portspoof fait en sorte que l’ensemble des 65 535 ports TCP paraissent ouverts et émule des signatures de service, transformant ainsi la phase de reconnaissance de l’attaquant d’un scan rapide en une opération longue et coûteuse
- Il renvoie
SYN+ACK à toute tentative de connexion et répond sur chaque port comme s’il s’agissait d’un service légitime différent grâce à plus de 9 000 signatures de service dynamiques basées sur des expressions régulières
- Il attribue au démarrage à chaque port des modes de diffusion mixtes — bannière immédiate, réponse différée ou absence de réponse — et ajoute du jitter à la durée de maintien des connexions pour compliquer le filtrage basé sur le timing
- Avec la configuration tarpit par défaut, un scan complet de versions
nmap -sV -p- peut prendre plus de 10 heures et générer des centaines de Mo de fausses données, consommant le temps et les threads du scanner de l’attaquant
- L’implémentation repose sur une boucle d’événements
epoll mono-thread, s’exécute en espace utilisateur sans privilèges root et ne bind qu’un seul port TCP par instance en cours d’exécution
Le problème que Portspoof cherche à résoudre
- L’objectif de Portspoof est de rendre la reconnaissance de l’attaquant lente, coûteuse et peu fiable
- Au lieu qu’un scan Nmap typique de 5 secondes cartographie les vrais services d’un système, face à Portspoof les 65 535 ports paraissent tous ouverts
- Chaque port ressemble à un service légitime différent, avec une conception pensée pour qu’il soit impossible de distinguer rapidement quels ports correspondent à de vrais services
Fonctions clés
-
Répond comme si les 65 535 ports TCP étaient tous ouverts
- Au lieu d’indiquer qu’un port est
CLOSED ou FILTERED, il renvoie SYN+ACK à chaque tentative de connexion
-
Émulation de services
- Utilise plus de 9 000 signatures de service dynamiques basées sur des expressions régulières
- Chaque port répond aux sondes du scanner avec une identité de service crédible et différente
-
Modes de diffusion mixtes
- Chaque port reçoit au démarrage un profil de comportement distinct
- Les modes mêlent envoi immédiat de bannière, réponse différée et silence
- Les durées de maintien sont réparties sur une large plage, au point de rendre une détection de version sur toute la plage
nmap -sV -p- peu praticable
-
Défense agressive
- Peut servir de « Exploitation Framework Frontend » visant les vulnérabilités propres aux outils de scan de l’attaquant
-
Modèle d’exécution léger
- S’exécute en espace utilisateur
- Ne nécessite pas de privilèges root
- Ne bind qu’un seul port TCP par instance en cours d’exécution
- Faible consommation CPU et mémoire
Comment il perturbe les scanners et la détection de version
- Lors d’un simple scan de ports, même une petite plage comme les ports 1 à 20 apparaît entièrement
open
- Dans la sortie d’exemple, des noms de services tels que
tcpmux, compressnet, echo, daytime et ftp-data s’affichent mélangés
- Lors d’un scan de détection de version, il renvoie des signatures dynamiques valides aux sondes de service
- Dans l’exemple sur les ports 1 à 100, on voit apparaître divers services et chaînes de versions comme
irc, http, pop3, ssh, ftp, smtp, telnet et tor-control
- Il devient donc difficile pour l’attaquant de déterminer quels numéros de port sont réellement utilisés par le système
- Un scan complet de versions
nmap -sV -p- prend plus de 10 heures avec la configuration tarpit par défaut et génère des centaines de Mo de fausses données
- Le scanner consomme du temps et des threads sur des connexions qui ne mènent à aucun résultat réel
Approche de conception : tarpit epoll mono-thread
- Les vrais services comme SSH, SMTP, FTP et HTTP envoient une bannière, maintiennent la connexion et attendent les entrées du client
- Une émulation crédible doit suivre le même flux accept, send, hold
- Un modèle avec un thread par client consommerait mémoire et CPU, et le coût des commutations de contexte pourrait épuiser les ressources du défenseur avant celles de l’attaquant
- Portspoof utilise une boucle d’événements
epoll mono-thread
- Chaque port se voit attribuer un mode de diffusion au démarrage
- Certains ports envoient immédiatement une bannière, d’autres répondent après réception de données client, et d’autres restent silencieux
- Les durées de maintien sont réparties sur plusieurs ordres de grandeur, de quelques dizaines de millisecondes à plusieurs minutes
- Chaque connexion comporte du jitter, si bien que sonder plusieurs fois le même port ne renvoie pas toujours le même timing
- Cette méthode complique les attaques consistant à envoyer des données inutiles sur tous les ports puis à mesurer les temps de réponse
- Un simple tarpit peut retenir une connexion pendant quelques secondes, alors qu’un vrai service peut fermer rapidement en cas de protocole incorrect
- Avec des modes mixtes et une large dispersion temporelle, même des milliers de faux ports se ferment dans une plage semblable à celle de vrais services
- Il n’existe plus de seuil propre permettant de filtrer les résultats
Asymétrie des coûts
- Le coût côté défenseur est d’environ 1 à 2 Ko de mémoire noyau par connexion inactive
- La boucle
epoll étant mono-thread, il n’y a pas de surcoût de commutation de contexte
- Un matériel ordinaire peut supporter plus de 10 000 connexions simultanées
- Le coût est déplacé vers l’attaquant, en temps et en effort
- Un simple scan de ports montre tous les ports comme ouverts, ce qui rend difficile l’obtention d’informations utiles
- Pour trouver les vrais services, il faut lancer une détection de version sur l’ensemble des 65 535 ports, puis une analyse au niveau protocolaire sur les cibles plausibles
- Un scan de 5 secondes devient plus de 10 heures de travail actif, tout en laissant un résultat qui ressemble toujours à une botte de foin
Changements de la v2.0
- v2.0 abandonne l’ancienne méthode consistant à envoyer une bannière puis à fermer la connexion
- Cette ancienne approche était vulnérable aux techniques de contournement de fermeture de connexion décrites dans l’article de blog Vicarius/Hored1971
- Le nouveau moteur tarpit maintient toutes les connexions ouvertes avec des timings mixtes
- L’objectif est de contrer le filtrage par fermeture de connexion, le fingerprinting temporel, l’analyse de bannière et la modélisation statistique de motifs
Installation et configuration de base
- La compilation nécessite un compilateur C++ et CMake 3.10+
- La procédure de compilation depuis les sources est la suivante
mkdir build && cd build
cmake -DCMAKE_INSTALL_SYSCONFDIR=/etc ..
make
sudo make install
- Portspoof s’exécute en espace utilisateur, mais des règles de pare-feu système sont nécessaires pour intercepter le trafic destiné aux autres ports
- Le port par défaut est 4444 ; il faut d’abord exclure les ports des vrais services, puis rediriger le reste du trafic TCP vers Portspoof
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 22 -j RETURN
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp -j REDIRECT --to-ports 4444
eth0 doit être remplacé par l’interface réseau réelle
- Il faut ajouter une règle
RETURN pour chaque port sur lequel tourne un vrai service
- Pour une application persistante, il est possible de sauvegarder les règles iptables ou d’utiliser
iptables-config dans le répertoire system_files
- Pour le script de démarrage, un exemple est disponible dans
system_files/init.d/
Modes d’exécution
- Le mode d’émulation de services est le mode recommandé
- Il génère et diffuse de fausses signatures de service aux scanners de ports
portspoof -c /etc/portspoof.conf -s /etc/portspoof_signatures -D
- Les timings tarpit personnalisés se définissent avec
-t et -T
- L’exemple ci-dessous maintient chaque connexion entre 10 et 60 secondes
portspoof -s /etc/portspoof_signatures -t 10 -T 60 -D
- Le Open Port Mode renvoie uniquement un état
OPEN à toute tentative de connexion, sans bannière de service
- Les connexions restent néanmoins traitées en tarpit
portspoof -D
- Le Fuzzing Mode peut servir à envoyer aux outils de scan des payloads aléatoires ou basés sur une wordlist
portspoof -1 -v
portspoof -f payloads.txt -v
Renforcement basé sur iptables
- La seule règle
REDIRECT de base suffit pour fonctionner, mais des scanners agressifs peuvent tenter de saturer Portspoof par le nombre de connexions
- Les règles de renforcement ajoutent une limitation de débit et un blocage automatique
- Les ports des vrais services sont exclus de la redirection
- Dans l’exemple, le port SSH 22 est exclu
- La règle de blocage globale s’applique aussi aux vrais services
- L’exemple de règles inclut les éléments suivants
- Autorisation du loopback
- Suppression pendant 60 secondes des IP marquées
PORTSCAN
- Suppression des nouveaux SYN au-delà de 10 par seconde et d’un burst de 30 par IP source
- Si une seule IP maintient plus de 100 connexions vers le port Portspoof 4444, elle est marquée puis bloquée
- Autorisation du trafic established/related et des nouveaux SYN, puis suppression du reste
- Dans les déploiements à fort trafic, il est possible d’augmenter la taille de la liste
xt_recent
echo "options xt_recent ip_list_tot=10000" > /etc/modprobe.d/xt_recent.conf
- Les paramètres liés au suivi de connexions du noyau et au backlog peuvent aussi être ajustés
sysctl -w net.netfilter.nf_conntrack_max=131072
sysctl -w net.core.somaxconn=4096
Portspoof Pro
- Portspoof Pro étend la tromperie non plus à un hôte unique, mais à l’échelle d’un réseau entier
- Un seul capteur émule tout un réseau
/16
- Il fournit des milliers d’IP
- Chaque IP dispose de services uniques sur tous les ports
- Il maintient des dialogues multi-étapes avec état
- Il propose des capacités de tromperie à l’échelle du réseau
- Il transforme l’espace d’IP sombres et les sous-réseaux inutilisés en grille de tromperie active
- Chaque hôte émulé présente des services uniques, avec une personnalité différente selon l’IP source
- Le tarpit actif épuise le pool de sockets de l’attaquant et throttle les outils automatisés
- Il prend en charge la détection de scans et le fingerprinting d’outils
- Il détecte les techniques de scan SYN, FIN, NULL, XMAS et ACK
- Il fingerprint Nmap, Masscan, ZMap et des scanners personnalisés
- Il envoie vers le SIEM une télémétrie JSON structurée avec mapping MITRE ATT&CK
- Il est pensé pour un déploiement en environnement opérationnel
- Il fonctionne dans un environnement sandbox à côté du trafic de production
- Des politiques de routage envoient le trafic de tromperie vers le capteur
- Il est indiqué qu’il n’y a ni tap inline ni risque pour les workloads réels
- Il aide à répondre à NIS2, DORA, ISO 27001, NIST CSF et CIS Controls
Licence et signalement des problèmes
- Portspoof utilise la licence GNU GPLv2
- Pour des applications commerciales et légales, il est indiqué de contacter l’auteur afin de discuter d’une licence adaptée
- Les bugs et demandes de fonctionnalités peuvent être signalés via le GitHub Issue Tracker ou par e-mail
1 commentaires
Avis sur Hacker News
Il y a 65536 ports, et le port 0 est lui aussi, sur certains systèmes d’exploitation, un port sur lequel on peut exposer un service accessible depuis Internet
Et si un développeur MariaDB passe par là, la configuration par défaut qui fait écouter la base de données sur le port 0 pour bloquer l’accès depuis Internet n’empêche en réalité pas l’accès Internet à la base sur un bon nombre de systèmes
if (mysqld_port)signifie quemysqld_portest différent de 0, et cela semble être le comportement au moins depuis MariaDB 5.5La sécurité informatique semble finalement condamnée à continuer d’évoluer vers des formes de défense active comme celle-ci
Quand on voit à quel point le système immunitaire est complexe et multicouche, on se dit que les ordinateurs et les réseaux finiront peut-être un jour par lui ressembler
Un jour, l’IT deviendra peut-être un domaine suffisamment mature, mais ce n’est pas encore le cas aujourd’hui
Cela dit, si on inclut aussi cet aspect, on voit apparaître un parallèle plutôt inquiétant
Pour bloquer les spambots qui collectaient des adresses email, j’avais créé une page web qui générait une infinité d’adresses email aléatoires : http://web.archive.org/web/20020610054821/http://www.sourtim...
Si on fait tourner ça, quelqu’un risque de scanner ma machine et de m’envoyer des dizaines de demandes de bug bounty disant qu’une version X avec une vulnérabilité connue est en cours d’exécution
Dans le milieu des années 90, il existait un produit honeypot appelé CyberCop Sting, antérieur à Ballista de Secure Networks
CyberCop Sting pouvait simuler des services TCP/UDP de plusieurs implémentations et, si je me souviens bien, on pouvait aussi configurer le comportement de la pile TCP/IP pour qu’elle ressemble à celui de différents systèmes d’exploitation. Pour l’époque, il y a presque 30 ans, c’était une fonctionnalité assez innovante
[1] https://theswissbay.ch/pdf/Gentoomen%20Library/Security/0321...
[2] https://news.ycombinator.com/item?id=26440139
Quelqu’un avait forcément dû le faire, bien sûr, mais je suis un peu surpris de ne jamais y avoir pensé auparavant, et encore plus surpris d’entendre parler de cette idée pour la première fois
J’ai l’impression qu’au final, cela risque surtout d’inciter des hackers ou des bots à examiner le serveur de plus près, ou au minimum à faire converger davantage de trafic
La plupart des script kiddies ne doivent probablement pas filtrer dans leurs outils les honeypots potentiels ou ce genre de dispositif
Mais une fois qu’on sait que l’hôte est actif, la vraie question est de savoir quel port attaquer. Si l’on suppose que le coût pour scanner ou attaquer chaque port de chaque serveur est comparable, alors même s’il est possible de distinguer les ports usurpés, il vaut mieux chercher une autre machine avec une probabilité de succès plus élevée. On pourrait lancer portspoof en local sur 127.0.0.35 pour comparer les données de réponse ou les différences de timing, mais l’espace de recherche devient soudain environ 5000 fois plus grand que les quelques ports habituellement ouverts, et les ports d’un autre serveur peuvent sembler offrir de meilleures chances de réussite
La plupart des outils ne prennent pas en compte le cas où tous les ports sont ouverts, produisant ainsi des faux positifs. C’est courant en test d’intrusion et cela fait perdre du temps, mais je n’ai pas envie de donner une raison de plus à un attaquant de regarder mon infrastructure. Je préfère presque l’exact opposé de cette approche : le port knocking
Face à des attaques larges, il faudrait le déployer sur des dizaines de millions d’hôtes pour qu’il ait un effet notable, afin qu’il devienne irréaliste pour un attaquant d’identifier seulement les honeypots et d’interagir avec eux. En cas d’attaque ciblée, cela peut certes faire perdre un peu de temps à l’attaquant pendant qu’il essaie d’exploiter les ports leurres, mais si vous faites tourner un service vulnérable, vous finirez quand même par vous faire compromettre. Et si vous êtes un éditeur, il se peut aussi que l’équipe sécurité d’un client potentiel, après avoir scanné votre infrastructure, vous oblige à répondre à un questionnaire de sécurité particulièrement pénible
Je fais quelque chose de similaire sur mon site web aussi. https://bini.wales renvoie 200 sur tous les endpoints et enregistre toutes les tentatives, ce qui en fait un honeypot correct contre les attaques automatisées
Ça attrape surtout les scans de masse visant des plugins WordPress vulnérables ou des backdoors oubliées. De manière similaire, https://varun.ch/login imite un site WordPress avec une petite subtilité
Sympa. Heureusement que le mot « honeypot » n’apparaît jamais
J’ai déjà hérité d’un « vrai » honeypot et, en le vérifiant, il y avait une trentaine de ports ouverts, et j’ai littéralement dit à voix haute : « mais c’est quoi cette merde ? »
Ouvrir des ports pour que des script kiddies s’excitent en croyant avoir trouvé quelque chose, alors qu’en réalité il n’y a rien. Un honeypot fermé ne ressemble pas vraiment à un honeypot à ce stade
Un honeypot sert à attirer et détecter les attaquants, puis généralement à enregistrer leur comportement et leurs schémas pour les analyser ou les bloquer. Cet outil gagnerait à avoir plus de journalisation au-delà d’iptables, et ce n’est pas un honeypot en soi, mais l’idée n’en est pas très éloignée. En revanche, je ne crois pas du tout la page GitHub quand elle dit que cela « renforce la sécurité de l’OS ». Ça apportera peut-être un peu d’obfuscation contre les scanners automatiques de services, mais si un serveur MySQL écoute sur le port 3306 et qu’un attaquant se connecte au 3306, il parlera toujours à MySQL. Peu importe que les 65534 autres ports renvoient des réponses absurdes
Il est indiqué que « chaque instance en cours d’exécution ne se lie qu’à un seul port TCP », donc je me demande comment cela fonctionne
Faut-il lancer 65535 instances pour couvrir tous les ports ?
Ensuite, il appelle
getsockoptpour savoir quel était le port d’origine : https://github.com/drk1wi/portspoof/blob/c3f3c34531c59df229e...Je ne connais pas les vraies limites matérielles ni l’usage mémoire, mais la redirection de ports est probablement plus simple
Est-ce que cela pourrait potentiellement devenir un amplificateur de DoS ?
En envoyant des paquets correctement usurpés, pourrait-on renvoyer beaucoup de paquets vers une source apparente ?
En UDP, ça pourrait devenir vraiment absurde