hacktricks/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries
2024-05-05 22:18:38 +00:00
..
bf-forked-stack-canaries.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/aw2 2024-05-05 22:18:38 +00:00
print-stack-canary.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/aw2 2024-04-07 03:07:20 +00:00
README.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/aw2 2024-04-07 22:24:36 +00:00

Stack Canaries

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

Andere Möglichkeiten, HackTricks zu unterstützen:

StackGuard und StackShield

StackGuard fügt einen speziellen Wert, bekannt als Canary, vor dem EIP (Extended Instruction Pointer) ein, speziell 0x000aff0d (null, Zeilenumbruch, EOF, Wagenrücklauf), um sich vor Pufferüberläufen zu schützen. Funktionen wie recv(), memcpy(), read() und bcopy() bleiben jedoch anfällig, und es schützt nicht den EBP (Base Pointer).

StackShield geht mit einem Globalen Rückgabestapel einen anspruchsvolleren Ansatz als StackGuard, der alle Rückgabeadressen (EIPs) speichert. Diese Einrichtung stellt sicher, dass ein Überlauf keinen Schaden verursacht, da ein Vergleich zwischen gespeicherten und tatsächlichen Rückgabeadressen erfolgt, um Überlaufvorkommen zu erkennen. Darüber hinaus kann StackShield die Rückgabeadresse gegen einen Grenzwert überprüfen, um festzustellen, ob der EIP außerhalb des erwarteten Datenspeichers zeigt. Diese Schutzmaßnahme kann jedoch durch Techniken wie Return-to-libc, ROP (Return-Oriented Programming) oder ret2ret umgangen werden, was darauf hindeutet, dass auch StackShield lokale Variablen nicht schützt.

Stack Smash Protector (ProPolice) -fstack-protector:

Dieser Mechanismus platziert einen Canary vor dem EBP und ordnet lokale Variablen um, um Puffer an höheren Speicheradressen zu positionieren, um ein Überschreiben anderer Variablen zu verhindern. Er kopiert auch sicher Argumente, die über den Stapel übergeben werden, über lokale Variablen und verwendet diese Kopien als Argumente. Es schützt jedoch keine Arrays mit weniger als 8 Elementen oder Puffer innerhalb einer Benutzerstruktur.

Der Canary ist eine Zufallszahl, abgeleitet von /dev/urandom oder einem Standardwert von 0xff0a0000. Er wird im TLS (Thread Local Storage) gespeichert, was gemeinsame Speicherbereiche über Threads hinweg ermöglicht, um threadspezifische globale oder statische Variablen zu haben. Diese Variablen werden ursprünglich vom Elternprozess kopiert, und Kindprozesse können ihre Daten ändern, ohne den Eltern- oder Geschwisterprozess zu beeinflussen. Wenn jedoch ein fork() ohne Erstellung eines neuen Canary verwendet wird, teilen alle Prozesse (Eltern und Kinder) denselben Canary, was ihn anfällig macht. Auf der i386-Architektur wird der Canary bei gs:0x14 und auf x86_64 bei fs:0x28 gespeichert.

Dieser lokale Schutz identifiziert Funktionen mit anfälligen Puffern für Angriffe und fügt Code am Anfang dieser Funktionen ein, um den Canary zu platzieren, und am Ende, um seine Integrität zu überprüfen.

Wenn ein Webserver fork() verwendet, ermöglicht es einen Brute-Force-Angriff, um das Canary-Byte für Byte zu erraten. Wenn jedoch execve() nach fork() verwendet wird, überschreibt es den Speicherbereich und macht den Angriff zunichte. vfork() ermöglicht es dem Kindprozess, ohne Duplikation auszuführen, bis er versucht zu schreiben, woraufhin eine Duplikation erstellt wird, was einen anderen Ansatz zur Prozesserstellung und Speicherbehandlung bietet.

Längen

In x64-Binärdateien ist das Canary-Cookie ein 0x8 Byte Qword. Die ersten sieben Bytes sind zufällig und das letzte Byte ist ein Nullbyte.

In x86-Binärdateien ist das Canary-Cookie ein 0x4 Byte Dword. Die ersten drei Bytes sind zufällig und das letzte Byte ist ein Nullbyte.

{% hint style="danger" %} Das am wenigsten signifikante Byte beider Canaries ist ein Nullbyte, da es das erste im Stapel ist, das von niedrigeren Adressen kommt, und daher Funktionen, die Zeichenfolgen lesen, bevor sie es lesen, anhalten. {% endhint %}

Umgehungen

Lecken des Canaries und dann Überschreiben (z. B. Pufferüberlauf) mit seinem eigenen Wert.

  • Wenn der Canary in Kindprozessen geforkt wird, könnte es möglich sein, ihn Byte für Byte brute-force:

{% content-ref url="bf-forked-stack-canaries.md" %} bf-forked-stack-canaries.md {% endcontent-ref %}

  • Wenn es eine interessante Leck- oder beliebige Leseanfälligkeit in der Binärdatei gibt, könnte es möglich sein, sie zu leaken:

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

  • Überschreiben von auf dem Stapel gespeicherten Zeigern

Der Stapel, der anfällig für einen Stapelüberlauf ist, könnte Adressen zu Zeichenfolgen oder Funktionen enthalten, die überschrieben werden können, um die Schwachstelle auszunutzen, ohne den Stapel-Canary erreichen zu müssen. Überprüfen Sie:

{% content-ref url="../../stack-overflow/pointer-redirecting.md" %} pointer-redirecting.md {% endcontent-ref %}

  • Ändern des Master- und Thread-Canary

Ein Pufferüberlauf in einer threadgeschützten Funktion, der mit Canary geschützt ist, kann verwendet werden, um den Master-Canary des Threads zu ändern. Dadurch ist die Schutzmaßnahme nutzlos, da die Überprüfung mit zwei identischen Canaries erfolgt (obwohl modifiziert).

Darüber hinaus könnte ein Pufferüberlauf in einer threadgeschützten Funktion verwendet werden, um den im TLS gespeicherten Master-Canary zu ändern. Dies liegt daran, dass es möglicherweise möglich ist, die Speicherposition zu erreichen, an der das TLS gespeichert ist (und daher den Canary), über einen bof im Stapel eines Threads.
Als Ergebnis ist die Schutzmaßnahme nutzlos, da die Überprüfung mit zwei identischen Canaries erfolgt (obwohl modifiziert).
Dieser Angriff wird im Write-up durchgeführt: http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads

Überprüfen Sie auch die Präsentation von https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015, die erwähnt, dass normalerweise das TLS durch mmap gespeichert wird und wenn ein Stapel eines Threads erstellt wird, wird er ebenfalls durch mmap generiert, was einen Überlauf ermöglichen könnte, wie im vorherigen Write-up gezeigt.

  • Ändern des GOT-Eintrags von __stack_chk_fail

Wenn die Binärdatei Partial RELRO hat, können Sie einen beliebigen Schreibzugriff verwenden, um den GOT-Eintrag von __stack_chk_fail zu ändern, damit er eine Dummy-Funktion ist, die das Programm nicht blockiert, wenn der Canary geändert wird.

Dieser Angriff wird im Write-up durchgeführt: https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/

Referenzen

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

Andere Möglichkeiten, HackTricks zu unterstützen: