hacktricks/reversing-and-exploiting/linux-exploiting-basic-esp/stack-overflow/README.md

7.7 KiB

Stack Overflow

Erlernen Sie AWS-Hacking von Grund auf 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 Speicherplatz ü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 Grenzprüfung für Eingaben durchführen.

Das Hauptproblem dieses Überschreibens besteht darin, dass die EIP- und EBP-Zeiger zum Zurückkehren zur vorherigen Funktion im Stack gespeichert sind. Daher kann ein Angreifer diese überschreiben und die Ausführungssteuerung des Programms kontrollieren.

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 gängige Funktionen, die anfällig dafür sind, sind: strcpy, strcat, sprintf, gets, fgets...

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 Overflows

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 einen Segmentation Fault zu erwarten, der darauf hinweist, dass versucht wurde, auf die Adresse 0x41414141 zuzugreifen.

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

Auf diese Weise ist es möglich, anstelle herauszufinden, welcher Offset den EIP überschreibt, manuell eine dieser Sequenzen als Padding zu verwenden und dann den Offset der Bytes zu finden, die es versehentlich ü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-Überläufen

Während eines Überlaufs (vorausgesetzt, die Überlaufgröße ist groß genug) können Werte anderer Variablen im Stack überschrieben werden, bis EBP und EIP (oder sogar mehr) erreicht sind.
Der häufigste Weg, diese Art von Schwachstelle auszunutzen, besteht darin, den EIP-Zeiger zu ändern, sodass die Steuerung an die vom Benutzer angegebene Stelle umgeleitet wird, wenn die Funktion endet.

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

Ret2win

In diesem Typ von CTF-Herausforderungen gibt es eine Funktion im Binär, die nie aufgerufen wird und die du aufrufen musst, um zu gewinnen. Für diese Herausforderungen musst du einfach den Offset zum Überschreiben des EIP finden und die Adresse der Funktion zum Aufrufen finden (normalerweise wäre ASLR deaktiviert), sodass, wenn die verwundbare Funktion zurückkehrt, die versteckte Funktion aufgerufen wird:

{% content-ref url="ret2win.md" %} ret2win.md {% endcontent-ref %}

Stack-Shellcode

In diesem Szenario könnte der Angreifer einen Shellcode im Stack platzieren und den kontrollierten EIP missbrauchen, um zum Shellcode zu gelangen und den Code des Angreifers auszuführen:

{% content-ref url="stack-shellcode.md" %} stack-shellcode.md {% endcontent-ref %}

ROP

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

{% content-ref url="rop-return-oriented-programing.md" %} rop-return-oriented-programing.md {% endcontent-ref %}

Arten von Schutzmaßnahmen

Es gibt mehrere Schutzmaßnahmen, die versuchen, die Ausnutzung von Schwachstellen zu verhindern. Überprüfe sie unter:

{% content-ref url="../common-binary-protections-and-bypasses/" %} common-binary-protections-and-bypasses {% endcontent-ref %}

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

Andere Möglichkeiten, HackTricks zu unterstützen: