E-Book, Deutsch, 519 Seiten
Reihe: Rheinwerk Computing
Gebeshuber / Teiniker / Zugaj Exploit!
1. Auflage 2019
ISBN: 978-3-8362-6600-0
Verlag: Rheinwerk
Format: EPUB
Kopierschutz: 0 - No protection
Code härten, Bugs analysieren, Hacks verstehen
E-Book, Deutsch, 519 Seiten
Reihe: Rheinwerk Computing
ISBN: 978-3-8362-6600-0
Verlag: Rheinwerk
Format: EPUB
Kopierschutz: 0 - No protection
Die Suche nach Exploits ist die Königsdisziplin für Entwickler. Neben viel Ausdauer und Spaß an Knobeleien müssen Sie zudem Wissen über Angriffsvektoren und Sicherheitsprobleme mitbringen. Hier lernen Sie die wichtigsten Techniken und Tools kennen und bekommen einen tiefgehenden Einblick in das Aufspüren, Ausnutzen und Verhindern von Exploits.
Aus dem Inhalt:
- Sichere Software-Entwicklung: Prozesslayout, Memory Management und mehr
- Reverse Engineering
- Secure Coding: Encapsulation, Data Validation, Error Handling
- Secure Design: Architectural Risk Analysis
- Kryptografie
- Lücken finden: Fuzzing, Codeanalyse und mehr
- Buffer Overflows ausnutzen
- Mitigations einsetzen: ASLR, SEHOP und mehr
- Schutzmechanismen umgehen
- Real Life Exploits: Heartbleed, Shellshock, Spectre & Meltdown und mehr
Dr. Klaus Gebeshuber ist FH-Professor für IT-Security an der FH JOANNEUM in Kapfenberg (Österreich). Er lehrt berufsbegleitend IT-Security im Studiengang IT & Mobile Security. Seine Schwerpunkte liegen im Bereich Netzwerksicherheit, Industrial Security, Security-Analysen und Penetration-Tests. Nach dem Studium der Elektrotechnik/Computertechnik an der Technischen Universität Wien war Dr. Gebeshuber 15 Jahre im Bereich der industriellen Softwareentwicklung und Automatisierungstechnik tätig. Er hält zahlreiche Industriezertifikate im Umfeld von IT-Security, Netzwerk-Sicherheit und Penetration Testing.
Autoren/Hrsg.
Weitere Infos & Material
Materialien zum Buch ... 13 Geleitwort ... 15 1. Einleitung ... 17 1.1 ... Über dieses Buch ... 17 1.2 ... Zielgruppe ... 19 1.3 ... Wie Sie mit dem Buch arbeiten ... 20 1.4 ... Die Autoren ... 20 2. Exploit! So schnell führt ein Programmierfehler zum Root-Zugriff ... 21 2.1 ... Das Szenario ... 21 2.2 ... Die Vorbereitungsarbeiten, Informationssammlung ... 22 2.3 ... Analyse und Identifikation von Schwachstellen ... 23 2.4 ... Ausnutzung der XSS-Schwachstelle ... 25 2.5 ... Analyse und Identifikation weiterer Schwachstellen ... 26 2.6 ... Zugriff auf das interne Netzwerk ... 31 2.7 ... Angriff auf das interne Netz ... 35 2.8 ... Privilege Escalation am Entwicklungsserver ... 39 2.9 ... Analyse des Angriffs ... 42 3. Einführung in die sichere Softwareentwicklung ... 43 3.1 ... Ein Prozessmodell für sichere Softwareentwicklung ... 44 3.2 ... Die Praktiken der sicheren Softwareentwicklung ... 46 3.3 ... Fachwissen für sichere Softwareentwicklung ... 51 4. Grundlagenwissen für sicheres Programmieren ... 67 4.1 ... Praktiken der agilen Softwareentwicklung ... 68 4.2 ... Die Programmiersprache C ... 69 4.3 ... Die Programmiersprache Java ... 76 4.4 ... Versionierung von Quellcode ... 82 4.5 ... Debugging und automatisiertes Testen ... 84 4.6 ... Continuous Integration ... 91 4.7 ... Beispiele auf GitHub und auf rheinwerk-verlag.de ... 94 5. Reverse Engineering ... 97 5.1 ... Analyse von C-Applikationen ... 97 5.2 ... Analyse von Java-Applikationen ... 129 5.3 ... Code Obfuscation ... 148 6. Sichere Implementierung ... 151 6.1 ... Reduzieren Sie die Sichtbarkeit von Daten und Code ... 151 6.2 ... Der sichere Umgang mit Daten ... 160 6.3 ... Der richtige Umgang mit Fehlern ... 176 6.4 ... Kryptografische APIs richtig einsetzen ... 182 6.5 ... Statische Codeanalyse ... 211 7. Sicheres Design ... 227 7.1 ... Architekturbasierte Risikoanalyse ... 227 7.2 ... Designprinzipien für sichere Softwaresysteme ... 232 7.3 ... Das HTTP-Protokoll ... 235 7.4 ... Sicheres Design von Webapplikationen ... 244 8. Kryptografie ... 281 8.1 ... Verschlüsselung ... 281 8.2 ... Hash-Funktionen ... 309 8.3 ... Message Authentication Codes und digitale Signaturen ... 321 8.4 ... NIST-Empfehlungen ... 327 9. Sicherheitslücken finden und analysieren ... 329 9.1 ... Installation der Windows-Testinfrastruktur ... 329 9.2 ... Manuelle Analyse der Anwendung ... 335 9.3 ... Automatische Schwachstellensuche mittels Fuzzing ... 340 9.4 ... Analyse des Absturzes im Debugger ... 343 9.5 ... Alternativen zum Fuzzing ... 344 9.6 ... Tools zur Programmanalyse ... 344
10. Buffer Overflows ausnutzen ... 357 10.1 ... Die Crash-Analyse des i.Ftp-Clients ... 357 10.2 ... Offsets ermitteln ... 360 10.3 ... Eigenen Code ausführen ... 363 10.4 ... Umgang mit Bad Characters ... 368 10.5 ... Shellcode generieren ... 372 10.6 ... Exception Handling ausnutzen ... 377 10.7 ... Analyse unterschiedlicher Buffer-Längen ... 379 10.8 ... Buffer Offsets berechnen ... 382 10.9 ... SEH-Exploits ... 382 10.10 ... Heap Spraying ... 386
11. Schutzmaßnahmen einsetzen ... 391 11.1 ... ASLR ... 391 11.2 ... Stack Cookies ... 393 11.3 ... SafeSEH ... 395 11.4 ... SEHOP ... 396 11.5 ... Data Execution Prevention ... 396 11.6 ... Schutz gegen Heap Spraying ... 399
12. Schutzmaßnahmen umgehen ... 401 12.1 ... Was sind Reliable Exploits? ... 401 12.2 ... Bypass von ASLR ... 402 12.3 ... Bypass von Stack Cookies ... 418 12.4 ... Bypass von SafeSEH ... 419 12.5 ... Bypass von SEHOP ... 420 12.6 ... Data Execution Prevention (DEP) -- Bypass mittels Return Oriented Programming ... 423 12.7 ... DEP Bypass mittels Return-to-libc ... 449
13. Format String Exploits ... 451 13.1 ... Formatstrings ... 451 13.2 ... Die fehlerhafte Anwendung ... 454 13.3 ... Aufbau der Analyseumgebung ... 457 13.4 ... Analyse des Stack-Inhalts ... 459 13.5 ... Speicherstellen mit %n überschreiben ... 463 13.6 ... Die Exploit-Struktur ... 466 13.7 ... Die Ermittlung von Adressen und Offsets ... 468 13.8 ... Die Verifikation der Adressen im Debugger ... 471 13.9 ... Die erste lauffähige Version des Exploits ... 473 13.10 ... ASLR Bypass ... 477
14. Real Life Exploitation ... 485 14.1 ... Heartbleed ... 485 14.2 ... SSL OpenFuck ... 488 14.3 ... Shellshock ... 493 14.4 ... Eternal Blue ... 495 14.5 ... Spectre und Meltdown ... 504 14.6 ... Stagefright ... 509 Index ... 511
3 Einführung in die sichere Softwareentwicklung
Die Hauptursache von Sicherheitsproblemen in Computersystemen sind Schwachstellen in der Software. Hacker nutzen Implementierungsfehler und Mängel im Softwaredesign, um ein System anzugreifen.
Softwaresysteme enthalten sowohl Implementierungsfehler (Bugs) als auch Designmängel (Design Flaws), die zu Sicherheitsrisiken werden können. Als Anwender hat man sich längst daran gewöhnt, dass Software nicht fehlerfrei ist. Gleichzeitig haben die Sicherheitsprobleme in den letzten Jahren überdurchschnittlich stark zugenommen.
Nach Gary McGraw sind die Ursachen dafür:
-
Connectivity: Die zunehmende Vernetzung der zumeist mobilen Computer über das Internet ermöglicht es den Hackern, Softwaresysteme von jedem Ort der Welt aus anzugreifen. Bestehende Softwarekomponenten werden als Webservices zur Verfügung gestellt, auch wenn diese nie dafür vorgesehen waren.
-
Extensibility: Applikationen können frei aus dem Internet geladen, Erweiterungen und Plugins auf Knopfdruck installiert werden. Webseiten und lokale Dokumente enthalten Scripts, um deren Funktionalität zu erweitern. All diese Techniken erschweren es, festzustellen, welche Software verwendet wird und ob diese fehlerfrei ist.
-
Complexity: Betriebssysteme, Applikationen oder auch nur Softwarebibliotheken bestehen aus Millionen von Codezeilen. Untersuchungen zeigen, dass die Fehlerwahrscheinlichkeit stark mit dem Umfang des Codes ansteigt – damit steigt auch die Anzahl der Sicherheitslücken.
Lange Zeit war das Thema Security alleine die Angelegenheit von Administratoren, die für den Betrieb von Firewalls, Intrusion-Detection-Systemen und Antivirenprogrammen zuständig waren. Es zeigt sich aber, dass dieser Ansatz nicht alleine zum Ziel führen kann. Schließlich ist es effizienter, Software zu entwickeln, die sich selbst schützen kann, indem sie weniger Angriffspunkte bietet.
3.1 Ein Prozessmodell für sichere Softwareentwicklung
Sichere Software entsteht nicht zufällig oder durch kleine Erweiterungen am fertigen Softwareprodukt. Software-Security basiert auf bewährten Methoden des Software-Engineerings. Eine wichtige Praktik des Software-Engineerings ist die Verwendung eines definierten Prozessmodells, in dem die Abfolge der einzelnen Phasen der Softwareentwicklung vorgegeben ist, um die reibungslose Erstellung eines Softwareprodukts sicherzustellen. Je nach Anwendungsbereich kommen unterschiedliche Prozessmodelle zum Einsatz. Werden diese Phasen des Prozessmodells der Reihe nach über die Projektlaufzeit verteilt, spricht man von einem Wasserfallmodell. Bei Anwendungen, bei denen sich die Anforderungen rasch ändern können, setzt man jedoch auf agile Entwicklungsmethoden. Bei agilen Prozessmodellen wird die Projektlaufzeit in gleich lange Iterationen unterteilt, wobei in jeder Iteration alle Phasen der Softwareentwicklung durchlaufen werden. Wartung und Weiterentwicklung können somit in zusätzliche Iterationen ausgelagert werden.
Nach Ian Sommerville sind die wichtigsten Phasen der Softwareentwicklung:
-
Analyse und Definition der Anforderungen: Die funktionalen und nicht-funktionalen Anforderungen sowie bestehende Rahmenbedingungen werden im Gespräch mit dem Kunden erarbeitet. Das Ergebnis der Anforderungsanalyse sind Use-Case-Spezifikationen, die in einem Anforderungsdokument zusammengefasst werden.
-
Architektur und Design: Die Struktur des Softwaresystems wird definiert. Durch Abstraktion wird die Gesamtfunktionalität auf Komponenten aufgeteilt, die über spezifizierte Schnittstellen und Protokolle interagieren. Architektur- und Designentscheidungen werden im Designdokument festgehalten, das üblicherweise auch UML-Diagramme enthält.
-
Implementierung und Unit Testing: Die Funktionalitäten der Komponenten werden weiter unterteilt, bis sie mit den Konstrukten einer Programmiersprache implementiert werden können. Jeder Teil der Implementierung wird mit Hilfe von Tests verifiziert. Das Ergebnis dieser Phase sind der Quellcode sowie verschiedene Konfigurationsdateien und Softwarebibliotheken, aus denen das fertige Softwaresystem automatisiert gebaut werden kann.
-
Systemtests: Durch Systemtests wird überprüft, ob das Softwaresystem die spezifizierten Anforderungen erfüllt. Nach einem erfolgreichen Abnahmetest wird das Softwaresystem an den Kunden ausgeliefert. Ein Protokoll der Testergebnisse dokumentiert das Ende dieser Phase.
-
Betrieb und Wartung: Das ist die mit Abstand längste Phase im Lebenszyklus eines Softwareprodukts. Die Software wurde installiert und ist als laufendes System im praktischen Einsatz. Im Zuge der Wartungstätigkeiten werden Fehler beseitigt, die bis dahin nicht entdeckt wurden. In diese Phase fällt auch das Hinzufügen neuer Funktionalitäten, wenn sich die Anforderungen mit der Zeit verändern (Software-Evolution).
Abbildung 3.1 Ein praktisches Prozessmodell für die Entwicklung von sicherer Software
Um ein sicheres Softwaresystem zu entwickeln, müssen mehrere sicherheitsrelevante Tätigkeiten in unterschiedlichen Phasen der Softwareentwicklung durchgeführt werden. Man hat daher die bekannten Prozessmodelle der Softwareentwicklung um konkrete Security-Aktivitäten erweitert, welche die Sicherheit in jeder Entwicklungsphase berücksichtigen. Die bekanntesten Vertreter dieser erweiterten Prozessmodelle sind der Security Development Lifecycle (SDL) von Microsoft und die Touchpoints for Software Security von Gary McGraw.
Das Prozessmodell, das in Abbildung 3.1 dargestellt ist, orientiert sich am Konzept der Touchpoints, da dieses Prozessmodell weniger strikt definiert ist und sich leichter in die Praxis überführen lässt. Die unterschiedlichen Praktiken zur Verbesserung der Softwaresicherheit basieren auf den Artefakten, die von den einzelnen Phasen des Entwicklungsprozesses erzeugt werden. Leider sind die Ressourcen in der Softwareentwicklung oft knapp bemessen, und eine vollständige Umsetzung aller notwendigen Aktivitäten ist nicht immer möglich. Daher erfolgt hier eine Priorisierung der Praktiken nach ihrer Wirksamkeit im Aufspüren von Sicherheitslücken:
-
Code-Review: Bei der Analyse des (Quell-)Codes versucht man, Implementierungsfehler zu finden. Im Gegensatz zum klassischen Debuggen wird dabei speziell auf Bugs geachtet, die erfahrungsgemäß zu Sicherheitslücken führen können.
-
Architectural Risk Analysis: Die Architektur und das Design eines Softwaresystems müssen kohärent sein und eine durchgängige Verteidigungslinie gegen Angriffe bilden. Eine Risikoanalyse versucht, Schwachstellen in dieser Struktur ausfindig zu machen.
-
Risk-Based Security-Tests: Security-Tests sind, technisch gesehen, Unit-, Component-, Integration- und Systemtests. Die Testfälle orientieren sich jedoch einerseits an den eingebauten Sicherheitsfunktionalitäten, andererseits an den potenziellen Schwachstellen aus der Risikoanalyse und den Angriffsmustern (Attack Patterns) von Hackern.
-
Penetration Testing: Man versucht, ein Softwaresystem in seiner realen Laufzeitumgebung anzugreifen. Dieser Blackbox-Ansatz ähnelt einem Hackerangriff sowohl in der Vorgehensweise als auch in der Auswahl der eingesetzten Tools.
-
Abuse Cases: Bei der Definition von Abuse Cases schlüpfen Entwickler in die Rolle von Hackern. Abuse Cases beschreiben das Systemverhalten während eines Angriffs. Dazu braucht es Wissen darüber, was geschützt werden muss, wie Angriffe ablaufen könnten und wie eine mögliche Verteidigung funktionieren soll.
-
Security Operations: Angriffe gegen ein Softwaresystem können jederzeit stattfinden. Mit Hilfe von Monitoring- und Logging-Tools können diese Aktivitäten erfasst und ausgewertet werden. Aus den analysierten Angriffsmustern können neue Verteidigungsstrategien entwickelt und in die Software integriert werden.
Da sich diese Praktiken auf die Artefakte der einzelnen Softwareentwicklungsphasen beziehen, sind sie vom verwendeten Prozessmodell weitestgehend unabhängig und können auch sehr gut zusammen mit agilen Methoden eingesetzt werden.
Die vorgeschlagene Reihenfolge der Software-Security-Praktiken kann sich im konkreten Anwendungsbereich natürlich ändern. Einen wesentlichen Einfluss auf die Reihenfolge der angewendeten Praktiken hat der Zeitpunkt, zu dem eine Security-Analyse durchgeführt wird: