- Der DownloadManager von qBittorrent ignorierte vom 6. April 2010 bis zum 12. Oktober 2024 rund 14 Jahre und 6 Monate lang Fehler bei der SSL-Zertifikatsprüfung, wodurch in Situationen mit abgefangenem Netzwerkverkehr mehrere Download-Abläufe zur Angriffsfläche wurden
- Das Problem wurde als CVE-2024-51774 erfasst; für eine Ausnutzung ist MITM-Zugriff oder DNS-Spoofing erforderlich
- Betroffen waren Pfade, die den DownloadManager nutzen, etwa Suche,
.torrent-Downloads, RSS-Feeds und favicon-Downloads; auch abgelaufene oder selbstsignierte Zertifikate konnten akzeptiert werden - Die Python-Installationsaufforderung unter Windows und der RSS-Ablauf zur Update-Prüfung können bei veränderten Antworten von hartcodierten URLs zum Download ausführbarer Dateien oder zur Manipulation von Update-Links führen
- Für Nutzer ist es sicherer, v5.0.1 direkt manuell im Browser herunterzuladen und zu aktualisieren, statt die Update-Aufforderung innerhalb der App zu verwenden
Seit über 14 Jahren bestehende Umgehung der Zertifikatsprüfung
- Die Klasse DownloadManager von qBittorrent ignorierte seit dem Commit
9824d86vom 6. April 2010 alle Fehler bei der SSL-Zertifikatsprüfung - Das Standardverhalten wurde mit dem Commit
3d9e971vom 12. Oktober 2024 auf Zertifikatsprüfung umgestellt - Das erste Patch-Release war die qBittorrent v5.0.1, die zum Zeitpunkt des Artikels zwei Tage zuvor erschienen war
- Das Problem wurde als CVE-2024-51774 erfasst
- Die Voraussetzungen für eine Ausnutzung sind MITM-Zugriff oder DNS-Spoofing
Große Angriffsfläche durch den DownloadManager
- Da der DownloadManager breit eingesetzt wird, waren Suche,
.torrent-Downloads, RSS-Feeds, favicon-Downloads und weitere Bereiche betroffen - Diese Pfade konnten abgelaufene Zertifikate, selbstsignierte Zertifikate oder Zertifikate, auf die beides zutraf, akzeptieren
- Die wichtigsten betroffenen Pfade lassen sich in Windows-Python-Installation, Software-Updates, RSS-Feeds und Angriffsfläche in der Dekomprimierungsbibliothek einteilen
Download ausführbarer Dateien im Windows-Python-Installationsablauf
- Wenn unter Windows keine ausreichend aktuelle Python-Version installiert ist, zeigt qBittorrent für die Nutzung von Such-Plugins ein Fenster an, das zur Installation oder Aktualisierung von Python auffordert
- Klickt der Nutzer auf das standardmäßig ausgewählte Yes oder drückt Enter, lädt qBittorrent die Python-Installationsdatei von einer hartcodierten
python.org-URL herunter - Nach dem Download benennt qBittorrent die Datei in
.exeum, führt sie aus und löscht nach Abschluss die temporäre Datei - Dieses Verhalten existiert seit Juni 2015 bis heute und betrifft
v3.2.1bisv5.0.0 - Bei Varianten für andere Betriebssysteme wird das Such-Widget deaktiviert, wenn Python fehlt oder nicht ausreichend aktuell ist; dasselbe Verhalten scheint dort nicht reproduzierbar zu sein
- Die ausführbare Datei kann beispielsweise unter einem Pfad wie
C:\Users\_user_\AppData\Local\Temp\is-G61QK.tmpgespeichert werden - Möglicherweise aufgrund des Verhaltens von
QProcesskönnen zwei Threads der ausführbaren Datei entstehen, von denen nur einer beendet wird, während der andere im sleeping-Zustand verbleibt
URL-Manipulation über den RSS-Feed der Update-Prüfung
- Installierte Windows- oder Linux-Versionen von qBittorrent führen beim Start standardmäßig eine Update-Prüfung aus, sofern es sich nicht um eine
appImage-Datei handelt - Die Update-Prüfung lädt ein XML-Dokument von einer hartcodierten Fosshub-RSS-URL herunter und parst daraus Informationen zu Programm-Releases
- Wenn im XML eine höhere Version als die aktuell ausgeführte gefunden wird, wird eine Update-URL extrahiert; es gibt einen Ablauf, bei dem der Nutzer ohne gesonderte Filterung oder Prüfung gefragt wird, ob er diese URL besuchen möchte
- Akzeptiert der Nutzer die Aufforderung, wird die URL im Standardbrowser geöffnet
- Der Nutzer erwartet im Vertrauenskontext eines von der Software bereitgestellten Links eine
.exe-Datei - Leitet ein Angreifer auf eine Filesharing-Seite wie mediafire, kann der Nutzer eine vom Angreifer kontrollierte ausführbare Datei wie ein Upgrade herunterladen
- Da qBittorrent Open Source ist, lässt sich leicht eine Backdoor-Funktion in die aktuelle Version einbauen und diese neu kompilieren
- Die Entwickler stellen zwar Schlüssel zur Prüfung von Binärsignaturen bereit, doch Schutz entsteht nur, wenn Nutzer tatsächlich prüfen und Prüfungsfehler respektieren
RSS-Feeds und Link-Injektion
- Alle von der Anwendung geparsten RSS-Feeds laufen über den DownloadManager und können daher hijacked werden
- Die von einem Opfer besuchten URLs können beobachtet und katalogisiert werden; RSS-URLs sind ihrer Natur nach statisch und bleiben lange bestehen
- Das
link-Element jedes Eintrags wird direkt geparst und kann heruntergeladen werden, wenn der Nutzer doppelklickt - Auch ohne MITM-Manipulation kann eine beliebige URL, die ein Autor oder ein Angreifer mit Feed-Poisoning in einen vom Nutzer abonnierten RSS-Feed einfügt, mit einem einzigen Doppelklick geöffnet werden
- CVE-2019-13640 war eine Schwachstelle, die Remote Code Execution über Shell-Metazeichen im Torrent-Namen oder im aktuellen tracker-Parameter erlaubte; da ein MITM-Angreifer bösartige Daten in RSS einfügen kann, steigt das Kombinationsrisiko
Download der GeoIP-Datenbank und Angriffsfläche beim Entpacken
- qBittorrent lädt beim Start standardmäßig automatisch eine binäre MaxMind-GeoIP-Datenbank mit der Erweiterung
.gzvon einer hartcodierten URL herunter und entpackt sie - Falls es eine Schwachstelle in der zlib-Dekomprimierung gibt, kann ein Angreifer diese Angriffsfläche mit einer beliebigen Datei von bis zu 64 MB anvisieren
- Die als Beispiel genannte CVE-2022-37434 ist ein Critical-Buffer-Overflow aus dem Jahr 2022 mit CVSS 9.8, greift hier aber nicht, weil die Funktion
inflateGetHeader()nicht aufgerufen wird - Der Code, der nach dem Entpacken die binäre MaxMind-Datenbank parst, ist Stand 2024 gut geschützt, war es in der Vergangenheit jedoch nicht; zusätzliche Angriffsflächen könnten vorhanden gewesen sein
- In einem Commit der Funktion
gzip::decompress()wurde der Zielpuffer von statischer Allokation auf dem Stack auf dynamische Allokation auf dem Heap umgestellt; wegen einer Prüfung vor dem Schreiben war dies jedoch nicht ausnutzbar
Automatisierbare Angriffsszenarien
- Da sowohl die URL der Python-Installationsdatei als auch die URL des Update-RSS-Feeds hartcodiert sind, kann ein bösartiges Skript in einer MITM-Umgebung verwundbare Versionen auflisten und angreifen
- Die RSS-Feed-URL muss außerhalb eines laufenden qBittorrent nicht besucht werden und kann daher als Software-Fingerprint dienen
- Da keine Zertifikatsprüfung stattfindet, kann ein Angreifer den Zielserver spoofen, ohne eine komplexe Man-On-The-Side-Auslieferung wie QUANTUM zu benötigen
- Aufgrund der hartcodierten URLs kann ein Angreifer gezielt nur die ungeprüften Anfragen von qBittorrent abfangen, ohne das Opfer durch fehlgeschlagene sichere Verbindungen im Browser oder in anderen Anwendungen zu warnen
- Mit der Option
-svon mitmproxy zusammen mit einem Python-Skript ist folgende Automatisierung möglich- Ersetzen der Python-
.exedurch eine beliebige ausführbare Datei: RCE mit einem einzigen Klick - Automatisches Ersetzen der URL im qBittorrent-Update-RSS: Browser-Hijacking/RCE, mittlere Nutzerinteraktion erforderlich
- Ersetzen aller oder bestimmter Links im qBittorrent-RSS-Viewer: RCE bis 2019, Download-Hijacking
- Ersetzen der Python-
Upgrade und Workarounds
- Es sollte auf qBittorrent v5.0.1 aktualisiert werden
- Für das Upgrade wird empfohlen, nicht die Update-Aufforderung innerhalb der App zu verwenden, sondern direkt manuell über den Browser herunterzuladen
- Alternativ können Clients wie Deluge oder Transmission verwendet werden, die diese Schwachstelle nicht haben
- Angriffe, die MITM erfordern, lassen sich nicht einfach als rein theoretisches Risiko abtun; jüngere Geschichte und praktische Beispiele in einigen Ländern müssen berücksichtigt werden
- Es gab Kontakt mit den Repository-Maintainern, aber keine Antwort darauf, ob beabsichtigt ist, ein GitHub Security Advisory zu veröffentlichen
1 Kommentare
Meinungen auf Hacker News
Die Klasse DownloadManager von qBittorrent hat seit Commit 9824d86 vom 6. April 2010 über 14 Jahre und 6 Monate hinweg auf allen Plattformen sämtliche Fehler bei der SSL-Zertifikatsprüfung ignoriert.
Das wirkt ziemlich gravierend.
Auffällig ist, dass das kein Bug war, sondern ein „Feature“.
void downloadThread::ignoreSslErrors(QNetworkReply* reply,QList errors) {
// Ignore all SSL errors
reply->ignoreSslErrors(errors);
}
https://github.com/qbittorrent/qBittorrent/commit/9824d86a3c...
Ich will diese Schwachstelle nicht verharmlosen, aber bei einem Pfad, der Remote Code Execution ermöglicht, die Kombination aus gültigem TLS-Zertifikat und Domainname als einzige Verteidigungslinie zu nutzen, ist meiner Meinung nach nahezu katastrophal.
Wenn eine Anwendung Artefakte aus dem Internet herunterlädt und ausführt, sollte sie mindestens auf eine bestimmte Version pinnen und vor der Ausführung den Hash der heruntergeladenen Datei prüfen.
Heißt das dann, dass automatische Updates unmöglich sind?
Der Mindeststandard sollte meiner Meinung nach Signaturprüfung sein.
Wenn man Software ausreichend häufig aktualisiert, gibt es auch genügend Gelegenheiten für einen Schlüsselwechsel.
Unter Windows kann man in den Build-Tools ein Code-Signing-Zertifikat verwenden und das Betriebssystem die heruntergeladene Binärdatei prüfen lassen.
Allerdings muss man beim Code Signing unbedingt einen Timestamp-Server verwenden, damit es nach Ablauf des Zertifikats nicht kaputtgeht.
In diesem Fall halte ich Hash-Prüfungen wegen der möglichen Man-in-the-Middle-Angriffe für schwierig.
Wenn ein Angreifer die Anfrage sehen und verändern kann, ist eine Hash-Prüfung außer zur Integritätsprüfung nutzlos.
Dass Desktop-Apps automatische Updates oder Prüfanforderungen an bestimmte Domains senden, bekommt aus Sicherheitssicht insgesamt wohl nicht genug Aufmerksamkeit.
Es gibt auch Szenarien, in denen der ursprüngliche Autor die Domain nicht mehr verlängert und sie feindlich übernommen wird; dafür habe ich bisher noch keine gute Lösung gesehen.
Es wäre erstaunlich, herausfinden zu können, wie viele Menschen in den vergangenen rund 15 Jahren tatsächlich von diesem Problem betroffen waren.
Ich frage mich, wie wichtig SSL-Prüfung für einen Angreifer war, der sich selbst in den etwas zwielichtigeren Ecken des Internets in der Masse verstecken kann.
Der Grund, warum so vieles „einfach funktioniert“, ist, dass sich niemand darum kümmert; und jetzt, da dieses Problem Aufmerksamkeit bekommt, kann es für Leute, die keine automatischen Updates machen, nur schlimmer werden.
Dieser Code war dafür zuständig, Python von python.org herunterzuladen, und eine Ausnutzung war zwar möglich, müsste aber ziemlich gezielt sein und hätte wohl bereits ein gewisses Maß an Zugriff auf das Ziel erfordert.
Um es anders auszunutzen, bräuchte man so etwas wie eine Übernahme der Domain python.org, was wahrscheinlich allen aufgefallen wäre.
Wenn jemand betroffen war, dann wahrscheinlich meist durch gezielte Angriffe.
Ein großer Teil des Artikels fühlt sich aufgebauscht an; ja, da stimmt etwas nicht, aber die Formulierung „qBittorrent Remote Code Execution“ ist zwar technisch korrekt, aber übermäßig alarmistisch.
Reale Daten zu bekommen scheint nahezu unmöglich, aber es wäre interessant, sie zu sehen.
Wenn man sich den qBittorrent-Code schon einmal angesehen hat, weiß man, dass es wirklich furchtbarer Code war.
Funktionen ohne Kommentare gingen seitenlang weiter, die Zeilenabstände waren dicht gedrängt, und es sah aus wie Gefängnisnotizen eines zu Unrecht eingesperrten psychotischen Patienten.
Schon in dem kleinen Teil, den ich gesehen habe, ein paar kompakte Seiten, wurden Rückgabewerte überhaupt nicht geprüft.
Ich erinnere mich, dass das Programm etwa eine Minute später abstürzte, wenn in einem Feld statt des üblichen korrekten zweistelligen Werts ein korrekter dreistelliger Wert stand.
Vor etwa 20 Jahren habe ich zweimal gegen Bezahlung in C++ programmiert, und nachdem ich von einem Maintainer die Nachricht „Dann schauen Sie doch selbst einmal nach“ bekommen hatte, habe ich es im Debugger laufen lassen.
Ich kam bis zu der Stelle, an der in der GUI der falsche und der richtige Wert gelesen wurden; als ich den Wert weiterverfolgte, wurde plötzlich überall -1 weitergereicht, und das Programm lief eine Weile einfach weiter.
Am Ende stürzte der Lauf mit dem falschen Wert in einer ziemlich weit entfernten Funktion mit einer Fehlermeldung ab, die wieder wie von einem zu Unrecht eingesperrten psychotischen Patienten wirkte.
Später hat einer der tatsächlichen qBittorrent-Entwickler das in der nächsten Version behoben, aber so war dieser Code nun einmal.
Es heißt nur: „BUGFIX: Don't ignore SSL errors (sledgehammer999)“.
https://www.qbittorrent.org/news
Meiner Meinung nach sollte es dazu eine Sicherheitsmeldung geben.
Selbst bei korrekter Zertifikatsprüfung ist das Herunterladen und Ausführen einer entfernten ausführbaren Datei per Definition eine Remote-Code-Execution-Schwachstelle.
Syncthing macht das ebenfalls so; vermutlich prüft es Zertifikate, aber unbeaufsichtigte automatische Updates sind logisch schwer von einem RAT/Trojaner zu unterscheiden.
Der Teil mit der Schwachstelle entsteht, wenn Dritte sie ausnutzen können.
Da man dem Softwareanbieter ohnehin vertrauen muss, ist ein automatisches Update selbst nicht gleich eine Remote-Code-Execution-Schwachstelle.
Auch wenn das nicht die direkte Ursache dieser Schwachstelle war: Solche Anwendungen, die mit vielen potenziell bösartigen Nodes kommunizieren, würden wohl stark von Memory Safety profitieren.
Die aktuellen Implementierungen scheinen jedoch alle in C++ geschrieben zu sein.
Der Artikel behandelt diese Art möglicher Schwachstelle auch in Punkt 4.
Sogar Deluge, das in Python geschrieben ist, hängt von libtorrent in C++ ab.
Ich weiß nicht, ob es einen modernen Fork des früheren Java-basierten Azureus-Clients gibt.
Viele BitTorrent-Clients trennen heutzutage die GUI von einem Daemon-Prozess, der die eigentliche Torrent-Verarbeitung übernimmt. Wenn man also den Daemon in Java baut und ihn mit einer nativen GUI verbindet, könnte das einen brauchbaren Kompromiss zwischen Sicherheit, Performance und User Experience ergeben.
Schon eine grobe Suche zeigt, dass es ein paar reine Go-BitTorrent-Bibliotheken gibt.
Es gibt rqbit, geschrieben in Rust und ohne Abhängigkeit von libtorrent: https://github.com/ikatson/rqbit
Als faule Frage statt eigener Recherche für die Diskussion: Wo müsste man anfangen, wenn man eine Alternative zu libtorrent bauen wollte?
Mich würde auch interessieren, ob es Versuche oder Erfolgsgeschichten gab und ob es tatsächlich funktionierende Clients gibt, die eine andere Implementierung verwenden.
Besonders je weiter es nach hinten geht, wirken die Punkte etwas übertrieben.
Punkt 1, „Malicious Executable Loader mit Tarnfunktion“, bedeutet, dass der Client per HTTPS Python von python.org herunterlädt.
Das ist nicht gut, und vor allem ist auch problematisch, dass es hart auf 3.12.4 codiert ist, aber ich sehe keinen klaren Ausnutzungspfad, der weder einen Man-in-the-Middle-Angriff noch Nutzerinteraktion erfordert.
Punkt 2, „Browser-Hijacking + Download einer ausführbaren Datei“, bedeutet, dass der Client per HTTPS eine RSS-Datei herunterlädt und den Nutzer unter bestimmten Bedingungen fragt, ob eine URL aus dieser Datei geöffnet werden soll.
Das Risiko ist noch geringer als bei Punkt 1, und selbst wenn man den Nutzer per Man-in-the-Middle angreift und dazu bringt, auf „update“ zu klicken, kann man am Ende nur eine Webseite anzeigen lassen.
Punkt 3, „Einschleusen beliebiger URLs in RSS-Feeds“, scheint darauf zu beruhen, dass der Forscher das erwartete Verhalten eines RSS-Clients verwechselt hat.
Punkt 4, „Angriffsfläche in der Dekomprimierungsbibliothek“, gilt: Wenn man eine zlib-Schwachstelle finden kann, kann man sehr viel Schlimmeres tun, als einen Torrent-Client anzugreifen.
Eingabedekomprimierung gilt grundsätzlich als eine Operation, von der man annimmt, dass sie sicher ist.
Mir fallen sofort Dinge wie HTTP-Server ein, die Stream-Komprimierung unterstützen.
Stimmt.
Ich will nicht zu negativ klingen, aber es wirkt, als würden Sicherheits-„Forscher“ selbst extrem unwahrscheinliche Möglichkeiten aufgreifen, um ein wenig Aufmerksamkeit zu bekommen.
Wenn sie es ehrlich dokumentiert hätten, hätte ich mehr Respekt davor gehabt; die Art hier sorgt eher für Stirnrunzeln.
Wenn Zertifikatsfehler nicht ignoriert worden wären, wären diese Punkte belanglos gewesen.
Da das ursprüngliche Problem darin besteht, SSL-Fehler zu ignorieren, wurden in der Praxis alle HTTPS-Downloads zu HTTP-Downloads herabgestuft, und ein Angriff ist sogar ohne Man-in-the-Middle möglich.
Anders gesagt: Wegen der fehlenden SSL-Prüfung vermittelten die HTTPS-URLs den Reviewern ein falsches Gefühl von Sicherheit.
Einverstanden.
Das als „Remote-Code-Execution-Schwachstelle“ zu bezeichnen, ist absurd übertrieben.
Heißt es als Nächstes, Webbrowser hätten eine „Remote-Code-Execution-Schwachstelle“, weil sie es erlauben, Programme von beliebigen Websites herunterzuladen und auszuführen, die sicher sein können oder auch nicht?
Oder wird als Nächstes neu verkündet, dass Regierungen schlimme Dinge tun können, wenn man in einem autoritären Staat lebt?
qBittorrent ist ein Client, der 1000-mal performanter ist als die anderen im Artikel genannten Alternativen; es ist schockierend, dass die Qualität dieser Probleme so niedrig ist.
Die Performance kommt von libtorrent-rasterbar (libtorrent.org).
Wenn man die neueste Version kompilieren und ausführen will, ist https://github.com/userdocs/qbittorrent-nox-static ein brauchbares Hilfsskript, das per Docker statische Binaries baut.
Ich wollte 5.0.0 mit libtorrent 1.2 ausführen, und dieses Skript war mit Abstand der einfachste Weg.