U23 - Shellcode. Twix Chaos Computer Club Cologne. Motivation Einstieg Der erste Shellcode Nullbytes, NOP Slides

Ähnliche Dokumente
Fallbeispiel Unix. Betriebssysteme. Hermann Härtig TU Dresden

Fallbeispiel Unix. Betriebssysteme. Hermann Härtig TU Dresden

U23 Assembler Workshop

G 5. Übung. G-1 Überblick. Besprechung 3. Aufgabe. Infos zur Aufgabe 5: fork, exec. Rechenzeiterfassung. Ü SoS I G.1

U23 Assembler Workshop

Tafelübung zu BS 5. Dateioperationen

Besprechung Aufgabe 1: Prozesse verwalten Fortsetzung Grundlagen C-Programmierung Aufgabe 2: Threadsynchronisation

Tafelübung zu BS 2. Threadsynchronisation

Betriebssysteme. Tafelübung 2. Thread-Synchronisation. Olaf Spinczyk.

Übungen zur Vorlesung Systemsicherheit

Buffer Overflow 1c) Angriffsstring: TTTTTTTTTTTTTTTT (16x) Beachte: Padding GCC-Compiler Zusatz: gcc O2 verhindert hier den Angriff (Code Optimierung)

Exploit-Entwicklung mit Python

Übungen zu Softwaresysteme I Jürgen Kleinöder Universität Erlangen-Nürnberg Informatik 4, 2004 K-Uebung9.fm

Vorbemerkungen Einführung Buffer Heap vs. Stack Sicherheit Literatur. Umgang mit Buffern. Stefan Bruhns

Assembler - Adressierungsarten

Übung 1 - Betriebssysteme I

Tafelübung zu BS 5. Dateioperationen

Tafelübung zu BS 5. Dateioperationen

4. Speicherverwaltung

4. Speicherverwaltung

Buffer Overflow. Denis Graf, Tim Krämer, Konstantin Schlese. Universität Hamburg Fachbereich Informatik. 6. Januar 2013

Systemaufrufe. Dr.-Ing. Matthias Sand. Lehrstuhl für Informatik 3 (Rechnerarchitektur) Friedrich-Alexander-Universität Erlangen-Nürnberg WS 2010/2011

Tafelübung zu BSRvS 1 4. Speicherverwaltung

Assembler Unterprogramme

U7 POSIX-Prozesse U7 POSIX-Prozesse

Übung zu Betriebssysteme

Vorlesung: Rechnerstrukturen, Teil 2 (Modul IP7)

Assembler. Dr.-Ing. Volkmar Sieh. Department Informatik 4 Verteilte Systeme und Betriebssysteme Friedrich-Alexander-Universität Erlangen-Nürnberg

Programmiertechnik. Teil 4. C++ Funktionen: Prototypen Overloading Parameter. C++ Funktionen: Eigenschaften

Betriebssysteme KU - Einführungstutorium

4.4 Prozesse. H. Weber, HS RM SS 2010 Systemprogrammierung Kap. 4.4 Seite 1 von 22

Systemprogrammierung

Tafelübung zu BS 4. Dateioperationen

Systemnahe Programmierung in C Übungen Jürgen Kleinöder, Michael Stilkerich Universität Erlangen-Nürnberg Informatik 4, 2011 U7.fm

2Binden 3. und Bibliotheken

Übungsbesprechung Blatt 3 Vorlesung Betriebssysteme I (WS 2018/19) Operating Systems And Middleware Group

2. Aufgabenblatt Musterlösung

Kodieren von Anweisungen im Binärformat für Maschinen quasi natürlich, zumindest effizient. Für Menschen hingegen ist Binärformat schwierig

Kompilierung eines Programmes. Mnemonics, ld, GCC, AS

Karlsruher Institut für Technologie

Rechnern netze und Organisatio on

Betriebssysteme Übung 2. Tutorium System Calls & Multiprogramming

Grundlagen der Informatik III Wintersemester 2010/ Vorlesung Dr.-Ing. Wolfgang Heenes

Malware-Analyse und Reverse Engineering. 4: Startup Prof. Dr. Michael Engel

C-Kurs 2010 Pointer. 16. September v2.7.3

x86 Assembler Praktische Einführung Sebastian Lackner Michael Müller 3. Juni 2013

Einführung in die Programmiersprache C

Rechnernetze und Organisation

Tafelübung zu BS 4. Speicherverwaltung

Nachdem die VM gestartet ist und sich darin angemeldet wurde, starten wir Eclipse.

