
مكتبة Rusty Hell's Gate / Halo's Gate / Tartarus' Gate / FreshyCalls / Syswhispers2
أسميت هذا المشروع Mordor لأن Hell's Gate / Halo's Gate / Tartarus' Gate تذكرني بـ البوابة السوداء لموردور في سيد الخواتم لسبب غريب ما هاها، والمشروع يحتاج إلى اسم رائع فلمَ لا؟
الشكر موصول إلى Middle-earth: Shadow of War Wiki
الاعتراض هو تقنية تُستخدم لاعتراض الاستدعاءات إلى دوال موجودة مسبقًا أو لإعادة توجيه مسار التنفيذ لواجهة برمجة تطبيقات شرعية إلى موقع آخر في الذاكرة. قد يكون موقع الذاكرة هذا تحت سيطرة مهاجم أو برنامج مكافحة فيروسات (AV) أو نظام كشف الاستجابة على نقاط النهاية (EDR) أو برنامج مكافحة الغش (AC).
Inline Hooking: يتيح لنا هذا استبدال أول بايتات قليلة (تعليمات لغة التجميع) من الدالة المستهدفة بتعليمة قفز لإعادة توجيه مسار التنفيذ إلى موقع آخر في الذاكرة.
Import Address Table Hooking (IAT hooking): جدول عناوين الاستيراد هو جدول بحث لمؤشرات الدوال الخاصة بالدوال المستوردة من ملفات DLL أو الملفات التنفيذية. يتيح لنا اعتراض IAT استبدال عنوان الدالة في جدول عناوين الاستيراد بآخر لإعادة توجيه مسار تنفيذ البرنامج.
الشكر موصول إلى Kyle Mistele
Hell's Gate هي تقنية حقن في العمليات تتيح لنا البحث عن عدد من البايتات يُسمى syscall stub، من وحدة ntdll.dll لاستخراج أرقام استدعاءات النظام وحفظها في جدول ذاكرة مخصص، يُستخدم بعد ذلك لاستدعاء واجهات برمجة تطبيقات النظام مباشرة. ومع ذلك، فإن قيد Hell's Gate هو أنه يحتاج إلى الوصول إلى وحدة ntdll.dll نظيفة إذا كانت الدوال معترضة. وإلا فإنه لا يستطيع ملء أرقام استدعاءات النظام المطلوبة ويفشل في النهاية في تقديم استدعاءات واجهة برمجة التطبيقات الأصلية. ولمعالجة هذه المشكلة، وُلدت شقيقة توأم تُسمى Halo's Gate، وهي مجرد رقعة على Hell's Gate مبنية على ملاحظة بسيطة جدًا.
عندما يُوضع اعتراض على دالة (jmp <address) لن نتمكن من استرداد أرقام استدعاءات النظام ديناميكيًا، ولمعالجة هذه المشكلة يمكننا النظر إلى أرقام استدعاءات النظام للدوال المجاورة وتعديل الحسابات وفقًا لذلك للحصول على رقم استدعاء النظام الخاص بنا، لأن معرّف استدعاء النظام في syscall stub يتبع بعضه البعض بشكل تزايدي.
يتحقق Hell's Gate فقط من تسلسل بايتات بالترتيب التالي 4c8bd1b8، والذي يبدو هكذا في لغة التجميع:
mov r10, rcx
mov eax, <syscall>
تقوم Halo's gate بنفس ما تقوم به Hell's Gate ولكن مع فحص إضافي لمعرفة ما إذا كان هناك خطاف (hook) موضوع من خلال التحقق مما إذا كانت البايت الأولى من التصدير هي e9 (jmp)، وإذا كان هناك خطاف موضوع فإن Halo's gate تبدأ في النظر إلى الدوال المجاورة وتعديل الحسابات وفقًا لذلك للحصول على رقم استدعاء النظام الخاص بنا، نظرًا لأن معرّف syscall في stub الخاص بـ syscall يتبع بعضه البعض بشكل متزايد.
ومع ذلك، لا تقوم جميع حلول EDR بوضع الخطاف في نفس الموقع (في بداية الدالة). ماذا لو وضعت حلول EDR الخطاف مباشرة بعد mov r10, rcx (4c8bd1)؟ سيؤدي هذا إلى كسر الكود الخاص بنا.
تحل Tartarus' Gate هذه المشكلة بإضافة فحص إضافي إلى Halo's gate من خلال البحث عن هذه البايتات بالتسلسل 4c8bd1e9 أيضًا، والذي يبدو هكذا في لغة التجميع.
mov r10, rcx
jmp <address>
ومع ذلك، إذا كانت جميع الدوال مخترقة (hooked) فيمكننا إيجاد الأولى وإلغاء اختراقها واحدة تلو الأخرى بدءًا من معرّف الاستدعاء 0. تُسمى هذه الطريقة Veles' Reek في SEKTOR7.
تبحث تقنية FreshyCalls في Export Directory عن الدوال التي تبدأ بـ Nt (باستثناء Ntdll) وترتبها حسب العناوين. والمفاجئ أن أدنى عنوان هو رقم استدعاء النظام 0 والذي يليه سيكون أرقام استدعاء النظام 1 و2 و3... يمكنك التحقق من ذلك بنفسك في x64 dbg أو Windbg.
تفعل Syswhispers2 الشيء نفسه، لكن بدلًا من البحث عن دوال Nt داخل دليل التصدير الخاص بـ ntdll.dll فإنها تبحث عن الدوال التي تبدأ بـ Zw. والمفاجئ أن دوال Zw ودوال Nt تشير إلى نفس stubs استدعاء النظام وستملك نفس رقم استدعاء النظام.
هنا يمكننا التحقق من ذلك:
الفرق بين دوال Zw وNt موضّح من قبل Microsoft هنا:
"*تُنفَّذ واجهة برمجة تطبيقات خدمات نظام التشغيل الأصلية في Windows كمجموعة من الروتينات التي تعمل في وضع النواة (kernel mode). تبدأ أسماء هذه الروتينات بالبادئة Nt أو Zw. يمكن لبرامج تشغيل وضع النواة استدعاء هذه الروتينات مباشرة. ويمكن لتطبيقات وضع المستخدم الوصول إلى هذه الروتينات باستخدام استدعاءات النظام.
مع بعض الاستثناءات، لكل روتين من روتينات خدمات النظام الأصلية نسختان مختلفتان قليلًا لهما أسماء متشابهة لكن ببادئات مختلفة. على سبيل المثال، تؤدي الاستدعاءات إلى NtCreateFile وZwCreateFile عمليات متشابهة، وهي في الواقع تُخدَم بواسطة نفس الروتين الأصلي في وضع النواة.
بالنسبة لاستدعاءات النظام من وضع المستخدم، تتصرف نسختا Nt وZw من الروتين بشكل متطابق. أما بالنسبة للاستدعاءات من برنامج تشغيل في وضع النواة، فتختلف نسختا Nt وZw من الروتين في كيفية تعاملهما مع قيم المعاملات التي يمررها المستدعي إلى الروتين.
يستدعي برنامج التشغيل في وضع النواة نسخة Zw من روتين خدمات النظام الأصلي لإبلاغ الروتين بأن المعاملات تأتي من مصدر موثوق في وضع النواة. في هذه الحالة، يفترض الروتين أنه يستطيع استخدام المعاملات بأمان دون التحقق منها أولًا. أما إذا كانت المعاملات قد تأتي من مصدر في وضع المستخدم أو من مصدر في وضع النواة، فإن برنامج التشغيل يستدعي بدلًا من ذلك نسخة Nt من الروتين، والتي تحدد بناءً على سجل خيط التنفيذ (thread) المستدعي ما إذا كانت المعاملات قد نشأت في وضع المستخدم أو وضع النواة*"
Hell's Gate: سيقوم هذا بتحليل ntdll.dll لإيجاد بداية syscall stub (4c8bd1b8) ثم استرداد معرّف استدعاء النظام. ومع ذلك، إذا كان syscall stub مخترقًا (hooked) فسوف تتعطل شيفرتنا.
Halo's Gate: نفس Hell’s Gate، لكنه يضيف فحصًا إضافيًا لمعرفة ما إذا كانت الاختراقات الأولى موجودة عبر التحقق مما إذا كانت البايتة الأولى هي e9 (jmp)، وإذا كان هناك اختراق موجود فسيبدأ Halo's gate في النظر إلى الدوال المجاورة وتعديل الحسابات وفقًا لذلك للحصول على رقم استدعاء النظام لدينا، لأن معرّف استدعاء النظام في syscall stub يتبع بعضه البعض بشكل متزايد.
Tartarus' Gate: نفس Halo's Gate لكنه يضيف فحصًا إضافيًا لمعرفة ما إذا كان syscall stub مخترقًا في السطر الثاني، بعد تعليمات التجميع mov r10, rcx عبر البحث عن التسلسل التالي من البايتات: `4c8bd1e9.
FreshyCalls: سيبحث عن الدوال التي تبدأ بـ Nt في Export Directory ويرتبها حسب العناوين، وأدنى عنوان هو معرّف استدعاء النظام 0.
SysWhispers1: يستخدم معلومات إصدار نظام التشغيل لاختيار رقم استدعاء النظام الصحيح.
Syswhispers2: نفس FreshyCalls، لكنه سيبحث عن دوال Zw في Export Directory ويخزّن الاسم باستبدال Zw بـ Nt.
SysWhispers3 هذا مشابه جدًا لـ SysWhispers2 باستثناء أنه يدعم أيضًا x86/WoW64، واستبدال تعليمات syscalls بـ EGG (ليتم استبداله ديناميكيًا)، والقفزات المباشرة إلى syscalls في وضع x86/x64 (في WOW64 يكون الأمر قياسيًا تقريبًا)، والقفزات المباشرة إلى syscalls عشوائية (مستعيرًا فكرة @ElephantSeal).
تمرين للقارئ من إعداد: مدونة ممتازة بقلم Alice Climent-Pommeret وKelzvirus