2 puntos por GN⁺ 2024-11-02 | 1 comentarios | Compartir por WhatsApp
  • El DownloadManager de qBittorrent ignoró los errores de validación de certificados SSL durante unos 14 años y 6 meses, desde el 6 de abril de 2010 hasta el 12 de octubre de 2024, lo que convirtió varios flujos de descarga en una superficie de ataque en escenarios de interceptación de red
  • Este problema fue asignado como CVE-2024-51774, y su explotación requiere acceso MITM o spoofing de DNS
  • Se vieron afectadas las rutas que usan DownloadManager, como búsquedas, descarga de .torrent, feeds RSS y descarga de favicons, y podían aceptarse certificados vencidos o autofirmados
  • En Windows, el prompt de instalación de Python y el flujo RSS de verificación de actualizaciones pueden derivar en la descarga de ejecutables o en la manipulación de enlaces de actualización si se modifica la respuesta de una URL hardcodeada
  • Para los usuarios, es más seguro actualizar mediante una descarga manual directa de v5.0.1 desde el navegador que mediante el prompt de actualización dentro de la app

Más de 14 años de bypass de validación de certificados

  • La clase DownloadManager de qBittorrent venía ignorando todos los errores de validación de certificados SSL desde el commit 9824d86 del 6 de abril de 2010
  • El comportamiento predeterminado cambió en el commit 3d9e971 del 12 de octubre de 2024 para validar certificados
  • El primer release con parche es qBittorrent v5.0.1, publicado 2 días antes al momento de escribir el artículo
  • Este problema fue asignado como CVE-2024-51774
  • Las condiciones para explotarlo son acceso MITM o spoofing de DNS

La amplia superficie de ataque creada por DownloadManager

  • Como DownloadManager se usa ampliamente, se vieron afectadas búsquedas, descarga de .torrent, feeds RSS, descarga de favicons, etc.
  • Esas rutas podían aceptar certificados vencidos, certificados autofirmados o certificados que cumplían ambas condiciones
  • Las principales rutas afectadas se dividen en instalación de Python en Windows, actualizaciones de software, feeds RSS y superficie de ataque en bibliotecas de descompresión

Descarga de ejecutables en el flujo de instalación de Python en Windows

  • En Windows, si no hay instalado un Python suficientemente reciente, qBittorrent muestra una ventana que pregunta si se desea instalar o actualizar Python para usar plugins de búsqueda
  • Si el usuario hace clic en la opción predeterminada Yes o presiona Enter, se descarga el instalador de Python desde una URL hardcodeada de python.org
  • Después de descargarlo, qBittorrent renombra el archivo como .exe, lo ejecuta y, al finalizar, elimina el archivo temporal
  • Este comportamiento existe desde junio de 2015 hasta la actualidad y afecta desde v3.2.1 hasta v5.0.0
  • En variantes de otros sistemas operativos, si Python no existe o no es suficientemente reciente, se desactiva el widget de búsqueda, y no parece reproducirse el mismo comportamiento
  • El ejecutable puede guardarse, por ejemplo, en una ruta como C:\Users\_user_\AppData\Local\Temp\is-G61QK.tmp
  • Tal vez por el comportamiento de QProcess, pueden crearse dos hilos del ejecutable: solo uno termina y el otro puede quedar en estado sleeping

Manipulación de URL mediante el RSS de verificación de actualizaciones

  • Las versiones instaladas de qBittorrent para Windows o Linux realizan por defecto una verificación de actualizaciones al ejecutarse, salvo que se trate de un archivo appImage
  • La verificación de actualizaciones descarga un documento XML desde una URL RSS hardcodeada de Fosshub y parsea la información de releases del programa
  • Si en el XML encuentra una versión superior a la que está en ejecución, extrae la URL de actualización y existe un flujo que pregunta al usuario si desea visitar esa URL, sin filtrado ni validación adicional
  • Si el usuario acepta el prompt, esa URL se abre en el navegador predeterminado
  • El usuario espera recibir un archivo .exe en un contexto de confianza, porque el enlace fue proporcionado por el software
  • Si un atacante redirige a un sitio de intercambio de archivos como mediafire, el usuario puede recibir un ejecutable controlado por el atacante como si fuera una actualización
  • Como qBittorrent es open source, es fácil recompilar la versión más reciente tras agregarle funcionalidad de backdoor
  • Los desarrolladores proporcionan una clave para verificar la firma de los binarios, pero la protección solo funciona si el usuario realmente verifica y respeta los fallos de verificación

