هجمات التلاعب المباشر بكائنات kernel (DKOM) على موفري ETW.

صورة جانبية لرجل ينظر إلى شاشة الكمبيوتر أثناء العمل في وقت متأخر من الليل

مؤلف

Ruben Boonen

CNE Capability Lead, Adversary Services

IBM X-Force

في هذا المنشور، يحلل قراصنة IBM Security X-Force Red الهجوميون كيف يمكن للمهاجمين، الذين لديهم صلاحيات مرتفعة، استخدام وصولهم لتطوير قدرات Windows Kernel بعد الاستغلال. وعلى مدى السنوات القليلة الماضية، أظهرت الحسابات العامة بشكل متزايد أن المهاجمين الأقل تطورًا يستخدمون هذه التقنية لتحقيق أهدافهم. ولذلك من المهم أن نسلط الضوء على هذه القدرة ونتعرف أكثر على تأثيرها المحتمل. وعلى وجه التحديد، في هذا المنشور، سنقيم كيف يمكن استخدام النواة بعد الاستغلال لتعطيل حساسات ETW وربطها بعينات برنامج ضار تم تحديدها في البرية العام الماضي.

مقدمة

وبمرور الوقت، تحسنت عمليات التخفيف من الأمان وقياس الكشف عن بُعد على نظام التشغيل Windows بشكل كبير. وعند دمج هذه القدرات مع حلول اكتشاف واستجابة نقطة النهاية (EDR) المهيأة جيدًا، فإنها يمكن أن تشكل حاجزًا غير بسيط أمام مرحلة ما بعد الاستغلال. ويواجه المهاجمون تكلفة ثابتة لتطوير وتكرار الأساليب والتقنيات والإجراءات (TTPs) لتجنب قواعد الكشف. وفي فريق محاكاة العدو في IBM Security X-Force، نواجه نفس المشكلة. وإن فريقنا مكلف بمحاكاة قدرات التهديد المتقدمة في بعض أكبر البيئات وأكثرها تحصينًا. وإن الجمع بين الحلول الأمنية المعقدة والمضبوطة بدقة وفرق مركز العمليات الأمنية (SOC) المدربة تدريبًا جيدًا يمكن أن يكون مرهقًا للغاية على الحرفية في العمل. وفي بعض الحالات، يصبح استخدام TTP معين غير فعال تمامًا خلال فترة تتراوح بين ثلاثة إلى أربعة أشهر (عادةً ما يكون مرتبطًا بمجموعات تقنيات محددة).

قد يختار المهاجمون الاستفادة من تنفيذ الرموز في Windows Kernel للتلاعب ببعض وسائل الحماية هذه أو لتجنب عدد من المستشعرات الموجودة على أرض المستخدم تمامًا. وكان أول عرض منشور لهذه القدرة في عام 1999 في مجلة Phrack Magazine. وخلال السنوات الفاصلة، تم الإبلاغ عن عدد من الحالات التي استخدم فيها عناصر التهديد (TAs) مجموعات الجذور النووية بعد الاستغلال. وتشمل بعض الأمثلة القديمة Derusbi Family ومجموعة أدوات Lamberts.

وبشكل تقليدي، كانت تقتصر هذه الأنواع من القدرات في الغالب على عناصر التهديد المتقدمة. ومع ذلك، في السنوات الأخيرة، شهدنا عددا أكبر من مهاجمي السلع يستخدمون عناصر أولية لاستغلال Bring Your Own Vulnerable Driver (BYOVD) لتسهيل الإجراءات على نقطة النهاية. وفي بعض الحالات، كانت هذه التقنيات بدائية للغاية وتقتصر على المهام البسيطة، ولكن كانت هناك أيضًا عروض توضيحية أكثر دقة.

وفي نهاية سبتمبر 2022، أصدرت أبحاث من ESET مستنداتفنية حول مثل قدرة مثل Kernel التي استخدمها عنصر تهديد Lazarus في عدد من الهجمات ضد كيانات في بلجيكا وهولندا لغرض استخراج البيانات. وتوضح هذه المستندات الفنية عددًا من العناصر الأولية للمعالجة المباشرة للكائنات في النواة (DKOM) التي تستخدمها الحمولة لتعمية القياس عن بُعد نظام OS / AV / اكتشاف نقاط النهاية والاستجابة لها. وإن عمليات البحث العامة المتاحة حول هذه التقنيات قليلة. ويُعد اكتساب فهم أكثر شمولاً لأساليب Kernel بعد الاستغلال أمر حساس للدفاع. ومن الحجج التقليدية والساذجة التي نسمعها غالبًا هي أن المهاجم الذي يتمتع بامتيازات عالية يمكنه فعل أي شيء، فلماذا يجب علينا تصميم القدرات في هذا السيناريو؟ وهذا موقف ضعيف. ويحتاج المدافعون إلى فهم القدرات التي يمتلكها المهاجم عندما يتم رفع مستوى صلاحياته، وأي مصادر بيانات تظل موثوقة (وأيها لا)، وما خيارات الاحتواء المتاحة، وكيف يمكن اكتشاف التقنيات المتقدمة (حتى لو لم تكن هناك طرق لإجراء عمليات الكشف هذه). وسأركز في هذا المنشور على وجه التحديد على تصحيح بنى Kernel Event Tracing for Windows (ETW) لجعل المقدمين إما غير فعالين أو غير قابلين للعمل. وسأقدم بعض المعلومات الأساسية عن هذه التقنية، وسأحلل كيف يمكن للمهاجمين أن يتلاعبوا ببنى Kernel ETW، وسأدخل في بعض آليات العثور على هذه البنى. وأخيرًا، سأراجع كيف تم تطبيق هذه التقنية من قبل Lazarus في حمولتها.

