Voltar para todas as publicações
Publicado em · por Renaud Deraison

O agente tinha um endereço

Na DEF CON 34, Eli Woodward, da Team Cymru, mostrou 48 horas de captura de um honeypot de IA: 3.993 requisições, 327 IPs de origem, 344 sondagens de credenciais, contra portas que ninguém havia anunciado. Os outros ataques a um agente de código precisam de um jeito de colocar texto diante dele. Este precisa de uma rota até ele. O Bromure Agentic Coding executa o agente atrás de NAT por padrão, de modo que não há rota alguma a encontrar.

Os outros ataques a um agente de código precisam de um jeito de colocar texto diante dele. Este precisa de uma rota até ele, e os scanners já têm uma.

Sábado de manhã, na DEF CON 34, no Creator Stage 3, Eli Woodward, da Team Cymru, deu uma palestra de meia hora chamada MCPwned: How Exposed AI Agents Became the Internet's New Recon Toy. Ele havia construído um honeypot de IA: 16 personas de LLM e de infraestrutura de IA distribuídas por 16 portas, cada uma devolvendo respostas, cabeçalhos, erros e comportamento de protocolo fiéis ao framework imitado, de modo que um scanner que a tocasse acreditaria ter encontrado a coisa real.

Em uma janela de 48 horas, o honeypot recebeu 3.993 requisições de 327 endereços IP de origem únicos, incluindo 155 sondagens de MCP e 344 sondagens de chaves de API de IA.

Ninguém havia anunciado aquelas portas, e nenhum dos 327 endereços tinha escolhido Woodward como alvo. O manual que ele extraiu da captura é do tipo enfadonho e industrial: abuso de registro de modelos no LiteLLM, enumeração de recursos MCP, força bruta de credenciais ciente do framework e varredura coordenada em busca de serviços de inferência local expostos. Os grupos que passaram uma década varrendo o espaço de endereçamento atrás de RDP aberto e Redis sem autenticação apontaram a mesma maquinaria para o ferramental de desenvolvimento de IA, à frente dos modelos de ameaça.

Ninguém precisa lhe enviar nada

Releia o último ano de ataques a agentes de código e todos compartilham um formato. Algo que o agente lê contém instruções: um relatório de bug, um comentário de PR invisível, uma página web buscada pelo agente, um README, uma linha de log do WAF. Em cada um desses casos, a entrega é o problema difícil do atacante. Ele precisa achar um canal que você conectou de propósito e fazer o texto dele entrar por ali.

Inverta a seta e esse problema desaparece. Um scanner manda um SYN para a porta 11434, e algo na sua máquina responde.

O que os scanners encontram

A população por trás da captura de Woodward chega à casa das dezenas de milhares.

A Censys mapeou os serviços MCP acessíveis pela internet e encontrou 12.520 deles, em 8.758 endereços IP únicos, em 56 países e 425 sistemas autônomos, em 28 de abril de 2026. Uma semana depois, em 6 de maio, a contagem já passava de 21.000. Cerca de quatro em cada dez aceitam requisições de qualquer um, sem verificação de credencial, porque o protocolo não exigia uma por padrão.

A Wiz foi bater à porta. Em um levantamento publicado em 28 de julho, encontraram MCP presente em 80% dos ambientes de nuvem, com cerca de um em cada seis expondo pelo menos um servidor. Entre os expostos, cerca de 70% entregavam o catálogo completo de ferramentas a um chamador não autenticado, cerca de 42% devolviam dados reais quando os pesquisadores invocavam uma ferramenta, e mais ou menos 10% serviam de fachada para backends sensíveis. A Wiz apontou um subconjunto confirmado para endpoints de metadados de nuvem e recebeu de volta credenciais temporárias.

A Knostic fez o mesmo exercício a partir do Shodan, identificando 1.862 servidores expostos; cada um dos 119 que verificaram manualmente respondeu a tools/list sem autenticação. Cada um desses servidores estava fazendo a única coisa para a qual existe, para um estranho.

A inferência local dá o mesmo quadro, com números mais redondos. A LeakIX contou 12.269 instâncias do Ollama sem autenticação em 23 de fevereiro de 2026, cada uma oferecendo enumeração de modelos por /api/tags, computação gratuita por /api/generate e /api/chat, roubo de modelos por /api/pull e /api/push, e, em cerca de mil casos, a cadeia de travessia de diretórios Probllama.

48 horas em 16 portas que ninguém anuncioua internet, varrendosem lista de alvos, sem phishing,nada a entregarsó um SYN para uma portaalgo responde16 personas de LLM e infra de IAem 16 portas, fiéis ao frameworkcabeçalhos, erros, protocoloe o log vai enchendo3.993 requisiçõesde 327 IPs de origem únicosem uma única janela de 48 horaso manual, igual de um IP para o outro155 sondagens MCP344 sondagens de chavesregistro de modelos LiteLLMvarreduras de inferência localenumeração de recursos, força bruta de credenciais ciente do framework e o que respondeu da última vezO que os scanners estão achando, na internet real21.000+ serviços MCPCensys, maio de 2026, eram 12.520cerca de 4 em 10 sem credencial70% entregam o catálogoWiz, julho de 2026, anonimamente42% devolvem dados reais12.269 Ollamas abertosLeakIX, fevereiro de 2026enumerar, gerar, pull, push
A captura de 48 horas de Woodward e a população real por trás dela. O scanner não precisa de lista de alvos nem de canal de entrega, porque os serviços respondem por conta própria.

Como sua máquina acaba respondendo

Você não decidiu colocar um serviço na internet. Você definiu OLLAMA_HOST=0.0.0.0 para que o laptop no sofá pudesse usar o modelo do desktop, e ligou um servidor MCP a todas as interfaces pelo mesmo motivo. Você rodou docker run -p 8080:8080 porque o README mandou. Você abriu um túnel para depurar algo num celular e o deixou aberto.

Aí você levou o laptop para outro lugar. Wi-Fi de conferência, um andar de coworking, um hotel, um roteador doméstico onde o UPnP fez o favor em seu nome, ou uma máquina de desenvolvimento na nuvem cujo grupo de segurança alguém alargou às pressas. O bind é uma flag; a exposição pertence a quem escreveu a tabela de roteamento atrás da qual você calhou de estar. Em nenhum momento você concordou com isso.

O Bromure Agentic Coding fecha essa brecha por padrão, sem que você configure nada.

A VM não tem endereço

O Bromure executa o agente de código em uma VM Linux descartável em Apple Silicon, com cada byte do tráfego dele atravessando um proxy no host, fora da caixa em que o agente roda. Para esta classe de ataque, é o lado de rede desse arranjo que carrega o peso.

Em Recursos → Rede, o modo é NAT, e NAT é o que você recebe sem fazer escolha alguma. A VM compartilha a conexão de rede do seu Mac pelo NAT embutido do Virtualization.framework: a saída funciona, e nada na sua LAN alcança a VM. Ligue um serviço a 0.0.0.0 dentro dessa VM e você o terá ligado a uma interface interna da VM, atrás do NAT. Não há tabela de encaminhamento de portas para preencher errado, porque o modo simplesmente não encaminha portas.

O SYN do scanner nunca chega a porta alguma, nem filtrada nem fechada, porque não há rota que leve a uma. O honeypot de Woodward precisou de 16 processos em escuta para coletar qualquer coisa. Um perfil Bromure não apresenta nenhum, e as 344 sondagens de credenciais não têm onde aterrissar.

O modo Bridged está lá quando você quiser, e dá à VM um endereço roteável na LAN por DHCP em uma interface física que você indica. É uma configuração por perfil, com um seletor de interface explícito, para que você só acabe na LAN na execução em que pretendia estar na LAN.

Seus servidores MCP não ficam escutando

Os servidores no painel MCP são configuração de perfil. O Bromure os traduz para JSON do Claude Code ou TOML do Codex e os injeta na inicialização. Um servidor stdio é um processo filho dentro da VM falando por pipes, ou seja, não tem socket, e a enumeração por tools/list não tem o que alcançar. Um servidor HTTP é uma URL para a qual você aponta, com um token bearer opcional, o que faz de você quem envia a requisição. Os 40% de serviços MCP que respondem a estranhos são servidores que alguém subiu e ligou na mão.

A inferência local roda no Mac

“Varredura coordenada em busca de serviços de inferência local expostos” é a expressão do próprio honeypot, e 12.269 Ollamas abertos é o que ela encontra. A autenticação Modelo local do Claude Code roteia a inferência para um modelo MLX no dispositivo, escolhido no painel Modelos locais, que roda no macOS, do lado do host do proxy. Não existe porta 11434 dentro da VM para expor. A perna local do Fusion segue o mesmo caminho.

Uma sonda que entrasse colheria valores falsos

Quem faz força bruta de credenciais ciente do framework sabe onde procurar: OPENAI_API_KEY no ambiente, ~/.aws/credentials, ~/.docker/config.json, um kubeconfig, ~/.ssh. O Bromure põe tudo isso na VM e faz tudo isso ser falso. Você recebe tokens brm_… e xai-brm-…, um kubeconfig sintético com certificados de cliente descartáveis, uma autenticação de registro em base64 falsa e material da AWS que devolve InvalidSignatureException no instante em que algo contorna o proxy. O Bromure mantém os valores reais no host e os substitui no fio, para o destino a que pertencem.

