
إثبات المفهوم لـ CVE-2021-28476، وهو إلغاء مرجعية مؤشر عشوائي في Hyper-V vmswitch.sys يسمح بحرمان الخدمة من الضيف إلى المضيف واحتمال تنفيذ التعليمات البرمجية عن بُعد (RCE).
يمكن لجهاز افتراضي ضيف في Hyper-V أن يتسبب في حالة حرمان من الخدمة (Denial-of-Service) على المضيف الأساسي بسبب تحليل غير آمن للإدخال بواسطة دالة VmsIfrInfoParams_OID_SWITCH_NIC_REQUEST في vmswitch.sys. يحدث الانهيار عندما تحاول الدالة إلغاء مرجع قيمة يتحكم بها الضيف كما لو كانت عنوانًا افتراضيًا للمضيف. قد يُستخدم هذا الخطأ للحصول على تنفيذ تعليمات برمجية عن بُعد (RCE) في بعض الظروف، وتحديدًا عندما يتم تمرير الطلب إلى جهاز أجهزة أساسي مع مؤشر إلى بيانات يتحكم بها المهاجم، ومع ذلك لست على علم بأن هذه التقنية تم إثباتها علنًا.
11 مايو 2021
https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-28476
إلغاء مرجع عشوائي (Arbitrary Dereference)
هندسة عكسية/تدقيق برمجي
تم العثور على هذا الخطأ أثناء الاستطلاع الأولي لبرنامج تشغيل 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، تم تصميم هذا الطلب للسماح بإعادة توجيه طلبات OID من جهاز ضيف إلى محول شبكة فعلي أساسي عبر محول الشبكة الخارجي لمفتاح Hyper-V القابل للتوسعة.
تستخدم طلبات OID بنية رسائل عامة ومعرفة جيدًا لطبقتها الخارجية، والتي تتضمن "InformationBuffer" مصممًا لاحتواء بيانات خاصة بنوع رسالة OID. في حالة OID_SWITCH_NIC_REQUEST، يكون تعريف InformationBuffer كما يلي (لاحظ أن هذا يختلف قليلاً عن البنية الموثقة، لكنه يطابق ما كان موجودًا وظيفيًا في الكود):
typedef struct _NDIS_SWITCH_NIC_OID_REQUEST {
NDIS_OBJECT_HEADER Header; //u32 sized struct
u32 Flags;
NDIS_SWITCH_PORT_ID SourcePortId; //u32 type
NDIS_SWITCH_PORT_NIC SourceNicIndex; //u32 type
NDIS_SWITCH_PORT_ID DestinationPortId; //u32 type
NDIS_SWITCH_PORT_NIC DestinationNicIndex; //u32 type
PNDIS_OID_REQUEST OidRequest; //**should** be a pointer to a forwarded NDIS_OID_REQUEST structure
} NDIS_SWITCH_NIC_OID_REQUEST, *PNDIS_SWITCH_NIC_OID_REQUEST;
كجزء من التحليل الأولي لهذا الكائن، ستحاول VmsIfrInfoParams_OID_SWITCH_NIC_REQUEST فك تغليف طلب NDIS_OID_REQUEST المُعاد توجيهه من البنية المغلفة _NDIS_SWITCH_NIC_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; //dereference and crash occurs here
}
}
...
//truncated
...
return;
}