3 pontos por GN⁺ 2023-07-14 | 1 comentários | Compartilhar no WhatsApp
  • O nome de host local padrão do macOS pode incluir o nome do usuário, permitindo que um site reduza os candidatos sem permissão por meio de diferenças no tempo de resolução de nomes mDNS
  • O atacante combina 50 nomes populares por país e gênero com candidatos de nomes de dispositivos e, nos experimentos, acertou o nome de usuários do macOS em 65% dos casos, em média
  • O JavaScript no navegador não pode abrir sockets UDP arbitrários, mas pode comparar a latência de resposta de endereços .local com requisições fetch, iframe, Image e WebRTC
  • Informações como fuso horário, idioma, localização por IP, navigator.language do Safari, resolução de tela e screen.isExtended são usadas para reduzir os candidatos de localidade e modelo de dispositivo
  • A praticidade é baixa e isso tende a aparecer facilmente na aba de rede das ferramentas de desenvolvedor, mas o mesmo método de descoberta via mDNS também pode ser usado para detectar impressoras, smart TVs, alto-falantes inteligentes e dispositivos IoT

Como o nome vaza pelo nome de host local do macOS

  • O nome real de usuários do macOS pode ser inferido no navegador sem solicitar permissões, e o ponto central é o protocolo mDNS e o formato padrão do nome de host local
  • Mesmo usando apenas uma lista de 50 nomes populares por gênero de um país específico, foi possível identificar corretamente o nome de usuários do macOS em 65% dos casos, em média
  • A Fingerprint não usa essa técnica em seu produto nem oferece serviço de rastreamento cross-site
  • O objetivo da discussão pública é ajudar fornecedores de navegadores a corrigirem rapidamente esse tipo de técnica

Como funcionam o mDNS e o Apple Bonjour

  • O multicast DNS é um protocolo para registrar, descobrir e transmitir nomes de dispositivos em uma rede local
  • Dispositivos como impressoras enviam pacotes UDP de registro para o IP interno reservado 224.0.0.251, que podem incluir nomes de host como HP_LaserJet_Printer.local
  • O domínio de topo .local indica que esse nome de host deve ser resolvido via mDNS
  • Roteadores retransmitem automaticamente esses pacotes para outros dispositivos da rede local, permitindo que armazenem os nomes de host em cache
  • Dispositivos enviam pacotes de consulta para o mesmo IP reservado para procurar um dispositivo de nome específico que possa existir na rede
  • Exemplos de nomes de host:
    • johns-mac-mini.local
    • david-ZenBook-UX431DA-UM431DA.local
    • james-iphone.local
    • canon-mf644c.local
    • bedroom-appletv.local
    • dlinkrouter.local
  • Em dispositivos Apple, o mDNS é amplamente usado como parte do recurso Apple Bonjour
  • O nome padrão do host local pode expor o nome do usuário e, no macOS, ele pode ser visto ou alterado em Ajustes do Sistema > Compartilhamento

Forma de contornar no navegador para verificar nomes de host mDNS

  • Como o mDNS é baseado em pacotes UDP, ele não pode ser usado diretamente por sockets UDP arbitrários no ambiente JavaScript do navegador
  • Em vez disso, é possível realizar um ataque de temporização explorando o fato de que o navegador tenta resolver o nome de host de uma URL
  • A prova de conceito envia requisições GET normais com fetch para um device-1.local existente e um device-2.local inexistente
  • Se o endereço for resolvido, o navegador envia um pacote TCP para a porta 80, que normalmente tende a estar fechada
  • No nível de rede, aparecem erros diferentes
    • device-1.local existente: ERR_CONNECTION_REFUSED
    • device-2.local inexistente: ERR_NAME_NOT_RESOLVED
  • No JavaScript, os dois erros são mapeados para o mesmo erro Failed to fetch, então não dá para depender do tipo de erro em si
  • Como a rede local é rápida, um nome de host mDNS válido é resolvido muito mais rápido do que o timeout padrão de conexão
  • No exemplo, um endereço válido levou 4ms e um inválido 5 segundos
  • Essa abordagem é consistente o bastante para uma prova de conceito e se comporta de forma parecida nos principais navegadores
  • Na prática, além de fetch, também é possível realizar ataques de temporização na resolução DNS com APIs de rede do JavaScript como iframe, Image e WebRTC

