stack- und heap-overflow-schutz bei windows xp und windows vista

60
Studienarbeit Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista Fachbereich Informationstechnik Studiengang Softwaretechnik und Medieninformatik Semester: SWT6 Name: Johannes Hohenbichler Datum: 20.08.2008 Version: 1.03 Betreuer: Dominik Schoop

Upload: johannes-hohenbichler

Post on 24-Jan-2015

2.952 views

Category:

Education


3 download

DESCRIPTION

Hierbei handelt es sich um eine Studienarbeit, deren Thema Stack- und Heap-Overflows unter Windows XP und Windows Vista ist. Zur Einführung ist ein umfangreiches Grundlagenkapitel enthalten, dass die generelle Funktionsweise von Overflows und Code-Injection unter Windows beschreibt. Eine Besonderheit sind hierbei die ausführlich auf Kompatibilität getesteten Demo-Programme mit Quellcode. Um Experimentierfreudigen einen möglichst leichten Einstieg zu geben, wird in den Quellcode-Beschreibungen auf Sicherheitsoptimierungen unterschiedlicher Compilerversionen eingegangen.

TRANSCRIPT

Page 1: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Studienarbeit

Stack- und Heap-Overflow-Schutz

bei

Windows XP und Windows Vista

Fachbereich Informationstechnik

Studiengang Softwaretechnik und Medieninformatik

Semester: SWT6

Name: Johannes Hohenbichler

Datum: 20.08.2008

Version: 1.03

Betreuer: Dominik Schoop

Page 2: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 2 -

I Inhaltsverzeichnis

I Inhaltsverzeichnis ......................................................................................................................... 1-2

II Abbildungsverzeichnis .................................................................................................................. 1-4

III Abkürzungsverzeichnis ................................................................................................................. 1-5

IV Toolsverzeichnis ........................................................................................................................... 1-6

V Besondere Darstellungsformen .................................................................................................... 1-7

1 Überblick ...................................................................................................................................... 1-8

2 Grundlagen – Systemarchitektur................................................................................................ 2-10

2.1 Speicherorganisation .......................................................................................................... 2-10

2.1.1 Virtueller Speicher ...................................................................................................... 2-10

2.1.2 Systemfunktionen....................................................................................................... 2-11

2.1.3 Speichersegmente ...................................................................................................... 2-13

2.1.4 Big- und Little-Endian ................................................................................................. 2-15

3 Grundlagen – Buffer Overflows .................................................................................................. 3-16

3.1 Buffer Overflows ................................................................................................................ 3-16

3.1.1 Off-By-One Buffer Overflows ..................................................................................... 3-17

3.1.2 Mit Buffer Overflows den Kontrollfluss ändern ......................................................... 3-18

3.1.3 Ausführen von beliebigem Code ................................................................................ 3-21

3.1.4 Klassische Stack-basierende Angriffe ......................................................................... 3-22

3.1.5 Exception Handler-basierende Angriffe ..................................................................... 3-25

3.1.6 Heap-basierende Angriffe .......................................................................................... 3-27

3.2 Shellcode und Payload ....................................................................................................... 3-29

3.2.1 Anforderungen an Shellcode ...................................................................................... 3-29

3.2.2 Besonderheiten von Windows-Shellcode .................................................................. 3-30

3.2.3 Was möglich ist ........................................................................................................... 3-30

3.2.4 Abstraktes Beispiel: Portbind Shellcode für Windows ............................................... 3-31

4 Das Sicherheits-Ensemble von Windows und seine Schwachstellen ........................................ 4-32

4.1 Das Windows-Zwei-Schichten-Modell................................................................................ 4-32

4.2 Zugriffsrechte, Authentifizierung und Access Token.......................................................... 4-33

4.2.1 Rechte von Prozessen unter Windows ....................................................................... 4-34

4.2.2 Windows Service Hardening ....................................................................................... 4-35

4.2.3 Rechte von Prozessen unter Windows Vista: UAC ..................................................... 4-35

Page 3: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 3 -

4.3 PatchGuard ......................................................................................................................... 4-37

4.4 Process Exection Block (PEB) Randomization..................................................................... 4-37

4.5 Heap-Schutz ........................................................................................................................ 4-38

4.6 Visual Studio 2005 - Der "Windows-Compiler" .................................................................. 4-40

4.6.1 Standard Annotation Language (SAL) ......................................................................... 4-40

4.6.2 Optimierte Anordnung von Stack-Elementen (O2) .................................................... 4-42

4.6.3 Puffer-Sicherheitsüberprüfung (GS) ........................................................................... 4-43

4.6.4 Sichere Ausnahmebehandlung (SafeSEH) .................................................................. 4-47

4.6.5 Data Execution Prevention (DEP) ............................................................................... 4-48

4.6.6 Address Space Layout Randomization (ASLR) ............................................................ 4-51

4.7 Abschließender Vergleich: XP gegenüber Vista ................................................................. 4-52

5 Fazit ............................................................................................................................................ 5-54

A Literaturverzeichnis .................................................................................................................... 5-56

B Quellcode ................................................................................................................................... 5-60

Page 4: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 4 -

II Abbildungsverzeichnis

Abbildung 2-1: 32-Bit-Windows Standard-Adresslayout nach [ 2 ] .................................................. 2-11

Abbildung 2-2: Prinzipielles Windows Prozess-Speicher-Layout nach [ 3 S. 182 ] und [ 4 S. 397 ] .. 2-13

Abbildung 2-3: Big-Endian im Speicher .............................................................................................. 2-15

Abbildung 2-4: Little-Endian im Speicher ........................................................................................... 2-15

Abbildung 3-1: Die Buffer buf0 und buf1 im Speicher ....................................................................... 3-18

Abbildung 3-2: Buffer Overflow von password_buffer in auth_flag .................................................. 3-21

Abbildung 3-3: Beispielhaftes Stackframe unter Windows allgemein ............................................... 3-22

Abbildung 3-4: Angriffsvektor ............................................................................................................ 3-23

Abbildung 3-5: Beispielhaftes Stackframe unter Verwendung von SEH [ 13 ] .................................. 3-27

Abbildung 4-1: Windows-Zwei-Schichten-Modell [ 4 ] ...................................................................... 4-33

Abbildung 4-2: Optimierte Anordnung von Stack-Elementen bei VS 2003 ....................................... 4-43

Abbildung 4-3: Beispielhaftes Stacklayout unter Verwendung von /GS bei VS 2005 [ 32 ] .............. 4-45

Page 5: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 5 -

III Abkürzungsverzeichnis

ASLR Address Space Layout Randomization

BS Betriebssystem

DACL Discretionary Access Control List

DEP Data Execution Protection, auch bekannt als NX

DoS Denial of Service

Dll Dynamic Link Library

EH Exception Handler

GByte Gigabyte

IE Internet Explorer

LSA Local Security Authority Subsystem Service

NX No eXecute, auch bekannt als DEP

RET Returnaddress

SAL Standard Annotation Language

SEH Structured Exception Handling

SFP Saved Frame Pointer

SID Security Identifier

VS Visual Studio

Page 6: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 6 -

IV Toolsverzeichnis

Programm Bezugsmöglichkeit

Windows power shell http://www.microsoft.com/windowsserver2003/technologies/management/power

shell/default.mspx

Strawberry Perl http://strawberryperl.com/

Process Explorer http://technet.microsoft.com/de-de/sysinternals/default(en-us).aspx

Display Heap Windows Server 2003 Resource Kit Tools

http://support.microsoft.com/kb/168609/de

Global Flags Debugging Tools for Windows

http://www.microsoft.com/whdc/devtools/debugging/default.mspx

Page 7: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 7 -

V Besondere Darstellungsformen In dieser Arbeit kommen im Wesentlichen vier spezielle Gestaltungselemente zur Anwendung

1. Begriffserklärungen und Hinweise sind in einer Box der folgenden Art untergebracht

2. Kommandos

Kommandos die auf der Kommandozeile eingegeben werden (cmd.exe)

sind grau hinterlegt

3. Programmausgaben

Programmausgaben

sind orange hinterlegt

4. Quellcode / Ausschnitte aus Dateien

Auszüge aus Quellcode / Konfigurationsdatein

sind hellblau hinterlegt

Begriffserklärungen und Hinweise

Begriff: Beschreibung oder Definition des Begriffs bzw. Hinweistext

Page 8: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 8 -

1 Überblick

Ausgangssituation

In der Vergangenheit waren Buffer-Overflows eines der Hauptsicherheitsrisiken für Software. In den

letzten Jahren haben Softwarehersteller an diesem Problem intensiv gearbeitet und den Schutz stark

erhöhen können. Das beweisen nicht zuletzt CVE1-Statistiken, die Windows Vista für das Jahr 2008

bis zum Erscheinen dies Dokuments, in dem Monat Juni, nur eine einzige Schwachstelle

bescheinigen, die direkt auf Buffer-Overflows zurückzuführen ist. [ 1 ]

Ziel dieser Arbeit

Das Ziel dieser Arbeit ist es, einen Überblick zu schaffen, welche Mechanismen die Betriebssysteme

Windows XP und Windows Vista zur Vermeidung und zur Schadensbegrenzung von Buffer Overflows

bieten. Dabei wird auf die Schwachstellen der vorhandenen Mechanismen eingegangen und es

werden Wege aufgezeigt, wie sich diese Schwachstellen praktisch auszunutzen lassen. Außerdem hat

es diese Arbeit zum Ziel, die Neuerungen von Windows Vista, dem noch weiter verbreiteten

Windows XP gegenüber zu stellen und so den sicherheitstechnischen Mehrwert von Windows Vista

darzulegen.

An wen richtet sich diese Arbeit

Diese Arbeit richtet sich an alle Leser, die an der definierten Zielsetzung interessiert sind. Zum

vollständigen Verständnis werden jedoch Grundkenntnisse der Programmiersprachen c und x86

Assembler vorausgesetzt. Für Buffer Overflows besonders relevante Punkte sind jedoch grundliegend

beschrieben, so dass die Arbeit auch für Leser ohne Vorkenntnisse aus dem Themengebiet "Buffer-

Overflows" verständlich sein sollte.

Gliederung dieser Arbeit

Die einzelnen Kapitel dieser Arbeit können für sich selektiv gelesen werden. Die beiden

Grundlagenkapitel(Kapitel 2, 3) bauen jedoch aufeinander auf und sollten von Beginn bis Ende

gelesen werden. Zudem wird im Hauptkapitel(Kapitel 4) auf die Angriffsmöglichkeiten bezug

genommen, die im Grundlagenkapitel "Buffer Overflows" erklärt werden.

In dem Kapitel 2 werden einige, für Buffer Overflows wichtige, Grundlagen zur Systemarchitektur

vorgestellt. Der Fokus liegt hierbei speziell auf Eigenheiten des NT-Kerns der Betriebssystemfamilie

Microsoft Windows.

1 National Vulnerability Database: http://nvd.nist.gov/

Page 9: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 9 -

In dem Kapitel 3 wird eine Einführung in das Thema Buffer Overflows gegeben und es werden

einzelne Codestücke präsentiert. Um die Übersichtlichkeit an dieser Stelle nicht unnötig zu

beeinträchtigen sind die vollständigen Programme in einem Zip-Archiv(Kapitel B) zu finden. Ebenfalls

im Kapitel B, finden sich Hinweise zum Übersetzen der jeweiligen Programme mit dem Compiler der

Entwicklungsumgebung Visual Studio 2003 / 2005. Ziel dieses Kapitels ist es, die grundliegenden

Konzepte von Buffer Overflows zu umreißen und einige windows-spezifische Angriffe zu erläutern.

Das Hauptkapitel dieser Arbeit beschäftigt sich im Detail mit den verschiedenen Schutzmaßnahmen

von Windows XP und Vista. Hierbei wird vor allem auf den effektiven Nutzen der einzelnen

Maßnahmen eingegangen. In diesem Zusammenhang werden Implementierungs- und

Designschwachstellen aufgezeigt und objektiv beurteilt. Dabei wird auf die im Kapitel 3 vorgestellten

Angriffe eingegangen und es wird geklärt, warum die Angriffe noch, oder nicht mehr, funktionieren.

Abschließend folg eine Zusammenfassung der wesentlichen Erkenntnisse der wesentlichen

Erkenntnisse und kritischen Blick auf die derzeitigen Entwicklungen.

Page 10: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 10 -

2 Grundlagen – Systemarchitektur

In diesem Kapitel werden Grundlagen aus den Bereichen Betriebssystem- und Rechnerarchitektur

vorgestellt, die für ein fundiertes Verständnis von Buffer Overflows benötigt werden. Dabei wird

speziell auf Eigenheiten des NT-Kernels, der Betriebssystemfamilie Microsoft Windows, eingegangen.

2.1 Speicherorganisation

In diesem Abschnitt wird die Speicherorganisation von Windows XP und Windows Vista grundliegend

erläutert um ein eine Basis für das Verständnis, der in Kapitel 3 beschriebenen Angriffstechniken, zu

schaffen.

2.1.1 Virtueller Speicher

Bei 32-Bit-Windows-Systemen steht einer Anwendung theoretisch der maximal adressierbare

Speicher von 0x00000000 bis 0xFFFFFFFF zur Verfügung, was einer Größe von 2³² Byte = 4 GByte

entspricht. Dabei ist die kleinste adressierbare Einheit ein Byte groß.

Diese 4 GByte teilt Windows in zwei Hälften. Den höherwertigen Bereich verwendet es für

Betriebssystemfunktionen und den niederwertigen Bereich für das Programm selbst. Die Trennung

ist normalerweise, wie in der Abbildung 2-1 zu sehen ist, in der Mitte des Gesamtspeichers

vorgenommen. Dank dem Konzept des virtuellen Adressraums, ist es dabei nicht wichtig, welche

Menge an Arbeitsspeicher das System tatsächlich benötigt. Mit Hilfe der Hardware, zur

Adressvirtualisierung, kann das Betriebssystem die Umsetzung von physikalischen in virtuelle

Adressen erledigen, ohne dass sich ein laufendes Programm darum bemühen muss. Dabei kümmert

sich das Betriebssystem automatisch um das Ein- und Auslagern von Speicher.

Page 11: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 11 -

Benutzermodus-

Prozesse

(2GB)

Systemspeicher

(2GB)

0000000h

(Kleine Adressen)

FFFFFFFFh

(Große Adressen)

7FFFFFFFh

00000000h

80000000h

FFFFFFFFh

Abbildung 2-1: 32-Bit-Windows Standard-Adresslayout nach [ 2 ]

2.1.2 Systemfunktionen

Im Zusammenhang mit Buffer Overflows ist weniger die im letzen Kapitel vorgestellte

Speicheraufteilung interessant, sondern viel mehr die Art wie auf Systemfunktionen zugegriffen wird.

Im normalen Programmbetrieb werden alle benötigten Systemfunktionen, wie beispielsweise

sleep(), in den virtuellen Adressbereich der Anwendung eingeblendet. Beim Übersetzen des

Quellcodes erzeugt der Compiler automatisch die Befehle zum Laden der nötigen Systemfunktionen.

Die Adressen an denen die verschiedenen Systemfunktionen zu finden sind, sind innerhalb eines

Systems normalerweise immer gleich. Unterschiede bezüglich der Funktionsadressen gibt es lediglich

zwischen den einzelnen Windows-Versionen sowie zwischen den verschiedenen Service-Packs. Eine

wirkliche Ausnahme entsteht allerdings durch Address Space Layout Randomization (ASLR), auf das in

dem Kapitel 4.6.4 eingegangen wird.

Ein Beispiel:

Mit dem Programm dumpbin.exe, das Teil von Visual Studio 2005 ist, lässt sich die Basis-Adresse des

Windows-Kernels ermitteln:

PS C:\WINDOWS\system32> dumpbin /headers kernel32.dll | select-string -

pattern "image base" 7C800000 image base (7C800000 to 7C906FFF)

Um nun beispielsweise die Absolute Adresse der Sleep-Funktion zu ermitteln muss noch die relative

Adresse, ausgehend von der Basis-Adresse, ermittelt werden:

Hinweis

Unter 32-Bit-Windows lässt sich

die Aufteilung auch mittels einer

Bootoption in das Verhältnis 3GB

zu 1GB (Programmspeicher zu

Systemspeicher) ändern. Unter

64-Bit-Windows-Varianten ist die

Speicheraufteilung nahezu 50%

zu 50% [ 2 S. 14ff ] .

Außerdem gibt es die Address

Windowing Extensions (AWE) mit

deren Hilfe sich der virtuelle

Speicher vergrößern lässt [ 2 S.

383ff ]

Page 12: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 12 -

PS C:\WINDOWS\system32> dumpbin /all kernel32.dll | select-string -pattern

"sleep" 7C8087E0: 73 6F 75 72 63 65 00 53 6C 65 65 70 00 53 6C 65 source.Sleep.Sle

