2 pontos por GN⁺ 2024-11-02 | 1 comentários | Compartilhar no WhatsApp
  • O DownloadManager do qBittorrent ignorou erros de validação de certificado SSL de 6 de abril de 2010 até 12 de outubro de 2024, por cerca de 14 anos e 6 meses, tornando vários fluxos de download uma superfície de ataque em cenários de interceptação de rede
  • O problema recebeu o identificador CVE-2024-51774 e sua exploração exige acesso MITM ou spoofing de DNS
  • Foram afetados caminhos que usam o DownloadManager, como busca, download de .torrent, feeds RSS e download de favicon, e até certificados expirados ou autoassinados podiam ser aceitos
  • No Windows, o prompt de instalação do Python e o fluxo RSS de verificação de atualizações podem levar ao download de executáveis ou à manipulação de links de atualização se a resposta das URLs codificadas no binário for alterada
  • É mais seguro atualizar baixando manualmente o v5.0.1 diretamente no navegador do que usar o prompt interno de atualização do app

Bypass de validação de certificados por mais de 14 anos

  • A classe DownloadManager do qBittorrent vinha ignorando todos os erros de validação de certificado SSL desde o commit 9824d86, em 6 de abril de 2010
  • O comportamento padrão mudou para validar certificados no commit 3d9e971, em 12 de outubro de 2024
  • O primeiro patch release era o qBittorrent v5.0.1, lançado 2 dias antes da data de publicação do texto
  • O problema foi registrado como CVE-2024-51774
  • As condições de exploração são acesso MITM ou spoofing de DNS

A ampla superfície de ataque criada pelo DownloadManager

  • O uso do DownloadManager é amplo, então foram afetados busca, download de .torrent, feeds RSS e download de favicon
  • Esses caminhos podiam aceitar certificados expirados, autoassinados ou ambos
  • Os principais vetores de impacto se dividem em instalação do Python no Windows, atualização de software, feeds RSS e superfície de ataque na descompressão de bibliotecas

Download de executável no fluxo de instalação do Python no Windows

  • No Windows, se não houver uma versão suficientemente recente do Python instalada, o qBittorrent exibe uma janela perguntando se o usuário quer instalar ou atualizar o Python para usar plugins de busca
  • Se o usuário clicar em Yes, opção marcada por padrão, ou pressionar Enter, o aplicativo baixa o instalador do Python de uma URL python.org codificada no binário
  • Após o download, o qBittorrent renomeia o arquivo para .exe e o executa, apagando o arquivo temporário ao final
  • Esse comportamento existe de junho de 2015 até hoje, afetando da v3.2.1 até a v5.0.0
  • Em outras variantes de sistema operacional, se o Python estiver ausente ou não for recente o bastante, o widget de busca é desativado, e o mesmo comportamento não parece reproduzível
  • O executável pode ser salvo em um caminho como C:\Users\_user_\AppData\Local\Temp\is-G61QK.tmp
  • Pode ser por causa do comportamento do QProcess, mas duas threads do executável podem ser criadas, apenas uma encerra e a outra pode permanecer em estado de sleeping

Manipulação de URL via RSS de verificação de atualização

  • Versões instaladas do qBittorrent no Windows ou Linux, quando não são arquivo appImage, verificam atualizações por padrão ao iniciar
  • A verificação de atualização funciona baixando um documento XML de uma URL RSS do Fosshub codificada no binário e analisando as informações de release do programa
  • Se o XML trouxer uma versão superior à atualmente em execução, o fluxo extrai a URL de atualização e pergunta ao usuário se deseja visitar essa URL, sem filtragem ou validação adicional
  • Se o usuário aceitar o prompt, essa URL é aberta no navegador padrão
  • O usuário tende a esperar um arquivo .exe dentro de um contexto de confiança, por ter vindo de um link fornecido pelo software
  • Se um invasor redirecionar para um site de compartilhamento de arquivos como o MediaFire, o usuário pode baixar um executável controlado pelo atacante como se fosse uma atualização
  • Como o qBittorrent é open source, é fácil adicionar uma backdoor à versão mais recente e recompilá-la
  • Os desenvolvedores fornecem chaves para verificar assinaturas dos binários, mas a proteção só funciona se o usuário realmente validar e respeitar uma falha de verificação

