Retour à tous les articles
Publié le · par Renaud Deraison

L’agent avait une adresse

À la DEF CON 34, Eli Woodward, de Team Cymru, a montré 48 heures de capture issues d’un pot de miel IA : 3 993 requêtes, 327 adresses IP sources, 344 sondages d’identifiants, contre des ports que personne n’avait annoncés. Les autres attaques visant un agent de code ont besoin d’un moyen de placer du texte devant lui. Celle-ci a besoin d’une route jusqu’à lui. Bromure Agentic Coding exécute l’agent derrière un NAT par défaut : il n’y a donc aucune route à trouver.

Les autres attaques visant un agent de code ont besoin d’un moyen de mettre du texte sous ses yeux. Celle-ci a besoin d’une route jusqu’à lui, et les scanners en ont déjà une.

Samedi matin à la DEF CON 34, sur la Creator Stage 3, Eli Woodward, de Team Cymru, a donné une conférence d’une demi-heure intitulée MCPwned: How Exposed AI Agents Became the Internet's New Recon Toy. Il avait construit un pot de miel IA : 16 personas de LLM et d’infrastructure IA répartis sur 16 ports, chacun renvoyant des réponses, des en-têtes, des erreurs et un comportement de protocole fidèles au framework imité, de sorte qu’un scanner qui y touchait croyait avoir trouvé la vraie chose.

Sur une fenêtre de 48 heures, le pot de miel a encaissé 3 993 requêtes provenant de 327 adresses IP sources uniques, dont 155 sondages MCP et 344 sondages de clés d’API IA.

Personne n’avait annoncé ces ports, et aucune des 327 adresses n’avait ciblé Woodward en particulier. Le mode opératoire qu’il a extrait de la capture est du genre ennuyeux et industriel : abus d’enregistrement de modèles LiteLLM, énumération de ressources MCP, force brute d’identifiants adaptée au framework, et balayages coordonnés à la recherche de services d’inférence locale exposés. Les équipes qui passent depuis dix ans l’espace d’adressage au peigne fin pour trouver du RDP ouvert et du Redis sans authentification ont pointé la même machinerie sur l’outillage de développement IA, avant même les modèles de menace.

Personne n’a besoin de vous envoyer quoi que ce soit

Reprenez la dernière année d’attaques contre les agents de code : elles partagent une même forme. Quelque chose que l’agent lit contient des instructions : un rapport de bug, un commentaire de PR invisible, une page web récupérée par l’agent, un README, une ligne de journal WAF. Dans chacun de ces cas, la livraison est le problème difficile de l’attaquant. Il lui faut trouver un canal que vous avez branché délibérément et y faire entrer son texte.

Inversez la flèche et le problème disparaît. Un scanner envoie un SYN sur le port 11434, et quelque chose répond sur votre machine.

Ce que trouvent les scanners

La population derrière la capture de Woodward se compte en dizaines de milliers.

Censys a cartographié les services MCP accessibles depuis Internet et en a trouvé 12 520, répartis sur 8 758 adresses IP uniques, dans 56 pays et 425 systèmes autonomes, au 28 avril 2026. Une semaine plus tard, le 6 mai, le compte dépassait 21 000. Environ quatre sur dix acceptent les requêtes de n’importe qui, sans vérification d’identifiant, parce que le protocole n’en exigeait pas par défaut.

Wiz est allé frapper à la porte. Dans une étude publiée le 28 juillet, ils ont trouvé MCP présent dans 80 % des environnements cloud, environ un sur six exposant au moins un serveur. Parmi ceux exposés, environ 70 % livraient leur catalogue d’outils complet à un appelant non authentifié, environ 42 % renvoyaient de vraies données lorsque les chercheurs invoquaient un outil, et environ 10 % servaient de façade à des backends sensibles. Wiz a pointé un sous-ensemble confirmé vers les points d’accès de métadonnées cloud et a récupéré des identifiants temporaires.

Knostic a mené le même exercice depuis Shodan, en prenant l’empreinte de 1 862 serveurs exposés ; chacun des 119 qu’ils ont vérifiés à la main répondait à tools/list sans authentification. Chacun de ces serveurs faisait la seule chose pour laquelle il existe, pour un inconnu.

L’inférence locale donne la même image, avec des chiffres plus ronds. LeakIX a dénombré 12 269 instances Ollama sans authentification le 23 février 2026, chacune offrant l’énumération des modèles via /api/tags, du calcul gratuit via /api/generate et /api/chat, le vol de modèles via /api/pull et /api/push, et, dans un millier de cas environ, la chaîne de traversée de répertoires Probllama.

