تمت ملاحظة برنامج الفدية DJVU/STOP، منذ اكتشافه لأول مرة في عام 2018، بشكل متقطع كجزء من هجمات برامج الفدية، ولكنه لم يكتسب شهرة برامج الفدية الأخرى مثل Revil أو Conti. ومع ذلك، فقد عادت إلى الظهور، حيث أصبح البديل الجديد من DJVU/STOP أحد أكثر البرامج الضارة لتشفير الملفات انتشارًا في عام 2021. لدرجة أنه أصبح مصدر إزعاج عالمي يستهدف الكيانات في جميع أنحاء الولايات المتحدة وأوروبا وآسيا وأمريكا الجنوبية وأفريقيا. تم اكتشافه في حزم برامج الكراك الشائعة أو حزم البرامج الإعلانية، والتي توجد عادةً على مواقع التورنت والأنظمة الأساسية الأخرى.
في سلسلة المدونات هذه المكونة من جزأين، سوف نتعمق في طريقة عمل برنامج DJVU/STOP Ransomware، وتقنياته وميزاته، وكيفية التعرف على الضحايا، والحفاظ على مثابرته.
طريقة عمل برنامج الفدية DJVU/STOP
DJVU/STOP ransomware عبارة عن برنامج تروجان ضار لتشفير الملفات يتطفل سراً على كمبيوتر الضحية ويقوم بتشفير جميع الملفات لجعلها غير قابلة للوصول. بعد ذلك، تقوم بإسقاط مذكرة فدية لإخطار الضحية بالتشفير. تتطلب المذكرة أيضًا مبلغًا محددًا من المال كفدية لمفاتيح فك التشفير التي ستقوم بفك تشفير الملفات المخترقة وجعلها في متناول الضحية.
ذا لودر
تعمل العينة التي تم تحليلها (hash) كبرنامج تحميل لنشر تشفير برامج الفدية كمرحلة نهائية من سلسلة العدوى.
لقد لوحظ أن هناك العديد من عمليات تنفيذ كود القشرة لجعل تسليم التشفير غير واضح قدر الإمكان من أجل التهرب من الأمن.
يقوم المُحمل أيضًا بإجراء بعض فحوصات الأمان التشغيلي (OPSEC) قبل تنفيذ المرحلة الأولية.
المرحلة 1
في المرحلة الأولية، يقوم المُحمل بتعداد النظام الضحية من خلال قراءة سمات النظام لاسترداد معلومات مثل اسم المستخدم وبنية المعالج ومسار النظام ودليل Windows الجذر ومحركات أقراص الشبكة، من بين التفاصيل الأخرى المطلوبة لمزيد من إصابة الجهاز.
يقوم المُحمل بتخصيص منطقة ذاكرة بأذونات القراءة/الكتابة/التنفيذ ويقوم بتفريغ كود shell المستقل عن الموضع ليتم تنفيذه لاحقًا.
المرحلة 2
في هذه المرحلة، يقوم كود shellcode الأساسي بتفريغ كود shell الثانوي في ذاكرة مخصصة.
يقوم رمز الغلاف الثانوي بإجراء «تفريغ العملية» لتسليم حمولة التشفير النهائية داخل عملية اللودر التي تم إنشاؤها حديثًا باستخدام معرف عملية مختلف.
تمتلك العملية التي تم إنشاؤها حديثًا مجموعة من التعليمات، نتيجة لتفريغ العملية، والتي يمكنها بدء التشفير على نظام الضحية وتنفيذ اتصالات الشبكة.
مرحلة الفدية
في المرحلة النهائية، يكون برنامج الفدية نشطًا على نظام الضحية ويبدأ في تشفير ملفاته، قبل تسليم مذكرة الفدية سيئة السمعة.
التحليل الفني
عمل اللودر
يقوم المُحمل بتخصيص ذاكرة باستخدام واجهة برمجة تطبيقات VirtualAlloc Win32 مع تعريف الوظيفة:
LPVOID Virtual Alloc ( [في، اختياري] عنوان LPVOID، [بوصة] الحجم: مقاس DW_T، [في] نوع موقع سقوط DWORD، [في] وورد فل بروتكت )؛
في أداة التحميل، يتم استخدام الوسيطات التالية لاستدعاء VirtualAlloc:
صفحة الذاكرة المخصصة قادرة على القراءة/الكتابة والتنفيذ. في حين أن هذا قد يبدو تافهًا على السطح، إلا أنه من السلوك الشائع الذي يُلاحظ حتى في أكثر البرامج الضارة تعقيدًا تنفيذ تعليمات برمجية ضارة على جهاز الضحية مع الحفاظ على السرية.
فل بروتكت: 0x40
نوع موقع الخريف: 0x1000
مقاس DW:
عنوان بروتوكول الإنترنت: 0x0
ذاكرة بدون بايت:
يقوم المُحمل بتعبئة الذاكرة المخصصة، من الخطوة السابقة، برمز shellcode.
يتم بعد ذلك نقل تدفق التنفيذ إلى كود shellcode المخصص حديثًا كما هو موضح أدناه. وتشير وحدة المعالجة المركزية الآن إلى التعليمات الأولى لكود shellcode الضار عند بدء التنفيذ.
العمل في المرحلة الأولى من Shellcode
تمت برمجة كود الغلاف الأساسي للمرحلة الأولى لحقن كود الغلاف الثانوي، المسؤول عن «تفريغ العملية»، لتسليم كود التشفير النهائي لبرنامج الفدية.
يقوم رمز shellcode الأساسي بتسليم الوحدات إلى مساحة العنوان الخاصة به، بما في ذلك على سبيل المثال لا الحصر:
ntdll.dll
Kernel32.dll
يتم حل العنوان من خلال الحصول على عنوان إحدى الوظائف الأساسية في وحدة kernel32 وهو Kernel32.getProcAddress. يستخدم مؤلفو البرامج الضارة Kernel32.getProcaddress لحل واجهات برمجة تطبيقات Win32 ديناميكيًا للتهرب من التدقيق في تحليل الكود من خلال النظر إلى جدول الاستيراد الخاص بالبرنامج. تم أيضًا حل بعض عناوين الوظائف المثيرة للاهتمام لاستخدامها لاحقًا في البرنامج.
بمجرد حصول البرامج الضارة على عنوان وظيفة Kernel32.getProcAddress، يتم استخدامها لحل عناوين الوظائف التالية:
Kernel 32. شركة عالمية
Kernel 32. جهاز كمبيوتر افتراضي
Kernel 32. قم بتعيين الخطأ الأخير
كيرنيل 32. سليب
Kernel 32. إنشاء لقطة مساعدة للأداة 32
كيرنيل 32. الوحدة 32 الأولى
كيرنيل 32. مقبض مغلق
بعد حل عناوين الوظائف المختلفة، يبدأ رمز shellcode في تنفيذ اثنين من واجهات برمجة تطبيقات Win32:
إنشاء أداة مساعدة 32 لقطة
الوحدة 32 الأولى
تم تمرير الحجج إلى إنشاء أداة مساعدة 32 لقطة هي:
أعلام DW: 0x08 (وحدة TH32CS_SNAP)
معرف العملية 32:0x0 (العملية الحالية)
مقبض إنشاء أداة مساعدة 32 لقطة( [في] أعلام DWORD، [في] معرف عملية DWORD TH32 )؛
الحجج التي تم تمريرها إلى وظيفة Module32First هي:
لقطة الشاشة: 0x108 (تم إرجاع مقبض اللقطة إلى اللقطة السابقة من لقطة CreateToolHelp32)
لومي: 0x19F768 (مؤشر إلى بنية MODULEENTRY32)
وحدة BOOL 32 الأولى ( [في] مقبض اللقطة، [داخل وخارج] وحدة LPMODULEENTRY32 لومن )؛
الرموز المذكورة أعلاه هي وظائف شائعة الاستخدام لتنفيذ أنشطة ضارة. في هذه الحالة:
يتم استخدام CreateToolHelp32Snapshot لإنشاء لقطة تحتوي على أكوام ووحدات وسلاسل، تستخدمها عمليات عملية معينة.
يتم استخدام Module32First لاجتياز الوحدات الموجودة في اللقطة المقدمة من CreateToolHelp32Snapshot.
يقوم المُحمل باسترداد كود shellcode بهذه الطريقة ثم ينتقل إلى تخصيص الذاكرة وكتابة كود shellcode.
تشغيل المرحلة الثانية (كود شل)
يخصص رمز غلاف المرحلة 1 الذاكرة بالوسيطات التي تمت الإشارة إليها سابقًا لكود غلاف المرحلة 2، باستخدام واجهة برمجة تطبيقات VirtualAlloc Win32.
تتضمن الخطوة التالية كتابة shellcode في الذاكرة المخصصة. يتم بعد ذلك نقل عنصر التحكم إلى منطق كتابة كود shellcode عبر «call 4AE04F2".
تصل المكالمة السابقة إلى منطق الكود الموضح أدناه، والذي يكتب بشكل متكرر كود غلاف المرحلة 2 في المخزن المؤقت المخصص.
بمجرد نقل رمز shellcode، يتم تعيين عنصر التحكم إلى رمز shellcode بواسطة أمر JMP كما هو موضح أدناه:
بعد القفزة، تشير وحدة المعالجة المركزية إلى بداية رمز غلاف المرحلة 2. يعد رمز shellcode هذا مسؤولاً عن إجراء «تفريغ العمليات» لتقديم حمولة تشفير برامج الفدية التي تقوم بتشفير بيانات المستخدم. يقوم كود shellcode للمرحلة الثانية بعد ذلك بتحميل وحدات user32.dll و ntdll.dll و kernel32.dll في العملية الحالية.
باستخدام Kernel32.getProcAddress، يتم حل عناوين الوظائف المثيرة للاهتمام التالية:
المستخدم 32. صندوق الرسائل أ
Kernel 32. إنشاء العملية أ
Kernel 32. إنشاء العملية أ
المستخدم 32. احصل على رسالة إضافية
Kernel 32. احصل على سياق الموضوع
Kernel 32. احصل على اسم ملف الوحدة
المستخدم 32. سجل في فئة XA
Kernel 32. جهاز كمبيوتر افتراضي
Kernel 32. احصل على سطر الأوامر A
المستخدم 32. إنشاء نظام التشغيل Windows XA
Kernel 32. جميع أجهزة OCEX الافتراضية
Kernel 32. احصل على سمات الملف A
المستخدم 32. أرسل رسالة
Kernel 32. النسخة الافتراضية المجانية
Kernel 32. احصل على معلومات بدء التشغيل
بروكا ويندوز 32.def للمستخدم
Kernel 32. ذاكرة معالجة القراءة
كيرنيل 32: الحماية الافتراضية
كيرنيل 32. وين إكسيك
Kernel 32. اكتب ذاكرة المعالجة
عملية الخروج من Kernel.Exit
Kernel 32. إنشاء ملف A
Kernel 32. تعيين سياق الموضوع
عرض خريطة Ntdll.ntunm للقسم
كيرنيل 32. اكتب ملف
موضوع السيرة الذاتية Kernel 32
Ntdll.nt اكتب ذاكرة افتراضية
نواة 32. مقبض مغلق
Kernel 32. انتظر كائنًا واحدًا
يتحقق كود shellcode من ملف معين باسم «apfHQ». أفضل افتراض لدينا هو أن الملف يستخدم كعلامة لتحديد الضحايا. على الرغم من أن السلسلة شائعة جدًا في العديد من عائلات البرامج الضارة، إلا أن السبب الدقيق لهذا السلوك لا يزال غير معروف.
يقوم رمز الغلاف بعد ذلك بإنشاء نافذة فئة باستخدام اثنين من واجهات برمجة التطبيقات، وهما user32.registerClassexa و user32.createWindwoexa. الاسم الذي يطلق على الفصل هو «saodkfnosa9uin».
يتم استخدام فئة النافذة التي تم إنشاؤها مسبقًا لإنشاء نافذة مخفية باستخدام User32.createWindowexa كما هو موضح أدناه:
عملية التجويف
كما ذكرنا أعلاه، فإن الهدف من المرحلة الثانية من shellcode هو إجراء عملية تفريغ لنشر برنامج تشفير برامج الفدية لتشفير بيانات المستخدم.
يعد تفريغ العمليات طريقة سرية لحقن التعليمات البرمجية الضارة في عملية حميدة وجديرة بالثقة لتجنب الاكتشاف والأمان. التفسير البديهي لتفريغ العملية هو نحت التعليمات الشرعية والأصلية للتطبيق الحميد لاستبداله بتطبيق ضار، دون السماح للتطبيق بمعرفة التغيير في الكود الذي أجراه ممثل التهديد. هذا هو السبب في أن المهاجمين ينشئون عملية في حالة معلقة ثم يستأنفونها بعد الانتهاء من التجويف.
الخطوات الأساسية المتضمنة في إجراء التجويف
الخطوة الأولى هي اختيار صورة PE مرشحة (تطبيق) للتفريغ. في هذه الحالة، تتم إعادة نشر أداة التحميل القابلة للتنفيذ مع حمولة برامج الفدية النهائية.
يتم بعد ذلك استخدام Win32 API Kernel32.getModuleFileNamea للحصول على اسم أداة التحميل القابلة للتنفيذ والتي يتم استخدامها لاحقًا في واجهة برمجة تطبيقات Kernel32.createProcessa.
يحصل رمز shellcode على المعلومات التي يجب استخدامها لاحقًا في إنشاء العملية. تتكون هذه المعلومات من معلومات بدء التشغيل الخاصة بالعملية وسطر الأوامر المقدم للعملية التي تم إنشاؤها حديثًا.
يقوم برنامج الفدية بعد ذلك بإطلاق عملية جديدة باستخدام المعلمات التالية: «—Admin ليس AutoStart IsNotTask».
كود شل باستخدام Kernel32.getStartupInfoA لاسترداد معلومات بدء التشغيل
كود شل باستخدام Kernel32.getStartupInfoA لاسترداد معلمات سطر الأوامر
بعد ذلك، تقوم البرامج الضارة بإنشاء عملية في حالة تعليق. يتم استخدام Kernel32.createProcessa لإنشاء العملية، باستخدام وسيطات مثل الهدف القابل للتنفيذ، ومعلومات بدء التشغيل، ومعلمات سطر الأوامر، وما إلى ذلك.
بعد ذلك، تسترد كتلة بيئة العملية عنوان الصورة الأساسية للملف التنفيذي الذي تم إنشاء العملية منه. يحتاج ممثل التهديد إلى معرفة العنوان الأساسي لإلغاء تعيين صورة PE الحقيقية (الكود) ثم تقديم الصورة الضارة.
يتم استخدام Kernel32.readProcessMemory للحصول على عنوان الصورة للصورة.
تتم عملية إلغاء التعيين عن طريق استدعاء الدالة ntdll.zwunMapViewOfSectionA:
تحاول البرامج الضارة الآن تخصيص ذاكرة افتراضية في مساحة الذاكرة للعملية البعيدة التي تم إنشاؤها. سيتم استخدام هذه الذاكرة لاستضافة رمز برنامج الفدية في العملية التي تم إنشاؤها حديثًا.
يتم استخدام Kernel32.VirtualAlloceX خصيصًا لإنشاء تخصيصات الذاكرة في مساحات العناوين البعيدة، كما هو موضح أدناه:
يتم تخزين الحمولة النهائية داخل اللودر. تبدأ الحمولة ببايت «MZ» يشير إلى أنها قابلة للتنفيذ. يجب استخراج هذا لمزيد من التحليل، نظرًا لأنه التشفير النهائي الذي ينشره اللودر من العملية الجديدة.
في الخطوة التالية، تقوم البرامج الضارة بكتابة الحمولة في ذاكرة المعالجة عن بُعد للعملية التي تم إنشاؤها حديثًا عبر CreateProcessa.
الآن يمكن للبرامج الضارة كتابة الحمولة النهائية في مساحة العنوان للعملية البعيدة باستخدام ntdll.zwwriteVirtualmemory/ntWriteProcessMemory كما هو موضح أدناه:
كتابة التعليمات البرمجية الضارة الجديدة (التجويف) في العملية التي تم إنشاؤها حديثًا كما هو موضح أدناه. تقوم البرامج الضارة بكتابة وحدات البايت بشكل متكرر في العملية البعيدة التي تكون في حالة تعليق. يتم إجراء التغييرات مقطعًا تلو الآخر (.text و.data وما إلى ذلك).
بعد ذلك، يتم تغيير نقطة الإدخال المستخدمة من قبل أداة تحميل Windows لبدء تنفيذ رمز البرنامج الخاص بالتطبيق.
يمكن العثور على هذه المعلومات في سلسلة المحادثات الأساسية التي تم إنشاؤها باستخدام العملية المعلقة. يتم استخدام Kernel32.getThreadContext لاسترداد المعلومات الخاصة بالخيط.
بمجرد تغيير نقطة الدخول، يتم تنفيذ التغييرات عبر واجهة برمجة تطبيقات Kernel32.setThreadContext، وتقوم العملية المعلقة بتنفيذ التعليمات البرمجية الضارة.
كخطوة أخيرة، يتم استئناف سلسلة المحادثات في العملية المستهدفة، والتي تستيقظ من حالة التعليق وتنفذ كود برنامج الفدية. يتم استخدام واجهة برمجة تطبيقات Kernel32.Resumethread لاستئناف سلسلة المحادثات البعيدة.
في هذه المرحلة، يمكننا ملاحظة مثيلات متعددة لبرنامج اللودر في قائمة العمليات. والمقابض المفتوحة بواسطة اللودر مغلقة الآن باستخدام Kernel32.closeHandle.
أخيرًا، يخرج المُحمل عبر Kernel32.exitProcess وينهي التنفيذ.
في قائمة معالجة الذاكرة، ستكون هناك عملية بمعرف مختلف، وهو نفس أداة التحميل القابلة للتنفيذ ولكن مع منطق كود مختلف مجوف فيه في مرحلة تفريغ العملية.
ستكون هذه العملية مع PID الجديد مسؤولة عن تشفير الضحية.
في الجزء الثاني من منشور المدونة، سنواصل تحليل كود تشفير برامج الفدية بعد الحصول على العملية التي تم إنشاؤها حديثًا من تفريغ الذاكرة.