Stack Overflow

Erlernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Was ist ein Stack Overflow

Ein Stack Overflow ist eine Schwachstelle, die auftritt, wenn ein Programm mehr Daten auf den Stack schreibt, als ihm zugewiesen sind. Diese überschüssigen Daten werden den angrenzenden Speicherbereich überschreiben, was zur Beschädigung gültiger Daten, zur Unterbrechung des Kontrollflusses und potenziell zur Ausführung von bösartigem Code führen kann. Dieses Problem tritt häufig aufgrund der Verwendung unsicherer Funktionen auf, die keine Begrenzungsprüfung für Eingaben durchführen.

Das Hauptproblem dieses Überschreibens besteht darin, dass der gespeicherte Anweisungszeiger (EIP/RIP) und der gespeicherte Basiszeiger (EBP/RBP) zum Zurückkehren zur vorherigen Funktion auf dem Stack gespeichert sind. Daher kann ein Angreifer diese überschreiben und die Ausführungsreihenfolge des Programms steuern.

Die Schwachstelle tritt normalerweise auf, weil eine Funktion mehr Bytes in den Stack kopiert als für sie allokiert sind, und dadurch andere Teile des Stacks überschrieben werden können.

Einige häufige Funktionen, die anfällig dafür sind, sind: strcpy, strcat, sprintf, gets... Auch Funktionen wie fgets, read & memcpy, die ein Längenargument enthalten, können auf verwundbare Weise verwendet werden, wenn die angegebene Länge größer ist als die allokierte.

Beispielsweise könnten die folgenden Funktionen anfällig sein:

void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}

Finden von Stack Overflow-Offsets

Der häufigste Weg, Stack Overflows zu finden, besteht darin, eine sehr große Eingabe von As zu geben (z. B. python3 -c 'print("A"*1000)') und auf einen Segmentation Fault zu warten, der darauf hinweist, dass die Adresse 0x41414141 versucht wurde zuzugreifen.

Darüber hinaus, sobald festgestellt wurde, dass es eine Stack Overflow-Schwachstelle gibt, müssen Sie den Offset finden, bis es möglich ist, die Rückkehradresse zu überschreiben. Dafür wird in der Regel eine De Bruijn-Sequenz verwendet. Diese ist für ein gegebenes Alphabet der Größe k und Teilfolgen der Länge n eine zyklische Sequenz, in der jede mögliche Teilfolge der Länge n genau einmal als zusammenhängende Teilfolge erscheint.

Auf diese Weise ist es möglich, anstelle herauszufinden, welcher Offset benötigt wird, um die EIP manuell zu steuern, eine dieser Sequenzen als Padding zu verwenden und dann den Offset der Bytes zu finden, die sie überschrieben haben.

Es ist möglich, pwntools dafür zu verwenden:

from pwn import *

# Generate a De Bruijn sequence of length 1000 with an alphabet size of 256 (byte values)
pattern = cyclic(1000)

# This is an example value that you'd have found in the EIP/IP register upon crash
eip_value = p32(0x6161616c)
offset = cyclic_find(eip_value)  # Finds the offset of the sequence in the De Bruijn pattern
print(f"The offset is: {offset}")

oder GEF:

#Patterns
pattern create 200 #Generate length 200 pattern
pattern search "avaaawaa" #Search for the offset of that substring
pattern search $rsp #Search the offset given the content of $rsp

Ausnutzen von Stack Overflows

Während eines Überlaufs (vorausgesetzt, die Überlaufgröße ist groß genug) können Werte von lokalen Variablen im Stack überschrieben werden, bis die gespeicherten EBP/RBP und EIP/RIP (oder sogar mehr) erreicht sind. Der häufigste Weg, diese Art von Schwachstelle auszunutzen, besteht darin, die Rückgabeadresse zu ändern, sodass beim Beenden der Funktion der Steuerfluss dorthin umgeleitet wird, wo der Benutzer es in diesem Zeiger angegeben hat.

In anderen Szenarien reicht es möglicherweise aus, nur einige Variablenwerte im Stack zu überschreiben, um die Ausnutzung zu ermöglichen (wie bei einfachen CTF-Herausforderungen).

Ret2win

Bei dieser Art von CTF-Herausforderungen gibt es eine Funktion im Binär, die nie aufgerufen wird und die Sie aufrufen müssen, um zu gewinnen. Für diese Herausforderungen müssen Sie nur den Offset finden, um die Rückgabeadresse zu überschreiben, und die Adresse der Funktion finden, die aufgerufen werden soll (normalerweise wäre ASLR deaktiviert), sodass beim Rückkehren der anfälligen Funktion die versteckte Funktion aufgerufen wird:

pageRet2win

Stack-Shellcode

In diesem Szenario könnte der Angreifer einen Shellcode im Stack platzieren und den kontrollierten EIP/RIP missbrauchen, um zum Shellcode zu springen und beliebigen Code auszuführen:

pageStack Shellcode

ROP & Ret2... Techniken

Diese Technik ist das grundlegende Framework, um den Hauptschutz vor der vorherigen Technik zu umgehen: Kein ausführbarer Stack (NX). Und es ermöglicht die Durchführung mehrerer anderer Techniken (ret2lib, ret2syscall...), die dazu führen, dass durch den Missbrauch vorhandener Anweisungen im Binärcode beliebige Befehle ausgeführt werden:

pageROP - Return Oriented Programing

Heap-Überläufe

Ein Überlauf tritt nicht immer im Stack auf, er könnte auch im Heap auftreten, zum Beispiel:

pageHeap Overflow

Arten von Schutzmaßnahmen

Es gibt mehrere Schutzmaßnahmen, die versuchen, die Ausnutzung von Schwachstellen zu verhindern, überprüfen Sie diese unter:

pageCommon Binary Exploitation Protections & Bypasses

Last updated