831 33E 00002442 Sleep

832 33F 0000239C SleepEx

Aus der Basis-Adresse und der relativen Adresse ergibt sich die absolute Adresse der Funktion sleep()

7c800000h + 00002442h = 7c802442h

Wie bereits erwähnt ist diese Adresse bei jedem Programmstart, unter Berücksichtigung der oben

genannten Ausnahmen, gleich.

Tools-Hinweis

Die obigen Kommandos wurden nicht in der normalen Eingabeaufforderung, sondern in der

kostenlos über Microsoft erhältlichen Powershell, ausgeführt. Der Grund hierfür ist, dass in der

Powershell die Funktion select-string() zur Verfügung steht. Bezugsmöglichkeiten: siehe

Toolsverzeichnis

Page 13: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 13 -

2.1.3 Speichersegmente

Der einem Prozess zur Verfügung stehende virtuelle Speicher, teilt sich wie in Abbildung 2-2 zu sehen

ist, in verschiedene Segmente auf. Wichtig sind hierbei vor allem die relative Position der Segmente

zueinander, sowie die Richtung des Schreibzugriffs. Der Schreibzugriff erfolgt immer von einer

Basisadresse in Richtung der höherwertigen Adressen.

Beispielhaftes

Stackframe

Gespeicherte Register der

aufrufenden Funktion

Lokale Variablen

Stack Frame Pointer (SFP)

Return Adresse (RET)

Parameter

Heap

.BSS

.DATA

.TXT

Stack

Systemspeicher

0000000h

(Kleine Adressen)

FFFFFFFFh

(Große Adressen)

Wachstumsrichtung

Heap entspricht einer Dynamischen

Erweiterung des BSS-Segments

(langlebige Daten)

Stack Registerinhalte

lokale Variablen

Funktionsparameter

(kurzlebige Daten)

.TXT Programmkode

.DATA Initialisierte

globale und statische Variablen

.BSS Nicht initialisierte

globale und statische Variablen

Prozess-Speicher

Sch

reib

rich

tun

g

Abbildung 2-2: Prinzipielles Windows Prozess-Speicher-Layout nach [ 3 S. 182 ] und [ 4 S. 397 ]

Page 14: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 14 -

Stack

Der Stack ist das Speichersegment, das zum Ablegen kurzlebiger Daten dient. So werden auf dem

Stack beispielsweise lokale Variablen und Funktionsparameter abgelegt.

In Abbildung 2-2 ist, auf der rechten Seite, ein typisches Stackframe abgebildet. Anhand der Pfeile,

die die Wachstumsrichtung angeben, lässt sich erkennen, dass der Stack von großen Adressen in

Richtung kleiner Adressen wächst.

Das Prinzip eines Stacks, oder auch Stapelspeicher genannt, ist folgendes:

1. Sollen neue, kurzlebige Daten zwischengespeichert werden, so werden diese auf die bereits

auf dem Stack liegenden Daten von oben aufgelegt. Die Operation zum Auflegen neuer

Daten nennt sich "push".

2. Werden die auf dem Stack gelegten Daten zur Verarbeitung benötigt oder muss der Stack

aufgeräumt werden, so wird von oben, Stück für Stück, abgebaut. Die Operation zum

Herunternehmen von vorhandenen Daten nennt sich "pop".

Wenn innerhalb eines Prozesses eine Funktion aufgerufen wird, so werden die benötigten Daten, wie

in der Abbildung 2-2 auf der rechten Seite zu sehen ist, auf dem Stack abgelegt (push). Ist die

Funktion beendet, so werden die Daten in umgekehrter Reihenfolge wieder vom Stack genommen

(pop).

Der Teil des Maschinencodes, der ein Stackframe aufbaut, nennt sich Prolog und der abbauende Teil

nennt sich Epilog.

Genauere Informationen zur Funktionsweise des Stacks können in [ 5 ] gefunden werden.

Heap

Der Heap ist der dynamische Speicherbereich eines Prozesses. Er kann dynamisch in seiner Größe

wachsen, somit kann der Prozess dynamisch Speicher anfordern und freigeben.

Der Heap ist in Abbildung 2-2 im Bereich der niedrigen Speicheradressen zu sehen, was für Windows

typisch ist. Außerdem ist in der Abbildung 2-2 dargestellt, dass der Heap in Richtung großer Adressen

wächst.

Inhaltlich gesehen werden auf dem Heap, verglichen mit dem Stack, langlebigere Daten abgelegt.

Ein Prozess hat typischer Weise mehrere Heaps. Ein neuer Heap kann z. B. mit der Windows-API-

Funktion HeapCreate() angefordert und mit HeapDestroy() wieder freigegeben werden. Das

Anfordern eines Speicherbereiches erfolgt anschließend mit HeapAlloc() und wird analog mit

HeapFree() wieder freigegeben. Bei Verwendung des c++-Operators new, wird automatisch

Speicher von dem Standard-Heap des Prozesses angefordert.

Page 15: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 15 -

Wie bereits angedeutet, hat der Programmierer die Wahl. Entweder er verwendet die von der

Windows-API bereitgestellten Funktionen für das Heap-Management, oder er verwendet seine

eigene Heap-Verwaltung. [ 6 ]

Die von Windows standardmäßig verwendete Heap-Verwaltung organisiert den Speicher in einer

Reihe unterschiedlicher Listen, die zusammen den gesamten Heap beschreiben. Dabei gibt es unter

anderem, eine Liste für noch freie, kleine Speicherblöcke mit Größe 4KByte und eine separat

geführte Liste, die alle belegten Blöcke enthält. Zudem werden temporären Listen erstellt, die der

Geschwindigkeitserhöhung dienen. [ 7 ] [ 8 ] [ 9 ]

2.1.4 Big- und Little-Endian

Als Big- und Little-Endian, werden zwei verschiedene Darstellungsformen von Werten, im Speicher

bezeichnet.

Beispiel: Darstellung der Speicher-Adresse AABBCCDD Hex = 2864434397 Dez im Speicher

Big-Endian: Das höchstwertige Paar steht ganz links, wie in Abbildung 2-3 zu sehen.

BB CCAA DD00000000h FFFFFFFFh

Big-Endian

Abbildung 2-3: Big-Endian im Speicher

Little-Endian: Das höchstwertige Paar steht ganz rechts, wie in Abbildung 2-4 zu sehen.

CC BBDD AA00000000h FFFFFFFFh

Little-Endian

Abbildung 2-4: Little-Endian im Speicher

Page 16: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 16 -

3 Grundlagen – Buffer Overflows

Ziel dieses Kapitel ist es, dem Leser die Grundkonzepte von Buffer Overflows zu vermitteln um so die

von Windows XP und Windows Vista verwendeten Schutzmechanismen besser beurteilen zu können.

Im Folgenden sind immer nur die unmittelbar relevanten Codeabschnitte gelistet. Die vollständigen

Programme mit Hinweisen zum Übersetzen und zugehöriger Programmausgaben sind im Anhang zu

finden.

3.1 Buffer Overflows

Im Kontext der Programmiersprache c, ist ein Buffer ein zusammenhängender Speicherbereich, der

Daten desselben Typs beinhaltet. In c werden Buffer häufig auch als Arrays bezeichnet.

Ein primitiver Buffer kann in c beispielsweise folgende Form haben:

char buf0[4] = "ABC\0";

In diesem Fall ist der Buffer 4 Byte groß und ist ein String-Buffer. Dabei dient das letzte Byte zur

Terminierung des Strings.

Ein Buffer Overflow, oder auch Puffer-Überlauf, passiert demnach, wenn die Grenzen des

vorgesehenen Speicherbereichs überschritten werden.

Die Folgen für das Gesamtsystem können dabei sehr unterschiedlich ausfallen.

So zeigt sich die gefährliche Seite von Buffer Overflows, wenn es dem Angreifer möglich ist

beliebigen Code einzuschleusen und seine Ausführung zu erreichen. In diesem Fall stehen dem

Angreifer nahezu unbegrenzte Möglichkeiten zur Verfügung. Von einem primitiven Beenden der

verwundbaren Software bis hin zum Erstellen von Benutzerkonten oder dem installieren eines Root-

Kits (Details zu Angriffen dieser Art in dem Kapitel 3.1.4).

Wichtiger Hinweis für Selbstversuche

Mit Visual Studio 2005 lassen sich die meisten Beispielprogramme nicht ohne weiteres mit den

erwarteten Ergebnissen übersetzen. Der Grund hierfür sind Optimierungen und

Schutzmechanismen, die der Visual Studio 2005 Compiler verwendet. Hinweise zum

„richtigen“ Übersetzen, sowie die vollständigen Programme finden sich jeweils im Anhang

Page 17: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 17 -

Bei weniger kritischen Programmierfehlern kann es zu inkonsistenten Daten kommen die nicht

zwangsläufige einen Programmabsturz nach sich ziehen müssen und somit lange unentdeckt bleiben

können. Damit beeinträchtigen diese Fehler zwar den Nutzen der Software, die

Angriffsmöglichkeiten können aber, wie das Beispiel im nächsten Abschnitt zeigt, recht beschränkt

sein.

3.1.1 Off-By-One Buffer Overflows

Ein klassischer Buffer Overflow im Zusammenhang mit c-Strings ist der "Off-By-One"-Fehler. Dabei

vergisst der Programmierer entweder den bereits erwähnten String-Terminator mitzuzählen, oder er

ist bei der indexzählweise der Arrays unaufmerksam.

Mit folgenden Programmausschnitten sollen die Folgen eines Off-By-One Overflows verdeutlicht

werden. Das vollständige Programm mit Compiler-Optionen und vollständiger Ausgabe sind im

Quellcode-Archiv zu finden (Kapitel B).

//gekürzt...

char buf0[] = "1234";

char buf1[4] = "ABC\0";

strcpy(buf1,buf0);

Führt man das vollständige Programm aus, so erhält man folgende Ausgabe

~~~ vorher ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Adresse von buf0: 0012FF68 sizeof(buf0): 5 Byte

Adresse von buf1: 0012FF64 sizeof(buf1): 4 Byte

buf0 1234

buf1 ABC

~~~ nachher ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

buf0

buf1 1234

Betrachtet man diese Programmausgabe genauer, so fällt auf, dass der Buffer buf1 zwar den

gewünschten Inhalt erhalten hat, buf0 seinen Inhalt aber offenbar verloren hat.

Was hier passiert ist schnell erklärt: Es kommt zu einen Buffer Overflow, weil der Programmierer

vergessen hat, dass der Compiler an der Stelle char buf0[] = "1234"; automatisch ein 5-Byte

großes, null-terminiertes String-Array erstellt.

Deshalb überschreibt strcpy() mit dem '\0' den ersten Teil des Buffers buf0, der nach buf1 im

Speicher liegt. Die Abbildung 3-1 soll diesen Vorgang verdeutlichen.

Hinweis zum Speicherlayout: Die Anordnung von Variablen im Speicher wird immer zum Zeitpunkt

des Übersetzens festgelegt und wird von dem Compiler entschieden. Der Compiler folgt beim

Erstellen des Speicherlayouts zwar festen Regeln, eine feste Beziehung zwischen der Reihenfolge der

Quellcode: Kapitel-3-1-1_off-by-one\off-by-one.c

Page 18: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 18 -

Definition/Deklaration im Quellcode und dem tatsächlichen Layout existieren jedoch nicht. Zur

Erinnerung: Der Heap unterliegt anderen Regeln, da dieser Speicher erst zur Laufzeit erstellt wird.

A '\0' 2 31CB 4 '\0'

buf1 buf0

1. Vorher

0x0012FF64 0x0012FF68

1 4 2 3'\0'32 4 '\0'3. Nachher

2. strcyp()

Abbildung 3-1: Die Buffer buf0 und buf1 im Speicher

Gibt man mittels printf("buf0 %s\n", buf0); den String buf0 aus, so wird nichts ausgegeben,

weil der String-Terminator bereits an erster Stelle steht und printf() mit dem Formatstring %s, nur

Zeichen bis zu dem ersten vorkommenden '\0' ausgibt.

Off-By-One Buffer-Overflows sind in den meisten Fällen nichts weiter als ärgerliche

Programmierfehler die relativ schwer zu finden sind. Der Nutzen ist für Angreifer bei

Programmierfehlern dieser Art meist sehr beschränkt. Hauptsächlich deshalb, weil der

Speicherbereich der durch den Benutzer beeinflusst werden kann, mit einer Speichereinheit (im

obigen Beispiel 1 Byte) nur sehr wenig Spielraum bietet. Die Folgen hängen aber davon ab, welche

Art von Informationen in den überschreibbaren Bereichen gespeichert sind.

Wie interessant selbst ein Off-By-One Buffer-Overflow werden kann zeigt der folgende Abschnitt.

3.1.2 Mit Buffer Overflows den Kontrollfluss ändern

Im dem folgenden Programm kann ein Buffer Overflow dazu verwendet werden eine Variable zu

überschreiben, die wesentlich für den Ablauf des Programms ist.

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "hacking.h"

int check_authentication(char *password) {

int auth_flag = 0;

char password_buffer[8] = {'F', 'F', 'F', 'F', 'F', 'F', 'F', 'F'};

printf("~~~ vorher ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");

printf("dump: password_buffer\n");

Quellcode: Kapitel-3-1-2_auth_overflow\auth_overflow.c

Page 19: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 19 -

dump(password_buffer, 8);

printf("dump: auth_flag\n");

dump(&auth_flag, 4);

strcpy(password_buffer, password);

if(strcmp(password_buffer, "password") == 0)

auth_flag = 1;

if(strcmp(password_buffer, "adminpw") == 0)

auth_flag = 1;

printf("~~~ nachher ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");

printf("dump: password_buffer\n");

dump(password_buffer, 8);

printf("dump: auth_flag\n");

dump(&auth_flag, 4);

return auth_flag;

}

int main(int argc, char *argv[]) {

//... gekürtzt

if(check_authentication(argv[1])) {

printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");

printf(" Zugang freigegeben.\n");

printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");

} else {

printf("\nZugang verweigert.\n");

}

getchar();

}

Hinweis: die Funktion dump() ist in der Include-Datei hacking.h definiert. Sie gibt von einer, per

ersten Parameter übergebenen Speicheradresse ausgehend, eine mit dem zweiten Parameter

definierte, Menge an Speicherinhalten, aus.

Das Programm übernimmt den ersten Parameter, den das Hauptprogramm übergeben bekommt und

kopiert ihn in der Funktion check_authentication() in einen Buffer, der als Zwischenspeicher

dient.

Stimmt das Passwort mit einem der gespeicherten Passwörter überein, so wird die Variable

auth_flag auf 1 gesetzt, was "wahr" entspricht.

Das Hauptprogramm nimmt den Rückgabewert der Funktion check_authentication() um

Zugang zu einem geschützten Bereich zu gewähren oder zu verweigern.

Page 20: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 20 -

Dabei gibt es in dem Programmfluss keinen Else-Zweig, der im Falle, keiner Übereinstimmung, die die

Variable auth_flag auf 0 setzen würde. Der Programmierer hat diesen Fall durch das Initaialisieren

mit 0 abgedeckt.

Gegen dieses Vorgehen ist prinzipiell nichts einzuwenden. Das Problem mit dem obigen Code ist

jedoch, dass die Funktion strcpy() unabhängig von der Größe des Zielbuffers password_buffer

alle Zeichen bis zum ersten '\0' kopiert.

Diese Frage lässt sich mit Hilfe der Programmausgabe beantworten:

~~~ vorher ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

dump: password_buffer

0012FF54: 46 46 46 46 46 46 46 46 | FFFFFFFF

dump: auth_flag

0012FF5C: 00 00 00 00 | ....

... gekürzt

Wie hier zu sehen ist liegt die Variable auth_flag unmittelbar nach dem Buffer password_buffer

im Speicher.

Das bedeutet, sollte es dem Benutzer möglich sein, dem Programm als ersten Parameter mehr als

acht Zeichen zu übergeben, so findet durch strcpy()ein Buffer Overflow in den Speicherbereich

der Variable auth_flag statt.

Startet man das Programm beispielsweise folgendermaßen:

auth_overflow.exe 12345678A

So erhält man folgende Ausgabe:

~~~ vorher ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

dump: password_buffer

0012FF54: 46 46 46 46 46 46 46 46 | FFFFFFFF

dump: auth_flag);

0012FF5C: 00 00 00 00 | ....

~~~ nachher ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

dump: password_buffer

0012FF54: 31 32 33 34 35 36 37 38 | 12345678

dump: auth_flag);

0012FF5C: 41 00 00 00 | A...

-=-=-=-=-=-=-=-=-=-=-=-=-=-

Access Granted.

-=-=-=-=-=-=-=-=-=-=-=-=-=-

Wie zu sehen ist, hat der Benutzer mittels "12345678" acht Zeichen übergeben und noch ein

