Steuern Flow Guard für Plattformsicherheit

Was ist Control Flow Guard?

Control Flow Guard (CFG) ist ein hochoptimiertes Plattformsicherheitsfeature, das zur Bekämpfung von Speicherbeschädigungsrisiken erstellt wurde. Durch das Platzieren enger Einschränkungen, aus denen eine Anwendung Code ausführen kann, ist es wesentlich schwieriger, beliebige Code durch Sicherheitsrisiken wie Pufferüberläufe auszuführen. CFG erweitert frühere Exploit-Minderungstechnologien wie /GS, DEP und ASLR.

  • Verhindern Sie Speicherbeschädigungen und Ransomware-Angriffe.
  • Beschränken Sie die Funktionen des Servers auf alle erforderlichen Funktionen an einem bestimmten Zeitpunkt, um die Angriffsoberfläche zu verringern.
  • Machen Sie es schwieriger, beliebigen Code durch Sicherheitsrisiken wie Pufferüberläufe zu nutzen.

Dieses Feature ist in Microsoft Visual Studio 2015 verfügbar und wird in "CFG-Aware"-Versionen von Windows ausgeführt – die x86- und x64-Versionen für Desktop und Server von Windows 10 und Windows 8.1 Update (KB3000850).

Wir ermutigen Entwickler dringend, CFG für ihre Anwendungen zu ermöglichen. Sie müssen CFG für jeden Teil Ihres Codes nicht aktivieren, da eine Mischung aus aktiviertem CFG- und nicht CFG-aktiviertem Code fein ausgeführt wird. Fehler beim Aktivieren von CFG für alle Code kann jedoch Lücken im Schutz öffnen. Darüber hinaus funktioniert CFG-aktivierter Code für "CFG-Unaware"-Versionen von Windows und ist daher vollständig mit ihnen kompatibel.

Wie kann ich CFG aktivieren?

In den meisten Fällen ist keine Änderung des Quellcodes erforderlich. Alles, was Sie tun müssen, ist eine Option zu Ihrem Visual Studio 2015-Projekt hinzuzufügen, und der Compiler und linker aktiviert CFG.

Die einfachste Methode besteht darin, zu Project | zu navigieren. Eigenschaften | Konfigurationseigenschaften | C/C++ | Codegenerierung und wählen Sie "Ja" (/guard:cf) für Steuerelement Flow Guard aus.

cfg property in visual studio

Hinzufügen von /guard:cf zu Project | Eigenschaften | Konfigurationseigenschaften | C/C++ | Befehlszeile | Zusätzliche Optionen (für den Compiler) und /guard:cf zu Project | Eigenschaften | Konfigurationseigenschaften | Linker | Befehlszeile | Zusätzliche Optionen (für den Linker).

cfg property for compilercfg property for linker

Weitere Informationen finden Sie unter /guard (Aktivieren von Steuerelement Flow Guard).

Wenn Sie Ihr Projekt aus der Befehlszeile erstellen, können Sie dieselben Optionen hinzufügen. Wenn Sie beispielsweise ein Projekt namens test.cpp kompilieren, verwenden Sie cl /guard:cf test.cpp /link /guard:cf.

Sie haben auch die Möglichkeit, den Satz von icall-Zieladressen dynamisch zu steuern, die von CFG mithilfe der SetProcessValidCallTargets aus der Speicherverwaltungs-API als gültig angesehen werden. Die gleiche API kann verwendet werden, um anzugeben, ob Seiten ungültig oder gültige Ziele für CFG sind. Die Funktionen VirtualProtect und VirtualAlloc behandeln standardmäßig einen bestimmten Bereich ausführbarer und gebundener Seiten als gültige indirekte Aufrufziele. Es ist möglich, dieses Verhalten, z. B. beim Implementieren eines Just-in-Time-Compilers, außer Kraft zu setzen, indem PAGE_TARGETS_INVALID beim Aufrufen von VirtualAlloc oder PAGE_TARGETS_NO_UPDATE beim Aufrufen von VirtualProtect unter Speicherschutzkonstanten angegeben werden.

Wie kann ich sagen, dass eine Binärdatei unter Kontrolle Flow Guard ist?

Führen Sie das Dumpbin-Tool (im Visual Studio 2015-Installation enthalten) aus der Visual Studio Eingabeaufforderung mit den Optionen /headers und /loadconfig: dumpbin /headers /loadconfig test.exe. Die Ausgabe für eine Binärdatei unter CFG sollte zeigen, dass die Kopfzeilenwerte "Guard" enthalten und dass die Ladekonfigurationswerte "CF Instrumented" und "FID-Tabelle vorhanden" enthalten.

output from dumpbin /headers

output from dumpbin /loadconfig

Wie funktioniert CFG wirklich?

Softwarerisiken werden häufig genutzt, indem unwahrscheinliche, ungewöhnliche oder extreme Daten für ein ausgeführtes Programm bereitgestellt werden. Ein Angreifer kann z. B. eine Pufferüberlaufrisiken ausnutzen, indem mehr Eingaben für ein Programm bereitgestellt werden als erwartet, wodurch der vom Programm reservierte Bereich überläuft, um eine Antwort zu halten. Dadurch könnte der angrenzende Speicher beschädigt werden, der möglicherweise einen Funktionszeiger enthält. Wenn das Programm diese Funktion aufruft, kann es dann zu einem durch den Angreifer angegebenen unbeaufsichtigten Speicherort springen.

Eine leistungsstarke Kombination aus Kompilierungs- und Laufzeitunterstützung von CFG implementiert jedoch die Kontrollflussintegrität, die eng eingeschränkt wird, wo indirekte Anrufanweisungen ausgeführt werden können.

Der Compiler führt folgendes aus:

  1. Fügt den kompilierten Code einfache Sicherheitsüberprüfungen hinzu.
  2. Identifiziert den Satz von Funktionen in der Anwendung, die gültige Ziele für indirekte Aufrufe sind.

Die Laufzeitunterstützung, die vom Windows Kernel bereitgestellt wird:

  1. Verwaltet effizient den Zustand, der gültige indirekte Anrufziele identifiziert.
  2. Implementiert die Logik, die überprüft, ob ein indirektes Anrufziel gültig ist.

So veranschaulichen Sie folgendes:

cfg pseudocode

Wenn eine CFG-Überprüfung zur Laufzeit fehlschlägt, beendet Windows sofort das Programm, wodurch jeder Exploit, der versucht, indirekt eine ungültige Adresse aufrufen zu können, abgebrochen wird.