أحدث الأخبار التقنية، مدعومة برؤى خبراء

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

شكرًا لك! أنت مشترك.

سيصلك محتوى الاشتراك باللغة الإنجليزية. ستجد رابط إلغاء الاشتراك في كل رسالة إخبارية. يمكنك إدارة اشتراكاتك أو إلغاء اشتراكك من هنا. لمزيد من المعلومات، راجع بيان خصوصية IBM.

ETW DKOM

تُعد ETW بنية تتبع عالية الأداء مضمنة داخل نظام التشغيل Windows. وتتيح تسجيل الأحداث وأنشطة النظام بواسطة التطبيقات وبرامج التشغيل ونظام التشغيل، مما يوفر رؤية مفصلة لسلوك النظام في التصحيح، وتحليل الأداء، والتشخيصات الأمنية.

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

سطح هجوم ETW الخاص بـ Kernel

ألقى باحثون من Binarly محاضر في مؤتمر BHEU 2021، تناولوا فيها سطح الهجوم العام لبنية ETW في نظام Windows. فيما يلي نظرة عامة على نموذج التهديد.

مخطط انسيابي يوضح نماذج التهديدات ETW
الشكل 1 – Veni, No Vidi, No Vici: هجمات على مستشعرات اكتشاف نقاط النهاية والاستجابة لها العمياء في بنية ETW (Binarly)

في هذا المنشور، نركّز على سطح الهجوم في مساحة النواة (Kernel)

مخطط يوضح ويصف الهجمات على موفري ETW في وضع kernel
الشكل 2، Veni, No Vidi, No Vici: هجمات على مستشعرات اكتشاف نقاط النهاية والاستجابة لها العمياء في بنية ETW (Binarly)

يتناول هذا المنشور فقط الهجمات ضمن الفئة الأولى من الهجوم الموضحة في "الشكل 2"، حيث يتم تعطيل التتبع أو تغييره بطريقة ما.

كملاحظة تحذيرية، عند التفكير في البنى الغامضة على Windows، من المهم دائمًا أن نتذكر أن هذه البنى عُرضة للتغيير، وفي الواقع أنها تتغير بشكل متكرر عبر إصدارات Windows. وهذا مهم بشكل خاص عند استخلاص بيانات Kernel، حيث من المحتمل أن تؤدي الأخطاء إلى ظهور شاشة الموت الزرقاء (BSoD)، فكن حذرًا!

التهيئة

يتم تسجيل موفري Kernel باستخدام nt!ETWregister ، وهي دالة تم تصديرها بواسطة ntoskrnl. ويمكن الاطلاع على نسخة مفككة من الدالة أدناه.

لقطة شاشة لرمز فك nt!EtwRegister
الشكل 3، فك nt!EtwRegister

تحدث التهيئة الكاملة داخل دالة EtwpRegisterKMProvider الداخلية، ولكن هناك ملخصان رئيسيان هنا:

  • يُعد ProviderId مؤشرًا إلى GUID مكون من 16 بايت. ويُعد هذا المُعرف الفريد العمومي (GUID) ثابتًا عبر أنظمة التشغيل، لذا يمكن استخدامه لتحديد الموفر الذي تتم تهيئته.
  • يُعد RegHandle عنوان ذاكرة يستقبل مؤشر إلى بنية _ETW_REG_ENTRY عند استدعاء ناجح. توفر بنية البيانات هذه وبعض خصائصها المتداخلة طرقًا للتلاعب بموفر ETW وفقًا للبحث من Binarly.

دعونا نسرد بإيجاز البنية التي أبرزتها Binarly على شريحتها في الشكل 2.

ETW_REG_ENTRY

يتم عرض قائمة كاملة 64 بت لبنية _ETW_REG_ENTRY  أدناه. تتوفر التفاصيل المضافة في مدونة Geoff Chappell هنا. يمكن أيضًا استكشاف هذه البنية بمزيد من التفصيل عبر مشروع Vergilius.

// 0x70 بايت (sizeof)
// Win11 22H2 10.0.22621.382
struct _ETW_REG_ENTRY
{
    struct _LIST_ENTRY RegList;                           //0x0
    struct _LIST_ENTRY GroupRegList;                      //0x10
    struct _ETW_GUID_ENTRY* GuidEntry;                    //0x20
    struct _ETW_GUID_ENTRY* GroupEntry;                   //0x28
    union
    {
        struct _ETW_REPLY_QUEUE* ReplyQueue;              //0x30
        struct _ETW_QUEUE_ENTRY* ReplySlot[4];            //0x30
        struct
        {
            VOID* Caller;                                 //0x30
            ULONG SessionId;                              //0x38
        };
    };
    union
    {
        struct _EPROCESS* Process;                        //0x50
        VOID* CallbackContext;                            //0x50
    };
    VOID* Callback;                                       //0x58
    USHORT Index;                                         //0x60
    union
    {
        USHORT Flags;                                     //0x62
        struct
        {
            USHORT DbgKernelRegistration:1;               //0x62
            USHORT DbgUserRegistration:1;                 //0x62
            USHORT DbgReplyRegistration:1;                //0x62
            USHORT DbgClassicRegistration:1;              //0x62
            USHORT DbgSessionSpaceRegistration:1;         //0x62
            USHORT DbgModernRegistration:1;               //0x62
            USHORT DbgClosed:1;                           //0x62
            USHORT DbgInserted:1;                         //0x62
            USHORT DbgWow64:1;                            //0x62
            USHORT DbgUseDescriptorType:1;                //0x62
            USHORT DbgDropProviderTraits:1;               //0x62
        };
    };
    UCHAR EnableMask;                                     //0x64
    UCHAR GroupEnableMask;                                //0x65
    UCHAR HostEnableMask;                                 //0x66
    UCHAR HostGroupEnableMask;                            //0x67
    struct _ETW_PROVIDER_TRAITS* Traits;                  //0x68
};

ETW_GUID_ENTRY

أحد الإدخالات المتداخلة داخل _ETW_REG_ENTRY هو GuidEntry، وهو عبارة عن بنية _ETW_GUID_ENTRY. ويمكن العثور على مزيد من المعلومات حول هذه البنية غير الموثقة في مدونة Geoff Chappell هنا وعبر مشروع Vergilius.

// 0x1a8 بايت (sizeof)
// Win11 22H2 10.0.22621.382
struct _ETW_GUID_ENTRY
{
    struct _LIST_ENTRY GuidList;                          //0x0
    struct _LIST_ENTRY SiloGuidList;                      //0x10
    volatile LONGLONG RefCount;                           //0x20
    struct _GUID Guid;                                    //0x28
    struct _LIST_ENTRY RegListHead;                       //0x38
    VOID* SecurityDescriptor;                             //0x48
    union
    {
        struct _ETW_LAST_ENABLE_INFO LastEnable;          //0x50
        ULONGLONG MatchId;                                //0x50
    };
    struct _TRACE_ENABLE_INFO ProviderEnableInfo;         //0x60
    struct _TRACE_ENABLE_INFO EnableInfo[8];              //0x80
    struct _ETW_FILTER_HEADER* FilterData;                //0x180
    struct _ETW_SILODRIVERSTATE* SiloState;               //0x188
    struct _ETW_GUID_ENTRY* HostEntry;                    //0x190
    struct _EX_PUSH_LOCK Lock;                            //0x198
    struct _ETHREAD* LockOwner;                           //0x1a0
};

TRACE_ENABLE_INFO

وأخيرًا، أحد الإدخالات المتداخلة داخل _ETW_GUID_ENTRY هو ProviderEnableInfo وهو عبارة عن بنية _TRACE_ENABLE_INFO. لمزيد من المعلومات حول عناصر بنية البيانات هذه، يمكنك الرجوع إلى وثائق Microsoft الرسمية ومشروع Vergilius. وتؤثر الإعدادات الموجودة في هذه البنية بشكل مباشر على العمليات وقدرات الموفر.

// 0x20 بايت (sizeof)
// Win11 22H2 10.0.22621.382
struct _TRACE_ENABLE_INFO
{
    ULONG IsEnabled;                                       //0x0
    UCHAR Level;                                           //0x4
    UCHAR Reserved1;                                       //0x5
    USHORT LoggerId;                                       //0x6
    ULONG EnableProperty;                                  //0x8
    ULONG Reserved2;                                       //0xc
    ULONGLONG MatchAnyKeyword;                             //0x10
    ULONGLONG MatchAllKeyword;                             //0x18
};

فهم استخدام مرجع التسجيل

في حين أن بعض الخلفيات النظرية جيدة، فمن الأفضل دائمًا النظر إلى استخدام الأمثلة الملموسة لاكتساب فهم أعمق للموضوع. دعونا نلقي نظرة سريعة على مثال. تتم تهيئة معظم موفري Kernel ETW المهمين داخل، nt!EtwpInitialize، والتي لا يتم تصديرها. وبالنظر إلى هذه الدالة، نجد حوالي خمسة عشر مزود خدمة.

