macOS Library Injection

Support HackTricks

dyld का कोड ओपन सोर्स है और https://opensource.apple.com/source/dyld/ पर पाया जा सकता है और इसे URL जैसे https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz का उपयोग करके एक टार के रूप में डाउनलोड किया जा सकता है।

Dyld Process

Dyld कैसे बाइनरी के अंदर लाइब्रेरी लोड करता है, इस पर एक नज़र डालें:

macOS Dyld Process

DYLD_INSERT_LIBRARIES

यह LD_PRELOAD on Linux के समान है। यह एक प्रक्रिया को इंगित करने की अनुमति देता है जो चलने वाली है कि एक विशेष लाइब्रेरी को एक पथ से लोड किया जाए (यदि env var सक्षम है)

यह तकनीक ASEP तकनीक के रूप में भी उपयोग की जा सकती है क्योंकि हर स्थापित एप्लिकेशन में "Info.plist" नामक एक plist होती है जो एक कुंजी LSEnvironmental का उपयोग करके पर्यावरणीय चर असाइन करने की अनुमति देती है।

2012 से Apple ने DYLD_INSERT_LIBRARIES की शक्ति को नाटकीय रूप से कम कर दिया है

कोड पर जाएं और src/dyld.cpp की जांच करें। फ़ंक्शन pruneEnvironmentVariables में आप देख सकते हैं कि DYLD_* चर हटा दिए गए हैं।

फ़ंक्शन processRestricted में प्रतिबंध का कारण सेट किया गया है। उस कोड की जांच करते समय आप देख सकते हैं कि कारण हैं:

  • बाइनरी setuid/setgid है

  • macho बाइनरी में __RESTRICT/__restrict अनुभाग का अस्तित्व।

  • सॉफ़्टवेयर में अधिकार हैं (हर्डनड रनटाइम) बिना com.apple.security.cs.allow-dyld-environment-variables अधिकार के

  • बाइनरी के अधिकार की जांच करें: codesign -dv --entitlements :- </path/to/bin>

अधिक अपडेटेड संस्करणों में आप इस तर्क को फ़ंक्शन configureProcessRestrictions के दूसरे भाग में पा सकते हैं। हालाँकि, जो नए संस्करणों में निष्पादित होता है वह फ़ंक्शन के शुरुआती जांच हैं (आप iOS या सिमुलेशन से संबंधित ifs को हटा सकते हैं क्योंकि वे macOS में उपयोग नहीं किए जाएंगे)।

लाइब्रेरी मान्यता

यहां तक कि यदि बाइनरी DYLD_INSERT_LIBRARIES env चर का उपयोग करने की अनुमति देती है, यदि बाइनरी लोड करने के लिए लाइब्रेरी के हस्ताक्षर की जांच करती है, तो यह एक कस्टम को लोड नहीं करेगी।

एक कस्टम लाइब्रेरी लोड करने के लिए, बाइनरी को निम्नलिखित अधिकारों में से एक होना चाहिए:

या बाइनरी को हर्डनड रनटाइम फ्लैग या लाइब्रेरी मान्यता फ्लैग नहीं होना चाहिए।

आप यह जांच सकते हैं कि क्या बाइनरी में हर्डनड रनटाइम है codesign --display --verbose <bin> के साथ CodeDirectory में रनटाइम फ्लैग की जांच करते हुए जैसे: CodeDirectory v=20500 size=767 flags=0x10000(runtime) hashes=13+7 location=embedded

आप एक लाइब्रेरी को भी लोड कर सकते हैं यदि यह बाइनरी के समान प्रमाणपत्र के साथ हस्ताक्षरित है

इसका (ab) उपयोग करने का एक उदाहरण खोजें और प्रतिबंधों की जांच करें:

macOS Dyld Hijacking & DYLD_INSERT_LIBRARIES

Dylib Hijacking

