تحليل Bootkit

مرحبا بالجميع! فيما يتعلق بإطلاق دورة "الهندسة العكسية" ، عقدنا درسًا مخططًا مفتوحًا. تفكيكها خوارزمية عملية bootkit في مراحل مختلفة من التحميل.



محاضر - آرثر باكولوف ، محلل الفيروسات في كاسبرسكي لاب.

المقالة التالية تمهيدية وهي نسخة نصية من جزء فقط من الدرس ، وهي مخصصة لمثبّت bootkit. تحليل مفصل لل bootkit نفسه ، راجع الفيديو.

Bootkit هو برنامج ضار يقوم بتعديل Master Boot Record ، وهو القطاع الأول من أول قرص فعلي أو قطاع تمهيد ، VBR. البرامج من هذا النوع ، في الأساس ، لها وظيفة طروادة وتستخدم لتنفيذ أي إجراءات خفية في النظام. في مثالنا ، ينفذ bootkit تصعيد الامتياز إلى مستوى العملية ، والذي يبدأ اسمه بتسلسل من الحروف: "inte". في الواقع ، فإن bootkit هو برنامج rootkit يبدأ العمل في حلقة الحماية 0 ، والتي تبدأ قبل أن يبدأ نظام التشغيل في التحميل. ولهذا السبب ، فهو مهتم جدًا بالبحث.

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

للعمل ، تم إعداد نموذج خاص bootkit-xp.exe ، يعمل تحت نظام التشغيل Windows XP. لذلك ، بالإضافة إلى دراسة bootkit ، كنا حنين قليلاً لنظام التشغيل هذا. ولكن بشكل عام ، تم اختيار نظام التشغيل XP من أجل تسهيل عكس اتجاهه ، نظرًا لأن XP هو تصور جيد وغياب المضاعفات غير الضرورية. حسنًا ، تمت كتابة العينة خصيصًا لنظام التشغيل هذا ، وفقًا لرمزها.

إليك ما يبدو عليه مثبّت bootkit :



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



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



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

نواصل استكشاف الرمز.



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

وبالتالي ، في الصورة أعلاه ، باستخدام CreateFile ، يتم الوصول إلى رابط رمزي إلى أول قرص ثابت فعلي متصل. إذا تم منح الوصول ، فيمكنك التعامل مع هذا "الملف" كما هو الحال مع أي ملف بسيط آخر. بمعنى ، سيتم تقديم القرص الثابت بأكمله كملف واحد كبير.

لذلك ، دعونا نستمر. المقبض عاد ، ونجد أنفسنا هنا:



ماذا يحدث بعد ذلك؟ ثم قراءة الدالة ReadFile 0x200 بايت الأولى. ولدينا هناك القطاع الأول من أول قرص فعلي.



كما قد تكون خمنت ، هذا هو سجل التمهيد الرئيسي (MBR). يتكون MBR من 3 أجزاء: جزء الرمز ، جدول القسم والتوقيع. في الحالة العادية ، يقرأ السير MBR في الذاكرة على العنوان 0: 0x7c00h ، ويمرر التحكم فيه. لذلك ، يبدأ جزء رمز MBR في التنفيذ. أثناء التنفيذ ، يقوم بتوزيع جدول القسم ، والعثور على قطاع التمهيد وتحميله. في حالة وجود bootkit ، إذا تم الكتابة فوق MBR ، سيتلقى الرمز الخاص به الآن التحكم.

حسنا ، قراءة MBR ، وما هو التالي ؟ ثم يفتح bootkit PhysicalDrive0 مرة أخرى ، ولكن مع وضع وصول الكتابة.



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

لماذا النسخ الاحتياطي القطاع؟ من الواضح أن هذا ضروري لحقيقة أنه ستكون هناك حاجة إليه في المستقبل.

ثم تبدأ الدورة. بطبيعة الحال ، عند النظر إلى الكود ، لا يسع المرء إلا الانتباه إلى الثوابت مثل var_1C و 1BEh وغيرها. وفي الوقت نفسه ، يجب تحديث بنية MBR الموجودة أعلاه في الذاكرة. على وجه الخصوص ، نحن مهتمون بعمود "الأوفست".



راجع ، قراءة المخزن المؤقت للقراءة القطاع الأول في lpBuffer . ثم تتم إضافة 1BEh إليه ، في الواقع ، ينتقل المؤشر إلى بداية جدول القسم. يتم إدراج جميع البيانات من الجدول إلى نهاية القطاع في _marked_bytes ، بدءًا من نفس الإزاحة - 1BE.



بمعنى ، يتم إدراج الأجزاء الثانية والثالثة من MBR الأصلي في _marked_bytes .

ماذا يحدث بعد ذلك؟ ثم يقوم SetFilePointer بتعيين المؤشر إلى بداية "ملفنا" ، أي إلى MBR.



ثم هناك كتابة (WriteFile) _marked_bytes وتحرير الذاكرة. في هذا ، تنتهي وظيفة مثبت bootkit.

ولكن سيكون من الجيد أن نرى بالضبط ما هو في الجزء الأول من _marked_bytes . للقيام بذلك ، تفريغها إلى القرص وتحليلها. أول ما يلفت انتباهك هو انخفاض بمقدار 2 من محتويات المتغير على العنوان 0x413.



إذا نظرت إلى الوثائق الفنية ، يمكنك أن تجد أن المتغير عند 0X413 يحتوي على مقدار الذاكرة الفعلية المثبتة بالكيلو بايت. وفقًا لذلك ، يقوم رمز bootkit "بقطع" كيلو بايتين من الذاكرة:



الآن ، حتى لا يتم عمل المزيد ، سيتم اعتبار أن هناك 2 كيلو بايت من الذاكرة أقل مما كانت عليه. لماذا - ليست واضحة بعد.

بعد ذلك ، يتم حساب العنوان الفعلي على قطعة "إيقاف التشغيل" من الذاكرة باستخدام إزاحة يسار بتة تبلغ 6 بتات:



يعمل التحول من 6 على إجراءين في آن واحد - يحول الكيلوبايت إلى بايت (ضرب قيمة المتغير بمقدار 2 ^ 10) ، وبالتالي الحصول على العنوان الفعلي للقطعة المعضلة من الذاكرة ، ويستخلص رقم القطعة منه ، ويقسم النتيجة على 0x10 (2 ^ 4).

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

هذه مجرد بداية bootkit. ثم سيكون هناك اعتراض المقاطعة ، وتتبع توقيع ntldr ، وتعديل وحدة kernel OS ، إلخ.

لذلك ، لن نفسد ذلك ، فمن الأفضل مشاهدة الندوة عبر الويب حتى النهاية حتى لا تفوت أي شيء.

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


All Articles