Verbos destrutivos são decididos no host

A Wiz encontrou cerca de 42% dos servidores expostos devolvendo dados reais, e uma classe de escrita e exclusão ao lado disso. Guardrails é um motor de políticas no proxy do host, cobrindo Kubernetes, AWS, DigitalOcean, registries de contêineres, GitHub, GitLab, Bitbucket e os endpoints de banco de dados em HTTPS. Escolha Bloquear operações destrutivas ou Somente leitura por recurso e a chamada bloqueada volta como um 403 seco, que o agente reporta como uma falha comum de API. O Bromure toma essa decisão no macOS, então não há nada dentro da VM para desligar.

No laptop do desenvolvedorOLLAMA_HOST=0.0.0.0para o outro laptop usar o modeloporta 11434, escutando em tudoo servidor MCP está ligado igualtools/list responde a quem pediro catálogo é o reconhecimentoe o ambiente é real344 sondagens em 48 h sabem os caminhosquem roteia até você é quem decidewi-fi de evento, UPnP, grupo largo demaisDentro de um perfil Bromurea VM fica em NAT, por padrãoa saída funciona; nada entra0.0.0.0 liga a uma interface internaMCP por stdio é um pipeum processo filho, sem socket a enumerarservidores HTTP são URLs que você apontaa inferência local roda no Macnenhuma 11434 na VM para varrere o ambiente guarda brm_… de todo jeitovalores reais no host, trocados no fio
As mesmas duas conveniências, em duas máquinas. Num laptop, uma flag para cada uma põe um serviço na rede em que você calhou de estar. Num perfil Bromure, a VM não tem rota de entrada, o servidor MCP é um pipe, o modelo roda no Mac e o ambiente que uma sonda varreria só tem valores falsos.

Uma tarefa vinda de um estranho ainda é texto

Suponha que você conecte um servidor MCP remoto que outra pessoa expôs, e que ele lhe responda com mais do que dados. Uma vez que os scanners conseguem enumerar esses serviços, quem encontrar um também pode usá-lo para alcançar seu agente pela porta da frente, como conteúdo.

O Bromure pontua esse conteúdo na entrada. Um modelo local de injeção de prompt lê o conteúdo dos arquivos, as páginas web e os blocos tool_result que o agente ingere, procurando um imperativo dirigido a quem estiver lendo. Registrar mas continuar anota cada ocorrência no Log de Segurança. Perguntar o que fazer pausa a requisição de saída e coloca o trecho marcado diante de você. Bloquear unilateralmente interrompe tudo antes que o modelo veja e devolve ao agente um 451 seco. Um segundo detector, um classificador ModernBERT ajustado mais um scanner determinístico para cargas de largura zero, bidirecionais e de tags Unicode, cobre CLAUDE.md, AGENTS.md, GROK.md e suas variantes aninhadas e globais.

Os dois modelos rodam no seu Mac, baixados uma vez de bromure.io. Pontuar a saída de um servidor MCP de terceiros não envolve mandar essa saída a lugar nenhum.

A batida na porta é uma linha no log

Cada requisição que a VM faz atravessa o proxy do host e, no nível de rastreio Atividade, o Bromure registra para cada uma o host, o status, a latência, o relatório de substituição e quaisquer avisos de vazamento. Detecções de injeção caem no Log de Segurança com o texto marcado anexado. Suba o nível e o Bromure guarda também os corpos das requisições de IA, cifrados com a mesma chave de chaveiro dos segredos do seu perfil.

Um agente que passou a receber instruções de fora precisa alcançar algum lugar para ser útil a alguém, e alcançar algum lugar é uma linha que você pode ler na máquina em que a sessão rodou.

E quando você quiser a máquina fora do caminho, ela some. Apagar home limpa /home/ubuntu, ou seja, dotfiles, .ssh, npm-global, .cargo e histórico do shell, de volta ao estado logo após o clone. Restaurar para a base descarta toda alteração de nível de sistema e reclona o disco de trabalho a partir da imagem base.

O MCP vai ganhar padrões melhores e o Ollama vai ganhar uma história de autenticação, e as portas do honeypot de Woodward serão outras portas em agosto que vem. O formato permanece. Rodar um agente direito hoje significa rodar um gateway e um punhado de servidores de ferramentas ao lado dele, e cada um deles é um programa que abre um socket num laptop que viaja.

Os outros textos publicados aqui pedem que você desconfie do que seu agente lê. Este faz uma pergunta mais curta: o que responde quando um estranho bate, e você não preferiria que nada respondesse.

Instale o Bromure Agentic Coding e dê ao seu agente uma máquina que os scanners não conseguem ver.