Bewährte Sicherheitsmethoden bei der Spieleentwicklung

In diesem Artikel werden bewährte Methoden für die Spieleentwicklung erläutert.

Einführung

Eine zunehmende Anzahl von Personen spielen Online-Spiele und Spiele mit benutzergemachten Inhalten. In Verbindung mit der zunehmenden Sicherheit des Betriebssystems Microsoft Windows bedeutet dies, dass Spiele für Angreifer ein immer verlockenderes Ziel darstellen. Spieleentwickler sollten sich darauf konzentrieren, sicherzustellen, dass die von ihnen veröffentlichten Spiele keine neuen Sicherheitslöcher für Angreifer schaffen, die sie ausnutzen können. Spieleentwickler haben eine Verantwortung und ein berechtigtes Interesse daran, die Computer ihrer Kunden daran zu hindern, durch böswillige Netzwerkdaten, Benutzeränderungen oder Manipulationen gehackt zu werden. Wenn eine Sicherheitsanfälligkeit ausgenutzt wird, kann dies dazu führen, dass Kunden und/oder Geld verloren gehen. In diesem Artikel werden einige gängige Methoden und Tools beschrieben, um die Codesicherheit zu erhöhen, ohne die Entwicklungszeit zu übersteigen.

Die drei häufigsten Fehler eines Entwicklungsteams bei der Veröffentlichung eines Produkts sind:

  • Erfordert Administratorrechte. Spiele sollten keine Administratorrechte erfordern. Weitere Details finden Sie unter Benutzerkontensteuerung für Spieleentwickler.
  • Kein automatisierter Schutz. Entwickler verwenden in der Regel nicht /GS, /SAFESEH oder /NX. Die Verwendung dieser Kompilierungs-/Linkkennzeichnungen kann viele grundlegende Sicherheitslöcher erkennen oder beseitigen, ohne die Arbeitsauslastung erheblich zu erhöhen. Auf diese Flaggen wird später in diesem Artikel eingegangen.
  • Verwenden verbotener APIs. Es gibt viele APIs (strcpy, strncpy usw.), die anfällig für Programmiererfehler sind und problemlos Sicherheitslöcher generieren. Entwickler sollten diese APIs durch die sicheren Versionen ersetzen. Visual Studio 2005 verfügt über ein Tool zum Analysieren von Binärdateien, die Objektdateien automatisch auf Verweise auf unsichere APIs überprüfen können. Weitere Informationen zu Informationen, die mit diesem Tool generiert werden, finden Sie unter Repel Attacks on Your Code with the Visual Studio 2005 Safe C and C++ Libraries by Martyn Lovell. Außerdem können Sie die Headerdatei abrufen, mit der banned.h Sie gesperrte Funktionen aus Code entfernen können (siehe die kostenlosen Sicherheitstools von Microsoft – banned.h).

Jeder der aufgeführten Fehler ist nicht nur üblich, sondern kann problemlos korrigiert werden, ohne dass sich die Entwicklungsarbeitsauslastung, die Codierungsstandards oder die Funktionalität erheblich ändern.

Beispiele für unsicheren Code

Im Folgenden sehen Sie ein einfaches Beispiel dafür, dass ein Angreifer einen Pufferüberlaufangriff durchführt:

void GetPlayerName(char *pDatafromNet)
{
    char playername[256]; 
    strncpy(playername, pDatafromNet, strlen(pDatafromNet));

    // ...
}

Auf der Oberfläche sieht dieser Code ok aus – er ruft schließlich eine sichere Funktion auf. Daten aus dem Netzwerk werden in einen Puffer kopiert, der 256 Bytes beträgt. Die strncpy-Funktion basiert auf der Suche nach einem NULL-Terminator in der Quellzeichenfolge oder ist durch die bereitgestellte Pufferanzahl begrenzt. Das Problem besteht darin, dass die Puffergröße falsch ist. Wenn Daten aus dem Netzwerk nicht überprüft werden oder die Puffergröße falsch ist (wie in diesem Beispiel), könnte ein Angreifer einfach einen großen Puffer bereitstellen, um Stapeldaten zu überschreiben, nachdem der Puffer beendet wurde, mit allen Daten im Netzwerkpaket. Dies würde es dem Angreifer ermöglichen, beliebigen Code auszuführen, indem der Anweisungszeiger überschrieben und die Absenderadresse geändert wird. Die einfachste Lektion dieses Beispiels besteht darin, der Eingabe erst zu vertrauen, wenn sie überprüft wurde.