لقطة شاشة لرمز فك nt!EtwpInitialize الجزئي
الشكل 4، فك nt!EtwpInitialize الجزئي

بأخذ مدخل Microsoft-Windows-Threat-Intelligence (EtwTi) كمثال، يمكننا التحقق من معلمة ThreatIntProviderGuid العالمي لاستعادة GUID لهذا المزود.

لقطة شاشة لرمز معرّف GUID لموفر EtwTi
الشكل 5، GUID لموفر EtwTi

سيكشف البحث في GUID هذا عبر الإنترنت على الفور عن قدرتنا على استرداد القيمة الصحيحة (f4e1897c-bb5d-5668-f1d8-040f4d8dd344).

لنلقِ نظرة على مثيل حيث تُستخدم معلمة مؤشر مرجع التسجيل،EtwThreatIntProvRegHandle، ونحلل كيفية استخدامها. المكان الذي تمت فيه الإشارة إلى المرجع هو nt!EtwTiLogDriverObjectUnLoad. من اسم هذه الدالة، يمكننا أن نستنتج أنها تهدف إلى توليد أحداث عندما يتم تفريغ كائن برنامج التشغيل من قبل Kernel.

لقطة شاشة لرمز فك nt!EtwTiLogDriverUnload
الشكل 6، فك nt!EtwTiLogDriverUnload

يتم استدعاء كل من دالتي nt!EtwEventEnabled وnt!EtwProviderEnabled هنا لتمرير مرجع التسجيل كأحد الوسيطات. لنلقِ نظرة على إحدى هذه الوظائف الفرعية لفهم المزيد عما يحدث.

لقطة شاشة لرمز فك nt!EtwProviderEnable
الشكل 7، إلغاء تجميع nt!EtwProviderEnable

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

struct _ETW_REG_ENTRY
{
    …
    struct _ETW_GUID_ENTRY* GuidEntry;                    //0x20
    …
}

وخاصية  GuidEntry->ProviderEnableInfo .

struct _ETW_GUID_ENTRY
{
    …
    struct _TRACE_ENABLE_INFO ProviderEnableInfo;         //0x60
    …
}

تنتقل الدالة بعد ذلك إلى عمليات فحص مماثلة على أساس المستوى. وأخيرًا، تُرجع الدالة القيمة true أو false للإشارة إلى ما إذا كان الموفر ممكّنًا لتسجيل الأحداث على مستوى وكلمة مفتاحية محددة. ويتوفر المزيد من التفاصيل باستخدام وثائق Microsoft الرسمية.

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

مهاجمة مراجع التسجيل

وبالنظر إلى سطح الهجوم المعلن من قبل Binarly وبالاعتماد على تحليلنا الخفيف، يمكننا أن نفترض بعض الاستراتيجيات لتعطيل جمع الأحداث.

  • يمكن للمهاجك تعيين المؤشر _ETW_REG_ENTRY إلى القيمة NULL . وستفترض أي دوال تشير إلى مرجع التسجيل بعد ذلك أنه لم يتم تهيئة الموفر.
  • يمكن للمهاجم تعيين القيمة NULL إلى المؤشر _ETW_REG_ENTRY->GuidEntry->ProviderEnableInfo . ومن المفترض أن يؤدي هذا إلى تعطيل قدرات جمع البيانات الخاصة بالموفر بشكل فعال، حيث أن ProviderEnableInfo هو مؤشر إلى بنية _TRACE_ENABLE_INFO التي تحدد كيفية عمل الموفر.
  • ويمكن للمهاجم استبدال خصائص بنية بيانات _ETW_REG_ENTRY->GuidEntry->ProviderEnableInfo للتلاعب بتكوين الموفر.
    • isEnabled: تعيين على 1 لتمكين تلقي الأحداث من الموفر أو لضبط الإعدادات المستخدمة عند تلقي الأحداث من الموفر. وقم بالتعيين على 0 لتعطيل تلقي الأحداث من الموفر.
    • Level: قيمة تشير إلى المستوى الأقصى للأحداث التي تريد أن يكتبها الموفر. ويكتب الموفر عادةً حدثًا إذا كان مستوى الحدث أقل من هذه القيمة أو مساويًا لها، بالإضافة إلى استيفاء معيار MatchAnyKeyword وMatchAllKeyword.
    • MatchAnyKeyword: قناع بت 64 بت للكلمات المفتاحية التي تحدد تأكيد الأحداث التي تريد من الموفر كتابتها. ويكتب الموفر عادةً حدثًا إذا كانت بتات الكلمات المفتاحية للحدث تتطابق مع أيٍّ من البتات المحددة في هذه القيمة أو إذا لم يتم تعيين بتات للكلمات المفتاحية في الحدث، وذلك بالإضافة إلى استيفاء معياري Level وMatchAllKeyword.
    • MatchallKeyword: قناع بت 64 بت للكلمات المفتاحية التي تقيد الأحداث التي تريد أن يكتبها الموفر. وعادةً ما يكتب الموفر حدثًا إذا كانت بتات الكلمات المفتاحية للحدث تتطابق مع جميع وحدات البت المحددة في هذه القيمة أو إذا لم يتم تعيين بتات للكلمات المفتاحية في الحدث، وذلك بالإضافة إلى استيفاء معايير Level وMatchAnyKeyword.

