
Step-by-step technical analysis and exploit development for CVE-2017-9822, a critical RCE in DotNetNuke via insecure XML deserialization in the DNNPersonalization cookie. Includes environment setup, debug configuration with dnSpy, gadget chain construction (ObjectDataProvider, ResourceDictionary), and webshell upload.
DNN (जिसे DotNetNuke भी कहा जाता है) संस्करण 9.1.1 से पहले कुकी के माध्यम से रिमोट कोड निष्पादन में सक्षम है, जिसे '2017-08 (महत्वपूर्ण) DNN वेबसाइटों पर रिमोट कोड निष्पादन संभव' भी कहा जाता है।

DotNetNuke क्या है?
DotNetNuke एक मुफ़्त और ओपन-सोर्स वेब CMS (सामग्री प्रबंधन प्रणाली) है जो C# में लिखा गया है और .NET प्लेटफ़ॉर्म पर आधारित है। DotNetNuke इंटरनेट पर बहुत लोकप्रिय और व्यापक रूप से उपयोग किया जाता है क्योंकि आप बिना अधिक तकनीकी ज्ञान के कुछ ही मिनटों में DNN वेब संस्करण को तैनात कर सकते हैं। DotNetNuke की एक और महत्वपूर्ण विशेषता VB.NET या C# में निर्मित तृतीय-पक्ष कस्टम मॉड्यूल बनाने या आयात करने की क्षमता है।
DNN को Windows Server, IIS, ASP.NET और Windows के लिए SQL Server से युक्त स्टैक पर स्थापित किया जा सकता है। DNN ईमेल के माध्यम से नए उपयोगकर्ता पंजीकरण सत्यापन का भी समर्थन करता है, लेकिन इस सुरक्षा सुविधा के काम करने के लिए आपको एक वैध SMTP सर्वर कॉन्फ़िगर करने की आवश्यकता है।
DNN की मुख्य विशेषताएं
• मॉड्यूलर आर्किटेक्चर: DNN समुदाय द्वारा विकसित अतिरिक्त मॉड्यूल (कार्यात्मक मॉड्यूल) स्थापित करके आसान विस्तार की अनुमति देता है। प्रशासक एडमिन इंटरफ़ेस के माध्यम से नए मॉड्यूल अपलोड कर सकते हैं (.zip पैकेज अपलोड करके) या सीधे सर्वर पर निर्देशिका में निकाल सकते हैं।
• उपयोगकर्ता प्रशासन: सिस्टम पोर्टल और मॉड्यूल के लिए विस्तृत सुरक्षा और अनुमति (भूमिकाएँ/अनुमतियाँ) कार्यक्षमता प्रदान करता है। उपयोगकर्ता खाते, भूमिकाएँ और अनुमतियाँ DNN में केंद्रीय रूप से प्रबंधित की जाती हैं।
• सामग्री प्रबंधन: WYSIWYG संपादन, लेख, छवियाँ, दस्तावेज़ प्रबंधन का समर्थन करता है। इसमें वर्कफ़्लो/प्रकाशन प्रणाली (समीक्षा प्रक्रिया द्वारा पोस्टिंग) और सामग्री संस्करण नियंत्रण है। सामग्री एक साझा डेटाबेस (SQL Server) पर संग्रहीत की जाती है।
• API और विस्तार एकीकरण: DNN डेवलपर्स को कस्टम मॉड्यूल (WebForms, MVC, Razor) विकसित करने और बाहरी सेवाओं को एकीकृत करने के लिए .NET API प्रदान करता है। बड़ी संख्या में तृतीय-पक्ष पुस्तकालय उपलब्ध हैं (थीम, ई-कॉमर्स मॉड्यूल, फ़ोरम, आदि) जो कार्यक्षमता का विस्तार करने की अनुमति देते हैं।
• इंटरफ़ेस और थीम: स्किन (थीम) प्रणाली सामग्री को इंटरफ़ेस से अलग करती है, जो लचीला वेब डिज़ाइन की अनुमति देती है। DNN द्वारा बनाई गई वेबसाइटें स्किन बदलकर इंटरफ़ेस बदल सकती हैं।
• मॉड्यूल स्थापना तंत्र: DNN मॉड्यूल ZIP फ़ाइलों में पैक किए जाते हैं, इन्हें प्रशासन इंटरफ़ेस के माध्यम से या मैन्युअल रूप से निकालकर स्थापित किया जा सकता है। DNN संकलित मॉड्यूल (.NET DLL) और गतिशील Razor मॉड्यूल दोनों का समर्थन करता है; प्रत्येक मॉड्यूल को प्रति पृष्ठ अनुमति सेटिंग्स के माध्यम से एक्सेस दिया या रद्द किया जा सकता है।
ऑपरेटिंग सिस्टम: Windows 10
.NET Framework: 4.5.1+
वेब सर्वर: Microsoft IIS 10
डेटाबेस सर्वर: Microsoft® SQL Server® 2019 Express, SQL Server Management Studio
DotNetNuke संस्करण 9.1.0
इंटरनेट पर उपलब्ध DotNetNuke तैनाती संस्करणों को खोजने और website के आधार पर जाँचने के लिए निम्नलिखित Google dorks का उपयोग किया जा सकता है:
inurl:dnn.js
inurl:dnn.modalpopup.js
inurl:dnn.servicesframework.js
inurl:dnn.xml.js
inurl:dnncore.js
inurl:/Portals/0/
inurl:/DesktopModules/
inurl:/DNNCorp/
inurl:/DotNetNuke
inurl:/tabid//Default.aspx
inurl:/tabid//language/*/Default.aspx
intext:"by DNN Corp "
वातावरण बनाने के लिए इस लेख का अनुसरण किया जा सकता है
असेंबली गुणों को "डीबग करने योग्य" गुणों में बदलें, यह बहुत आवश्यक है क्योंकि रनटाइम के दौरान कुछ अनुकूलन लागू होंगे और अनजाने में हमारे डीबगिंग में बाधा उत्पन्न कर सकते हैं, कुछ ब्रेकपॉइंट हिट नहीं हो सकते या कुछ चर मौजूद नहीं होंगे।
DotNetNuke.dll को dnSpy (32 बिट) में लोड करें और Edit Assembly Attributes (C#) चुनें

पंक्ति को बदलें
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
से
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]

