<summary><strong>Lernen Sie AWS-Hacking von Grund auf mit</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* Wenn Sie Ihr **Unternehmen in HackTricks beworben sehen möchten** oder **HackTricks im PDF-Format herunterladen möchten**, überprüfen Sie die [**ABONNEMENTPLÄNE**](https://github.com/sponsors/carlospolop)!
* Holen Sie sich das [**offizielle PEASS & HackTricks-Merch**](https://peass.creator-spring.com)
* **Treten Sie der** 💬 [**Discord-Gruppe**](https://discord.gg/hRep4RUj7f) oder der [**Telegram-Gruppe**](https://t.me/peass) bei oder **folgen** Sie uns auf **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an die** [**HackTricks**](https://github.com/carlospolop/hacktricks) und [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub-Repositories senden.
Para verificar, ob die Systemaufrufe korrekt ausgeführt werden, muss das vorherige Programm kompiliert werden und die Systemaufrufe sollten in **strace ./KOMPILIERTE\_PROGRAMM** erscheinen.
Beim Erstellen von Shellcodes kann ein Trick angewendet werden. Die erste Anweisung ist ein Sprung zu einem Aufruf. Der Aufruf ruft den Originalcode auf und legt zusätzlich den EIP im Stack ab. Nach der Aufrufanweisung haben wir den benötigten String platziert, sodass wir mit diesem EIP auf den String zeigen und den Code weiter ausführen können.
Besteht aus einem kleinen Code, der die Speicherseiten eines Prozesses nach der darin gespeicherten Shellcode durchsucht (sucht nach einer Signatur im Shellcode). Nützlich in Fällen, in denen nur wenig Platz zum Einspritzen von Code zur Verfügung steht.
Es handelt sich um verschlüsselte Shells, die über kleine Codes verfügen, die sie entschlüsseln und zu ihnen springen lassen, unter Verwendung des Call-Pop-Tricks, hier ein **Beispiel für eine Caesar-Verschlüsselung**:
Nützlich, wenn die Adresse des Stacks nicht in den EIP eingegeben werden kann (überprüfen, dass der EIP nicht 0xbf enthält) oder wenn der Speicherort des Shellcodes nicht berechnet werden kann. Wenn jedoch die anfällige Funktion einen Parameter akzeptiert (der Shellcode wird hier platziert).
Durch das Ändern des EIP in eine Adresse zu einem **ret** wird die nächste Adresse geladen (die Adresse des ersten Arguments der Funktion). Das bedeutet, dass der Shellcode geladen wird.
Der Exploit würde sein: SHELLCODE + Padding (bis zum EIP) + **\&ret** (die nächsten Bytes des Stacks zeigen auf den Beginn des Shellcodes, da die Adresse des übergebenen Parameters in den Stack eingefügt wird)
Es scheint, dass Funktionen wie **strncpy** nach Abschluss die Adresse, an der der Shellcode gespeichert war, vom Stack entfernen und diese Technik unmöglich machen. Mit anderen Worten, die Adresse, die der Funktion als Argument übergeben wird (die den Shellcode speichert), wird durch eine 0x00 ersetzt, sodass beim Aufruf des zweiten **ret** eine 0x00 gefunden wird und das Programm abstürzt.
Durch Betrachten des Aufbaus des Stacks eines neuen Prozesses in Linux kann ein Exploit entwickelt werden, sodass das Programm in einer Umgebung gestartet wird, in der nur eine Variable vorhanden ist, nämlich der Shellcode. Die Adresse davon kann dann berechnet werden als: addr = 0xbfffffff - 4 - strlen(KOMPLETTER\_AUSFÜHRBARER\_NAME) - strlen(shellcode)
Da ESP immer auf den Anfang des Stacks zeigt, besteht diese Technik darin, den EIP durch die Adresse eines **jmp esp** oder **call esp** zu ersetzen. Auf diese Weise wird der Shellcode nach der Überschreibung des EIP gespeichert, da nach dem Ausführen des **ret** ESP auf die nächste Adresse zeigt, genau dort, wo der Shellcode gespeichert wurde.
Wenn ASLR in Windows oder Linux nicht aktiviert ist, können **jmp esp** oder **call esp** aus einem gemeinsam genutzten Objekt aufgerufen werden. Wenn ASLR aktiviert ist, könnte innerhalb des anfälligen Programms gesucht werden.
Darüber hinaus ermöglicht die Platzierung des Shellcodes nach der EIP-Korruption anstelle in der Mitte des Stacks, dass die push- oder pop-Anweisungen, die in der Funktion ausgeführt werden, die Shellcode nicht berühren (was passieren könnte, wenn sie in der Mitte des Stacks der Funktion platziert würden).
Sehr ähnlich dazu, wenn bekannt ist, dass eine Funktion die Adresse speichert, an der der Shellcode gespeichert ist, kann **call eax** oder **jmp eax (ret2eax)** aufgerufen werden.
Diese Art von Überläufen tritt auf, wenn eine Variable nicht darauf vorbereitet ist, eine so große Zahl wie die übergebene zu verarbeiten, möglicherweise aufgrund einer Verwechslung zwischen vorzeichenbehafteten und vorzeichenlosen Variablen, zum Beispiel:
En el vorherigen Beispiel sehen wir, dass das Programm 2 Parameter erwartet. Der erste ist die Länge des folgenden Strings und der zweite ist der String.
Wenn wir als ersten Parameter eine negative Zahl übergeben, wird angezeigt, dass len <256istundwirdiesenFilterpassieren,außerdemwirdauchstrlen(buffer)kleineralslsein,daleinunsignedintistundsehrgroßseinwird.
Diese Art von Overflows zielt nicht darauf ab, etwas im Prozess des Programms zu schreiben, sondern darauf, schlecht gestaltete Filter zu umgehen, um andere Schwachstellen auszunutzen.
Es ist nicht bekannt, welchen Wert eine nicht initialisierte Variable annehmen kann, und es könnte interessant sein, dies zu beobachten. Es könnte sein, dass sie den Wert annimmt, den eine Variable aus der vorherigen Funktion hatte und diese vom Angreifer kontrolliert wird.
Im Wesentlichen handelt es sich hierbei um eine Struktur mit **Funktionen, die aufgerufen werden**, bevor das Programm beendet wird. Dies ist interessant, wenn Sie Ihren **Shellcode aufrufen können, indem Sie einfach zu einer Adresse springen**, oder in Fällen, in denen Sie zurück zu main gehen müssen, um die **Format-String ein zweites Mal auszunutzen**.
Hinweis, dass dies **keine****endlose Schleife** erzeugt, da der Canary bemerken wird, dass das Ende des Stacks möglicherweise beschädigt ist und die Funktion nicht erneut aufgerufen wird. Daher können Sie mit diesem **eine weitere Ausführung** der Schwachstelle haben.
Ein Format-String kann auch missbraucht werden, um Inhalte aus dem Speicher des Programms auszulesen.\
Zum Beispiel gibt es in der folgenden Situation eine **lokale Variable im Stack, die auf eine Flagge zeigt**. Wenn Sie herausfinden, wo im **Speicher** der **Zeiger** auf die **Flagge** ist, können Sie **printf** dazu bringen, auf diese **Adresse zuzugreifen** und die **Flagge** auszugeben:
Beachten Sie, dass Sie nach dem **vorherigen Exploit** und der Feststellung, dass Sie **Inhalte auslesen** können, **Zeiger** auf **`printf`** in den Abschnitt setzen können, in dem das **ausführbare** Programm **geladen** ist, und es **vollständig auslesen**!
Wenn es Ihnen gelingt, eine **Adresse** zu einem **Shellcode** in **`__DTOR_END__`** zu **schreiben**, wird dies **ausgeführt**, bevor das Programm endet.\
In der Regel finden Sie den **DTOR**-Abschnitt **zwischen** den Werten `ffffffff` und `00000000`. Wenn Sie also nur diese Werte sehen, bedeutet das, dass **keine Funktion registriert ist**. Überschreiben Sie also die **`00000000`** mit der **Adresse** des **Shellcodes**, um ihn auszuführen.
Die **sprintf**-Funktion kopiert einen formatierten String **in** eine **Variable**. Daher könnten Sie die **Formatierung** eines Strings missbrauchen, um einen **Buffer Overflow in der Variable** zu verursachen.\
Beispielsweise schreibt das Payload `%.44xAAAA` 44B+"AAAA" in die Variable, was einen Buffer Overflow verursachen kann.
**`atexit()`** ist eine Funktion, der **andere Funktionen als Parameter übergeben werden**. Diese **Funktionen** werden ausgeführt, wenn ein **`exit()`** ausgeführt wird oder das **Hauptprogramm beendet wird**.\
Wenn Sie die **Adresse** einer dieser **Funktionen** beispielsweise auf einen Shellcode zeigen lassen können, werden Sie die **Kontrolle über den Prozess erlangen**, aber dies ist derzeit komplizierter.\
Derzeit sind die **Adressen der auszuführenden Funktionen** hinter mehreren Strukturen versteckt, und schließlich zeigen die Adressen, auf die sie zeigen, nicht auf die Adressen der Funktionen, sondern sind **verschlüsselt mit XOR** und Verschiebungen mit einem **zufälligen Schlüssel**. Daher ist dieser Angriffsvektor derzeit **zumindest auf x86** und **x64\_86** nicht sehr nützlich.\
Die **Verschlüsselungsfunktion** ist **`PTR_MANGLE`**. **Andere Architekturen** wie m68k, mips32, mips64, aarch64, arm, hppa... **implementieren die Verschlüsselungsfunktion nicht**, da sie das Gleiche zurückgeben wie sie als Eingabe erhalten haben. Daher wären diese Architekturen durch diesen Vektor angreifbar.
Das Problem ist, dass EIP und ESP durch die **`PTR_MANGLE`**-Funktion übergeben werden, daher sind die **Architekturen, die anfällig für diesen Angriff sind, die gleichen wie oben**.\
Jedoch sind nach meinen Recherchen die anderen Register nicht geschützt, **so dass, wenn es ein `call ebx`, `call esi` oder `call edi`** innerhalb der aufgerufenen Funktion gibt, die Kontrolle übernommen werden kann. Oder Sie könnten auch EBP ändern, um ESP zu ändern.
Jedes Objekt einer **Klasse** hat einen **VPtr**, der ein **Pointer** auf das Array seiner Klasse ist. Der VPtr ist Teil des Headers jedes Objekts, daher könnte, wenn eine **Überschreibung** des **VPtr** erreicht wird, dieser so **geändert** werden, dass er auf eine Dummy-Methode zeigt, sodass beim Ausführen einer Funktion der Shellcode aufgerufen wird.
Einige unsichere Funktionen werden durch sichere Funktionen ersetzt. Nicht standardisiert. (nur für x86, nicht für Kompilierungen mit -fomit-frame-pointer, nicht für statische Kompilierungen, nicht alle anfälligen Funktionen werden sicher gemacht und LD\_PRELOAD funktioniert nicht bei SUID-Binärdateien).
Lädt gemeinsam genutzte Bibliotheken von 0x00000000 bis 0x00ffffff, damit immer ein Byte 0x00 vorhanden ist. Dies hält jedoch kaum einen Angriff auf, insbesondere nicht in Little Endian.
Führt ein ROP aus, bei dem die Funktion strcpy@plt (aus der plt) aufgerufen wird und auf den Eintrag in der GOT gezeigt wird und das erste Byte der zu aufrufenden Funktion (system()) kopiert wird. Anschließend wird dasselbe mit GOT+1 gemacht und das 2. Byte von system() kopiert... Schließlich wird die in der GOT gespeicherte Adresse aufgerufen, die system() sein wird.
Die freien Stücke sind in einer doppelt verketteten Liste (bin) und es dürfen niemals zwei freie Stücke nebeneinander sein (sie werden zusammengeführt).
Im "size"-Feld gibt es Bits, um anzuzeigen: ob das vorherige Stück verwendet wird, ob das Stück über mmap() zugewiesen wurde und ob das Stück zum primären Arena gehört.
Wenn ein Stück freigegeben wird und eines der benachbarten Stücke frei ist, werden sie durch die Makro unlink() fusioniert und das größere neue Stück wird an frontlink() übergeben, um es in den entsprechenden Bin einzufügen.
Daher, wenn es gelingt, P->bk mit der Adresse eines Shellcodes und P->fd mit der Adresse eines Eintrags in der GOT oder DTORS minus 12 zu ändern, wird erreicht:
BK->fd = FD -> \*(\&shellcode + 8) = (&\_\_dtor\_end\_\_ - 12) —> Dies führt dazu, dass 4 Bytes ab dem 8. Byte des Shellcodes geschrieben werden, daher sollte das erste Instruction des Shellcodes ein Sprungbefehl sein, um dies zu überspringen und zu den Nops zu gelangen, die zum Rest des Shellcodes führen.
Nach dem Shellcode wird Füllmaterial eingefügt, bis die Felder prev\_size und size des nächsten Stücks erreicht sind. An diesen Stellen werden 0xfffffff0 (um prev\_size zu überschreiben, damit das Bit angezeigt wird, dass es frei ist) und "-4" (0xfffffffc) in die size eingefügt (damit, wenn im 3. Stück überprüft wird, ob das 2. Stück frei ist, tatsächlich auf die modifizierte prev\_size zugegriffen wird, die angibt, dass es frei ist) -> Wenn also free() überprüft, wird es zur size des 3. Stücks gehen, aber tatsächlich zum 2. - 4. und denken, dass das 2. Stück frei ist. Dann wird **unlink()** aufgerufen.
Beim Aufruf von unlink() werden die ersten Daten des 2. Stücks als P->fd verwendet, sodass die Adresse, die überschrieben werden soll, - 12 (weil FD->bk 12 zur in FD gespeicherten Adresse hinzufügt) dort eingefügt wird. An dieser Stelle wird die zweite Adresse im 2. Stück eingefügt, die die Adresse des Shellcodes sein soll (falsches P->bk).
**fake\_size = pack("\<I”, 0xfffffffc) #-4, para que piense que el “size” del 3º trozo está 4bytes detrás (apunta a prev\_size) pues es ahí donde mira si el 2º trozo está libre**
**got\_free = pack("\<I", 0x08048300 - 12) #Dirección de free() en la plt-12 (será la dirección que se sobrescrita para que se lanza la shellcode la 2º vez que se llame a free)**
**payload += prev\_size + fake\_size + got\_free + addr\_sc #Se modifica el 2º trozo, el got\_free apunta a donde vamos a guardar la direccion addr\_sc + 12**
Dann wird das Programm denken, dass "a" frei ist und in einem Bin liegt, und unlink() aufrufen, um es zu entkoppeln. Da jedoch die Kopfgröße PREV\_SIZE -4 beträgt, wird angenommen, dass der "a"-Chunk tatsächlich bei b+4 beginnt. Das heißt, es wird ein unlink() auf einen Chunk durchgeführt, der bei b+4 beginnt. Daher wird bei b+12 der "fd"-Zeiger und bei b+16 der "bk"-Zeiger sein.
Frontlink wird aufgerufen, wenn etwas freigegeben wird und keiner seiner benachbarten Chunks frei ist. Es wird unlink() nicht aufgerufen, sondern direkt frontlink().
Durch das Überschreiben von zwei mallocs auf unkontrollierte Weise und eines auf kontrollierte Weise, der nur einmal freigegeben wird, können wir einen Exploit durchführen.
Wenn einer erneut verwendet werden soll, wird er ohne Probleme zugewiesen. Wenn der andere verwendet werden soll, wird ihm derselbe Speicherplatz zugewiesen, sodass die "fd"- und "bk"-Zeiger mit den Daten gefälscht werden, die die vorherige Reservierung schreiben wird.
Es ist nur ein Aufruf von free() erforderlich, um die Ausführung beliebigen Codes zu verursachen. Es ist wichtig, einen zweiten Chunk zu finden, der von einem vorherigen überlaufen und freigegeben werden kann.
In \[1] wird das Feld size und das Bit NON\_MAIN\_ARENA überprüft, das geändert werden kann, damit die Überprüfung true zurückgibt und heap\_for\_ptr() ausgeführt wird, das ein "and" auf "mem" ausführt und die 2,5 unwichtigsten Bytes auf 0 setzt (in unserem Fall von 0x0804a000 auf 0x08000000) und auf 0x08000000->ar\_ptr zugreift (als ob es ein struct heap\_info wäre).
Auf diese Weise können wir beispielsweise einen Chunk bei 0x0804a000 kontrollieren und einen Chunk bei **0x081002a0** freigeben, um zur Adresse 0x08100000 zu gelangen und beispielsweise **0x0804a000** zu schreiben. Wenn dieser zweite Chunk freigegeben wird, wird heap\_for\_ptr(ptr)->ar\_ptr den Wert zurückgeben, den wir in 0x08100000 geschrieben haben (da der "and"-Operator auf 0x081002a0 angewendet wird und von dort der Wert der ersten 4 Bytes, ar\_ptr, abgeleitet wird).
Daher, wenn wir in av->bins\[2] den Wert von \_\_DTOR\_END\_\_-12 schreiben, wird in der letzten Anweisung in \_\_DTOR\_END\_\_ die Adresse des zweiten Chunks geschrieben.
An der Adresse, an der die Adresse des zweiten Chunks mit den letzten 5 Nullen landet, müssen wir die Adresse dieses ersten Chunks setzen, damit heap\_for\_ptr() denkt, dass ar\_ptr am Anfang des ersten Chunks liegt und av->bins\[2] von dort abruft.
Auf diese Weise wird \_int\_free(CHUNK1, CHUNK2) aufgerufen und die Anweisungen zum Schreiben in \_\_DTOR\_END\_\_ der Adresse von prev\_size des CHUNK2, der dann zum Shellcode springt, ausgeführt.
Para apply this technique, some additional requirements need to be met, which complicate the payload further.
This technique is no longer applicable as almost the same patch as for unlink was applied. It compares if the new site being pointed to is also pointing back to it.
This way, if "fb" is set to a function address in the GOT, the overwritten chunk will be placed at this address. For this to work, the arena needs to be close to the dtors addresses. More precisely, av->max\_fast needs to be at the address we are going to overwrite.
So, if we set a size of 8 + NON\_MAIN\_ARENA + PREV\_INUSE in the size field, fastbin\_index() will return fastbins\[-1\], which will point to av->max\_fast.
Additionally, the chunk adjacent to the freed one must be larger than 8 -> Since we have stated that the size of the freed chunk is 8, in this fake chunk, we just need to put a size larger than 8 (also, since the shellcode will be in the freed chunk, we need to put a jmp at the beginning that falls into nops).
Due to the nulls of \_DTOR\_END\_ and the few addresses in the GOT, none of these sections' addresses are suitable for overwriting. Let's see how to apply fastbin to attack the stack.
Moreover, the contiguous chunk to the freed one must be larger than 8 -> Since we have mentioned that the size of the freed chunk is 16, in this fake chunk, we just need to put a size larger than 8 (also, since the shellcode will be in the freed chunk, we need to put a jmp at the beginning that falls into nops that come after the size field of the new fake chunk).
In this case, we aim to have a pointer to a malloc that can be altered by the attacker (e.g., the pointer is on the stack below a potential overflow to a variable).
Thus, we could make this pointer point wherever we want. However, not every location is valid; the size of the faked chunk must be smaller than av->max\_fast and more specifically equal to the size requested in a future malloc() call + 8. Therefore, if we know that after this vulnerable pointer, a malloc(40) is called, the size of the fake chunk must be 48.
For example, if the program asks the user for a number, we could enter 48 and point the modifiable malloc pointer to the next 4 bytes (which could belong to EBP with luck, so the 48 remains behind, as if it were the size header). Additionally, the address ptr-4+48 must meet several conditions (in this case, ptr=EBP), that is, 8 <ptr-4+48<av->system\_mem.
If this is met, when the next malloc call, which we said was malloc(40), is made, the EBP address will be assigned. If the attacker can also control what is written in this malloc, they can overwrite both the EBP and the EIP with the desired address.
I think this is because when it is freed, free() will save that at the address pointing to the EBP of the stack, there is a chunk of the perfect size for the new malloc() being reserved, so it assigns that address.
The first thing to do is overwrite the size of the wilderness chunk with a very large value (0xffffffff), so any sufficiently large memory request will be handled in \_int\_malloc() without the need to expand the heap.
Victim collects the value of the current wilderness chunk address (the current av->top), and remainder is exactly the sum of that address plus the number of bytes requested by malloc(). So, if \&EIP-8 is at 0xbffff224 and av->top contains 0x080c2788, then the amount we need to reserve in the controlled malloc for av->top to point to $EIP-8 for the next malloc() will be:
It is important to ensure that the size of the new wilderness chunk is larger than the request made by the last malloc(). That is, if the wilderness is pointing to \&EIP-8, the size will be right in the EBP field of the stack.
The freed chunks are placed in the bin based on their size. But before being placed, they are stored in unsorted bins. When a chunk is freed, it is not immediately placed in its bin but remains in unsorted bins. Next, if a new chunk is requested and the previously freed one can be used, it is returned; otherwise, if a larger chunk is requested, the freed chunk in unsorted bins is placed in its appropriate bin.
Reservieren Sie zwei mallocs, so dass das erste nach der Freigabe des zweiten überlaufen werden kann und in seinen Bin eingefügt wird (dh ein malloc größer als der zweite Abschnitt reserviert wird, bevor der Überlauf erfolgt).
Das Ziel ist es, wenn wir einen Heap überlaufen können, der darunter einen bereits freigegebenen und in seinem Bin befindlichen Abschnitt hat, können wir seinen bk-Pointer ändern. Wenn wir seinen bk-Pointer ändern und dieser Abschnitt der erste in der Bin-Liste wird und reserviert wird, wird die Bin getäuscht und glaubt, dass der nächste Abschnitt in der falschen Adresse liegt, die wir angegeben haben (zum Beispiel im Stack oder GOT). Wenn also ein weiterer Abschnitt reserviert wird und der Angreifer Berechtigungen dafür hat, wird ihm ein Abschnitt an der gewünschten Position gegeben und er kann dort schreiben.
Nachdem der modifizierte Abschnitt freigegeben wurde, muss ein größerer Abschnitt als der freigegebene reserviert werden, damit der modifizierte Abschnitt aus den unsortierten Bins entfernt und in seinen Bin eingefügt wird.
Daher muss die Bin warten, bis malloc() ausreichend oft aufgerufen wird, damit der modifizierte Bin erneut verwendet wird und die Bin täuscht, indem sie glaubt, dass der nächste Abschnitt in der falschen Adresse liegt. Dann wird der gewünschte Abschnitt gegeben.
Um die Verwundbarkeit so schnell wie möglich auszunutzen, wäre ideal: Reservierung des verwundbaren Abschnitts, Reservierung des Abschnitts, der geändert wird, Freigabe dieses Abschnitts, Reservierung eines größeren Abschnitts als des zu ändernden, Änderung des Abschnitts (Verwundbarkeit), Reservierung eines Abschnitts gleicher Größe wie der verwundene und Reservierung eines zweiten Abschnitts gleicher Größe, der auf die gewählte Adresse zeigt.
Zum Schutz vor diesem Angriff wird die typische Überprüfung verwendet, dass der Abschnitt "nicht" falsch ist: Es wird überprüft, ob bck->fd auf victim zeigt. Das heißt, in unserem Fall, ob der fd-Pointer des falschen Abschnitts, der im Stack angezeigt wird, auf victim zeigt. Um diesen Schutz zu umgehen, müsste der Angreifer in der Lage sein, auf die richtige Weise (wahrscheinlich über den Stack) die Adresse von victim in die richtige Adresse zu schreiben. Damit es wie ein echter Abschnitt aussieht.
Der Angriff ist wie zuvor, dh der bk-Pointer muss geändert werden und all diese malloc()-Aufrufe sind erforderlich, aber zusätzlich muss die Größe des modifizierten Abschnitts so geändert werden, dass diese Größe - nb <MINSIZEist.
Zum Beispiel muss die Größe auf 1552 gesetzt werden, damit 1552 - 1544 = 8 <MINSIZE(dieSubtraktionkannnichtnegativsein,daeinunsignedWertverglichenwird).
Es besteht im Wesentlichen darin, so viel wie möglich Speicher für Heaps zu reservieren und diese mit einer Schicht von Nops gefolgt von einer Shellcode zu füllen. Außerdem wird 0x0c als Polster verwendet. Es wird versucht, zur Adresse 0x0c0c0c0c zu springen, und wenn also eine Adresse überschrieben wird, die mit diesem Polster aufgerufen wird, wird dorthin gesprungen. Im Wesentlichen besteht die Taktik darin, so viel wie möglich zu reservieren, um zu sehen, ob ein Pointer überschrieben wird, und zu 0x0c0c0c0c zu springen, in der Hoffnung, dass dort Nops vorhanden sind.
Es besteht darin, durch Reservierungen und Freigaben den Speicher so zu strukturieren, dass reservierte Abschnitte zwischen freien Abschnitten verbleiben. Der zu überlaufende Puffer wird in einem der freien Abschnitte platziert.
<summary><strong>Erlernen Sie AWS-Hacking von Grund auf mit</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* Wenn Sie Ihr **Unternehmen in HackTricks bewerben möchten** oder **HackTricks als PDF herunterladen möchten**, überprüfen Sie die [**ABONNEMENTPLÄNE**](https://github.com/sponsors/carlospolop)!
* **Treten Sie der** 💬 [**Discord-Gruppe**](https://discord.gg/hRep4RUj7f) oder der [**Telegramm-Gruppe**](https://t.me/peass) bei oder **folgen** Sie uns auf **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an die** [**HackTricks**](https://github.com/carlospolop/hacktricks) und [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub-Repositories senden.