Auch wenn Daten anfänglich nicht aus dem Netzwerk stammen, besteht weiterhin ein potenzielles Risiko. Die moderne Spieleentwicklung erfordert viele Personen, die die gleiche Codebasis entwerfen, entwickeln und testen. Es gibt keine Möglichkeit zu wissen, wie die Funktion in Zukunft aufgerufen wird. Fragen Sie sich immer, woher die Daten stammen, und was könnte ein Angreifer kontrollieren? Netzbasierte Angriffe sind zwar die häufigsten, aber nicht die einzigen Methoden zur Schaffung von Sicherheitslücken. Könnte ein Angreifer einen Mod erstellen oder eine gespeicherte Datei so bearbeiten, dass eine Sicherheitslücke entsteht? Wie sieht es mit vom Benutzer bereitgestellten Bild- und Audiodateien aus? Böswillige Versionen dieser Dateien könnten im Internet veröffentlicht und gefährliche Sicherheitsrisiken für Ihre Kunden entstehen.

Verwenden Sie als Nebennotiz strsafe.h oder Safe CRT anstelle von strncpy, um das Beispiel zu korrigieren. Safe CRT ist eine vollständige Sicherheitsüberholung der C-Runtime und ist bestandteil von Visual Studio 2005. Weitere Informationen zu Safe CRT finden Sie unter Security Enhancements in the CRT von Michael Howard.

Möglichkeiten zur Verbesserung der Sicherheit

Es gibt mehrere Möglichkeiten, die Sicherheit im Entwicklungszyklus zu verbessern. Hier sind einige der besten Möglichkeiten:

Lesen Sie über Sicherheit

Das Buch, Writing Secure Code, Second Edition von Michael Howard und David LeBlanc, bietet eine ausführliche und klare Erläuterung von Strategien und Methoden zur Verhinderung von Angriffen und mildernden Exploits. Angefangen bei Methoden zum Design von Sicherheit in einer Version bis hin zu Techniken zur Sicherung von Netzwerkanwendungen deckt das Buch alle Aspekte ab, die ein Spieleentwickler benötigt, um sich, seine Produkte und seine Kunden vor Angreifern zu schützen. Das Buch kann verwendet werden, um eine Kultur der Sicherheit in einem Entwicklungsstudio zu fördern. Denken Sie nicht nur an die Codesicherheit als Problem eines Entwicklers oder an das Problem eines Testers. Stellen Sie sich die Sicherheit als etwas, das das gesamte Team – vom Programmmanager bis zum Entwickler bis zum Tester – berücksichtigen sollte, wenn sie an einem Projekt arbeiten. Je mehr Augen Teil des Überprüfungsprozesses sind, desto größer ist die Chance, vor der Freigabe eine Sicherheitslücke zu entdecken.

Writing Secure Code, Second Edition finden Sie im Microsoft Press Store und allgemeinere Sicherheitsinformationen finden Sie in Fending Off Future Attacks by Reducing Attack Surface von Michael Howard.

Michael Howard, David LeBlanc und John Viega haben ein weiteres Buch über das Thema geschrieben, das alle gängigen Betriebssysteme und Programmiersprachen mit dem Titel 19 Deadly Sins of Software Security umfasst.

Sicherheitspräsentationen, die sich auf Spiele konzentrieren, finden Sie auf der Downloadseite von Microsoft XNA Developer Presentations .

Analyse der Bedrohungsmodellierung