zusätzliches 'A' angehängt.

Wie in der Abbildung 3-2 zu sehen ist, wird das 'A' an die Speicheradresse 0x0012FF5C geschrieben.

Der Rückgabewert der Funktion check_authentication() ist als int deklariert und wird durch

das Programm als wahr oder falsch interpretiert. Da in der Programmiersprache c alle Werte ungleich

0 dem Wert "Wahr" entsprechen, wird im Falle eines Overflows der Zugang zum geschützten Bereich

gewährt.

Page 21: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 21 -

F F 0 00FF 0

password_buffer auth_flag

0x0012FF54 0x0012FF5C

F FFF

1 4 0 0A32 05 876

Overflowrichtung

1. Vorher

3. Nachher

2. strcyp()

Abbildung 3-2: Buffer Overflow von password_buffer in auth_flag

Dieses Beispiel zeigt eindrucksvoll, wie bereits ein einziges Zeichen an der richtigen Stelle genügen

kann, um den Ablauf eines Programms wesentlich zu beeinflussen.

Hinweis: Werden in diesem Programm mehr wie zwölf Zeichen übergeben, so stürzt das Programm

ab, da Informationen auf dem Stack überschrieben werden, die für den weiteren Programmablauf

benötigt werden. Abgesehen von Programmabstürzen, bietet diese Möglichkeit der Manipulation

von Werten, einen interessanten Ansatzpunkt für weitere Angriffsmöglichkeiten, auf die in den

folgenden Abschnitten eingegangen wird.

Bei dem zuletzt vorgestellten Overflow, ist außerdem zu bedenken, dass nicht nur Zahlenwerte und

Strings auf diese Weise manipuliert werden können. Es ist ebenso möglich Funktionspointer zu

überschreiben. Auf diese Weise kann wahlfrei, vorhandener, oder auch eingeschleuster

Programmcode ausgeführt werden.

Damit kommt dieses Grundagekapitel zu den "nützlicheren" Angriffsmöglichkeiten mittels Buffer

Overflows: Dem Ausführen von beliebigem Code.

3.1.3 Ausführen von beliebigem Code

Um auf einem Zielsystem beliebigen Code auszuführen sind prinzipiell immer zwei Schritte nötig

1. Den auszuführenden Code in den Arbeitsspeicher des Zielsystems einschleusen

2. Eine Möglichkeit finden den eingeschleusten Code ausführen zu lassen

Der erste Punkt lässt sich, ähnlich wie im Beispiel des letzten Abschnitts, mittels Programmparameter

erreichen.

Der zweite Punkt wird meistens durch das Manipulieren eins Funktionspointers erreicht. Dazu

können vom Programmierer selbst angelegte Funktionspointer verwendet werden, oder aber auch

auf dem Stack liegende Rücksprungadressen. [ 5 ]

Page 22: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 22 -

Da die wirkliche Herausforderung mehr beim Ausführen, als beim Einschleusen liegt, werden in den

restlichen Abschnitten dieses Kapitels einige Möglichkeiten vorgestellt, um den Code zur Ausführung

zu bringen.

3.1.4 Klassische Stack-basierende Angriffe

Stack-basierende Angriffe verfahren normaler weise streng nach dem bereits vorgestellten Schema:

1. Den auszuführenden Code in Arbeitsspeicher des Zielsystems einschleusen

2. Eine Möglichkeit finden den gespeicherten Code ausführen zu lassen

Eine Möglichkeit den Code einzuschleusen haben wir bereits kennen gelernt: Die strcpy()-Funktion.

Kommen wir also zu Punkt zwei: Dem Starten des eingeschleusten Codes.

Bei klassischen Stack-basierenden Angriffen erfolgt das Starten des Codes durch das Manipulieren,

der auf dem Stack gespeicherten Rücksprung-Adresse(RET). Betrachtet man die in Abbildung 3-3

dargestellte Speicherbelegung, so stellt man fest, dass RET an einer höheren Adresse im Speicher

liegt als die lokalen Variablen.

Beispielhaftes

Stackframe

Wa

ch

stu

msrich

tun

g

Gespeicherte Register der

aufgerufenen Funktion

Lokale Variablen

Stack Frame Pointer (SFP)

Return Adresse (RET)

Parameter

0000000h

(Kleine Adressen)

FFFFFFFFh

(Große Adressen)

Ove

rflo

wrich

tun

g

Abbildung 3-3: Beispielhaftes Stackframe unter Windows allgemein

Da lokal angelegte String-Arrays (Buffer) nichts weiter sind als die in Abbildung 3-3 dargestellten

lokalen Variablen, ist es möglich, mit einer ausreichend großen Eingabe die Return-Adresse zu

überschreiben.

Damit der nächste Schritt, das Bestimmen der gewünschten Rücksprungadresse, einfacher ist, wird

als Füllmenge (um RET zu erreichen) ein spezieller Assembler-Befehl verwendet: ein NOP. NOP steht

für No OPeration und hat als einzige Aufgabe einen Maschinenzyklus zu verbrauchen. Danach führt

Page 23: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 23 -

die CPU die Befehlsverarbeitung mit dem darauf folgenden Befehl fort. Typischer Weise werden an

dieser Stelle einige NOPs aufeinander folgen und bilden so einen NOP-Sled2.

Um nun den eingeschleusten Code ausführen zu lassen, muss RET auf den ersten eingeschleusten

Befehl zeigen. Wenn ein NOP-Sled verwendet wird, reicht es an dieser Stelle aus, einen beliebigen

Punkt auf dem NOP-Sled zu treffen. Das ist besonders hilfreich, weil der Compiler mit dem das

verwundbare Programm übersetzt wird möglicher Weise einige Optimierungen durchführt, die die

exakte Positionsbestimmung des ersten Befehls erschweren können. Aus demselben Grund ist es

üblich die gewünschte Return-Adresse mehrfach zu wiederholen.

Besondere Aufmerksamkeit muss man der Ausrichtung der eingeschleusten Return-Adresse widmen.

Das bedeutet man muss darauf achten, dass das erste Byte der selbst geschriebenen Return-Adresse

auch wirklich über das erste Byte der alten Return-Adresse geschrieben wird. Ohne Verwendung

eines Debuggers, lässt sich die korrekte Ausrichtung am einfachsten durch Probieren finden. Dabei

sollten maximal vier Versuche nötig sein, da eine Adresse bei 32-Bit-Systemen nur 4 Byte groß ist und

es somit nur vier Möglichkeiten gibt.

Die absolute Adresse des Puffers wird meist mittels eines Debuggers ermittelt und auf x86-Systemen

in Little-Endian-Anordnung eingebgeben. Interessant hierbei ist auch, dass der Stack eines Prozesses

immer an derselben Adresse beginnt, was bedeutet, dass auch hier Probieren zum Ziel führen kann.

Alternativ können zur Positionsbestimmung von Buffern auch Formatstring-Verwundbarkeit

verwendet werden [ 5 ] . Auf Formatstrings wird in dieser Arbeit jedoch nicht eingegangen, weil sie

nicht Teil des Themas "Buffer-Overflows" sind.

Insgesamt wird dem auszunutzenden Programm die in Abbildung 3-4 dargestellte Kombination

übergeben. Diese Kombination aus NOP-Sled, Payload3 und widerholter Return-Adresse, wird häufig

als Angriffsvektor bezeichnet.

NOP-sledRET

(mehrfach wiederholt)Payload

Abbildung 3-4: Angriffsvektor

Bleibt noch zu erwähnen, dass die Speichermenge die für den Payload zur Verfügung steht, durch die

Position der Return-Adresse begrenzt ist. Dieses Problem lässt sich aber durch einen relativen

Sprung, nach den Speicherbereich mit der Return-Adresse umgehen. [ 10 ]

2 NOP-Sled/NOP-Sledge: Übersetzt: NOP-Schlitten. Das bedeutet, eine Folge von NOPs führen direkt, ohne jede weitere

Funktion, zu dem nächsten „richtigen“ Maschinenbefehl. Beispielsweise dem ersten Befehl des Sehellcodes.

3 Der Payload/Shellcode besteht aus Maschinencode. Er ist der Teil des einzuschleusenden Codes, der die eigentliche

Funktionalität beinhaltet. Häufig werden die Begriffe Payload und Shellcode als Synonym verwendet. Details zu Shellcode werden in dem Kapitel 3.2 behandelt

Page 24: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 24 -

Beispiel: stack-overflow.c im Quellcode-Ordner "Kapitel-3-1-4_stack-overflow"

Eine Variante des Programms auth_overflow.c ist unter dem Namen stack-overflow.c Quellcode-

Archiv zu finden. Dieses Programm bekommt seine Eingabe dabei nicht als Parameter, sondern liest

von einer Datei. Außerdem wird nicht die Funktion strcpy() verwendet, sondern die Funktion

memcpy(). Für diese Modifikationen gibt es zwei Gründe:

1. Mit der Windows-Eingabeaufforderung ist es nicht ohne weiteres möglich einem Programm,

per Parameter Zeichen zu übergeben, die nicht "druckbar" sind. Da das auf die meisten

Maschinenbefehle zutrifft, ist ein einfaches Einschleusen von Code über die Kommandozeile

nicht möglich. Abhilfe würde an dieser Stelle das Programm cat4 schaffen mit dem man die

Eingabe an das Programm umleiten kann. Cat ist aber nicht Bestandteil von Windows. Zudem

besteht das Problem der Parameterübergabe mit nichtdruckbaren Zeichen auch in den

meisten Debuggern. Aus diesem Grund liest das Demo-Programm aus einer Datei.

2. Wie in dem Abschnitt 2.1 beschrieben, liegt der für das Programm selbst zur Verfügung

stehende Speicher im niederen Adressbereich. Deshalb ist die Wahrscheinlichkeit sehr hoch,

dass der Buffer in dem der eingeschleuste Code liegt in einem Adressbereich liegt, der mit

zwei führenden Nullen (0x00AABBCC) beginnt. Das bedeutet, dass strcpy() die

Speicheradresse nicht mehr kopiert. Es gibt eine Reihe von Möglichkeiten den

eingeschleusten Code trotz dieses strcpy()-Problems zur Ausführung zu bringen

(beispielsweise "return to libc"). Um das Beispiel einfach zu halten wird dieses Problem an

dieser Stelle durch die Verwendung von memcpy() umgangen.

Trotz dieser zwei Vereinfachungen, bleibt das demonstrierte Prinzip in allen Fällen gleich: Den

Angriffsvektor einschleusen und den Maschinencode zur Ausführung bringen.

Ein funktionierender Angriffsvektor zu dem Programm stack-overflow.c ist ebenfalls im Quellcode-

Archiv zu finden. Dabei wird der Angriffsvektor mittels eines Perl-Skripts generiert. Der hierbei

verwendete Payload startet hierbei nichts weiter als den Windows-Taschenrechner clac.exe. Details

zur Erstellung von Payload folgt in dem Abschnitt 3.2.

4 cat ist ein Kommandozeilen-Tool aus der UNIX-Welt, mit dem sich unter anderem sehr einfach Eingaben aus einer Datei

lesen lassen. Das Tool gibt es auch für Windows

Tools-Hinweis

Die felxibelste Möglichkeit einen Angriffsvektor zu erstellen ist mit der Programmiersprach Perl.

Perl gibt es auch für Windows: Toolsverzeichnis IV

Page 25: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 25 -

Gekürzte Ausgabe des Programms stack-overflow.exe

~~~ nachher ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

dump(password_buffer...);

0012FA48: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 | ................

0012FA58: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 | ................

0012FA68: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 | ................

0012FA78: 29 c9 83 e9 dd d9 ee d9 74 24 f4 5b 81 73 13 b3 | ).......t$.[.s..

0012FA88: 87 5d 85 83 eb fc e2 f4 4f 6f 19 85 b3 87 d6 c0 | .]......Oo......

0012FA98: 8f 0c 21 80 cb 86 b2 0e fc 9f d6 da 93 86 b6 cc | ..!.............

0012FAA8: 38 b3 d6 84 5d b6 9d 1c 1f 03 9d f1 b4 46 97 88 | 8...]........F..

0012FAB8: b2 45 b6 71 88 d3 79 81 c6 62 d6 da 97 86 b6 e3 | .E.q..y..b......

0012FAC8: 38 8b 16 0e ec 9b 5c 6e 38 9b d6 84 58 0e 01 a1 | 8.....\n8...X...

0012FAD8: b7 44 6c 45 d7 0c 1d b5 36 47 25 89 38 c7 51 0e | .DlE....6G%.8.Q.

0012FAE8: c3 9b f0 0e db 8f b6 8c 38 07 ed 85 b3 87 d6 ed | ........8.......

0012FAF8: 8f d8 6c 73 d3 d1 d4 7d 30 47 26 d5 db f9 85 67 | ..ls...}0G&....g

0012FB08: c0 ef c5 7b 39 89 0a 7a 54 e4 3c e9 d0 a9 38 fd | ...{9..zT.<...8.

0012FB18: d6 87 5d 85 50 fa 12 00 50 fa 12 00 50 fa 12 00 | ..].P...P...P...

0012FB28: 50 fa 12 00 50 fa 12 00 50 fa 12 00 50 fa 12 00 | P...P...P...P...

0012FB38: 50 fa 12 00 50 fa 12 00 50 fa 12 00 50 fa 12 00 | P...P...P...P...

0012FB48: 50 fa 12 00 50 fa 12 00 50 fa 12 00 50 fa 12 00 | P...P...P...P...

0012FB58: ff | .

dump(&auth_flag, 4);

0012FA44: 00 00 00 00 | ....

Erklärung:

1. Der Wert 90 Hex entspricht einem NOP

2. Der rot markierte Bereich ist der Maschinencode zum Starten von calc.exe

3. Am Schluss folgt die mehrfach wiederholte Return-Adresse

3.1.5 Exception Handler-basierende Angriffe

Die Programmiersprache c bietet von sich aus keinerlei Möglichkeiten, Ausnahmen im

Programmablauf abzufangen. Eine solche Ausnahme ist beispielsweise eine Division durch Null. Mit

C++ wurde dieser Missstand behoben und es ist somit, durch Elemente der Programmiersprache,

möglich eine Ausnahmebehandlung durchzuführen. Das bedeutet, dass ein Programm, das eine

Division durch null durchführt, nicht mehr zwangsläufig abstürzt, sondern durch eine geeignete

Ausnahmebehandlung weiterlaufen kann. [ 11 ]

Microsoft hat für die Programmiersprache c eigene Elemente eingebracht, mit denen eine

Ausnahmebehandlung möglich wird: __try und __except

Diese Art der Ausnahmebehandlung nennt sich Structured Exception Handling (SEH). Im Unterschied

zu c++ wird die Art der Ausnahme mittels eines unsigned int ermittelt, während in c++ anhand des

Klassen-Typs unterschieden wird. [ 11 ] [ 12 ]

NOP-sled

RET

(mehrfach wiederholt)

Payload

Page 26: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 26 -

Beispiel: Strukturierte Ausnahmebehandlung (SEH) - Division durch Null

#include <stdio.h>

int MyExceptionHandler(void);

int main(int argc,char *argv[]){

int a = 1000, b = 0, c = 0;

if(argc != 2){

printf("Divisor als Parameter uebergeben\n");

exit(0);

}

b = atoi(argv[1]);

/* Falls eine 0 als erster Programmparameter übergeben wird, wird

* eine EXCEPTION_INT_DIVIDE_BY_ZERO ausgelößt */

__try {

c = a / b;

printf("Ergebnis der Division %i / %i = %i\n", a, b, c);

} __except ( MyExceptionHandler() ){}

printf("Programm beendet sich\n");

return 0;

}

/* return 1, damit die Exception nicht and das

* Betriebsystem weitergereicht wird */

int MyExceptionHandler(void){

printf("Exception.. Ausnahme abgefangen und als behandelt markiert");

return 1;

}

SEH lässt sich im Zusammenhang mit Buffer Overflows nutzen, um eingeschleusten Code zur

Ausführung zu bringen. Dabei macht sich der Angreifer den Umstand zu nutze, dass die

Funktionsadresse der Funktion zur Ausnahmebehandlung, wie in Abbildung 3-5 zu sehen ist, auf dem

Stack gespeichert wird.

Quellcode: Kapitel-3-1-5_exception\exception.c

Page 27: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 27 -

Beispielhaftes

Stackframe

Wa

ch

stu

msrich

tun

g

Gespeicherte Register der

aufgerufenen Funktion

Lokale Variablen

Stack Frame Pointer (SFP)

Return Adresse (RET)

Parameter

0000000h

(Kleine Adressen)

FFFFFFFFh

(Große Adressen)

Ove

rflo

wrich

tun

g

...

Pointer zur nächsten

SEH-Funktion

Pointer zur SEH-Funktion

Abbildung 3-5: Beispielhaftes Stackframe unter Verwendung von SEH [ 13 ]

