mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-13 06:42:54 +00:00
100 lines
6.5 KiB
Markdown
100 lines
6.5 KiB
Markdown
# 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 %}
|