hacktricks/binary-exploitation/stack-overflow/README.md

101 lines
6.5 KiB
Markdown
Raw Normal View History

# Przepełnienie stosu
<details>
<summary><strong>Nauka hakowania AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Inne sposoby wsparcia HackTricks:
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakowania, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na GitHubie.
</details>
## Co to jest przepełnienie stosu
**Przepełnienie stosu** to podatność, która występuje, gdy program zapisuje więcej danych na stosie, niż jest mu przydzielone do przechowywania. Nadmiarowe dane **nadpisują sąsiednie miejsce w pamięci**, prowadząc do uszkodzenia poprawnych danych, zakłócenia przepływu kontroli i potencjalnie wykonania złośliwego kodu. Ten problem często wynika z użycia funkcji niebezpiecznych, które nie wykonują sprawdzania granic danych wejściowych.
Głównym problemem tego nadpisania jest to, że **zachowany wskaźnik instrukcji (EIP/RIP)** i **zachowany wskaźnik bazowy (EBP/RBP)** do powrotu do poprzedniej funkcji są **przechowywane na stosie**. Dlatego atakujący będzie mógł nadpisać te wartości i **kontrolować przepływ wykonania programu**.
Podatność zazwyczaj pojawia się, gdy funkcja **kopiuję więcej bajtów na stosie niż jest na niego zaalokowane**, co pozwala na nadpisanie innych części stosu.
Niektóre powszechne funkcje podatne na to to: **`strcpy`, `strcat`, `sprintf`, `gets`**... Ponadto funkcje takie jak **`fgets`**, **`read` & `memcpy`**, które przyjmują argument **długości**, mogą być używane w podatny sposób, jeśli określona długość jest większa niż zaalokowana.
Na przykład, następujące funkcje mogą być podatne:
```c
void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}
```
### Znajdowanie przesunięć przepełnienia stosu
Najczęstszym sposobem na znalezienie przepełnienia stosu jest podanie bardzo dużego wejścia z literami `A` (np. `python3 -c 'print("A"*1000)'`) i oczekiwanie `Segmentation Fault`, co wskazuje, że próbowano uzyskać dostęp do **adresu `0x41414141`**.
Ponadto, gdy już zidentyfikujesz podatność na przepełnienie stosu, będziesz musiał znaleźć przesunięcie, aż będzie możliwe **nadpisanie adresu powrotu**, w tym celu zazwyczaj używa się **sekwencji De Bruijna**. Dla danego alfabetu o rozmiarze _k_ i podsekwencji o długości _n_, jest to **cykliczna sekwencja, w której każda możliwa podsekwencja o długości _n_** występuje dokładnie raz **jako ciągła podsekwencja**.
W ten sposób, zamiast ręcznie określać potrzebne przesunięcie do kontrolowania EIP, można użyć jednej z tych sekwencji jako dopełnienia, a następnie znaleźć przesunięcie bajtów, które nadpisały ten adres.
Można to zrobić przy użyciu **pwntools**:
```python
from pwn import *
# Generate a De Bruijn sequence of length 1000 with an alphabet size of 256 (byte values)
pattern = cyclic(1000)
# This is an example value that you'd have found in the EIP/IP register upon crash
eip_value = p32(0x6161616c)
offset = cyclic_find(eip_value) # Finds the offset of the sequence in the De Bruijn pattern
print(f"The offset is: {offset}")
```
lub **GEF**:
```bash
#Patterns
pattern create 200 #Generate length 200 pattern
pattern search "avaaawaa" #Search for the offset of that substring
pattern search $rsp #Search the offset given the content of $rsp
```
## Wykorzystywanie przepełnień stosu
Podczas przepełnienia (przy założeniu, że rozmiar przepełnienia jest wystarczająco duży) będziesz mógł **nadpisać** wartości zmiennych lokalnych na stosie aż do osiągnięcia zapisanych **EBP/RBP i EIP/RIP (lub nawet więcej)**.\
Najczęstszym sposobem wykorzystania tego rodzaju podatności jest **modyfikacja adresu powrotu**, aby po zakończeniu funkcji **przepływ sterowania został przekierowany w miejsce, które użytkownik określił** w tym wskaźniku.
Jednakże, w innych scenariuszach może być wystarczające **nadpisanie wartości niektórych zmiennych na stosie** dla eksploatacji (jak w łatwych wyzwaniach CTF).
### Ret2win
W tego rodzaju wyzwaniach CTF, istnieje **funkcja** **wewnątrz** binariów, która **nigdy nie jest wywoływana** i **musisz ją wywołać, aby wygrać**. W tych wyzwaniach wystarczy znaleźć **przesunięcie do nadpisania adresu powrotu** i **znaleźć adres funkcji** do wywołania (zwykle [**ASLR**](../common-binary-protections-and-bypasses/aslr/) byłoby wyłączone), więc gdy podatna funkcja zakończy działanie, ukryta funkcja zostanie wywołana:
{% content-ref url="ret2win.md" %}
[ret2win.md](ret2win.md)
{% endcontent-ref %}
### Shellcode na stosie
W tym scenariuszu atakujący może umieścić shellcode na stosie i wykorzystać kontrolowany EIP/RIP, aby przeskoczyć do shellcode i wykonać dowolny kod:
{% content-ref url="stack-shellcode.md" %}
[stack-shellcode.md](stack-shellcode.md)
{% endcontent-ref %}
### ROP i techniki Ret2...
Ta technika stanowi podstawową strukturę do obejścia głównej ochrony poprzedniej techniki: **Brak wykonalnego stosu (NX)**. Pozwala ona na wykonanie kilku innych technik (ret2lib, ret2syscall...), które zakończą się wykonaniem dowolnych poleceń poprzez nadużywanie istniejących instrukcji w binariach:
{% content-ref url="../rop-return-oriented-programing/" %}
[rop-return-oriented-programing](../rop-return-oriented-programing/)
{% endcontent-ref %}
## Rodzaje zabezpieczeń
Istnieje kilka zabezpieczeń próbujących zapobiec wykorzystaniu podatności, sprawdź je w:
{% content-ref url="../common-binary-protections-and-bypasses/" %}
[common-binary-protections-and-bypasses](../common-binary-protections-and-bypasses/)
{% endcontent-ref %}