Wie Buffer-Overflow-Angriffe funktionieren
Es gibt zwei verschiedene Arten von Buffer-Overflow-Angriffen: Stapel-basierte und Heap-basierte.
Puffer-Überläufe oder auch Buffer-Overflows sind bei Hackern eine beliebte Schwachstelle – die überwiegende Zahl der von Microsoft bereitgestellten Patches korrigiert unkontrollierte Puffer-Probleme. Aber wie verhält es sich mit selbst erstellten Anwendungen? Sie sind genau wie geschäftliche Applikationen ebenfalls empfänglich für Buffer-Overflow-Angriffe. Genau deshalb ist es unverzichtbar zu verstehen, wie diese ablaufen und die selbst erstellten Anwendungen entsprechenden Schwachstellen-Tests zu unterziehen, bevor diese zur allgemeinen Nutzung freigegeben werden.
Ein Puffer-Überlauf ist eine Schwachstelle, bei der ein Programm ausgenutzt wird, das gerade auf eine Benutzer-Eingabe wartet. Es gibt zwei verschiedene Arten von Buffer-Overflow-Angriffen: Stapel-basierte und Heap-basierte. Heap-basierte Angriffe überschwemmen den Speicherplatz, der für ein Programm reserviert ist. Allerdings ist dieser Angriff aufgrund der schwierigen Ausführung relativ selten. Stapel-basierte Puffer-Überläufe dagegen sind mit Abstand die häufigste Variante dieser Angriffsart.
Bei einem Stapel-basierten Puffer-Überlauf verwendet das Programm mit der Schwachstelle zur Speicherung von Benutzer-Eingaben ein Objekt, das als Stapel oder Stack bezeichnet wird. Normalerweise ist dieser Stack solange leer, bis das Programm eine Eingabe von einem Benutzer benötigt. Zu diesem Zeitpunkt schreibt das Programm eine Rücksprung-Speicheradresse in den Stack und platziert darauf die Benutzer-Eingabe. Nachdem der Stapel verarbeitet wurde, wird die Eingabe an die Rücksprung-Adresse gesendet, die vom Programm festgelegt wurde.
Allerdings ist die Größe des Stapels nicht unbegrenzt. Der Programmierer, der die Anwendung entwickelt, muss die Größe des für den Stack reservierten Speicherplatzes festlegen. Falls die Länge der Benutzer-Eingabe diesen reservierten Speicherplatz übertrifft, läuft der Stack über. Für sich betrachtet stellt dies kein sonderliches großes Problem dar. Es kann allerdings zu einer gewaltigen Sicherheitslücke werden, wenn dies in Kombination mit der Eingabe von Schad-Code geschieht.
Nehmen wir zum Beispiel an, ein Programm wartet darauf, dass der Anwender seinen Namen eingibt. Anstelle eines Namens wird der Hacker dann ein ausführbares Kommando eingeben, das die Stack-Größe überschreitet. Normalerweise handelt es sich dabei um eine relativ kurze Anweisung. In einer Linux-Umgebung könnte die Anweisung häufig EXEC(„sh“) lauten, wodurch das System dazu veranlasst wird, ein Fenster mit einer Eingabe-Aufforderung zu öffnen – in Linux-Kreisen auch als Root-Shell bekannt.
Der reine Überlauf des Puffers durch das ausführbare Kommando bedeutet allerdings noch nicht, dass dieses auch ausgeführt wird. Der Angreifer muss für diesen Fall noch eine Rücksprung-Adresse angeben, die auf die bösartige Anweisung zeigt. Das Programm stürzt dann teilweise ab, weil der Stack überläuft. Es versucht sich wiederherzustellen, indem es zur Rücksprung-Adresse springt. Diese wurde jedoch so verändert, dass sie auf die Anweisung zeigt, die der Hacker eingegeben hat. Natürlich bedeutet dies, dass der Hacker die Adresse kennen muss, auf der die bösartige Anweisung liegt. Um zu vermeiden, dass die tatsächliche Adresse benötigt wird, schließt man die Schad-Anweisung häufig beidseitig zwischen NOP-Anweisungen – einer Art Zeiger – ein. Die Technik des beidseitigen Einschließens – auch Padding genannt – wird meist dann verwendet, wenn der genaue Adressbereich des Speichers unbekannt ist. Deshalb wird die Anweisung ausgeführt, sobald die vom Hacker angegebene Adresse irgendwo innerhalb des Paddings liegt.
Der letzte Punkt dreht sich um die Berechtigungen für das ausführbare Programm. Wie Sie sicherlich wissen, verfügen die meisten modernen Betriebssysteme über Mechanismen zum Steuern der Zugriffsrechte des Benutzers, der gegenwärtig angemeldet ist. Ausführbare Programme erfordern normalerweise Berechtigungen einer höheren Ebene. Diese Programme laufen deshalb entweder im Kernel-Modus oder mit den geerbten Berechtigungen eines Dienst-Kontos. Wenn ein Stack-Overflow-Angriff die Anweisung an der neuen Rücksprung-Adresse ausführt, denkt das Programm, dass es immer noch läuft. Dies bedeutet: Das geöffnete Fenster mit der Eingabe-Aufforderung wird mit demselben Satz von Berechtigungen ausgeführt wie die kompromittierte Anwendung. Allgemeiner ausgedrückt: Der Angreifer erhält die vollständige Kontrolle über das Betriebssystem.