Translated ['src/generic-methodologies-and-resources/phishing-methodolog

This commit is contained in:
Translator 2025-09-29 23:39:02 +00:00
parent acc995027d
commit 029ab3bfb2
4 changed files with 228 additions and 103 deletions

1
.gitignore vendored
View File

@ -11,3 +11,4 @@ book
book/*
hacktricks-preprocessor.log
hacktricks-preprocessor-error.log
searchindex.js

View File

@ -3,95 +3,109 @@
{{#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 Apples 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 Apples 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 kernels 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 kernels code pages to ensure they havent 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 cant 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 CPUs memory controller to mark the kernels 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)। इसके अलावा इस तकनीक का उपयोग करने वाले exploit के बारे में और जानकारी [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 पर user processes के लिए the virtual memory address space **0x0 से 0x8000000000** तक फैला होता है। हालांकि, ये addresses सीधे physical memory से मैप नहीं होते। इसके बजाय, kernel page tables का उपयोग virtual addresses को वास्तविक physical addresses में translate करने के लिए करता है।
iOS पर user processes के लिए **virtual memory address space** **0x0 से 0x8000000000** तक फैला हुआ होता है। हालाँकि, ये addresses सीधे physical memory से मैप नहीं होते। इसके बजाय, **kernel** virtual addresses को वास्तविक **physical addresses** में translate करने के लिए **page tables** का उपयोग करता है।
#### Levels of Page Tables in iOS
Page tables तीन स्तरों में hierarchical तरीके से व्यवस्थित होते हैं:
Page tables तीन स्तरों में hierarchical रूप से व्यवस्थित होते हैं:
1. **L1 Page Table (Level 1)**:
* यहाँ का हर entry एक बड़े virtual memory रेंज का प्रतिनिधित्व करता है।
* यह **0x1000000000 bytes** (या **256 GB**) of virtual memory कवर करता है।
* यहाँ हर entry virtual memory के एक बड़े क्षेत्र का प्रतिनिधित्व करती है।
* यह **0x1000000000 bytes** (या **256 GB**) की virtual memory को कवर करती है।
2. **L2 Page Table (Level 2)**:
* यहाँ का एक entry एक छोटी virtual memory region का प्रतिनिधित्व करता है, विशेष रूप से **0x2000000 bytes** (32 MB)।
* अगर L1 entry पूरे रेंज को स्वयं मैप नहीं कर सकती तो वह L2 table की ओर pointer कर सकती है।
* यहाँ की एक entry virtual memory के एक छोटे क्षेत्र का प्रतिनिधित्व करती है, विशेष रूप से **0x2000000 bytes** (32 MB)।
* अगर एक L1 entry पूरे क्षेत्र को स्वयं मैप नहीं कर सकती तो वह एक L2 table की ओर इशारा कर सकती है।
3. **L3 Page Table (Level 3)**:
* यह सबसे fine-grained स्तर है, जहाँ हर entry एक single **4 KB** memory page को मैप करती है।
* अगर और अधिक granular control चाहिए तो L2 entry एक L3 table की ओर pointer कर सकती है।
* यह सबसे सूक्ष्म स्तर है, जहाँ हर entry एक single **4 KB** memory page को मैप करती है।
* अगर अधिक बारीकी से नियंत्रण की आवश्यकता हो तो एक L2 entry L3 table की ओर इशारा कर सकती है।
#### Mapping Virtual to Physical Memory
* **Direct Mapping (Block Mapping)**:
* page table के कुछ entries सीधे एक range of virtual addresses को contiguous range of physical addresses से मैप करते हैं (एक तरह का शॉर्टकट)।
* पेज टेबल की कुछ entries सीधे तौर पर एक range of virtual addresses को contiguous physical addresses के range से मैप कर देती हैं (एक तरह का शॉर्टकट)।
* **Pointer to Child Page Table**:
* अगर finer control चाहिए, तो एक level की entry (उदा. L1) next level (उदा. L2) के child page table की ओर pointer कर सकती है
* अगर और अधिक बारीकी की जरूरत हो, तो एक स्तर की entry (उदा., L1) अगले स्तर पर एक **child page table** की ओर इशारा कर सकती है (उदा., L2)
#### Example: Mapping a Virtual Address
मान लीजिए आप virtual address **0x1000000000** को access करने की कोशिश करते हैं:
मान लीजिए आप virtual address **0x1000000000** तक पहुंचने की कोशिश करते हैं:
1. **L1 Table**:
* kernel उस L1 page table entry को चेक करता है जो इस virtual address के अनुरूप है। अगर उसमें **pointer to an L2 page table** है, तो वह उस L2 table पर जाता है।
* kernel उस virtual address से संबंधित L1 page table entry की जाँच करता है। अगर उसमें **pointer to an L2 page table** है, तो वह उस L2 table पर जाता है।
2. **L2 Table**:
* kernel अधिक विस्तृत mapping के लिए L2 page table को देखता है। अगर यह entry **L3 page table** की ओर pointer करती है, तो वह वहाँ जाता है।
* kernel अधिक विस्तृत मैपिंग के लिए L2 page table की जाँच करता है। अगर इस entry में **pointer to an L3 page table** है, तो वह वहां जाता है।
3. **L3 Table**:
* kernel अंतिम L3 entry को देखता है, जो वास्तविक memory page के **physical address** की ओर इशारा करती है।
* kernel अंतिम L3 entry देखता है, जो वास्तविक memory page के **physical address** की ओर इशारा करती है।
#### Example of Address Mapping
यदि आप physical address **0x800004000** को L2 table के first index में लिखते हैं, तो:
यदि आप L2 table के पहले index में physical address **0x800004000** लिखते हैं, तब:
* Virtual addresses **0x1000000000 से 0x1002000000** तक physical addresses **0x800004000 से 0x802004000** तक मैप होंगे।
* Virtual addresses **0x1000000000** से **0x1002000000** तक physical addresses **0x800004000** से **0x802004000** तक मैप होंगे।
* यह L2 स्तर पर एक **block mapping** है।
वैकल्पिक रूप से, यदि L2 entry किसी L3 table की ओर pointer करती है:
वैकल्पिक रूप से, अगर L2 entry किसी L3 table की ओर इशारा करती है:
* virtual address रेंज **0x1000000000 -> 0x1002000000** में हर 4 KB page को L3 table के individual entries मैप करेंगे
* Virtual address रेंज **0x1000000000 -> 0x1002000000** में हर 4 KB page को L3 table की व्यक्तिगत entries द्वारा मैप किया जाएगा
### Physical use-after-free
एक **physical use-after-free (UAF)** तब होत है जब:
एक **physical use-after-free (UAF)** तब होत है जब:
1. एक process कुछ memory allocate करता है जिसे पढ़ने और लिखने योग्य बनाया गया होता है।
2. page tables इस memory को उस specific physical address से map करने के लिए अपडेट किए जाते हैं ताकि process इसे access कर सके
3. process उस memory को deallocate (free) कर देता है।
4. परन्तु किसी बग के कारण, kernel page tables से mapping हटाना भूल जाता है, जबकि संबंधित physical memory को free के रूप में चिह्नित कर दिया जाता है।
5. kernel उसके बाद इस "freed" physical memory को अन्य प्रयोजनों के लिए फिर से allocate कर सकता है, जैसे kernel data
6. क्योंकि mapping हटाया नहीं गया, process अभी भी इस physical memory को read और write कर सकता है।
1. कोई process कुछ memory को **readable और writable** के रूप में **allocate** करता है।
2. **page tables** को अपडेट किया जाता है ताकि यह memory process के लिए एक specific physical address से मैप हो जाए
3. process उस memory को **deallocate** (free) कर देता है।
4. हालांकि, किसी **bug** के कारण kernel **mapping को page tables से हटाना भूल जाता है**, जबकि वह corresponding physical memory को free चिह्नित कर देता है।
5. kernel फिर इस "freed" physical memory को अन्य उपयोगों (जैसे कि **kernel data**) के लिए **reallocate** कर सकता है
6. क्योंकि mapping हटाया नहीं गया था, process अभी भी उस physical memory को **read और write** कर सकता है।
इसका मतलब है कि process kernel memory के pages को access कर सकता है, जिनमें संवेदनशील डेटा या संरचनाएँ हो सकती हैं, जिससे attacker kernel memory को manipulate कर सकता है।
इसका मतलब है कि process **kernel memory के pages** तक पहुँच सकता है, जिनमें संवेदनशील डेटा या संरचनाएँ हो सकती हैं, और संभावित रूप से एक attacker को **kernel memory को manipulate** करने की अनुमति मिल सकती है।
### IOSurface Heap Spray
क्योंकि attacker यह नियंत्रित नहीं कर सकता कि कौन से specific kernel pages freed memory को मिलेगें, वे एक तकनीक का उपयोग करते हैं जिसे **heap spray** कहा जाता है:
चूंकि attacker यह नियंत्रित नहीं कर सकता कि freed memory को किस specific kernel page पर allocate किया जाएगा, वे एक तकनीक का उपयोग करते हैं जिसे **heap spray** कहा जाता है:
1. attacker kernel memory में बहुत सारी IOSurface objects बनाते हैं
2. प्रत्येक IOSurface object अपने किसी field में एक **magic value** रखता है, जिससे उसे पहचानना आसान हो जाता है।
3. वे freed pages को scan करते हैं यह देखने के लिए कि क्या इनमें से कोई IOSurface object freed page पर आ गया है।
4. जब उन्हें किसी freed page पर IOSurface object मिलता है, तो वे उसे kernel memory को **read और write** करने के लिए उपयोग कर सकते हैं।
1. attacker kernel memory में बहुत से IOSurface objects **create** करता है
2. हर IOSurface object के एक field में एक पहचानयोग्य **magic value** होता है, जिससे पहचान आसान हो जाती है।
3. वे freed pages को **scan** करते हैं यह देखने के लिए कि क्या इनमें से कोई IOSurface object किसी freed page पर आ गया है।
4. जब उन्हें freed page पर एक IOSurface object मिलता है, तो वे इसका उपयोग करके **kernel memory को read और write** कर सकते हैं।
इस बारे में और जानकारी [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+) devices हार्डवेयर mitigations (जैसे PPL या SPTM) लाते हैं जो physical UAF तकनीकों को काफी कम प्रभावी बनाते हैं।
> PPL उन pages पर कड़े MMU प्रोटेक्शन्स लागू करता है जो code signing, entitlements, और संवेदनशील kernel data से संबंधित होते हैं, इसलिए भले ही कोई page reuse हो जाए, userland या compromised kernel code से PPL-protected pages पर लिखना ब्लॉक कर दिया जाता है।
> Secure Page Table Monitor (SPTM) PPL को बढ़ाता है और page table updates को कठिन बनाता है। यह सुनिश्चित करता है कि privileged kernel code भी बिना secure checks के freed pages को silently remap न कर सके या mappings के साथ छेड़छाड़ न कर सके।
> KTRR (Kernel Text Read-Only Region) बूट के बाद kernel के code सेक्शन को read-only के रूप में लॉक कर देता है। यह runtime में kernel code में किसी भी परिवर्तन को रोकता है, जिससे physical UAF exploits का एक बड़ा attack vector बंद हो जाता है।
> इसके अलावा, `IOSurface` allocations अब कम predictable हैं और user-accessible regions में map करना कठिन है, जिससे “magic value scanning” trick कम विश्वसनीय हो गयी है। और `IOSurface` अब entitlements और sandbox restrictions से guarded है।
> ध्यान रखें कि iOS 16+ (A12+) devices हार्डवेयर mitigations (जैसे PPL या SPTM) लाते हैं जो physical UAF तकनीकों को काफी कम प्रभावी बनाते हैं।
> PPL code signing, entitlements, और संवेदनशील kernel डेटा से जुड़े पेजों पर कड़े MMU protections लागू करता है, इसलिए भले ही कोई पेज reuse हो जाए, userland या compromised kernel code से PPL-protected पेजों पर लिखने की कोशिशें ब्लॉक हो जाती हैं।
> Secure Page Table Monitor (SPTM) PPL का विस्तार है और page table updates को खुद ही harden करता है। यह सुनिश्चित करता है कि यहां तक कि privileged kernel code भी freed pages को चुपचाप remap या mappings के साथ छेड़छाड़ नहीं कर सकता बिना secure checks के।
> KTRR (Kernel Text Read-Only Region) kernel के code section को boot के बाद read-only के रूप में लॉक कर देता है। यह किसी भी runtime बदलाव को रोकता है, जो physical UAF exploits अक्सर निर्भर करते हैं।
> इसके अलावा, `IOSurface` allocations अब कम predictable हैं और user-accessible क्षेत्रों में map करना कठिन है, जिससे “magic value scanning” ट्रिक कम भरोसेमंद हो जाती है। और `IOSurface` अब entitlements और sandbox restrictions द्वारा सुरक्षित है।
### Step-by-Step Heap Spray Process
1. **Spray IOSurface Objects**: attacker कई IOSurface objects बनाता है जिनमें एक विशेष identifier ("magic value") होता है।
2. **Scan Freed Pages**: वे जांचते हैं कि क्या इन objects में से कोई freed page पर allocate हुआ है।
3. **Read/Write Kernel Memory**: IOSurface object के fields को manipulate करके वे kernel memory में arbitrary reads और writes करने में सक्षम हो जाते हैं। इससे वे:
* एक field का उपयोग करके kernel memory में किसी भी 32-bit value को पढ़ सकते हैं
* दूसरे field का उपयोग करके 64-bit values लिख सकते हैं, जिससे एक स्थिर kernel read/write primitive हासिल होता है।
1. **Spray IOSurface Objects**: attacker कई IOSurface objects create करता है जिनमें एक विशेष identifier ("magic value") होता है।
2. **Scan Freed Pages**: वे यह जाँचते हैं कि क्या इन objects में से कोई freed page पर allocate हुआ है।
3. **Read/Write Kernel Memory**: IOSurface object के fields को manipulate करके, वे kernel memory में **arbitrary reads और writes** करने की क्षमता प्राप्त कर लेते हैं। इससे वे कर पाते हैं:
* एक field का उपयोग करके kernel memory में किसी भी 32-bit value को **read** करना
* दूसरे field का उपयोग करके 64-bit values **write** करना, जिससे एक स्थिर **kernel read/write primitive** प्राप्त होता है।
Generate IOSurface objects with the magic value IOSURFACE\_MAGIC to later search for:
```c
@ -114,7 +128,7 @@ io_connect_t id = result.surface_id;
}
}
```
एक मुक्त भौतिक पेज में **`IOSurface`** ऑब्जेक्ट खोजें:
एक मुक्त भौतिक पृष्ठ में **`IOSurface`** ऑब्जेक्ट्स खोजें:
```c
int iosurface_krw(io_connect_t client, uint64_t *puafPages, int nPages, uint64_t *self_task, uint64_t *puafPage) {
io_connect_t *surfaceIDs = malloc(sizeof(io_connect_t) * 0x4000);
@ -150,23 +164,23 @@ return 0;
```
### IOSurface के साथ Kernel Read/Write प्राप्त करना
kernel memory में एक IOSurface ऑब्जेक्ट पर नियंत्रण हासिल करने के बाद (mapped to a freed physical page accessible from userspace), हम इसे **arbitrary kernel read and write operations** के लिए उपयोग कर सकते हैं।
kernel memory में एक IOSurface ऑब्जेक्ट (mapped to a freed physical page accessible from userspace) का नियंत्रण हासिल करने के बाद, हम इसे **arbitrary kernel read and write operations** के लिए उपयोग कर सकते हैं।
**Key Fields in IOSurface**
**IOSurface के प्रमुख फील्ड**
IOSurface ऑब्जेक्ट में दो महत्वपूर्ण फील्ड होते हैं:
IOSurface ऑब्जेक्ट में दो महत्वपूर्ण फील्ड हैं:
1. **Use Count Pointer**: एक **32-bit read** की अनुमति देता है।
2. **Indexed Timestamp Pointer**: एक **64-bit write** की अनुमति देता है।
इन pointers को overwrite करके हम इन्हें kernel memory में 任意 (arbitrary) पतों पर redirect कर सकते हैं, जिससे read/write क्षमता मिलती है
इन pointers को overwrite करके, हम उन्हें kernel memory में arbitrary addresses की ओर redirect कर सकते हैं, जिससे read/write क्षमताएँ सक्षम होती हैं
#### 32-Bit Kernel Read
read करने के लिए:
पढ़ने के लिए:
1. **Use Count Pointer** को overwrite करके इसे target address minus a 0x14-byte offset की ओर पॉइंट कराएँ
2. `get_use_count` method का उपयोग करके उस पते पर मौजूद मान पढ़ें।
1. **use count pointer** को overwrite करके इसे target address से 0x14-बाइट कम offset पर point करें
2. `get_use_count` मेथड का उपयोग करके उस address पर मौजूद value पढ़ें।
```c
uint32_t get_use_count(io_connect_t client, uint32_t surfaceID) {
uint64_t args[1] = {surfaceID};
@ -184,10 +198,12 @@ iosurface_set_use_count_pointer(info.object, orig);
return value;
}
```
#### 64-Bit Kernel Write
#### 64-बिट Kernel लिखना
1. लक्ष्य पते पर **indexed timestamp pointer** को ओवरराइट करें।
2. 64-बिट मान लिखने के लिए `set_indexed_timestamp` method का उपयोग करें।
लिखने के लिए:
1. **indexed timestamp pointer** को लक्ष्य पते पर ओवरराइट करें।
2. `set_indexed_timestamp` method का उपयोग करके 64-bit मान लिखें।
```c
void set_indexed_timestamp(io_connect_t client, uint32_t surfaceID, uint64_t value) {
uint64_t args[3] = {surfaceID, 0, value};
@ -201,13 +217,13 @@ set_indexed_timestamp(info.client, info.surface, value);
iosurface_set_indexed_timestamp_pointer(info.object, orig);
}
```
#### Exploit प्रवाह सारांश
#### Exploit Flow Recap
1. **Trigger Physical Use-After-Free**: Free पेज पुन: उपयोग के लिए उपलब्ध होते हैं।
2. **Spray IOSurface Objects**: kernel memory में एक unique "magic value" के साथ कई IOSurface objects allocate करें।
3. **Identify Accessible IOSurface**: अपने नियंत्रित freed page पर मौजूद IOSurface का पता लगाएँ
4. **Abuse Use-After-Free**: IOSurface object में pointers को modify करके IOSurface methods के माध्यम से arbitrary **kernel read/write** सक्षम करें।
1. **Trigger Physical Use-After-Free**: फ्री पेज पुन: उपयोग के लिए उपलब्ध होते हैं।
2. **Spray IOSurface Objects**: kernel memory में unique "magic value" के साथ कई IOSurface objects आवंटित किए जाते हैं।
3. **Identify Accessible IOSurface**: अपने नियंत्रण वाले freed पेज पर एक IOSurface ढूँढें
4. **Abuse Use-After-Free**: IOSurface object में pointers बदलकर IOSurface methods के माध्यम से arbitrary **kernel read/write** सक्षम करें।
इन primitives के साथ, exploit kernel memory के लिए नियंत्रित **32-bit reads** और **64-bit writes** प्रदान करता है। आगे के jailbreak चरणों में अधिक स्थिर read/write primitives शामिल हो सकते हैं, जिसके लिए अतिरिक्त सुरक्षा तंत्रों (उदा., नए arm64e devices पर PPL) को बायपास करने की आवश्यकता हो सकती है।
With these primitives, the exploit provides controlled **32-bit reads** and **64-bit writes** to kernel memory. Further jailbreak steps could involve more stable read/write primitives, which may require bypassing additional protections (e.g., PPL on newer arm64e devices).
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,69 +1,147 @@
# फ़िशिंग का पता लगाना
# Phishing का पता लगाना
{{#include ../../banners/hacktricks-training.md}}
## परिचय
फ़िशिंग प्रयास का पता लगाने के लिए यह महत्वपूर्ण है कि **आप समझें कि आजकल कौन सी फ़िशिंग तकनीकें उपयोग की जा रही हैं**। इस पोस्ट के मुख्य पृष्ठ पर, आप यह जानकारी पा सकते हैं, इसलिए यदि आप नहीं जानते कि आज कौन सी तकनीकें उपयोग की जा रही हैं, तो मैं आपको मुख्य पृष्ठ पर जाने और कम से कम उस अनुभाग को पढ़ने की सिफारिश करता हूँ
Phishing प्रयास का पता लगाने के लिए यह महत्वपूर्ण है कि आप **समझें कि आजकल कौन सी phishing techniques इस्तेमाल हो रही हैं**। इस पोस्ट के parent पेज पर आप यह जानकारी पा सकते हैं, इसलिए अगर आप यह नहीं जानते कि आज किन techniques का उपयोग हो रहा है तो मैं सुझाव दूंगा कि आप parent पेज पर जाएँ और कम से कम उस सेक्शन को पढ़ लें
यह पोस्ट इस विचार पर आधारित है कि **हमलावर किसी न किसी तरह से पीड़ित के डोमेन नाम की नकल करने या उसका उपयोग करने की कोशिश करेंगे**। यदि आपका डोमेन `example.com` है और आपको किसी कारण से एक पूरी तरह से अलग डोमेन नाम जैसे `youwonthelottery.com` का उपयोग करके फ़िश किया गया है, तो ये तकनीकें इसे उजागर नहीं करेंगी।
यह पोस्ट इस विचार पर आधारित है कि **हमलावर किसी न किसी तरह पीड़ित के domain नाम की नकल करने या उसका उपयोग करने की कोशिश करेंगे**। अगर आपका domain `example.com` है और किसी कारण से आपको पूरी तरह से अलग domain जैसे `youwonthelottery.com` का उपयोग करके phish किया जा रहा है, तो ये techniques उसे उजागर नहीं करेंगी।
## डोमेन नाम भिन्नताएँ
## डोमेन नाम के वैरिएशन
ईमेल के अंदर **समान डोमेन** नाम का उपयोग करने वाले फ़िशिंग प्रयासों को **खोजना** काफी **आसान** है।\
यह **हमलावर द्वारा उपयोग किए जाने वाले सबसे संभावित फ़िशिंग नामों की एक सूची बनाने** के लिए पर्याप्त है और **जांचें** कि क्या यह **पंजीकृत** है या बस यह जांचें कि क्या इसका कोई **IP** है।
उन phishing प्रयासों को उजागर करना जिनमें ईमेल के अंदर समान domain नाम का उपयोग किया गया हो, अपेक्षित रूप से काफी आसान है।\
पर्याप्त है कि आप हमलावर द्वारा इस्तेमाल किए जा सकने वाले सबसे संभावित phishing नामों की एक सूची generate करें और जांचें कि वे **रजिस्टर्ड** हैं या नहीं या बस यह देखें कि क्या कोई **IP** उनका उपयोग कर रहा है।
### संदिग्ध डोमेन खोजना
### संदिग्ध डोमेनों का पता लगाना
इसके लिए, आप निम्नलिखित उपकरणों में से किसी का उपयोग कर सकते हैं। ध्यान दें कि ये उपकरण स्वचालित रूप से DNS अनुरोध भी करेंगे यह जांचने के लिए कि क्या डोमेन का कोई IP असाइन किया गया है:
इस उद्देश्य के लिए आप निम्न टूल्स में से किसी का उपयोग कर सकते हैं। ध्यान दें कि ये टूल्स स्वतः DNS अनुरोध भी कर के यह जाँचते हैं कि डोमेन को कोई IP असाइन है या नहीं:
- [**dnstwist**](https://github.com/elceef/dnstwist)
- [**urlcrazy**](https://github.com/urbanadventurer/urlcrazy)
### बिटफ्लिपिंग
Tip: अगर आप एक candidate सूची generate करते हैं, तो इसे अपने DNS resolver लॉग्स में भी फीड करें ताकि आप अपने org के अंदर से होने वाले **NXDOMAIN lookups** का पता लगा सकें (उपयोगकर्ता किसी टाइपो तक पहुँचने की कोशिश कर रहे हैं इससे पहले कि हमलावर वास्तव में उसे रजिस्टर करे)। नीति अनुमति देती है तो इन डोमेनों को Sinkhole या pre-block करें।
**आप इस तकनीक का संक्षिप्त विवरण मुख्य पृष्ठ पर पा सकते हैं। या पढ़ें मूल शोध** [**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/)
**सभी संभावित बिट-फ्लिपिंग डोमेन नामों की भी निगरानी की जानी चाहिए।**
For example, a 1 bit modification in the domain microsoft.com can transform it into _windnws.com._\
**Attackers may register as many bit-flipping domains as possible related to the victim to redirect legitimate users to their infrastructure**.
### बुनियादी जांच
**All possible bit-flipping domain names should be also monitored.**
एक बार जब आपके पास संभावित संदिग्ध डोमेन नामों की एक सूची हो, तो आपको उन्हें **जांचना चाहिए** (मुख्य रूप से HTTP और HTTPS पोर्ट) यह देखने के लिए कि क्या वे पीड़ित के डोमेन के किसी लॉगिन फॉर्म का उपयोग कर रहे हैं।\
आप पोर्ट 3333 की भी जांच कर सकते हैं यह देखने के लिए कि क्या यह खुला है और `gophish` का एक उदाहरण चला रहा है।\
यह जानना भी दिलचस्प है कि **प्रत्येक खोजे गए संदिग्ध डोमेन की उम्र कितनी है**, जितना नया होगा उतना ही जोखिम भरा होगा।\
आप संदिग्ध वेब पृष्ठ के HTTP और/या HTTPS के **स्क्रीनशॉट** भी ले सकते हैं यह देखने के लिए कि क्या यह संदिग्ध है और इस मामले में **गहराई से देखने के लिए इसे एक्सेस करें**
If you also need to consider homoglyph/IDN lookalikes (e.g., mixing Latin/Cyrillic characters), check:
### उन्नत जांच
{{#ref}}
homograph-attacks.md
{{#endref}}
यदि आप एक कदम और आगे बढ़ना चाहते हैं, तो मैं आपको **संदिग्ध डोमेन की निगरानी करने और समय-समय पर अधिक खोजने** की सिफारिश करूंगा (हर दिन? इसमें केवल कुछ सेकंड/मिनट लगते हैं)। आपको संबंधित IPs के खुले **पोर्ट्स** की भी **जांच करनी चाहिए** और **`gophish` या समान उपकरणों के उदाहरणों की खोज करनी चाहिए** (हाँ, हमलावर भी गलतियाँ करते हैं) और **संदिग्ध डोमेन और उपडोमेन के HTTP और HTTPS वेब पृष्ठों की निगरानी करनी चाहिए** यह देखने के लिए कि क्या उन्होंने पीड़ित के वेब पृष्ठों से कोई लॉगिन फॉर्म कॉपी किया है।\
इसको **स्वचालित करने** के लिए, मैं आपको पीड़ित के डोमेन के लॉगिन फॉर्म की एक सूची रखने, संदिग्ध वेब पृष्ठों को स्पाइडर करने और संदिग्ध डोमेन के अंदर पाए गए प्रत्येक लॉगिन फॉर्म की तुलना पीड़ित के डोमेन के प्रत्येक लॉगिन फॉर्म के साथ करने की सिफारिश करूंगा, जैसे कि `ssdeep` का उपयोग करके।\
यदि आपने संदिग्ध डोमेन के लॉगिन फॉर्म का पता लगा लिया है, तो आप **जंक क्रेडेंशियल्स भेजने** और **जांचने** की कोशिश कर सकते हैं कि क्या यह आपको पीड़ित के डोमेन की ओर पुनर्निर्देशित कर रहा है।
### बेसिक जाँच
## कीवर्ड का उपयोग करने वाले डोमेन नाम
एक बार जब आपके पास संभावित संदिग्ध डोमेन नामों की सूची हो, तो आपको उन्हें **जांचना** चाहिए (मुख्य रूप से पोर्ट्स HTTP और HTTPS) ताकि यह देखा जा सके कि क्या वे पीड़ित के किसी login form जैसा कोई form उपयोग कर रहे हैं।\
आप पोर्ट 3333 भी चेक कर सकते हैं यह देखने के लिए कि क्या यह खुला है और `gophish` का इंस्टेंस चल रहा है।\
यह भी जानना दिलचस्प होगा कि प्रत्येक खोजे गए संदिग्ध डोमेन की उम्र कितनी है — जितना नया होगा उतना अधिक जोखिम होगा।\
आप HTTP और/या HTTPS संदिग्ध वेब पेज के **screenshots** भी ले सकते हैं ताकि देखें कि यह संदिग्ध है या नहीं और उस स्थिति में **गहरा निरीक्षण करने के लिए इसे access करें**
मुख्य पृष्ठ पर एक डोमेन नाम भिन्नता तकनीक का भी उल्लेख किया गया है जिसमें **पीड़ित के डोमेन नाम को एक बड़े डोमेन के अंदर रखा जाता है** (जैसे paypal-financial.com के लिए paypal.com)।
### एडवांस्ड जाँच
### प्रमाणपत्र पारदर्शिता
अगर आप एक कदम आगे जाना चाहते हैं तो मैं सुझाव दूँगा कि आप उन संदिग्ध डोमेनों की निगरानी करें और समय-समय पर (हर दिन?) और नए संदिग्ध डोमेनों की तलाश करें (यह कुछ सेकंड/मिनट ही लेता है)। आपको संबंधित IPs के खुले पोर्ट्स भी जांचने चाहिए और `gophish` या समान tools के इंस्टेंस की खोज करनी चाहिए (हाँ, हमलावर भी गलतियाँ करते हैं) और संदिग्ध डोमेनों और सबडोमेनों के HTTP और HTTPS वेब पेजों की निगरानी करनी चाहिए ताकि देखा जा सके कि क्या उन्होंने पीड़ित के वेब पेजों से कोई लॉगिन फॉर्म कॉपी किया है।\
इसे ऑटोमेट करने के लिए मेरा सुझाव है कि पीड़ित के डोमेनों के लॉगिन फॉर्म्स की एक सूची रखें, संदिग्ध वेब पेजों को spider करें और प्रत्येक पाए गए लॉगिन फॉर्म की तुलना पीड़ित के डोमेन के प्रत्येक लॉगिन फॉर्म से कुछ जैसे `ssdeep` का उपयोग करके करें।\
अगर आपने संदिग्ध डोमेनों के लॉगिन फॉर्म्स का पता लगा लिया है, तो आप जंक क्रेडेंशियल भेजकर यह जांचने की कोशिश कर सकते हैं कि क्या यह आपको पीड़ित के domain पर redirect कर रहा है।
पिछले "ब्रूट-फोर्स" दृष्टिकोण को अपनाना संभव नहीं है, लेकिन वास्तव में **ऐसे फ़िशिंग प्रयासों का पता लगाना संभव है** प्रमाणपत्र पारदर्शिता के कारण। हर बार जब एक प्रमाणपत्र 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" द्वारा फ़िल्टर कर सकते हैं:
### favicon और वेब फिंगरप्रिंट्स से शिकार (Shodan/ZoomEye/Censys)
कई phishing kits उस ब्रांड के favicon को reuse करते हैं जिसकी वे impersonate कर रहे होते हैं। Internet-wide scanners base64-encoded favicon का MurmurHash3 compute करते हैं। आप hash generate कर सकते हैं और उस पर pivot कर सकते हैं:
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 जैसे community tools देखें ताकि Shodan/ZoomEye/Censys के लिए hashes और dorks जनरेट कर सकें।
Notes
- Favicons पुनः उपयोग होते हैं; मेल खाने वाले परिणामों को leads के रूप में मानें और कार्रवाई करने से पहले content और certs को validate करें।
- बेहतर सटीकता के लिए domain-age और keyword heuristics के साथ संयोजन करें।
### URL telemetry hunting (urlscan.io)
`urlscan.io` सबमिट किए गए URLs के historical screenshots, DOM, requests और TLS metadata को स्टोर करता है। आप brand abuse और clones के लिए खोज कर सकते हैं:
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 उदाहरण:
```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'
```
JSON से pivot करें:
- `page.tlsIssuer`, `page.tlsValidFrom`, `page.tlsAgeDays` का उपयोग lookalikes के लिए बहुत नए certs खोजने के लिए करें
- `task.source` के मान, जैसे `certstream-suspicious`, का उपयोग findings को CT monitoring से जोड़ने के लिए करें
### RDAP के माध्यम से डोमेन उम्र (scriptable)
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
```
अपनी पाइपलाइन को डोमेनों को उनके registration age buckets (उदा., <7 days, <30 days) के टैग करके समृद्ध करें और तदनुस triage प्रथमिकत दें
### TLS/JAx फिंगरप्रिंट्स से AiTM इन्फ्रास्ट्रक्चर की पहचान
आधुनिक credential-phishing में बढ़ते हुए **Adversary-in-the-Middle (AiTM)** reverse proxies (उदा., Evilginx) का उपयोग session tokens चुराने के लिए होता है। आप network-side detections जोड़ सकते हैं:
- egress पर TLS/HTTP फिंगरप्रिंट्स (JA3/JA4/JA4S/JA4H) को लॉग करें। कुछ Evilginx builds में स्थिर JA4 client/server मान देखे गए हैं। केवल कमजोर संकेत के रूप में known-bad fingerprints पर अलर्ट करें और हमेशा content और domain intel से पुष्टि करें।
- CT या urlscan के माध्यम से मिले lookalike hosts के लिए TLS certificate metadata (issuer, SAN count, wildcard use, validity) को सक्रिय रूप से रिकॉर्ड करें और DNS age तथा geolocation के साथ correlate करें।
> नोट: फिंगरप्रिंट्स को enrichment के रूप में मानें, केवल blockers के रूप में नहीं; frameworks विकसित होते हैं और वे randomise या obfuscate कर सकते हैं।
### कीवर्ड का उपयोग करने वाले डोमेन नाम
मूल पृष्ठ में एक डोमेन नाम वेरिएशन तकनीक का भी ज़िक्र है, जिसमें **victim's domain name को एक बड़े डोमेन के अंदर रखा जाता है** (उदा., paypal-financial.com for paypal.com)।
#### Certificate Transparency
पिछला "Brute-Force" तरीका अपनाना संभव नहीं है, पर certificate transparency की वजह से ऐसे phishing प्रयासों का पता लगाया जा सकता है। हर बार जब कोई CA द्वारा certificate जारी होता है, उसके विवरण सार्वजनिक किए जाते हैं। इसका मतलब है कि certificate transparency को पढ़कर या मॉनिटर करके ऐसे डोमेन्स ढूँढना संभव है जिनके नाम में कोई कीवर्ड इस्तेमाल हुआ हो। उदाहरण के लिए, अगर कोई attacker [https://paypal-financial.com](https://paypal-financial.com) का certificate बनाता है, तो certificate देखकर कीवर्ड "paypal" मिल सकता है और पता चल सकता है कि suspicious email उपयोग किया जा रहा है।
पोस्ट [https://0xpatrik.com/phishing-domains/](https://0xpatrik.com/phishing-domains/) सुझाव देता है कि आप Censys का उपयोग किसी विशेष कीवर्ड से संबंधित certificates खोजने के लिए कर सकते हैं और date (केवल "new" certificates) तथा CA issuer "Let's Encrypt" के अनुसार filter कर सकते हैं:
![https://0xpatrik.com/content/images/2018/07/cert_listing.png](<../../images/image (1115).png>)
हालांकि, आप मुफ्त वेब [**crt.sh**](https://crt.sh) का उपयोग करके "वही" कर सकते हैं। आप **कीवर्ड** के लिए **खोज** कर सकते हैं और यदि आप चाहें तो **तारीख और CA द्वारा** परिणामों को **फ़िल्टर** कर सकते हैं।
हालाँकि, आप free वेब **crt.sh** का उपयोग करके "उसी" काम को कर सकते हैं। आप **कीवर्ड खोज** सकते हैं और परिणामों को **date और CA** के अनुसार filter कर सकते हैं यदि आप चाहें।
![](<../../images/image (519).png>)
इस अंतिम विकल्प का उपयोग करते हुए, आप यहां तक कि फ़ील्ड मिलान पहचान का उपयोग कर सकते हैं यह देखने के लिए कि क्या वास्तविक डोमेन की कोई पहचान संदिग्ध डोमेन में से किसी से मेल खाती है (ध्यान दें कि एक संदिग्ध डोमेन एक झूठी सकारात्मक हो सकती है)।
इस विकल्प का उपयोग करके आप Matching Identities फ़ील्ड का उपयोग भी कर सकते हैं यह देखने के लिए कि क्या किसी असली डोमेन की कोई identity किसी suspicious domain से मिलती है (ध्यान दें कि एक suspicious domain false positive हो सकता है)।
**एक और विकल्प** शानदार प्रोजेक्ट [**CertStream**](https://medium.com/cali-dog-security/introducing-certstream-3fc13bb98067) है। CertStream नए उत्पन्न प्रमाणपत्रों का एक वास्तविक समय का प्रवाह प्रदान करता है जिसका उपयोग आप (नज़दीकी) वास्तविक समय में निर्दिष्ट कीवर्ड का पता लगाने के लिए कर सकते हैं। वास्तव में, एक प्रोजेक्ट है [**phishing_catcher**](https://github.com/x0rz/phishing_catcher) जो यही करता है।
**एक और विकल्प** है शानदार प्रोजेक्ट **CertStream**। CertStream newly generated certificates का real-time stream देता है जिसे आप निर्दिष्ट कीवर्ड्स का (near) real-time पता लगाने के लिए उपयोग कर सकते हैं। वास्तव में, एक प्रोजेक्ट है **phishing_catcher** जो यही करता है।
### **नए डोमेन**
व्यावहारिक सुझाव: जब CT hits का triage कर रहे हों, NRDs, untrusted/unknown registrars, privacy-proxy WHOIS, और बहुत हाल के `NotBefore` समय वाले certs को प्राथमिकता दें। शोर कम करने के लिए अपने मालिकाना डोमेनों/ब्रांड्स की allowlist बनाए रखें।
**एक अंतिम विकल्प** कुछ TLDs के लिए **नए पंजीकृत डोमेन** की एक सूची एकत्र करना है ([Whoxy](https://www.whoxy.com/newly-registered-domains/) ऐसी सेवा प्रदान करता है) और **इन डोमेन में कीवर्ड की जांच करना**। हालाँकि, लंबे डोमेन आमतौर पर एक या अधिक उपडोमेन का उपयोग करते हैं, इसलिए कीवर्ड FLD के अंदर नहीं दिखाई देगा और आप फ़िशिंग उपडोमेन नहीं खोज पाएंगे।
#### **New domains**
**एक अंतिम विकल्प** यह है कि कुछ TLDs के लिए **newly registered domains** की एक सूची इकट्ठा करें ([Whoxy](https://www.whoxy.com/newly-registered-domains/) ऐसी सेवा प्रदान करता है) और इन डोमेन्स में कीवर्ड्स चेक करें। हालाँकि, लंबे डोमेन्स आमतौर पर एक या अधिक subdomains का उपयोग करते हैं, इसलिए कीवर्ड FLD के अंदर प्रकट नहीं होगा और आप phishing subdomain नहीं पाएंगे।
अतिरिक्त heuristic: कुछ **file-extension TLDs** (उदा., `.zip`, `.mov`) को alerting में अतिरिक्त संदेह के साथ मानें। ये अक्सर lures में filenames के साथ भ्रमित होते हैं; बेहतर सटीकता के लिए TLD संकेत को brand keywords और NRD age के साथ मिलाएँ।
## 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}}

View File

@ -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; }