تجاوز Windows Defender Application Control باستخدام Loki C2
يُعد Windows Defender Application Control (WDAC) حلاً أمنيًا يقيّد تنفيذ البرامج ليشمل البرامج الموثوقة فقط. ونظرًا إلى أنها مصنفة كأحد الحدود الأمنية، تقدّم Microsoft مكافآت مالية مقابل اكتشاف التجاوزات المؤهلة، ما يجعل هذا المجال نشطًا وتنافسيًا غي مجال البحث الأمني.
النتائج النموذجية لتقديم مكافأة أخطاء تخطي WDAC:
وبمراجعة قائمة الحظر الموصى بها من Microsofts WDAC، نرى أسماء بارزة مثل Jimmy Bayne (@bohops) وCasey Smith (@subTee) اكتشفوا ثغرات لتجاوز WDAC لا تزال دون إصلاح، لكنها حظيت بتنويه شرفي. وبعيدًا عن هذه القائمة، يتضمن مشروع LOLBAS Project أساليب تجاوز إضافية لم تُصلَح بعد، ولم تُدرَج ضمن قائمة الحظر لدى Microsoft. ومن الأمثلة على ذلك تطبيق Microsoft Teams، الذي لا يزال يُعد وسيلة قابلة للاستخدام لتجاوز WDAC، رغم توثيقه ضمن LOLBAS.
عندما واجهنا WDAC في أثناء عمليات الفريق الأحمر، نجحنا في تخطيه ونفذنا حمولة القيادة والتحكم (C2) من المرحلة الثانية باستخدام التقنيات التالية:
1. استخدم تقنية LOLBIN معروفة مثل MSBuild.exe
2. التحميل الجانبي لملف DLL غير موثوق من خلال تطبيق موثوق
3. استغلال قاعدة استبعاد مخصّصة ضمن سياسة WDAC الخاصة بالعميل
4. اكتشاف عملية تنفيذ جديدة في تطبيق موثوق تسمح بنشر C2
وكما أوضح Ruben Boonen (@FuzzySec) في كلمته التي ألقاها في Wild West Hackin’ Fest بعنوان Statikk Shiv: الاستفادة من تطبيقات Electron في مهام ما بعد الاستغلال، تعمل تطبيقات Electron كمتصفحات ويب تعرض تطبيقات سطح المكتب باستخدام تقنيات الويب القياسية مثل HTML وJavaScript وCSS. محرك JavaScript في Electron هو Node.js، التي توفر واجهات برمجة تطبيقات فائقة تتمكن من التفاعل مع نظام التشغيل المضيف. تسمح هذه الواجهات بتنفيذ إجراءات مثل قراءة وكتابة الملفات، وتنفيذ البرامج وعمليات أخرى تقليدية في التطبيقات الأصلية.
في وقت التشغيل، يقرأ تطبيق Electron ملفات JavaScript، ويفسر أكوادها وينفذها ضمن عملية Electron. يوضح الرسم المتحرك أدناه كيفية قراءة تطبيق Microsoft Teams Electron لملف JavaScript في وقت التشغيل، والذي يستخدم بعد ذلك وحدة child_process لتنفيذ whoami.exe.
في هذا المثال، تقرأ عملية Teams Electron ملف JavaScript، والذي يُنشئ بعد ذلك whoami.exe باستخدام وحدة child_process. تشغل هذه الوحدة عملية Electron لتنفيذ uv_spawnالخاصة بواجهة برمجة التطبيقات المصدرة والمسؤولة عن التفاعل مع نظام التشغيل لإنشاء عملية جديدة.
تتكون البنية التقليدية لتطبيقات Windows مما يلي:
يستدعي الملف EXE الدوال المصدرة من ملفات DLL لتوسيع إمكاناته. إلا أن تطبيقات Electron تعكس هذه البنية. فبدلاً من استدعاء EXE لواجهات برمجة التطبيقات من ملفات DLL، يعرض Electron EXE نفسه عمليات تصدير واجهات برمجة التطبيقات، والتي تستدعيها ما يلي:
تسمح هذه البنية بتفاعل Node.js JavaScript ووحدات Node مع نظام التشغيل بطرق لا يستطيع JavaScript التقليدي في المتصفحات فعلها.
في الصورة أدناه، نفحص تطبيق Teams Electron باستخدام أداة PE Bear، وهي أداة رائعة أنشأها @hasherezade، وهي التي تكشف أن ملف Teams Electron التنفيذي يحتوي على 2977 واجهة برمجة تطبيقات مصدرة. يوفر هذا الكم الهائل من واجهات برمجة التطبيقات وظائف واسعة يمكن الاستفادة منها من خلال ملفات Node.js JavaScript ووحدات Node للتفاعل مع نظام التشغيل.
نظرًا إلى أن تطبيقات Electron تنفذ JavaScript وقت التشغيل، فإن تعديل ملفات JavaScript هذه يسمح للمهاجمين بحقن كود Node.js عشوائي في عملية Electron. ومن خلال الاستفادة من واجهات برمجة تطبيقات Node.js وChromium، يمكن لكود JavaScript التفاعل مع نظام التشغيل.
لم أكتشف بنفسي إمكانية تعديل ملفات JavaScript الخاصة بتطبيقات Electron الموثوقة لتنفيذ كود Node.js JavaScript عشوائي. يعود تاريخ أقدم المراجع التي وجدتها إلى عام 2022.
في بداية عام 2022، نشر Andrew Kisliakov مدونة "Microsoft Teams وتطبيقات Electron الأخرى بمثابة LOLbins". أسهم Andrew و@mrd0x بالنتائج التي توصلوا إليها في مشروع LOLBAS.
وفي وقت لاحق من عام 2022، استكشف كل من Valentina Palmiotti (@chompie1337)، وEllis Springe (@knavesec)، وRuben هذا النهج بشكل أكبر، ما أدى إلى تطوير أداة استمرارية داخلية استُخدمت لاحقًا في عمليات الفريق الأحمر.
في عام 2022 أيضًا، نشر Michael Taggart مشروع quASAR، وهي أداة مصممة لتعديل تطبيقات Electron بهدف تمكين تنفيذ الأوامر. في مدونته "Quasar: اختراق تطبيقات Electron"، شارك أنه في سبتمبر 2022، تواصل معه أحد أعضاء مشروع Electron، وأبلغه أن التحقق من السلامة كان ميزة تجريبية وأنهم يتطلعون إلى دعمها بالكامل في المستقبل.
من خلال تجربتي الشخصية مع تطبيقات Electron الحديثة مثل Signal، تأكدت من أن عمليات التحقق من السلامة أصبحت الآن مطبقة على بعض تطبيقات Electron، ما يمنع تعديل ملفات JavaScript الخاصة بها. ومع ذلك، لا تزال العديد من تطبيقات Electron الموزعة على نطاق واسع عرضة للخطر.
وقد رُصدت هذه التقنية أيضًا في هجمات واقعية. في عام 2022، اخترق عنصر تهديد تطبيق الدردشة MiMi من خلال باب خلفي عن طريق تعديل ملفات JavaScript المرفقة على خادم التوزيع. حددت Trend Micro هذا الهجوم كهجوم على سلسلة توريد، حيث جرى توزيع تطبيق Electron المخترق على المستخدمين النهائيين، ما أتاح تنفيذ كود JavaScript خبيث ينزل حمولة C2 في المرحلة الثانية وينفذها.
في شهر أبريل من عام 2024، كان Bobby Cooke (@0xBoku) يبحث عن عملية تنفيذ جديدة لاستخدامها استعدادًا لعملية الفريق الأحمر القادمة لأحد العملاء في القطاع المالي. ويتميز هذا القطاع بمعايير أمنية أعلى ولوائح أكثر صرامة، وغالبًا ما يُطبق ضوابط أمنية إضافية مثل WDAC. في أثناء بحثي، عثرت على تطبيق Electron آخر معرض للخطر. لكن، نظرًا إلى أنه غير موقع من Microsoft، فمن غير المرجح أن يتخطى سياسة WDAC الخاصة بالعميل.
ثم انتقلت إلى تطبيق Microsoft Teams القديم، وهو موقع من Microsoft ويمكنه تخطي حتى أكثر سياسات WDAC صرامة. في هذه المرحلة، انضم إليّ Dylan Tran (@d_tranman) في هذه المهمة، وبدأنا نبحث عن طريقة لزيادة الامتيازات من تنفيذ Node.js JavaScript عشوائي إلى تنفيذ كود shellcode C2 في المرحلة الثانية.
بينما يمكن أن يتفاعل Node.js مع نظام التشغيل من خلال واجهات برمجة التطبيقات الخاصة به، إلا أنه يفتقر إلى الوظائف الكاملة للغة C، حيث يمكن للمطورين استدعاء WINAPIs وNTAPIs مباشرة. ولسد هذه الفجوة، أنشأ المطورون وحدات Node توسع إمكانات إطار العمل Node.js. هذه الوحدات، محولة برمجيًا من كود C++، يمكنها استدعاء WINAPIs، والتفاعل مع واجهات برمجة التطبيقات Node.js وتنفيذ JavaScript داخل تطبيقات Electron. تحتوي وحدات Node المحولة برمجيًا على امتداد .node وتُحمل في عمليات Windows عبر حدث تحميل DLL.
خلال بحثنا، فحصنا العديد من تطبيقات Electron وحللنا وحدات Node الموقعة الخاصة بها. لقد اكتشفنا أنه يمكن التفاعل مع هذه الوحدات مباشرةً من JavaScript، ما يسمح لنا بالاستفادة من إمكاناتها المدمجة.
بينما يُعد إنشاء وحدات Node مخصصة لتنفيذ كود shellcode نهجًا قابلاً للتطبيق وهو من إمكانات Loki C2، إلا أنه يطرح مشكلة الأسبقية. يؤدي تحميل وحدة Node من JavaScript إلى تشغيل حدث تحميل DLL، والذي يمكن حظره وفقًا لسياسات WDAC التي تفرض قواعد صارمة ضد ملفات DLL غير الموقعة. ولحسن الحظ، يوجد عدد كبير من وحدات Node الموقعة عبر تطبيقات Electron الشرعية.
بدا هذا النهج في تنفيذ الحمولة مبشرًا، لذا شاركنا نتائجنا مع Valentina وانضمت إلينا في هذه المهمة. وبفضل مساعدتها، تعمقنا أكثر في عكس وحدات Node الموقعة، بحثًا عن ثغرات أو إمكانات مدمجة تسمح لنا بتنفيذ كود shellcode عشوائي.
أحد الأمثلة على وحدة Node ذات الإمكانات المفيدة هو windows_process_tree.node، وهي وحدة موقعة من Microsoft ومرفقة مع Visual Studio Code. عند فحصها في PE Bear، فإنها تكشف عن وجود دالتين جرى تصديرهما، كما هو موضح أدناه.
على عكس ملفات DLL التقليدية، لا تُدرج وحدات Node جميع دوالها المتاحة في جدول التصدير. تُستدعى الدالة المصدرة napi_register_module_v1 من خلال عملية Electron وهي مسؤولة عن تحميل الوحدة وعرض وظائفها المُصدرة لعملية Electron. وهذا يكون بمثابة جسر، ما يُمكّن JavaScript داخل عملية Electron من استدعاء دوال الوحدة والتفاعل معها.
من الطرق البسيطة لإدراج جميع الدوال القابلة للاستدعاء في وحدة Node الاستفادة من كود Node.js أدناه.
عند تنفيذ نص Node.js البرمجي هذا في PowerShell، نرى وجود دالتين قابلتين للاستدعاء في windows_process_tree.node. وهما getProcessList وgetProcessCpuUsage.
وبفضل الاستمرارية، من الممكن تحديد كيفية استدعاء هذه الدوال من JavaScript. تتمثل أحد قيود Node.js في أنه يفتقر إلى واجهة برمجة تطبيقات مدمجة لإدراج جميع العمليات الجارية على النظام. وهذا القيد هو السبب في أن Microsoft طرحت الدالة getProcessList ضمن هذه الوحدة، ما وسع إمكانات تطبيق VS Code Electron.
من الممكن استرداد هذه المعلومات مباشرةً في JavaScript باستخدام الوحدة child_process لتنفيذ PowerShell في عملية فرعية، والذي يعرض تفاصيل حول العمليات الجارية. في الصورة أدناه، يُنشئ Loki C2 عملية PowerShell فرعية لاسترداد قائمة العمليات.
يمثل هذا النهج مخاطر أمنية تشغيلية كبيرة. يُعد تنفيذ عمليات PowerShell الفرعية قابلاً للكشف بشكل كبير ويزيد من احتمالية الإبلاغ عن عملية الاختراق أو حظرها. ولتجنب ذلك، يستفيد Loki C2 من وحدات Node الموقعة مثل windows_process_tree.node لتوسيع إمكانات Node.js.
يتضمن Loki C2 الأمر ps، الذي يسترجع معلومات العملية عن طريق تحميل وحدة windows_process_tree.node الموقعة من Microsoft واستدعاء الدالة getProcessList، كما هو موضح في الصورة أدناه.
يظهر أدناه كود Loki C2 JavaScript الذي يستدعي دالة getProcessList الموجودة في وحدة windows_process_tree.node. تُرجع الدالة getProcessList بيانات العملية بتنسيق JSON، والتي ينظمها Loki C2 في جدول منظم لتحسين إمكانية القراءة.
قد يكون تحديد كيفية استدعاء الدوال الموجودة داخل وحدات Node بشكل صحيح أمرًا صعبًا نظرًا إلى أن هياكلها الداخلية غير موثقة. ومع ذلك، وباستخدام أدوات مثل Ghidra، التي طورتها NSA، وبالتعاون مع مهندسين مهرة متخصصين في الهندسة العكسية مثل Valentina، نجحنا في تحليل هذه الوحدات وتحديد كيفية التفاعل مع دوالها.
اكتشفت Valentina في النهاية طريقة لتنفيذ كود shellcode الخاص بخادم C2 في المرحلة الثانية من دون تحميل ملف DLL غير موقع، ولكنني سأترك لها الأمر للكشف عن التفاصيل. عملتُ أنا وDylan وValentina معًا على تحسين التقنية لضمان الاستقرار خلال حملة التصيد الاحتيالي القادمة.
للأسف، أبلغ الفريق الأزرق عن حملتنا الأولية للتصيد الاحتيالي عبر البريد الإلكتروني وحظرها. وبعد هذا الإخفاق، بدأت أنا وBrett Hawkins (@h4wkst3r) الاستعداد لحملة ثانية. بصفتي المسؤول عن الحمولات، لم أكن أرغب في إعادة استخدام الحمولة نفسها—لأن ذلك سيسهل على الفريق الأزرق تتبعنا وإيقاف حملتنا الثانية. ومع ذلك، لم يكن لدينا الوقت الكافي لتطبيق تقنية Valentina على حمولة جديدة، لذلك بدأت في تطوير حمولة جديدة باستخدام طريقة بديلة.
عادة ما تُستغل إمكانية تنفيذ JavaScript عشوائيًا في تطبيقات Electron الموثوقة لتنفيذ أوامر تنشر وكيل C2. ومع ذلك، ومن دون تقنية Valentina، ستفشل هذه الطريقة في مواجهة WDAC، لأنها ستتطلب في النهاية تنفيذ برنامج غير موقّع، والذي من المحتمل أن يُحظر.
مع بقاء بضعة أيام فقط للاستعداد للحملة الثانية، خطرت لي الفكرة: ماذا لو أنشأت إطار عمل C2 كامل باستخدام JavaScript؟
إذا كان وكيل C2 نفسه مكتوبًا بالكامل بلغة JavaScript، فيمكنه إنشاء قناة C2 حتى ضد سياسات WDAC الأكثر صرامة. وعندئذٍ، يمكن إجراء استكشاف لإيجاد طريقة لنشر حمولة C2 في المرحلة الثانية. لن تكون هناك أي أحداث تحميل DLL غير موقعة—سيُنفذ JavaScript فقط ضمن عملية Teams الموثوق بها.
كل ما كنا نحتاجه هو وظائف كافية من أجل:
وباستخدام جميع أكواد Node.js التي كتبتها في أثناء بحثي، أعددت إثبات مفهوم لخادم C2 بين عشية وضحاها. في اليوم التالي، شاركته مع Dylan، وطورناه معًا بسرعة ليصبح خادم C2 وظيفي بالكامل يعتمد على JavaScript. كان خادم C2 لدينا يتمكن من فعل ما يلي:
حقق JavaScript C2، المعروف الآن باسم Loki C2، نجاحًا في الحملة الثانية. ومنذ ذلك الحين، واصلنا تحسين Loki C2 وتطويره، مضيفين المزيد من المزايا، مع زيادة الاستقرار وتعزيز الإمكانات.
بفضل كل المعرفة التي اكتسبتها من هذا البحث حول Electron، طوّرت واجهة مستخدم رسومية لأداة Loki C2 باستخدام إطار عمل Electron.
في الفيديو أدناه، أوضح كيفية تخطي سياسة WDAC صارمة باستخدام Loki C2. القسمان أدناه يوضحان ما يحدث في الفيديو.
في هذا العرض التوضيحي، يُنشر WDAC عبر App Control Policy Wizard على نسخة Windows Server 2025 EC2 محدثة في AWS. يوفر المعالج ثلاثة قوالب أساسية للسياسات:
يُعد وضع Windows الافتراضي هو الأكثر صرامة، حيث يسمح بتنفيذ ما يلي:
في العرض التوضيحي، حُددت سياسة وضع Windows الافتراضي. وجرى تعطيل وضع التدقيق الافتراضي بحيث يفرض WDAC السياسات على الفور. بالإضافة إلى ذلك، جرى التحقق من خيارات الدمج مع قوائم الحظر الموصى بها والتي تتضمن القواعد الموجودة في قائمة حظر WDAC الموصى بها من Microsoft. يُنشئ معالج التحكم في التطبيق ملف XML وملف CIP لسياسة WDAC، والتي تُنشر بعد ذلك على الخادم باستخدام CITool.exe.
بمجرد تنشيط WDAC، حاولت تنفيذ Loki C2 Agent.exe، لكن WDAC حظره، حيث إن الملف التنفيذي غير مُوقَّع من Microsoft.
ولتخطي هذا القيد، نسخت محتويات مجلد /resources/app/ الخاصة بأداة Loki Agent. يوجد مجلد باسم "Teams" على سطح المكتب، يحتوي على تطبيق Microsoft Teams القديم الشرعي. ويؤكد عرض خصائص Teams.exe أنه موقع من Microsoft.
ثم انتقلت إلى مجلد /resources/ الخاص بتطبيق Teams وحذفت جميع الملفات الموجودة. وبمجرد مسحها، لصقت مجلد Loki C2 Agent /resources/app/ المنسوخ مسبقًا في ~/Desktop/teams/resources/app/.
باستخدام هذا التعديل، نفذت Teams.exe بالنقر عليه. ونظرًا إلى أن ملف Teams التنفيذي موقع من Microsoft، فإن WDAC لا تحظره. في System Informer، يمكننا أن نرى أن عملية Teams قد أُنشئت بنجاح من دون تدخل WDAC. لكن، لأنني استبدلت مجلد /resources/app/ في Teams بكود Loki C2 Agent، فإن تطبيق Teams المعتمد على Electron ينفذ الآن JavaScript الخاص بأداة Loki C2 Agent داخل عملية Teams الموثوقة.
نجحت عملية Teams في معاودة الاتصال بعميل Loki C2، ونفذتُ العديد من الأوامر للتأكد من إمكانية التحكم عن بُعد في الخادم المخترق.
بعد الحصول على صلاحية الوصول الأولي باستخدام Loki C2، حددنا طرقًا متعددة لتنفيذ وكيل C2 للمرحلة الثانية يتمتع بإمكانات أكثر، مثل Dragon، وهو خادم C2 الداخلي الذي طورته أنا وShawn Jones (@anthemtotheego). على الرغم من أننا لن نكشف عن جميع طرق زيادة الامتيازات التي اكتشفناها منذ إنشاء Loki C2 الأولي في هذا المنشور، إلا أننا نعتزم تغطيتها في المنشورات القادمة.
عند تنفيذها بشكل صحيح، تستمر هذه التقنية في تخطي حلول اكتشاف نقاط النهاية والاستجابة لها الفائقة. لكن، في غياب C2 خفي من المرحلة الثانية، يجب على المشغلين الاعتماد على تنفيذ الأوامر عبر الإنشاء الذي ينفذ الأوامر في العمليات الفرعية. وسيؤدي ذلك إلى بدء عمليات الكشف بسرعة بعد الاستغلال في حلول اكتشاف نقاط النهاية والاستجابة لها الرائدة.
يتماشى Loki C2 مع تقنية MITRE ATT&CK وهي T1218.011 - تنفيذ وكيل النظام الثنائي: تطبيقات Electron.
بعد البحث على الإنترنت، اكتشفت أن تقنية تفريغ تطبيقات Electron واستبدال أكوادها بخادم C2 لم يُكشف عنها علنًا أو لم تُستخدم على أرض الواقع. لكن، بعد مشاركة Loki C2 مع فرق حمراء موثوقة، أكدت إحداها أنهم طوروا إمكانات مماثلة داخليًا.
حتى مع وجود MITRE ATT&CK TTP، ومنشورات بحثية متعددة، ومدخل LOLBAS، تظل تقنية تفريغ تطبيقات Electron نفسها غير مكتشفة. وحسب افتراضي، لا تركز حلول اكتشاف نقاط النهاية والاستجابة لها على اكتشاف هذه التقنية، بل على مؤشرات ما بعد الاستغلال، مثل إنشاء عمليات فرعية لتنفيذ الأوامر. وبما أننا طورنا دوالاً لنشر خادم C2 في المرحلة الثانية مع تجنب عمليات الاكتشاف الشائعة بعد الاستغلال، فقد استخدمنا هذه التقنية بنجاح في عدة مهام مع تجنب الاكتشاف.
مع أخذ كل هذا في الحسبان، في المرة القادمة التي تسمع فيها موردًا يدعي “تغطية MITRE %100” ، يجدر بك أن تتساءل عما يعنيه ذلك حقًا...