Shellcode
# Shellcode

Shellcode ist ein Begriff aus der Programmierung und bezeichnet einen zumeist sehr kleinen Patch von in Opcodes umgewandelten Assemblerbefehlen, mit denen beabsichtigt wird, ein Programm oder System zu manipulieren, oder für nicht vorgesehene Zwecke auszunutzen. Dabei wird oft versucht, eine Shell zu starten, daher auch der Name. Shellcodes haben ihren Ursprung in Pufferüberlauf- und anderen Code-Injektions-Attacken, sie können aber auch bei Software-, insbesondere Penetrationstests zum Einsatz kommen, beim Experimentieren und in der Didaktik.

## 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 Exploits darf im Shellcode kein 0-Byte enthalten sein, weil dieses in C das String-Ende markiert. Im Allgemeinen müssen weitere Hindernisse umgangen werden, beispielsweise werden nur Buchstaben und Zahlen zugelassen oder die Groß- und Kleinschreibung verändert, oder es müssen bestimmte Offsets eingehalten werden, was etwa durch Auffüllen mit mehr oder minder kreativen Ketten von Nulloperationen (sog. NOP Slides) erreicht werden kann.

Anstatt eigenen Code auszuführen, was nicht immer möglich ist (zum Beispiel bei 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):

Der Opcode String:

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.

