
POC لإحباط/هزيمة محللي البرامج الضارة
العمل التالي عبارة عن إثبات مفهوم (POC) لتمكين البرامج الضارة من "تقييد" نفسها بضحية معينة من أجل إعاقة جهود محللي البرامج الضارة.
أنا لا أتحمل أي مسؤولية عن الاستخدام الخبيث لأي أفكار أو كود موجود داخل هذا المشروع. أقدم هذا البحث لتثقيف المتخصصين في أمن المعلومات بشكل أكبر وتوفير تدريب إضافي/مادة للتفكير لمحللي البرامج الضارة، ومهندسي الهندسة العكسية، وفرق الدفاع بشكل عام.
في المرة الأولى التي يتم فيها تشغيل البرنامج الضار على ضحية، يقوم بتشفير الحمولة الفعلية (RDLL) باستخدام AES باستخدام بيانات بيئية من تلك الضحية. في كل مرة لاحقة يتم فيها تشغيل البرنامج الضار، يقوم بجمع نفس المعلومات البيئية، وفك تشفير الحمولة المخزنة كمصفوفة بايت داخل البرنامج الضار باستخدام AES، وتشغيلها. إذا فشل فك التشفير/فشلت الحمولة في العمل، يقوم البرنامج الضار بحذف نفسه. حماية ضد مهندسي الهندسة العكسية ومحللي البرامج الضارة.


لم أشعر أن هذا المشروع قد اكتمل، لذا عدت وقمت بإعادة كتابة كبيرة إلى حد ما. يمكن العثور على البحث الأصلي والتقنيات هنا.
التغييرات الرئيسية هي كما يلي:
هناك العديد من الأشياء المختلفة التي يمكن أخذها من كود المصدر لهذا المشروع لاستخدامها في أماكن أخرى. نأمل أن يكون مفيدًا لشخص ما.
كانت هناك بعض القصور في الإصدار الأصلي من BeatRev التي قررت محاولة معالجتها.
كان Stage2 سابقًا ملفًا تنفيذيًا مستقلاً يتم تخزينه كتيار بيانات بديل (ADS) لـ Stage1. لتحقيق التشفير باستخدام AES حسب الضحية ثم فك التشفير والتنفيذ، في كل مرة يتم تشغيل Stage1 كان يقرأ ADS، ويفك تشفيره، ويكتب مرة أخرى إلى ADS، ويستدعي CreateProcess، ثم يعيد تشفير Stage2 ويكتبه مرة أخرى إلى القرص في ADS. كان هذا الكثير من عمليات الإدخال/الإخراج وبالطبع لم يكن استدعاء CreateProcess جيدًا.
صادفت بحث Steven Fewer حول DLLs الانعكاسية وبدا مناسبًا. Stage2 الآن هو RDLL؛ يمكن نقل برنامجنا الضار/مشغل الشيل كود/أي شيء نريد حمايته إلى تنسيق RDLL وتخزينه كمصفوفة بايت داخل Stage1 يتم فك تشفيرها عند وقت التشغيل وتنفيذها بواسطة Stage1. هذا يزيل جميع عمليات الإدخال/الإخراج واستدعاء CreateProcess من الإصدار 1 وهو تغيير مرحب به.
لم يكن لدى Stage1 أي إجراءات حقيقية للتهرب من برامج مكافحة الفيروسات مبرمجة؛ كان هذا متعمدًا، حيث إنه عمل إضافي ولم يكن هدف هذا البحث حقًا. أثناء إعادة الكتابة، أخذتها كتحدٍ إضافي وأضفت تجزئة API لإزالة الوظائف من جدول عناوين الاستيراد (IAT) لـ Stage1. وقد ساعد هذا في الاكتشاف وأصبح لدى Stage1 معدل اكتشاف 4/66 على VirusTotal. كنت مرتاحًا لتحميل Stage1 نظرًا لأنه مقيد بالفعل بالجهاز الأصلي الذي تم تشغيله عليه وتتغير بصمة الملف باستمرار بسبب تشفير AES الذي يحدث.
بدأت مؤخرًا في الانتباه إلى الانتروبيا كوسيلة لاكتشاف البرامج الضارة؛ لمحاولة خفض الانتروبيا العالية جدًا التي يعطيها blob ثنائي مشفر بـ AES ضخم لملف تنفيذي، بحثت في دمج شيل كود مخزن كـ UUIDs. نظرًا لأن الثنائي مخزن في تمثيل سلسلة، فهناك انتروبيا أقل بشكل عام في الملف التنفيذي. باستخدام هذه التقنية، أصبحت انتروبيا Stage0 الآن ~6.8 و Stage1 ~4.5 (على مقياس أقصى 8).
أخيرًا، إنها مهمة ضخمة لدمج وإنتاج Stage0 كامل بسبب جميع القطع التي يجب التلاعب بها. لتسهيل ذلك، قمت بإنشاء تطبيق بناء يمكنه استيعاب ملف قالب Stage0.c، و stub Stage1، و stub Stage2، وملف شيل كود خام (تم بناء هذا حول Stage2 كمشغل شيل كود يحتوي على شيل كود CobaltStrike) وإنتاج حمولة Stage0 مترجمة للاستخدام على الهدف.
يحتوي كود DLL الانعكاسي من Stephen Fewer على بعض التعليمات الخاصة بمترجم Visual Studio؛ أنا متأكد من أنه من الممكن نقل التقنية إلى MingW ولكن ليس لدي المهارات للقيام بذلك. المشكلة الرئيسية هنا هي أن شيل كود CobaltStrike (بدون حالة ~265K) يجب أن يوضع داخل RDLL ويتم ترجمته. للتغلب على هذا ودمجه بشكل جيد مع بقية العملية، كتبت Stage2 RDLL الخاص بي ليحتوي على كتلة ذاكرة متغيرة عامة بحجم شيل كود CS؛ تحتوي كتلة الذاكرة ~265K هذه على عنصر نائب صغير يمكن تحديده في الثنائي المترجم. تمت إضافة هذا بالفعل في الكود في src/Stage2.
بمجرد الترجمة، يتم نقل هذا Stage2stub إلى kali حيث يمكن إجراء تصحيح ثنائي لوضع شيل كود CS الحقيقي في المكان المناسب في الذاكرة. ينتج عن هذا Stage2 الكامل.
لتجنب كارثة الإدخال/الإخراج و CreateProcess الموصوفة سابقًا، يجب أيضًا تصحيح Stage2 الكامل في Stage1 المترجم بواسطة Stage0؛ هذا ضروري للسماح بتشفير Stage2 مرة واحدة على الهدف بالإضافة إلى منع تخزين Stage2 بشكل منفصل على القرص. يتم تنفيذ نفس المفهوم الموصوف سابقًا لـ Stage2 بواسطة Stage0 على الهدف لتجميع حمولة Stage1 النهائية. يجب ملاحظة أن وظيفة memmem تُستخدم لتحديد العنصر النائب داخل كل stub؛ هذه الوظيفة غير متوفرة على Windows، لذا تم استخدام تطبيق مخصص. شكرًا لـ Foxik384 على كوده.
لإجراء تصحيح ثنائي، يجب تخصيص الذاكرة المطلوبة مسبقًا؛ هذا له تأثير تراكمي، حيث يجب أن يكون Stage1 كبيرًا بما يكفي لاحتواء Stage2 أيضًا. مع الخطوة الإضافية لتحويل Stage2 إلى سلسلة UUID، يتضخم حجم Stage2 وكذلك Stage1 لاستيعابه. ينتج عن Stage2 RDLL بحجم مترجم ~290K حمولة Stage0 ~1.38M، وحمولة Stage1 ~700K.
يدعم تطبيق البناء فقط إنشاء ملفات EXE x64. ومع ذلك، مع القليل من العمل الإضافي، من الناحية النظرية يمكنك جعل Stage0 DLL، وكذلك Stage1، وجعل دورة الحياة بأكملها موجودة كاختراق DLL بدلاً من ملف تنفيذي مستقل.
ستساعدك هذه التعليمات على البدء في استخدام هذا POC.

منذ حوالي 6 أشهر، خطر ببالي أنه بينما تعلمت وفعلت الكثير مع البرامج الضارة فيما يتعلق بالتهرب من برامج مكافحة الفيروسات / EDR، فقد أمضيت القليل من الوقت في محاولة التهرب أو هزيمة الهندسة العكسية / تحليل البرامج الضارة. كان ذلك لعدة أسباب وجيهة:
ومع ذلك، كانت تجربة فكرية مثيرة للاهتمام وكان لدي بعض الزملاء الذين يعرفون بالفعل عن تحليل البرامج الضارة الذين يمكنني تبادل الأفكار معهم. بدا الأمر تحديًا بحجم مختلف تمامًا مقارنة بالتهرب من برامج مكافحة الفيروسات / EDR وقررت أن أحاوله.