Einführung Sprachfeatures Hinweise, Tipps und Styleguide Informationen. Einführung in C. Patrick Schulz

Tafelübung zu BS 2. Threadsynchronisation

Einführung in die Programmiersprache C

Rechnernetze und -Organisation. Teil B 2012 Tomislav Nad Karl C. Posch

Rechnerne etze und -O Organisatio on

Arrays (Felder/Vektoren)

C-Kurs 2011: Arrays, Strings, Pointer

Übungen zu Systemnahe Programmierung in C (SPiC) Inhalt. Moritz Strübe, Rainer Müller (Lehrstuhl Informatik 4) Sommersemester 2014

Rechnernetze und -Organisation. Teil B (30. März 2011) 2011 Michael Hutter Karl C. Posch

System Monitoring mit strace. Systemcall tracing

Übungen zur Systemprogrammierung 1 Michael Golm, Jürgen Kleinöder Universität Erlangen-Nürnberg Informatik 4,

Tafelübung zu BS 2. Threadsynchronisation

Übung zu Betriebssysteme

Michael Dienert. 8. Dezember 2016

Hello World! Eine Einführung in das Programmieren Das erste Programm

Bash-Skripting Linux-Kurs der Unix-AG

Shell-Scripting Linux-Kurs der Unix-AG

Shell-Scripting Linux-Kurs der Unix-AG

Mikroprozessoren Grundlagen AVR-Controller Input / Output (I/O) Interrupt Mathematische Operationen

Informatik I (D-ITET)

Einführung in die Programmiersprache C

Unterprogramme. Unterprogramme

Assembler - Einleitung

Hardware-Programmierung mit Linux/NASM

Einschub: HW-Zugriff aus dem Userspace

Hinweise 80x86-Architektur

Aufbau eines Kernelmoduls

ERA-Zentralübung Maschinenprogrammierung

Abstrakte C-Maschine und Stack

Betriebssystembau (BSB)

Malware-Analyse und Reverse Engineering. 10: Systemaufrufe und Tracing Prof. Dr. Michael Engel

Bash-Scripting Linux-Kurs der Unix-AG

Betriebssystembau (BSB)

Homogene Multi-Core-Prozessor-Architekturen

Strings (Zeichenketten)

Eine Mini-Shell als Literate Program

Ein- und Ausgabe mit Dateien

Technische Informatik II Rechnerarchitektur

Offenbar hängt das Ergebnis nur von der Summe der beiden Argumente ab...

Embedded-Linux-Seminare. Linux als Betriebssystem

Shell-Scripting Linux-Kurs der Unix-AG

Aufgabenblatt 5 Musterlösung

Einführung. Übungen zur Vorlesung Virtuelle Maschinen. Stefan Potyra. SoSe 2009

E-/A-Funktionalität nicht Teil der Programmiersprache

Transkript:

Twix e.v. http://koeln.ccc.de 2016-11-28

Überblick 1 Motivation Was ist Shellcode? Beispiel 2 Einstieg Erzeugen, Testen von Shellcode 3 Der erste Shellcode Strings in Shellcode 4 Nullbytes, NOP Slides Das Problem mit den Nullbytes Nullbyte freier Shellcode NOP Slides

1 Motivation Was ist Shellcode? Beispiel 2 Einstieg Erzeugen, Testen von Shellcode 3 Der erste Shellcode Strings in Shellcode 4 Nullbytes, NOP Slides Das Problem mit den Nullbytes Nullbyte freier Shellcode NOP Slides

Was ist Shellcode? Was ist Shellcode? Shellcode ist eine Sequenz von Befehlen, die eine Shell öffnet. Wir haben eine Möglichkeit gefunden, Daten in einen ausführbaren Bereich eines Programms einzuschleusen und auszuführen.

Beispiel Beispiel eines verwundbaren Programms 1 int main(int argc, char **argv) 2 { 3 char buffer[100]; 4 strcpy(buffer,argv[1]); 5 return 0; 6 } Warum ist dieses Programm anfällig? strcpy() prüft Bufferlänge nicht Rücksprungadresse überschreiben Welche Vorbedingungen brauchen wir? ausführbarer Stack bekanntes Adresslayout

1 Motivation Was ist Shellcode? Beispiel 2 Einstieg Erzeugen, Testen von Shellcode 3 Der erste Shellcode Strings in Shellcode 4 Nullbytes, NOP Slides Das Problem mit den Nullbytes Nullbyte freier Shellcode NOP Slides