أساليب البحث في Kernel

لدينا الآن فكرة جيدة عن شكل هجوم DKOM على ETW. ولنفترض أن المهاجم لديه ثغرة أمنية تمنح نواة Kernel عنصر أساسي للقراءة والكتابة (Kernel Read/Write)، كما هو الحال مع برنامج Lazarus الضار في هذه الحالة عند تحميل برنامج تشغيل ضعيف. ما ينقصنا هو طريقة للعثور على مراجع التسجيل هذه.

سوف أحدد تقنيتين رئيسيتين للعثور على هذه المراجع وإظهار المتغير الخاص بالتقنية التي يستخدمها Lazarus في حمولة Kernel الخاصة به.

تجاوز KASLR بمستوى النزاهة المتوسط (MEDIL)

أولاً، قد يكون من الحكمة توضيح أنه على الرغم من وجود Kernel ASLR، فإن هذا ليس حدًا أمنيًا للمهاجمين المحليين إذا كان بإمكانهم تنفيذ الرمز في MEDIL أو أعلى. وهناك العديد من الطرق لتسريب مؤشرات Kernel المقيدة فقط في سيناريوهات آلية تحديد الوصول أو LowIL. وللحصول على بعض المعلومات الأساسية، يمكنك إلقاء نظرة على لدي 99 مشكلة ولكن مؤشر Kernel ليس واحدًا بواسطة Alex Ionescu، لا تزال العديد من هذه التقنيات قابلة للتطبيق اليوم.

الأداة المفضلة هنا هي ntdll!NtQuerySystemInformation مع فئة SystemModuleInformation:

internal static UInt32 SystemModuleInformation = 0xB;

[DllImport(“ntdll.dll”)]
internal static extern UInt32 NtQuerySystemInformation(
    UInt32 SystemInformationClass,
    IntPtr SystemInformation,
    UInt32 SystemInformationLength,
    ref UInt32 ReturnLength);

تُرجع هذه الدالة العنوان الأساسي المباشر لجميع الوحدات النمطية المحملة في مساحة Kernel. وفي هذه المرحلة، من الممكن تحليل هذه الوحدات على القرص وتحويل إزاحات الملفات الأولية إلى عناوين افتراضية نسبية والعكس صحيح.

public static UInt64 RvaToFileOffset(UInt64 rva, List<SearchTypeData.IMAGE_SECTION_HEADER> sections)
{
    foreach (SearchTypeData.IMAGE_SECTION_HEADER section in sections)
    {
        if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.VirtualSize)
        {
            return (rva – section.VirtualAddress + section.PtrToRawData);
        }
    }
    return 0;
}

public static UInt64 FileOffsetToRVA(UInt64 fileOffset, List<SearchTypeData.IMAGE_SECTION_HEADER> sections)
{
    foreach (SearchTypeData.IMAGE_SECTION_HEADER section in sections)
    {
        if (fileOffset >= section.PtrToRawData && fileOffset < (section.PtrToRawData + section.SizeOfRawData))
        {
            return (fileOffset – section.PtrToRawData) + section.VirtualAddress;
        }
    }
    return 0;
}

كما يمكن للمهاجم تحميل هذه الوحدات النمطية في عملية أرض المستخدم باستخدام استدعاءات واجهة برمجة تطبيقات مكتبة التحميل القياسية (على سبيل المثال، ntdll!LdrLoadDll). وسيؤدي القيام بذلك إلى تجنب تعقيدات تحويل إزاحات الملفات إلى RVA والرجوع إليها. ومع ذلك، من وجهة نظر الأمن التشغيلي (OpSec) فإن هذا ليس مثاليًا من وجهة نظر الأمن التشغيلي (OpSec) لأنه يمكن أن يولد المزيد من عمليات الكشف عن بُعد.

الطريقة الأولى: سلاسل مقاطع الرموز

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

بالنظر إلى مراجع تسجيل ETW، دعونا نأخذ Microsoft Windows-استعلامات التهديدات كمثال. فيما يلي، يمكنك رؤية المكالمة الكاملة إلى nt!EtwRegister.

لقطة شاشة لفك CALL بالكامل لدالة nt!EtwRegister
الشكل 8، فك كامل لدالة الاستدعاء nt!EtwRegister