Injeção em feeds RSS e links

  • Todos os feeds RSS analisados pelo aplicativo passam pelo DownloadManager, então podem ser sequestrados
  • As URLs visitadas pela vítima podem ser observadas e catalogadas, e URLs de RSS tendem a ser estáticas e persistirem por muito tempo
  • O elemento link de cada item é analisado diretamente e pode ser baixado quando o usuário dá duplo clique
  • Mesmo sem adulteração MITM, uma URL arbitrária inserida por um autor ou por um atacante que poluiu o feed RSS assinado pelo usuário pode ser aberta com um único duplo clique
  • A CVE-2019-13640 era uma vulnerabilidade que permitia execução remota de comandos por meio de metacaracteres de shell no nome do torrent ou no parâmetro atual do tracker, e um atacante MITM poderia inserir dados maliciosos no RSS, ampliando o risco de combinação

Download do banco GeoIP e superfície de ataque na descompressão

  • Ao iniciar, o qBittorrent baixa automaticamente por padrão de uma URL codificada no binário um banco de dados MaxMind GeoIP binário com extensão .gz e o descomprime
  • Se houver uma vulnerabilidade na descompressão zlib, um atacante pode mirar essa superfície com um arquivo arbitrário de até 64 MB
  • O exemplo citado, CVE-2022-37434, foi um buffer overflow Critical com CVSS 9.8 em 2022, mas não se aplica aqui porque a função inflateGetHeader() não é chamada
  • O código que analisa o banco de dados binário da MaxMind após a descompressão está bem protegido em 2024, mas isso não era necessariamente verdade no passado, e pode ter havido superfície de ataque adicional
  • Em um commit da função gzip::decompress(), o buffer de destino mudou de uma alocação estática na stack para uma alocação dinâmica na heap, e havia checagens antes da escrita, então não era explorável

Cenários de ataque automatizáveis

  • Tanto a URL do instalador do Python quanto a URL do feed RSS de atualização são codificadas no binário, então um script malicioso em ambiente MITM pode enumerar versões vulneráveis e atacar
  • A URL do feed RSS dificilmente seria visitada fora do momento em que o qBittorrent está em execução, então pode servir como impressão digital do software
  • Como não havia validação de certificado, o atacante pode fazer spoofing do servidor de destino sem precisar de uma implantação Man-On-The-Side mais complexa, como QUANTUM
  • Pela natureza das URLs codificadas no binário, é possível interceptar seletivamente apenas as requisições não validadas do qBittorrent sem alertar a vítima por falhas de conexão segura no navegador ou em outros aplicativos
  • Com a opção -s do mitmproxy junto de um script Python, é possível automatizar o seguinte
    • Trocar o .exe do Python por um executável arbitrário: RCE com um único clique
    • Substituir automaticamente a URL do RSS de atualização do qBittorrent: sequestro de navegador/RCE, com interação moderada do usuário
    • Substituir todos os links ou links específicos no visualizador RSS do qBittorrent: RCE até 2019, sequestro de downloads

Upgrade e formas de mitigação

  • É necessário atualizar para o qBittorrent v5.0.1
  • Recomenda-se fazer o upgrade por download manual direto no navegador, e não pelo prompt interno de atualização do app
  • Como alternativa, é possível usar clientes como Deluge e Transmission, que não têm essa vulnerabilidade
  • Não é fácil tratar ataques que exigem MITM apenas como risco teórico, considerando o histórico recente e casos concretos em alguns países
  • Houve contato com o mantenedor do repositório, mas não houve resposta sobre a intenção de publicar um advisory de segurança no GitHub

