أمان DHCP في نظام التشغيل Windows 10: استكشاف ثغرة أمنية حرجة CVE-2019-0726



الصورة: Pexels

مع إصدار تحديثات كانون الثاني (يناير) لنظام التشغيل Windows ، أثارت أنباء الثغرة الخطيرة الخطيرة CVE-2019-0547 في عملاء DHCP الجمهور. إن ارتفاع تصنيف CVSS وحقيقة أن Microsoft لم تنشر على الفور تقييمًا للأداء ، مما جعل من الصعب على المستخدمين اتخاذ قرار بشأن تحديث عاجل للنظام ، زاد الاهتمام. حتى أن بعض المنشورات اقترحت أن عدم وجود فهرس يمكن تفسيره كدليل على أن استغلال العمل سوف يظهر في المستقبل القريب.

يمكن للحلول مثل MaxPatrol 8 التعرف على أجهزة الكمبيوتر على الشبكة المعرضة لهجمات معينة. تقوم حلول أخرى ، مثل PT NAD ، باكتشاف مثل هذه الهجمات بنفسها. لجعل هذا ممكنًا ، من الضروري وصف كل من قواعد اكتشاف نقاط الضعف في المنتجات وقواعد اكتشاف الهجمات على هذه المنتجات. بدوره ، لكي يصبح هذا ممكنًا ، من الضروري لكل نقطة ضعف فردية أن تعرف المتجه وطريقة وظروف تشغيله ، أي حرفيًا كل التفاصيل والفروق الدقيقة المرتبطة بالعملية. مطلوب فهم أكثر اكتمالا وأعمق بكثير مما يمكن تجميعه عادة من الأوصاف على مواقع البائعين أو في CVE ، مثل:

تظهر مشكلة عدم الحصانة لأن نظام التشغيل يعالج الكائنات الموجودة في الذاكرة بشكل غير صحيح.

لذلك ، لإضافة منتجات الشركة إلى قواعد الكشف عن الهجمات على ثغرة أمنية جديدة في DHCP ، وكذلك قواعد تحديد الأجهزة المتأثرة بها ، يجب أن تفهم التفاصيل. في حالة الثغرات الأمنية الثنائية ، غالبًا ما يتم استخدام patch-diff لاكتساب نظرة ثاقبة على الأخطاء الأساسية ، أي مقارنة التغييرات التي تم إجراؤها على الكود الثنائي لتطبيق أو مكتبة أو نواة نظام التشغيل مع تصحيح محدد ، وهو تحديث يعمل على إصلاح هذا الخطأ. ولكن المرحلة الأولى هي دائما استطلاع.

ملاحظة : للانتقال مباشرة إلى وصف الثغرة الأمنية ، وتجاوز مفاهيم DHCP الأساسية ، يمكنك تخطي الصفحات القليلة الأولى والانتقال مباشرة إلى قسم "DecodeDomainSearchListData Function".

استطلاع


ننتقل إلى محرك البحث وعرض جميع تفاصيل الضعف المعروفة حاليا. هذه المرة يوجد حد أدنى من التفاصيل ، وكلها عبارة عن مواكب مجانية للمعلومات التي يتم جمعها من المنشور الأصلي على موقع MSRC. هذا الموقف مثالي تمامًا للأخطاء التي اكتشفتها Microsoft أثناء التدقيق الداخلي.

لقد اكتشفنا من المنشور أننا نواجه مشكلة عدم حصانة تلف الذاكرة ، الموجودة في كل من أنظمة العميل والخادم الخاصة بنظام التشغيل Windows 10 ، الإصدار 1803 وتظهر في الوقت الذي يرسل فيه مهاجم ردودًا مصممة خصيصًا إلى عميل DHCP. بعد يومين من تلك اللحظة على الصفحة ، ستظهر مؤشرات الأداء أيضًا:



كما ترون ، صنفت MSRC "2 - استغلال أقل احتمالا". هذا يعني أن الخطأ ذو الاحتمالية العالية إما أنه لا يعمل على الإطلاق ، أو أن العملية محفوفة بمثل هذه الصعوبات ، التي يتطلب التغلب عليها تكاليف عمل مرتفعة للغاية. من المسلم به أن Microsoft لا تميل إلى التقليل من شأن هذه التقديرات. يتأثر هذا جزئيًا بمخاطر فقدان السمعة ، وجزئيًا ببعض الاستقلال لمركز الاستجابة داخل الشركة. لذلك ، لنفترض: نظرًا لأن التهديد بالاستغلال مبين في التقرير على أنه غير مرجح ، فمن المؤكد أنه كذلك. في الواقع ، قد يكون هذا قد أكمل التحليل ، ولكن لن يكون من الضروري التحقق من ضعفه على الأقل ومعرفة ماهية الثغرة الأمنية. في النهاية ، على الرغم من كل الشخصية التي لا يمكن إنكارها ، فإن الأخطاء تميل إلى تكرار نفسها وإظهار نفسها في أماكن أخرى.