Feeds RSS e inyección de enlaces

  • Todos los feeds RSS que parsea la aplicación pasan por DownloadManager, por lo que pueden ser secuestrados
  • Las URL que visita la víctima pueden observarse y listarse, y las URL RSS tienden a ser estáticas y mantenerse por mucho tiempo
  • El elemento link de cada ítem se parsea directamente y puede descargarse si el usuario hace doble clic
  • Incluso sin manipulación MITM, una URL arbitraria insertada por el autor del feed al que está suscrito el usuario, o por un atacante que contamine el feed, puede abrirse con un solo doble clic
  • CVE-2019-13640 fue una vulnerabilidad que permitía ejecución remota de comandos mediante metacaracteres de shell en el nombre del torrent o en el parámetro actual de tracker, y el riesgo combinado aumenta porque un atacante MITM puede insertar datos maliciosos en el RSS

Descarga de la base de datos GeoIP y superficie de ataque en descompresión

  • Al ejecutarse, qBittorrent descarga automáticamente desde una URL hardcodeada y descomprime una base de datos MaxMind GeoIP binaria con extensión .gz
  • Si existe una vulnerabilidad en la descompresión con zlib, un atacante podría apuntar a esta superficie de ataque con un archivo arbitrario de hasta 64 MB
  • CVE-2022-37434, citado como ejemplo, es un buffer overflow Critical con CVSS 9.8 de 2022, pero no aplica aquí porque no se llama a la función inflateGetHeader()
  • El código que parsea la base de datos binaria MaxMind después de la descompresión está bien protegido a 2024, pero en el pasado era distinto y pudo haber habido superficie de ataque adicional
  • En un commit de la función gzip::decompress(), el búfer de destino pasó de una asignación estática en el stack a una asignación dinámica en el heap, y no era explotable porque había una comprobación antes de escribir

Escenarios de ataque automatizables

  • Como la URL del instalador de Python y la URL del feed RSS de actualizaciones están hardcodeadas, un script malicioso en un entorno MITM puede enumerar versiones vulnerables y atacarlas
  • La URL del feed RSS no tiene motivo para visitarse salvo cuando qBittorrent está en ejecución, por lo que puede usarse como huella del software
  • Al no haber validación de certificados, el atacante puede suplantar el servidor objetivo sin despliegues complejos de Man-On-The-Side como QUANTUM
  • Por la naturaleza de las URL hardcodeadas, es posible interceptar selectivamente solo las solicitudes no validadas de qBittorrent sin alertar a la víctima con fallos de conexión segura en el navegador u otras aplicaciones
  • Usando la opción -s de mitmproxy junto con un script de Python, se puede automatizar lo siguiente
    • Reemplazar el .exe de Python por un ejecutable arbitrario: RCE con un solo clic
    • Reemplazar automáticamente la URL del RSS de actualización de qBittorrent: secuestro del navegador/RCE, requiere una interacción moderada del usuario
    • Reemplazar todos o algunos enlaces específicos del visor RSS de qBittorrent: RCE hasta 2019, secuestro de descargas

Actualización y mitigaciones

  • Hay que actualizar a qBittorrent v5.0.1
  • Se recomienda actualizar mediante descarga manual directa desde el navegador, no mediante el prompt de actualización dentro de la app
  • Como alternativa, se pueden usar clientes que no tengan esta vulnerabilidad, como Deluge o Transmission
  • Es difícil descartar como un riesgo meramente teórico los ataques que requieren MITM, considerando la historia reciente y casos reales en algunos países
  • Hubo contacto con los mantenedores del repositorio, pero no se recibió respuesta sobre si tienen intención de emitir un aviso de seguridad en GitHub

