
आधुनिक सुरक्षा उत्पाद (CrowdStrike, Bitdefender, SentinelOne आदि) nLoadImage फंक्शन को clr.dll के अंदर हुक (hook) करते हैं ताकि इन-मेमोरी .NET असेंबली लोड को इंटरसेप्ट और स्कैन कर सकें। यह टूल उस फंक्शन को अनहुक (unhook) करता है।
एक मूल C++ उपयोगिता जो .NET सामान्य भाषा रनटाइम में EDR/AV हुक को बायपास करने के लिए मूल nLoadImage फ़ंक्शन कार्यान्वयन को पुनर्स्थापित करती है।
यह उपकरण CLR के nLoadImage फ़ंक्शन से सुरक्षा उत्पाद हुक हटाता है - महत्वपूर्ण देशी प्रवेश बिंदु जो सभी इन-मेमोरी .NET असेंबली लोडिंग को संभालता है। डिस्क से स्वच्छ clr.dll पढ़कर और मेमोरी में हुक किए गए फ़ंक्शन बाइट्स को अधिलेखित करके, यह मूल CLR व्यवहार को पुनर्स्थापित करता है, जिससे Assembly.Load(byte[]) EDR निरीक्षण या स्कैनिंग के बिना निष्पादित हो सकता है।
आधुनिक सुरक्षा उत्पाद (BitDefender, CrowdStrike, SentinelOne, आदि) clr.dll के अंदर nLoadImage फ़ंक्शन को इंटरसेप्ट और स्कैन करने के लिए हुक करते हैं। यह उपकरण उस फ़ंक्शन को अनहुक करता है:
clr.dll पढ़नाnLoadImage बाइट्स ढूँढनाअनहुक करने के बाद, Assembly.Load(byte[]) EDR निरीक्षण के बिना निष्पादित होता है।
nLoadImage महत्वपूर्ण देशी फ़ंक्शन है जो .NET रनटाइम में सभी इन-मेमोरी असेंबली लोडिंग को संभालता है। इसे प्रबंधित कोड में InternalCall के रूप में घोषित किया गया है, जिसका अर्थ है कि इसका कोई C# कार्यान्वयन नहीं है - इसके बजाय, यह देशी CLR कोड का सीधा सेतु है।
कॉल चेन:
प्रबंधित कोड (C#)
↓
Assembly.Load(byte[])
↓
RuntimeAssembly.nLoadImage(...) [InternalCall - कोई प्रबंधित निकाय नहीं]
↓
clr.dll!AssemblyNative::LoadImage (मूल C++ कार्यान्वयन)
↓
असेंबली AppDomain में लोड हो गई
यह महत्वपूर्ण क्यों है:
लगभग हर इन-मेमोरी असेंबली लोड nLoadImage से होकर गुज़रता है। Assembly.Load(byte[]) विधि और इसके ओवरलोड (प्रतीक बाइट्स के साथ लोडिंग सहित) सभी पर्दे के पीछे nLoadImage को आमंत्रित करते हैं। जब आप Assembly.Load(byte[]) कॉल करते हैं, तो mscorlib.dll में प्रबंधित कोड आपकी बाइट सरणी को RuntimeAssembly.nLoadImage() के माध्यम से पास करता है, जो [MethodImpl(MethodImplOptions.InternalCall)] से चिह्नित है - जिसका अर्थ है कि C# में इसका निकाय खाली है और निष्पादन तुरंत देशी CLR कोड पर कूद जाता है।
यहां तक कि गतिशील कोड निर्माण परिदृश्य - सीरियलाइज़ेशन फ्रेमवर्क जो रनटाइम पर असेंबली उत्सर्जित करते हैं, XML सीरियलाइज़र जनरेशन, और रेड टीम टूल जैसे कि Cobalt Strike का execute-assembly - सभी इस एकल फ़ंक्शन के माध्यम से चैनल होते हैं।
मूल कार्यान्वयन:
mscorlib.dll में nLoadImage InternalCall स्टब clr.dll के अंदर मूल C++ फ़ंक्शन AssemblyNative::LoadImage को इंगित करता है। यह फ़ंक्शन:
.NET फ्रेमवर्क 4.8+ में, प्रत्येक nLoadImage कॉल स्वचालित रूप से असेंबली बाइट्स को निष्पादन से पहले स्कैन करने के लिए Windows Defender के AMSI (AmsiScanBuffer) को पास करता है, जिससे यह सुरक्षा उत्पादों के लिए एक महत्वपूर्ण चोकपॉइंट बन जाता है।
फ़ंक्शन हस्ताक्षर (.NET फ्रेमवर्क 4.7+):
[MethodImpl(MethodImplOptions.InternalCall)]
static internal extern Assembly nLoadImage(
byte[] rawAssembly, // PE bytes
byte[] rawSymbolStore, // Optional PDB bytes
Evidence evidence, // CAS evidence (obsolete)
ref StackCrawlMark stackMark, // Security stack marker
bool fIntrospection, // Reflection-only flag
bool fSkipIntegrityCheck, // Skip integrity validation
SecurityContextSource securityContextSource // Security context
);
जब आप Assembly.Load(byte[]) कॉल करते हैं, तो यह इन विशिष्ट पैरामीटरों के साथ nLoadImage को आमंत्रित करता है:
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return RuntimeAssembly.nLoadImage(
rawAssembly, // आपकी बाइट सरणी
null, // rawSymbolStore
null, // evidence
ref stackMark, // LookForMyCaller
false, // fIntrospection
SecurityContextSource.CurrentAssembly // securityContextSource
);
fIntrospection पैरामीटर नियंत्रित करता है कि असेंबली निष्पादन के लिए (false) या केवल रिफ्लेक्शन-ओनली निरीक्षण के लिए (true) लोड की गई है या नहीं। Assembly.ReflectionOnlyLoad(byte[]) विधि nLoadImage को fIntrospection=true के साथ कॉल करती है, जिससे कोड निष्पादन के बिना मेटाडेटा परीक्षा संभव होती है।
EDR इसे क्यों हुक करता है:
चूँकि nLoadImage सभी इन-मेमोरी असेंबली लोड के लिए एकल प्रवेश बिंदु है, EDR उत्पाद इसे मूल स्तर पर clr.dll में हुक करते हैं। यह उन्हें अनुमति देता है:
पारंपरिक बाइपास (AMSI पैचिंग, ETW अक्षम करना) CLR-स्तरीय हुक को प्रभावित नहीं करते क्योंकि वे स्टैक में उच्च स्तर पर काम करते हैं। हुक CLR के अंदर ही होता है, AMSI को आमंत्रित करने से पहले।
CLRUnhook.exe
वर्तमान प्रक्रिया में CLR को अनहुक करता है। नोट: यह तभी काम करता है जब CLR पहले से लोड हो (यानी, .NET एप्लिकेशन से चल रहा हो या CLR को मैन्युअल रूप से लोड करने के बाद)।
CLRUnhook.exe powershell.exe
CLRUnhook.exe 1234
दूरस्थ प्रक्रिया में CLR को अनहुक करता है।
=== CLR अनहुकिंग टूल ===
[*] मोड -> दूरस्थ प्रक्रिया अनहुकिंग
[*] लक्ष्य -> पीआईडी 21436
[+] पीआईडी मिला -> 21436
[*] दूरस्थ प्रक्रिया में CLR->nLoadImage अनहुक कर रहा है...
[DEBUG] दूरस्थ मोड सक्षम
[DEBUG] clr.dll 0x00007FFD38CB0000 पर मिला
[DEBUG] CLR पथ -> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
[DEBUG] CLR मॉड्यूल आकार -> 10108928 बाइट्स
[DEBUG] दूरस्थ प्रक्रिया से 10108928 बाइट्स पढ़े गए
[DEBUG] मॉड्यूल में 'nLoadImage' खोज रहा है (आकार: 10108928)
[DEBUG] दूरस्थ आधार पता: 0x00007FFD38CB0000
[DEBUG] स्ट्रिंग 'nLoadImage' (11 बाइट्स) के लिए स्कैन कर रहा है...
[DEBUG] RVA 0x7c12b8 पर स्ट्रिंग मिली
[DEBUG] दूरस्थ पॉइंटर खोज रहा है: 0x7ffd394712b8
[DEBUG] ऑफसेट 0x7a4340 पर पॉइंटर मिला
[DEBUG] RVA 0x5e4f30 पर मान्य फ़ंक्शन पॉइंटर मिला
[DEBUG] RVA 0x00000000005E4F30 पर nLoadImage मिला
[DEBUG] हुक किया गया फ़ंक्शन पता -> 0x00007FFD39294F30
[DEBUG] डिस्क फ़ाइल में ऑफसेट 0x00000000005E4F30 पर स्वच्छ फ़ंक्शन
[DEBUG] पैच से पहले हुक किए गए बाइट्स पढ़ रहा है...
[DEBUG] अनहुक करने से पहले पहले 16 बाइट्स:
4C 8B DC 49 89 5B 08 49 89 73 10 4D 89 4B 20 57
[DEBUG] डिस्क से स्वच्छ बाइट्स:
8B 4B 78 E8 88 A9 EA FF C6 44 24 28 00 80 3D A4
[DEBUG] 30 बाइट्स सफलतापूर्वक लिखे गए
[DEBUG] अनहुक करने के बाद पहले 16 बाइट्स:
8B 4B 78 E8 88 A9 EA FF C6 44 24 28 00 80 3D A4
[DEBUG] सत्यापन सफल: पैच किए गए बाइट्स स्वच्छ बाइट्स से मेल खाते हैं!
[+] सफलता -> दूरस्थ प्रक्रिया में CLR nLoadImage अनहुक हो गया!
[+] EDR/AV हुक बायपास हो गए
[*] बाहर निकलने के लिए Enter दबाएं...
प्रबंधित कोड (C#)
↓
Assembly.Load(byte[])
↓
RuntimeAssembly.nLoadImage(...) [InternalCall]
↓
clr.dll!AssemblyNative::LoadImage
↓
[EDR हुक] ← हम इसे बायपास करते हैं
↓
मूल CLR कोड
clr.dll में nLoadImage ढूँढता है (वर्तमान में हुक किया हुआ)C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ से मूल clr.dll पढ़ता हैnLoadImage का पता लगाने के लिए पैटर्न स्कैनिंग का उपयोग करता है:
तकनीक अनुसंधान:
कार्यान्वयन:
केवल शैक्षिक और अधिकृत सुरक्षा अनुसंधान के लिए।
सुरक्षा नियंत्रणों को बायपास करने के लिए इस उपकरण का अनधिकृत उपयोग कंप्यूटर धोखाधड़ी कानूनों (CFAA, समकक्ष क़ानून) का उल्लंघन कर सकता है। केवल उन सिस्टम पर उपयोग करें जिनके आप मालिक हैं या जिनके परीक्षण के लिए आपके पास स्पष्ट लिखित अनुमति है।