Unternehmensdaten sind oft ein Geschäftsgeheimnis. Das Auslaufen kann zu einem Schlag auf den Ruf, finanziellen Verlusten oder sogar zum Bankrott führen. Daher müssen die Sicherheitsanforderungen für ein B2B-Produkt sehr hoch sein. Bei der Erstellung eines neuen Produkts - Corporate Mail Mail.ru - haben wir dem Thema Sicherheit besondere Aufmerksamkeit gewidmet.
Corporate Mail Mail.ru ist eine lokale Version der bekannten B2C-Mail Mail.ru. Im Vergleich dazu enthält es eine Reihe von Modifikationen, um in einer neuen Umgebung zu arbeiten - der Kundenschaltung.
Um die Sicherheit unserer Kunden zu gewährleisten, haben wir uns entschlossen, ein Audit in einem Drittunternehmen durchzuführen und alle festgestellten Mängel zu beheben, bevor wir das Produkt auf den Markt bringen. Zu diesem Zweck wandten sie sich an eines der renommiertesten Unternehmen im Bereich der Informationssicherheit - die digitale Sicherheit.
Die Prüfungsergebnisse liegen unter dem Schnitt.
Remotecodeausführung in uWSGI
Es gibt verschiedene Frameworks zum Erstellen von Python-Webanwendungen. In der Regel wird die Python Web Server Gateway-Schnittstelle (WSGI) für die Kommunikation zwischen der Webanwendung und dem Webserver verwendet. Darüber hinaus können Sie mit WSGI Middleware-Komponenten implementieren.
Um die Kommunikation zwischen einer Python-Webanwendung und einem Webserver wie Apache oder Nginx zu standardisieren, wurde PEP 0333 entwickelt, gefolgt von PEP 3333, das die WSGI-Schnittstelle beschreibt. Wir werden uns nicht mit der Funktionsweise von WSGI befassen, sondern Ihnen einen beliebten Server vorstellen, der die WSGI-Schnittstelle unterstützt - uWSGI.
Der uWSGI-Server kann sowohl im normalen Webservermodus als auch im "WSGI-Modus" arbeiten und Daten mit einem anderen Webserver wie Nginx austauschen. Gleichzeitig verwendet Nginx das gleichnamige Binärprotokolluwsgi , das aufgrund seiner umfangreichen Funktionalität für Cyberkriminelle interessant ist. Bei der Analyse der "Interna" der Lösung wurde ein uWSGI-Server gefunden, auf den alle internen Komponenten des Produkts Zugriff hatten.
Das Problem war, dass das uwsgi-Protokoll sogenannte magische Variablen verwenden kann , mit denen Sie den uWSGI-Server dynamisch konfigurieren können. Unter diesen Variablen gibt es
UWSGI_FILEeine, mit der Sie eine neue dynamische Anwendung laden können, wenn Sie den Pfad zur Datei in der Variablen angeben. Wie sich herausstellte , kann uwsgi-Server verschiedene Schaltungen auf diese Weise behandeln, zum Beispiel section, fd, call, oder interessanteste - exec. Somit können Sie die Variable als Wert übergebenexec://<cmmand>um einen beliebigen Bash-Befehl auszuführen. Ein Exploit wurde geschrieben, um dieses Problem zu analysieren und ist auf github verfügbar .