Eine Analyse der Bedrohungsmodellierung ist eine gute Möglichkeit zur Bewertung der Systemsicherheit, nicht in einer bestimmten Sprache oder mithilfe eines Tools, sondern in einer umfassenden End-to-End-Methode, die in einigen Besprechungen durchgeführt werden kann. Bei der ordnungsgemäßen Implementierung kann ein Threadmodell alle Stärken und Schwächen eines Systems identifizieren, ohne dem Projekt erhebliche Arbeitslasten oder Besprechungszeiten hinzuzufügen. Die Methode der Bedrohungsmodellierung betont auch die Idee, die Systemsicherheit vor und während des Entwicklungsprozesses zu bewerten, um sicherzustellen, dass eine umfassende Bewertung durchgeführt wird, während sie sich auf die riskantesten Features konzentriert. Es kann als Profiler für Sicherheit betrachtet werden. Da sie nicht auf einer bestimmten Sprache oder auf ein bestimmtes Tool basieren, kann die Bedrohungsmodellierung in jedem Entwicklungsstudio verwendet werden, das an jedem Projekt in einem beliebigen Genre arbeitet. Die Bedrohungsmodellierung ist auch eine hervorragende Methode, um die Idee zu stärken, dass Sicherheit die Verantwortung aller und nicht das Problem einer anderen Person ist.

Achten Sie beim Modellieren von Bedrohungen auf Folgendes:

  • UDP-Datenquellen
  • Datenquellen, die keine Authentifizierung erfordern
  • Datenquellen, die im Rahmen einer breit angelegten Informationsbeschaffung häufig und regelmäßig abgefragt werden
  • Jede Möglichkeit eines Clients, Daten direkt an andere Clients zu senden

Dies sind die Bereiche, die ein gutes Potenzial für Sicherheitsschwächen haben.

Mehr zu Threat Modeling finden Sie unter Threat Modeling und im Buch Threat Modeling von Frank Swiderski und Window Snyder.

Datenausführungsverhinderung (/NX)

Ein aktuelles Tool zum Verringern mehrerer Exploits ist die Verhinderung von Datenausführung (Data Execution Prevention, DEP). Wenn Sie die Option /NX in den Build-Befehl einschließen, markiert Visual Studio Speicherseiten mit Flags, die angeben, ob der Code ausgeführt werden darf oder nicht. Jedes Programm, das versucht, auf einer Speicherseite auszuführen, die nicht mit EXECUTE-Berechtigung gekennzeichnet ist, führt zu einer unzulässigen Beendigung des Programms. Die Verhinderung wird auf Prozessorebene erzwungen und wirkt sich auf Entwickler aus, die selbst ändernden Code oder systemeigene JIT-Sprachcompiler verwenden. Derzeit unterstützen nur AMDs Athlon64- und Opteron-Prozessoren sowie Intels Itanium- und neueste Pentium-4-Prozessoren die Ausführungsverhinderung, aber es wird erwartet, dass alle 32-Bit- und 64-Bit-Prozessoren in Zukunft die Ausführungsverhinderung unterstützen werden. (Ein von einem Entwickler verwendetes Kopierschutzschema kann von der Ausführungsverhinderung betroffen sein, aber Microsoft hat mit Kopierschutzanbietern gearbeitet, um die Auswirkungen zu minimieren.) Es empfiehlt sich, DEP zu verwenden.

Weitere Informationen zu DEP finden Sie unter Datenausführungsverhinderung.

Puffersicherheitsprüfung (/GS) und Image verfügt über sichere Ausnahmehandler (/SAFESEH)

Puffersicherheitsprüfung, die durch das Compilerflagge /GS angegeben wurde, und Image verfügt über sichere Ausnahmehandler, die durch das Linker-Flag /SAFESEH (erste Implementierung in Visual Studio .NET 2003) angegeben wurden, können die Aufgabe des Entwicklers, Code etwas einfacher zu sichern.

Die Verwendung des /GS-Flags bewirkt, dass der Compiler eine Überprüfung auf einige Arten von stapelbasierten Pufferüberläufen erstellt, die zum Überschreiben der Absenderadresse einer Funktion ausgenutzt werden können. Die Verwendung von /GS erkennt nicht jeden potenziellen Pufferüberlauf und sollte nicht als Catch-All betrachtet werden, sondern eine gute Verteidigungstechnologie.

Die Verwendung des Flags /SAFESEH weist den Linker an, nur eine ausführbare Datei oder DLL zu generieren, wenn sie auch eine Tabelle der sicheren Ausnahmehandler der ausführbaren Datei oder DLL generieren kann. Safe Structured Exception Handling (SafeSEH) beseitigt die Ausnahmebehandlung als Ziel von Pufferüberlaufangriffen, indem sichergestellt wird, dass der Ausnahmehandler vor der Verteilerfunktion in der Funktionstabelle in der Bilddatei registriert wird. Diese Schutzvorteile sind mit Windows XP SP2, Windows Server 2003, Windows Vista und Windows 7 aktiviert. Damit /SAFESEH ordnungsgemäß funktioniert, muss sie auch in einer All-or-Nothing-Methode verwendet werden. Alle Bibliotheken, die Code enthalten, der an eine ausführbare Datei oder DLL gebunden ist, müssen mit /SAFESEH kompiliert werden, oder die Tabelle wird nicht generiert.

