<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://demowiki.knowlus.com/index.php?action=history&amp;feed=atom&amp;title=Puffer%C3%BCberlauf</id>
	<title>Pufferüberlauf - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://demowiki.knowlus.com/index.php?action=history&amp;feed=atom&amp;title=Puffer%C3%BCberlauf"/>
	<link rel="alternate" type="text/html" href="https://demowiki.knowlus.com/index.php?title=Puffer%C3%BCberlauf&amp;action=history"/>
	<updated>2026-04-07T15:18:54Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in Demo Wiki</subtitle>
	<generator>MediaWiki 1.44.2</generator>
	<entry>
		<id>https://demowiki.knowlus.com/index.php?title=Puffer%C3%BCberlauf&amp;diff=14441&amp;oldid=prev</id>
		<title>imported&gt;Vfb1893: BKL Modula aufgelöst</title>
		<link rel="alternate" type="text/html" href="https://demowiki.knowlus.com/index.php?title=Puffer%C3%BCberlauf&amp;diff=14441&amp;oldid=prev"/>
		<updated>2025-08-21T19:10:26Z</updated>

		<summary type="html">&lt;p&gt;BKL &lt;a href=&quot;/index.php?title=Modula&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;Modula (Seite nicht vorhanden)&quot;&gt;Modula&lt;/a&gt; aufgelöst&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Belege|Im Artikel sind Belege nur gelegentlich zu finden.|Dieser Artikel}}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Pufferüberläufe&amp;#039;&amp;#039;&amp;#039; ({{enS|buffer overflow}}), nicht zu verwechseln mit [[Stapelüberlauf|Stapelüberläufen]] (englisch &amp;#039;&amp;#039;‚{{lang|en|stack overflows}}‘&amp;#039;&amp;#039;), gehören zu den häufigsten [[Sicherheitslücke|Sicherheitslücken]] in aktueller [[Software]], die sich u.&amp;amp;nbsp;a. über das [[Internet]] ausnutzen lassen können. Im Wesentlichen werden bei einem Pufferüberlauf durch Fehler im Programm zu große Datenmengen in einen dafür zu kleinen reservierten [[Speicherbereich]] –&amp;amp;nbsp;den [[Puffer (Informatik)|Puffer]]&amp;amp;nbsp;– geschrieben, wodurch nach dem Ziel-Speicherbereich liegende Speicherstellen überschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Ursache für unerwünschtes Schreiben außerhalb des Puffers kann nicht nur eine übergroße Datenmenge, sondern auch ein [[Arithmetischer Überlauf|Überlauf]] (oder sonstige fehlerhafte Berechnung) der Zieladresse sein, die anzeigt, wo der Datensatz in den Puffer geschrieben werden soll. In diesem Fall wird von einem &amp;#039;&amp;#039;‚{{lang|en|pointer overflow}}‘&amp;#039;&amp;#039; (vom englischen &amp;#039;&amp;#039;{{lang|en|pointer}}&amp;#039;&amp;#039;, für „[[Zeiger (Informatik)|Zeiger]]“) gesprochen.&lt;br /&gt;
&lt;br /&gt;
== Gefahren durch Pufferüberläufe ==&lt;br /&gt;
Ein Pufferüberlauf kann zum Absturz des betreffenden Programms, zur Verfälschung von Daten oder zur Beschädigung von Datenstrukturen der [[Laufzeitumgebung]] des Programms führen. Durch Letzteres kann die [[Rücksprungadresse]] eines [[Unterprogramm]]s mit beliebigen Daten überschrieben werden, wodurch ein Angreifer durch Übermittlung von beliebigem [[Maschinensprache|Maschinencode]] beliebige Befehle mit den Privilegien des für den Pufferüberlauf anfälligen Prozesses ausführen kann. Dieser Code hat in der Regel das Ziel, dem Angreifer einen komfortableren Zugang zum System zu verschaffen, damit dieser das System dann für seine Zwecke verwenden kann. Pufferüberläufe in verbreiteter [[Server]]- und [[Client]]software werden auch von [[Internetwurm|Internetwürmern]] ausgenutzt.&lt;br /&gt;
&lt;br /&gt;
Angriffe mit Pufferüberläufen sind ein wichtiges Thema in der [[Computersicherheit]] und [[Netzwerksicherheit]]. Sie können nicht nur über jegliche Art von Netzwerken, sondern auch lokal auf dem System versucht werden. Behoben werden sie in der Regel nur durch kurzfristig gelieferte Fehlerkorrekturen ([[Patch (Software)|Patches]]) der Hersteller.&lt;br /&gt;
&lt;br /&gt;
Interpretierte Sprachen sind, abgesehen von Fehlern im [[Interpreter]], in der Regel nicht anfällig, da der Speicher vom Interpreter, und nicht vom Programm selbst, verwaltet wird.&lt;br /&gt;
&lt;br /&gt;
== Programmiersprachen ==&lt;br /&gt;
Die wesentlichste Ursache für Pufferüberläufe ist die Verwendung von [[Programmiersprache]]n, die nicht die Möglichkeit bieten, Grenzen von [[Speicherbereich]]en automatisch zu überwachen, um eine [[Bereichsüberschreitung]] von Speicherbereichen zu verhindern. Dazu gehört besonders die Sprache [[C (Programmiersprache)|C]], die das Hauptgewicht auf [[Rechenleistung|Performance]] (und ursprünglich Einfachheit des Compilers) legt und auf eine Überwachung verzichtet, sowie die C-Weiterentwicklung [[C++]]. Hier ist ein Programmierer teilweise gezwungen, den entsprechenden Code von Hand zu generieren, wobei oft absichtlich oder aus Nachlässigkeit darauf verzichtet wird. Die Überprüfung ist häufig auch fehlerhaft implementiert, da während der Programmtests diese Programmteile meist nicht oder ungenügend getestet werden. Daneben stellen der (im Fall von C++) komplexe Sprachumfang und die Standardbibliothek sehr viele fehleranfällige Konstrukte zur Verfügung, zu denen es in vielen Fällen kaum eine Alternative gibt.&lt;br /&gt;
&lt;br /&gt;
Die häufig verwendete Programmiersprache C++ bietet nur eingeschränkte Möglichkeiten zur automatischen Überprüfung von Feldgrenzen. Als Weiterentwicklung der Programmiersprache C übernimmt sie die meisten Eigenschaften von C, wobei sich aber das Risiko von Pufferüberläufen bei Benutzung von modernen Sprachmitteln (u.&amp;amp;nbsp;a. automatische Speicherverwaltung) weitestgehend vermeiden lässt. Aus Gewohnheit, Kompatibilitätsgründen zu vorhandenem C-Code, Systemaufrufen in C-Konvention sowie aus Performancegründen wird von diesen Möglichkeiten aber nicht immer Gebrauch gemacht. Laufzeitüberprüfungen sind im Gegensatz zu Sprachen wie beispielsweise [[Pascal (Programmiersprache)|Pascal]] oder [[Ada (Programmiersprache)|Ada]] nicht Bestandteil der Sprache, lassen sich aber in einigen Anwendungsfällen (z.&amp;amp;nbsp;B. mit [[Smart Pointer]]n) nachrüsten.&lt;br /&gt;
&lt;br /&gt;
Da die meisten Programmiersprachen auch Standardbibliotheken definieren, bedeutet die Wahl einer Sprache meist auch die Verwendung der entsprechenden Standardbibliotheken. Im Fall von C und C++ enthält die Standardbibliothek eine Anzahl von gefährlichen Funktionen, die zum Teil gar keine sichere Verwendung zulassen und zu denen zum Teil keine Alternativen bestehen.&lt;br /&gt;
&lt;br /&gt;
Auf Programmiersprachenebene kann die Gefahr von Pufferüberläufen durch die Verwendung von Programmiersprachen, die konzeptionell sicherer als C++ oder C sind, verringert oder ausgeschlossen werden. Ein sehr viel geringeres Risiko besteht zum Beispiel in Programmiersprachen wie [[Rust (Programmiersprache)|Rust]], [[Java (Programmiersprache)|Java]], [[C-Sharp|C#]] oder der Pascal-Familie [[Modula-2]], [[Object Pascal]] oder Ada.&lt;br /&gt;
&lt;br /&gt;
Fast ausgeschlossen sind Pufferüberläufe beispielsweise in der Programmiersprache [[Java (Programmiersprache)|Java]], da die Ausführung im [[Bytecode]] überwacht wird. Aber auch in Java gibt es einerseits Pufferüberläufe, deren Ursache im Laufzeitsystem liegt und von denen mehrere [[Java Runtime Environment|JRE]]-Versionen betroffen sind.&amp;lt;ref&amp;gt;[http://www.linux-community.de/Neues/story?storyid=21756 &amp;#039;&amp;#039;Schwachstelle im Sun Java Runtime Environment&amp;#039;&amp;#039;] – &amp;#039;&amp;#039;LinuxCommunity&amp;#039;&amp;#039;, am 17. Januar 2007&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;[http://www.scip.ch/?vuldb.2842 Sun Java JRE bis 1.5.x GIF Image Handler Pufferüberlauf] – &amp;#039;&amp;#039;vuldb.com&amp;#039;&amp;#039;, am 22. Januar 2007 (letzte Änderung am 7. Juli 2015)&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Prozessoren und Programmierstil ==&lt;br /&gt;
Weitere Eigentümlichkeiten von C und C++ sowie der am häufigsten eingesetzten [[Prozessor]]en machen das Auftreten von Pufferüberläufen wahrscheinlich. Die Programme in diesen Sprachen bestehen zum Teil aus [[Unterprogramm]]en. Diese besitzen lokale Variablen.&lt;br /&gt;
&lt;br /&gt;
Bei modernen Prozessoren ist es üblich, die Rücksprungadresse eines Unterprogramms und dessen lokale Variablen auf einen als [[Stapelspeicher|Stack]] bezeichneten Bereich zu legen. Dabei werden beim Unterprogrammaufruf &amp;#039;&amp;#039;zunächst&amp;#039;&amp;#039; die Rücksprungadresse und &amp;#039;&amp;#039;danach&amp;#039;&amp;#039; die lokalen Variablen auf den Stack gelegt. Bei modernen Prozessoren wie dem [[Intel]] [[Pentium]] wird der Stack durch eingebaute Prozessorbefehle verwaltet und wächst zwingend &amp;#039;&amp;#039;nach unten&amp;#039;&amp;#039;. Werden Felder oder Zeichenketten in den lokalen Variablen verwendet, werden diese meist &amp;#039;&amp;#039;nach oben&amp;#039;&amp;#039; beschrieben. Wird die Feldgrenze nicht geprüft, kann man damit durch Überschreiten des Feldes die Rückkehradresse auf dem Stack erreichen und gegebenenfalls absichtlich modifizieren.&lt;br /&gt;
&lt;br /&gt;
Das folgende Programmstück in C, das in ähnlicher Form oft verwendet wird, zeigt einen solchen Pufferüberlauf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void input_line()&lt;br /&gt;
{&lt;br /&gt;
    char line[1000];&lt;br /&gt;
    if (gets(line))     // gets erhält Zeiger auf das Array, keine Längeninformation&lt;br /&gt;
        puts(line);     // puts schreibt den Inhalt von line nach stdout&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei Prozessoren, die den Stack nach unten beschreiben, sieht dieser vor dem Aufruf von &amp;#039;&amp;#039;gets&amp;#039;&amp;#039; (Funktion der Standard-Bibliothek von C) so aus (wenn man vom eventuell vorhandenen Base Pointer absieht&amp;lt;ref&amp;gt;&amp;#039;&amp;#039;[http://www.a-m-i.de/tips/stack/stack.php Was ist ein Stack?]&amp;#039;&amp;#039;. 2. Juni 2012.&amp;lt;/ref&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot;&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe6&amp;quot;| Rücksprungadresse&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| 1000. Zeichen&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| … …&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| 3. Zeichen&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| 2. Zeichen&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| 1. Zeichen&lt;br /&gt;
| ←Stackpointer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;&amp;#039;Der Stack wächst nach unten, die Variable wird nach oben überschrieben&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;gets&amp;#039;&amp;#039; liest eine Zeile von der Eingabe und schreibt die Zeichen ab &amp;#039;&amp;#039;line[0]&amp;#039;&amp;#039; in den Stack. Es überprüft die Länge der Zeile nicht. Gemäß der Semantik von C erhält &amp;#039;&amp;#039;gets&amp;#039;&amp;#039; nur die Speicheradresse als Pointer, jedoch keinerlei Information über die verfügbare Länge. Wenn man jetzt 1004 Zeichen eingibt, überschreiben die letzten 4 Bytes die Rücksprungadresse (unter der Annahme, dass eine Adresse hier 4 Bytes groß ist), die man auf ein Programmstück innerhalb des Stack richten kann. In den ersten 1000 Zeichen kann man gegebenenfalls ein [[Shellcode|geeignetes Programm]] eingeben.&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;00@45eA/%A@4&amp;lt;/code&amp;gt; … ... … ... … ... … ... … ... … ... &amp;lt;code&amp;gt;0A&amp;amp;%&amp;lt;/code&amp;gt;&lt;br /&gt;
: &amp;#039;&amp;#039;Eingabe, wird von gets in den Stack geschrieben (1004 Zeichen)&amp;#039;&amp;#039;&lt;br /&gt;
{| border=&amp;quot;0&amp;quot;&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe6&amp;quot;| modifizierte Rücksprungadresse&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| line, 1000. Zeichen&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| …&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| line, 5. Zeichen&lt;br /&gt;
| drittes Byte im Code&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| line, 4. Zeichen&lt;br /&gt;
| zweites Byte im Code&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| line, 3. Zeichen&lt;br /&gt;
| Ziel der Rücksprungadresse, Programmcodestart&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| line, 2. Zeichen&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| line, 1. Zeichen&lt;br /&gt;
| ←Stackpointer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;&amp;#039;Überschreiben der Rücksprungadresse und Programmcode im Stack&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Falls das Programm höhere Privilegien besitzt als der Benutzer, kann dieser unter Ausnutzung des Pufferüberlaufs durch eine spezielle Eingabe diese Privilegien erlangen.&lt;br /&gt;
&lt;br /&gt;
== Gegenmaßnahmen ==&lt;br /&gt;
=== Programmerstellung ===&lt;br /&gt;
Eine sehr nachhaltige Gegenmaßnahme besteht in der Verwendung [[Typsicherheit|typsicherer]] Programmiersprachen und -werkzeuge, wie zum Beispiel [[Java (Programmiersprache)|Java]] oder [[C-Sharp|C#]], bei denen die Einhaltung von zugewiesenen Speicherbereichen gegebenenfalls schon beim Übersetzen in Maschinensprache mit dem [[Compiler]] kontrolliert, aber spätestens zur [[Laufzeit (Informatik)|Laufzeit]] mit entsprechendem Programmcode überwacht wird. Es ist hierbei unerlässlich, dass das Verändern von [[Zeiger (Informatik)|Zeigervariablen]] nur nach strengen, einschränkenden Regeln erfolgen darf, und es ist in diesem Zusammenhang auch hilfreich, wenn ausschließlich das [[Laufzeitsystem]] [[automatische Speicherbereinigung]]en durchführt.&lt;br /&gt;
&lt;br /&gt;
Bei der Erstellung von Programmen muss also auf die Überprüfung aller Feldgrenzen geachtet werden. Dies liegt bei nicht-typsicheren Programmiersprachen in der Verantwortung des Programmierers. Allerdings sollte vorzugsweise die Verwendung von Programmiersprachen, die automatisch Feldgrenzen überwachen, in Erwägung gezogen werden, was jedoch nicht immer ohne weiteres möglich ist. Bei Verwendung von C++ sollte die Verwendung von Feldern im C-Stil so weit wie möglich vermieden werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void input_line()&lt;br /&gt;
{&lt;br /&gt;
    char line[1000];&lt;br /&gt;
    if (fgets(line, sizeof(line), stdin))   // fgets überprüft die Länge&lt;br /&gt;
        puts(line);  // puts schreibt den Inhalt von line nach stdout&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;&amp;#039;Gegenmaßnahme: fgets überprüft die Eingabelänge&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Überprüfung des Programmcodes ===&lt;br /&gt;
Spezielle Überprüfungswerkzeuge erlauben die Analyse des Codes und entdecken mögliche Schwachstellen. Allerdings kann der Code zur Feldgrenzenüberprüfung fehlerhaft sein, was oft nicht getestet wird.&lt;br /&gt;
&lt;br /&gt;
=== Unterstützung durch Compiler ===&lt;br /&gt;
In C und C++ steht eine sehr große Auswahl bestehender Programme zur Verfügung. Moderne [[Compiler]] wie neue Versionen des &amp;#039;&amp;#039;GNU C-Compilers&amp;#039;&amp;#039; erlauben die Aktivierung von Überprüfungscode-Erzeugung bei der Übersetzung.&lt;br /&gt;
&lt;br /&gt;
Sprachen wie C erlauben aufgrund ihres Designs nicht immer die Überprüfung der Feldgrenzen (Beispiel: &amp;#039;&amp;#039;gets&amp;#039;&amp;#039;). Die Compiler müssen andere Wege gehen: Sie fügen zwischen der Rücksprungadresse und den lokalen Variablen Platz für eine Zufallszahl (auch „Canary“ genannt) ein. Beim Programmstart wird diese Zahl ermittelt, wobei sie jedes Mal unterschiedliche Werte annimmt. Bei jedem Unterprogrammaufruf wird die Zufallszahl in den dafür vorgesehenen Bereich geschrieben. Der erforderliche Code wird vom Compiler automatisch generiert. Vor dem Verlassen des Programms über die Rücksprungadresse fügt der Compiler Code ein, der die Zufallszahl auf den vorgesehenen Wert überprüft. Wurde sie geändert, ist auch der Rücksprungadresse nicht zu trauen. Das Programm wird mit einer entsprechenden Meldung abgebrochen.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot;&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe6&amp;quot;| Rücksprungadresse&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#FF6900&amp;quot;| Zufallszahlbarriere&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| line, 1000. Zeichen&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| …&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| line, 3. Zeichen&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| line, 2. Zeichen&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| line, 1. Zeichen&lt;br /&gt;
| ←Stackpointer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;&amp;#039;Gegenmaßnahme: Zufallszahlbarriere &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Daneben kann man manche Compiler auch veranlassen, beim Unterprogrammaufruf eine &amp;#039;&amp;#039;Kopie&amp;#039;&amp;#039; der Rücksprungadresse unterhalb der lokalen Felder zu erzeugen. Diese Kopie wird beim Rücksprung verwendet, die Ausnutzung von Pufferüberläufen ist dann wesentlich erschwert:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot;&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe6&amp;quot;| Rücksprungadresse&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| line, 1000. Zeichen&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| …&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| line, 3. Zeichen&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| line, 2. Zeichen&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|class=&amp;quot;hintergrundfarbe5&amp;quot;| line, 1. Zeichen&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#00FF00&amp;quot;| Kopie der Rücksprungadresse&lt;br /&gt;
| ←Stackpointer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
: &amp;#039;&amp;#039;&amp;#039;Gegenmaßnahme: Kopie der Rücksprungadresse&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Compiler und Compilererweiterungen ==&lt;br /&gt;
Für die [[GNU Compiler Collection]] existieren beispielsweise zwei verbreitete Erweiterungen, die Maßnahmen wie die oben beschriebenen implementieren:&lt;br /&gt;
* Der &amp;#039;&amp;#039;Stack Smashing Protector&amp;#039;&amp;#039; von [[IBM]], ehemals als &amp;#039;&amp;#039;ProPolice&amp;#039;&amp;#039; bekannt ([http://www.trl.ibm.com/projects/security/ssp/ Homepage, englisch]).&lt;br /&gt;
* Der &amp;#039;&amp;#039;Stack Guard&amp;#039;&amp;#039;, entwickelt an der [[Oregon Health &amp;amp; Science University]], zwischenzeitlich bei der [[Linux-Distribution]] &amp;#039;&amp;#039;Immunix&amp;#039;&amp;#039;, jetzt bei [[Novell]].&lt;br /&gt;
&lt;br /&gt;
== Heap-Überlauf ==&lt;br /&gt;
Ein &amp;#039;&amp;#039;Heap-Überlauf&amp;#039;&amp;#039; ist ein Pufferüberlauf, der auf dem [[Dynamischer Speicher|Heap]] stattfindet. Speicher auf dem Heap wird zugewiesen, wenn Programme dynamischen Speicher anfordern, etwa über malloc() oder den &amp;#039;&amp;#039;new&amp;#039;&amp;#039;-Operator in [[C++]]. Werden in einen Puffer auf dem Heap Daten ohne Überprüfung der Länge geschrieben und ist die Datenmenge größer als die Größe des Puffers, so wird über das Ende des Puffers hinausgeschrieben und es kommt zu einem Speicherüberlauf.&lt;br /&gt;
&lt;br /&gt;
Durch &amp;#039;&amp;#039;Heap-Überläufe&amp;#039;&amp;#039; kann durch Überschreiben von Zeigern auf Funktionen beliebiger Code auf dem Rechner ausgeführt werden, insbesondere wenn der Heap ausführbar ist. [[FreeBSD]] hat beispielsweise einen Heap-Schutz, hier ist das nicht möglich. Sie können nur in [[Programmiersprache]]n auftreten, in denen bei Pufferzugriffen keine Längenüberprüfung stattfindet. [[C (Programmiersprache)|C]], [[C++]] oder [[Assemblersprache|Assembler]] sind anfällig, [[Java (Programmiersprache)|Java]] oder [[Perl (Programmiersprache)|Perl]] sind es nicht.&lt;br /&gt;
&lt;br /&gt;
Zum Bsp. wurde am 23. Juni 2015 von [[Adobe Inc.|Adobe]] bekannt gegeben, dass durch solch einen Pufferüberlauf beliebiger [[Schadprogramm|Schadcode]] auf Systemen ausgeführt werden könne und so die Kontrolle über das System übernommen werden könnte, auf denen der [[Adobe Flash|Flash Player]] installiert sei.&amp;lt;ref&amp;gt;{{Internetquelle |autor=Dennis Schirrmacher |url=https://www.heise.de/security/meldung/Adobe-Notfall-Update-fuer-Flash-Player-2724360.html |titel=Adobe: Notfall-Update für Flash Player |werk=Heise Security |hrsg=[[Heise online]] |datum=2015-06-24 |abruf=2015-06-29}}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{Internetquelle |url=https://helpx.adobe.com/security/products/flash-player/apsb15-14.html |titel=Security updates available for Adobe Flash Player – CVE number: CVE-2015-3113 |werk=Adobe Security Bulletin |hrsg=[[Adobe Inc.]] |datum=2015-06-23 |abruf=2015-06-29}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Siehe auch|Shellcode|Exploit}}&lt;br /&gt;
&lt;br /&gt;
== Beispiel ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define BUFSIZE 128&lt;br /&gt;
&lt;br /&gt;
char * copy_string(const char *s)&lt;br /&gt;
{&lt;br /&gt;
    char * buf = malloc(BUFSIZE); // Annahme: Längere Strings kommen niemals vor&lt;br /&gt;
&lt;br /&gt;
    if (buf)&lt;br /&gt;
        strcpy(buf, s); // Heap-Überlauf, falls strlen(s) &amp;gt; 127&lt;br /&gt;
&lt;br /&gt;
    return buf;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da strcpy() die Größen von Quelle und Ziel nicht überprüft, sondern als Quelle einen null-terminierten (&amp;#039;\0&amp;#039;) Speicherbereich erwartet, ist auch die folgende Variante unsicher (sie wird allerdings nicht über &amp;quot;buf&amp;quot; hinausschießen, sondern ggf. über das Ende des &amp;quot;s&amp;quot; zugewiesenen Speicherbereichs).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
char * buf;&lt;br /&gt;
&lt;br /&gt;
buf = malloc(1 + strlen(s)); // Plus 1 wegen des terminierenden NUL-Zeichens&lt;br /&gt;
if (buf)&lt;br /&gt;
    strcpy(buf, s);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der strncpy-Befehl dagegen kopiert maximal n Zeichen von der Quelle zum Ziel und funktioniert somit, wenn s nullterminiert oder größer als BUFSIZE ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
char *buf;&lt;br /&gt;
&lt;br /&gt;
if ((buf = malloc(BUFSIZE)) != NULL) { // Überprüfung des Zeigers.&lt;br /&gt;
    strncpy(buf, s, BUFSIZE - 1);&lt;br /&gt;
    buf[BUFSIZE - 1] = &amp;#039;\0&amp;#039;;  // Nachteil: Die Zeichenkette muss manuell terminiert werden.&lt;br /&gt;
}&lt;br /&gt;
return buf;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Einige Betriebssysteme, z.&amp;amp;nbsp;B. [[OpenBSD]], bieten die Funktion &amp;#039;&amp;#039;strlcpy&amp;#039;&amp;#039; an, die ihrerseits sicherstellt, dass der Zielstring nullterminiert wird und das Erkennen eines abgeschnittenen Zielstrings vereinfacht.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Angriffsvektor]]&lt;br /&gt;
* [[Arithmetischer Überlauf]]&lt;br /&gt;
* [[NX-Bit]]&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
* Aleph One: &amp;#039;&amp;#039;[http://fringe.davesource.com/Fringe/Hacking/Documents/Smashing_The_Stack Smashing The Stack For Fun And Profit].&amp;#039;&amp;#039; In: &amp;#039;&amp;#039;[[Phrack-Magazin]].&amp;#039;&amp;#039; 7, Nr. 49 (Dieser Artikel veranschaulicht sehr gut die Wirkungsweise von Pufferüberläufen).&lt;br /&gt;
* Jon Erickson: &amp;#039;&amp;#039;Forbidden Code.&amp;#039;&amp;#039; mitp, Bonn 2004, ISBN 3-8266-1457-7.&lt;br /&gt;
* Tobias Klein: &amp;#039;&amp;#039;Buffer Overflows und Format-String-Schwachstellen. Funktionsweisen, Exploits und Gegenmaßnahmen.&amp;#039;&amp;#039; Dpunkt, Heidelberg 2004, ISBN 3-89864-192-9.&lt;br /&gt;
* Felix Lindner: &amp;#039;&amp;#039;Ein Haufen Risiko. Pufferüberläufe auf dem Heap und wie man sie ausnutzt.&amp;#039;&amp;#039; In: &amp;#039;&amp;#039;[[c’t]]. Magazin für Computer-Technik.&amp;#039;&amp;#039; 23, 9, 2006, S. 186–192, [https://www.heise.de/security/artikel/Ein-Haufen-Risiko-270800.html auch kostenlos online im heise Security].&lt;br /&gt;
* Oliver Müller: &amp;#039;&amp;#039;Überläufer. Systemeinbruch via Stack-Overflow.&amp;#039;&amp;#039; In: &amp;#039;&amp;#039;[[iX – Magazin für professionelle Informationstechnik]].&amp;#039;&amp;#039; Band 2, 2007, S. 100–105.&lt;br /&gt;
* Stephan Kallnik, Daniel Pape, Daniel Schröter, Stefan Strobel, Daniel Bachfeld: [https://www.heise.de/security/artikel/Eingelocht-270148.html &amp;#039;&amp;#039;Eingelocht. Buffer-Overflows und andere Sollbruchstellen&amp;#039;&amp;#039;.] heise Security, auch in {{Webarchiv |url=http://www.heise.de/ct/01/23/216/ |text=&amp;#039;&amp;#039;c’t&amp;#039;&amp;#039; 23/2001, S. 216 |wayback=20011114032312}}. Einführungsartikel mit einfachen Beispielen in C.&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://insecure.org/stf/smashstack.html Technische Details von Buffer-Overflow (und Exploits)]&lt;br /&gt;
* [https://www.heise.de/security/artikel/Ein-Haufen-Risiko-270800.html/0 Ausnutzung eines Heap overflow]&lt;br /&gt;
* {{Webarchiv |url=http://www.heise.de/ct/01/23/216/ |text=Buffer-Overflows und wie man sich davor schützt |wayback=20011114032312}}&lt;br /&gt;
* [https://www.heise.de/security/artikel/Eingelocht-270148.html Buffer-Overflows und andere Sollbruchstellen]&lt;br /&gt;
&lt;br /&gt;
== Einzelnachweise ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Normdaten|TYP=s|GND=4752450-9}}&lt;br /&gt;
&lt;br /&gt;
{{SORTIERUNG:Pufferuberlauf}}&lt;br /&gt;
[[Kategorie:Programmfehler]]&lt;br /&gt;
[[Kategorie:Sicherheitslücke]]&lt;br /&gt;
[[Kategorie:Hackertechnik (Computersicherheit)]]&lt;/div&gt;</summary>
		<author><name>imported&gt;Vfb1893</name></author>
	</entry>
</feed>