Wie bei den klassischen Stack-basierenden Buffer Overflows, wird von einem verwundbaren Buffer

ausgehend, diese Funktionsadresse im Speicher überschrieben. Der Unterschied besteht lediglich

darin, dass die Behandlung der Ausnahme veranlasst werden muss, z. B. mit einer Division durch

Null. [ 14 ]

Interessant ist hierbei, dass jedes Programm mindestens einen, automatisch erstellten SEH besitzt,

den der main()-Routine.

Im Quellcode-Archiv findet sich im Ordner "Kapitel-3-1-5_exception_exploit" ein vollständiges

Beispiel, wie sich SEH unter Windows praktisch ausnutzen lässt.

3.1.6 Heap-basierende Angriffe

Heap-basierende Angriffe funktionieren prinzipiell genauso, wie alle anderen Buffer-Overflows auch.

Es werden Daten überschrieben, die nach einem verwundbaren Puffer im Speicher liegen. Der

einzige Unterschied besteht darin, dass, verglichen mit den anderen Datensegmenten, im Heap

andere Daten gespeichert sind.

Folgende Daten finden sich vermehrt bzw. nur auf dem Heap:

1. Nutzdaten. Beispielsweise die Variable auth_flag aus dem Abschnitt 3.1.2 (gibt es auch auf

beim Stack)

Page 28: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 28 -

2. Daten die den Programmablauf steuern und vom Programmierer bewusst angelegt wurden

(auch auf dem Stack vorhanden, aber selten)

3. Daten die den Programmablauf steuern und vom Compiler automatisch angelegt werden

4. Daten die der Speicherverwaltung dienen. Beispielsweise das Windows-Heap-Management

Den Punkt "Nutzdaten", wurde bereits in dem Abschnitt 3.1.2 ausführlich behandelt und da an dieser

Stelle keine wesentlichen Unterschiede existieren, wird an dieser Stelle nicht näher darauf

eingegangen.

Der zweite Punkt ist vom prinzipiellen Vorgehen bereits bekannt.

Der Punkt Nummer Drei bietet interessante Möglichkeiten, ist in der Praxis jedoch kaum anzutreffen.

Punkt Nummer Vier hat in den letzten Jahren deutlich an Bedeutung gewonnen und ist vor allem im

Zusammenhang mit dem Windows-Heap-Management interessant. Deshalb wird im Folgenden das

prinzipielle Vorgehen bei Angriffen auf das Windows-Heap-Management erläutert.

Angriffe auf das Windows-Heap-Management

Wie bereits in dem Abschnitt 2.1.3 beschrieben, ist ein Heap, der mit HeapCreate()erzeugt wird,

durch eine Reihe von Listen organisiert. Wird mit der Funktion HeapAlloc() ein Speicherbereich

angefordert, so wird von der Heapverwaltung ein passendes Stück Speicher gesucht. Dieses Stück

Speicher wird, unmittelbar vor dem nutzbaren Bereich, mit einem Header versehen, der

Informationen für die Heapverwaltung enthält. [ 15 ] [ 8 ]

Bei Angriffen auf die Heapverwaltung ist es das Ziel, die Headerinformationen derart zu

manipulieren, dass eine begrenzte Menge an Daten an eine beliebige Stelle im Speicher geschrieben

werden kann. Hierbei macht sich der Angreifer zunutze, dass die Headerinformationen Pointer

enthalten, die zur Verkettung der Listen und zur Referenzierung des Nutzspeichers dienen. Beim

Anfordern und Freigeben von Speicher werden die Header teilweise kopiert und unter bestimmten

Bedingungen in einer doppelt verketteten Liste gespeichert. Zur Bestimmung der jeweiligen

Nachbarelemente werden die Headerinformationen verwendet. Somit ist es möglich, durch gezieltes

Überschreiben der entsprechenden Pointer, einen wahlfreien Schreibzugriff mit einer Datenmenge

von 4 Bytes zu erreichen. Dieser Vorgang lässt sich prinzipiell beliebig oft wiederholen, meist ist

jedoch eine Menge von 4 Bytes vollkommen ausreichend, da dies die Größe eines Pointers ist. Somit

lässt sich beispielsweise im Process Execution Block (PEB) ein Pointer überschreiben. Hier bietet sich

der Pointer auf die Funktion ExitProcess() an, die vor dem endgültigen Beenden des Prozesses

ausgeführt wird. Durch das Überschreiben des ExitProcess()-Pointers kann eingeschleuster Code

durch das Beenden des Programms zur Ausführung gebracht werden. [ 15 ] [ 8 ] [ 16 ] [ 17 ] [ 18 ] [

16 ] [ 19 ]

In der Praxis gibt es eine Vielzahl von Variationen der eben beschriebenen Methode. Hierbei haben

jedoch alle Varianten die Gemeinsamkeit, dass sie durch gezieltes Manipulieren der Header, Code zur

Ausführung bringen.

Page 29: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 29 -

Einen besonderen Reiz haben vor allem die Varianten, die es dem angegriffenen Programm

ermöglichen weiter zu laufen, indem sie die beschädigten Heapstrukturen wieder mit gültigen

Werten reparieren. Ein weiterer Grund für die gestiegene Popularität von Angriffen auf das

Heapmanagement sind vor allem Mechanismen, die zum Schutz des Stacks eingeführt wurden und

den Heap so zum schwächsten Glied der Kette werden ließen. Details zu aktuellen

Schutzmechanismen des Stacks werden im Kapitel 4.6 behandelt.

3.2 Shellcode und Payload

Die beiden Begriffe Shellcode und Payload werden heutzutage häufig als Synonym verwendet. Streng

genommen ist der Shellcode jedoch eine spezielle Form des Payloads:

1. Der Payload an sich ist der Teil des Angriffsvektors, der die eigentliche Funktionalität

beinhaltet, also beispielsweise das Starten des Windows-Taschenrechners.

2. Der Shellcode ist streng genommen ein spezieller Payload, der eine Shell

(Eingabeaufforderung) startet, mit der der Angreifer interagieren kann.

In dieser Arbeit wird häufig ebenfalls der Begriff "Shellcode", anstelle des historisch korrekten

Begriffes verwendet. Die Begründung ist die Tatsache, dass der Begriff Shellcode einen höheren

Wiedererkennungswert bietet und selbst in Printmedien gebräuchlicher ist.

Da das Thema Shellcode, bei sorgfältiger Behandlung, den Umfang dieser Arbeit bei weitem

sprengen würde, wird im Folgenden nur stichpunktartig auf Anforderungen an Shellcode

eingegangen.

3.2.1 Anforderungen an Shellcode

Anforderungen an die Darstellung des Shellcodes :

1. Zeichensatz: Shellcode unterliegt einigen Einschränkungen bezüglich der verwendbaren

Zeichen. Beispielsweise darf in Shellcode der durch strcpy() eingeschleust wird, nicht das

Zeichen 0x00 vorkommen, weil strcpy() nur bis zu diesem Zeichen kopiert. Außerdem werden

die eingegebenen Zeichen häufig von dem angegriffenen Programm geprüft und z. B. nur

druckbare Zeichen verarbeitet.

2. Kompatibilität: Die Kompatibilität von Shellcode ist unumgänglich auf eine Art der

Speicheranordnung beschränkt: entweder Big- oder Little-Endian.

3. Kodierung: Soll eine Funktion angegriffen werden die eine UTF-8 kodierte Zeichenfolge

erwartet, so muss außer der Big- und Little-Endian-Anordnung außerdem eine bestimmte

Reihenfolge von Zwei-Byte-Paaren eingehalten werden. [ 20 ]

4. Kompaktheit: Häufig ist die Menge an einschleusbaren Zeichen beschränkt.

5. Unentdeckt bleiben: Unter Umständen passiert der Shellcode auf dem Weg zum Ziel

Intrusion Detection Systeme (IDS), die die übertragenen Daten auf bekannte Schad-

Signaturen hin überprüfen.

Page 30: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 30 -

Anforderungen an die Logik des Shellcodes:

1. Betriebssystemabhängig: Da die meisten Betriebssysteme einen grundliegend

unterschiedlichen Zugriff auf Systemfunktionen haben, muss der Shellcode meistens

Betriebssystemspezifisch sein.

2. Behandlung der Anwendung: Unter bestimmten Umständen hat man die Möglichkeit, das

angegriffene Programm weiter laufen zu lassen und so die Wahrscheinlichkeit, das der

Angriff entdeckt wird stark zu reduzieren.

3.2.2 Besonderheiten von Windows-Shellcode

Verglichen mit Shellcode der unter Linux lauffähig ist, gibt es für Windows-Shellcode eine Reihe von

Besonderheiten

1. Windows-Shellcode ist größer als Linux-Shellcode [ 21 ]

2. Keine 1-zu-1-Abbildung der Bibliotheksfunktionen des Betriebssystems zu den Systemcalls auf

Kernelebene [ 21 ]

3. Die verwundbaren Buffer liegen meist in einem Speicherbereich, der mit 0x00… beginnt und

somit ein nicht verwendbares Zeichen darstellt.

3.2.3 Was möglich ist

Je nachdem welchen Anforderungen (siehe 3.2.1) der eingeschleuste Code unterliegt, ergeben sich

unterschiedliche Möglichkeiten:

1. Erweitern der Rechte durch angreifen von lokalen Prozessen die mit umfangreicheren Privilegien

ausgestattet sind.

2. Nachladen von Systemfunktionen, falls der Prozess eine für den Angriff wichtige Dll-Funktion5

nicht geladen hat, kann man diese Dll selbst nachladen.

3. Nachladen von Code, falls der eingeschleuste Code in seiner Größe beschränkt war, hat man die

Möglichkeit z. B. aus dem Internet Code nachzuladen. [ 21 ]

Wenn man davon ausgeht, dass man die Möglichkeit hat, eine unbegrenzte Menge an

eingeschleusten Code, mit Administrator-Rechten auszuführen, dann hat man praktisch keine

Einschränkungen mehr. Man kann beispielsweise:

1. Ein lokales Benutzer-Konto erstellen (Local Access)

2. Einen Prozess starten, der beliebige Befehle über das Netzwerk ausführt (Remote Access)

3. Einen Keylogger installieren, der sämtliche Aktivitäten des Benutzers aufzeichnet, inklusive

Tastatur- und Mausinteraktion (Spionage)

5 Dynamic Link Library (Dll)

Page 31: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 31 -

3.2.4 Abstraktes Beispiel: Portbind Shellcode für Windows

An dieser Stelle folgt ein eine allgemeine Beschreibung, der Vorgehensweise, zum Starten einer

Remote-Shell: [ 21 ]

1. Suchen der Datei kernel32.dll

2. Auflösen der Symbole GetProcAddressA(), LoadLibraryA() sowie ExitProcess()

3. Laden der Winsock Bibliothek ws2_32.dll

4. eine Shell an einen TCP-Port binden

4.1. Socket erzeugen

4.2. Socket an Port binden

4.3. Auf dem Port auf eingehende Verbindung warten

4.4. Verbindung akzeptieren

5. Kommandointerpreter starten

6. Den Elternprozess sauber beenden oder die beschädigten Strukturen reparieren

Um nicht zu sehr vom eigentlichen Thema, den Buffer Overflows, abzukommen, wird an dieser Stelle

nicht weiter auf das Themengebiet Shellcode eingegangen. Interessierten sei [ 21 ] für weitere

Informationen empfohlen.

Es folgt nun eine Vorstellung der Verschiedenen Mechanismen in Windows, die dazu dienen den

Schaden durch Buffer-Overflows so gering wie möglich zu halten.

Page 32: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 32 -

4 Das Sicherheits-Ensemble von Windows und seine Schwachstellen

Dieses Kapitels hat es zum Ziel, die Frage nach dem betitelten Stack- und Heap-Overflow-Schutz bei

Windows XP und Windows Vista zu klären. Nicht eingegangen wird auf weitere nützliche Funktionen

zur Erhöhung der Sicherheit, die nichts direkt mit Buffer-Overflows zu tun haben.

Die vorhergegangenen beiden Grundlagenkapitel, haben sich im Wesentlichen damit beschäftigt,

welche Bedingungen, unter früheren Windowsversionen, gegeben sein mussten, um einem Buffer-

Overflow erfolgreich auszunutzen.

Dieses Kapitel beschäftigt sich zu Beginn damit, wie sich der Schaden, eines unter fremder Kontrolle

stehenden Programms, einschränken lässt und welche neuen Ansätze mit Windows Vista verfolgt

werden (bis einschließlich Kapitel 4.2).

Anschließend werden Methoden von Windows XP und Vista analysiert und bewertet, die es zum Ziel

haben, Angriffe mittels Buffer-Overflows so früh wie möglich zu entschärfen.

4.1 Das Windows-Zwei-Schichten-Modell

Den grundlegendsten Schutzmechanismus der Windows-Architektur bildet das Zwei-

Schichtenmodell.

Unter Windows ist die gesamte Funktionalität in zwei unterschiedlich privilegierte Bereiche

eingeteilt: [ 4 ]

Kernel-Mode (Ring 0): Der Modus mit den höchstmöglichen Privilegien – Keine

Einschränkungen beim Zugriff auf die Ressourcen des Kernels

User-Mode (Ring 1): Eingeschränkter Modus – Beim Zugriff auf Systemressourcen muss eine

ganze Abfolge von Funktionen abgearbeitet werden, die vom Ring0 als Services zur

Verfügung gestellt werden.

Häufig werden User- und Kernel-Mode wie in Abbildung 4-1 grafisch dargestellt. Dabei soll

symbolisiert werden, dass auf die innen liegenden Funktionen und Ressourcen nur über die

verbindende Schicht zugegriffen werden kann.

Page 33: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 33 -

Abbildung 4-1: Windows-Zwei-Schichten-Modell [ 4 ]

Im Ring0 finden sich vorrangig Gerätetreiber und Systemfunktionen. Im Ring1 hingegen findet sich

alles Übrige, z. B. ein Browser oder ein FTP-Server.

Schafft es ein Angreifer direkt im Ring0 einen Programmierfehler für sich zu nutzen, so stehen im

praktisch keine Hindernisse mehr im Weg. Allerdings erfordern Angriffe auf dieser Ebene sehr

spezifisches Detailwissen, das äußerst selten offen zugänglich ist. Dies ist auch der Grund dafür, dass

Angriffe auf den Ring0 verhältnismäßig selten vorkommen. Ein Beispiel für einen erfolgreichen

Angriff auf den Gerätetreiber diverser W-LAN-Chips ist der Angriff von Jon Ellch (Pseudonym: Jonny

Cache)[ 22 ] . [ 4 ] [ 23 ]

Meist ist es aus dem oben genannten Grund einfacher, eine verwundbare Anwendung im Ring1

anzugreifen. Jedoch haben Prozesse im Ring1 einen Prozess-Kontext, der einen

rechtebeschreibenden Token beinhaltet. Näheres dazu im nächsten Abschnitt.

4.2 Zugriffsrechte, Authentifizierung und Access Token

Meldet sich ein Benutzer an einem Windows-System an, so bekommt er vom Local Security Authority

Subsystem Service (LSA) ein Access Token zugeteilt. Dieser Token besteht aus einem Security

Identifier (SID), der zu seinem Benutzerkonto gehört, und einigen weiteren SIDs, die zu seinen

Gruppen gehören in denen er Mitglied ist. Eine solche SID ist eine 48 Bit lange Nummer, die

domainweit einzigartig ist. Außerdem enthält der Token, falls definiert, eine Liste von nicht erlaubten

SIDs und eine Liste mit Privilegien, die zu den jeweiligen SIDs gehören. Privilegien sind z. B. das Recht

einen Treiber zu laden (SeLoadDriverPrivilege) oder das Recht den Computer herunterzufahren

(SeShutdownPrivilege).[ 4 ] [ 24 ]

Ring1(User-Mode)

Ring0(Kernel-Mode)

Kernel

Page 34: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 34 -

Alle Ressourcen, auf die ein Benutzer theoretisch zugreifen kann, haben eine so genannte

Discretionary Access Control List (DACL)6. Praktisch wird der Zugang auf die Ressource durch LSA

reglementiert. Das bedeutet, der Zugriff ist nur erlaubt, wenn eine der SIDs aus dem Token des

Benutzers in der DACL-Liste unter dem entsprechenden Privileg (Lesen, Schreiben usw.) zu finden ist.

[ 4 ]

Nach [ 4 ] lässt sich zur besseren Übersicht eine Einteilung in Subjekte und Objekte vornehmen

1. Subjekte: Einheiten, die Aktionen durchführt – unter Windows sind das Prozesse

2. Objekte: Sind die Empfänger einer Aktion – unter Windows zugriffsgeschützte Objekte mit

zugehörigen DACL wie z. B. Dateien und Registry-Einträge

4.2.1 Rechte von Prozessen unter Windows