Weitere Informationen finden Sie unter Puffersicherheitsprüfung (/GS) und Image has Safe Exception Handlers (/SAFESEH).

Siehe auch Informationen über das /SDL-Flag von Microsoft Visual Studio 2012 und die Erweiterungen des /GS-Flags in Visual Studio 2012.

PREfast

PREfast ist ein kostenloses Tool von Microsoft, das Ausführungspfade in kompilierten C oder C++ analysiert, um Laufzeitfehler zu finden. PREfast arbeitet durch alle Ausführungspfade in allen Funktionen und bewertet jeden Pfad für Probleme. Ursprünglich für die Entwicklung von Treibern und anderem Kernel-Code verwendet, kann dieses Tool Spieleentwicklern helfen, Zeit zu sparen, indem es einige Fehler beseitigt, die schwer zu finden sind oder vom Compiler ignoriert werden. Die Verwendung von PREfast ist eine hervorragende Möglichkeit, die Arbeitsauslastung zu reduzieren und die Anstrengungen sowohl des Entwicklungsteams als auch des Testteams zu konzentrieren. PREfast ist in Visual Studio Team Suite und Visual Studio Team Edition für Softwareentwickler als Codeanalyse verfügbar, aktiviert durch den Compilerschalter /analyze. (Diese Option ist auch in der kostenlosen Version des Compilers verfügbar, der im Windows Software Development Kit enthalten ist.)

Hinweis

Visual Studio 2012 unterstützt /analyze in allen Editionen. Weitere Informationen zur Verfügbarkeit von Codeanalysen in allen Editionen von Visual Studio finden Sie unter What's New in Code Analysis.

 

Durch die Verwendung der Kopfzeilenanmerkung (insbesondere für Pufferzeigerargumente) kann PREfast zusätzliche Probleme verfügbar machen, z. B. Speicherüberschreibfehler, eine häufige Quelle von Abstürze und potenzielle Sicherheitsrisiken. Dazu wird die Standardanmerkungssprache (STANDARD Annotation Language, SAL) verwendet, bei der es sich um eine Form von Markup für C/C++-Funktionsprototypen handelt, die zusätzliche Informationen zur erwarteten Zeigerargumentsemantik und Korrelation mit Längenparametern, deklarierten Puffergrößen usw. bereitstellen. Alle Header für Windows-Betriebssysteme werden kommentiert, und das Hinzufügen von SAL-Mark-up in öffentlichen API-Headern in Ihren eigenen Bibliotheken ermöglicht PREfast, detailliertere und aggressivere Überprüfungen in Ihrem Clientcode für solche APIs durchzuführen. Eine Einführung in SAL und Links zu weiteren Informationen finden Sie im Blogeintrag von Michael Howard: Eine kurze Einführung in die Standardanmerkungssprache (SAL).

Windows Application Verifier

Die Windows Application Verifier oder AppVerifier können Testern helfen, indem sie mehrere Funktionen in einem Tool bereitstellen. Der AppVerifier ist ein Tool, das entwickelt wurde, um gängige Programmierfehler leichter zu testen. AppVerifier kann die an API-Aufrufe übergebenen Parameter überprüfen, fehlerhafte Eingaben einspeisen, um die Fähigkeit zur Fehlerbehandlung zu prüfen, und Änderungen an der Registrierung und am Dateisystem protokollieren. AppVerifier kann auch Pufferüberläufe im Heap erkennen, überprüfen, ob eine Zugriffssteuerungsliste (Access Control List, ACL) ordnungsgemäß definiert wurde, und die sichere Verwendung von Socket-APIs erzwingen. AppVerifier kann zwar nicht vollständig sein, kann jedoch ein Tool in der Toolbox des Testers sein, um einem Entwicklungsstudio bei der Veröffentlichung eines Qualitätsprodukts zu helfen.

