Ihr erster Pufferüberlauf
Egal, ob Sie Student, Entwickler oder Manager in einem Unternehmen sind, Sie sollten dies versuchen. Der Schlüssel zum Schreiben von sicherem Code besteht darin, zu verstehen, wie schlechter Code beschädigt wird. Die einzige Möglichkeit, schlechten Code zu knacken, besteht darin, sich die Hände schmutzig zu machen und bei binären Ausbeutungsherausforderungen Granaten zu zerplatzen. In diesem Artikel zeige ich Ihnen anhand eines Beispiels, das ich auf YouTube erstellt habe, wie Sie Ihren eigenen Pufferüberlaufangriff ausführen können.
In einem meiner YouTube-Videos habe ich erklärt, wie Strings in der Programmiersprache C dazu geführt haben, dass Menschen gehackt wurden. Der Hauptgrund dafür ist, dass dem C-String-Typ kein eingebackenes Längenattribut zugeordnet ist. Die einzige Möglichkeit festzustellen, ob eine Zeichenfolge fertig ist, besteht darin, zum Ende der Zeichenfolge zu navigieren.
https://youtu.be/fjMrDDj47E8
Dieses Konzept hat zu unzähligen Pufferüberlauf-Schwachstellen in Software geführt und in der Folge zu Tausenden von Cyberangriffen und dem Diebstahl persönlicher Daten geführt.
Unser anfälliger Server
Unten ist etwas Code für einen einfachen Server in C.
#include <stdio.h>
#include <secrets.h>
void debug()
{
printf("!! ENTERING DEBUG MODE !!\n");
system("/bin/bash");
}
int checkPassword()
{
char password[64];
printf("password: ");
gets(password);
return isValidPassword(password);
}
int main(int argc, char **argv)
{
printf("WELCOME TO THE SECURE SERVER\n");
if (checkPassword())
{
debug();
} else {
printf("Wrong password, sorry;\n");
}
}
Allerdings gibt es hier eine große Schwachstelle. Das Passwort, das schließlich überprüft wird, wird von der Funktion gets gelesen , was eine extrem anfällige Funktion ist. Wenn Sie mir nicht glauben, sehen Sie sich die Manpage für gets an.
Never use gets(). Because it is impossible to tell without knowing the data
in advance how many characters gets() will read, and because gets() will
continue to store characters past the end of the buffer, it is extremely
dangerous to use. It has been used to break computer security. Use fgets()
instead.
Der Stapel
Am schwierigsten zu verstehen für Programmierer und Experten für Cybersicherheit ist, wie ein Datenüberlauf außerhalb eines Puffers dazu führen kann, dass ein Hacker die Kontrolle über Ihren Code und letztendlich über Ihren Computer erlangt. Die Art und Weise, wie dies geschieht, liegt daran, wie Computer den Speicher organisieren, wenn ein Programm ausgeführt wird.
Im obigen Codebeispiel startet das Programm in main. Nach dem Start von main wird in Zeile 10 other_function aufgerufen. Es ist äußerst wichtig zu verstehen, wie other_function weiß, dass es nach der Rückkehr zu Zeile 11 gehen soll.
Die Struktur, die diese Informationen enthält, wird als „Stack“ bezeichnet. Der Stack ist der RAM-Bereich, der verwendet wird, wenn Ihr Programm ausgeführt wird, und in dem sowohl Kontrollflussinformationen (z. B. Rücksprungadressen) als auch Daten gespeichert werden.
Wenn main other_function aufruft , wird die Adresse, die als nächstes in main ausgeführt wird, nachdem other_function zurückkehrt, oben auf den Stapel geschoben. other_function wird ausgeführt , und dann kehrt das Programm zu der von main gespeicherten Adresse zurück .
Hier beginnen Pufferüberläufe eine Rolle zu spielen. Wenn in den Daten Ihres Programms ein Pufferüberlauf auftritt, können Sie die Ablaufsteuerungsinformationen ändern und schließlich ändern, wie das Programm ausgeführt wird.
Versuch es selber
Dasselbe gilt für dieses Code-Snippet hier. Die Idee hinter diesem Programm ist: Wenn Sie das Passwort kennen, erhalten Sie eine Shell. Leider kennen wir Hacker das Passwort nicht, also bekommen wir keine Shell. Da jedoch die Funktion gets verwendet wird, können wir die Pufferüberlauf-Schwachstelle ausnutzen und die Rücksendeadresse überlaufen lassen. Anstatt zu main zurückzukehren , können wir direkt zur Debug - Funktion zurückkehren, ohne das Passwort zu kennen.
Folgen Sie hier:
https://github.com/lowlevellearning/secure-server-stuff
Testfunktionalität
Um zu beginnen, sollten wir den Server ausführen und seine Funktionalität testen. Versuchen wir auch, das Passwort zu erraten.
In Ordnung, keine Würfel. Hier beginnt das Hacken.
Absturz des Servers
Wir können den Pufferüberlauf ausnutzen, wie der Name schon sagt, indem wir den Puffer überlaufen lassen. Dazu stellen wir mehr Daten bereit, als der Server verarbeiten kann.
Unten sehen wir, dass das Programm einen Segmentierungsfehler hatte. Das bedeutet, dass das Programm versucht hat, auf Speicher zuzugreifen, auf den es nicht zugreifen konnte. Wenn Sie ein Entwickler sind, ist das schlecht. Aber wenn Sie versuchen, den Server zu hacken, ist das gut :)
Lassen Sie uns den Absturz ein wenig weiter aufschlüsseln.
Hier können wir sehen, dass das Programm beim Versuch, die Anweisungen an der Adresse 0x41414141 auszuführen, einen Segfault hatte. Diese Adresse sollte … seltsam erscheinen. Interessanterweise ist 0x41414141 die Hex-Darstellung der Zeichenfolge „AAAA“, was bedeutet, dass unsere Zeichenfolge von As in die Rücksprungadresse übergelaufen ist und die CPU versucht hat, sie auszuführen. JETZT WERDEN HACKEN!
Kontrolle übernehmen
Um eine genaue Kontrolle über die Absenderadresse zu erhalten, müssen wir genau bestimmen, welcher Teil unseres ASCII-Strings das Programm zum Absturz gebracht hat. Wir können das tun, indem wir unseren String mit verschiedenen Zeichen modulieren und die Zeichen verwenden, um zu bestimmen, wo unsere Kontrolle über die Rücksendeadresse beginnt und endet.
Anstelle einer langen Zeichenfolge von As geben wir 64 As ein, gefolgt von einer Reihe zusätzlicher ASCII-Zeichen. 64 ist die Länge unseres Eingabepuffers, das ist also ein guter Ausgangspunkt, um die Länge zu schätzen. Danach fügen wir weitere Zeichen ein. Um zu überprüfen, wo unsere Kontrolle beginnt, verwenden Sie den gleichen Befehl wie zuvor.
Jetzt können Sie sehen, dass wir eine neue Rücksendeadresse haben. 0x45454545 ist die Hex-Darstellung von „EEEE“! Das bedeutet, dass wir bestimmt haben, wo unser Überlauf die Kontrolle über den Rückgabezeiger übernimmt. Von hier aus müssen wir eine Adresse in den Puffer einfügen, die uns tatsächlich wichtig ist. Wir versuchen, zur Debug-Funktion zurückzukehren, also sollten wir diese Adresse anstelle des EEEE-Strings einfügen.
Um die Adresse von debug zu ermitteln, führen wir einen einfachen Befehl aus …
objdump -d -Mintel ./hacked | less
Es sieht so aus, als ob die Debug-Adresse 0x08049296 ist. Wenn wir die Debug-Adresse dort platzieren, wo unsere EEEE-Zeichenfolge war, können wir vielleicht das Programm steuern und zum Debug zurückkehren, ohne das Passwort zu benötigen.
Die letzte Ausbeutung
Wir können das mit etwas Python-Fu machen.
import sys
payload = b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
payload += b"BBBBCCCCDDDD"
payload += b"\x08\x04\x92\x96"[::-1]
sys.stdout.buffer.write(payload)
user@user:~/vuln$ (python3 exploit.py; cat) | ./hacked
WELCOME TO THE SECURE SERVER
password: !! ENTERING DEBUG MODE !!
cat password
too_kool_4_skoo
Bitte folgen Sie mir auf Medium, gehen Sie auf YouTube abonnieren. Da kommt noch mehr!

![Was ist überhaupt eine verknüpfte Liste? [Teil 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































