
أداة فك ضغط وتسجيل تلقائي للملفات التي تستهدف إطار عمل DotNet Framework
أداة فك ضغط وتسجيل تلقائية تستهدف ملفات إطار عمل .NET! تم الكشف عن هذه الأداة في Black Hat USA 2022. وفي Black Hat Asia 2023، تم نشر DotDumperGUI وDotDumperNative، إلى جانب الإصدار 1.1-stable من DotDumper. من المفترض استخدام هذه الأدوات الثلاث معًا، حيث يتطلب DotDumper 1.1-stable وجود مكتبات DotDumperNative، بينما يُستخدم DotDumperGUI كواجهة مستخدم رسومية لفتح وتصفية مخرجات JSON من عمليات تشغيل DotDumper.
غالبًا ما يُعتبر الكشف التلقائي والتصنيف الموثوق لأي ملف معين هو الكأس المقدسة لتحليل البرامج الضارة. والمشاكل والعقبات التي تواجه الوصول إلى ذلك كثيرة، ولهذا السبب يحظى إنشاء مثل هذا النظام بتقدير كبير. عندما يتعلق الأمر بالملفات الثنائية التي تستهدف .NET، تهدف أداتنا مفتوحة المصدر الجديدة DotDumper إلى المساعدة في العديد من الخطوات الحاسمة على طول الطريق: تسجيل النشاط (في الذاكرة)، تفريغ أجزاء الذاكرة المثيرة للاهتمام، واستخراج الخصائص من العينة المعطاة.
باختصار، فك الضغط اليدوي هو عملية شاقة تستهلك وقتًا غير متناسب من المحللين. تزيد الملفات الثنائية المُبهمة من الوقت الذي يجب أن يقضيه المحلل لفك ضغط ملف معين. عند توسيع نطاق ذلك، تحتاج المؤسسات إلى العديد من المحللين الذين يشخصون البرامج الضارة يوميًا، ربما بالاقتران مع صندوق حماية قابل للتوسع. يمكن استخدام الوقت الثمين المفقود في التعمق في الحملات أو العينات المثيرة للاهتمام للكشف عن تهديدات جديدة، بدلاً من البرامج الضارة العامة المبتذلة المنتشرة على نطاق واسع. بعد كل شيء، يبحث المحللون عن الإبر القليلة في كومة القش.
إذن، ما الفرق الذي يحدثه DotDumper؟ تشغيل عينة برنامج ضار قائم على .NET عبر DotDumper يوفر ملفات سجل لاستدعاءات الدوال الحاسمة والمُسيّقة والشائعة بثلاثة تنسيقات (نص عادي مقروء للبشر، JSON، وXML)، بالإضافة إلى نسخ من أجزاء الذاكرة المفيدة. على هذا النحو، يمكن للمحلل تصفح سجل استدعاءات الدوال. بالإضافة إلى ذلك، يمكن فحص الملفات المُفرَّغة لتصنيفها، مما يوفر رؤية إضافية للعينة الضارة والبيانات التي تحتويها. وهذا يقلل من الوقت الحاسم لعمليات التصنيف الأولي والاستجابة للحوادث، ويوفر وقت محللي SOC والباحثين لاحتياجات تحليلية أكثر تعقيدًا.
لتسجيل وتفريغ استدعاءات الدوال المُسيّقة ونتائجها، يستخدم DotDumper مزيجًا من الانعكاس والخطافات المدارة، وكلها مكتوبة بلغة C# نقية. أدناه، سيتم إبراز الميزات الرئيسية وتفصيلها، بالإضافة إلى مقتطفات من نتائج DotDumper لعينة من برنامج AgentTesla سارق البيانات المعبأ، والتي توجد تجزئاتها أدناه.
| نوع التجزئة | قيمة التجزئة |
|---|---|
| SHA-256 | b7512e6b8e9517024afdecc9e97121319e7dad2539eb21a79428257401e5558d |
| SHA-1 | c10e48ee1f802f730f41f3d11ae9d7bcc649080c |
| MD-5 | 23541daadb154f1f59119952e7232d6b |
يمكن الوصول إلى DotDumper من خلال واجهة سطر أوامر، مع مجموعة متنوعة من الوسائط. تُظهر الصورة أدناه قائمة المساعدة. لاحظ أنه لن تتم مناقشة جميع الوسائط، بل أكثرها استخدامًا.

الشرط الأدنى لتشغيل عينة معينة هو توفير الوسيطة "-file" مع اسم ملف أو مسار ملف. إذا تم تقديم مسار كامل، يتم استخدامه. إذا تم تقديم اسم ملف، يتم التحقق من دليل العمل الحالي، وكذلك المجلد الذي يوجد فيه ملف DotDumper القابل للتنفيذ.
ما لم يتم تقديم اسم دليل، يتم تعيين اسم المجلد "-log" مساويًا لاسم الملف للعينة بدون الامتداد (إن وجد). يقع المجلد في نفس المجلد الذي يوجد فيه DotDumper، حيث سيتم حفظ السجلات والملفات المُفرَّغة.
في حالة وجود مكتبة، أو نقطة دخول بديلة إلى ملف ثنائي، يجب تجاوز نقطة الدخول باستخدام "-overrideEntry true". بالإضافة إلى ذلك، يجب توفير الفئة المؤهلة بالكامل، والتي تتضمن مساحة الاسم باستخدام "-fqcn My.NameSpace.MyClass". يخبر هذا DotDumper بالفئة التي سيتم تحديدها، حيث يتم استرداد اسم الدالة المقدمة (باستخدام "-functionName MyFunction").
إذا كانت الدالة المحددة تتطلب وسائط، فيجب توفير عدد الوسائط باستخدام "-argc" وعدد الوسائط المطلوبة. يجب توفير أنواع الوسائط وقيمها كـ "string|myValue int|9". لاحظ أنه عند استخدام مسافات في القيم، يجب وضع الوسيطة على واجهة سطر الأوامر بين علامتي اقتباس لضمان تمريرها كوسيطة واحدة.
الخيارات الأخرى الأقل استخدامًا مثل "-raceTime" أو "-deprecated" آمنة في إعداداتها الافتراضية ولكن قد تتطلب تعديلًا في المستقبل بسبب التغييرات في إطار عمل .NET. يتم عرضها حاليًا في واجهة سطر الأوامر لتسهيل إجراء التغييرات، إذا لزم الأمر، حتى لو كنت تستخدم إصدارًا أقدم من DotDumper عندما يحين الوقت.
التسجيل والتفريغ هما الميزتان الأساسيتان لـ DotDumper. لتقليل الوقت الذي يستغرقه التحليل، يجب أن يوفر التسجيل سياقًا للمحلل. يتم ذلك من خلال تزويد المحلل بالمعلومات التالية لكل استدعاء دالة مُسجل:
لاحظ أنه لكل ملف مُفرَّغ، يكون اسم الملف مساويًا لتجزئة SHA-256 الخاصة بالملف.
لتوضيح ما سبق، يتم تقديم مقتطف من سجل أدناه. يُظهر المقتطف تفاصيل عينة AgentTesla المذكورة أعلاه، حيث تقوم بتحميل المرحلة الثانية باستخدام وظيفة Assembly.Load الخاصة بـ .NET.
![سجل لاستدعاء دالة Assembly.Load(byte[] rawAssembly) المُعترَض](images/assembly_load.png)
أولاً، يتم إعطاء وقت النظام المحلي، بالإضافة إلى نوع الإرجاع الأصلي للدالة واسمها ووسيط/وسائطها. ثانيًا، يتم إعطاء تتبع الاستدعاء، حيث يظهر أن الدالة الرئيسية للعينة تؤدي إلى مُنشئ، وتُهيئ المكونات، وتستدعي وظيفتين مخصصتين. تم استدعاء دالة Assembly.Load من داخل "NavigationLib.TaskEightBestOil.GGGGGGGGGGGGGGGGGGGG(String str)". يوفر هذا السياق للمحلل للعثور على الكود حول هذه الاستدعاء إذا كان ذا أهمية.
ثم يتم إعطاء معلومات حول ترتيب استدعاء التجميع. كلما زاد عدد المراحل التي تم تحميلها، زاد التعقيد في رؤية المراحل التي نشأت منها الاستدعاء. يتوقع المرء عادةً أن تقوم مرحلة واحدة بتحميل المرحلة التالية، ولكن في بعض الحالات تستخدم المراحل اللاحقة المراحل السابقة بترتيب غير خطي. بالإضافة إلى ذلك، يتم إعطاء معلومات حول التجميع الأصلي لإثراء البيانات بشكل أكبر للمحلل.
بعد ذلك، يتم إعطاء تجزئة الأصل. أصل المرحلة هو المرحلة السابقة، والتي في هذا المثال ليست موجودة بعد. سيكون للمرحلة المُحملة حديثًا هذه المرحلة كأصل لها. يسمح هذا للمحلل بربط الأحداث بسهولة أكبر.
أخيرًا، يتم تخزين نوع الإرجاع والقيمة للدالة، بالإضافة إلى نوع واسم وقيمة كل وسيطة تم تمريرها إلى الدالة المُخطَّطة. إذا كان أي متغير أكبر من 100 بايت في الحجم، يتم تخزينه على القرص بدلاً من ذلك. ثم يتم إدراج مرجع في السجل للإشارة إلى الملف، بدلاً من عرض القيمة. تم تعيين الحد لتجنب التعثر في طباعة السجل، حيث أن بعض المصفوفات يبلغ حجمها آلاف المؤشرات.