Weitere Informationen zur Anwendungsüberprüfung finden Sie unter Application Verifier und Verwendung von Application Verifier im Lebenszyklus Ihrer Softwareentwicklung.

Fuzz-Testing

Fuzz-Tests sind eine halbautomatisierte Methode für Tests, die aktuelle Testmethoden verbessern können. Die zentrale Idee hinter Fuzz-Tests besteht darin, eine vollständige Bewertung aller Eingaben durchzuführen, indem zufällige Daten eingegeben werden, um zu sehen, welche Unterbrechungen erforderlich sind; dazu gehören alle Netzwerkdaten, Mods und gespeicherten Spiele usw. Fuzz-Tests sind ziemlich einfach zu erledigen. Ändern Sie einfach wohlgeformte Dateien oder Netzwerkdaten, indem Sie zufällige Bytes einfügen, angrenzende Bytes kippen oder numerische Werte negieren. 0xff, 0xffff, 0xffffffff, 0x00, 0x0000, 0x00000000 und 0x80000000 sind Werte, die beim Fuzz-Testing gut geeignet sind, Sicherheitslücken aufzudecken. Sie können die resultierenden Interaktionskombinationen mithilfe von AppVerifier beobachten. Fuzzing ist zwar nicht vollständig, aber einfach zu implementieren und zu automatisieren, und es kann die schwer fassbaren und unvorhersehbaren Bugs aufspüren.

Weitere Informationen zu Fuzz-Tests finden Sie in der Präsentation Gamefest 2007 Practical Steps in Game Security.

Authenticode-Signatur

Authenticode ist eine Methode, um sicherzustellen, dass ausführbare Dateien, DLL-Dateien und Windows-Installer-Pakete (.msi Dateien), die der Benutzer erhält, von dem, was ein Entwickler veröffentlicht hat, unverändert sind. Durch die Verwendung einer Kombination aus kryptografischen Prinzipien, vertrauenswürdigen Entitäten und Branchenstandards überprüft Authenticode die Integrität von ausführbaren Inhalten. Microsoft stellt eine kryptografische API, CryptoAPI, bereit, die zum automatischen Erkennen von Manipulationen von signiertem Code verwendet werden kann. Wenn nach einer Veröffentlichung ein Sicherheitsleck auftritt, kann ein Zertifikat widerrufen werden, und der mit diesem Zertifikat signierte Code wird nicht mehr authentifiziert. Durch das Widerrufen eines Zertifikats wird die Überprüfung aller mit diesem Zertifikat signierten Titel widerrufen. Windows wurde entwickelt, um mit der Authenticode-Signatur zu arbeiten und benachrichtigt einen Benutzer in bestimmten Situationen über nicht signierten Code, der den PC eines Benutzers für Angriffe verfügbar macht.

Authenticode sollte nicht als Methode zum Beseitigen von Sicherheitsproblemen betrachtet werden, sondern eine Methode zum Erkennen von Manipulationen, nachdem eine ausführbare Datei freigegeben wurde. Eine ausführbare Datei oder DLL, die ein ausnutzbares Sicherheitsproblem enthält, kann mit Authenticode signiert und überprüft werden, führt jedoch weiterhin das Sicherheitsproblem mit dem neuen System ein. Erst nachdem ein Produkt oder eine Aktualisierung als sicher überprüft wurde, sollte der Code signiert werden, um Benutzern zu versichern, dass sie über eine Version verfügen, die nicht manipuliert wurde.

Auch wenn ein Entwickler der Meinung ist, dass keine Bedrohung für seine Veröffentlichungen besteht, verlassen sich andere Technologien und Dienste auf Authenticode. Die Codesignierung ist einfach zu integrieren und zu automatisieren; Es gibt keinen Grund, dass Entwickler ihre Versionen nicht signiert haben.

Weitere Informationen zur Authenticode-Signierung finden Sie unter Authenticode-Signierung für Spieleentwickler.

Minimieren von Berechtigungen

In der Regel sollten Prozesse mit den mindesten Berechtigungen ausgeführt werden, die für den Betrieb erforderlich sind. Unter Windows Vista und Windows 7 erfolgt dies mithilfe der Benutzerkontensteuerung, sodass das Spiel nicht als Administrator, sondern als Standardbenutzer ausgeführt werden kann. Für Windows XP werden Spiele in der Regel immer als Administrator ausgeführt. Auch unter Windows Vista und Windows 7 ist es manchmal erforderlich, die Administratorrechte für bestimmte Vorgänge zu erhöhen.