Startet ein am System angemeldeter Benutzer einen Prozess, so wird in dem Prozess-Kontext der

Token des Benutzers gespeichert. Fortan darf der Prozess (Subjekt) auf alle Ressourcen (Objekte)

zugreifen, auf die auch der Benutzer durch seinen Token Zugriff hat.

Ist nun unter Windows XP ein Administrator am System angemeldet und startet den Internet

Explorer, so hat der Browser denselben Token wie der Administrator. Surft der Administrator nun

beispielsweise über eine Seite, die den populären Animated-Cursor Exploit7 eingebaut hat, so stehen

dem Angreifer keinerlei Hindernisse im Weg. Er hat dank des hoch-privilegierten Token, mit der SID

des angemeldeten Administrators, vollständigen Zugriff auf das gesamte System.

Mit Windows 2000 wurde die Möglichkeit eingeführt, einen Kindprozess/Thread mit einem

eingeschränkten Token zu starten. Der eingeschränkte Token kann, ausgehend von dem Original-

Token, wie folgt definiert werden: Privilegien entfernen, SIDs entfernen, nicht erlaubte SIDs

hinzufügen. Wurde ein Thread mit einem eingeschränkten Token gestartet, so ist er an die neuen

Einschränkungen gebunden. Allerdings ist es möglich dem Thread mit dem eingeschränkten Token,

wieder den uneingeschränkten Token zuzuweisen. Weil diese Möglichkeit besteht, empfiehlt es sich

die API-Funktion CreateProcessAsUser( ) zu verwenden, so dass diese Möglichkeit nicht mehr

besteht. [ 24 ]

Mit Windows Server 2003 wurde es möglich die Privilegien eines Prozess-Token dauerhaft

einzuschränken. Diese Möglichkeit ist aber ungleich der des eingeschränkten Token, da hier der

Prozess dauerhaft seine eigenen Privilegien beschneidet. Alle von ihm erzeugten Kindprozesse erben,

nach demselben Prinzip wie bei Windows 2000, den Token des Elternprozesses, z. B. einen, in den

Privilegien eingeschränkten. Die Möglichkeit die SIDs des Token zu modifizieren besteht hier nicht.[

24 ]

6 DACL wird in der Literatur häufig auch ohne das führende D, nur als Access Control List (ACL), verwendet.

Außerdem wird häufig der Ausdruck Security Descriptor als Synonym verwendet. 7 Animated-Cursor Exploit: http://www.securityfocus.com/advisories/7814

Page 35: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 35 -

4.2.2 Windows Service Hardening

Da auch Windows-Services nichts weiter wie Prozesse sind, haben auch sie einen Token über den sie

im Betrieb ihre Berechtigungen erhalten. Für einen Angreifer sind damit die Standard-Services einer

Windows-Installation besonders interessant, weil sie aufgrund ihrer Funktionalität ständig laufen und

typischer Weise Systemfunktionen ausführen, die hohe Privilegien benötigen.

Mit Windows Server 2003 wurden zwei neue Service-Konten eingerichtet die den bisher

übermächtigen LocalSystem entlasten sollten: LocalService und NetworkService. Dabei sind die

beiden neuen Konten in den Rechten derart beschnitten, dass viele Services nicht mit ihnen arbeiten

können und deshalb den bisherigen LocalSystem weiterhin verwenden.[ 4 ]

Zur verbesserten Schadensbegrenzung wurde bei Windows Vista eine Reihe von Maßnahmen

eingeführt, die ein erheblich granulareres Rechtemanagement wie bisher ermöglichen:

1. Service-spezifische SIDs: Jeder Service hat eine eigene SID. Sinnvoller Weise bekommen nur

diejenigen Objekte in ihrer DACL die SIDs des speziellen Services eingetragen, die sie auch

wirklich benötigen.[ 4 ]

2. Eingeschränkte SIDs: Die RESTRICTED-SID kennzeichnet einen Prozess, der ein

eingeschränktes Token enthält. [ 25 ] (nicht auf Services beschränkt)

3. Reduzierte Privilegien für Services: Überflüssige Privilegien, wie das Debugging Privileg

wurden den Diensten generell entzogen [ 4 ]

4. Session 0 Isolation: Unter Windows Server 2003 und früheren Versionen, war es unter

Umständen möglich seine Privilegien durch Angriffe auf Services mit höheren Privilegien

innerhalb derselben Session zu erweitern. Diese Problem wird dadurch entschärft, dass nur

noch Services in der Session 0 laufen und alle vom User gestarteten Anwendungen in

eigenen Session (1 und höher) gestartet werden. [ 26 ] [ 27 ]

5. UAC: siehe nächster Abschnitt (nicht auf Services beschränkt)

4.2.3 Rechte von Prozessen unter Windows Vista: UAC

Es ist zwar bekannt, dass es sich nicht empfiehlt mit Administratorrechten im Internet zu surfen, die

Konsequenz als normaler Benutzer an einem System zu arbeiten, haben jedoch nur wenige

Anwender gezogen. Der Hauptgrund hierfür ist die mangelnde Unterstützung seitens Windows. So ist

es bis zu der Version "Vista" nötig gewesen, eine Druckerinstallation oder das Stellen der Uhrzeit mit

Administratorrechten zu erledigen.

UAC steht für User Account Control und soll das Arbeiten als eingeschränkter Benutzer erleichtern.

Dazu fragt Windows Vista den Benutzer, falls nötig, automatisch nach dem Passwort, für das

Benutzerkonto, dass zum ausführen der Aktion nötig ist. Dabei ist die Interaktion mit den BS solange

gesperrt, bis der Benutzer auf die Anfrage reagiert hat.

Page 36: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 36 -

Im Detail verwendet UAC eine neue Technik namens Mandatory Integrity Control (MIC). MIC ist eine

Erweiterung für die DACLs um sogenannte Integrity Level (IL). Gespeichert werden diese neuen

Rechte in den Mandatory ACLs (MACL).

Als IL wurden folgende vier Möglichkeiten eingeführt:

Low

Medium (als Standard)

High

System

Jeder Prozess hat in seinem Token zusätzlich ein IL gespeichert. Will ein Prozess mit einem niedrigen

IL auf eine Ressource mit einem höheren IL zugreifen, so ist die oben beschriebene Interaktion mit

dem Benutzer vonnöten.

Damit UAC funktioniert wurde der LSA modifiziert, so dass es jetzt zwei Arten von Token gibt:

einen gefilterten: ohne erweiterte Rechte

einen gelinkten: mit allen Originalrechten

Außerdem muss der Programmierer im Manifest seiner Anwendung das benötigte IL angeben.

Standardmäßig werden alle Prozesse mit dem gefilterten Token ausgeführt. Der gelinkte Token wird

nur verwendet, wenn eine Applikation, aufgrund des Eintrags im Manifest, nach erweiterten Rechten

fragt. Dieses Verhalten führt auch dazu, dass selbst ein angemeldeter Administrator zuerst vom

System um Erlaubnis gefragt wird, wenn die Aufgabe ein höheres IL erfordert.

Als Beispiel für eine sinnvolle Anwendung des UAC kann der Internet Explorer betrachtet werden:

Der Internet Explorer läuft per Voreinstellung mit Low-IL, was bedeutet, er kann nur auf

Objekte mit LOW-IL SIDs zugreifen. Standardmäßig sind das nur

%USERPROFILE%\AppData\LocalLow und der Registry-Key HKCU\Software\AppDataLow. Auf

alle anderen Systemressourcen hat der Prozess des IE keinen Zugriff, was die Sicherheit stark

erhöht.

Wird der IE mit aktivierten UAC betrieben, so wird diese Konstellation häufig als Protected Mode IE

(PMIE) oder auch Low Rights Internet Explorer (LoRIE) bezeichnet.

UAC ist die für den Benutzer offensichtlichste und auch eine der nützlichsten Sicherheitsmaßnahmen

zur Schadensbegrenzung. Allerdings empfinden viele Benutzer die ständige Nachfrage nach

erweiterten Rechten als störend. Außerdem funktionieren nicht alle Programme einwandfrei mit

UAC. Diese zwei Kritikpunkte führen dazu, dass viele Benutzer UAC Systemweit deaktivieren, was den

gesamten Nutzen hinfällig macht.

Page 37: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 37 -

4.3 PatchGuard

PatchGuard wurde von Microsoft entwickelt und hat es zum Ziel Software von Drittherstellern daran

zu hindern Änderungen am Kernel vorzunehmen. Dadurch soll potentiell gefährlicher Software

erschwert werden sich einzunisten.

Eingeführt wurde PatchGuard mit den Windows-Versionen Server 2003 mit SP1 (64-Bit) und XP

Professional x64. Eine Portierung auf die x86-Versionen ist derzeit nicht geplant. [ 28 ]

Da PatchGuard eine Reihe von Unzulänglichkeiten besitzt, die das Umgehen des Schutzes relativ

einfach machen, ist der tatsächliche Nutzen in Bezug auf Schadsoftware fraglich. Häufig wird sogar

behauptet, PatchGuard sei lediglich ein Instrument von Microsoft, um die Dritthersteller dazu zu

zwingen, saubereren und stabileren Code zu schreiben. [ 29 ]

Viel Kritik an dem System gab es auch von den Herstellern von Sicherheits-Software, wie Anti-Viren-

Software und Rootkit-Detection-Tools, da sich diese Produkte häufig an den, durch dieses System

nicht mehr erreichbaren Stellen, eingenistet haben, um so von einem möglichst uneingeschränkten

Punkt aus operieren zu können. [ 29 ]

Eine umfassende Analyse der neusten Version (v3) von PatchGuard ist im Internet unter [ 28 ] zu

finden.

4.4 Process Exection Block (PEB) Randomization

Überblick

Mit Windows XP SP28 wurde eine Funktionalität namens PEB-Randomization eingeführt. Ihr Ziel ist

es, Angriffe zu erschweren, die zur Codeausführung PEB-Einträge manipulieren. Im Process Exection

Block (PEB) sind vor allem für Angriffe interessante Funktions-Pointer gespeichert, wie ein Pointer auf

die Funktion ExitProcess().

Funktionsweise

Beim Programmstart wird die Basisadresse des PEB dynamisch gewählt. Dadurch ist ein Remote-

Exploit9, dass den PEB als Einstiegspunkt verwendet, nicht mehr zuverlässig, da die zu

überschreibende Adresse des Funktions-Pointers in dem, jetzt an einem zufälligen Ort im Speicher

liegenden, PEB gespeichert ist.

8 Funktionalität ist auch in Server 2003 SP1 / Vista vorhanden

9 Ein Remote-Exploit ist dadurch charakterisiert, dass der Angreifer entfernt über ein Netzwerk zugreift und

nicht an der Maschine selbst sitzt.

Page 38: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 38 -

Schwachstellen

Wie sich ein einer Untersuchung von Symantec herausstellte [ 30 ] , beschränkt sich die Anzahl der

Möglichkeiten, für die Basisadresse des PEB, auf 16. Hinzu kommt noch, dass die Adresse in 20% aller

Fälle gleich ist.

Effektiver Schutz

Die Möglichkeit verlässliche Remote-Exploits zu schreiben wurde reduziert. Die Option der Brute-

Force-Angriffe bleibt jedoch, mit einem recht hohen Erfolgsgrad, bestehen.

4.5 Heap-Schutz

Überblick

Wie in Abschnitt 3.1.6 beschrieben, kann es auch auf dem Heap zu Buffer-Overflows kommen. Um

den Schaden begrenzen zu können, wurden mit dem SP2 von Windows XP im Wesentlichen zwei

neue Features, für die von Windows bereitgestellte Heap-Verwaltung, eingeführt: [ 8 ]

Cookies auf dem Heap (vergleichbar mit denen der GS-Funktionalität des Stacks)

Plausibilitätsprüfung (sanity checking) der Headerinformationen der einzelnen Heap-

Segmente

Funktionsweise Cookies

Bei jedem Aufruf von HeapAlloc() wird vor und nach jedem Puffer auf dem Heap ein 1-Byte

großes, mit Pseudo-Zufallszahlen initialisiertes Cookie, abgelegt. [ 8 ]

Im Betrieb wird vor jedem Entnehmen eines Blocks aus der "Frei-Liste" geprüft, ob der Wert des

Cookies noch der Selbe ist, wie zum Zeitpunkt der Initialisierung. Dazu wird der Wert mit dem des

separat gespeicherten Original-Cookies verglichen. Hat sich der Wert geändert, so wird zuerst ein

HeapDestory() ausgeführt und anschließend wird eine Exception geworfen. Falls diese nicht

behandelt wird, wird das Programm beendet. [ 8 ]

Außerdem wurde ein sogenannter Low Fragmentation Heap (LFH) entwickelt, der Primär der

Performancesteigerung dient. Dieser LFH ist ebenfalls durch ein Cookie geschützt. Allerdings durch

eins der Größe 4-Byte. Durch das größere Cookie, wird das erraten des Werts und die

Wahrscheinlichkeit für erfolgreiche Brute-Force-Angriffe, stark reduziert. [ 17 ]

Funktionsweise Plausibilitätsprüfung

Die "Frei-Listen" sind als doppelt verkette Listen aufgebaut. Die Pointer, die zur Verkettung der Liste

in beide Richtungen dienen, nennen sich Blink, für das vorhergegangene Element und Flink, für das

nächste Element. [ 8 ]

Page 39: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 39 -

Vor jedem Entnehmen eines Blocks aus der "Free-List" werden Blink und Flink auf ihre Plausibilität

hin geprüft. Das bedeutet, es wird geprüft, ob der der Blink aus dem Header des Folgeelements auch

tatsächlich auf das aktuelle Element zeigt. Dieselbe Prüfung wird in die andere Richtung vollzogen.

[ 8 ]

Schwachstellen

Innerhalb der Heap-Verwaltung gibt es nicht nur die oben genannten "Frei-Listen", sondern auch

Lookaside-Liste, die primär der Geschwindigkeitserhöhung dienen. Diese Listen sind nur einfach

verkette Listen und aus diesem Grund könnten die Pointer nicht auf Plausibilität hin geprüft werden..

Da aber unter XP mit SP2 der PEB und der Heap dynamische Startadressen haben, benötigt ein Brute-

Force-Angriff nach mehr wie 2000 Versuche, vorausgesetzt die Applikation läuft nach einem

fehlgeschlagenen Versuch weiter. [ 17 ]

Eine weitere Schwachstelle ist das nur 1-Byte große Cookie und die in Abschnitt 4.4 beschriebene,

schwache Zufallswahl des PEB-Speicherortes. Hinzu kommt noch die Tatsache, dass der LFH unter

Windows XP SP2 standardmäßig von keiner Applikation verwendet wird. [ 17 ]

Einen weiteren Angriff auf das Heap-Management beschreibt Alexander Anisimov. Dabei nutzt er die

Tatsache, dass die Cookie-Prüfung und die Plausibilitätsprüfung der Pointer nur unter bestimmten

Umständen stattfinden. So ist es Alexander Anisimov, unter einer Reihe von Voraussetzungen

möglich, die Blink- und Flink-Pointer derart zu manipulieren, dass ein wahlfreier Schreibzugriff von

1016 Bytes möglich ist. Die Voraussetzungen für diese Art von Angriff sind jedoch derart exotisch,

dass Microsoft an dieser Stelle keinen unmittelbaren Handlungsbedarf sieht. [ 8 ]

Eine etwas robustere Methode, als die von Alexander Anisimov, beschreibt Nicolas Falliere in [ 15 ] .

Dabei ist das Prinzip das gleiche: Es werden Blink- und Flink-Pointer überschrieben, dadurch kommt

es zu einem wahlfreien Schreibzugriff der Größe von 4-Byte. Dabei unterliegt dieser Angriff aber den

gleichen Problemen wie der Angriff, auf die einfach verketteten Lookaside-Listen. Es ist also auch hier

nur ein Brute-Force-Angriff möglich. [ 15 ]

Nach [ 31 ] werden die Lookaside-Listen in den aktuellen Windows-Versionen nicht mehr verwendet,

wodurch auf ihnen basierende Angriffe nicht mehr möglich sind.

Effektiver Schutz

Unter Windows XP mit SP1 war es aufgrund der fixen Speicherorte des PEB und des Heaps, sowie des

Fehlens, der oben beschrieben Neuerungen, möglich zuverlässige Remote-Exploits zu schreiben [ 17 ]

Mit Windows XP SP2 wurden Maßnahmen eingeführt, die das Entwickeln zuverlässiger Exploits

deutlich erschwert haben. Dennoch sind Brute-Force-Angriffe weiterhin möglich.

Hinweis: Die in diesem Abschnitt beschriebenen Schwachstellen und Verbesserungen beziehen sich

ausschließlich auf das Heap-Management von Windows. Programme die ihr eigenes Heap-

Page 40: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 40 -