نريد هنا تسريب المؤشر إلى مرجع التسجيل،EtwThreatIntProvRegHandle. وكما رأينا تم تحميله في param_4 في السطر الأول من الشكل 8. ويتحول هذا المؤشر إلى مؤشر عمومي داخل قسم .data في وحدة Kernel النمطية. ونظرًا لأن هذا الاستدعاء يحدث في دالة غير مُصدرة، فإنه لا يمكننا تسريب عنوانها مباشرةً. وبدلاً من ذلك، علينا أن ننظر إلى المكان الذي يُشار فيه إلى هذا المؤشر العمومي ونرى ما إذا كان مستخدم في دالة يمكن أن يتسرب عنوانها.

لقطة شاشة من الرمز لمراجع nt!EtwThreatIntProvRegHandle
الشكل 9، مراجع nt!EtwThreatIntProvRegHandle

يكشف استكشاف بعض هذه الإدخالات بسرعة عن مرشح في nt!KeInsertQueueApc.

لقطة شاشة لرمز فك التجميع الجزئي لـ nt!KeInsertQueueApc
الشكل 10، فك nt!KeInsertQueueApc جزئي

هذا مرشح رائع لعدة أسباب:

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

يوضح النظر إلى التجميع التخطيط التالي.

لقطة شاشة لرمز فك nt!KeInsertQueueApc الجزئي
الشكل 11، عدم التجميع nt!KeInsertQueueApc الجزئي

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

Int32 pOffset = Marshal.ReadInt32((IntPtr)(pBuff.ToInt64() + i + 3));
hEtwTi = (IntPtr)(pOffset + i + 7 + oKeInsertQueueApc.pAddress.ToInt64());

باستخدام مرجع التسجيل، يمكن بعد ذلك الوصول إلى بنية البيانات _ETW_REG_ENTRY.

وبشكل عام، يمكن استخدام سلاسل مقاطع الرموز هذه لتسريب مجموعة متنوعة من بنى بيانات Kernel. ومع ذلك، تجدر الإشارة إلى أنه ليس من الممكن دائمًا العثور على سلاسل مقاطع الرموز هذه وأحيانًا قد تحتوي سلاسل مقاطع الرموز على مراحل معقدة متعددة. على سبيل المثال، قد تبدو سلسلة مقاطع الرموز المحتملة لتسريب ثوابت إدخال دليل الصفحات (PDE) على هذا النحو.

MmUnloadSystemImage -> MiUnloadSystemImage -> MiGetPdeAddress

في الواقع، كشف تحليل سريع لمراجع تسجيل ETW أن معظمهم ليس لديهم سلاسل مقاطع رموز مناسبة يمكن استخدامها كما هو موضح أعلاه.

الطريقة الثانية: مسح الذاكرة

الخيار الرئيسي الآخر لتسريب مراجع تسجيل ETW هذه هو استخدام مسح الذاكرة، إما من ذاكرة Kernel المباشرة أو من وحدة نمطية على القرص. وتذكر أنه عند مسح الوحدات النمطية على القرص، من الممكن تحويل إزاحات الملفات إلى RVAs.

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

لقطة شاشة لرمز فك nt!EtwpInitialize الجزئي
الشكل 12، فك nt!EtwpInitialize الجزئي

يتم تجميع جميع الاستدعاءات الخمسة عشر الموجهة إلى nt!EtwRegister  في الغالب في هذه الدالة. وتتمثل الاستراتيجية الرئيسية هنا في العثور على نمط فريد يظهر قبل الاستدعاء الأول لـ nt!EtwRegister ونمط ثانٍ يظهر بعد آخر استدعاء لـ nt!EtwRegister. وهذا ليس معقدًا جدًا. وتتمثل إحدى الحيل التي يمكن استخدامها لتحسين قابلية النقل في إنشاء ماسح ضوئي للنمط قادر على التعامل مع سلاسل البايت التي تحتوي على قيم بديلة. وهذه مهمة تركت للقارئ.

بمجرد تحديد مؤشر البدء والإيقاف، يمكن الاطلاع على جميع التعليمات التي تظهر بينهما.

  • يمكن تحديد تعليمات CALL المحتملة بناءً على رمز التشغيل للدالة CALL وهو 0xe8.
  • وبعد ذلك، يتم استخدام قراءة بحجم DWORD لحساب الإزاحة النسبية لتعليمات CALL المحتملة.
  • ثم تتم إضافة هذه الإزاحة إلى العنوان النسبي لـ CALL وزيادته بمقدار خمسة (حجم تعليمات التجميع).
  • وأخيرًا، يمكن مقارنة هذه القيمة الجديدة بـ nt!EtwRegister للعثور على جميع مواقع CALL الصالحة.

وبمجرد العثور على جميع تعليمات CALL، يصبح من الممكن البحث فيما سبق واستخراج وسيطات الوظيفة، أولاً GUID الذي يحدد موفر ETW وثانيًا، عنوان مرجع التسجيل. ومع وجود هذه المعلومات في متناول اليد، يمكننا تنفيذ هجمات DKOM المستنيرة على مراجع التسجيل للتأثير على عمل الموفرين المحددين.