In den Fällen, in denen der Prozess mit vollständigen Administratorrechten ausgeführt wird, sind in der Regel nur wenige Rechte über die eines Standardbenutzers hinaus erforderlich. Der Administratorzugriff umfasst viele Rechte, die nicht von legitimen Code benötigt werden, aber von einem Angreifer verwendet werden können, durch einige Schwächen im Prozess. Beispiele für solche Rechte sind SE_TAKE_OWNERSHIP, SE_DEBUG, SE_CREATE_TOKEN, SE_ASSIGNPRIMARYTOKEN, SE_TCB, SE_SECURITY, SE_LOAD_DRIVER, SE_SYSTEMTIME, SE_BACKUP, SE_RESTORE, SE_SHUTDOWN und SE_AUDIT (siehe Priviledge Constants).

Ein einmal begonnener Prozess kann zwar nicht mehr Rechte erhalten, aber er kann leicht Rechte aufgeben. Beim Start kann der Prozess sofort Win32-APIs verwenden, um Rechte zu entfernen, die nicht erforderlich sind.

Nutzen von Windows-Sicherheit Features

Windows Vista und Windows 7 umfassen eine Reihe neuer Features, die die Codesicherheit verbessern. Die Benutzerkontensteuerung ist sicherlich die wichtigste, die es zu verstehen und zu übernehmen gilt, aber es gibt auch noch andere Funktionen. Zusätzlich zu den Windows XP SP2-Technologien, wie der Windows-Firewall, der Datenausführungsverhinderung, der Puffersicherheitsprüfung und sicheren Ausnahmehandlern, die auch unter Windows Vista und Windows 7 verfügbar sind, gibt es drei neuere Sicherheitsfeatures:

  • Die optionale Funktion zur Randomisierung des Adressraum-Layouts. Dies wird durch Verknüpfen mit der Option /DYNAMICBASE in Visual Studio 2005 Service Pack 1 oder Visual Studio 2008 aktiviert. Dies führt dazu, dass das System die Positionen vieler wichtiger System-DLLs in Ihrem Prozessraum zufällig verteilt, was das Schreiben von ausnutzbaren Angriffsprogrammen, die sich weit über das Internet verbreiten, erheblich erschwert. Dieses Linker-Flag wird von Windows XP und älteren Versionen von Windows ignoriert.
  • Heap-Beschädigungen können zu einer ganzen Klasse von Sicherheitslücken führen, weshalb das Speichersystem von Windows Vista und Windows 7 jetzt einen Modus unterstützt, der den Prozess beendet, wenn eine Heap-Beschädigung erkannt wird. Wenn Sie HeapSetInformation mit HeapEnableTermianteOnCorruption aufrufen, wird dieses Verhalten aktiviert. Dieser Aufruf schlägt unter Windows XP und einer älteren Version von Windows fehl.
  • Beim Schreiben von Diensten können sie mithilfe eines neuen Features konfiguriert werden, um anzugeben, welche Berechtigungen tatsächlich erforderlich sind, sowie den Ressourcenzugriff auf eine bestimmte SID zu beschränken. Dies erfolgt über ChangeSeviceConfig2 mithilfe von SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO und SERVICE_CONFIG_SERVICE_SID_INFO.

Zusammenfassung

Die Entwicklung eines Spiels für den aktuellen und zukünftigen Markt ist kostspielig und zeitaufwendig. Die Veröffentlichung eines Spiels mit Sicherheitsproblemen kostet letztendlich mehr Geld und Zeit, um sie zu beheben. Es liegt also im Interesse aller Spieleentwickler, Tools und Techniken zur Entschärfung von Sicherheitslücken vor der Veröffentlichung zu integrieren.

Die Informationen in diesem Artikel sind nur eine Einführung in das, was ein Entwicklungsstudio tun kann, um sich und ihre Kunden zu helfen. Weitere Informationen zu allgemeinen Sicherheitspraktiken und Sicherheitsinformationen finden Sie im Microsoft Security Developer Center.