48 heures sur 16 ports que personne n’avait annoncésInternet, qui balaiepas de liste de cibles,pas de phishing, rien à livrerjuste un SYN sur un portquelque chose répond16 personas LLM et infra IAsur 16 ports, fidèles au frameworken-têtes, erreurs, protocoleet le journal se remplit3 993 requêtesde 327 adresses IP uniquesen une seule fenêtre de 48 hle mode opératoire, identique d’une IP à l’autre155 sondages MCP344 sondages de clés IAenregistrement LiteLLMbalayages d’inférence localeénumération de ressources, force brute d’identifiants adaptée au framework, et tout ce qui a répondu la fois d’avantCe que les scanners trouvent, sur l’Internet réel21 000+ services MCPCensys, mai 2026, contre 12 520env. 4 sur 10 sans identifiant70 % livrent le catalogueWiz, juillet 2026, anonymement42 % renvoient de vraies données12 269 Ollama ouvertsLeakIX, février 2026énumérer, générer, pull, push
La capture de 48 heures de Woodward, et la population bien réelle qui se trouve derrière. Le scanner n’a besoin ni de liste de cibles ni de canal de livraison, puisque les services répondent d’eux-mêmes.

Comment votre machine finit par répondre

Vous n’avez pas décidé de mettre un service sur Internet. Vous avez posé OLLAMA_HOST=0.0.0.0 pour que le portable du canapé puisse utiliser le modèle du poste fixe, et vous avez lié un serveur MCP à toutes les interfaces pour la même raison. Vous avez lancé docker run -p 8080:8080 parce que le README le disait. Vous avez ouvert un tunnel pour déboguer quelque chose sur un téléphone et vous l’avez laissé ouvert.

Puis vous avez emporté le portable ailleurs. Le wifi d’une conférence, un étage de coworking, un hôtel, un routeur domestique où l’UPnP a obligeamment agi en votre nom, ou une machine de dev cloud dont quelqu’un a élargi le groupe de sécurité à la hâte. Le bind tient en un drapeau ; l’exposition appartient à qui a écrit la table de routage derrière laquelle vous vous trouvez. À aucun moment vous n’y avez consenti.

Bromure Agentic Coding referme cet écart par défaut, sans que vous ayez à régler quoi que ce soit.

La VM n’a pas d’adresse

Bromure exécute l’agent de code dans une VM Linux jetable sur Apple Silicon, chaque octet de son trafic traversant un proxy sur l’hôte, à l’extérieur de la boîte où tourne l’agent. Pour cette classe d’attaque, c’est le volet réseau de ce dispositif qui porte tout le poids.

Sous Ressources → Réseau, le mode est NAT, et le NAT est ce que vous obtenez sans faire de choix. La VM partage la connexion réseau de votre Mac via le NAT intégré de Virtualization.framework : la sortie fonctionne, et rien sur votre LAN ne peut atteindre la VM. Liez un service à 0.0.0.0 dans cette VM et vous l’aurez lié à une interface interne à la VM, derrière le NAT. Il n’y a aucune table de redirection de ports à mal remplir, puisque le mode ne redirige aucun port.

Le SYN du scanner n’atteint aucun port, ni filtré ni fermé, parce qu’aucune route n’y mène. Le pot de miel de Woodward avait besoin de 16 processus à l’écoute pour récolter quoi que ce soit. Un profil Bromure n’en présente aucun, et les 344 sondages d’identifiants n’ont nulle part où atterrir.

Le mode Ponté est là quand vous en voulez : il donne à la VM une adresse routable sur le LAN par DHCP, sur une interface physique que vous nommez. C’est un réglage par profil, avec un sélecteur d’interface explicite, pour que vous ne vous retrouviez sur le LAN que lors des exécutions où vous vouliez y être.

Vos serveurs MCP n’écoutent pas

Les serveurs du panneau MCP sont de la configuration de profil. Bromure les traduit en JSON Claude Code ou en TOML Codex et les injecte au démarrage. Un serveur stdio est un processus enfant à l’intérieur de la VM qui parle par des tubes : il n’a donc pas de socket, et l’énumération par tools/list n’a rien à atteindre. Un serveur HTTP est une URL que vous visez, avec un jeton bearer facultatif, ce qui fait de vous celui qui envoie la requête. Les 40 % de services MCP qui répondent aux inconnus sont des serveurs que quelqu’un a montés et liés à la main.

L’inférence locale tourne sur le Mac

« Balayages coordonnés à la recherche de services d’inférence locale exposés » est l’expression du pot de miel lui-même, et 12 269 Ollama ouverts sont ce qu’il trouve. L’authentification Modèle local de Claude Code achemine l’inférence vers un modèle MLX embarqué choisi dans le panneau Modèles locaux, qui tourne sur macOS, du côté hôte du proxy. Il n’y a aucun port 11434 dans la VM à exposer. Le volet embarqué de Fusion emprunte le même chemin.

Une sonde entrée ne récolterait que des leurres

Quiconque pratique la force brute d’identifiants adaptée au framework sait où chercher : OPENAI_API_KEY dans l’environnement, ~/.aws/credentials, ~/.docker/config.json, un kubeconfig, ~/.ssh. Bromure met tout cela dans la VM et rend tout cela faux. Vous obtenez des jetons brm_… et xai-brm-…, un kubeconfig synthétique avec des certificats client jetables, une fausse authentification de registre en base64, et du matériel AWS qui renvoie InvalidSignatureException dès que quelque chose contourne le proxy. Bromure garde les vraies valeurs sur l’hôte et les substitue sur le fil, pour la destination à laquelle elles appartiennent.

Les verbes destructeurs se décident sur l’hôte

Wiz a trouvé environ 42 % de serveurs exposés renvoyant de vraies données, et à côté une classe d’écriture et de suppression. Guardrails est un moteur de politiques dans le proxy hôte, couvrant Kubernetes, AWS, DigitalOcean, les registres de conteneurs, GitHub, GitLab, Bitbucket et les points d’accès de bases de données en HTTPS. Réglez Bloquer les opérations destructrices ou Lecture seule par ressource, et l’appel bloqué revient en 403 sec que l’agent signale comme un échec d’API ordinaire. Bromure prend cette décision dans macOS : il n’y a donc rien à désactiver dans la VM.

Sur le portable du développeurOLLAMA_HOST=0.0.0.0pour que l’autre portable ait le modèleport 11434, à l’écoute sur toutle serveur MCP est lié pareiltools/list répond à qui demandele catalogue est la reconnaissanceet l’environnement est réel344 sondages en 48 h connaissent les cheminsc’est le routage qui décidewifi de conférence, UPnP, groupe trop largeDans un profil Bromurela VM est en NAT, par défautla sortie marche ; rien n’entre0.0.0.0 se lie à une interface interneMCP en stdio est un tubeun processus enfant, pas de socketles serveurs HTTP sont des URL viséesl’inférence locale tourne sur le Macaucun 11434 dans la VM à scanneret l’env contient des brm_… de toute façonvraies valeurs sur l’hôte, échangées sur le fil
Les deux mêmes commodités, sur deux machines. Sur un portable, un drapeau chacune suffit à poser un service sur le réseau où vous vous trouvez. Dans un profil Bromure, la VM n’a pas de route entrante, le serveur MCP est un tube, le modèle tourne sur le Mac, et l’environnement qu’une sonde balaierait ne contient que des leurres.

Une tâche venue d’un inconnu reste du texte

Supposons que vous branchiez un serveur MCP distant que quelqu’un d’autre a exposé, et qu’il vous réponde avec autre chose que des données. Dès lors que les scanners peuvent énumérer ces services, celui qui en trouve un peut aussi s’en servir pour atteindre votre agent par la grande porte, sous forme de contenu.

Bromure note ce contenu à son arrivée. Un modèle local d’injection de prompt lit le contenu des fichiers, les pages web et les blocs tool_result que l’agent ingère, à la recherche d’un impératif adressé à quiconque lit. Consigner mais continuer enregistre chaque détection dans le journal de sécurité. Me demander quoi faire met en pause la requête sortante et place le passage signalé sous vos yeux. Bloquer unilatéralement l’arrête avant que le modèle ne la voie et renvoie à l’agent un 451 sec. Un second détecteur, un classifieur ModernBERT affiné plus un scanner déterministe pour les charges utiles à largeur nulle, bidirectionnelles et en balises Unicode, couvre CLAUDE.md, AGENTS.md, GROK.md et leurs variantes imbriquées et globales.

Les deux modèles tournent sur votre Mac, téléchargés une fois depuis bromure.io. Noter la sortie d’un serveur MCP tiers n’implique d’envoyer cette sortie nulle part.

Le coup frappé à la porte est une ligne de journal

Chaque requête émise par la VM traverse le proxy hôte, et au niveau de trace Activité, Bromure consigne pour chacune l’hôte, le statut, la latence, le rapport de substitution et tout avertissement de fuite. Les détections d’injection atterrissent dans le journal de sécurité avec le texte signalé en pièce jointe. Montez le niveau et Bromure conserve aussi les corps des requêtes IA, chiffrés avec la même clé de trousseau que les secrets de votre profil.

Un agent qui s’est mis à prendre des instructions de l’extérieur doit atteindre un endroit pour être utile à qui que ce soit, et atteindre un endroit est une ligne que vous pouvez lire sur la machine où la session s’est déroulée.

Et quand vous voulez que la machine disparaisse, elle disparaît. Effacer le home efface /home/ubuntu, c’est-à-dire les dotfiles, .ssh, npm-global, .cargo et l’historique du shell, et le ramène à son état d’après clonage. Réinitialiser à la base annule toute modification au niveau système et re-clone le disque de travail depuis l’image de base.

MCP finira par avoir de meilleurs réglages par défaut et Ollama par se doter d’une authentification, et les ports du pot de miel de Woodward seront d’autres ports en août prochain. La forme, elle, tient. Faire tourner un agent correctement aujourd’hui signifie faire tourner une passerelle et une poignée de serveurs d’outils à côté, et chacun d’eux est un programme qui lie une socket sur un portable qui voyage.

Les autres articles publiés ici vous demandent de vous méfier de ce que lit votre agent. Celui-ci pose une question plus courte : qu’est-ce qui répond lorsqu’un inconnu frappe, et ne préféreriez-vous pas que rien ne réponde.

Installez Bromure Agentic Coding, et donnez à votre agent une machine que les scanners ne peuvent pas voir.