Como fazer força bruta do nome de usuários do macOS

  • O nome de host local padrão do macOS inclui o nome do usuário e o nome do dispositivo, e o formato varia conforme a localidade do idioma do sistema
    • Inglês: <name>s-macbook-pro.local
    • Francês: macbook-air-de-<name>.local
    • Russo: mac-mini-<name>.local
  • Em uma abordagem simples, combinar os 1.000 nomes mais comuns, as 10 localidades mais frequentes e 5 nomes típicos de dispositivos macOS exigiria verificar 50.000 nomes de host
  • Nesse caso, a varredura completa pode levar mais de 1 hora
  • Uma estratégia mais eficiente é limitar a busca a uma única localidade, um único dispositivo e 50 nomes comuns daquela localidade
  • Reduzir o escopo diminui a precisão, mas também reduz o tempo do ataque, tornando o cenário mais realista
  • A seleção da localidade pode usar o fuso horário, o idioma e a localização do endereço IP do navegador
  • O Safari expõe a localidade do sistema pela propriedade navigator.language, e esse valor normalmente coincide com a localidade do nome de host alvo
  • Outra forma de contornar e descobrir o país de origem do usuário é o método de detecção da região do Apple ID tratado anteriormente
  • Os candidatos de dispositivo podem ser reduzidos pela resolução de tela
    • Por exemplo, a resolução 1728x1117 sugere fortemente um MacBook Pro de 16 polegadas
    • Uma tela estendida pode ser detectada pela propriedade screen.isExtended
    • Se uma tela estendida for detectada, os candidatos de dispositivo podem voltar para os 3 a 5 dispositivos Apple com macOS mais comuns

Limitações e outras aplicações possíveis

  • Esse ataque não é prático por causa de fraquezas inerentes e várias limitações
  • A menos que o operador do site esteja tentando deliberadamente remover o anonimato de visitantes, isso pode ser facilmente detectado na aba de rede das ferramentas de desenvolvedor do navegador
  • Ao combinar esse método com detecção de aplicativos instalados, seria possível criar um site nocivo que exibisse, sem permissão, o nome real do usuário e um cargo inferido pela lista de aplicativos profissionais em uso
  • Embora dispositivos Apple com macOS sejam o principal exemplo, a técnica de descoberta via mDNS pode ser expandida de várias formas
  • Ela também pode ser usada para detectar impressoras, smart TVs, alto-falantes inteligentes e outros dispositivos IoT domésticos por meio de varredura da rede local
  • Também pode se aplicar a iPhone e iPad, desde que a sincronização por Wi‑Fi ou o recurso de depuração remota do Safari esteja ativado