याद रखें कि पिछले लाइब्रेरी मान्यता प्रतिबंध भी लागू होते हैं Dylib हाइजैकिंग हमलों को करने के लिए।

Windows की तरह, MacOS में आप भी dylibs को हाइजैक कर सकते हैं ताकि एप्लिकेशन मनमाने कोड को निष्पादित कर सकें (ठीक है, वास्तव में एक सामान्य उपयोगकर्ता के लिए यह संभव नहीं हो सकता क्योंकि आपको एक TCC अनुमति की आवश्यकता हो सकती है ताकि आप एक .app बंडल के अंदर लिख सकें और एक लाइब्रेरी को हाइजैक कर सकें)। हालांकि, MacOS एप्लिकेशन लाइब्रेरी को लोड करने का तरीका Windows की तुलना में अधिक प्रतिबंधित है। इसका मतलब है कि मैलवेयर डेवलपर्स अभी भी स्टेल्थ के लिए इस तकनीक का उपयोग कर सकते हैं, लेकिन अधिकार बढ़ाने के लिए इसका दुरुपयोग करने की संभावना बहुत कम है

सबसे पहले, यह अधिक सामान्य है कि MacOS बाइनरी लाइब्रेरी को लोड करने के लिए पूर्ण पथ इंगित करती हैं। और दूसरा, **MacOS कभी भी लाइब्रेरी के लिए $PATH के फ़ोल्डरों में खोज नहीं करता है।

इस कार्यक्षमता से संबंधित कोड का मुख्य भाग ImageLoader::recursiveLoadLibraries में है ImageLoader.cpp

एक macho बाइनरी लाइब्रेरी लोड करने के लिए 4 विभिन्न हेडर कमांड का उपयोग कर सकती है:

  • LC_LOAD_DYLIB कमांड एक dylib लोड करने के लिए सामान्य कमांड है।

  • LC_LOAD_WEAK_DYLIB कमांड पिछले वाले की तरह काम करता है, लेकिन यदि dylib नहीं पाया जाता है, तो निष्पादन बिना किसी त्रुटि के जारी रहता है।

  • LC_REEXPORT_DYLIB कमांड यह प्रतीक एक अलग लाइब्रेरी से प्रॉक्सी (या फिर से निर्यात) करता है।

  • LC_LOAD_UPWARD_DYLIB कमांड का उपयोग तब किया जाता है जब दो लाइब्रेरी एक-दूसरे पर निर्भर करती हैं (इसे upward dependency कहा जाता है)।

हालांकि, dylib हाइजैकिंग के 2 प्रकार हैं:

  • गायब कमजोर लिंक की गई लाइब्रेरी: इसका मतलब है कि एप्लिकेशन एक लाइब्रेरी लोड करने की कोशिश करेगा जो LC_LOAD_WEAK_DYLIB के साथ कॉन्फ़िगर की गई नहीं है। फिर, यदि एक हमलावर एक dylib को उस स्थान पर रखता है जहां इसे लोड करने की उम्मीद है

  • लिंक "कमजोर" होने का मतलब है कि एप्लिकेशन लाइब्रेरी नहीं मिलने पर भी चलना जारी रखेगा।

  • इस से संबंधित कोड ImageLoaderMachO::doGetDependentLibraries फ़ंक्शन में है ImageLoaderMachO.cpp जहां lib->required केवल तब false है जब LC_LOAD_WEAK_DYLIB सत्य है।

  • बाइनरी में कमजोर लिंक की गई लाइब्रेरी खोजें (आपके पास बाद में हाइजैकिंग लाइब्रेरी बनाने का एक उदाहरण है):

otool -l </path/to/bin> | grep LC_LOAD_WEAK_DYLIB -A 5 cmd LC_LOAD_WEAK_DYLIB cmdsize 56 name /var/tmp/lib/libUtl.1.dylib (offset 24) time stamp 2 Wed Jun 21 12:23:31 1969 current version 1.0.0 compatibility version 1.0.0