Management implementieren, profitieren von keiner der hier vorgestellten Neuerungen. Der Heap-

Schutz wurde von Microsoft dennoch durch andere, in diesem Dokument vorgestellte

Sicherheitsfunktionen, stark verbessert. Zu nennen sind in diesem Zusammenhang vor allem DEP,

SafeSEH und ASLR (Vista).

Insgesamt hat sich die Gefahr durch Heap-basierende Angriffe stark verringert. So dass sich Angriffe

zukünftig verstärkt auf Anwendungsdaten konzentrieren werden, die auf dem Heap liegen (frei

übersetzt nach [ 9 ] ).

4.6 Visual Studio 2005 - Der "Windows-Compiler"

Wie jedes andere Programm auch, müssen die Quelldateien eins Betriebssystems mit einem

Compiler in ausführbare Dateien übersetzt werden. Im Falle von Windows kommt bei Microsoft

Visual Studio (VS) zum Einsatz [ 32 ] .

Im Folgenden werden die, für Buffer-Overflows relevanten, Funktionen von VS 2005 vorgestellt und

mit den Verbesserungen gegenüber früher Schutzfunktionen verglichen. Der Focus wird hierbei auf

VS 200510 liegen, da dies der Compiler ist, mit dem das Betriebssystem Windows Vista übersetzt

wird. Außerdem wird der effektive Nutzen der Maßnahmen diskutiert.

4.6.1 Standard Annotation Language (SAL)

Option Beschreibung [ 33 ] Standard Windows Binaries

/analyze

(Compiler)

Codeanalyse in der Enterprise-Version - Windows Vista

Überblick

SAL dient der Compiler gestützten Qualitätssicherung des Codes und ist in den Versionen "Team

System" und "Team Edition" von VS 2005 mittels der Option /analyze verfügbar. Ihr Ziel ist es dem

Entwickler beim Übersetzen seiner Programme Hinweise zu geben, an welcher Stelle der

Programmcode möglicher weise nicht so arbeitet wie erwartet. Die Hauptaufgabe von SAL ist es

dabei, auf potentielle Buffer-Overflows aufmerksam zu machen. [ 31 ] [ 34 ]

10

In den verwendeten Quellen ist häufig die Rede von dem „Whidbey-Compiler“. Whidbey ist der Codename für Visual Studio 2005

Page 41: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 41 -

Funktionsweise

Beim Erstellen des Quellcodes muss der Programmierer sogenannte Annotations in seinen Code

einbringen. Zum Beispiel die Annotation __out_ecount, wie in folgendem Beispiel zu sehen ist:

void FillString(

__out_ecount(cchBuf) TCHAR* buf,

size_t cchBuf,

char ch) {

for (size_t i = 0; i < cchBuf; i++) {

buf[i] = ch;

}

}

Quelle: [ 34 ]

Beim Kompilieren mit der /analyse Option wird VS in diesem Beispiel folgende Ausgabe erstellen:

c:\code\saltest\saltest.cpp(54) : warning C6203: Buffer overrun for non-stack buffer 'b' in

call to 'FillString': length '420' exceeds buffer size '400'

c:\code\saltest\saltest.cpp(54) : warning C6386: Buffer overrun: accessing 'argument 1', the

writable size is '200*2' bytes, but '420' bytes might be written: Lines: 53, 54

c:\code\saltest\saltest.cpp(54) : warning C6387: 'argument 1' might be '0': this does not

adhere to the specification for the function 'FillString': Lines: 53, 54

Quelle: (43)

Dabei gibt es eine Reihe weiterer Annotations, die der Programmierer in seinen Code verwenden

kann.

Da die ursprüngliche Hauptaufgabe von SAL darin bestand Buffer zu beschreiben, auf die lesend und

schreibend zugegriffen wird, versehen die Entwickler von Windows Vista alle entsprechenden

Funktionen mit Annotations, bevor das Produkt an den Kunden ausgeliefert wird. [ 34 ]

Schwachstellen

Da SAL eine Meta-Sprache ist, die zur Unterstützung von statischen Analysetools entwickelt wurde,

können dem entsprechend nur Fehler gefunden werden, die beim Kompilieren erkennbar sind.

Buffer-Overflows, die zur Laufzeit auftreten, weil die Puffergröße beispielsweise von einer

Benutzereingabe abhängt, können nicht erkannt werden. [ 34 ]

Page 42: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 42 -

Effektiver Nutzen

Durch die Verwendung von SAL ist der Programmierer gezwungen sich mehr Gedanken über den

Ablauf seiner Funktionen zu machen. Zusammen mit einer konsequenten Anwendung und der

Berücksichtigung der Compilerwarnungen, hätten mit SAL bereits in der Vergangenheit einige Buffer-

Overflows vermieden werden können.

Da SAL eine automatisierte Neuerung zur Verbesserung der Code-Qualität ist, ist SAL eine effektive

Maßnahme gegen die Entstehung von Sicherheitslücken.

4.6.2 Optimierte Anordnung von Stack-Elementen (O2)

Option Beschreibung [ 33 ] Standard Windows

Binaries

/O2

(Compiler)

Erstellt schnellen Code. bei Release-Build Theoretisch alle

Überblick

Seit VS 2003 wird, beim Erstellen eins Release-Builds11, die Anordnung von Variablen (Puffern) auf

dem Stack optimiert. Dabei ist es das Ziel potentiell verwundbare Puffer an einer ungefährlicheren

Position anzulegen [ 35 ] .

Funktionsweise

Wie auf der Abbildung 4-2 zu erkennen ist, wird die lokale Variable auth_flag, vor dem potentiell

verwundbaren Puffer im Speicher angelegt. Da der Schreibzugriff immer nur in Richtung größer

werdender Adressen stattfindet, ist die Variable auth_flag in Sicherheit. Dasselbe Verfahren wird

auch bei dem Anlegen von Pointer angewendet.

11

Standardmäßig ist bei dem Profil „Release“, in Visual Studio, die Compiler-Option O2 aktiviert

Page 43: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 43 -

Wa

ch

stu

msrich

tun

gpassword_buffer: char[32]

auth_flag: int

Stack Frame Pointer (SFP)

Return Adresse (RET)

Parameter

0000000h

(Kleine Adressen)

FFFFFFFFh

(Große Adressen)

Ove

rflo

wrich

tun

g

Stackframe

Ohne

Optimierung

auth_flag: int

password_buffer: char[32]

Stack Frame Pointer (SFP)

Return Adresse (RET)

Parameter

Stackframe

Mit

Optimierungint check_authentication(char *password) {

int auth_flag = 0;

char password_buffer[8];

strcpy(password_buffer, password);

if(strcmp(password_buffer, "password") == 0)

auth_flag = 1;

if(strcmp(password_buffer, "adminpw") == 0)

auth_flag = 1;

return auth_flag;

}

Quellcode

Abbildung 4-2: Optimierte Anordnung von Stack-Elementen bei VS 2003

Effektiver Schutz

Durch dieses Verfahren wird zwar der Schutz, von lokalen Variablen und Pointern, vor Buffer-

Overflows gewährt. Nicht geschützt sind diese Ziele jedoch vor Buffer-Underruns12.

Die größte Gefahr bleibt nach wie vor bestehen. Wie in der Abbildung 4-2 zu sehen ist, ist es immer

noch möglich, ausgehend von dem verwundbaren Puffer, die Returnadresse (RET) zu überschreiben

und so beliebigen Code zur Ausführung zu bringen. Kombiniert mit den im Folgenden vorgestellten

Mechanismen ergibt sich dennoch ein echter Mehrwert durch diese Optimierungen.

4.6.3 Puffer-Sicherheitsüberprüfung (GS)

Option Beschreibung [ 33 ] Standard [ 35 ] Windows

Binaries [ 32 ]

/GS

(Compiler)

Puffer-Sicherheitsüberprüfung aktiviert

seit VS 2005

teilweise bei

XP SP2, Vista

/GS-

(Compiler)

Puffer-Sicherheitsüberprüfung deaktivieren deaktiviert

seit Visual C++ 2002

teilweise bei

XP SP2, Vista

12

Zu einem Buffer-Underrun kann es beispielsweise durch fehlerhafte Pointerarithmetik kommen

Page 44: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 44 -

Überblick

Hinter dem Compilerswitch /GS verbirgt sich eine Funktion namens Buffer Security Check. Das

Haupt-Ziel dieser Funktion ist es, ein Überschreiben der Return-Adresse zu erkennen und das

Programm gegebenenfalls abzubrechen. Unter Linux gibt es mit StackGuard und ProPolice Lösungen,

die diesem Prinzip ebenfalls folgen.

Verfügbar ist diese Option seit Visual C++ 2002 und standardmäßig aktiviert ist die Option seit VS

2005[ 35 ] . Dabei gilt es allerdings zu beachten, dass sich die Implementierungsdetails und damit der

effektive Schutz, seit der ersten Version stark verändert haben. Im Folgenden wird nur auf die

Implementierung von VS 2005 eingegangen.

Seit Windows XP SP2 bzw. Windows Server 2003 ist die Option auch in den meisten Windows-

Binaries Standard. [ 32 ]

Funktionsweise

Programme, die mit der /GS Option kompiliert wurden, initialisieren nach dem Programmstart 4Byte

großes Master-Cookie, mit nicht vorhersagbarem Inhalt. Wird anschließend im Programmverlauf eine

geschützte Funktion aufgerufen, so wird innerhalb des Funktionsprologs eine Kopie des Master-

Cookies, wie auf Abbildung 4-3 zu sehen, auf dem Stack platziert. Wichtig ist hierbei vor allem die

Position des Cookies auf dem Stack: es liegt nach den potentiell verbundbaren lokalen Variablen und

vor der Return-Adresse. Hat die Funktion ihre Arbeit erledigt, so wird innerhalb des Funktionsepilogs

der momentane Wert, des auf dem Stack liegenden Cookies, mit dem Master-Cookie verglichen.

Sollte innerhalb der Funktion ein Buffer-Overflow vorgekommen sein, der bis zu dem Cookie reicht,

so wird das an dieser Stelle erkannt. Gegebenenfalls wird anschließend eine Ausnahme geworfen

und falls diese nicht entsprechend behandelt wird, wird das Programm wird mit einer Fehlermeldung

abgebrochen. [ 32 ]

Page 45: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 45 -

Beispielhaftes

Stackframe

Wa

ch

stu

msrich

tun

g

0000000h

(Kleine Adressen)

FFFFFFFFh

(Große Adressen)

Ove

rflo

wrich

tun

g

Gespeicherte Register der

aufgerufenen Funktion

Sichere Parameter

Lokale Variablen

Exception Handler

Cookie

Stack Frame Pointer (SFP)

Return Adresse (RET)

Verwundbare Parameter

Abbildung 4-3: Beispielhaftes Stacklayout unter Verwendung von /GS bei VS 2005 [ 32 ]

Ebenfalls auf Abbildung 4-3 zu sehen, ist ein Feld "Sichere Parameter". Diese Neuerung gibt es seit

Visual Studio 2005 und soll verhindern, dass durch verwundbare Funktionsparameter nachfolgende

Speicherbereiche überschrieben werden können. Aktiviert wird diese Funktionalität ebenfalls mit der

/GS Option. Dabei stellen die sicheren Parameter nichts weiter dar, wie eine Kopie der Original-

Parameter. Während des Funktionsablaufs wird ausschließlich mit der Kopie (den sicheren

Parametern) gearbeitet. Aufgrund ihrer Position auf dem Stack, kann durch das weiter unten

liegende Cookie, ein von dem Parametern ausgehende Buffer-Overflow ebenfalls erkannt werden. [

32 ]

Schwachstellen

Die offensichtlichste und auch von Microsoft offiziell dokumentierte Schwachstelle, ist die Tatsache,

dass das Cookie nur unter bestimmten Umständen angelegt wird. Begründet wird dieses Verhalten

vor allem durch den Overhead, der durch das zusätzliche Verwalten und Prüfen der Cookies entsteht.

Das bedeute praktisch, dass ein Prüfung mittels Cookie, unter folgenden Umständen trotz aktivierter

/GS Option nicht erfolgt: [ 33 ] [ 32 ]

Bei Funktionen, die keinen Puffer enthalten

Wenn die /O Optionen (Code optimieren) nicht aktiviert werden

Bei Funktionen mit variabler Argumentliste (...)

Bei Funktionen, die mit naked (C++) markiert sind

Bei Funktionen, die Inlineassemblycode in der ersten Anweisung enthalten

Page 46: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 46 -

Wenn ein Parameter nur auf eine Art und Weise verwendet wird, die im Falle eines

Pufferüberlaufs höchstwahrscheinlich nicht ausgenutzt werden kann

Passend zu dem letzten Punkt, wurde erst kürzlich herausgefunden, dass Puffer von einer Größe

kleiner wie 5 Byte offenbar als nicht gefährlich eingestuft werden und somit keinen Schutz durch

Cookies besitzen. [ 32 ]

Die meisten der obigen Fälle kann der Entwickler glücklicher weise eliminieren, indem er das Pragma

strict_gs_check(on) verwendet [ 4 ] . Allerdings sollte bei diesem Vorgehen der zusätzliche

Overhead und die damit einhergehenden Performanceeinbußen nicht außer Acht gelassen werden.

Falls der Angreifer die Möglichkeit hat, einen wahlfreien Schreibzugriff der Größe 4-Byte

auszuführen, bevor der Cookie-Check durchgeführt wird, kann versucht werden das Master-Cookie

mit einem bekannten Wert zu überschreiben. Da es in der aktuellen Implementierung nur 256

mögliche Positionen für das Cookie gibt und der Speicherbereich beschreibbar ist, bieten sich hier

Brute-Force-Angriffe an. [ 32 ] [ 36 ]

Die gefährlichste Schwachstelle bei der Verwendung von /GS ist die Tatsache, dass man wie in der

Abbildung 4-3 zu sehen ist, von einem verwundbaren Puffer ausgehend ohne weiteres den Exception

Handler überschreiben kann. Wie in dem Abschnitt 3.1.5 kann dabei der Exception Handler anstelle

der Return-Adresse überschrieben werden. Diese Methode funktioniert deshalb, weil die Funktion

zum Prüfen des Cookies erst am Ende der Funktion aufgerufen wird. Bis dies geschieht kann ein

Angreifer eine Exception auslösen und somit die Ausführung des manipulierten Exception Handler

veranlassen[ 36 ] . Dieser Angriffsmöglichkeit begegnet VS mit der Einführung von SafeSEH auf das

später noch eingegangen wird.

Effektiver Schutz

/GS für sich allein bringt kaum einen Mehrwert, da durch das Manipulieren des Exception Handlers

weiterhin alle Möglichkeiten offen stehen (Windows XP SP1, Windows Server 2003 SP0, Vista).

In Verbindung mit SafeSEH (siehe nächster Abschnitt) jedoch, ist Microsoft hier ein sehr effektiver

Schutzmechanismus gelungen, der den Stack für Angreifer zunehmend uninteressanter werden lässt.

Wie eine aktuelle Studie von Symantec [ 32 ] zu dem Thema zeit, werden jedoch bei weitem nicht

alle ausführbaren Windows-Dateien von Windows XP und Vista mit der /GS Option kompiliert. Dabei

existiert bereits eine Liste mit Dateien, die ohne /GS Kompiliert wurden und somit nicht geschützt

sind. Außerdem wurde von Symantec, zur Erstellung der besagten Liste, ein Programm entwickelt,

dass in der Lage ist zu erkennen, ob ein Binary mit /GS kompiliert wurde. Mit diesen Hilfsmitteln sind

Angriffe auf ungeschützte Dateien bereits vorprogrammiert.

Dateien die mit /GS kompiliert wurden und zusätzlich zu dem eigentlichen Buffer-Overflow die

Möglichkeit eines wahlfreien 4-Byte-Schreibzugriffs bieten, sind aus den oben beschriebenen Grund

anfällig für Brute-Force-Angriffe. [ 32 ] [ 36 ]

Page 47: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 47 -

Nicht vergessen werden darf bei diesem Mechanismus der Schadensbegrenzung jedoch, dass hier

keinerlei Schutz vor Denial of Service Angriffen (DoS)13 geboten wird.

Abschließend sein noch darauf hingewiesen, dass die meisten Programme von Microsoft heutzutage

mit /GS und /SafeSEH kompiliert werden.

4.6.4 Sichere Ausnahmebehandlung (SafeSEH)

Option Beschreibung [ 37 ] Standard Windows

Binaries [ 4 ]

/SAFESEH[:NO]

(Linker)

Abbild verfügt über sichere Ausnahmehandler ? teilweise bei

Windows XP SP2,

Windows Server

2003 SP1,

Windows Vista

Überblick

Die aktuelle Version der Linker-Option /SafeSEH wurde mit Windows XP SP2 / Server 2003 SP1