1 comentários

 
GN⁺ 2023-07-14
Comentários do Hacker News
  • Eu uso Little Snitch no macOS, e ele tem uma interface razoável que pode ser configurada para perguntar explicitamente ao usuário local antes de permitir uma requisição de rede
    https://www.obdev.at/products/littlesnitch/index.html
    Isso me pega de vez em quando durante login remoto, geralmente quando a sessão SSH tenta baixar algo novo, como componentes do NodeJS pelo NPM. O download via SSH no terminal de texto fica travado e, quando percebo que o motivo é o Little Snitch, preciso ir até a mesa no andar de baixo, mexer o mouse para acordar o monitor, desbloquear o protetor de tela e clicar em “Allow” na caixa de diálogo do Little Snitch
    Então ele está funcionando como foi projetado. Dito isso, ferramentas desse tipo muitas vezes vêm configuradas para permitir silenciosamente requisições na rede local por padrão, então não sei se a brincadeira do post original funcionaria no meu ambiente

    • No meu caso, é difícil imaginar configurar o LittleSnitch para permitir apenas nomes de host específicos no navegador. Eu tenho uma regra do tipo “permitir todo o tráfego para 53/80/443”; caso contrário, a maioria dos sites exibiria centenas de pop-ups do LittleSnitch
    • Eu uso NetFence em um iPhone com jailbreak
      É impressionante ver que tipos de conexões de socket os apps abrem às escondidas, inclusive apps bancários
      https://havoc.app/package/netfence
    • Só que o Little Snitch ainda deixa o IP vazar ao bloquear :(
      https://news.ycombinator.com/item?id=35363343
    • Já usei OpenSnitch, um software parecido no Linux. Não encontrou nada estranho, mas foi bem incômodo no uso normal do dia a dia
    • Só para constar, a resolução de DNS acontece antes do pop-up de permitir/negar conexão. Por exemplo, www.example.com é resolvido para 1.1.1.1, mas nenhuma conexão real com 1.1.1.1 é criada até você clicar em Confirm
      Se você adicionar um Pi-hole à rede, provavelmente não vai se arrepender do tempo/dinheiro/investimento
  • Existe alguma forma de impedir que sites da internet mais ampla façam requisições de rede para a minha rede local? É difícil imaginar por que isso deveria ser permitido por padrão
    Não estou defendendo a volta das permissões da Local Intranet Zone do IE

    • Em geral, por causa de CORS, isso não é possível. A única razão de esse “hack” funcionar é que o tempo de falha é diferente entre uma requisição para um domínio que não resolve e uma requisição que resolve, mas é negada
      Mas mesmo que você esteja rodando algo em https://192.168.2.1, um app web executado em https://my-own-domain.com não pode acessá-lo, a menos que o serviço em 192.168.2.1 permita my-own-domain.com como Origin
    • O Brave adicionou recentemente um recurso que exige permissão para acesso à rede local
      https://brave.com/privacy-updates/27-localhost-permission/
      Post no HN: https://news.ycombinator.com/item?id=36574775
    • Um app que costuma abusar muito disso é o app de desktop do Discord, que deixa uma porta local aberta e escutando
      Quando o navegador vai para uma página de convite de canal do Discord, ele envia uma requisição via essa porta para localhost e entrega o ID do canal ao cliente. Aí o app pode mostrar uma experiência nativa de “Join Channel”
      Descobri isso ao ver que o comportamento continuava mesmo no modo anônimo e com o navegador deslogado do Discord. Isso não é bom. Precisamos melhorar muito o sandboxing de todos os aplicativos no desktop
    • Dá para bloquear com um filtro estático do uBlock Origin:
      ||local^$all
      Isso bloqueia todas as requisições para .local, inclusive requisições vindas do próprio .local. Se você quiser permitir que foo.local se comunique consigo mesmo, por exemplo porque roda um servidor web, vai precisar de uma exceção adicional por domínio:
      @@||foo.local^$domain=foo.local,all
      Ou, se você confia em todo o .local e quer permitir que qualquer foo.local se comunique com qualquer bar.local, pode adicionar uma única exceção geral para .local:
      @@||local^$domain=local,all
    • Para evitar confusão, o problema aqui não é um servidor na internet enviando requisições para a rede local, e sim o navegador web local enviando essas requisições. Claro, o JavaScript executado no navegador pode ter sido carregado de um servidor na internet
  • Com o passar do tempo, fico cada vez mais inclinado a usar a internet em geral dentro de uma caixa Qubes, em uma VM descartável de Whonix/Tor, com JavaScript desativado
    Isso é realmente nojento. Não é surpreendente, mas o simples fato de ser possível é horrível de várias formas
    Se você não conhece a fingerprint.com, eles fazem “perfilamento profundo de usuários”. Pense em manter o mesmo ID de usuário mesmo mudando de computador, navegador e sistema operacional. Tem uma demo na página principal, e é meio assustador o quanto acerta

    • Ela reconhece totalmente como o mesmo dispositivo mesmo com IPs diferentes de VPN. Muito assustador
    • Isso é nojento. É impressionante que consiga fazer isso no modo anônimo padrão do iPhone, mesmo trocando entre dois IPs, embora ele devesse claramente parecer igual a todos os outros iPhones
      Filtro do uBlock Origin para quebrar a demo:
      ||fpjscdn.net
  • Com um tipo semelhante de ataque de temporização, dá para fazer varredura de portas na máquina local e em outros dispositivos da rede local a partir do navegador
    https://github.com/Flu1dTeam/PortScanner
    Antigamente, a eBay foi pega fazendo isso
    https://blog.nem.ec/2020/05/24/ebay-port-scanning/

    • O quê? Isso é assustador demais, como é que eu nunca tinha ouvido falar disso até agora?
  • Ainda bem que eu sempre deixo o nome dos meus dispositivos alterado
    O esquema de nomes padrão da Apple é um erro de privacidade. Uma vez saí pela primeira vez com alguém das forças de segurança; era uma mulher sozinha e claramente preocupada em se proteger, então ela tinha pesquisado meu histórico e avisado algumas pessoas da comunidade ao redor sobre onde estaríamos
    Já eu nem sabia o sobrenome dela, e até brincava com isso. Depois do jantar, quando entramos no carro, a tela do painel mostrou que um iPhone tinha sido pareado automaticamente, e o nome desse iPhone estava com o nome e sobrenome dela, o que me chamou a atenção. Não comentei nada na hora e, até o fim do trajeto, pedi que ela tentasse adivinhar como eu sabia o nome dela

    • É muito comum um carro alugado ainda ter uma dúzia de perfis de celulares pareados anteriormente, junto com agenda de contatos, locais salvos no mapa e histórico. Claro, isso quase não serve para nada, mas é um vazamento de informação bem descuidado
      O mais difícil é se lembrar de apagar o meu perfil antes de devolver o carro
  • No exemplo acima, um endereço válido leva 4 milissegundos, enquanto um inválido leva 5 segundos
    Isso é surpreendente. Eu esperaria que uma falha numa consulta DNS fosse muito mais rápida do que o timeout de conexão padrão que vem depois de uma consulta DNS bem-sucedida
    Ainda assim, sempre achei s-mac-xxxx uma escolha meio estranha. Ainda mais considerando que é uma empresa que vende privacidade como um grande diferencial. Eu teria esperado que não usassem o nome real, ou então que aqui a “facilidade de uso” tenha falado mais alto. Do ponto de vista de privacidade, os nomes de host gerados aleatoriamente do Windows são melhores

    • O DNS comum pergunta a um único servidor em um único IP por uma resposta sim/não, mas o mDNS é multicast, então nenhum servidor individual pode dizer com autoridade “não”†. Só dá para perceber que o registro não existe quando a consulta expira sem resposta
      † Estritamente falando, isso não é totalmente correto. Se algum dispositivo souber que aquele nome pertence a ele, pode responder que não
    • O motivo de o nome real do usuário entrar no hostname talvez seja o AirDrop. Parece que o sistema usa o hostname em recursos como Personal Hotspot e AirDrop, e outros tipos de nome provavelmente causariam bastante confusão ao compartilhar arquivos
    • Além da questão do timeout de conexão padrão, aqui também houve connection refused, ou seja, recebeu um RST, e não um timeout de conexão
  • O texto é bem escrito e interessante. Gostei especialmente do tom sem exageros, com frases como “considerando as fraquezas inerentes e as muitas limitações, este ataque não é prático”

    • Em outro universo, isso viraria “FINGERBleed”, com direito a site chamativo e logo também
    • Não tenho tanta certeza
      Esse método permite testar se um hostname específico existe na rede
      Se for só um hostname único, talvez não seja grande coisa, mas e os hostnames fixos ou padrão, comuns no mundo de IoT?
      Um site passa a poder adivinhar sorrateiramente se o usuário possui determinado dispositivo. Em ataques direcionados, isso é pior ainda. Se você conhece alguns dispositivos da rede, pode inferir se o usuário que acessou está dentro da rede alvo
  • Seria bom se desligar o JavaScript não desligasse também a experiência final do usuário

    • Esse é o único motivo de eu não conseguir desativar JavaScript globalmente
      Mesmo assim, daqui para frente parece que vou ter que deixar desativado por padrão por causa das preocupações com privacidade
    • Não existe alguma forma de restringir fortemente o que um motor de JavaScript pode fazer?
  • Felizmente, o nome dos meus dispositivos costuma ser algo como “MacBook Pro de xxxs (34)”. Não é bug, é feature

    • Defina o nome de usuário do laptop como user e o hostname como hostname. Quanto mais gente fizer isso, melhor
  • Interessante, bem escrito e com uma prova de conceito decente. Ficou bem feito
    Como contramedida divertida, daria para mudar o hostname do dispositivo para algo como atemptingurl.local, para fazer o atacante querer visitar esse site. A página poderia ser cuidadosamente preparada para executar a mesma técnica contra o atacante e devolver uma mensagem como:
    “Olá, [nome do dispositivo do hacker]! As informações da sua máquina, endereço IP, localização geográfica e outros dados de fingerprint foram coletados e enviados para [insira o nome de uma agência cibernética assustadora].” Mesmo que o sujeito seja um veterano experiente e não um script kiddie, no mínimo isso arrancaria uma risada
    As pessoas precisam de mais motivos para rir :-)

    • Para isso, seria preciso rodar um servidor HTTP com CORS totalmente liberado. Aí você fica exposto a qualquer falha do servidor HTTP escolhido, reduzindo também a sua própria segurança