* **@rpath के साथ कॉन्फ़िगर किया गया**: Mach-O बाइनरी में **`LC_RPATH`** और **`LC_LOAD_DYLIB`** कमांड हो सकते हैं। उन कमांड के **मानों** के आधार पर, **लाइब्रेरी** **विभिन्न निर्देशिकाओं** से **लोड** की जाएगी।
* **`LC_RPATH`** में कुछ फ़ोल्डरों के पथ होते हैं जो बाइनरी द्वारा लाइब्रेरी लोड करने के लिए उपयोग किए जाते हैं।
* **`LC_LOAD_DYLIB`** में लोड करने के लिए विशिष्ट लाइब्रेरी का पथ होता है। ये पथ **`@rpath`** को शामिल कर सकते हैं, जिसे **`LC_RPATH`** में मानों द्वारा **बदल दिया जाएगा**। यदि **`LC_RPATH`** में कई पथ हैं, तो सभी का उपयोग लाइब्रेरी को लोड करने के लिए किया जाएगा। उदाहरण:
* यदि **`LC_LOAD_DYLIB`** में `@rpath/library.dylib` है और **`LC_RPATH`** में `/application/app.app/Contents/Framework/v1/` और `/application/app.app/Contents/Framework/v2/` है। दोनों फ़ोल्डर `library.dylib` को लोड करने के लिए उपयोग किए जाएंगे। यदि लाइब्रेरी `[...]/v1/` में मौजूद नहीं है और हमलावर इसे `[...]/v2/` में लोड करने के लिए रख सकता है क्योंकि **`LC_LOAD_DYLIB`** में पथों का क्रम अनुसरण किया जाता है।
* **बाइनरी में rpath पथ और लाइब्रेरी खोजें**: `otool -l </path/to/binary> | grep -E "LC_RPATH|LC_LOAD_DYLIB" -A 5`

<div data-gb-custom-block data-tag="hint" data-style='info'>

**`@executable_path`**: यह **मुख्य निष्पादन फ़ाइल** वाले निर्देशिका का **पथ** है।

**`@loader_path`**: यह **Mach-O बाइनरी** वाले **निर्देशिका** का **पथ** है जिसमें लोड कमांड होता है।

* जब इसे एक निष्पादन में उपयोग किया जाता है, तो **`@loader_path`** प्रभावी रूप से **`@executable_path`** के समान होता है।
* जब इसे एक **dylib** में उपयोग किया जाता है, तो **`@loader_path`** **dylib** का **पथ** देता है।

</div>

इस कार्यक्षमता का दुरुपयोग करके **अधिकार बढ़ाने** का तरीका तब होगा जब एक **एप्लिकेशन** जो **रूट** द्वारा **निष्पादित** किया जा रहा है, किसी **निर्देशिका में किसी लाइब्रेरी की तलाश कर रहा है जहां हमलावर के पास लिखने की अनुमति है।**

<div data-gb-custom-block data-tag="hint" data-style='success'>

