Wenn sich ein Zufall ausrechnen lässt, führt das meist zu Problemen, zumindest bei Sicherheitssoftware. Ein solches Problem betrifft jetzt die weitverbreitete Libcurl.
Curl (Client for URLs; in Langfassung: Curl URL Request Library, [1]) ist ein weitverbreitetes Programm zum Übertragen von Dateien. Dabei unterstützt es viele Protokolle wie etwa HTTP, HTTPS, FTP, FTPS, DICT, LDAP, SMB, IMAP, SCP, RTMP. Im Unterschied zu »wget« lädt Curl nicht nur Daten herunter, sondern auch hoch.
Curl kann auch mit komplizierteren Protokollen und Verfahren wie SSL-Zertifikaten, HTTP Post, HTTP Put, HTTP-Form-basierten Uploads und User-/Password-Authentifikation umgehen. Die Libcurl-Bibliothek implementiert die gesamte Funktionalität, zahlreiche Applikation verwenden sie.
Einige der Verfahren benötigen Zufallszahlen. Das betrifft zum Beispiel die Digest-Authentification-Prozedur. Sie wendet eine MD5-Krypto-Hashfunktion auf den Benutzernamen und das Passwort an, um den Benutzer zu authentifizieren. Die verwendet einen so genannten Nonce-Wert, den die interne Libcurl-Zufallsfunktion generiert. Dieser Ansatz ist notwendig, um Replay-Attacken zu verhindern, die darauf basieren, dass ein Angreifer den gesendeten Hashwert abhört und später erneut an den Server zur Authentifikation sendet.
Dieses Szenario wäre immer möglich, solange der Angreifer Zugriff auf die Netzwerkverbindung hat. Um dieser Sicherheitslücke vorzubeugen, verknüpft die Software den zufälligen Nonce-Wert mit dem Passwort, sodass ein einmal abgehörter Hashwert nutzlos ist. Neben der Digest-Authentifikation gibt es noch weitere Protokolle, die Zufallszahlen benötigen. Dazu gehört unter anderem die NTLM-Authentifikation, die auch bei Samba und Squid zum Einsatz kommt. NTLM ist ein Challenge-Response-Verfahren, bei dem die Challenge auch wieder eine Zufallszahl ist.
Aus diesen Gründen ist es sehr wichtig, dass die Libcurl-Bibliothek selbst gute Pseudo-Zufallszahlen erzeugen kann, denn davon hängt die Sicherheit bei der Datenübertragung mit den verschiedenen Verfahren ab. Zum Generieren der Zufallszahlen verwendet Libcurl die »randit()«-Funktion, die in der »lib/rand.c«-Datei implementiert ist.
Genau hier hat sich jedoch ein Programmierfehler [2] eingeschlichen. Im relevanten C-Code findet sich folgende Zeile:
result = Curl_ssl_random(data, (unsigned char *)&rnd, sizeof(rnd));
Sie soll die zu generierende Zufallszahl in die Unsigned-Int-Variable »rnd« schreiben. Diese Variable ist in den Argumenten der »randit()«-Funktion enthalten:
static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
Hier übergibt der Programmierer einen Zeiger auf »rnd«. An dieser Speicherposition liegt dann also die generierte Zufallszahl.
Beim genaueren Betrachten der beiden Zeilen fällt aber selbst ungeübten C-Programmieren auf, dass bei der Implementation etwas gründlich danebengeht: Statt einfach den Zeiger an »Curl_ssl_random()« zu übergeben, wird ein Zeiger auf den Zeiger – nämlich »&rnd« – übergeben. Im Ergebnis wird die Zufallszahl an eine völlig falsche Speicherstelle geschrieben und der Wert der Rnd-Variablen ist dadurch eben nicht mehr zufällig. Das Ende vom Lied ist: Angreifer könnten sich unter Umständen unberechtigt authentifizieren.
Betroffen von diesem Problem ist die Libcurl-Version 7.52.0. Viele Applikationen bedienen sich der Libcurl-Bibliothek, ein baldiges Update ist erforderlich. (jcb)
Infos
- Curl: https://curl.haxx.se
- Fehler in der Libcurl; https://curl.haxx.se/docs/adv_20161223.html





