Um das zu erweitern, was vonbrand (korrekterweise +1) gesagt hat, gibt es zwei Teile des Stack-Schutzes von Linux.
Kanarienvögel stapeln
Stack Canaries sind die vom Compiler erzwungene Funktion, auf die sich vonbrand bezieht. Diese können nicht ohne Neukompilierung deaktiviert werden.
Um sich das selbst zu beweisen und zu sehen, wie sie funktionieren, nehmen Sie den folgenden Code:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
int mybadfunction(char* a_bad_idea)
{
char what[100];
strcpy(what, a_bad_idea);
printf("You passed %s\n", what);
}
int main(int argc, char** argv)
{
printf("Tralalalaala\n");
mybadfunction(argv[1]);
}
Kompilieren Sie das jetzt (gcc -fstack-protector -masm=intel -S test.c
) in etwas, das gnu as gerne zusammenbauen und die Ausgabe lesen würde. Der wichtige Punkt ist der beim Verlassen der mybadfunction
Funktion, gibt es dieses kleine Stück Code:
mov edx, DWORD PTR [ebp-12]
xor edx, DWORD PTR gs:20
je .L2
call __stack_chk_fail
Wie Sie sich denken können, wird ein Stack-Cookie von [ebp-12]
genommen und mit dem Wert bei gs:20
vergleichen . Passt nicht? Dann ruft es eine Funktion __stack_chk_fail
auf in glibc, was Ihr Programm genau dort beendet.
Es gibt Möglichkeiten, dies zu umgehen, indem Sie Exploits schreiben, aber der einfache Weg, einen Shellcode-Testfall zu erstellen, besteht darin, Ihr Programm mit -fno-stack-protector
zu kompilieren .
Nicht ausführbare Seiten
Es gibt einige andere Überlegungen zu modernen Linux-Systemen. Wenn Sie den üblichen Shellcode-Test-Stub nehmen:
char buffer[] = {...};
typedef void (* func)(void);
int main(int argc, char** argv)
{
func f = (func) buffer;
f();
return 0;
}
modernes GCC/Linux bildet den .rodata
ab Abschnitt der PE-Datei schreibgeschützt ohne Ausführungsberechtigungen. Sie müssen dies ausschalten, was mit dem Codebeispiel aus diesem Blogbeitrag möglich ist. Grundidee:Sie verwenden mprotect
um die gewünschten Berechtigungen zu den Seiten hinzuzufügen, in denen sich die Shellcode-Daten befinden.
Nicht ausführbare Stacks
Wenn Sie ein herkömmliches Exploit-Szenario testen, z. mein schlechter Code oben, mit Ihrem Shellcode müssen Sie dann auch sicherstellen, dass der Stack für die einfachen Fälle ausführbar ist. Das PE-Dateiformat enthält ein Feld, um festzustellen, ob der Stack lauffähig ist – das können Sie mit execstack abfragen und kontrollieren. Um einen ausführbaren Stack zu aktivieren, führen Sie
ausexecstack -s /path/to/myprog
Das kann kann mit beliebigen Programmen ausgeführt werden, ohne dass eine Neukompilierung erforderlich ist, deaktiviert jedoch nicht automatisch Stapelkanarien, da diese beim Kompilieren eingebrannt werden.
Zusätzlicher Bonus:aslr:
Um das auszuschalten, echo 0 > /proc/sys/kernel/randomize_va_space
.
Hast du gerade jemandem gesagt, wie man meinen kostbaren Pinguin ausbeutet?
Nein. Jeder Exploit muss Stack Canaries umgehen (sehr nicht trivial) und entweder ein Programm mit execstack
finden set oder set it (was bedeutet, dass es ohnehin schon beliebige Befehle ausführen kann) oder aber schwierigere Techniken verwenden, wie z. B. return to libc/return-orientierte Programmierung.
Der Stack-Schutz wird vom Compiler durchgeführt (fügen Sie dem Stack einige zusätzliche Daten hinzu und speichern Sie einige bei Aufruf, überprüfen Sie die Gesundheit bei der Rückkehr). Kann das nicht deaktivieren ohne neu zu kompilieren. Es ist ein Teil des Punktes, wirklich...