من نفس الصفحة ، قمنا بتنزيل التصحيح (تحديث أمني) المقدم في شكل أرشيف .msu ، وقم بفك حزمه والبحث عن الملفات التي من المرجح أن تكون مرتبطة بمعالجة استجابات DHCP من جانب العميل. في الآونة الأخيرة ، أصبح القيام بذلك أكثر صعوبة ، حيث بدأت التحديثات يتم تسليمها ليس في شكل حزم منفصلة تعمل على إصلاح أخطاء معينة ، ولكن كحزمة تراكمية واحدة تتضمن جميع التصحيحات الشهرية. أدى هذا إلى زيادة كبيرة في الضوضاء الزائدة ، أي التغييرات التي لا تتعلق بمهمتنا.

من بين مجموعة الملفات بأكملها ، يعثر البحث على عدة مكتبات مناسبة للمرشح ، والتي نقارنها بإصداراتها على نظام غير متطابق. تبدو مكتبة dhcpcore.dll الأكثر واعدة. في هذه الحالة ، ينتج BinDiff تغييرات بسيطة:



في الواقع ، بخلاف التغييرات التجميلية التي أدخلت على وظيفة واحدة - DecodeDomainSearchListData. إذا كنت على دراية جيدة ببروتوكول DHCP والخيارات التي لا تستخدمها كثيرًا ، فيمكنك افتراض أن هذه الوظيفة تعالج القائمة. إذا لم يكن كذلك ، فانتقل إلى المرحلة الثانية - دراسة البروتوكول.

DHCP وخياراتها


يعد DHCP ( RFC 2131 | wiki ) بروتوكولًا موسعًا ويتم توفير إمكانات التجديد بواسطة حقل الخيارات. يتم وصف كل خيار بواسطة علامة فريدة (الرقم ، المعرف) ، والحجم الذي تشغله البيانات الموجودة في الخيار ، والبيانات نفسها. هذه الممارسة نموذجية لبروتوكولات الشبكة ، وأحد الخيارات "المزروعة" في البروتوكول هو خيار البحث عن المجال الموصوف في RFC 3397 . يسمح لخادم DHCP بتعيين نهايات اسم المجال القياسية على العملاء ، والتي سيتم استخدامها لاحقات DNS للاتصال الذي تم تكوينه بهذه الطريقة.

دعونا ، على سبيل المثال ، تم تعيين نهايات الاسم التالية على عميلنا:

.microsoft.com .wikipedia.org 



بعد ذلك ، في أي محاولة لتحديد العنوان حسب اسم المجال ، ستحل استعلامات DNS محل اللواحق من هذه القائمة بدورها حتى يتم العثور على عرض ناجح. على سبيل المثال ، إذا قام المستخدم بإدخال ru في شريط عنوان المتصفح ، فسيتم إنشاء استعلامات DNS أولاً لـ ru.microsoft.com ، ثم لـ ru.wikipedia.org:



في الواقع ، المتصفحات الحديثة ذكية جدًا ، وبالتالي تستجيب لعمليات إعادة التوجيه إلى محرك البحث لأسماء لا تشبه FQDN. لذلك ، نرفق أدناه استنتاج الأدوات المساعدة الأقل فسادًا:



قد يبدو للقارئ أن هذه هي الثغرة الأمنية ، لأن القدرة على استبدال لواحق DNS باستخدام خادم DHCP ، والذي يمكن لأي جهاز على الشبكة التعرف عليه ، يشكل تهديدًا للعملاء الذين يطلبون أي معلمات شبكة عبر DHCP . لكن لا: على النحو التالي من RFC ، يعتبر هذا سلوكًا قانونيًا وموثقًا. في الواقع ، يعد خادم DHCP أحد المكونات الموثوقة التي يمكن أن يكون لها تأثير قوي على الأجهزة التي تصل إليها.

خيار البحث عن المجال


تم ترقيم خيار البحث في المجال 0x77 (119). مثل كل الخيارات ، يتم تشفيره بعلامة أحادية البايت برقم الخيار. مثل معظم الخيارات الأخرى ، مباشرة بعد العلامة حجم بايت واحد من البيانات التالية الحجم. قد تكون مثيلات الخيار موجودة في رسالة DHCP أكثر من مرة. في هذه الحالة ، يتم تسلسل البيانات من جميع هذه الأقسام بالتسلسل الذي تظهر به في الرسالة.



في المثال المقدم ، مأخوذ من RFC 3397 ، يتم تقسيم البيانات إلى ثلاثة أقسام ، كل منها 9 بايت. كما ترون من الصورة ، يتم ترميز أسماء النطاقات الفرعية في اسم المجال المؤهل بالكامل بطول واحد من الاسم ، متبوعًا مباشرةً بالاسم نفسه. ينتهي تشفير اسم المجال المؤهل بالكامل مع بايت فارغ (أي ، اسم نطاق فرعي بحجم فارغ).

بالإضافة إلى ذلك ، يستخدم الخيار أبسط طريقة لضغط البيانات ، أو بالأحرى ، إعادة توزيع النقاط. بدلاً من حجم اسم المجال ، قد يحتوي الحقل على القيمة 0xc0. ثم تقوم البايتة التالية بتعيين الإزاحة نسبة إلى بداية بيانات الخيار ، والتي يجب استخدامها للبحث عن نهاية اسم المجال.

وبالتالي ، في هذا المثال ، يتم ترميز قائمة لاحقات المجال اثنين:

 .eng.apple.com .marketing.apple.com 

DecodeDomainSearchListData وظيفة


لذلك ، فإن رقم خيار DHCP 0x77 (119) يسمح للخادم بتكوين لاحقات DNS على العملاء. ولكن ليس على الأجهزة التي تعمل بأنظمة تشغيل Windows. عادةً ما تتجاهل أنظمة Microsoft هذا الخيار ، لذا فإن تاريخ أسماء DNS ، إذا دعت الضرورة ، تم تخطيها عبر سياسات المجموعة. استمر هذا حتى وقت قريب ، عندما أضاف الإصدار التالي من Windows 10 ، الإصدار 1803 ، المعالجة لخيار البحث عن المجال. اذا حكمنا من خلال اسم الوظيفة في dhcpcore.dll ، حيث تم إجراء التغييرات ، فإن الخطأ في السؤال يكمن في المعالج المُضاف.

الحصول على العمل. نقوم بتمشيط الرمز قليلاً ومعرفة ما يلي. يقوم الإجراء DecodeDomainSearchListData ، بما يتوافق تمامًا مع الاسم ، بفك تشفير البيانات من خيار البحث في المجال للرسالة المستلمة من الخادم. عند الإدخال ، يتلقى صفيف بيانات معبأ بالطريقة الموضحة في الفقرة السابقة ، وعند الإخراج ، ينشئ سلسلة منتهية بقيمة خالية تحتوي على قائمة بنهايات اسم المجال مفصولة بفواصل. على سبيل المثال ، تحول هذه الوظيفة البيانات من المثال أعلاه إلى سلسلة:

  eng.apple.com,marketing.apple.com 

يتم استدعاء DecodeDomainSearchListData من الإجراء UpdateDomainSearchOption ، الذي يقوم بتعيين القائمة التي تم إرجاعها إلى قيمة "DhcpDomainSearchList" الخاصة بمفتاح التسجيل:
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{INTERFACE_GUID}\
تخزين المعلمات الرئيسية لواجهة شبكة محددة.



الدالة DecodeDomainSearchListData يفي بتمريرين. في التمريرة الأولى ، يتم تنفيذ جميع الإجراءات باستثناء الكتابة إلى المخزن المؤقت للإخراج. وبالتالي ، يتم تخصيص التمرير الأول لحساب حجم الذاكرة المطلوبة لاستيعاب البيانات التي تم إرجاعها. في المرحلة الثانية ، تم تخصيص الذاكرة بالفعل لهذه البيانات وتملأ الذاكرة المخصصة. الوظيفة صغيرة إلى حد ما ، حوالي 250 تعليمات ، وتتمثل مهمتها الرئيسية في معالجة كل من الخيارات الثلاثة الممكنة للشخصية الممثلة في دفق الإدخال: 1) 0x00 ، 2) 0xc0 ، أو 3) جميع القيم الأخرى. الإصلاح الافتراضي للخطأ المتعلق بـ DHCP يتعلق أساسًا بإضافة التحقق من حجم المخزن المؤقت الناتج في بداية التمريرة الثانية. إذا كان هذا الحجم صفرًا ، فلن يتم تخصيص الذاكرة للمخزن المؤقت وتنتهي الوظيفة فورًا وتُرجع خطأً:



اتضح أن مشكلة عدم الحصانة تظهر في الحالات التي يكون فيها حجم المخزن المؤقت الهدف صفرًا. في نفس الوقت ، في بداية التنفيذ ، تقوم الدالة بفحص بيانات الإدخال ، التي لا يمكن أن يكون حجمها أقل من وحدتي بايت. لذلك ، للتشغيل ، يلزم تحديد خيار غير فارغ للمجال اللاحق بحيث يكون حجم المخزن المؤقت للإخراج صفرًا.

استغلال


أول ما يتبادر إلى الذهن هو أنه يمكنك استخدام نقاط إعادة التوزيع الموصوفة مسبقًا بحيث تقوم بيانات الإدخال غير الفارغة بإنشاء سطر إخراج فارغ:



سيؤدي الخادم الذي تم تكوينه لإرسال خيار يتضمن هذا المحتوى في الاستجابة إلى انتهاك وصول العملاء غير المحدثين بالفعل. يحدث هذا للسبب التالي. في كل خطوة ، عندما تقوم الوظيفة بتوزيع جزء من اسم المجال المؤهل بالكامل ، تقوم بنسخه إلى المخزن المؤقت الهدف ووضع نقطة بعده. في المثال المأخوذ من RFC ، سيتم نسخ البيانات إلى المخزن المؤقت بالترتيب التالي:

 1). eng. 2). eng.apple. 3). eng.apple.com. 

ثم ، عندما يحتوي المجال على حجم مجال صفري ، فإن الوظيفة تستبدل الحرف السابق للمخزن المؤقت الوجهة بفاصلة:

 4). eng.apple.com, 

ويستمر التحليل:

 5). eng.apple.com,marketing. 6). eng.apple.com,marketing.apple. 7). eng.apple.com,marketing.apple.com. 8). eng.apple.com,marketing.apple.com, 

في نهاية الإدخال ، يبقى فقط استبدال الفاصلة الأخيرة بحرف صفري وستحصل على سطر جاهز للكتابة إلى السجل:

 9). eng.apple.com,marketing.apple.com 

ماذا يحدث عندما يرسل مهاجم مخبأ يتكون بالطريقة الموصوفة؟ إذا نظرت إلى المثال ، يمكنك أن ترى أن القائمة الواردة فيه تتكون من عنصر واحد - سلسلة فارغة. في التمريرة الأولى ، تقوم الدالة بحساب حجم بيانات الإخراج. نظرًا لأن البيانات لا تحتوي على اسم مجال غير صفري واحد ، يكون الحجم صفرًا.

في المرحلة الثانية ، يتم تخصيص كتلة من الذاكرة الديناميكية لوضع البيانات فيها ونسخ البيانات نفسها. لكن دالة التحليل على الفور تواجه حرفًا خاليًا ، مما يدل على نهاية اسم المجال ، وبالتالي ، كما قيل ، يستبدل الحرف السابق من نقطة إلى فاصلة. وهنا نواجه مشكلة. التكرار المخزن المؤقت الهدف في الموضع صفر. لا يوجد شخصية سابقة. ينتمي الحرف السابق إلى رأس كتلة الذاكرة الديناميكية. وسيتم استبدال هذه الشخصية نفسها بـ 0x2c ، أي بفاصلة.

ومع ذلك ، يحدث هذا فقط على أنظمة 32 بت. باستخدام int غير الموقعة لتخزين الموضع الحالي من تكرار المخزن المؤقت الهدف يقدم التعديلات على المعالجة على أنظمة x 64. دعونا نولي اهتمامًا أكبر للشفرة المسؤولة عن كتابة فاصلة إلى المخزن المؤقت:



يتم طرح الوحدة من الموضع الحالي باستخدام سجل eax 32 بت ، بينما عند معالجة المخزن المؤقت ، يصل الكود إلى سجل rax كامل 64 بت. في بنية AMD64 ، تُلغي أي عمليات ذات سجلات 32 بت الجزء العلوي من السجل. هذا يعني أنه في سجل rax ، الذي كان يحتوي سابقًا على صفر ، بعد الطرح ، لن يتم تخزين القيمة -1 ، ولكن سيتم تخزين 0xffffffff. لذلك ، على أنظمة 64 بت ، ستتم كتابة القيمة 0x2c على العنوان buf [0xffffffff] ، أي أبعد من حدود الذاكرة المخصصة للمخزن المؤقت.

تتوافق البيانات التي تم الحصول عليها بشكل جيد مع تقييم أداء Microsoft ، لأنه من أجل استغلال هذه الثغرة الأمنية ، يحتاج المهاجم إلى معرفة كيفية إجراء رش كومة الذاكرة المؤقتة عن بُعد على عميل DHCP وفي نفس الوقت يكون لديه سيطرة كافية على تخصيص ذاكرة ديناميكية لتسجيل القيم المحددة مسبقًا ، وهي فاصلة والبايت صفر ، أنتجت في العنوان أعد وأدت إلى عواقب سلبية تسيطر عليها. وإلا ، فإن كتابة البيانات إلى عنوان لم يتم التحقق منه سينتج عنه انخفاض في عملية ملف Svchost.exe ، إلى جانب جميع الخدمات المستضافة حاليًا فيه ، وإعادة تشغيل هذه الخدمات بواسطة نظام التشغيل. حقيقة أن المهاجمين في ظروف معينة يمكن أن تستخدم أيضا لمصلحتهم الخاصة.

يبدو أن هذا هو كل ما يمكن قوله عن الخطأ قيد التحقيق. يبقى الشعور بأن هذا أبعد ما يكون عن النهاية. كما لو أننا لم نفكر في جميع الخيارات. يجب أن يكون هناك شيء أكثر مخفي في هذه السطور.

CVE-2019-0726


ربما على ما هو عليه. إذا نظرت عن كثب إلى نوع البيانات التي تسببت في الخطأ وقارنته بكيفية حدوث هذا الخطأ بالضبط ، فستلاحظ أن قائمة أسماء النطاقات يمكن تغييرها بحيث يكون حجم المخزن المؤقت الناتج غير بحجم صفر ، ولكن محاولة الكتابة خارجها سوف يتم نفس الشيء. للقيام بذلك ، يجب أن يكون العنصر الأول في القائمة عبارة عن سلسلة فارغة ، ويمكن أن تحتوي جميع العناصر الأخرى على نهايات مجال عادية. على سبيل المثال:



يتضمن الخيار المقدم عنصرين. لاحقة المجال الأولى فارغة ، وينتهي على الفور مع صفر بايت. اللاحقة الثانية هي .ru. سيكون حجم الخط المحسوب في الإخراج مساوياً لثلاث وحدات بايت ، مما سيسمح للتغلب على التحقق الذي يفرضه تحديث يناير على إفراغ المخزن المؤقت الهدف. في الوقت نفسه ، يفرض الصفر في بداية البيانات الدالة على كتابة فاصلة بالحرف السابق في السلسلة الناتجة ، ولكن بما أن الموضع الحالي للتكرار في السلسلة هو صفر ، كما في الحالة المذكورة أعلاه ، سيحدث التسجيل مرة أخرى خارج المخزن المؤقت المخصص.

الآن من الضروري تأكيد النتائج النظرية التي تم الحصول عليها في الممارسة العملية. نحن نحاكي موقفًا يرسل فيه خادم DHCP رسالة تحتوي على الخيار المقدم استجابة لطلب من العميل ، ونلاحظ فورًا استثناء عند محاولة كتابة فاصلة إلى موضع 0xffffffff المخصص أسفل السطر المؤقت الناتج:



هنا ، يحتوي السجل r8 على مؤشر للخيارات الواردة ، rdi هو عنوان المخزن المؤقت الهدف المحدد ، و rax هو الموضع في هذا المخزن المؤقت حيث سيتم كتابة الحرف. لقد حصلنا على هذه النتائج على نظام محدث بالكامل (اعتبارًا من يناير 2019).

نكتب عن المشكلة المكتشفة في Microsoft و ... يفقدون الرسالة. نعم ، هذا يحدث في بعض الأحيان حتى مع البائعين السمعة. لا يوجد نظام مثالي ، وفي هذه الحالة عليك البحث عن طرق أخرى للاتصال. لذلك ، بعد أسبوع ، وحتى دون تلقي استجابة تلقائية خلال هذا الوقت ، نتصل بالمدير مباشرةً عبر Twitter ووفقًا لنتائج عدة أيام من تحليل التطبيق ، نكتشف أن التفاصيل المرسلة لا علاقة لها بـ CVE-2019-0547 وتمثل ثغرة أمنية مستقلة والتي معرف CVE جديد. بعد شهر ، في مارس ، يظهر التصحيح المقابل ، ويتلقى الخطأ الرقم CVE-2019-0726 .

هذه هي الطريقة التي يمكنك من خلالها محاولة معرفة تفاصيل الثغرة الأمنية ليوم واحد لاكتشاف 0 يومًا عن طريق الخطأ ببساطة عن طريق الوثوق بحدسك.

كتب بواسطة ميخائيل تسفيتكوف ، أخصائي تحليل تطبيق التقنيات الإيجابية.

Source: https://habr.com/ru/post/ar448378/


All Articles