Erzeugen, Testen von Shellcode Erzeugen von Shellcode 1 Anweisungen in Assembler schreiben 2 Anweisungen assemblieren 3 Assemblierten Code aus der Objektdatei kopieren 4 In escapte Darstellung überführen Python ist gut geeignet um diesen Vorgang zu scripten. Auch Makefiles vereinfachen das. $ as -o example.elf example.s $ objcopy -O binary example.elf example.bin $ hexdump -ve '1/1 "\\x%.2x"' example.bin \xc8\x00\x00\x00\x31\xc0\xc9\xc3

Erzeugen, Testen von Shellcode Testen von Shellcode 1 #include <string.h> 2 #include <sys/mman.h> 3 const char shellcode[] = "\xc8\x00\x00\x00\x31\xc0\xc9\xc3"; 4 int main(void) { 5 void (*executable_memory)(void) = mmap( 6 NULL, sizeof(shellcode), 7 PROT_READ PROT_WRITE PROT_EXEC, 8 MAP_ANONYMOUS MAP_PRIVATE, 0, 0 9 ); 10 memcpy(executable_memory, shellcode, sizeof(shellcode)); 11 executable_memory(); 12 return 0; 13 }

Was sind? Einige Aktionen darf nur das Betriebssystem ausführen, z.b. die Hardware steuern, Input/Output Unsere Software läuft in der Regel im Userspace, muss also das Betriebssystem ansprechen Das geschieht mittels sogenannten lösen einen Softwareinterrupt aus, der vom Betriebssystem gefangen und behandelt wird

Linux Syscall Calling Convention Jedem Syscall ist eine Nummer zugeordnet, die auf i386 in eax abgelegt wird Die Argumente der liegen jeweils in einem bestimmtem Register Der Rückgabewert liegt in eax, wenn die Kontrolle an das Programm zurückgegeben wird Auf i386 wird der Syscall durch die Instruktion int 0x80 ausgelöst Kernel stellt Register wiederher

Linux Syscall Calling Convention Syscall Nr. Arg. 1 Arg. 2 Arg. 3 Arg. 4 Arg. 5 Arg. 6 Rückgabewert eax ebx ecx edx esi edi ebp eax

Der write() Syscall ssize_t write(int fd, const void *buf, size_t count); Syscall mit der Nummer 4 write() schreibt ein char-array buf der Länge count in einen Datenstrom, referenziert über eine Dateidiskriptornummer fd Immer vorhanden sind die Datenströme stdin(standardeingabe) 0, stdout(standardausgabe) 1 und stderr(standardfehlerausgabe) 2 Rückgabewert: Anzahl der Bytes die geschrieben wurden, im Fehlerfall -1

Beispiel mit write() 1.data 2 hlo_str: 3.string "Hello World!\n" 4.text 5.global main 6 main: 7 enter $0,$0 8 push %ebx 9 mov $13, %edx 10 mov $hlo_str, %ecx 11 mov $1, %ebx 12 mov $4, %eax 13 int $0x80 14 pop %ebx 15 leave 16 ret Länge des Strings(13) edx Pointer auf den String ecx Datenstrom(stdout,1) ebx Syscallnummer(write,4) eax Softwareinterrupt Nummer 0x80 auslösen

Der read() Syscall ssize_t read(int fd, void *buf, size_t count); Syscall mit der Nummer 3 Liest von einem Datenstrom fd in ein char-array buf bis zu count Bytes Rückgabewert: Anzahl gelesener Bytes, im Fehlerfall -1

Beispiel mit read() und write() und Nutzung des Rückgabewerts 1.text 2.global main 3 main: 4 enter $0,$0 5 push %ebx 6 add $32, %esp 7 mov $32, %edx 8 mov %esp, %ecx 9 mov $0, %ebx 10 mov $3, %eax 11 int $0x80 12 mov %eax, %edx 13 mov $1, %ebx 14 mov $4, %eax 15 int $0x80 16 pop %ebx 17 leave 18 ret

Ohne die Libc zu benutzen: Schreibt ein Programm, dass nach einem Namen fragt und dann Hallo <name>äusgibt.

1 Motivation Was ist Shellcode? Beispiel 2 Einstieg Erzeugen, Testen von Shellcode 3 Der erste Shellcode Strings in Shellcode 4 Nullbytes, NOP Slides Das Problem mit den Nullbytes Nullbyte freier Shellcode NOP Slides

Der fork() Syscall pid_t fork(void); Syscall mit der Nummer 2 fork() kopiert den aktuellen Prozess, erzeugt also einen neuen Childprocess Rückgabewert: 0 im Childprocess, die PID des neuen Prozesses im Parentprocess, -1 im Fehlerfall