eingeführt und ist nur für x86-Architekturen verfügbar[ 37 ] [ 4 ] . Ihr Ziel ist es, der im vorherigen

Abschnitt angesprochene Möglichkeit, zum Umgehen der Cookie-Prüfung zu begegnen.

Hinweis: Die genaue Geschichte des SAFESEH-Option ist etwas unklar: Eine Funktion zum validieren

gab es scheinbar bereits mit Server 2003 SP0, unklar ist allerdings welche Funktionalität wann und

mit welchem Umfang eingeführt wurde.

Funktionsweise

Ein mit der /SafeSEH Option kompiliertes Programm, hat in dem Header der ausführbaren Datei

(PE-Header) eine Liste "Sicherer Exception Handler". Wenn im Verlauf des Programms eine

Ausnahme ausgelöst wird, so prüft die Laufzeitumgebung, ob der auf dem Stack liegende, zur

Ausführung vorgesehene, Exception Handler in der besagten Liste steht. Sollte im Programmverlauf

der Exception Handler manipuliert worden sein, so wird dies von Windows erkannt und das

Programm wird abgebrochen. [ 4 ]

13

Ziel von Denial of Service Angriffen ist es, einen Service oder Dienst für den Nutzer unverfügbar zu machen.

Page 48: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 48 -

Schwachstellen

Windows kann einen Exception Handler nur auf seine Richtigkeit überprüfen, wenn das Programm

mit der /SafeSEH Option kompiliert wurde. Dementsprechend sind alle DLLs und Programme von

Drittherstellern, die diese Option nicht verwenden weiterhin verwundbar. [ 14 ]

Effektiver Schutz

Zum Zeitpunkt der Analyse von Ben Nagy [ 14 ] im September 2006, waren keinerlei Möglichkeiten

bekannt, bei Binaries die mit /GS und /SafeSEH kompiliert wurden, die Return-Adresse oder den

Exception Handler als zuverlässigen Einstiegspunkt zu nutzen, um beliebigen Code zur Ausführung zu

bringen. [ 14 ]

Die Ansätze zum Angriff, auf die im letzten Abschnitt vorgestellten Cookies, bleiben jedoch weiterhin

bestehen und bieten einen Ansatzpunkt für weitergehende Analysen.

Auch bei diesem Mechanismus der Schadensbegrenzung darf nicht vergessen werden, dass hier

keinerlei Schutz vor Denial of Service Angriffen geboten wird.

4.6.5 Data Execution Prevention (DEP)

Option Beschreibung [ 37 ] Standard [ 37 ] Windows Binaries

/NXCOMPAT[:NO]

(Linker)

Gibt an, dass eine ausführbare Datei mit dem

Windows-Feature

Datenausführungsverhinderung kompatibel ist.

wenn die

Komponente

Vista erfordert

teilweise bei

Windows XP SP2,

Windows Server

2003 SP1,

Windows Vista

Überblick

Das Ziel von Hardware-DEP (Hardware-enforced DEP) ist es, Angreifern die Möglichkeit zu nehmen,

eingeschleusten Code von beliebigen Speichersegmenten ausgehend, ausführen zu können. Dabei ist

es bisher historisch bedingt gewesen, dass auf dem Stack und dem Heap liegende Daten ausgeführt

werden können, obwohl dies bei entsprechender Programmierung eigentlich nicht nötig ist.

Sollte bei Verwendung von Hardware-DEP dennoch versucht werden Code von einem als nicht

ausführbar markierten Bereich auszuführen, so wird eine Exception geworfen und falls diese nicht

abgefangen wird, wird das Programm beendet. [ 38 ]

Page 49: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 49 -

Außer dem Hardware-DEP gibt es auch ein Software-DEP (Software-enforced DEP). Die

Namensgebung ist dabei nicht unbedingt logisch. Software-DEP wird nämlich bereits unter dem

Schlagwort SafeSEH geführt und hat es lediglich zum Ziel, Exception Handler auf Manipulationen hin

zu prüfen und das Programm gegebenenfalls abzubrechen (siehe Abschnitt 4.6.4). Software-DEP

kann in diesem Zusammenhang als eine Art Erweiterung zu Hardware-DEP gesehen werden. Für

Software-DEP ist keine spezielle Hardware-Unterstützung notwendig. [ 38 ] [ 39 ]

DEP ist seit Windows XP SP2 und Windows Server 2003 SP1 standardmäßig aktiviert. Hierbei sind

sowohl Software-DEP, als auch Hardware-DEP inbegriffen. [ 38 ]

Funktionsweise

Damit Hardware-DEP funktioniert wird ein Prozessor mit entsprechender Funktionalität benötigt. Bei

AMD heißt die entsprechende Funktion "no-execute" (NX), bei Intel "Execute Disable" (XD). [ 39 ]

Außerdem muss in der Datei Boot.ini bei 32-Bit-Systemen die Physical Address Extension (PAE)

aktiviert sein. Bei 64-Bit-Windows-Versionen ist PAE nicht nötig, weil die entsprechende

Funktionalität bereits nativ implementiert ist.

Software- und Hardware-DEP werden global mit dem Eintrag /noexecute=policy_level in der

Boot.ini konfiguriert. Dabei gibt es für policy_level folgende vier Einstellungsmöglichkeiten: [ 39 ]

1. OptIn: Ist unter Windows XP SP2 die Standardkonfiguration. Mit dieser Option gilt die

Datenausführungsverhinderung standardmäßig nur für Windows-Systembinärdateien. [ 39 ]

2. OptOut: Ist unter Windows 2003 Server SP1 [ 40 ] die Standardkonfiguration.

Datenausführungsverhinderung standardmäßig für alle Prozesse aktivieren. Es kann über

Registryeinträge, eine Liste mit Ausnahmen erstellt werden. [ 39 ]

3. AlwaysOn: Datenausführungsverhinderung gilt für das gesamte System. [ 39 ]

4. AlwaysOff: Für das gesamte System deaktivieren. [ 39 ]

Außer über die globalen Einstellungen, lässt sich DEP für DLLs auch mittels eins "Incompatible-Flags"

deaktivieren. [ 40 ]

Eine dauerhafte Aktivierung von DEP lässt sich mit der oben angegebenen Compiler-Option

/NXCOMPAT:YES erreichen [ 31 ] .

Im Betrieb wird bei Hardware-DEP für jede virtuelle Speicherseite ein Bit gesetzt, dass den

Speicherbereich entweder als ausführbar oder nicht ausführbar markiert. Wird im Betrieb von einem

als "nicht ausführbar" markierten Speicherbereich Code ausgeführt, so wird eine Exception geworfen

und falls sie nicht behandelt wird, wird der Prozess beendet.

Page 50: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 50 -

Schwachstellen

Im Wesentlichen haben alle Schwachstellen, die mit DEP in Zusammenhang gebracht werden, mit

dem Tradeoff zwischen Sicherheit und Kompatibilität zu tun, den Microsoft bei der Implementierung

von Hardware-DEP gegangen ist.

So werden in der Regel weder der Internet Explorer 7, noch Java unter Windows Vista SP1 / XP SP2

mit Hardware-DEP betrieben. Dadurch gelang es Shane Macauly und Alexander Sotrov im Rahmen

des Wettbewerbs "Pwn to Own" im April 2008 mittels Flash und Java, Hardware-DEP zu umgehen

und beliebigen eingeschleusten Code auszuführen. Diese, in Flash begründete Einstiegsmöglichkeit,

wurde bereits 6 Tage nach dem Bekanntwerden von Adobe behoben. [ 41 ] [ 42 ]

Eine weitere Schwachstelle von Hardware-DEP wurde bereits im Jahr 2005 gefunden [ 40 ] . Bei

dieser Methode nutzt der Angreifer die Möglichkeit, das Kompatibility-Flag vom User-Mode aus

nachträglich ändern zu können. Dabei muss es dem Angreifer allerdings bereits möglich sein, im Stil

von return2libc eigenen Code ausführen zu können. Außerdem benötigt er die Adressen mehrerer

Speicherregionen, die gezielt manipuliert werden müssen. Aufgrund der letzen Anforderung sind

Angriffe dieser Art unter Windows Vista nicht mehr zuverlässig möglich, da dort ASLR zur Verfügung

steht. Microsoft hat auf die Veröffentlichung des Angriffs von Alexander Anisimov mit der Aussage

reagiert, man glaube nicht, dies sei eine Schachstelle, weil der Angreifer bereits Code zur Ausführung

bringen können muss. Abgesehen davon sei DEP auch primär zum Schutz vor Remote-Angriffen

entwickelt worden. [ 43 ] [ 44 ]

Effektiver Schutz

Die Implementierung von DEP scheint, in Hinsicht auf Remote-Angriffe, bisher keine Schwachstellen

zu haben. Wünschenswert wäre es dennoch, die oben angesprochenen Unzulänglichkeiten

schnellstmöglich zu korrigieren, um so potentiellen neuen Angriffen so schwer wie möglich zu

machen.

Eine wirkliche Gefahr stellt die Abwärtskompatibilität von DEP dar. Hier sind die Dritthersteller

gefragt: Sie sollten schnellstmöglich sicherstellen, dass alle Ihre Produkte mit aktivierten Hardware-

DEP uneingeschränkt lauffähig sind.

Page 51: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 51 -

4.6.6 Address Space Layout Randomization (ASLR)

Option Beschreibung [ 37 ] Standard[ 4 ] Windows

Binaries [ 31 ]

/DYNAMICBASE[:NO]

(Linker)

Address Space Layout Randomization verfügbar und

Standard seit

VS 2005 SP1

Windows Vista

seit Beta2

Überblick

ASLR ist eine Funktionalität, die ausschließlich unter Windows Vista zur Verfügung steht und seit

Visual Studio 2005 SP1 auch für Eigenentwicklungen verfügbar ist. Das Ziel von ASLR ist es, Remote-

Angriffe, die es zum Ziel haben eigenen Code zur Ausführung zu bringen, so unzuverlässig wie

möglich zu machen. Ausschließen lässt sich diese Art von Angriff mit ASLR nicht, da das System

grundliegend auf einen begrenzten Grad an Wahrscheinlichkeit zurückgreift. [ 30 ]

Funktionsweise

Wird bei VS 2005 SP1 /DYNAMICBASE als Option beim Linken angegeben, so wird im PE-Header der

ausführbaren Datei ein Flag gesetzt, dass der Laufzeitumgebung mitteilt, dass ASLR verwendet

werden soll. [ 30 ]

Beim Bootvorgang von Windows Vista wird ein globales Image-Offset gewählt, von dem ausgehend

alle DLLs geladen werden. Dadurch ist es weiterhin effizient möglich, innerhalb aller Prozesse auf

eine gemeinsame Funktionalität einer DLL zuzugreifen. Außer dem globalen Image-Offset werden die

Basisadressen von der TXT-, DATA- und BSS-Segmente sowie der der DLLs, bei jedem Reboot neu

gewählt. Im Unterschied dazu, werden die Basisadressen des Stacks und der angelegten Heaps, bei

jedem Programmstart neu gewählt und sind für jeden Thread verschieden. Zusätzlich zu der

Basisadresse des Stacks, wird der Initial-Stack-Pointer dynamisch gewählt. [ 30 ]

Die Bestimmung der dynamischen Adressen erfolgt dabei durch Pseudo-Zufallszahlen. Die Menge der

möglichen Basisadressen ist dabei sehr unterschiedlich. So ist beispielsweise die Menge der

möglichen Adressen für den Initial Stack-Pointer auf einem 32-Bit-System 16.384, für die

Basisadresse des globalen Image-Offsets jedoch, existieren lediglich 256 Möglichkeiten. [ 30 ]

Nichts direkt mit dem eigentlichen ASLR der Linker-Option /DYNAMICBASE, hat die in Abschnitt 4.4

beschriebene dynamische Wahl des PEB zu tun. Dabei wird ebenfalls, bei jedem Programmstart, die

Adresse des PEB zufällig gewählt.

Page 52: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 52 -

Schwachstellen

Die offensichtlichste Schwachstelle von ASLR existiert bei lokalen Angriffen. Dabei muss ein Angreifer

lediglich einen eigenen Prozess starten und mittels eines Debuggers die globale Basisadresse

ermitteln. Hierbei sollte allerdings berücksichtigt werden, dass ALSR primär zum Schutz vor Remote-

Angriffen entwickelt wurde und somit ist es in der Regel nicht möglich, einen eigenen Prozess zu

starten, von dem diese Information abgeleitet werden kann. [ 30 ]

Eine wirkliche Schwachstelle hingegen ist die Tatsache, dass ähnlich wie bei GS und SafeSEH, noch

nicht alle Windows Binaries mit der entsprechenden Option kompiliert wurden. Nach [ 4 ] sind bei

Windows Vista Ultimate 1676 von 1767 Dateien mit ASLR kompiliert.

Einer Analyse von Symantec zufolge[ 30 ] , bestehen in der Implementierung von ASLR noch einige

Verbesserungsmöglichkeiten. Im Wesentlichen wird dabei die Häufigkeitsverteilung der

Basisadressen als verbesserungswürdig eingestuft. Die größte Schwachstelle in diesem

Zusammenhang betrifft die Basisadresse des PEB, die in 25% aller Fälle identisch ist. Außerdem zeigt

sich bei der Verwendung von HeapAlloc() eine sehr deutliche Häufigkeitsverteilung. Ausgehend

von diesen Implementierungsschwächen bieten sich Brute-Force-Angriffe geradezu an. [ 30 ]

Effektiver Schutz

Wie bereits erwähnt ist der Schutz vor lokalen Angriffen durch ASLR nahezu null.

Die Möglichkeit zuverlässige Remote-Exploits zu schreiben, wurde durch ASLR signifikant verringert.

Dabei bleibt jedoch die Möglichkeit der Brute-Force Angriffe bestehen. Dies könnte vor allem durch

die oben erwähnten Schwächen in der Häufigkeitsverteilung interessant werden. Da sich Microsoft

dieser Problematik jedoch bewusst ist und dieses Problem selbst auf eine

Implementierungsschwäche zurückführt, kann auf eine baldige Beseitigung dieser Unzulänglichkeit

gehofft werden. [ 30 ]

Auch bei diesem Mechanismus der Schadensbegrenzung darf nicht vergessen werden, dass hier

keinerlei Schutz vor Denial of Service Angriffen geboten wird.

4.7 Abschließender Vergleich: XP gegenüber Vista

Wie sich der folgenden Tabelle entnehmen lässt, sind viele Neuerungen der jüngeren Vergangenheit

auch in Windows XP enthalten. Diese Neuerungen für sich haben die Schwierigkeit zuverlässige

Exploits zu schreiben, die auf Buffer-Overflows basieren, stark erhöht. Laut CVE-Statistik [ 1 ] gab es

für Windows XP im Jahr 2007 noch 28 veröffentliche Schwachstellen, die direkt auf Buffer-Overflows

zurückzuführen waren. Im Jahr 2008 ist es, bis zum Druckzeitpunkt dieser Arbeit im Juni 2008, noch

keine einzige solche Schwachstelle. [ 1 ]

Page 53: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 53 -

Tabelle 1: Sicherheitsmechanismen in XP und Vista

Windows XP Windows Vista

UAC und Service Hardening Nein Ja

Patchguard Ja,

nur bei 64Bit

Ja,

nur bei 64Bit

PEB Randomization Seit SP2 Ja

SAL Ja,

bei entsprechender

Entwicklungsumgebung

Ja,

bei entsprechender

Entwicklungsumgebung

Stackoptimierungen(O2) Ja,

muss beim Kompilieren

aktiviert werden

Ja,

muss beim Kompilieren

aktiviert werden

SafeSEH Seit SP2,

muss beim Linken aktiviert

werden

Ja,

muss beim Linken aktiviert

werden

DEP Seit SP2,

muss beim Linken aktiviert

werden

Ja,

muss beim Linken aktiviert

werden

ASLR Nein Ja,

muss beim Linken aktiviert

werden

Weitere Neuerungen wie UAC und ASLR, die nur Windows Vista und seinen Folgeversionen zugänglich sind, haben den Sicherheitsstandard noch weiter erhöht, so dass Buffer-Overflows als Einfallstor zunehmend unwahrscheinlicher werden. Außerdem schränken sie den Spielraum des eingeschleusten Codes stark ein, was ebenfalls einen sicherheitstechnischen Mehrwert darstellt. Im Fazit folgt nun eine kurze Zusammenfassung und eine Bewertung der Gesamtmenge an Maßnahmen, die in Windows XP und Windows Vista zum Einsatz kommen.

Page 54: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 54 -

5 Fazit

In den beiden ersten Kapiteln wurden einige traditionelle und einige neuere Angriffstechniken

vorgestellt, die auf Buffer-Overflows basieren und mit denen ein modernes Betriebssystem

heutzutage zurechtkommen muss. In dem letzten Kapitel wurden die Mechanismen vorgestellt, die