1 comentarios

 
GN⁺ 2024-11-02
Opiniones de Hacker News
  • La clase DownloadManager de qBittorrent estuvo ignorando todos los errores de validación de certificados SSL en todas las plataformas durante 14 años y 6 meses, desde el commit 9824d86 del 6 de abril de 2010.
    Parece bastante grave.

  • No quiero minimizar esta vulnerabilidad, pero me parece casi un desastre que, en una ruta que permite ejecución remota de código, la única línea de defensa sea una combinación válida de certificado TLS y nombre de dominio.
    Como mínimo, si una aplicación descarga algún artefacto desde internet y lo ejecuta, debería fijarlo a una versión específica y verificar el hash del archivo descargado antes de ejecutarlo.

    • ¿Entonces eso significa que las actualizaciones automáticas son imposibles?

    • Creo que el mínimo debería ser la verificación de firmas.
      Si actualizas el software con suficiente frecuencia, también tendrás suficientes oportunidades para rotar claves.

    • En Windows se puede usar un certificado de firma de código en las herramientas de compilación y hacer que el sistema operativo verifique el binario descargado.
      Eso sí, para la firma de código hay que usar sí o sí un servidor de sellado de tiempo, para que no se rompa cuando caduque el certificado.

    • En este caso creo que la comprobación de hash es difícil por la naturaleza potencial de ataque de intermediario.
      Si el atacante puede ver y modificar el contenido de la solicitud, la comprobación de hash deja de servir salvo para verificar integridad.

      En general, la forma en que las apps de escritorio envían solicitudes de actualización automática o de comprobación a dominios específicos parece no recibir suficiente atención desde el punto de vista de seguridad.
      Hay escenarios como que el autor original deje de renovar el dominio y este sea tomado de forma hostil, y todavía no he encontrado una buena solución.

  • Sería sorprendente poder saber cuántas personas se vieron realmente afectadas por este problema durante los últimos casi 15 años.
    Me pregunto qué tan importante habrá sido la validación SSL para un atacante que pudiera mezclarse entre la multitud incluso en el lado algo turbio de internet.
    Demasiadas cosas “simplemente funcionan” porque a nadie le importa, y ahora que este problema salió a la luz, la situación solo puede empeorar para quienes no hagan actualización automática.

    • Probablemente algo cercano a 0.
      Este código se encargaba de descargar Python desde python.org, y aunque era explotable, tendría que haber sido bastante dirigido y probablemente ya requería cierto nivel de acceso al objetivo.
      Para explotarlo de otra forma haría falta algo como secuestrar el dominio python.org, lo que probablemente todos habrían notado.
    • Sería interesante saber cuántas personas se vieron realmente afectadas durante los últimos casi 15 años, pero personalmente creo que la cifra es casi 0.
      Si alguien fue afectado, lo más probable es que haya sido un ataque dirigido.
    • Yo también creo que 0.
      Gran parte del artículo se siente exagerada, y aunque es cierto que hay un problema, la expresión “ejecución remota de código en qBittorrent” es técnicamente correcta pero demasiado alarmista.
    • Para lo que se hace con un navegador web uso un navegador web, y solo abro la app de torrents cuando quiero descargar un archivo .torrent que obtuve directamente.
    • Pensé lo mismo.
      Conseguir datos reales parece casi imposible, pero sería interesante verlos si se pudiera.
  • Si alguna vez viste el código de qBittorrent, sabrás que era código espantoso.
    Funciones sin comentarios que se extendían por páginas, con líneas apretadas, y parecía el cuaderno escrito en prisión por un paciente psicótico encarcelado injustamente.
    Incluso en la pequeña parte que vi, unas pocas páginas comprimidas, no había ninguna comprobación de valores de retorno.

    Recuerdo que si en cierto campo entraba un valor válido de 3 letras en lugar del valor válido habitual de 2 letras, el programa se bloqueaba más o menos un minuto después.
    Había programado en C++ por dinero un par de veces unos 20 años antes, y después de recibir un mensaje del mantenedor diciendo “bueno, revíselo usted mismo”, lo corrí con un depurador.
    Llegué hasta el punto en la GUI donde se leían el valor incorrecto y el correcto, y al seguir ese valor, de pronto -1 se estaba pasando por todos lados, mientras el programa seguía avanzando como si nada durante un rato.

    Al final, la ejecución con el valor incorrecto se bloqueó en una función bastante lejana, con un mensaje de error que parecía de un paciente psicótico encarcelado injustamente.
    Después, uno de los desarrolladores reales de qBittorrent lo corrigió en la siguiente versión, pero, en fin, así era ese código.

  • Solo dice “BUGFIX: Don't ignore SSL errors (sledgehammer999)”.
    https://www.qbittorrent.org/news
    Personalmente creo que debería haber un aviso de seguridad.

  • Incluso con una validación correcta de certificados, descargar y ejecutar un ejecutable remoto es, por definición, una vulnerabilidad de ejecución remota de código.
    Syncthing también usa este método, y aunque probablemente sí valida certificados, las actualizaciones automáticas desatendidas son lógicamente difíciles de distinguir de un RAT/troyano.

    • Literalmente no lo es.
    • Me cuesta estar de acuerdo con esto.
      La parte de vulnerabilidad aparece cuando un tercero puede explotarla.
      De todos modos tienes que confiar en el proveedor del software, así que la actualización automática en sí misma no equivale a una vulnerabilidad de ejecución remota de código.
    • No es fundamentalmente distinto de hacer clic en Yes cuando te preguntan “¿Quieres actualizar a la última versión?”.
    • Si las mismas personas de las que descargaste el programa original también realizan la actualización automática desatendida, ¿cómo habría que verlo? ¿Y si no son las mismas?
  • Aunque no fue la causa directa de esta vulnerabilidad, aplicaciones como esta, que se comunican con muchos nodos potencialmente maliciosos, probablemente se beneficiarían mucho de la seguridad de memoria.
    Pero las implementaciones actuales parecen estar todas escritas en C++.
    El artículo también trata este tipo de posible vulnerabilidad en el punto 4.