تصحيح Lazarus ETW

حصلت على عينة من ملف  FudModle DLL المذكور في مستندات ESET الفنية  وقمت بتحليلها. ويقوم ملف DLL هذا بتحميل برنامج تشغيل Dell ضعيف تم توقيعه (من موارد XOR المشفرة المضمنة) ثم يقوم بتشغيل برنامج التشغيل لتصحيح العديد من بنيات Kernel للحد من القياس عن بُعد على المضيف.

لقطة شاشة لرمز التجزئة لـ Lazarus FudModule
الشكل 13، تجزئة Lazarus FudModule

كجزء أخير من هذا المنشور، أود مراجعة الاستراتيجية التي يستخدمها Lazarus للعثور على مراجع تسجيل Kernel ETW. وإنه اختلاف في طريقة المسح التي ناقشناها أعلاه.

في بداية دالة البحث، يقوم Lazarus بحل nt!EtwRegister ويستخدم هذا العنوان لبدء المسح

لقطة شاشة لرمز فك بحث ETW الجزئي لـ Lazarus FudModule
الشكل 14، فك بحث Lazarus FudModule الجزئي ETW

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

عند البحث عن مراجع إلى nt!EtwRegister في ntoskrnl ، يبدو أنه لم يتم تفويت الكثير من الإدخالات باستخدام هذه التقنية. ربما أجرى Lazarus أيضًا تحليلاً إضافيًا لتحديد أن الإدخالات الفائتة ليست مهمة أو لا تحتاج إلى تصحيح. وفيما يلي، يتم تمييز الإدخالات الفائتة. ويسمح استخدام الاستراتيجية هذه لـ Lazarus بتخطي 0x7b1de0 بايت أثناء إجراء المسح الذي قد يكون مقدارًا غير تافه إذا كان الماسح الضوئي بطيئًا.

لقطة شاشة لرمز حالات استدعاء nt!EtwRegister
الشكل 15، مثيلات الاستدعاءات إلى nt!EtwRegister

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

لقطة شاشة لرمز فك بحث ETW الجزئي لـ Lazarus FudModule
الشكل 16، فك بحث Azarus FudModule الجزئي ETW

الرمز غامض بعض الشيء، لكننا نستوعب النقاط الرئيسية للفكرة. يبحث الرمز عن استدعاءات إلى nt!EtwRegister، ويستخرج مرجع التسجيل، ويحوّل هذا المرجع إلى العنوان المباشر باستخدام تجاوز KASLR، ويضع المؤشر في مصفوفة مخصصة لهذا الغرض ضمن بنية تكوين برنامج ضار (المخصصة عند التهيئة).

وأخيرًا، دعونا نلقي نظرة على ما يفعله Lazarus لتعطيل هؤلاء الموفرين.

لقطة شاشة لرمز معالجات تسجيل Lazarus FudModule NULL ETW
الشكل 17، مراجع تسجيل Lazarus FudModule NULL ETW

هذا منطقي في الغالب، ما يفعله Lazarus هنا هو تسريب المتغير العام الذي رأيناه سابقًا ثم الكتابة فوق المؤشر في ذلك العنوان باستخدام القيمة NULL. وهذا يمحو الإشارة إلى بنية البيانات _ETW_REG_ENTRY بشكل فعال إذا كانت موجودة.

لست سعيدًا تمامًا بالأساليب المعروضة لعدة أسباب:

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

لقد أعدت تطبيق هذه التقنية في مجال العلوم؛ ولكنني أجريت بعض التعديلات على الأساليب.

  • يتم استخدام خوارزمية بحث محسّنة للسرعة للعثور على جميع وحدات البايت 0xe8 في ntoskrnl.
  • وبعد ذلك، تتم بعض المعالجة اللاحقة لتحديد تعليمات CALL الصالحة والوجهات الخاصة بكل منها.
  • ليست كل الاستدعاءات إلى nt!EtwRegister  مفيدة لأنه في بعض الأحيان تُستدعى الدالة باستخدام وسيطة ديناميكية لمرجع التسجيل. ولهذا السبب، هناك حاجة إلى بعض المنطق الإضافي لتصفية الاستدعاءات المتبقية.
  • وأخيرًا، يتم حل جميع مُعرفات GUID إلى نموذج قابل للقراءة البشرية ويتم تعداد مراجع التسجيل.

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

تأثير ETW DKOM

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

ومع ذلك، فإن بعض المجموعات الفرعية من هؤلاء الموفرين حساسة أمنيًا. أوضح مثال على ذلك هو Microsoft Windows-استعلامات التهديدات (EtwTi)، وهو مصدر بيانات أساسي لبرنامج Microsoft Defender Advanced Threat Protection (MDATP) والذي أصبح الآن يسمى Defender for Endpoint (كل هذا مربك جدًا). يُجدر بالذكر أن الوصول إلى هذا الموفر مقيد بشدة، ولا يستطيع التسجيل لدى هذا الموفر سوى برامج تشغيل Early Launch Anti Malware(ELAM). وبالمثل، يجب أن تتمتع العمليات في طبقة المستخدم التي تتلقى هذه الأحداث بحالة محمية (ProtectedLight / Antimalware) وأن تكون موقعة بنفس شهادة برنامج تشغيل ELAM.

