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
This commit is contained in:
parent
54b04f6471
commit
8c5d0f1d36
@ -1,97 +1,97 @@
|
||||
# iOS Physical Use-After-Free via IOSurface
|
||||
# iOS Physical Use After Free via IOSurface
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
## 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) में मिलती है।
|
||||
यह सारांश उस पोस्ट से लिया गया है: [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) में मिल सकती है।
|
||||
|
||||
### Memory management in XNU <a href="#memory-management-in-xnu" id="memory-management-in-xnu"></a>
|
||||
|
||||
iOS पर user processes के लिए **virtual memory address space** **0x0 से 0x8000000000** तक फैला होता है। हालांकि, ये एड्रेसेस सीधे physical memory से मैप नहीं होते। इसके बजाय, **कर्नेल** virtual एड्रेस को वास्तविक **physical addresses** में translate करने के लिए **page tables** का उपयोग करता है।
|
||||
iOS पर user processes के लिए the virtual memory address space **0x0 से 0x8000000000** तक फैला होता है। हालांकि, ये addresses सीधे physical memory से मैप नहीं होते। इसके बजाय, kernel page tables का उपयोग virtual addresses को वास्तविक physical addresses में translate करने के लिए करता है।
|
||||
|
||||
#### Levels of Page Tables in iOS
|
||||
|
||||
Page tables तीन स्तरों में व्यवस्थित होते हैं:
|
||||
Page tables तीन स्तरों में hierarchical तरीके से व्यवस्थित होते हैं:
|
||||
|
||||
1. **L1 Page Table (Level 1)**:
|
||||
* यहाँ हर entry वर्चुअल मेमोरी के बड़े रेंज का प्रतिनिधित्व करती है।
|
||||
* यह **0x1000000000 bytes** (या **256 GB**) वर्चुअल मेमोरी को कवर करती है।
|
||||
* यहाँ का हर entry एक बड़े virtual memory रेंज का प्रतिनिधित्व करता है।
|
||||
* यह **0x1000000000 bytes** (या **256 GB**) of virtual memory कवर करता है।
|
||||
2. **L2 Page Table (Level 2)**:
|
||||
* यहाँ की एक entry वर्चुअल मेमोरी के छोटे क्षेत्र का प्रतिनिधित्व करती है, विशेषकर **0x2000000 bytes** (32 MB)।
|
||||
* यदि कोई L1 entry पूरे क्षेत्र को खुद नहीं मैप कर सकती तो वह किसी L2 table की ओर pointer कर सकती है।
|
||||
* यहाँ का एक entry एक छोटी virtual memory region का प्रतिनिधित्व करता है, विशेष रूप से **0x2000000 bytes** (32 MB)।
|
||||
* अगर L1 entry पूरे रेंज को स्वयं मैप नहीं कर सकती तो वह L2 table की ओर pointer कर सकती है।
|
||||
3. **L3 Page Table (Level 3)**:
|
||||
* यह सबसेละเอียด स्तर है, जहाँ हर entry एक single **4 KB** मेमोरी पेज को मैप करती है।
|
||||
* आवश्यकता होने पर L2 entry किसी L3 table की ओर pointer कर सकती है।
|
||||
* यह सबसे fine-grained स्तर है, जहाँ हर entry एक single **4 KB** memory page को मैप करती है।
|
||||
* अगर और अधिक granular control चाहिए तो L2 entry एक L3 table की ओर pointer कर सकती है।
|
||||
|
||||
#### Mapping Virtual to Physical Memory
|
||||
|
||||
* **Direct Mapping (Block Mapping)**:
|
||||
* page table की कुछ entries सीधे किसी वर्चुअल एड्रेस रेंज को contiguous physical address रेंज से मैप करती हैं (एक तरह का शॉर्टकट)।
|
||||
* page table के कुछ entries सीधे एक range of virtual addresses को contiguous range of physical addresses से मैप करते हैं (एक तरह का शॉर्टकट)।
|
||||
* **Pointer to Child Page Table**:
|
||||
* यदि अधिक सूक्ष्म नियंत्रण की ज़रूरत हो, तो एक स्तर की entry (जैसे L1) अगले स्तर में किसी **child page table** की ओर pointer कर सकती है (जैसे L2)।
|
||||
* अगर finer control चाहिए, तो एक level की entry (उदा. L1) next level (उदा. L2) के child page table की ओर pointer कर सकती है।
|
||||
|
||||
#### Example: Mapping a Virtual Address
|
||||
|
||||
मान लीजिए आप virtual address **0x1000000000** तक पहुँचने की कोशिश करते हैं:
|
||||
मान लीजिए आप virtual address **0x1000000000** को access करने की कोशिश करते हैं:
|
||||
|
||||
1. **L1 Table**:
|
||||
* कर्नेल उस virtual address से संबंधित L1 page table entry को चेक करता है। यदि उसमें **pointer to an L2 page table** है, तो वह उस L2 table पर जाता है।
|
||||
* kernel उस L1 page table entry को चेक करता है जो इस virtual address के अनुरूप है। अगर उसमें **pointer to an L2 page table** है, तो वह उस L2 table पर जाता है।
|
||||
2. **L2 Table**:
|
||||
* कर्नेल अधिक विस्तृत मैपिंग के लिए L2 page table को चेक करता है। यदि इस entry में **pointer to an L3 page table** है, तो वह वहां जाता है।
|
||||
* kernel अधिक विस्तृत mapping के लिए L2 page table को देखता है। अगर यह entry **L3 page table** की ओर pointer करती है, तो वह वहाँ जाता है।
|
||||
3. **L3 Table**:
|
||||
* कर्नेल अंतिम L3 entry को देखता है, जो वास्तविक मेमोरी पेज के **physical address** की ओर इशारा करती है।
|
||||
* kernel अंतिम L3 entry को देखता है, जो वास्तविक memory page के **physical address** की ओर इशारा करती है।
|
||||
|
||||
#### Example of Address Mapping
|
||||
|
||||
यदि आप L2 table के पहले index में physical address **0x800004000** लिखते हैं, तो:
|
||||
यदि आप physical address **0x800004000** को L2 table के first index में लिखते हैं, तो:
|
||||
|
||||
* Virtual addresses **0x1000000000** से **0x1002000000** तक physical addresses **0x800004000** से **0x802004000** तक मैप होंगे।
|
||||
* Virtual addresses **0x1000000000 से 0x1002000000** तक physical addresses **0x800004000 से 0x802004000** तक मैप होंगे।
|
||||
* यह L2 स्तर पर एक **block mapping** है।
|
||||
|
||||
वैकल्पिक रूप से, यदि L2 entry किसी L3 table की ओर pointer करती है:
|
||||
|
||||
* तो वर्चुअल रेंज **0x1000000000 -> 0x1002000000** के हर 4 KB पेज को L3 table की व्यक्तिगत entries मैप करेंगी।
|
||||
* virtual address रेंज **0x1000000000 -> 0x1002000000** में हर 4 KB page को L3 table के individual entries मैप करेंगे।
|
||||
|
||||
### Physical use-after-free
|
||||
|
||||
एक **physical use-after-free (UAF)** तब होती है जब:
|
||||
एक **physical use-after-free (UAF)** तब होता है जब:
|
||||
|
||||
1. कोई process कुछ मेमोरी **readable और writable** के रूप में **allocate** करता है।
|
||||
2. उस मेमोरी को process द्वारा एक्सेस करने योग्य एक specific physical address से मैप करने के लिए **page tables** अपडेट होते हैं।
|
||||
3. Process उस मेमोरी को **deallocate** (free) कर देता है।
|
||||
4. लेकिन किसी **बग** के कारण, कर्नेल **page tables से mapping हटाना भूल जाता है**, जबकि संबंधित physical memory को free के रूप में मार्क कर दिया गया होता है।
|
||||
5. कर्नेल फिर इस "freed" physical memory को अन्य प्रयोजनों के लिए **reallocate** कर सकता है, जैसे कि **kernel data**।
|
||||
6. चूंकि mapping नहीं हटाई गई थी, process अभी भी इस physical memory को **read और write** कर सकता है।
|
||||
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 कर सकता है।
|
||||
|
||||
इसका अर्थ है कि process **kernel memory के पेजों तक पहुँच** बना सकता है, जिनमें संवेदनशील डेटा या संरचनाएँ हो सकती हैं, जिससे attacker को **kernel memory में छेड़छाड़** करने का मौका मिल सकता है।
|
||||
इसका मतलब है कि process kernel memory के pages को access कर सकता है, जिनमें संवेदनशील डेटा या संरचनाएँ हो सकती हैं, जिससे attacker kernel memory को manipulate कर सकता है।
|
||||
|
||||
### IOSurface Heap Spray
|
||||
|
||||
क्योंकि attacker यह नियंत्रित नहीं कर सकता कि किस specific kernel पेज को freed memory के लिए allocate किया जाएगा, वे एक तकनीक का उपयोग करते हैं जिसे कहा जाता है **heap spray**:
|
||||
क्योंकि attacker यह नियंत्रित नहीं कर सकता कि कौन से specific kernel pages freed memory को मिलेगें, वे एक तकनीक का उपयोग करते हैं जिसे **heap spray** कहा जाता है:
|
||||
|
||||
1. attacker kernel memory में कई **IOSurface objects** बनाता है।
|
||||
2. प्रत्येक IOSurface object अपनी किसी field में एक **magic value** रखता है, जिससे उसे आसानी से पहचानना संभव होता है।
|
||||
3. वे freed पेजों को **scan** करते हैं यह देखने के लिए कि क्या कोई IOSurface object किसी freed पेज पर आ गया है।
|
||||
4. जब उन्हें किसी freed पेज पर IOSurface object मिलता है, तो वे इसे kernel memory को **read और write** करने के लिए उपयोग कर सकते हैं।
|
||||
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** करने के लिए उपयोग कर सकते हैं।
|
||||
|
||||
इसके बारे में अधिक जानकारी हेतु देखें: [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+) डिवाइस हार्डवेयर mitigations (जैसे PPL या SPTM) लाते हैं जो physical UAF तकनीकों को काफी कम प्रभावी बनाते हैं।
|
||||
> PPL उन पेजों पर सख्त MMU protections लागू करता है जो code signing, entitlements, और संवेदनशील kernel डेटा से संबंधित हैं, तो भले ही कोई पेज reuse हो जाए, userland या compromised kernel code से PPL-protected पेजों पर writes रोके जाते हैं।
|
||||
> Secure Page Table Monitor (SPTM) PPL को बढ़ाता है और page table updates को भी मजबूत करता है। यह सुनिश्चित करता है कि privileges वाले kernel code द्वारा freed पेजों को चुपके से remap या mappings में छेड़छाड़ नहीं की जा सके बिना secure checks के।
|
||||
> 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” ट्रिक कम भरोसेमंद हो जाती है। और `IOSurface` अब entitlements और sandbox restrictions से guarded है।
|
||||
> ध्यान दें कि 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 है।
|
||||
|
||||
### Step-by-Step Heap Spray Process
|
||||
|
||||
1. **Spray IOSurface Objects**: attacker कई IOSurface objects बनाते हैं जिनमें एक विशेष पहचानकर्ता ("magic value") होता है।
|
||||
2. **Scan Freed Pages**: वे यह चेक करते हैं कि क्या इनमें से कोई object किसी freed पेज पर allocate हुआ है।
|
||||
3. **Read/Write Kernel Memory**: IOSurface object की fields में बदलाव करके वे kernel memory में **arbitrary reads और writes** करने की क्षमता हासिल कर लेते हैं। इससे वे कर पाते हैं:
|
||||
* एक field का उपयोग करके kernel memory में किसी भी 32-bit मान को **read** करना।
|
||||
* दूसरे field का उपयोग करके 64-bit मान **write** करना, जिससे स्थिर **kernel read/write primitive** मिलती है।
|
||||
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 हासिल होता है।
|
||||
|
||||
Generate IOSurface objects with the magic value IOSURFACE\_MAGIC to later search for:
|
||||
```c
|
||||
@ -114,7 +114,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 +150,23 @@ return 0;
|
||||
```
|
||||
### IOSurface के साथ Kernel Read/Write प्राप्त करना
|
||||
|
||||
Kernel memory में एक IOSurface object पर नियंत्रण मिलने के बाद (जो userspace से पहुंच योग्य freed physical page पर mapped होता है), हम इसे arbitrary kernel read और write operations के लिए उपयोग कर सकते हैं।
|
||||
kernel memory में एक IOSurface ऑब्जेक्ट पर नियंत्रण हासिल करने के बाद (mapped to a freed physical page accessible from userspace), हम इसे **arbitrary kernel read and write operations** के लिए उपयोग कर सकते हैं।
|
||||
|
||||
**IOSurface में मुख्य फील्ड**
|
||||
**Key Fields in IOSurface**
|
||||
|
||||
IOSurface object में दो महत्वपूर्ण फील्ड हैं:
|
||||
IOSurface ऑब्जेक्ट में दो महत्वपूर्ण फील्ड होते हैं:
|
||||
|
||||
1. **Use Count Pointer**: एक **32-bit read** की अनुमति देता है।
|
||||
2. **Indexed Timestamp Pointer**: एक **64-bit write** की अनुमति देता है।
|
||||
|
||||
इन pointers को overwrite करके हम इन्हें kernel memory के arbitrary addresses पर redirect कर सकते हैं, जिससे read/write क्षमताएँ सक्षम हो जाती हैं।
|
||||
इन pointers को overwrite करके हम इन्हें kernel memory में 任意 (arbitrary) पतों पर redirect कर सकते हैं, जिससे read/write क्षमता मिलती है।
|
||||
|
||||
#### 32-Bit Kernel Read
|
||||
|
||||
पढ़ने के लिए:
|
||||
read करने के लिए:
|
||||
|
||||
1. Overwrite the **use count pointer** ताकि वह target address minus 0x14-बाइट offset को point करे।
|
||||
2. उस address पर मान पढ़ने के लिए `get_use_count` method का उपयोग करें।
|
||||
1. **Use Count Pointer** को overwrite करके इसे target address minus a 0x14-byte offset की ओर पॉइंट कराएँ।
|
||||
2. `get_use_count` method का उपयोग करके उस पते पर मौजूद मान पढ़ें।
|
||||
```c
|
||||
uint32_t get_use_count(io_connect_t client, uint32_t surfaceID) {
|
||||
uint64_t args[1] = {surfaceID};
|
||||
@ -186,10 +186,8 @@ return value;
|
||||
```
|
||||
#### 64-Bit Kernel Write
|
||||
|
||||
लिखने के लिए:
|
||||
|
||||
1. **indexed timestamp pointer** को लक्षित पते पर ओवरराइट करें।
|
||||
2. `set_indexed_timestamp` method का उपयोग करके 64-bit मान लिखें।
|
||||
1. लक्ष्य पते पर **indexed timestamp pointer** को ओवरराइट करें।
|
||||
2. 64-बिट मान लिखने के लिए `set_indexed_timestamp` method का उपयोग करें।
|
||||
```c
|
||||
void set_indexed_timestamp(io_connect_t client, uint32_t surfaceID, uint64_t value) {
|
||||
uint64_t args[3] = {surfaceID, 0, value};
|
||||
@ -203,13 +201,13 @@ set_indexed_timestamp(info.client, info.surface, value);
|
||||
iosurface_set_indexed_timestamp_pointer(info.object, orig);
|
||||
}
|
||||
```
|
||||
#### Exploit Flow Recap
|
||||
#### Exploit प्रवाह सारांश
|
||||
|
||||
1. **Trigger Physical Use-After-Free**: Free pages पुन: उपयोग के लिए उपलब्ध हो जाती हैं।
|
||||
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** सक्षम हो सकें।
|
||||
3. **Identify Accessible IOSurface**: अपने नियंत्रित freed page पर मौजूद IOSurface का पता लगाएँ।
|
||||
4. **Abuse Use-After-Free**: IOSurface object में pointers को modify करके IOSurface methods के माध्यम से arbitrary **kernel read/write** सक्षम करें।
|
||||
|
||||
इन primitives के साथ, exploit नियंत्रित **32-bit reads** और **64-bit writes** kernel memory में प्रदान करता है। आगे के jailbreak चरणों में अधिक स्थिर read/write primitives शामिल हो सकते हैं, जिनके लिए अतिरिक्त सुरक्षा उपायों को बायपास करना पड़ सकता है (उदा., PPL on newer arm64e devices).
|
||||
इन primitives के साथ, exploit kernel memory के लिए नियंत्रित **32-bit reads** और **64-bit writes** प्रदान करता है। आगे के jailbreak चरणों में अधिक स्थिर read/write primitives शामिल हो सकते हैं, जिसके लिए अतिरिक्त सुरक्षा तंत्रों (उदा., नए arm64e devices पर PPL) को बायपास करने की आवश्यकता हो सकती है।
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user