GnuTLS X.509 mit Codefehler bei der Zertifikatsverifizierung

Originalartikel von Virendra Bisht, Vulnerability Researcher

GnuTLS (GNU Transport Layer Security ist eine Implementierung der SSL-, TLS- und DTLS-Protokolle. Die Bibliothek bietet Anwendungen eine Möglichkeit, die Protokolle zu nutzen, ohne ihren eigenen Verschlüsselungscode aufsetzen zu müssen. Sie ist auf Sicherheit und Interoperabilität ausgerichtet und wird häufig anstelle anderer Bibliotheken eingesetzt, weil sie unter der GNU Lesser General Public License vertrieben wird.
Experten haben herausgefunden, dass der Überprüfungscode des Zertifikats GnuTLS X.509 bestimmte Fehlerkonditionen, die während des Prüfprozesses auftreten, nicht richtig behandelt. So meldet GnuTLS die erfolgreiche Überprüfung des Zertifikats, obwohl diese fehlgeschlagen ist. Das Ergebnis: Ungültige Zertifikate werden als echt akzeptiert.

Dieser Fehler kann schwerwiegende Folgen haben, weil GnuTLS in vielen Anwendungen und Softwarepaketen verwendet wird, einschließlich Exim, Weechat, Mutt, Lynx, CUPS und gnoMint. Auch für Webapplikationen, E-Mail-Programme und anderen Code wird die GNU-Bibliothek eingesetzt. Daher ist es schwierig, die Zahl der betroffenen Anwendungen zu ermitteln. Zu den Betriebssystemen, die GnuTLS unterstützen, gehören die folgenden:

  • Red Hat Enterprise Linux Desktop (v. 6)
  • Red Hat Enterprise Linux HPC Node (v. 6)
  • Red Hat Enterprise Linux Server (v. 6)
  • Red Hat Enterprise Linux Server AUS (v. 6.5)
  • Red Hat Enterprise Linux Server EUS (v. 6.5.z)
  • Red Hat Enterprise Linux Workstation (v. 6)
  • Ubuntu 12.10
  • Ubuntu 12.04 LTS
  • Ubuntu 10.04 LTS
  • openSUSE 11.4

Ein Angreifer kann ein speziell aufgesetztes ungültiges Sicherheitszertifikat nutzen, das dann von einer Anwendung (Browser, E-Mail-Client, Feed Reader etc.), die GnuTLS nutzt, akzeptiert wird. Als Folge können vertrauliche Informationen veröffentlicht werden und Angreifer können unter Umständen über die Ausnutzung einer weiteren Schwachstelle die Kontrolle über das System des Opfers übernehmen.

Der X.509 Code

Die X.509-Protokolle beruhen auf einem hierarchisch aufgebauten Vertrauensmodell. Certification Authorities (CAs) zertifizieren die Einheiten. Üblicherweise gibt es mehr als eine CA, und sie können außerdem weitere CAs zertifizieren, die dann ebenfalls Zertifikate ausstellen. Das bedeutet, man muss für sichere Kommunikationswege einer oder mehreren CAs vertrauen, und nur Zertifikate, die diese ausstellen, werden akzeptiert.

Der Grund für die Probleme liegt in einem einfachen Coding-Fehler, der wohl seit vielen Jahren in einigen Anwendungen vorhanden ist, einschließlich in Linux-Betriebssystemen. Der Fehler umfasst die für die X.509-Zertifikatsüberprüfung zuständigen Bibliotheksfunktionen von GnuTLS.

Das Hauptproblem liegt in der goto-Anweisung mit einer nicht initialisierten Variablen. Die Anweisung ist berüchtigt und wurde von vielen Sicherheitsforschern kritisiert. In diesem Fall kann der Verifizierungsprozess kurzgeschlossen werden, falls die goto-Anweisung unter bestimmten fehlerhaften Bedingungen ausgeführt wird. Damit lässt sich der Prozess der Zertifikatsauthentisierung umgehen und die Zertifikate als verifiziert präsentieren.

In der verify.c-Funktion gibt check_if_ca “true” oder eher 1 zurück, wenn das Zertifikat echt ist oder von einer CA ausgegeben wurde. Der Wert sollte Null sein, falls das Zertifikat nicht echt ist oder nicht von einer CA ausgegeben wurde. Einige wenige andere Funktionen geben einen negativen Wert aus, wenn sie fehlschlagen. In den meisten Programmiersprachen bedeutet 0 „falsch“ und jeder andere Wert (Integer) bedeutet „richtig“ (true). So validiert gnutls_x509_crt_verify nicht gültige Zertifikate als echt.

In C gibt es die folgenden Rückgabe-Codes für das Handling von Programmierfehlern:

  1. Wert Null für Erfolg und Nicht-Null (oder weniger) für Fehlschlag ausgeben.
  2. Code explizit ausgeben und später die Werte prüfen (z.B. “ja”, “nein” etc.)
  3. Gibt 1 für Erfolg und 0 für Fehlschlag.

Anscheinend werden für GnuTLS Methode 1 und 3 miteinander als Rückgabe-Codes genutzt. Als Fix für den Fehler wird “goto cleanup” durch “goto fail” ersetzt:

Label fail is defined as under
Fail:
result = 0;

Vor dem Bug-Fix ist das Cleanup-Label wie unter Cleanup definiert:

gnutls_datum_t cert_signed_data = { NULL, 0 };
gnutls_datnum_t cert_signature = { NULL, 0 };
gnutls_x509_crt_t issuer = NULL;
int issuer_version, result;

Nach dem Bug-Fix ist das Cleanup-Label wie unter Cleanup geändert worden:

gnutls_datum_t cert_signed_data = { NULL, 0 };
gnutls_datnum_t cert_signature = { NULL, 0 };
gnutls_x509_crt_t issuer = NULL;
int issuer_version, result=0;

Der Ausschnitt zeigt einen Vergleich:


Bild 1. Screenshot der korrigierten Return-Codes (Quelle Gitorious)

Angriffsmethoden

Ein Angreifer könnte diese Probleme in mehrfacher Hinsicht ausnützen, je nach Verwendung der angreifbaren Bibliothek. Der Fehler lässt sich für Man-in-the-Middle-Angriffe missbrauchen. Versucht ein Opfer, sich bei einer Site anzumelden, kann der Angreifer sein eigenes Zertifikat präsentieren und vorgeben, die Site zu sein. Das falsche Zertifikat besteht den Überprüfungsprozess und wird als authentisch angenommen. So kann der Angreifer dann vertrauliche Daten abfangen. Solche Angriffe sind hocheffektiv und häufig schwierig zu entdecken.

Ein Angreifer könnte auch seinen eigenen Webserver mit einigen Webanwendungen hosten, die ein gefälschtes Zertifikat haben und vorgeben, eine bestimmte Site zu sein. Über Social Engineering-Techniken kann er diese Lücke ausnutzen.

Gegenmaßnahmen

GnuTLS-Entwickler haben ein Advisory dazu veröffentlicht. Jede Anwendung, die nicht aktuell gepatchte Versionen der Überprüfungsbibliotheken für digitale Zertifikate nutzt, ist für diesen Fehler anfällig. Nutzern von GnuTLS wird empfohlen, auf ddie folgende Version zu aktualisieren:

  • GnuTLS version (3.2.12 oder 3.1.22)

Sie können auch den Patch für GnuTLS 2.12.x aufspielen. Alle Anwendungen, die einen Link zur GnuTLS-Bibliothek haben, müssen nach dem Update neu gestartet werden.

Dank auch an Nikos Mavrogiannopoulos vom Red Hat Security Technologies Team für die Entdeckung des Fehler.

 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*