एप्लिकेशनों में **गायब लाइब्रेरी** खोजने के लिए एक अच्छा **स्कैनर** [**Dylib Hijack Scanner**](https://objective-see.com/products/dhs.html) है या एक [**CLI संस्करण**](https://github.com/pandazheng/DylibHijack).\
इस तकनीक के बारे में तकनीकी विवरण के साथ एक अच्छा **रिपोर्ट** [**यहां**](https://www.virusbulletin.com/virusbulletin/2015/03/dylib-hijacking-os-x) पाया जा सकता है।

</div>

**उदाहरण**

<div data-gb-custom-block data-tag="content-ref" data-url='macos-dyld-hijacking-and-dyld_insert_libraries.md'>

[macos-dyld-hijacking-and-dyld\_insert\_libraries.md](macos-dyld-hijacking-and-dyld\_insert\_libraries.md)

</div>

## Dlopen Hijacking

<div data-gb-custom-block data-tag="hint" data-style='danger'>

याद रखें कि **पिछले लाइब्रेरी मान्यता प्रतिबंध भी लागू होते हैं** Dlopen हाइजैकिंग हमलों को करने के लिए।

</div>

**`man dlopen`** से:

* जब पथ **स्लैश वर्ण** नहीं रखता (यानी यह केवल एक पत्ते का नाम है), **dlopen() खोज करेगा**। यदि **`$DYLD_LIBRARY_PATH`** लॉन्च पर सेट किया गया था, तो dyld पहले उस निर्देशिका में **देखेगा**। अगला, यदि कॉलिंग mach-o फ़ाइल या मुख्य निष्पादन ने **`LC_RPATH`** निर्दिष्ट किया है, तो dyld उन निर्देशिकाओं में **देखेगा**। अगला, यदि प्रक्रिया **अप्रतिबंधित** है, तो dyld **वर्तमान कार्यशील निर्देशिका** में खोज करेगा। अंत में, पुराने बाइनरी के लिए, dyld कुछ फॉलबैक का प्रयास करेगा। यदि **`$DYLD_FALLBACK_LIBRARY_PATH`** लॉन्च पर सेट किया गया था, तो dyld उन निर्देशिकाओं में खोज करेगा, अन्यथा, dyld **`/usr/local/lib/`** में देखेगा (यदि प्रक्रिया अप्रतिबंधित है), और फिर **`/usr/lib/`** में (यह जानकारी **`man dlopen`** से ली गई थी)।
1. `$DYLD_LIBRARY_PATH`
2. `LC_RPATH`
3. `CWD`(यदि अप्रतिबंधित)
4. `$DYLD_FALLBACK_LIBRARY_PATH`
5. `/usr/local/lib/` (यदि अप्रतिबंधित)
6. `/usr/lib/`

<div data-gb-custom-block data-tag="hint" data-style='danger'>

यदि नाम में कोई स्लैश नहीं है, तो हाइजैकिंग करने के लिए 2 तरीके होंगे:

* यदि कोई **`LC_RPATH`** **लिखने योग्य** है (लेकिन हस्ताक्षर की जांच की जाती है, इसलिए इसके लिए आपको बाइनरी को भी अप्रतिबंधित होना चाहिए)
* यदि बाइनरी **अप्रतिबंधित** है और फिर CWD से कुछ लोड करना संभव है (या उल्लेखित env चर में से एक का दुरुपयोग करना)

</div>

* जब पथ **फ्रेमवर्क** पथ की तरह दिखता है (जैसे `/stuff/foo.framework/foo`), यदि **`$DYLD_FRAMEWORK_PATH`** लॉन्च पर सेट किया गया था, तो dyld पहले उस निर्देशिका में **फ्रेमवर्क आंशिक पथ** (जैसे `foo.framework/foo`) के लिए देखेगा। अगला, dyld **प्रदान किए गए पथ को जैसा है** (सापेक्ष पथों के लिए वर्तमान कार्यशील निर्देशिका का उपयोग करते हुए) का प्रयास करेगा। अंत में, पुराने बाइनरी के लिए, dyld कुछ फॉलबैक का प्रयास करेगा। यदि **`$DYLD_FALLBACK_FRAMEWORK_PATH`** लॉन्च पर सेट किया गया था, तो dyld उन निर्देशिकाओं में खोज करेगा। अन्यथा, यह **`/Library/Frameworks`** (macOS पर यदि प्रक्रिया अप्रतिबंधित है), फिर **`/System/Library/Frameworks`** में खोज करेगा।
1. `$DYLD_FRAMEWORK_PATH`
2. प्रदान किया गया पथ (यदि अप्रतिबंधित है तो सापेक्ष पथों के लिए वर्तमान कार्यशील निर्देशिका का उपयोग करना)
3. `$DYLD_FALLBACK_FRAMEWORK_PATH`
4. `/Library/Frameworks` (यदि अप्रतिबंधित)
5. `/System/Library/Frameworks`

<div data-gb-custom-block data-tag="hint" data-style='danger'>

यदि एक फ्रेमवर्क पथ है, तो इसे हाइजैक करने का तरीका होगा:

* यदि प्रक्रिया **अप्रतिबंधित** है, तो CWD से सापेक्ष पथ का दुरुपयोग करते हुए उल्लेखित env चर (यहां तक कि यदि यह दस्तावेज़ में नहीं कहा गया है यदि प्रक्रिया प्रतिबंधित है तो DYLD\_\* env vars हटा दिए जाते हैं)

</div>

* जब पथ **स्लैश रखता है लेकिन फ्रेमवर्क पथ नहीं है** (यानी एक पूर्ण पथ या dylib के लिए आंशिक पथ), dlopen() पहले (यदि सेट है) **`$DYLD_LIBRARY_PATH`** में देखता है (पथ से पत्ते का भाग)। अगला, dyld **प्रदान किए गए पथ का प्रयास करता है** (सापेक्ष पथों के लिए वर्तमान कार्यशील निर्देशिका का उपयोग करते हुए (लेकिन केवल अप्रतिबंधित प्रक्रियाओं के लिए))। अंत में, पुराने बाइनरी के लिए, dyld फॉलबैक का प्रयास करेगा। यदि **`$DYLD_FALLBACK_LIBRARY_PATH`** लॉन्च पर सेट किया गया था, तो dyld उन निर्देशिकाओं में खोज करेगा, अन्यथा, dyld **`/usr/local/lib/`** में देखेगा (यदि प्रक्रिया अप्रतिबंधित है), और फिर **`/usr/lib/`** में।
1. `$DYLD_LIBRARY_PATH`
2. प्रदान किया गया पथ (यदि अप्रतिबंधित है तो सापेक्ष पथों के लिए वर्तमान कार्यशील निर्देशिका का उपयोग करना)
3. `$DYLD_FALLBACK_LIBRARY_PATH`
4. `/usr/local/lib/` (यदि अप्रतिबंधित)
5. `/usr/lib/`

<div data-gb-custom-block data-tag="hint" data-style='danger'>

यदि नाम में स्लैश हैं और फ्रेमवर्क नहीं है, तो इसे हाइजैक करने का तरीका होगा:

* यदि बाइनरी **अप्रतिबंधित** है और फिर CWD या `/usr/local/lib` से कुछ लोड करना संभव है (या उल्लेखित env चर में से एक का दुरुपयोग करना)

</div>

<div data-gb-custom-block data-tag="hint" data-style='info'>

नोट: **dlopen खोज को नियंत्रित करने के लिए कोई** कॉन्फ़िगरेशन फ़ाइलें **नहीं हैं**।

नोट: यदि मुख्य निष्पादन **set\[ug]id बाइनरी या अधिकारों के साथ कोडसाइन** है, तो **सभी पर्यावरणीय चर अनदेखा कर दिए जाते हैं**, और केवल एक पूर्ण पथ का उपयोग किया जा सकता है ([DYLD\_INSERT\_LIBRARIES प्रतिबंधों की जांच करें](macos-dyld-hijacking-and-dyld\_insert\_libraries.md#check-dyld\_insert\_librery-restrictions) अधिक विस्तृत जानकारी के लिए)

नोट: Apple प्लेटफार्मों पर "यूनिवर्सल" फ़ाइलों का उपयोग 32-बिट और 64-बिट लाइब्रेरी को संयोजित करने के लिए किया जाता है। इसका मतलब है कि **कोई अलग 32-बिट और 64-बिट खोज पथ नहीं हैं**।

नोट: Apple प्लेटफार्मों पर अधिकांश OS dylibs **dyld कैश में संयोजित** होते हैं और डिस्क पर मौजूद नहीं होते हैं। इसलिए, यह जांचने के लिए **`stat()`** कॉल करना कि क्या कोई OS dylib मौजूद है **काम नहीं करेगा**। हालाँकि, **`dlopen_preflight()`** एक संगत mach-o फ़ाइल खोजने के लिए **`dlopen()`** के समान चरणों का उपयोग करता है।

</div>

**पथों की जांच करें**

आइए निम्नलिखित कोड के साथ सभी विकल्पों की जांच करें:
```c
// gcc dlopentest.c -o dlopentest -Wl,-rpath,/tmp/test
#include <dlfcn.h>
#include <stdio.h>

int main(void)
{
void* handle;

fprintf("--- No slash ---\n");
handle = dlopen("just_name_dlopentest.dylib",1);
if (!handle) {
fprintf(stderr, "Error loading: %s\n\n\n", dlerror());
}

fprintf("--- Relative framework ---\n");
handle = dlopen("a/framework/rel_framework_dlopentest.dylib",1);
if (!handle) {
fprintf(stderr, "Error loading: %s\n\n\n", dlerror());
}

fprintf("--- Abs framework ---\n");
handle = dlopen("/a/abs/framework/abs_framework_dlopentest.dylib",1);
if (!handle) {
fprintf(stderr, "Error loading: %s\n\n\n", dlerror());
}

fprintf("--- Relative Path ---\n");
handle = dlopen("a/folder/rel_folder_dlopentest.dylib",1);
if (!handle) {
fprintf(stderr, "Error loading: %s\n\n\n", dlerror());
}

fprintf("--- Abs Path ---\n");
handle = dlopen("/a/abs/folder/abs_folder_dlopentest.dylib",1);
if (!handle) {
fprintf(stderr, "Error loading: %s\n\n\n", dlerror());
}

return 0;
}

यदि आप इसे संकलित और निष्पादित करते हैं, तो आप देख सकते हैं कि प्रत्येक पुस्तकालय के लिए कहाँ असफलता से खोज की गई। इसके अलावा, आप FS लॉग को फ़िल्टर कर सकते हैं:

sudo fs_usage | grep "dlopentest"

Relative Path Hijacking

यदि एक privileged binary/app (जैसे SUID या कुछ बाइनरी जिसमें शक्तिशाली अधिकार हैं) एक सापेक्ष पथ लाइब्रेरी को लोड कर रहा है (उदाहरण के लिए @executable_path या @loader_path का उपयोग करके) और Library Validation अक्षम है, तो यह संभव हो सकता है कि बाइनरी को एक स्थान पर ले जाया जाए जहाँ हमलावर सापेक्ष पथ लोड की गई लाइब्रेरी को संशोधित कर सके, और इसे प्रक्रिया में कोड इंजेक्ट करने के लिए दुरुपयोग कर सके।

Prune DYLD_* और LD_LIBRARY_PATH env variables

फाइल dyld-dyld-832.7.1/src/dyld2.cpp में pruneEnvironmentVariables नामक फ़ंक्शन पाया जा सकता है, जो किसी भी env वेरिएबल को हटा देगा जो DYLD_ और LD_LIBRARY_PATH= से शुरू होता है

यह विशेष रूप से suid और sgid बाइनरी के लिए env वेरिएबल DYLD_FALLBACK_FRAMEWORK_PATH और DYLD_FALLBACK_LIBRARY_PATH को null पर सेट करेगा।

यह फ़ंक्शन उसी फ़ाइल के _main फ़ंक्शन से इस तरह से बुलाया जाता है यदि OSX को लक्षित किया गया हो:

#if TARGET_OS_OSX
if ( !gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache ) {
pruneEnvironmentVariables(envp, &apple);

और उन बूलियन फ्लैग्स को कोड में उसी फ़ाइल में सेट किया गया है:

#if TARGET_OS_OSX
// support chrooting from old kernel
bool isRestricted = false;
bool libraryValidation = false;
// any processes with setuid or setgid bit set or with __RESTRICT segment is restricted
if ( issetugid() || hasRestrictedSegment(mainExecutableMH) ) {
isRestricted = true;
}
bool usingSIP = (csr_check(CSR_ALLOW_TASK_FOR_PID) != 0);
uint32_t flags;
if ( csops(0, CS_OPS_STATUS, &flags, sizeof(flags)) != -1 ) {
// On OS X CS_RESTRICT means the program was signed with entitlements
if ( ((flags & CS_RESTRICT) == CS_RESTRICT) && usingSIP ) {
isRestricted = true;
}
// Library Validation loosens searching but requires everything to be code signed
if ( flags & CS_REQUIRE_LV ) {
isRestricted = false;
libraryValidation = true;
}
}
gLinkContext.allowAtPaths                = !isRestricted;
gLinkContext.allowEnvVarsPrint           = !isRestricted;
gLinkContext.allowEnvVarsPath            = !isRestricted;
gLinkContext.allowEnvVarsSharedCache     = !libraryValidation || !usingSIP;
gLinkContext.allowClassicFallbackPaths   = !isRestricted;
gLinkContext.allowInsertFailures         = false;
gLinkContext.allowInterposing         	 = true;

जो मूल रूप से यह मतलब है कि यदि बाइनरी suid या sgid है, या इसके हेडर में RESTRICT खंड है या इसे CS_RESTRICT ध्वज के साथ साइन किया गया है, तो !gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache सत्य है और env वेरिएबल्स को हटाया जाता है।

ध्यान दें कि यदि CS_REQUIRE_LV सत्य है, तो वेरिएबल्स को नहीं हटाया जाएगा लेकिन लाइब्रेरी मान्यता यह जांचेगी कि वे मूल बाइनरी के समान प्रमाणपत्र का उपयोग कर रहे हैं।

प्रतिबंधों की जांच करें

SUID & SGID

# Make it owned by root and suid
sudo chown root hello
sudo chmod +s hello
# Insert the library
DYLD_INSERT_LIBRARIES=inject.dylib ./hello

# Remove suid
sudo chmod -s hello

Section __RESTRICT with segment __restrict

gcc -sectcreate __RESTRICT __restrict /dev/null hello.c -o hello-restrict
DYLD_INSERT_LIBRARIES=inject.dylib ./hello-restrict

Hardened runtime

Keychain में एक नया प्रमाणपत्र बनाएं और इसका उपयोग बाइनरी पर हस्ताक्षर करने के लिए करें:

# Apply runtime proetction
codesign -s <cert-name> --option=runtime ./hello
DYLD_INSERT_LIBRARIES=inject.dylib ./hello #Library won't be injected

# Apply library validation
codesign -f -s <cert-name> --option=library ./hello
DYLD_INSERT_LIBRARIES=inject.dylib ./hello-signed #Will throw an error because signature of binary and library aren't signed by same cert (signs must be from a valid Apple-signed developer certificate)

# Sign it
## If the signature is from an unverified developer the injection will still work
## If it's from a verified developer, it won't
codesign -f -s <cert-name> inject.dylib
DYLD_INSERT_LIBRARIES=inject.dylib ./hello-signed

# Apply CS_RESTRICT protection
codesign -f -s <cert-name> --option=restrict hello-signed
DYLD_INSERT_LIBRARIES=inject.dylib ./hello-signed # Won't work

ध्यान दें कि भले ही कुछ बाइनरीज़ 0x0(none) फ्लैग के साथ साइन की गई हों, वे निष्पादित होने पर CS_RESTRICT फ्लैग को गतिशील रूप से प्राप्त कर सकती हैं और इसलिए यह तकनीक उन पर काम नहीं करेगी।

आप यह जांच सकते हैं कि किसी प्रक्रिया में यह फ्लैग है या नहीं (get csops here):

csops -status <pid>

और फिर जांचें कि फ्लैग 0x800 सक्षम है।

संदर्भ

HackTricks का समर्थन करें

Last updated