1 comentários

 
GN⁺ 2024-11-02
Comentários do Hacker News
  • A classe DownloadManager do qBittorrent ignorou todos os erros de validação de certificado SSL em todas as plataformas por 14 anos e 6 meses, desde o commit 9824d86 em 6 de abril de 2010
    Parece bem grave

  • Não quero minimizar essa vulnerabilidade, mas considerar como única linha de defesa uma combinação válida de certificado TLS e nome de domínio em um caminho que permite execução remota de código beira o desastre
    No mínimo, se um aplicativo baixa e executa algo da internet, ele deveria fixar uma versão específica e validar o hash do arquivo baixado antes de executá-lo

    • Então isso significa que atualização automática é impossível?

    • Acho que o critério mínimo é verificação de assinatura
      Se o software for atualizado com frequência suficiente, também haverá oportunidades suficientes para rotação de chave

    • No Windows, dá para usar um certificado de assinatura de código na ferramenta de build e deixar o sistema operacional validar o binário baixado
      Só que é preciso usar um servidor de timestamp na assinatura de código, senão ela quebra quando o certificado expira

    • Aqui eu diria que a verificação de hash é difícil por causa da natureza potencial de um ataque man-in-the-middle
      Se o atacante puder ver e alterar o conteúdo da requisição, a checagem de hash deixa de servir para algo além de confirmação de integridade

      De modo geral, parece que não se dá atenção suficiente, do ponto de vista de segurança, à forma como apps desktop fazem requisições de atualização automática ou checagem para domínios específicos
      Há cenários como o autor original deixar de renovar o domínio e ele acabar sendo tomado de forma maliciosa, mas ainda não encontrei uma boa solução para isso

  • Seria surpreendente se fosse possível saber quantas pessoas foram realmente afetadas por isso ao longo de cerca de 15 anos
    Fico pensando o quão importante foi a validação de SSL para um atacante que consegue se misturar na parte mais suspeita da internet
    Coisas demais “simplesmente funcionam” porque ninguém liga, e agora que isso ganhou visibilidade, a situação só pode piorar para quem não faz atualização automática

    • Provavelmente perto de 0
      Esse código servia para baixar o Python de python.org, e embora a exploração fosse possível, ela teria que ser bastante direcionada e já exigiria algum nível de acesso ao alvo
      Para explorar de outras formas, seria preciso algo como sequestrar o domínio python.org, e provavelmente todo mundo perceberia
    • Seria interessante saber quantas pessoas foram realmente afetadas ao longo desses cerca de 15 anos, mas pessoalmente acho que foi quase 0
      Se alguém foi afetado, provavelmente foi em ataques direcionados
    • Eu também diria 0
      Boa parte do texto parece inflada; há de fato algo problemático, mas a expressão “execução remota de código no qBittorrent” é tecnicamente correta, porém alarmista em excesso
    • Eu uso navegador para o que é de navegador, e só abro app de torrent quando quero baixar um arquivo .torrent diretamente
    • Pensei a mesma coisa
      Parece quase impossível obter dados reais, mas seria interessante se fosse possível ver isso
  • Se você já olhou o código do qBittorrent, sabe que era um código terrível
    Havia funções sem comentários por várias páginas, com espaçamento de linhas apertado, e aquilo parecia as anotações de prisão de um paciente psicótico injustamente encarcerado
    Mesmo na pequena parte que eu vi, algumas páginas comprimidas, não havia nenhuma checagem de valor de retorno

    Pelo que lembro, se um campo recebesse um valor correto de 3 letras em vez do valor correto habitual de 2 letras, o programa travava cerca de um minuto depois
    Há uns 20 anos eu já tinha programado em C++ por dinheiro duas vezes, e depois da mensagem do mantenedor do tipo “então vá olhar você mesmo”, rodei no depurador
    Cheguei ao ponto em que a GUI lia tanto o valor errado quanto o valor correto, e ao seguir aquele valor percebi que, de repente, -1 estava sendo passado para todo lado, e o programa simplesmente continuava por um bom tempo

    No fim, o lado executado com o valor errado travou em uma função bem distante, junto com uma mensagem de erro que parecia coisa de um paciente psicótico injustamente encarcerado
    Depois disso, um dos desenvolvedores reais do qBittorrent corrigiu aquilo na versão seguinte, mas, de todo modo, era esse o nível do código

  • Só consta “BUGFIX: Don't ignore SSL errors (sledgehammer999)”
    https://www.qbittorrent.org/news
    Pessoalmente, acho que deveria haver um aviso de segurança

  • Mesmo com a verificação correta de certificado, baixar e executar um executável remoto é, por definição, uma vulnerabilidade de execução remota de código
    O Syncthing também usa esse modelo; ele provavelmente verifica certificados, mas atualização automática sem supervisão é logicamente difícil de distinguir de um RAT/trojan

    • Literalmente não é isso
    • Tenho dificuldade em concordar com isso
      A parte da vulnerabilidade só existe quando um terceiro pode explorar
      Como de qualquer forma você precisa confiar no fornecedor do software, atualização automática por si só não é uma vulnerabilidade de execução remota de código
    • Não é fundamentalmente diferente de clicar em Yes em “Deseja atualizar para a versão mais recente?”
    • Como isso deve ser visto se as mesmas pessoas que disponibilizaram o programa original também fazem a atualização automática sem supervisão, ou se não for esse o caso?
  • Embora isso não tenha sido a causa direta desta vulnerabilidade, parece que aplicações como esta, que se comunicam com muitos nós potencialmente maliciosos, teriam muito a ganhar com segurança de memória
    Só que as implementações atuais parecem todas escritas em C++
    O texto também aborda esse tipo de possibilidade de vulnerabilidade no item 4

Até o Deluge, escrito em Python, depende do libtorrent, feito em C++
Não sei se existe um fork moderno do antigo cliente Azureus baseado em Java
Hoje em dia, muitos clientes BitTorrent separam a GUI do processo daemon que faz o processamento real dos torrents, então talvez dê para chegar a um bom equilíbrio entre segurança, desempenho e experiência do usuário fazendo o daemon em Java e conectando-o a uma GUI nativa

  • Mesmo procurando por alto, dá para achar algumas bibliotecas BitTorrent puras em Go

  • Existe o rqbit, escrito em Rust e sem dependência do libtorrent: https://github.com/ikatson/rqbit

  • Fazendo uma pergunta preguiçosa em vez de pesquisar por conta própria para fomentar a discussão: por onde se começaria para criar uma alternativa ao libtorrent?
    Também tenho curiosidade se já houve tentativas ou casos de sucesso, e se existem clientes realmente funcionais usando outras implementações

  • Especialmente nos itens mais para o fim, isso parece um pouco exagerado
    O item 1, “loader de executável malicioso com recurso oculto”, diz que o cliente baixa o Python de python.org via HTTPS
    Não é bom, e o fato de estar fixado em 3.12.4 também é um problema, mas não vejo um caminho claro de exploração que não exija tanto ataque man-in-the-middle quanto interação do usuário

    O item 2, “sequestro do navegador + download de executável”, diz que o cliente baixa um arquivo RSS via HTTPS e, sob certas condições, pergunta ao usuário se deve abrir a URL contida nesse arquivo
    É ainda menos arriscado que o item 1, e mesmo que se faça um ataque man-in-the-middle no usuário e o convença a clicar em “update”, no fim das contas só dá para mostrar uma página web

    O item 3, “injeção de URL arbitrária em feed RSS”, parece ser um caso em que o pesquisador confundiu o comportamento esperado do cliente RSS
    O item 4, “superfície de ataque da biblioteca de descompressão”, significaria que, se fosse possível encontrar uma vulnerabilidade no zlib, daria para fazer coisas muito piores do que atacar um cliente de torrent
    Descompressão de entrada é, em princípio, uma operação presumida como segura

    • A primeira coisa que me vem à cabeça é algo como um servidor HTTP que suporte compressão de stream

    • Sim
      Não quero soar negativo demais, mas parece que “pesquisadores” de segurança estão agarrando até possibilidades remotíssimas por um pouco de notoriedade
      Eu teria mais respeito se isso tivesse sido documentado com honestidade, mas a forma como foi feito aqui só causa incômodo

    • Se os erros de certificado não tivessem sido ignorados, esses itens teriam sido triviais
      Como o problema original é ignorar erros de SSL, na prática todos os downloads via HTTPS foram rebaixados a downloads via HTTP, e isso permite ataque mesmo sem man-in-the-middle

      Em outras palavras, a ausência de validação SSL deu aos revisores uma falsa sensação de segurança sobre URLs HTTPS

    • Concordo
      Chamar isso de “vulnerabilidade de execução remota de código” é um exagero absurdo

      Da próxima vez vão dizer que há uma “vulnerabilidade de execução remota de código” porque um navegador web permite baixar e executar programas de sites arbitrários que podem ou não ser seguros?
      Ou vão anunciar de novo que, se você vive num país autoritário, o governo pode fazer coisas ruins?

  • O qBittorrent é um cliente 1000 vezes mais rápido do que as outras opções mencionadas na matéria, então é chocante ver a qualidade dessas questões tão baixa

    • O Deluge também tem desempenho tão bom quanto o qBittorrent
      Quem entrega o desempenho é o libtorrent-rasterbar (libtorrent.org)
  • Para compilar e rodar a versão mais recente, https://github.com/userdocs/qbittorrent-nox-static é um script auxiliar razoável que usa Docker para gerar um binário estático
    Eu queria rodar o 5.0.0 usando o libtorrent 1.2, e esse script foi de longe o jeito mais fácil