फिर Compile चुनें और इस मॉड्यूल को पुरानी स्थान पर सहेजें।
इसके बाद, व्यवस्थापक अधिकारों के साथ dnSpy लॉन्च करें और Debug -> Attach to Process चुनें

w3wp.exe प्रक्रिया चुनें

हमें इस प्रक्रिया को डीबग करने के लिए संलग्न करने का कारण यह है कि IIS पर वेब एप्लिकेशन आमतौर पर वर्कर प्रक्रियाओं का उपयोग करते हैं। वे प्रत्येक एप्लिकेशन पूल के लिए IIS वेब सर्वर पर आने वाले वेब अनुरोधों को संसाधित करने के लिए जिम्मेदार होते हैं, एक मशीन पर कई वर्कर प्रक्रियाएँ हो सकती हैं और सभी का सामान्य नाम w3wp.exe होता है। एक छोटा सा ध्यान देने वाली बात यह है कि कभी-कभी कोई w3wp प्रक्रिया नहीं चल रही होगी, IIS पहले वेब अनुरोध प्राप्त होने तक वर्कर प्रक्रियाएँ शुरू नहीं करेगा।

डीबगिंग पर वापस आते हुए, प्रक्रिया संलग्न करने के बाद अगला चुनें: Debug -> Windows -> Modules

एक मॉड्यूल पर क्लिक करें और Open All Modules चुनें

अब Assembly विंडो में हम सभी संबंधित मॉड्यूल देख सकते हैं

डिसीरियलाइज़ेशन बाइट स्ट्रीम की व्याख्या करने और उन्हें ऐसे डेटा में परिवर्तित करने की प्रक्रिया है जिसे एप्लिकेशन द्वारा निष्पादित किया जा सकता है।
डिसीरियलाइज़ेशन के साथ मुख्य समस्या यह है कि अधिकांश समय यह उपयोगकर्ता इनपुट डेटा का उपयोग कर सकता है। इसका मतलब है कि आप एप्लिकेशन के आवश्यक प्रारूप में दुर्भावनापूर्ण पेलोड सम्मिलित कर सकते हैं और तर्क में हेरफेर कर सकते हैं, डेटा का खुलासा कर सकते हैं या रिमोट कोड निष्पादित भी कर सकते हैं।
DotNetNuke अज्ञात उपयोगकर्ताओं के वैयक्तिकरण विकल्पों को संग्रहीत करने के लिए DNNPersonalization कुकी का उपयोग करता है (प्रमाणित उपयोगकर्ताओं के विकल्प उनके प्रोफ़ाइल पृष्ठ के माध्यम से संग्रहीत किए जाते हैं)। रिपोर्ट के अनुसार, यह दोष DNNPersonalization कुकी प्रसंस्करण में होता है, इस कुकी का उपयोग उपयोगकर्ता प्रोफ़ाइल लोड करने के लिए किया जाता है, हालांकि यह एक गैर-मौजूद पृष्ठ (404 त्रुटि) तक पहुँचने पर अप्रमाणित ट्रिगर भी कर सकता है। इस बग का प्रवेश बिंदु DotNetNuke.dll मॉड्यूल में LoadProfile फ़ंक्शन है, हम dnSpy का उपयोग करके इस मॉड्यूल को डीकंपाइल करेंगे और विस्तार से विश्लेषण करेंगे:
Tại PersonalizationController#LoadProfile(int, int)

यदि userId शून्य नहीं है तो चर text को request से DNNPersonalization कुकी का मान निर्दिष्ट किया जाएगा, फिर Globals#DeserializeHashTableXml को कॉल किया जाएगा

Globals#DeserializeHashTableXml XmlUtils#DeSerializeHashtable को कॉल करता है

प्रसंस्करण प्रक्रिया इस प्रकार है:
404 स्थिति + कुकी DNNPersonalization ट्रिगर करने के लिए burp का उपयोग करके अनुरोध भेजें

यहाँ देखा जा सकता है कि 404 को संभालने के लिए कॉल किया गया फ़ंक्शन Handler404OrException ने एक चैलेंज चेन को ट्रिगर किया और Personalization.LoadProfile(int,int) को कॉल किया।

उपरोक्त कोड में ध्यान देने योग्य बात यह है कि if शर्त जाँचती है कि वर्तमान अनुरोध पहले से IsAuthenticated है या नहीं, और स्पष्ट रूप से हमने अभी जो अनुरोध किया है वह एक गैर-मौजूद प्रवेश बिंदु के लिए अप्रमाणित है। तो वर्तमान अनुरोध को एक प्रमाणित उपयोगकर्ता के रूप में क्यों निष्पादित किया जा रहा है?
डीबगिंग जारी रखते हुए, स्टैक के अंत के पास वापस जाने पर AdvancedUrlRewriter#Handle404OrException पर निम्नलिखित else if लूप दिखाई देता है:

यहाँ यह जाँचता है कि वर्तमान अनुरोध context.User शून्य है या नहीं, यदि ऐसा है तो context.User को वर्तमान थ्रेड उपयोगकर्ता निर्दिष्ट करता है, ब्रेकपॉइंट सेट करके निम्नलिखित परिणाम देखा जा सकता है:

अब IsAuthenticated चर का मान true है और उपयोगकर्ता वर्तमान थ्रेड चलाने वाला उपयोगकर्ता है जो IIS सर्वर के IIS APPPOOL समूह से संबंधित है, इसलिए अनुरोध एक प्रमाणित उपयोगकर्ता के रूप में निष्पादित किया जाता है। इस तर्क के मौजूद होने का कारण यह है कि 404 हैंडलर को HttpContext.User सेट होने से पहले लागू किया जाता है और आगे की प्रक्रिया User.IsAuthenticated पर निर्भर करती है, इसलिए Null संदर्भ त्रुटियों से बचने के लिए, डेवलपर्स User ऑब्जेक्ट को वर्तमान थ्रेड के WindowsPrinicipal ऑब्जेक्ट से निर्दिष्ट करते हैं।
XmlSerializer Microsoft का अपना सीरियलाइज़ेशन वर्ग है, जिसका उपयोग स्ट्रिंग और xml ऑब्जेक्ट के बीच रूपांतरण के लिए किया जाता है। इसका नाम स्थान है: System.Xml.Serialization।
XmlSerializer उपयोग का उदाहरण:


XmlSerializer के माध्यम से RCE हमले की शर्त यह है कि XmlSerializer कंस्ट्रक्टर को पास किए गए डेटा प्रकार को नियंत्रित करना आवश्यक है। अर्थात्, गैजेट की ओर ले जाने वाले डेटा प्रकारों को XmlSerializer.mapping गुण में पास किया जाना चाहिए।
xml डिसीरियलाइज़ हमले के लिए सबसे सामान्य गैजेट ObjectDataProvider है। यह गैजेट ysoserrial .net टूल द्वारा बनाया जा सकता है।
मूल रूप से इस वर्ग का उपयोग करते समय, हम किसी भी वर्ग की किसी भी विधि को कॉल कर सकते हैं।

उदाहरण के लिए हम नीचे दिए गए मापदंडों के साथ Process.Start को कॉल कर सकते हैं:
ObjectDataProvider o = new ObjectDataProvider(); o.MethodParameters.Add("cmd.exe"); o.MethodParameters.Add("/c calc"); o.MethodName = "Start"; o.ObjectInstance = new Process(); Console.ReadKey();
उपरोक्त कोड के साथ एक xml डिसीरियलाइज़ पेलोड बनाएँ:


ResourceDictionary wpf विकास के लिए उपयोग किया जाता है, चूंकि यह wpf है, इसलिए इसे xaml भाषा का उपयोग करना होगा। पहले आइए एक पेलोड देखें जो कमांड निष्पादित करने के लिए ResourceDictionary का उपयोग करता है।
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:b="clr-namespace:System;assembly=mscorlib" xmlns:c="clr-namespace:System.Diagnostics;assembly=system"> <ObjectDataProvider d:Key="" ObjectType="{d:Type c:Process}" MethodName="Start"> <ObjectDataProvider.MethodParameters> <b:String>cmd</b:String> <b:String>/c calc</b:String> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> </ResourceDictionary>
इस xaml की व्याख्या:

उपरोक्त कोड का निष्पादन ObjectDataProvider -> Person.Evil() के समतुल्य है। यदि XmlSerializer के माध्यम से RCE हमला किया जाता है, तो प्रवाह इस प्रकार दिखेगा: ObjectDataProvider -> XamlReader.Parse() -> ObjectDataProvider -> System.Diagnostics.Process.Start("cmd.exe","/c calc")
अब लक्ष्य एक ऐसा ऑब्जेक्ट ढूँढ़ना है जो डिसीरियलाइज़ करने पर कोड निष्पादित कर सके। POC में, "मनमाना फ़ाइल अपलोड" का शोषण करने के लिए DotNetNuke.Common.Utilities.FileSystemUtils के PullFile फ़ंक्शन का उपयोग किया जाता है।


हमें obj.xml मिला:

पेलोड भेजें


DNN द्वारा कुकीज़ को डिसीरियलाइज़ करने के बाद, http सर्वर पर /cmd.aspx का अनुरोध होता है, अर्थात डिसीरियलाइज़ेशन सफल हुआ, वेबशेल DNN पर अपलोड हो गया।

इसी प्रकार फ़ाइल पढ़ने के लिए DotNetNuke.Common.Utilities.FileSystemUtils के WriteFile फ़ंक्शन का लाभ उठाएँ