Der execve() Syscall int execve(const char *filename, char *const argv[], char *const envp[]); Syscall mit der Nummer 11 execve() ersetzt das Programm des aktuell laufenden Prozesses durch ein anderes Programm filename ist der Dateiname des zu ladenen Programmes, argv die Null-terminierte Liste der Argumente und envp die Null-terminierte Liste mit den Environmentvariablen Rückgabewert: -1 im Fehlerfall

Der exit() Syscall void _exit(int status); Syscall mit der Nummer 1 Beendet das laufende Programm mit dem Rückgabewert status

Der open() Syscall int open(const char *pathname, int flags); Syscall mit der Nummer 5 Öffnet eine Datei pathname Rückgabewert: Nummer des Filediskriptors im Erfolgsfall, -1 im Fehlerfall

Der close() Syscall int close(int fd); Syscall mit der Nummer 6 Schließt eine geöffnete Datei mit dem Filediskriptor fd Rückgabewert: 0 im Erfolgsfall, -1 im Fehlerfall

Strings in Shellcode Wie kommt man eigentlich an die Adresse von einem String? Wo liegt denn hier das Problem? Ideen?

Strings in Shellcode Lösung Wir wissen wo der String relativ im Shellcode liegt relativer Jump vor den String Dann ein call zurück, die Adresse des Strings wird auf den Stack gepusht Mit einem Pop kommt die Adresse des Strings in ein Register 1.text 2 jmp my_string 3 back_to_my_code: 4 pop %eax 5... do stuff 6 my_string: 7 call back_to_my_code 8.string "Mein String, an den ich unbedingt kommen muss."

Strings in Shellcode Beispiel: Hello World! 1.text 2 enter $0, $0 3 push %ebx 4 jmp hello_str 5 begin: 6 pop %ecx 7 mov $13, %edx 8 mov $1, %ebx 9 mov $4, %eax 10 int $0x80 11 pop %ebx 12 leave 13 ret 14 hello_str: 15 call begin 16.string "Hello World!\n"

1 Compiliert das Hello World Beispiel und führt es in der Testbench aus. 2 Schreibt einen Shellcode der eine Shell öffnet, also z.b. /bin/sh ausführt, und führt ihn in der Testbench aus.

1 Motivation Was ist Shellcode? Beispiel 2 Einstieg Erzeugen, Testen von Shellcode 3 Der erste Shellcode Strings in Shellcode 4 Nullbytes, NOP Slides Das Problem mit den Nullbytes Nullbyte freier Shellcode NOP Slides

Das Problem mit den Nullbytes Das Beispiel vom Beginn 1 int main(int argc, char **argv) 2 { 3 char buffer[100]; 4 strcpy(buffer, argv[1]); 5 return 0; 6 } Welches Problem haben wir hier? Würde euer Shellcode von vorhin hier einfach funktionieren? Ideen?

Nullbyte freier Shellcode Erster Schritt: Nullbyte freie Instruktionen Einige Instruktionen oder deren Argumente enthalten Nullbytes. z.b. enter $0, $0 oder mov $0, %eax. Statt enter $0, $0 push %ebp und mov %esp, %ebp benutzen Statt mov $0, %eax xor %eax, %eax benutzen

Nullbyte freier Shellcode Zweiter Schritt: Nullbyte freie Strings Ein Nullbyte haben wir immer noch: den Nulldelimiter von unserem String Das stört, wenn wir dahinter z.b. noch eine Rücksprungadresse überschreiben Die Lösung ist einfach: Nulldelimiter durch einen Platzhalter ersetzen, während der Ausführung wieder durch Null ersetzen

Nullbyte freier Shellcode Beispiel: Nullbyte freie Strings 1 push %ebp 2 mov %esp, %ebp 3 push %ebx 4 jmp filename_str 5 begin: 6 pop %ebx 7 xor %eax, %eax 8 xor %ecx, %ecx 9 movb %cl, 8(%ebx) 10 movb $0100, %cl 11 movb $5, %al 12 int $0x80 13 pop %ebx 14 leave 15 ret 16 filename_str: 17 call begin 18.string "test.txt"

NOP Slides NOP Slides Oft schwer, exakt eine Adresse zu treffen Abhilfe können NOP Slides schaffen: Eine Folge von 1 Byte langen NOP Anweisungen vor den eigentlichen Shellcode schreiben Opcode von NOP: 0x90 Wird interpretiert als xchg %eax, %eax

1 Macht euren Shellcode Nullbyte frei. 2 Probiert euren Shellcode an der Bufferoverflow Challenge mit NOP Slide vom letzten Termin aus.