
CVE-2021-28476 के लिए प्रूफ-ऑफ-कॉन्सेप्ट, एक Hyper-V vmswitch.sys मनमाना पॉइंटर डीरेफरेंस जो गेस्ट-टू-होस्ट डिनायल-ऑफ-सर्विस और संभावित RCE की अनुमति देता है।
एक Hyper-V गेस्ट वर्चुअल मशीन vmswitch.sys में VmsIfrInfoParams_OID_SWITCH_NIC_REQUEST फ़ंक्शन द्वारा इनपुट के असुरक्षित पार्सिंग के कारण अपने अंतर्निहित होस्ट पर Denial-of-Service स्थिति उत्पन्न कर सकती है। क्रैश फ़ंक्शन द्वारा गेस्ट-नियंत्रित मान को होस्ट वर्चुअल एड्रेस के रूप में डीरेफरेंस करने के प्रयास के कारण होता है। यह बग कुछ शर्तों के तहत RCE प्राप्त करने के लिए उपयोग किया जा सकता है, विशेष रूप से जहां अनुरोध अंतर्निहित हार्डवेयर डिवाइस को हमलावर-नियंत्रित डेटा के पॉइंटर के साथ पास किया जाता है, हालांकि मुझे इस तकनीक के सार्वजनिक रूप से प्रदर्शित होने की जानकारी नहीं है।
11 मई, 2021
https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-28476
अमान्य डीरेफरेंस
रिवर्स इंजीनियरिंग/कोड ऑडिटिंग
यह बग vmswitch ड्राइवर के मेरे प्रारंभिक टोही के दौरान पाया गया था। MSDN पर दस्तावेज़ीकरण की समीक्षा करते समय यह नोट किया गया कि NDIS_SWITCH_NIC_OID_REQUEST संरचना में एक पॉइंटर था, और मुझे एक फ़ंक्शन नाम में संरचना नाम का संदर्भ देखना याद आया। कुछ रिवर्स इंजीनियरिंग यह समझने के लिए की गई थी कि फ़ंक्शन कैसे काम कर सकता है, यह देखते हुए कि गेस्ट को होस्ट VA का कोई ज्ञान नहीं होना चाहिए लेकिन कोई वास्तविक सुरक्षा जांच मौजूद नहीं थी। फिर एक संशोधित Linux Hyper-V ड्राइवर का उपयोग होस्ट को नकली अनुरोध भेजने के लिए किया गया, जिससे तुरंत क्रैश हो गया।
vmswitch.sys ड्राइवर में RNDIS OID अनुरोधों को संभालने के लिए कई फ़ंक्शन शामिल हैं, जिनमें कुछ विशेष रूप से आने वाले संदेशों को लॉग करने के लिए हैं। इनमें से एक VmsIfrInfoParams_OID_SWITCH_NIC_REQUEST, OID_SWITCH_NIC_REQUEST प्रकार के अनुरोधों को संभालता है। MSDN दस्तावेज़ीकरण के अनुसार, यह अनुरोध Hyper-V एक्स्टेंसिबल स्विच बाहरी नेटवर्क एडाप्टर के माध्यम से गेस्ट मशीन से अंतर्निहित भौतिक नेटवर्क एडाप्टर तक OID अनुरोधों को अग्रेषित करने की अनुमति देने के लिए डिज़ाइन किया गया है।
OID अनुरोध अपनी बाहरी परत के लिए एक अच्छी तरह से परिभाषित, सामान्य संदेश संरचना का उपयोग करते हैं, जिसमें एक "InformationBuffer" शामिल होता है जो किसी OID संदेश प्रकार के लिए विशिष्ट डेटा रखने के लिए डिज़ाइन किया गया है। OID_SWITCH_NIC_REQUEST के मामले में, InformationBuffer की निम्नलिखित परिभाषा है (ध्यान दें कि यह दस्तावेज़ित संरचना से थोड़ा भिन्न है, लेकिन कोड में कार्यात्मक रूप से मौजूद चीज़ों से मेल खाता है):
typedef struct _NDIS_SWITCH_NIC_OID_REQUEST {
NDIS_OBJECT_HEADER Header; //u32 आकार की संरचना
u32 Flags;
NDIS_SWITCH_PORT_ID SourcePortId; //u32 प्रकार
NDIS_SWITCH_PORT_NIC SourceNicIndex; //u32 प्रकार
NDIS_SWITCH_PORT_ID DestinationPortId; //u32 प्रकार
NDIS_SWITCH_PORT_NIC DestinationNicIndex; //u32 प्रकार
PNDIS_OID_REQUEST OidRequest; //**होना चाहिए** अग्रेषित NDIS_OID_REQUEST संरचना के लिए एक पॉइंटर
} NDIS_SWITCH_NIC_OID_REQUEST, *PNDIS_SWITCH_NIC_OID_REQUEST;
इस ऑब्जेक्ट के प्रारंभिक पार्सिंग के भाग के रूप में, VmsIfrInfoParams_OID_SWITCH_NIC_REQUEST एनकैप्सुलेटिंग _NDIS_SWITCH_NIC_OID_REQUEST से अग्रेषित NDIS_OID_REQUEST अनुरोध को अनरैप करने का प्रयास करेगा। हालांकि, यदि कोई Hyper-V गेस्ट OidRequest मान के रूप में एक अमान्य मेमोरी स्थान प्रदान करता है, तो डीरेफरेंस आउट-ऑफ-बाउंड रीड का कारण बनेगा और रूट पार्टीशन कर्नेल को क्रैश कर देगा।
प्रभावित फ़ंक्शन का स्यूडो-कोड इस प्रकार है:
void VmsIfrInfoParams_OID_SWITCH_NIC_REQUEST(void* unknown1, u64 unknown2, _NDIS_SWITCH_NIC_OID_REQUEST* request, u32 buffer_size) {
NDIS_OID_REQUEST* forwarded_request;
if((unknown1 != 0) && (buffer_size != 0)) {
if(buffer_size > 0x20) {
forwarded_request = (NDIS_OID_REQUEST*)request->OidRequest; //डीरेफरेंस और क्रैश यहां होता है
}
}
...
//छोटा किया गया
...
return;
}