Ein Beispiel für eine Abfrage, die einen Befehl ausführt.
Diese Sicherheitsanfälligkeit kann nur ausgenutzt werden, wenn der Angreifer:
- Befindet sich beispielsweise bereits im internen Netzwerk des Produkts, wurde eine der Komponenten kompromittiert. Dies könnte es ihm ermöglichen, eine neue Komponente zu entführen, Zugriff auf neue Daten zu erhalten und den Angriff fortzusetzen.
- Hat SSRF mit der Fähigkeit, beliebige Daten über TCP zu senden (zum Beispiel mit
gopher://). In diesem Szenario kann ein Angreifer Zugriff auf das Innere des Produkts erhalten.
Es ist anzumerken, dass Implementierungen von CGI-Schnittstellen für andere Programmiersprachen oder Frameworks ebenfalls anfällig sein können, z. B. ein Exploit aus demselben Repository für FastCGI. Dies bedeutet nicht, dass dies eine Sicherheitsanfälligkeit im üblichen Sinne ist, sondern eine Funktion von CGI-Servern. Daher müssen Sie den Zugriff auf solche Server so weit wie möglich einschränken.
CSRF-Schutz umgehen
Mit der Einführung verschiedener Sicherheitsmechanismen in Browsern verschwinden clientseitige Angriffe auf das moderne Web allmählich. Dies gilt auch für CSRF: Browser haben bereits die Unterstützung für das SameSite-Cookie implementiert, obwohl bei falscher Konfiguration möglicherweise noch Lücken bestehen. Darüber hinaus ermöglichen viele beliebte Frameworks Entwicklern die einfache Konfiguration des CSRF-Schutzes. Einige Fehler oder unkritische Sicherheitslücken können jedoch zu einem CSRF-Angriff führen. Solche Fehler wurden in der in unserem Produkt enthaltenen Kalenderanwendung gefunden.
Die Anwendung verfügt über eine API, mit der Sie Aktionen für die Ereignisse und Kalender des Benutzers ausführen können, z. B.: Bearbeiten, Anzeigen oder Löschen. Um auf das Objekt zu verweisen, wird der UID-Parameter im URL-Pfad übergeben, der für die ID des Kalenders oder Ereignisses verantwortlich ist. Es sieht aus wie das:
example.com/api/calendar/{UID}/action?
example.com/api/event/{UID}/action?
Standardmäßig wird die UID zufällig generiert und kann vom Benutzer nicht beeinflusst werden. In der Anwendung wurden jedoch zwei Stellen gefunden, an denen der Benutzer die UID ändern kann.
Der erste besteht darin, Dateien im ICS-Format (einem speziellen Format für Kalender und Ereignisse) zu importieren. Sie verfügen über ein spezielles UID-Feld, das der Benutzer beim Importieren steuert. In diesem Fall bleiben die UIDs nach dem Importieren von Ereignissen dieselben wie in der Datei übertragen. Dieser Parameter hat auch keine Filterung. Somit könnte der Benutzer ein Ereignis mit einer beliebigen UID erstellen.
Die zweite ist die Möglichkeit, den UID-Kalender beim Bearbeiten zu ändern. Dies kann durch Abfangen der Anforderung zum Bearbeiten des Kalenders und einfaches Ändern des UID-Felds erfolgen. Auch hier gab es keine Filterung.
Ein weiteres wichtiges Merkmal: Diese API implementiert den CSRF-Schutz. Dazu wird in den GET-Parametern ein spezieller Parameter übergeben, der sowohl als Schlüssel für die API als auch als CSRF-Token fungiert. Es wird über JavaScript zu allen API-Anforderungen hinzugefügt. Es wird empfohlen, CSRF-Token in GET-Parametern zu übergeben. In diesem Fall können Token durch den Referer, die Anwendungsprotokolle oder den Browserverlauf gelangen.
Alles zusammenfügen. Ein Angreifer kann Objekt-UIDs in einer Anwendung steuern und den Zugriff auf Ereignisse und Kalender für andere Benutzer freigeben. In diesem Fall sehen Benutzer dieselbe UID. Wenn sie mit einem solchen Objekt arbeiten, werden Anforderungen mit der vom Angreifer kontrollierten UID ausgeführt. Auf diese Weise kann ein Angreifer ein Objekt mit einer UID wie folgt erstellen:
../../../AnyPathTo?anyparam=value&
Wenn der Benutzer nun eine Aktion für das Objekt ausführt, wird eine Anforderung generiert:
example.com/api/event/../../../AnyPathTo?anyparam=value&/action
Dann wird auch ein Token hinzugefügt, der die Rolle eines CSRF-Tokens spielt:
example.com/api/event/../../../AnyPathTo?anyparam=value&/action&token=abcdef
Und schließlich normalisiert der Browser bei der Anforderung die Sequenz "
../". Infolgedessen wird die Anforderung an gesendet
example.com/AnyPathTo?anyparam=value&/action&token=abcdef
Jetzt kann ein Angreifer einen Benutzer zwingen, eine Anforderung über einen beliebigen Pfad mit beliebigen Parametern und mit dem richtigen CSRF-Token an die Anwendung zu senden. Es bleibt zu verstehen, welche Anforderungsmethoden wir ausführen können.
Es stellte sich als einfach heraus: Beim Bearbeiten wird PUT gesendet, beim Löschen, LÖSCHEN, beim Anzeigen GET (POST wird zum Erstellen verwendet, und wir können das Opfer nicht zwingen, es zu verwenden). Mit DELETE kann ein Angreifer den Browser des Benutzers zwingen, eine Anforderung zum Löschen eines Objekts aus dem Benutzer auszuführen. Ein separater Bonus für einen Angreifer besteht darin, dass beim Bearbeiten eines Objekts durch einen Benutzer eine PUT-Anforderung mit dem Anforderungshauptteil gesendet wird. Beim Bearbeiten eines Kalenders enthält der Anforderungshauptteil JSON, das alle Parameter des aktuellen Kalenders enthält. Das heißt, der Angreifer, der den "böswilligen" Kalender erstellt hat, steuert diese Parameter. Wenn es dem Angreifer gelingt, eine Bearbeitungsanforderung vom böswilligen Kalender in den privaten Kalender des Benutzers umzuleiten, werden alle Eigenschaften des böswilligen Kalenders auf die Eigenschaften des Kalenders des Opfers angewendet.Dies kann den Zugriff auf den Kalender überschreiben, da es sich um eine der in JSON angegebenen Kalendereigenschaften handelt.
MITM-Angriffsfähigkeit
Das Eindringen eines Eindringlings in das interne Netzwerk des Unternehmens ist eine gefährliche Situation, die schwerwiegende Folgen hat. Daher bestand eine unserer Aufgaben während der Prüfung des Produkts darin, Fehler in der Systemarchitektur zu finden, die einem Eindringling helfen könnten, sich durch die Domäne zu bewegen oder externe Angriffe zu verbessern.
Eine der Hauptfunktionen des Produkts ist die Integration in Active Directory. Es ist für die Authentifizierung über LDAP und das Sammeln von Nachrichten vom Exchange-Server implementiert. In diesem Beispiel konzentrieren wir uns auf ActiveSync. Für einen Angreifer ist dies ein sehr interessantes Ziel, da Benutzerkonten und Kennwörter während der Verbindung zwischen dem Produkt und Active Directory übertragen werden. Durch den Zugriff auf die Verbindungen kann ein Angreifer Konten entführen und ist der Gefährdung der Domäne einen Schritt näher gekommen.
In internen Lösungen und auf den Servern von Unternehmen gibt es häufig ein Problem mit der falschen Verwendung von TLS oder dessen Fehlen, während es nicht schwierig ist, TLS für einen Dienst zu implementieren. Dies ist normalerweise eine Folge der Tatsache, dass das interne Netzwerk des Unternehmens als sicherer angesehen wird und Unternehmensadministratoren keine Zeit damit verbringen, die richtige PKI-Infrastruktur zu erstellen und Zertifikate für alle Server auszustellen.
Der häufigste Angriff in Unternehmensnetzwerken ist MITM. Diese Art von Angriff ermöglicht meistens den Zugriff auf das Active Directory eines Unternehmens. Gleichzeitig ist es für einen Angreifer nicht immer möglich, die Server-zu-Server-Interaktion innerhalb des Unternehmensnetzwerks anzugreifen. Meistens fällt er oder sein Modell bei Penetrationstests in ein Benutzernetzwerksegment, in dem kein Exchange-Server oder Domänencontroller vorhanden ist. Darüber hinaus verwendet das Produkt in unserem Fall keine Protokolle zur Auflösung von Broadcast-Namen wie NBNS, LLMNR, mDNS, sodass durch das Spoofing dieser Protokolle MITM nicht implementiert werden kann. Für ein erfolgreiches MITM zwischen der Lösung und anderen Servern muss der Angreifer daher Zugriff auf das Netzwerk haben, in dem eine dieser Komponenten installiert ist. Es ist manchmal möglich, dieses Ziel zu erreichen - es gibt anfällige Router oder Server,Damit können Sie letztendlich auf ein bestimmtes Netzwerk zugreifen.
In unserem Fall stellte sich während der Analyse heraus, dass die Integration in Active Directory anfällig für MITM-Angriffe ist.
Wenn der Benutzer einen Benutzernamen und ein Kennwort eingibt, sendet das System zwei LDAP-Anforderungen an den Domänencontroller. Die erste Anforderung gibt eine Liste der E-Mail-Adressen zurück. Wenn die Anmeldung des Benutzers in dieser Liste vorhanden ist, wird die zweite Anforderung gesendet, nämlich die einfache LDAP-Authentifizierung. Daten werden im Klartext ohne Verwendung von SSL / TLS übertragen, oder LDAPS (LDAP über SSL) wird nicht verwendet. Auf diese Weise kann ein Angreifer auch im Falle eines passiven MITM-Angriffs Benutzerkonten abrufen, die derzeit im Produkt autorisiert sind.
Das zweite Problem: Beim Herstellen einer Verbindung zu einem Exchange-Server mithilfe des ActiveSync-Protokolls zum Sammeln eingehender Nachrichten hat das System das TLS-Zertifikat des Servers nicht authentifiziert. In diesem Fall könnte ein Angreifer einen aktiven MITM-Angriff implementieren. Wenn er eine Verbindung erhält, kann er ein selbstsigniertes Zertifikat ausstellen, eine Verbindung herstellen und die Daten an den Exchange-Server weiterleiten. Dann ist MITM unsichtbar und ein Angreifer kann Benutzeranmeldeinformationen abrufen, die im ActiveSync-Protokoll übertragen werden.
Durch Ausnutzen dieser Sicherheitsanfälligkeiten kann ein Angreifer theoretisch Benutzerkonten abrufen und diese dann zum Angriff auf die Active Directory-Domäne verwenden. Unabhängig davon ist zu beachten, dass die korrekte Verwendung von TLS eine notwendige Aufgabe für ein Unternehmen ist, das eine Lösung implementiert.
Ergebnis
Wir sind ständig mit Hackerangriffen konfrontiert und haben solide Erfahrung darin gesammelt, sie abzuwehren. Wir sind der Ansicht, dass die Produkte, die wir in den Umkreis des Kunden stellen, so sicher wie möglich sein sollten, auch basierend auf den Ergebnissen unabhängiger Überprüfungen. Corporate Mail Mail.ru ist genau ein solches Produkt.
Wir standen vor einer mühsamen Aufgabe: Eine große Codebasis mit vielen Microservices auf die Infrastruktur des Kunden zu übertragen, damit die E-Mails die meiste Zeit von selbst funktionieren, ohne Fehler und Eingriffe des Administrators.
Wir haben die Prüfer gebeten, der geänderten Autorisierung (Corporate Mail verwendet die AD des Kunden) und der Haupt-Mail-API die größte Aufmerksamkeit zu widmen. Der Quellcode dieser Komponenten wurde detailliert analysiert. Infolgedessen waren die festgestellten Mängel hauptsächlich auf die geänderte Netzwerktopologie und die für die lokale Lösung spezifischen Änderungen zurückzuführen.
Für die übrigen Komponenten (Kalender, Mail.ru für die Business Administration-Oberfläche) wurde ein Gray-Box-Modell verwendet: Auditoren interagierten mit den Diensten mit den Berechtigungen normaler Benutzer, konnten jedoch mit der laufenden Anwendung eine Verbindung zum Container herstellen, teilweise über den API-Quellcode verfügen und die Details mit den Entwicklern klären.
Das Audit war für uns sehr nützlich. Wir haben bei einigen Komponenten eine Reihe von Mängeln festgestellt, die wir umgehend korrigiert haben, um ein sicheres Produkt auf den Markt zu bringen. Gleichzeitig waren wir von dem hohen Schutzniveau der meisten anderen Komponenten überzeugt. Wir planen, solche Audits regelmäßig durchzuführen. Wir möchten, dass unser Produkt nicht nur unserer Meinung nach, sondern auch der Meinung unabhängiger Auditoren immer zu den sichersten Lösungen im Inland gehört.
Die Sicherheit von Corporate Mail ist die Kombination aus der Sicherheit des Produkts selbst und der Infrastruktur des Kunden. Das heißt, die Verantwortung für die Sicherheit von Unternehmensdaten liegt bei uns, dem Entwickler und dem Kunden selbst. Darüber hinaus haben wir Empfehlungen für Best Practices zum Schutz der Infrastruktur vor Fehlern formuliert und Kunden bei der Installation unseres Produkts stets beraten.