mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/binary-exploitation/ios-exploiting/ios-physical-uaf-ios
This commit is contained in:
parent
3ee40a0b08
commit
b89e4077a4
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,3 +11,4 @@ book
|
||||
book/*
|
||||
hacktricks-preprocessor.log
|
||||
hacktricks-preprocessor-error.log
|
||||
searchindex.js
|
||||
|
@ -3,97 +3,107 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
## iOS Exploit Mitigations
|
||||
|
||||
- **Code Signing** in iOS works by requiring every piece of executable code (apps, libraries, extensions, etc.) to be cryptographically signed with a certificate issued by Apple. When code is loaded, iOS verifies the digital signature against Apple’s trusted root. If the signature is invalid, missing, or modified, the OS refuses to run it. This prevents attackers from injecting malicious code into legitimate apps or running unsigned binaries, effectively stopping most exploit chains that rely on executing arbitrary or tampered code.
|
||||
- **CoreTrust** is the iOS subsystem responsible for enforcing code signing at runtime. It directly verifies signatures using Apple’s root certificate without relying on cached trust stores, meaning only binaries signed by Apple (or with valid entitlements) can execute. CoreTrust ensures that even if an attacker tampers with an app after installation, modifies system libraries, or tries to load unsigned code, the system will block execution unless the code is still properly signed. This strict enforcement closes many post-exploitation vectors that older iOS versions allowed through weaker or bypassable signature checks.
|
||||
- **Data Execution Prevention (DEP)** marks memory regions as non-executable unless they explicitly contain code. This stops attackers from injecting shellcode into data regions (like the stack or heap) and running it, forcing them to rely on more complex techniques like ROP (Return-Oriented Programming).
|
||||
- **ASLR (Address Space Layout Randomization)** randomizes the memory addresses of code, libraries, stack, and heap every time the system runs. This makes it much harder for attackers to predict where useful instructions or gadgets are, breaking many exploit chains that depend on fixed memory layouts.
|
||||
- **KASLR (Kernel ASLR)** applies the same randomization concept to the iOS kernel. By shuffling the kernel’s base address at each boot, it prevents attackers from reliably locating kernel functions or structures, raising the difficulty of kernel-level exploits that would otherwise gain full system control.
|
||||
- **Kernel Patch Protection (KPP)** also known as **AMCC (Apple Mobile File Integrity)** in iOS, continuously monitors the kernel’s code pages to ensure they haven’t been modified. If any tampering is detected—such as an exploit trying to patch kernel functions or insert malicious code—the device will immediately panic and reboot. This protection makes persistent kernel exploits far harder, as attackers can’t simply hook or patch kernel instructions without triggering a system crash.
|
||||
- **Kernel Text Readonly Region (KTRR)** is a hardware-based security feature introduced on iOS devices. It uses the CPU’s memory controller to mark the kernel’s code (text) section as permanently read-only after boot. Once locked, even the kernel itself cannot modify this memory region. This prevents attackers—and even privileged code—from patching kernel instructions at runtime, closing off a major class of exploits that relied on modifying kernel code directly.
|
||||
- **Pointer Authentication Codes (PAC)** use cryptographic signatures embedded into unused bits of pointers to verify their integrity before use. When a pointer (like a return address or function pointer) is created, the CPU signs it with a secret key; before dereferencing, the CPU checks the signature. If the pointer was tampered with, the check fails and execution stops. This prevents attackers from forging or reusing corrupted pointers in memory corruption exploits, making techniques like ROP or JOP much harder to pull off reliably.
|
||||
- **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
|
||||
|
||||
これは [https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html) の投稿を要約したものです。さらにこの手法を使ったエクスプロイトの詳細は [https://github.com/felix-pb/kfd](https://github.com/felix-pb/kfd) にあります。
|
||||
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のユーザプロセス向けの virtual memory address space は **0x0 から 0x8000000000** までです。ただし、これらのアドレスは physical memory に直接対応しているわけではありません。代わりに、**kernel** が **page tables** を使って virtual addresses を実際の **physical addresses** に変換します。
|
||||
ユーザプロセスの**仮想メモリ空間**は iOS では **0x0 から 0x8000000000** までに広がっています。しかし、これらのアドレスは物理メモリに直接対応しているわけではありません。代わりに、**カーネル**は **page tables** を使って仮想アドレスを実際の**物理アドレス**へ変換します。
|
||||
|
||||
#### Levels of Page Tables in iOS
|
||||
|
||||
Page tables は階層化されており、3つのレベルで構成されます:
|
||||
Page table は階層構造で、3 レベルに分かれています:
|
||||
|
||||
1. **L1 Page Table (Level 1)**:
|
||||
* ここでの各エントリは仮想メモリの大きな範囲を表します。
|
||||
* **0x1000000000 bytes**(**256 GB**)の仮想メモリをカバーします。
|
||||
* ここにある各エントリは大きな仮想メモリ領域を表します。
|
||||
* 1 エントリは **0x1000000000 バイト**(= **256 GB**)の仮想メモリをカバーします。
|
||||
2. **L2 Page Table (Level 2)**:
|
||||
* ここでのエントリはより小さな領域、具体的には **0x2000000 bytes**(32 MB)を表します。
|
||||
* L1 エントリがその領域全体を直接マップできない場合、L2 テーブルへのポインタを指すことがあります。
|
||||
* ここでのエントリはより小さな領域、具体的には **0x2000000 バイト**(= 32 MB)を表します。
|
||||
* L1 のエントリは全体を直接マップできない場合、L2 テーブルを指すことがあります。
|
||||
3. **L3 Page Table (Level 3)**:
|
||||
* これは最も細かいレベルで、各エントリが単一の **4 KB** ページをマップします。
|
||||
* 最も細かいレベルで、各エントリが単一の **4 KB** ページをマップします。
|
||||
* より細かい制御が必要な場合、L2 エントリは L3 テーブルを指すことがあります。
|
||||
|
||||
#### Mapping Virtual to Physical Memory
|
||||
|
||||
* **Direct Mapping (Block Mapping)**:
|
||||
* page table のいくつかのエントリは、仮想アドレスの範囲を連続する physical addresses に直接 **map** します(ショートカットのようなものです)。
|
||||
* page table のいくつかのエントリは、仮想アドレスの範囲を連続する物理アドレスの範囲に直接**マップ**します(ショートカットのようなもの)。
|
||||
* **Pointer to Child Page Table**:
|
||||
* より細かい制御が必要な場合、あるレベルのエントリ(例: L1)は次のレベルの **child page table** を指すことができます(例: L2)。
|
||||
* より細かい制御が必要な場合、あるレベルのエントリ(例えば L1)が次レベルの**子ページテーブル**(例えば L2)を指すことがあります。
|
||||
|
||||
#### Example: Mapping a Virtual Address
|
||||
|
||||
仮に仮想アドレス **0x1000000000** にアクセスしようとすると:
|
||||
|
||||
1. **L1 Table**:
|
||||
* kernel はこの仮想アドレスに対応する L1 page table エントリをチェックします。もし **pointer to an L2 page table** があれば、L2 テーブルへ進みます。
|
||||
* カーネルはこの仮想アドレスに対応する L1 エントリをチェックします。もし **L2 page table を指すポインタ**があれば、L2 テーブルへ進みます。
|
||||
2. **L2 Table**:
|
||||
* kernel はより詳細なマッピングのために L2 page table をチェックします。もしこのエントリが **pointer to an L3 page table** を指していれば、さらに L3 へ進みます。
|
||||
* カーネルはより詳細なマッピングのために L2 エントリをチェックします。もしこのエントリが **L3 page table を指す**なら、さらに L3 へ進みます。
|
||||
3. **L3 Table**:
|
||||
* kernel は最終的な L3 エントリを参照し、それが実際のメモリページの **physical address** を指します。
|
||||
* 最終的な L3 エントリを参照し、それが実際のメモリページの**物理アドレス**を指します。
|
||||
|
||||
#### Example of Address Mapping
|
||||
|
||||
もし L2 テーブルの最初のインデックスに physical address **0x800004000** を書き込んだ場合:
|
||||
もし L2 テーブルの最初のインデックスに物理アドレス **0x800004000** を書き込んだ場合:
|
||||
|
||||
* 仮想アドレス **0x1000000000** から **0x1002000000** は物理アドレス **0x800004000** から **0x802004000** へマップされます。
|
||||
* これは L2 レベルでの **block mapping** です。
|
||||
* 仮想アドレス **0x1000000000** から **0x1002000000** までは、物理アドレス **0x800004000** から **0x802004000** へマップされます。
|
||||
* これは L2 レベルでの**block mapping**です。
|
||||
|
||||
また、L2 エントリが L3 テーブルを指す場合:
|
||||
代わりに、L2 エントリが L3 テーブルを指す場合:
|
||||
|
||||
* 仮想アドレス範囲 **0x1000000000 -> 0x1002000000** の各 4 KB ページは L3 テーブルの個別エントリでマップされます。
|
||||
* 仮想アドレス範囲 **0x1000000000 -> 0x1002000000** の各 4 KB ページは L3 テーブルの個別のエントリによってマップされます。
|
||||
|
||||
### Physical use-after-free
|
||||
|
||||
A **physical use-after-free** (UAF) は次のような状況で発生します:
|
||||
「physical use-after-free (UAF)」は次のような状態が起きたときに発生します:
|
||||
|
||||
1. プロセスが読み書き可能としていくつかのメモリを **allocates** する。
|
||||
2. **page tables** が更新され、そのメモリがプロセスからアクセス可能な特定の physical address にマップされる。
|
||||
3. プロセスがそのメモリを **deallocates (free)** する。
|
||||
4. しかし、**bug** のために kernel は page tables からその mapping を削除し忘れ、対応する physical メモリは free としてマークされる。
|
||||
5. kernel はその「free」になった physical memory を他の用途(例: **kernel data**)のために **reallocate** する。
|
||||
6. mapping が削除されていないため、プロセスはその physical memory を引き続き **read and write** できる。
|
||||
1. プロセスがあるメモリを **readable and writable** として **割り当てる**。
|
||||
2. カーネルはそのメモリを特定の物理アドレスにアクセス可能としてマッピングするために **page tables** を更新する。
|
||||
3. プロセスがそのメモリを **解放(free)** する。
|
||||
4. しかし、バグによりカーネルは対応する物理メモリを **free とマークする** 一方で、page tables からそのマッピングを**削除し忘れる**。
|
||||
5. カーネルはその「解放された」物理メモリを別の目的、例えば **カーネルデータ** のために **再割り当て** することができる。
|
||||
6. マッピングが残っているため、プロセスはまだこの物理メモリを **read/write** できてしまう。
|
||||
|
||||
つまり、プロセスは **kernel memory のページ** にアクセスできるようになり、そこには機密データや構造体が含まれている可能性があるため、攻撃者が **kernel memory を操作** できる恐れがあります。
|
||||
つまりプロセスは**カーネルメモリのページ**へアクセスできる状態になり得ます。そこには機密データや構造体が含まれている可能性があり、攻撃者にカーネルメモリを**操作**させることができます。
|
||||
|
||||
### IOSurface Heap Spray
|
||||
|
||||
攻撃者は freed メモリにどの kernel ページが割り当てられるかを制御できないため、次のような **heap spray** 技法を使います:
|
||||
攻撃者はどのカーネルページが解放されたメモリに割り当てられるかを制御できないため、次のような**heap spray** 技法を使います:
|
||||
|
||||
1. 攻撃者は kernel memory 内に大量の IOSurface objects を **create** する。
|
||||
2. 各 IOSurface object はそのフィールドの1つに **magic value** を含め、特定しやすくします。
|
||||
3. 彼らは freed pages を **scan** して、その中にこれらの IOSurface objects が入っているかどうかを確認します。
|
||||
4. freed page 上に IOSurface object を見つけた場合、それを使って **kernel memory の read/write** を行えます。
|
||||
1. 攻撃者はカーネルメモリ内に多数の IOSurface オブジェクトを**作成**する。
|
||||
2. 各 IOSurface オブジェクトは識別しやすい**magic value** をそのフィールドの一つに持たせておく。
|
||||
3. 攻撃者は解放されたページを**スキャン**して、これらの IOSurface オブジェクトが解放ページに配置されていないか確認する。
|
||||
4. 解放ページ上で IOSurface オブジェクトを見つけたら、それを使って**カーネルメモリの読み書き**が可能になる。
|
||||
|
||||
詳細は [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups) を参照してください。
|
||||
この手法の詳細は [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups) を参照してください。
|
||||
|
||||
> [!TIP]
|
||||
> iOS 16+ (A12+) デバイスはハードウェア緩和策(PPL や SPTM など)を導入しており、physical UAF 技術の有効性を大幅に低下させています。
|
||||
> PPL は code signing、entitlements、敏感な kernel data に関連するページに対して厳格な MMU 保護を課し、ページが再利用されても userland や compromised kernel code からの書き込みをブロックします。
|
||||
> Secure Page Table Monitor (SPTM) は PPL を拡張し、page table の更新自体を強化します。これにより、特権を持つ kernel コードであっても secure checks を経ずに freed pages を再マップしたりマッピングを改竄したりすることができなくなります。
|
||||
> KTRR (Kernel Text Read-Only Region) はブート後に kernel のコード領域を読み取り専用に固定します。これにより runtime による kernel code の変更が防がれ、physical UAF エクスプロイトが頼りにする主要な攻撃ベクトルが閉じられます。
|
||||
> さらに、`IOSurface` の割り当ては予測しにくくなり、user-accessible な領域へマッピングするのが難しくなっているため、magic value をスキャンするトリックの信頼性が低下しています。`IOSurface` は現在 entitlements や sandbox 制限でも保護されています。
|
||||
> 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 制限によっても保護されています。
|
||||
|
||||
### Step-by-Step Heap Spray Process
|
||||
|
||||
1. **Spray IOSurface Objects**: 攻撃者は特別な識別子("magic value")を持つ多くの IOSurface objects を作成します。
|
||||
2. **Scan Freed Pages**: それらのオブジェクトのいずれかが freed page に割り当てられているかを確認します。
|
||||
3. **Read/Write Kernel Memory**: IOSurface object のフィールドを操作することで、**arbitrary reads and writes** を kernel memory に対して実行できるようになります。これにより:
|
||||
* あるフィールドを使って kernel memory の任意の 32-bit 値を **read** できる。
|
||||
* 別のフィールドを使って 64-bit 値を **write** でき、安定した **kernel read/write primitive** を実現できる。
|
||||
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** を得られる。
|
||||
|
||||
Generate IOSurface objects with the magic value IOSURFACE_MAGIC to later search for:
|
||||
Generate IOSurface objects with the magic value IOSURFACE\_MAGIC to later search for:
|
||||
```c
|
||||
void spray_iosurface(io_connect_t client, int nSurfaces, io_connect_t **clients, int *nClients) {
|
||||
if (*nClients >= 0x4000) return;
|
||||
@ -114,7 +124,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);
|
||||
@ -148,25 +158,25 @@ free(surfaceIDs);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
### IOSurface を使ったカーネル読み書きの実現
|
||||
### IOSurface を用いたカーネルの読み書き実現
|
||||
|
||||
カーネルメモリ上の IOSurface オブジェクトを制御できるようになった後(ユーザースペースからアクセス可能な解放済み物理ページにマップされている)、これを使って**任意のカーネル読み書き操作**が可能になる。
|
||||
kernel memory 内の IOSurface オブジェクトを制御できるようになった後(userspace からアクセス可能な freed physical page にマップされている状態)、それを **arbitrary kernel read and write operations** に利用できます。
|
||||
|
||||
**IOSurface の重要なフィールド**
|
||||
**Key Fields in IOSurface**
|
||||
|
||||
IOSurface オブジェクトには2つの重要なフィールドがある:
|
||||
IOSurface オブジェクトには重要なフィールドが二つあります:
|
||||
|
||||
1. **Use Count Pointer**: **32-bit の読み取り**を可能にする。
|
||||
2. **Indexed Timestamp Pointer**: **64-bit の書き込み**を可能にする。
|
||||
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};
|
||||
@ -184,12 +194,12 @@ iosurface_set_use_count_pointer(info.object, orig);
|
||||
return value;
|
||||
}
|
||||
```
|
||||
#### 64ビットカーネル書き込み
|
||||
#### 64-Bit Kernel Write
|
||||
|
||||
書き込みを行うには:
|
||||
|
||||
1. ターゲットアドレスに **インデックス付きタイムスタンプポインタ** を上書きする。
|
||||
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};
|
||||
@ -203,13 +213,13 @@ set_indexed_timestamp(info.client, info.surface, value);
|
||||
iosurface_set_indexed_timestamp_pointer(info.object, orig);
|
||||
}
|
||||
```
|
||||
#### Exploit Flow Recap
|
||||
#### エクスプロイトの流れ(要約)
|
||||
|
||||
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 methods 経由で任意の **kernel read/write** を可能にする。
|
||||
2. **Spray IOSurface Objects**: カーネルメモリに一意の「magic value」を埋めた多数のIOSurfaceオブジェクトを割り当てる。
|
||||
3. **Identify Accessible IOSurface**: 自分が制御する解放済みページ上のIOSurfaceを特定する。
|
||||
4. **Abuse Use-After-Free**: IOSurfaceオブジェクト内のポインタを改ざんし、IOSurfaceのメソッド経由で任意の **kernel read/write** を可能にする。
|
||||
|
||||
これらのプリミティブにより、エクスプロイトはカーネルメモリに対する制御された **32-bit reads** と **64-bit writes** を提供する。さらなる jailbreak 手順では、より安定した read/write プリミティブが必要になり、追加の保護(例: 新しい arm64e デバイス上の PPL)を回避する必要がある場合がある。
|
||||
これらのプリミティブにより、エクスプロイトはカーネルメモリに対する制御された **32-bit reads** と **64-bit writes** を提供する。さらに進んだ jailbreak のステップでは、より安定した read/write primitives が必要になる場合があり、追加の保護(例: 新しい arm64e デバイスでの PPL)を回避する必要がある。
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,69 +1,147 @@
|
||||
# フィッシングの検出
|
||||
# Detecting Phishing
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## はじめに
|
||||
## Introduction
|
||||
|
||||
フィッシングの試みを検出するには、**現在使用されているフィッシング技術を理解することが重要です**。この投稿の親ページにはこの情報があるので、今日使用されている技術について知らない場合は、親ページに行って少なくともそのセクションを読むことをお勧めします。
|
||||
phishingの試行を検出するには、**現在使われているphishing techniquesを理解することが重要です**。この投稿の親ページにその情報があるので、もしどのtechniquesが使われているか分からない場合は親ページの少なくとも該当セクションを読むことをおすすめします。
|
||||
|
||||
この投稿は、**攻撃者が被害者のドメイン名を何らかの形で模倣または使用しようとする**という考えに基づいています。あなたのドメインが `example.com` と呼ばれ、何らかの理由で `youwonthelottery.com` のような全く異なるドメイン名でフィッシングされる場合、これらの技術ではそれを明らかにすることはできません。
|
||||
この投稿は**攻撃者が被害者のドメイン名を何らかの方法で模倣するか利用しようとする**という考えに基づいています。もしあなたのドメインが`example.com`で、`youwonthelottery.com`のような全く別のドメインでphishingされた場合、これらの手法は検出できません。
|
||||
|
||||
## ドメイン名のバリエーション
|
||||
|
||||
メール内で**類似のドメイン**名を使用するフィッシングの試みを**明らかにするのは比較的簡単**です。\
|
||||
攻撃者が使用する可能性のある**最も考えられるフィッシング名のリストを生成し**、それが**登録されているか**、またはその**IP**が使用されているかを**確認**するだけで十分です。
|
||||
メール内で類似したドメイン名を使う**phishing**の試みは、比較的**簡単**に**発見**できます。\
|
||||
攻撃者が使用する可能性が高いドメイン名のリストを**生成**し、それが**登録されているか**、またはそのドメインに割り当てられた**IP**が存在するかどうかを**確認**するだけで十分です。
|
||||
|
||||
### 疑わしいドメインの発見
|
||||
### 疑わしいドメインの見つけ方
|
||||
|
||||
この目的のために、以下のツールのいずれかを使用できます。これらのツールは、ドメインにIPが割り当てられているかどうかを自動的に確認するDNSリクエストも実行します:
|
||||
この目的には、以下のツールのいずれかを使用できます。これらのツールはドメインに割り当てられたIPがあるかどうかを確認するために、DNSクエリを自動的に実行する点に注意してください:
|
||||
|
||||
- [**dnstwist**](https://github.com/elceef/dnstwist)
|
||||
- [**urlcrazy**](https://github.com/urbanadventurer/urlcrazy)
|
||||
|
||||
### ビットフリッピング
|
||||
ヒント: 候補リストを生成した場合は、それをDNSリゾルバログに入れて**NXDOMAIN lookups from inside your org**(攻撃者が実際に登録する前にユーザがタイプミスで到達しようとしたもの)を検出してください。ポリシーが許すなら、これらのドメインをシンクホール化するか事前にブロックしてください。
|
||||
|
||||
**この技術の簡単な説明は親ページにあります。あるいは、** [**https://www.bleepingcomputer.com/news/security/hijacking-traffic-to-microsoft-s-windowscom-with-bitflipping/**](https://www.bleepingcomputer.com/news/security/hijacking-traffic-to-microsoft-s-windowscom-with-bitflipping/) **で元の研究を読むことができます。**
|
||||
### Bitflipping
|
||||
|
||||
例えば、ドメイン microsoft.com の1ビットの変更は、_windnws.com_ に変換できます。\
|
||||
**攻撃者は、被害者に関連するビットフリッピングドメインをできるだけ多く登録し、正当なユーザーを自分のインフラにリダイレクトさせることができます**。
|
||||
**You can find a short the explanation of this technique in the parent page. Or read the original research in** [**https://www.bleepingcomputer.com/news/security/hijacking-traffic-to-microsoft-s-windowscom-with-bitflipping/**](https://www.bleepingcomputer.com/news/security/hijacking-traffic-to-microsoft-s-windowscom-with-bitflipping/)
|
||||
|
||||
**すべての可能なビットフリッピングドメイン名も監視する必要があります。**
|
||||
例えば、ドメインmicrosoft.comの1ビット変更で_windnws.com_のようになることがあります。\
|
||||
**攻撃者は被害者に関連する可能な限り多くのbit-flippingドメインを登録して、正当なユーザを自分たちのインフラにリダイレクトする可能性があります。**
|
||||
|
||||
**すべての可能なbit-flippingドメイン名も監視するべきです。**
|
||||
|
||||
もしhomoglyph/IDNの類似(例:Latin/Cyrillic文字の混合)も考慮する必要があるなら、次を確認してください:
|
||||
|
||||
{{#ref}}
|
||||
homograph-attacks.md
|
||||
{{#endref}}
|
||||
|
||||
### 基本的なチェック
|
||||
|
||||
潜在的な疑わしいドメイン名のリストができたら、それらを**チェック**する必要があります(主にHTTPおよびHTTPSポート)**被害者のドメインの誰かに似たログインフォームを使用しているかどうかを確認するために**。\
|
||||
ポート3333が開いていて `gophish` のインスタンスが稼働しているかどうかも確認できます。\
|
||||
**発見された疑わしいドメインがどれくらい古いかを知ることも興味深い**です。若いほどリスクが高くなります。\
|
||||
疑わしいウェブページのHTTPおよび/またはHTTPSの**スクリーンショット**を取得して、それが疑わしいかどうかを確認し、その場合は**アクセスして詳しく見る**ことができます。
|
||||
潜在的に疑わしいドメイン名のリストを入手したら、まずそれらを**チェック**してください(主にHTTPおよびHTTPSのポート)そしてそれらが被害者のドメインのものと**類似したログインフォームを使用しているかどうかを確認**します。\
|
||||
また、ポート3333が開いていて`gophish`のインスタンスが動作しているかを確認することもできます。\
|
||||
発見した各疑わしいドメインが**どれくらい古いか(登録日)**を知ることは興味深いです。若いほどリスクが高いです。\
|
||||
HTTPおよび/またはHTTPSの疑わしいウェブページの**スクリーンショット**を取得して、疑わしいかどうか確認し、その場合はさらに詳しく**アクセスして調査**してください。
|
||||
|
||||
### 高度なチェック
|
||||
|
||||
さらに一歩進みたい場合は、**疑わしいドメインを監視し、時々(毎日?数秒/分しかかかりません)さらに検索することをお勧めします**。関連するIPのオープン**ポート**も**チェック**し、**`gophish` や類似のツールのインスタンスを検索**することも必要です(はい、攻撃者も間違いを犯します)し、**疑わしいドメインおよびサブドメインのHTTPおよびHTTPSウェブページを監視**して、被害者のウェブページからログインフォームをコピーしているかどうかを確認します。\
|
||||
これを**自動化するために**、被害者のドメインのログインフォームのリストを持ち、疑わしいウェブページをスパイダーし、疑わしいドメイン内で見つかった各ログインフォームを被害者のドメインの各ログインフォームと比較するために `ssdeep` のようなものを使用することをお勧めします。\
|
||||
疑わしいドメインのログインフォームを特定した場合、**ジャンククレデンシャルを送信**し、**被害者のドメインにリダイレクトされるかどうかを確認**できます。
|
||||
さらに踏み込むなら、これらの疑わしいドメインを**監視し、時々(毎日?数秒/分しかかかりません)追加のドメインを検索する**ことをお勧めします。関連IPの開いている**ポート**を**チェック**し、`gophish`や類似ツールのインスタンスを**検索**するべきです(はい、攻撃者もミスをします)。疑わしいドメインやサブドメインのHTTPおよびHTTPSのウェブページを**監視**して、被害者のウェブページからログインフォームをコピーしていないか確認してください。\
|
||||
この作業を**自動化する**ために、被害者ドメインのログインフォーム一覧を用意し、疑わしいウェブページをスパイダーで巡回して、疑わしいドメイン内で見つかった各ログインフォームを`ssdeep`のようなものを使って被害者ドメインの各ログインフォームと比較することを推奨します。\
|
||||
もし疑わしいドメインのログインフォームを見つけたら、ダミーの資格情報を**送信**して、それが被害者のドメインへ**リダイレクトするかどうか**を**確認**できます。
|
||||
|
||||
## キーワードを使用したドメイン名
|
||||
---
|
||||
|
||||
親ページでは、**被害者のドメイン名をより大きなドメイン内に入れる**というドメイン名のバリエーション技術についても言及しています(例:paypal-financial.com は paypal.com のためのものです)。
|
||||
### Hunting by favicon and web fingerprints (Shodan/ZoomEye/Censys)
|
||||
|
||||
### 証明書の透明性
|
||||
多くのphishingキットは、なりすますブランドのfaviconを再利用します。ネットワーク全体のスキャナはbase64エンコードされたfaviconのMurmurHash3を計算します。ハッシュを生成してそれを起点に調査できます:
|
||||
|
||||
前述の「ブルートフォース」アプローチを取ることはできませんが、実際には**そのようなフィッシングの試みを明らかにすることも可能です**。CAによって証明書が発行されるたびに、詳細が公開されます。これは、証明書の透明性を読み取ることや監視することで、**名前の中にキーワードを使用しているドメインを見つけることが可能であることを意味します**。例えば、攻撃者が [https://paypal-financial.com](https://paypal-financial.com) の証明書を生成した場合、証明書を見ることで「paypal」というキーワードを見つけ、疑わしいメールが使用されていることを知ることができます。
|
||||
Pythonの例 (mmh3):
|
||||
```python
|
||||
import base64, requests, mmh3
|
||||
url = "https://www.paypal.com/favicon.ico" # change to your brand icon
|
||||
b64 = base64.encodebytes(requests.get(url, timeout=10).content)
|
||||
print(mmh3.hash(b64)) # e.g., 309020573
|
||||
```
|
||||
- Shodanで検索: `http.favicon.hash:309020573`
|
||||
- ツールを使う場合: favfreakのようなコミュニティツールを参照して、Shodan/ZoomEye/Censys向けのハッシュやdorksを生成する。
|
||||
|
||||
投稿 [https://0xpatrik.com/phishing-domains/](https://0xpatrik.com/phishing-domains/) では、特定のキーワードに影響を与える証明書を検索し、日付(「新しい」証明書のみ)およびCA発行者「Let's Encrypt」でフィルタリングするためにCensysを使用できると提案しています:
|
||||
注意
|
||||
- Faviconsは再利用されることが多いので、一致は手がかりとして扱い、行動する前にコンテンツとcertsを検証する。
|
||||
- 精度を上げるために、domain-ageやkeyword heuristicsと組み合わせる。
|
||||
|
||||
### URLテレメトリのハンティング (urlscan.io)
|
||||
|
||||
`urlscan.io`は、提出されたURLの過去のスクリーンショット、DOM、リクエスト、TLSメタデータを保存します。ブランドの悪用やクローンを探索できます:
|
||||
|
||||
Example queries (UI or API):
|
||||
- Find lookalikes excluding your legit domains: `page.domain:(/.*yourbrand.*/ AND NOT yourbrand.com AND NOT www.yourbrand.com)`
|
||||
- Find sites hotlinking your assets: `domain:yourbrand.com AND NOT page.domain:yourbrand.com`
|
||||
- Restrict to recent results: append `AND date:>now-7d`
|
||||
|
||||
API example:
|
||||
```bash
|
||||
# Search recent scans mentioning your brand
|
||||
curl -s 'https://urlscan.io/api/v1/search/?q=page.domain:(/.*yourbrand.*/%20AND%20NOT%20yourbrand.com)%20AND%20date:>now-7d' \
|
||||
-H 'API-Key: <YOUR_URLSCAN_KEY>' | jq '.results[].page.url'
|
||||
```
|
||||
From the JSON, pivot on:
|
||||
- `page.tlsIssuer`, `page.tlsValidFrom`, `page.tlsAgeDays` — lookalikesの判別のため、非常に新しいcertsを検出する
|
||||
- `task.source` の値(例: `certstream-suspicious`) — 所見をCT監視に紐づけるため
|
||||
|
||||
### RDAPによるドメイン年齢(スクリプト可能)
|
||||
|
||||
RDAPは機械可読な作成イベントを返す。**新規登録ドメイン (NRDs)** のフラグ付けに有用。
|
||||
```bash
|
||||
# .com/.net RDAP (Verisign)
|
||||
curl -s https://rdap.verisign.com/com/v1/domain/suspicious-example.com | \
|
||||
jq -r '.events[] | select(.eventAction=="registration") | .eventDate'
|
||||
|
||||
# Generic helper using rdap.net redirector
|
||||
curl -s https://www.rdap.net/domain/suspicious-example.com | jq
|
||||
```
|
||||
Enrich your pipeline by tagging domains with registration age buckets (e.g., <7 days, <30 days) and prioritise triage accordingly.
|
||||
|
||||
### TLS/JAx fingerprints to spot AiTM infrastructure
|
||||
|
||||
近年の credential-phishing では、セッション・トークンを盗むために **Adversary-in-the-Middle (AiTM)** 型の reverse proxies(例: Evilginx)が増えています。ネットワーク側での検出を追加できます:
|
||||
|
||||
- Log TLS/HTTP fingerprints (JA3/JA4/JA4S/JA4H) at egress. 一部の Evilginx ビルドでは安定した JA4 クライアント/サーバー値が観測されています。known-bad なフィンガープリントに対しては弱いシグナルとしてアラートを出し、必ずコンテンツと domain intel で確認してください。
|
||||
- Proactively record TLS certificate metadata (issuer, SAN count, wildcard use, validity) for lookalike hosts discovered via CT or urlscan and correlate with DNS age and geolocation.
|
||||
|
||||
> Note: Treat fingerprints as enrichment, not as sole blockers; frameworks evolve and may randomise or obfuscate.
|
||||
|
||||
### Domain names using keywords
|
||||
|
||||
親ページでは、ドメイン名バリエーションの手法として、**victim's domain name inside a bigger domain**(例: paypal-financial.com が paypal.com の場合)のように被害者ドメインをより大きなドメイン名の中に含める手法も紹介されています。
|
||||
|
||||
#### Certificate Transparency
|
||||
|
||||
前述の "Brute-Force" アプローチは実行困難な場合がありますが、証明書透明性のおかげでこのようなフィッシング試行を発見することは実際に可能です。CA が証明書を発行するたびにその詳細は公開されます。つまり、証明書透明性を読む、あるいは監視することで、名前の中にキーワードを含むドメインを見つけることができます。たとえば攻撃者が [https://paypal-financial.com](https://paypal-financial.com) の証明書を作成すると、その証明書から "paypal" というキーワードを見つけ、不審なメールに使われていると判断できます。
|
||||
|
||||
投稿 [https://0xpatrik.com/phishing-domains/](https://0xpatrik.com/phishing-domains/) では、Censys を使って特定のキーワードに該当する証明書を検索し、日付(新しい証明書のみ)や CA 発行者 "Let's Encrypt" でフィルタする方法が提案されています:
|
||||
|
||||
.png>)
|
||||
|
||||
ただし、無料のウェブ [**crt.sh**](https://crt.sh) を使用して「同じこと」を行うこともできます。**キーワードを検索し**、**結果を日付とCAでフィルタリング**することができます。
|
||||
しかし、無料のウェブサービス [**crt.sh**](https://crt.sh) を使って同様のことができます。キーワードで検索し、必要に応じて日付や CA で結果をフィルタできます。
|
||||
|
||||
.png>)
|
||||
|
||||
この最後のオプションを使用すると、Matching Identitiesフィールドを使用して、実際のドメインのいずれかのアイデンティティが疑わしいドメインのいずれかと一致するかどうかを確認できます(疑わしいドメインは偽陽性である可能性があることに注意してください)。
|
||||
この方法では、Matching Identities フィールドを使って実際のドメインのいずれかの identity が不審なドメインと一致するかを確認できます(不審なドメインは誤検知である場合もあります)。
|
||||
|
||||
**もう一つの代替手段**は、[**CertStream**](https://medium.com/cali-dog-security/introducing-certstream-3fc13bb98067)という素晴らしいプロジェクトです。CertStreamは、新しく生成された証明書のリアルタイムストリームを提供し、指定されたキーワードを(ほぼ)リアルタイムで検出するために使用できます。実際、[**phishing_catcher**](https://github.com/x0rz/phishing_catcher)というプロジェクトがあり、まさにそれを行います。
|
||||
**Another alternative** は [**CertStream**](https://medium.com/cali-dog-security/introducing-certstream-3fc13bb98067) という素晴らしいプロジェクトです。CertStream は新しく生成された証明書のリアルタイムストリームを提供し、指定したキーワードを(ほぼ)リアルタイムで検出するのに使えます。実際に [**phishing_catcher**](https://github.com/x0rz/phishing_catcher) というプロジェクトがこれを実装しています。
|
||||
|
||||
### **新しいドメイン**
|
||||
実践的なヒント: CT ヒットをトリアージする際は、NRDs、untrusted/unknown registrars、privacy-proxy WHOIS、および非常に最近の `NotBefore` 時刻を持つ cert を優先してください。所有しているドメイン/ブランドの allowlist を維持してノイズを減らしましょう。
|
||||
|
||||
**最後の代替手段**は、いくつかのTLDの**新しく登録されたドメインのリストを収集**し、**これらのドメイン内のキーワードを確認することです**。ただし、長いドメインは通常1つ以上のサブドメインを使用するため、キーワードはFLD内に表示されず、フィッシングサブドメインを見つけることはできません。
|
||||
#### **New domains**
|
||||
|
||||
**One last alternative** は、いくつかの TLD について newly registered domains のリストを集め([Whoxy](https://www.whoxy.com/newly-registered-domains/) などが提供)、それらのドメインに含まれるキーワードをチェックすることです。ただし、長いドメインは通常 1 つ以上のサブドメインを使うため、キーワードが FLD の中に現れず、フィッシング用サブドメインを見つけられないことがあります。
|
||||
|
||||
追加のヒューリスティック: 特定の file-extension TLD(例: `.zip`, `.mov`)は、誘い文句でファイル名と誤認されやすいため、アラートで追加の疑いを持って扱ってください。TLD シグナルをブランドキーワードや NRD 年齢と組み合わせると精度が上がります。
|
||||
|
||||
## References
|
||||
|
||||
- urlscan.io – Search API reference: https://urlscan.io/docs/search/
|
||||
- APNIC Blog – JA4+ network fingerprinting (includes Evilginx example): https://blog.apnic.net/2023/11/22/ja4-network-fingerprinting/
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -24,13 +24,15 @@
|
||||
/* 2 — load a single index (remote → local) */
|
||||
async function loadIndex(remote, local, isCloud=false){
|
||||
let rawLoaded = false;
|
||||
try {
|
||||
const r = await fetch(remote,{mode:'cors'});
|
||||
if (!r.ok) throw new Error('HTTP '+r.status);
|
||||
importScripts(URL.createObjectURL(new Blob([await r.text()],{type:'application/javascript'})));
|
||||
rawLoaded = true;
|
||||
} catch(e){ console.warn('remote',remote,'failed →',e); }
|
||||
if(!rawLoaded){
|
||||
if(remote){
|
||||
try {
|
||||
const r = await fetch(remote,{mode:'cors'});
|
||||
if (!r.ok) throw new Error('HTTP '+r.status);
|
||||
importScripts(URL.createObjectURL(new Blob([await r.text()],{type:'application/javascript'})));
|
||||
rawLoaded = true;
|
||||
} catch(e){ console.warn('remote',remote,'failed →',e); }
|
||||
}
|
||||
if(!rawLoaded && local){
|
||||
try { importScripts(abs(local)); rawLoaded = true; }
|
||||
catch(e){ console.error('local',local,'failed →',e); }
|
||||
}
|
||||
@ -40,13 +42,41 @@
|
||||
return data;
|
||||
}
|
||||
|
||||
async function loadWithFallback(remotes, local, isCloud=false){
|
||||
if(remotes.length){
|
||||
const [primary, ...secondary] = remotes;
|
||||
const primaryData = await loadIndex(primary, null, isCloud);
|
||||
if(primaryData) return primaryData;
|
||||
|
||||
if(local){
|
||||
const localData = await loadIndex(null, local, isCloud);
|
||||
if(localData) return localData;
|
||||
}
|
||||
|
||||
for (const remote of secondary){
|
||||
const data = await loadIndex(remote, null, isCloud);
|
||||
if(data) return data;
|
||||
}
|
||||
}
|
||||
|
||||
return local ? loadIndex(null, local, isCloud) : null;
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const MAIN_RAW = 'https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/refs/heads/master/searchindex.js';
|
||||
const CLOUD_RAW = 'https://raw.githubusercontent.com/HackTricks-wiki/hacktricks-cloud/refs/heads/master/searchindex.js';
|
||||
const htmlLang = (document.documentElement.lang || 'en').toLowerCase();
|
||||
const lang = htmlLang.split('-')[0];
|
||||
const mainReleaseBase = 'https://github.com/HackTricks-wiki/hacktricks/releases/download';
|
||||
const cloudReleaseBase = 'https://github.com/HackTricks-wiki/hacktricks-cloud/releases/download';
|
||||
|
||||
const mainTags = Array.from(new Set([`searchindex-${lang}`, 'searchindex-en', 'searchindex-master']));
|
||||
const cloudTags = Array.from(new Set([`searchindex-${lang}`, 'searchindex-en', 'searchindex-master']));
|
||||
|
||||
const MAIN_REMOTE_SOURCES = mainTags.map(tag => `${mainReleaseBase}/${tag}/searchindex.js`);
|
||||
const CLOUD_REMOTE_SOURCES = cloudTags.map(tag => `${cloudReleaseBase}/${tag}/searchindex.js`);
|
||||
|
||||
const indices = [];
|
||||
const main = await loadIndex(MAIN_RAW , '/searchindex.js', false); if(main) indices.push(main);
|
||||
const cloud= await loadIndex(CLOUD_RAW, '/searchindex-cloud.js', true ); if(cloud) indices.push(cloud);
|
||||
const main = await loadWithFallback(MAIN_REMOTE_SOURCES , '/searchindex.js', false); if(main) indices.push(main);
|
||||
const cloud= await loadWithFallback(CLOUD_REMOTE_SOURCES, '/searchindex-cloud.js', true ); if(cloud) indices.push(cloud);
|
||||
|
||||
if(!indices.length){ postMessage({ready:false, error:'no-index'}); return; }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user