Windows Vista und frühere Versionen mitbringen, um sich gegen diese Gefahren zu wappnen. Dabei

ist es offensichtlich, dass Microsoft einen beachtlichen Entwicklungsaufwand investiert hat um den

Ruf des unsicheren "Blue-Screen-Windows" endgültig abzulegen.

Dabei sind neue Programmierpraktiken wie SAL entstanden, die den Entwicklern helfen Buffer-

Overflows erst gar nicht entstehen zu lassen und somit den wohl effektivsten Schutz gegen Buffer-

Overflows bietet. Sollten sich im Code von Drittherstellern, oder im Betriebssystem selbst dennoch

Buffer-Overflows finden, so wird der praktische Nutzen, durch die meisten in diesem Dokument

vorgestellten Mechanismen, auf Denial of Service Angriffe reduziert. Dies gilt allerdings nur, wenn die

gesamte Breite, an zur Verfügung stehenden Schutzmechanismen, verwendet wird. Das einfachste

Negativbeispiel ist ein Programm, das zwar mit /GS, aber nicht mit /SafeSEH kompiliert wurde. Hier

verwendet der Angreifer einfach den Exception Handler und nicht die Rücksprungadresse als

Einstiegspunkt.

Kritik und Lob zugleich verdient Windows Vista für seine Abwärtskompatibilität. So freut es

Dritthersteller, dass sie ihre Programme nicht aufwändig umschreiben müssen, um mit den neuen

Sicherheitsmechanismen kompatibel zu sein, denn sie bleiben einfach inkompatibel. Was den

Programmierer der Software freut, ist schlecht für die Gesamtsicherheit des Systems. Als

bekanntestes Negativbeispiel sei hier nochmals der Internet Explorer 7 genannt, der selbst heute

noch mit deaktivierten DEP das Tor zur Welt öffnet.

Sollte es einem Anwender gelingen, nur Programme zu betreiben, die alle zur Verfügung stehenden

Mechanismen verwenden, so betreibt er das mit Abstand sicherste Windows-System das es bisher

gab.

Dennoch ist "das sicherste" nicht gleichzusetzen mit "sicher". Dieser Tatsache ist sich auch Stephen

Toulouse (Senior Product Manager bei Microsoft Security Technology) bewusst, der sagt:

"Keins der Features aus Windows Vista, weder allein, noch zusammen, ist

kugelsicher. Dennoch erhöht sich der Schutz gegenüber Windows XP

signifikant" (Frei übersetzt nach [ 29 ] ).

Aus dieser richtigen, aber auch sehr unverfänglichen Aussage, lässt sich ablesen, wie schwer es ist,

den effektiven Schutz eines Betriebssystems zu beurteilen.

Um die gesamte Sicherheit von Windows Vista zu bewerten darf man nicht nur veröffentliche

Sicherheitslücken bewerten, sondern man muss auch Dienstleister, mit moralisch fragwürdiger

Motivation in seine Bewertung mit einbeziehen, die versprechen gegen Bezahlung funktionierende

Exploits zu liefern. Ebenso dürfen Hacker mit unterschiedlichen Idealen nicht vergessen werden, die

Page 55: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 55 -

teilweise kein Interesse daran haben ihre "private Exploits" zu veröffentlichen, da Sie dadurch ihren

"Freiraum" verkleinern würden.

Auch wenn sich abschließend nicht sagen lässt "Windows Vista ist sicher", der Mehrwert den

Neuerungen wie UAC und ASLR gegenüber Windows XP bringen, ist unbestritten. Wer also vor der

Wahl steht XP oder Vista, dem sollte vom sicherheitstechnischen Standpunkt aus, auf jeden Fall zu

Vista geraten werden.

Page 56: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 56 -

A Literaturverzeichnis

1. Statistics. [Online] National Vulnerability Database, 15. 7 2008. http://nvd.nist.gov/.

2. Mark E. Russinovich, David A. Solomon. Windows Internals. Redmond : Microsoft Corporation,

2005. ISBN 3-86063-977-3.

3. James C. Foster, Vitaly Osipov, Nish Bhalla, Niels Heinen. Buffer Overflow Attacks: Detect, Exploit,

Prevent. Rockland : Syngress Publishing, Inc., 2005. ISBN 1-932266-67-4.

4. Joel Scambray, Stuart McClure. Hacking Exposed Windows: Windows Security Secrets & Solutions,

Third Edition. s.l. : McGraw-Hill, 2008. ISBN 978-0-07-149426-7.

5. Ericson, Jon. HACKING: THE ART OF EXPLOITATION, 2ND EDITION. San Francisco : NO STARCH

PRESS, 2008. ISBN 978-1-59327-144-2.

6. Know-how: Heap-Verwaltung Haufenakrobatik. Stiller, Andreas. 4, Hannover : Heise Zeitschriften

Verlag GmbH & Co. GK, 2007. ISSN 0724-8679.

7. Pufferüberläufe auf dem Heap und wie man sie ausnutzt. Lindner, Felix. 09, Hannover : Heise

Zeitschriften Verlag GmbH & Co. GK, 2006. ISSN 0724-8679.

8. Alexander Anisimov, Positive Technologies. Defeating Microsoft Windows XP SP2 Heap protection

and DEP bypass. [Online] 2004. [Zitat vom: 5. 4 2008.] http://www.maxpatrol.com/defeating-xpsp2-

heap-protection.htm.

9. Horovitz, Matt, Conover und Oded. Windows Heap Exploitation. [Online] [Zitat vom: 5. 4 2008.]

http://www.cybertech.net/~sh0ksh0k/projects/winheap/XPSP2%20Heap%20Exploitation.ppt.

10. Kallnik, Stephan, et al. Buffer-Overflows und andere Sollbruchstellen. heise Security. [Online] 30.

6 2003. [Zitat vom: 1. 4 2008.] http://www.heise.de/security/Buffer-Overflows-und-andere-

Sollbruchstellen--/artikel/37958/2.

11. Visual C++ Referenz. msdn. [Online] Microsoft Corporation. [Zitat vom: 17. 5 2008.]

http://msdn2.microsoft.com/de-de/library/de5awhsw.aspx.

12. Using an Exception Handler (Windows). msdn. [Online] Microsoft Corporation. [Zitat vom: 29. 4

2008.] http://msdn2.microsoft.com/en-us/library/ms681409%28VS.85%29.aspx.

13. Mangarae, Aelphaeis. SEH Overwrites Simplified v1.01. [Online] 27. 10 2007. [Zitat vom: 2. 4

2008.] http://www.milw0rm.com/papers/187.

14. Nagy, Ben. SEH (Structured Exception Handling) Security Changes in XPSP2 and 2003 SP1.

[Online] eEye Digital Security, 5. 12 2006. [Zitat vom: 16. 5 2008.]

http://www.eeye.com/html/resources/newsletters/vice/VI20060830.html.

Page 57: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 57 -

15. Falliere, Nicolas. Bypassing Windows heap protections. [Online] [Zitat vom: 11. 4 2008.]

http://packetstormsecurity.org/papers/bypass/bypassing-win-heap-protections.pdf.

16. Conover, Matt. Double Free Vulnerabilities. Vulnerabilities & Exploits. [Online] 1 2007. [Zitat vom:

1. 5 2008.]

http://www.symantec.com/enterprise/security_response/weblog/2007/01/double_free_vulnerabilit

ies_pa.html.

17. Conover, Matt & Horovitz, Oded. Windows Heap Exploitation. [Online] 12 2004. [Zitat vom: 5. 4

2008.] http://www.cybertech.net/~sh0ksh0k/projects/winheap/XPSP2%20Heap%20Exploitation.ppt.

18. Conover, Matt & w00w00 Security Team. w00w00 on Heap Overflows. [Online] 1 1999. [Zitat

vom: 1. 4 2008.] http://www.w00w00.org/files/articles/heaptut.txt.

19. c0ntex. Windows Heap Overflows using the Process Environment Block (PEB). [Online] [Zitat vom:

6. 4 2008.] http://www.milw0rm.com/papers/66.

20. Wana, Thomas aka. greuff. Writing UTF-8 compatible shellcodes. [Online] [Zitat vom: 2. 4 2008.]

http://www.phrack.org/issues.html?issue=62&id=9.

21. Tüllmann, Thorsten. Shellcode unter Windows, Linux und MacOS. [Online] 15. 2 2006. [Zitat vom:

4. 5 2008.] http://www.tm.uka.de/itm/uploads/folien/88/08-Thorsten_Tuellmann-Shellcode.pdf.

22. Kritische Lücke in Intels Centrino WLAN-Treibern. Heise Security. [Online] Heise Zeitschriften

Verlag GmbH & Co. GK, 2. 8 2006. [Zitat vom: 14. 5 2008.] Kritische Lücke in Intels Centrino WLAN-

Treibern.

23. Barnaby, Jack Senior. Remote Windows Kernel Exploitation - Step into the Ring 0. [Online] 2005.

[Zitat vom: 14. 5 2008.] http://research.eeye.com/html/papers/download/StepIntoTheRing.pdf.

24. Messier, Matt und Viega, John. Secure Programming Cookbook for C and C++. s.l. : O'Reilly, 2003.

0-596-00394-3.

25. Jesper M., Johansson. Sicherheit auf dem Prüfstand: Tools zum Verwalten von ACLs. TechNet

Magazin. [Online] 2008. [Zitat vom: 16. 5 2008.] http://technet.microsoft.com/de-

de/magazine/cc138006.aspx.

26. Impact of Session 0 Isolation on Services and Drivers in Windows Vista. Windows Hardware

Developer Central. [Online] 20. 12 2007. [Zitat vom: 16. 5 2008.]

http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-

d599bac8184a/Session0_Vista.docx.

27. Moore, Brett. Shattering By Example. [Online] 10 2003. [Zitat vom: 16. 5 2008.] http://security-

assessment.com/files/whitepapers/Shattering_By_Example-V1_03102003.pdf.

28. Skywing. PatchGuard Reloaded: A Brief Analysis of PatchGuard Version 3. [Online] 9 2007. [Zitat

vom: 17. 5 2008.] http://www.uninformed.org/?v=8&a=5&t=txt.

Page 58: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 58 -

29. Lemos, Robert. Vista raises the bar for flaw finders. [Online] 29. 1 2007. [Zitat vom: 17. 5 2008.]

http://www.securityfocus.com/news/11439.

30. Whitehouse, Ollie. An Analysis of Address Space Layout Randomization on Windows Vista™.

[Online] 2007. [Zitat vom: 2. 4 2008.]

http://www.symantec.com/avcenter/reference/Address_Space_Layout_Randomization.pdf.

31. Hellen, Ian und Kumar, Vishal. Security Engineering in Windows Vista. HITBSecConf2006 -

Malaysia. [Online] 18. 9 2006. [Zitat vom: 24. 5 2008.]

http://packetstormsecurity.org/hitb06/DAY_1_-_Ian_Hellen_and_Vishal_Kumar_-

_Security_Engineering_in_Vista.pdf.

32. Whitehouse, Ollie. Analysis of GS protections in Microsoft Windows Vista. [Online] 2007. [Zitat

vom: 18. 5 2008.] http://www.symantec.com/avcenter/reference/GS_Protections_in_Vista.pdf.

33. Visual C++-Compileroptionen. msdn. [Online] [Zitat vom: 17. 5 2008.]

http://msdn.microsoft.com/de-de/library/9s7c9wdw.aspx.

34. Howard, Michael. A Brief Introduction to the Standard Annotation Language (SAL). Michael

Howard's Web Log - A Simple Software Security Guy at Microsoft! [Online] 19. 5 2006. [Zitat vom: 27.

5 2008.] http://blogs.msdn.com/michael_howard/archive/2006/05/19/602077.aspx.

35. Branbray. Security Improvements to the Whidbey Compiler. http://blogs.msdn.com/. [Online] 11.

11 2003. [Zitat vom: 17. 5 2008.] http://blogs.msdn.com/branbray/archive/2003/11/11/51012.aspx.

36. Litchfield, David. Defeating the Stack Based Buffer Overflow Prevention Mechanism of Microsoft

Windows 2003 Server. [Online] 8. 9 2003. [Zitat vom: 2. 4 2008.]

http://www.nextgenss.com/papers/defeating-w2k3-stack-protection.pdf.

37. Visual C++-Linkeroptionen. msdn. [Online] [Zitat vom: 18. 5 2008.]

http://msdn.microsoft.com/de-de/library/y0zzbyt4.aspx.

38. How to Configure Memory Protection in Windows XP SP2. Microsoft TechNet. [Online] 9. 12

2004. [Zitat vom: 24. 5 2008.]

http://www.microsoft.com/technet/security/prodtech/windowsxp/depcnfxp.mspx.

39. A detailed description of the Data Execution Prevention (DEP) feature in Windows XP Service

Pack 2, Windows XP Tablet PC Edition 2005, and Windows Server 2003. Hilfe und Support. [Online]

26. 10 2006. [Zitat vom: 24. 5 2008.] http://support.microsoft.com/?scid=kb%3Ben-

us%3B875352&x=1&y=8.

40. skape und Skywing. Bypassing Windows Hardware-enforced Data Execution Prevention.

Uninformed - vol 2 article 4. [Online] 10 2005. [Zitat vom: 25. 5 2008.]

http://www.uninformed.org/?v=2&a=4.

Page 59: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 59 -

41. Erste Hintergründe zum Flash-Hack beim PWN-to-OWN-Wettbewerb. heise Security. [Online] 3. 4

2008. [Zitat vom: 24. 5 2008.] http://www.heise.de/security/Adobe-schliesst-sieben-Luecken-im-

Flash-Player--/news/meldung/106237.

42. Adobe schließt sieben Lücken im Flash-Player. heise Security. [Online] 9. 4 2008. [Zitat vom: 25. 5

2008.] http://www.heise.de/security/Adobe-schliesst-sieben-Luecken-im-Flash-Player--

/news/meldung/106237.

43. Microsoft: Fehler in Buffer-Overflow-Schutz ist keine Schwachstelle. heise online. [Online] 2. 2

2008. [Zitat vom: 25. 5 2008.] http://www.heise.de/newsticker/Microsoft-Fehler-in-Buffer-Overflow-

Schutz-ist-keine-Schwachstelle--/meldung/55851.

44. Buffer-Overflow-Schutz in Windows XP SP2 lückenhaft. heise Security. [Online] 31. 01 2005. [Zitat

vom: 25. 5 2008.] http://www.heise.de/security/Buffer-Overflow-Schutz-in-Windows-XP-SP2-

lueckenhaft--/news/meldung/55738.

45. Stephan Kallnik, Daniel Pape, Daniel Schröter, Stefan Strobel. http://www.heise.de. heise

Security. [Online] 3. 6 2003. [Zitat vom: 1. 4 2008.] http://www.heise.de/security/Buffer-Overflows-

und-andere-Sollbruchstellen--/artikel/37958/0.

46. Howard, Michael. Windows Vista Security – A Bigger Picture. http://blogs.msdn.com. [Online] 12.

6 2006. [Zitat vom: 17. 5 2008.]

http://blogs.msdn.com/michael_howard/archive/2006/06/12/628207.aspx.

47. One, Aleph. Smashing The Stack For Fun And Profit. [Online] [Zitat vom: 2. 4 2008.]

http://www.phrack.org/issues.html?issue=49&id=14#article.

48. skape. Understanding Windows Shellcode. [Online] 6. 9 2003. [Zitat vom: 31. 3 2008.]

http://nologin.org/Downloads/Papers/win32-shellcode.pdf.

49. talz. How-to exploit default exception handler to gain stability on win32. [Online] [Zitat vom: 16.

5 2008.] http://www.securityforest.com/wiki/index.php/Exploit:_Stack_Overflows_-

_Exploiting_default_seh_to_increase_stability.

Page 60: Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Stack- und Heap-Overflow-Schutz bei Windows XP und Windows Vista

Seite - 60 -

B Quellcode

Der Quellcode wurde aus Platzgründen in einen Zip-Archiv ausgelagert. Diese Zip-Datei, sowie die

aktuelle Version dieses Dokuments, sind unter folgender Adresse erhältlich:

http://jssk.de/data/studienarbeit/Quellcode-Studienarbeit-BOs.zip

Sollten sich im Laufe der Zeit Änderungen ergeben, so dass der oben angegebenen Link nicht mehr

funktioniert, so bin ich unter folgender Kontaktadresse erreichbar.

Kontaktadresse: [email protected]

Inhalte des Qullecode-Archivs

Hinweise zum Kompilieren

Batchdateien zum Kompilieren mit Visual-Studio 2005 bzw. 2008

Quellcode zu dem Programmen

Beispielprogramme, fertig kompiliert

Beispielhafte Programmabläufe (Programmausgaben)

Perlskripte zum erstellen des Bytecodes

Beispielhaft erstellter Bytecode