Ret2esp / Ret2reg
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Da der ESP (Stack Pointer) immer auf die Spitze des Stacks zeigt, besteht diese Technik darin, den EIP (Instruction Pointer) durch die Adresse einer jmp esp
oder call esp
Anweisung zu ersetzen. Dadurch wird der Shellcode direkt nach dem überschriebenen EIP platziert. Wenn die ret
Anweisung ausgeführt wird, zeigt ESP auf die nächste Adresse, genau dort, wo der Shellcode gespeichert ist.
Wenn Address Space Layout Randomization (ASLR) in Windows oder Linux nicht aktiviert ist, ist es möglich, jmp esp
oder call esp
Anweisungen in gemeinsam genutzten Bibliotheken zu verwenden. Mit aktivem ASLR muss man jedoch möglicherweise innerhalb des verwundbaren Programms nach diesen Anweisungen suchen (und man könnte PIE überwinden müssen).
Darüber hinaus stellt die Fähigkeit, den Shellcode nach der EIP-Korruption zu platzieren, anstatt in der Mitte des Stacks, sicher, dass keine push
oder pop
Anweisungen, die während des Betriebs der Funktion ausgeführt werden, mit dem Shellcode interferieren. Diese Interferenz könnte auftreten, wenn der Shellcode in der Mitte des Funktionsstacks platziert wird.
Wenn Ihnen der Platz fehlt, um nach dem Überschreiben von RIP zu schreiben (vielleicht nur ein paar Bytes), schreiben Sie einen initialen jmp
Shellcode wie:
Und schreibe den Shellcode früh im Stack.
Du kannst ein Beispiel für diese Technik unter https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp mit einem finalen Exploit wie: finden
Sie können ein weiteres Beispiel für diese Technik unter https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html sehen. Es gibt einen Buffer Overflow ohne aktiviertes NX, es wird ein Gadget verwendet, um die Adresse von $esp
zu verringern und dann ein jmp esp;
, um zum Shellcode zu springen:
Ähnlich, wenn wir wissen, dass eine Funktion die Adresse zurückgibt, an der der Shellcode gespeichert ist, können wir call eax
oder jmp eax
Anweisungen nutzen (bekannt als ret2eax Technik), was eine weitere Methode bietet, um unseren Shellcode auszuführen. Genau wie eax könnte jedes andere Register, das eine interessante Adresse enthält, verwendet werden (ret2reg).
Hier finden Sie einige Beispiele:
strcpy
wird in eax
die Adresse des Puffers speichern, in dem der Shellcode gespeichert war, und eax
wird nicht überschrieben, sodass es möglich ist, ein ret2eax
zu verwenden.
In ARM64 gibt es keine Anweisungen, die es ermöglichen, zum SP-Register zu springen. Es könnte möglich sein, ein Gadget zu finden, das sp in ein Register verschiebt und dann zu diesem Register springt, aber in der libc meiner Kali konnte ich kein solches Gadget finden:
Die einzigen, die ich entdeckte, würden den Wert des Registers ändern, in das sp kopiert wurde, bevor zu ihm gesprungen wird (so dass es nutzlos wird):
Wenn ein Register eine interessante Adresse hat, ist es möglich, zu ihm zu springen, indem man einfach die geeignete Anweisung findet. Du könntest etwas verwenden wie:
In ARM64 speichert x0
den Rückgabewert einer Funktion, daher könnte es sein, dass x0 die Adresse eines Puffers speichert, der vom Benutzer mit einem Shellcode kontrolliert wird, um auszuführen.
Beispielcode:
Überprüfung der Disassemblierung der Funktion zeigt, dass die Adresse zum Puffer (anfällig für bof und vom Benutzer kontrolliert) in x0
gespeichert wird, bevor von der Pufferüberlauf zurückgegeben wird:
Es ist auch möglich, das Gadget br x0
in der do_stuff
Funktion zu finden:
Wir werden dieses Gadget verwenden, um dorthin zu springen, da die Binärdatei OHNE PIE kompiliert ist. Mit einem Muster ist es möglich zu sehen, dass der Offset des Pufferüberlaufs 80 beträgt, sodass der Exploit folgendermaßen aussehen würde:
Wenn anstelle von fgets
etwas wie read
verwendet worden wäre, wäre es möglich gewesen, PIE zu umgehen, indem nur die letzten 2 Bytes der Rücksprungadresse überschrieben werden, um zur br x0;
-Anweisung zurückzukehren, ohne die vollständige Adresse zu kennen.
Mit fgets
funktioniert es nicht, da es ein Nullbyte (0x00) am Ende hinzufügt.
NX: Wenn der Stack nicht ausführbar ist, hilft das nicht, da wir den Shellcode im Stack platzieren und springen müssen, um ihn auszuführen.
Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)