Incluso Deluge, escrito en Python, depende de libtorrent, que está en C++
No sé si existe algún fork moderno del antiguo cliente Azureus basado en Java
Hoy en día muchos clientes BitTorrent separan la GUI del proceso demonio que se encarga del procesamiento real de torrents, así que si el demonio se hiciera en Java y se conectara a una GUI nativa, podría lograrse un equilibrio decente entre seguridad, rendimiento y experiencia de usuario

  • Buscando por encima, hay varias bibliotecas BitTorrent puras en Go

  • Existe rqbit, escrito en Rust y que no depende de libtorrent: https://github.com/ikatson/rqbit

  • Para debatir, y en vez de buscarlo yo mismo, voy con una pregunta perezosa: ¿por dónde habría que empezar para crear una alternativa a libtorrent?
    También me da curiosidad si hubo intentos o casos de éxito, y si existen clientes reales en funcionamiento que usen otra implementación

  • Especialmente hacia los últimos puntos, parece un poco exagerado
    El punto 1, “cargador de ejecutables maliciosos con función de ocultamiento”, se refiere a que el cliente descarga Python desde python.org mediante HTTPS
    No es ideal, y en particular también es un problema que esté hardcodeado a 3.12.4, pero no veo una ruta de explotación clara que no requiera tanto un ataque de intermediario como interacción del usuario

    El punto 2, “secuestro del navegador + descarga de ejecutable”, se refiere a que el cliente descarga un archivo RSS por HTTPS y, bajo ciertas condiciones, le pregunta al usuario si quiere abrir una URL dentro de ese archivo
    El riesgo es incluso menor que en el punto 1, y aunque hagas un ataque de intermediario al usuario y logres que haga clic en “update”, al final lo único que puedes mostrarle es una página web

    En el punto 3, “inyección de URL arbitrarias en feeds RSS”, parece que el investigador confundió el comportamiento esperado de un cliente RSS
    En el punto 4, “superficie de ataque de la biblioteca de descompresión”, si puedes encontrar una vulnerabilidad en zlib, puedes hacer cosas mucho peores que atacar un cliente torrent
    La descompresión de entradas es una operación que básicamente se asume segura

    • Lo primero que se me viene a la mente es algo como un servidor HTTP que soporte compresión por streaming

    • Correcto
      No quiero sonar demasiado negativo, pero parece que algunos “investigadores” de seguridad se aferran hasta a posibilidades muy remotas con tal de ganar un poco de notoriedad
      Si lo hubieran documentado con honestidad, lo habría respetado más; la forma en que lo hicieron aquí solo causa rechazo

    • Si no hubieran ignorado los errores de certificado, esos puntos habrían sido triviales
      Como el problema original está en ignorar los errores SSL, en la práctica todas las descargas HTTPS quedaron degradadas a descargas HTTP, y se pueden atacar incluso sin un ataque de intermediario

      Dicho de otro modo, la ausencia de verificación SSL les dio a los revisores una falsa sensación de seguridad respecto de las URL HTTPS

    • De acuerdo
      Llamar a esto una “vulnerabilidad de ejecución remota de código” es una exageración absurda

      ¿La próxima vez dirán que los navegadores web tienen una “vulnerabilidad de ejecución remota de código” porque permiten descargar y ejecutar programas desde sitios arbitrarios que pueden o no ser seguros?
      ¿O también van a anunciar como novedad que, si vives en un país autoritario, el gobierno puede hacer cosas malas?

  • qBittorrent es un cliente 1000 veces más rendidor que las otras opciones mencionadas en el artículo, así que me sorprende que la calidad de estos problemas sea tan baja

    • Deluge también rinde tan bien como qBittorrent
      Lo que aporta el rendimiento es libtorrent-rasterbar (libtorrent.org)
  • Si quieres compilar y ejecutar la versión más reciente, https://github.com/userdocs/qbittorrent-nox-static es un buen script auxiliar que compila un binario estático con Docker
    Quería ejecutar la 5.0.0 usando libtorrent 1.2, y este script fue, por lejos, lo más fácil