باستخدام EtwExplorer يمكن الحصول على فكرة أفضل عن أنواع المعلومات التي يمكن أن يشير إليها هذا الموفر.

لقطة شاشة لصفحة ملف ETW Explorer
الشكل 18، مستكشف ETW

يُعد بيان XML أكبر من أن يتم تضمينه هنا بالكامل، ولكن يتم عرض حدث واحد أدناه لإعطاء فكرة عن أنواع البيانات التي يمكن منعها باستخدام DKOM.

لقطة شاشة لرمز بيان XML الجزئي لـ EtwTi
الشكل 19، بيان XML الجزئي لـ EtwTi

الخاتمة

لطالما كانت النواة ولا تزال منطقة مهمة ومثيرة للجدل، حيث تحتاج Microsoft ومقدمو الخدمات الخارجيون إلى بذل جهود لحماية سلامة نظام التشغيل. لا يُعد تلف البيانات في Kernel أحد أهداف ما بعد الاستغلال فحسب، بل يُعد أيضًا عنصرًا مركزيًا في تطوير Kernel. ولقد أحرزت Microsoft تقدمًا كبيرًا في هذا المجال بالفعل مع تقديم الأمان القائم على محاكاة افتراضية (VBS) وواحد من عناصرها مثل حماية بيانات Kernel (KDP).

ويحتاج مستهلكو نظام التشغيل Windows بدورهم إلى التأكد من الاستفادة من هذه التطورات لفرض أكبر قدر ممكن من التكلفة على المهاجمين المحتملين. ويمكن استخدام Windows Defender Application Control (WDAC) لضمان وجود ضمانات حماية VBS ووجود السياسات التي تحظر تحميل برامج التشغيل التي قد تكون خطيرة.

وتزداد أهمية هذه الجهود لأننا نرى بشكل متزايد أن عناصر تهديد السلع تستفيد من هجمات BYOVD لأداء DKOM في مساحة Kernel.

 

Mixture of Experts | 12 ديسمبر، الحلقة 85

فك تشفير الذكاء الاصطناعي: تقرير إخباري أسبوعي

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

مراجع إضافية

  • Veni, No Vidi, No Vici: الهجمات على مستشعرات اكتشاف نقاط النهاية والاستجابة لها العمياء لـ ETW (شرائح BHEU 2021) هنا
  • Veni, No Vidi, No Vici: الهجمات على مستشعرات اكتشاف نقاط النهاية والاستجابة لها العمياء لـ ETW (فيديو BHEU 2021) هنا
  • تطوير أمن Windows (BlueHat Shanghai 2019)، هنا
  • استغلال ثغرة أمنية "بسيطة"، في 35 خطوة سهلة أو أقل!، هنا
  • استغلال ثغرة أمنية "بسيطة"، الجزء 1.5، تسرب المعلومات، هنا
  • مقدمة إلى استعلامات التهديدات ETW، هنا
  • TelemetrySourcerer، هنا
  • معالج سياسة WDAC، هنا

تعرف على المزيد حول X-Force Red هنا. احجز موعدًا لاستشارة مجانية مع X-Force هنا.

حلول ذات صلة
حلول الأمن المؤسسي

طوّر برنامجك الأمني بشكل غير مسبوق بفضل الحلول المقدمة من أكبر موفري خدمات الأمن المؤسسي.

استكشف حلول الأمن الإلكتروني
خدمات الأمن الإلكتروني

يمكنك تحويل أعمالك وإدارة المخاطر من خلال الخدمات الاستشارية في الأمن الإلكتروني والخدمات السحابية وخدمات الأمان المُدارة.

    استكشف خدمات الأمن الإلكتروني
    الأمن الإلكتروني بالذكاء الاصطناعي (AI)

    حسِّن سرعة الفرق الأمنية ودقتها وإنتاجيتها باستخدام حلول الأمن السيبراني المدعومة بالذكاء الاصطناعي.

    استكشف الأمن السيبراني بالذكاء الاصطناعي
    اتخِذ الخطوة التالية

    سواء كنت بحاجة إلى حلول أمن البيانات أو إدارة نقاط النهاية أو إدارة الهوية والوصول (IAM)، فإن خبرائنا مستعدون للعمل معك لتحقيق وضع أمني قوي. طوّر أعمالك وتمكّن من إدارة المخاطر في مؤسستك مع شركة عالمية رائدة في مجال استشارات الأمن السيبراني، والخدمات السحابية، والخدمات الأمنية المُدارة.

    استكشف حلول الأمن الإلكتروني اكتشف خدمات الأمن السيبراني