
أشياء سيئة من أشخاص سيئين
تم اختيار عينة Hive التي تم تحليلها والإشارة إليها في هذا المستند عشوائيًا من هذه القائمة التي أنشأها @rivitna والذي أتوجه إليه بأحر الشكر. القطع الأثرية متاحة على منصة VirusTotal.
في هذا المستند، تم اتخاذ الملف a0h2uih3d2.exe كمرجع
MD5: 15CF5E0DA094ACDD751A513402A8C941
SHA-1: 72E15AC4473903C814E65E3C06F54EB0399580AA
SHA-256: 335D2E4A743D059955760ECF2EC25EE86D36AA60B096C9180E860C64EF78EE55
للحصول على فكرة عن مدى تعقيد برنامج الفدية هذا، يرجى إلقاء نظرة على هذا التحليل المنشور من قبل مركز Microsoft لاستخبارات التهديدات (MSTIC).
يرجى قراءة المستند بأكمله بعناية قبل البدء بالتعامل مع الكود!
في الأشهر الأخيرة، وجهت معظم طاقتي نحو دراسة وهندسة عكسية لخوارزمية تشفير Hive v5. كان لي شرف التعاون مع محلل برمجيات خبيثة ومهندس عكسي بارع @rivitna الذي قام في الماضي بتحليل الإصدارات السابقة من Hive ونشر أكوادًا وبراهين مفاهيم (PoCs) تتعلق بآليات التشفير الخاصة بها. لقد ساهم (وليس بقليل) في تحديد المكونات المشاركة في عمليات تشفير Hive v5، والتي أصبح تحليلها أكثر صعوبة لكونها مكتوبة بلغة RUST. لقد وجدت بعض القواسم المشتركة مع Babuk، وهو برنامج فدية مهم جدًا آخر تم الكشف عن مصادره في يونيو 2021:
عند تشغيل برنامج الفدية Hive v5 على نظام الضحية، فإنه يولد مفتاحين بنص واضح، باستخدام الخوارزمية الموضحة في الدليل أدناه، والمعتمدة على واجهتي برمجة تطبيقات Windows QueryPerformanceCounter و QueryPerformanceFrequency.
يرجى إلقاء نظرة على هذه الصفحة من Microsoft لمزيد من المعلومات حول واجهات برمجة التطبيقات QueryPerformanceCounter، وهنا لـ QueryPerformanceFrequency.
QueryPerformanceCounter هو عداد وقت دقيق جدًا. عند استدعائه، فإنه يعيد الوقت المنقضي منذ آخر مرة تم فيها تشغيل الكمبيوتر.
QueryPerformanceFrequency يعيد قيمة (تردد) عداد الأداء. له قيمة ثابتة تبلغ 0x989680. وهذا يعني أن قيمة QueryPerformanceCounter يتم تحديثها 0x989680 مرة في الثانية، أي 10,000,000 مرة.
يبلغ حجم المفتاحين ذوي النص الواضح 0xCFFF00 بايت، ويتم توليدهما واحدًا تلو الآخر بايتًا ببايت. أدناه المقتطف الذي يتيح إنشاء مصفوفة من 0xA00000 بايت، وهو الجزء الأكبر مما يسمى بمفتاح النص الواضح الذي يستخدمه Hive لتشفير الملفات على جهاز الكمبيوتر الخاص بالضحية.

يتم الحصول على كل بايت من المفتاح بأخذ قيمة سجل AL. يحتوي سجل EAX على نتيجة الدالة 0044ADE0 التي أعيدت تسميتها بالعلامة createByte والتي تنفذ الفرق بين اللحظة الزمنية الحالية وقيمة البذرة الأولية، المحسوبة عند أول استدعاء للدالة 0044A850 التي أعيدت تسميتها بالعلامة call_to_QueryPerformanceCounter.
فيما يلي الكود المكتوب بلغة C++ لتوليد مفتاح نص واضح:

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

في المجلد HiveRansomwareV5_custom_keygen_PoC ستجد الكود الخام المستخرج بالهندسة العكسية من عينة Hive v5 التي تم تحليلها. إنه ليس كودًا محسنًا مثل الموجود في البرمجية الخبيثة، لأنني كنت بحاجة إلى عدم تفويت سطر واحد من الكود في النسخة المترجمة.
في المجلد HiveRansomwareV5_custom_keygen_PoC-optimized ستجد الكود المحسن المشتق من الكود الخام المذكور أعلاه. في هذه النسخة، يكون الكود أسهل بكثير في القراءة من الكود الخام، وذلك لفهم الوظيفة التي ينفذها.
كلا النسختين تحتاجان إلى تخصيص باسم المستخدم الخاص بك قبل تشغيلهما من أجل حفظ مفتاح النص الواضح المُولَّد على سطح المكتب لديك.
يتم توليد كلا مفتاحي النص الواضح باستخدام نفس الخوارزمية.
يتكون مفتاح النص الواضح من 0xA00000 بايت مولدة عشوائيًا بشكل آمن. ثم يتم نسخ أول 0x2FFF00 بايت في النهاية، مما ينشئ مفتاح نص واضح نهائيًا بحجم 0xCFFF00 بايت.

ثم يستخدم Hive المفتاحين المُولَّدين لتشفير الملفات، لكن قبل كل شيء، يقوم برنامج الفدية Hive v5 بتشفير المفاتيح المُولَّدة في بنية مخصصة (يشار إليها فيما بعد باسم تدفقات المفاتيح) ويضعها في جذر كل محرك أقراص يقوم بتشفيره باستخدام امتداد .key. على سبيل المثال، إذا كان لديك محركا الأقراص C وD مثبتين على نظامك، فستكون تدفقات المفاتيح المشفرة موجودة في جذر كل محرك.

يستخدم برنامج الفدية Hive v5 مفاتيح النص الواضح المُولَّدة لتشفير الملفات باستخدام تعليمة XOR، لذا فنحن أمام تشفير متماثل سريع جدًا على معالجات x86/x64 الحديثة.
يحتاج برنامج الفدية Hive v5 إلى حماية مفتاح النص الواضح المُولَّد بتشفيره مرتين، وسنسمي هاتين المرحلتين فيما بعد بالجولات. يتطلب الأمر جولتين من التشفير للحصول على تدفق المفاتيح النهائي.
لتحقيق ذلك، يتم تنفيذ الخطوات التالية في كل جولة:
تضمن الخطوة 3 إنشاء تدفق مفاتيح يمكن فتحه بزوج مزدوج من المفاتيح الخاصة: تلك التي يولدها Hive أثناء التشفير، وتلك التي ولدها شريك Hive عندما قام بتجميع برنامج الفدية من أجلنا.

في نهاية هذا الوصف، هناك نقطة معينة تتضح: مفتاح النص الواضح، والمفتاح الخاص، وقيمة nonce المستخدمة في جولتي التشفير يتم توليدها جميعًا بواسطة نفس الدالة أعلاه (0044ADE0 والمعروفة أيضًا باسم createByte). الدالة 0044ADE0 مشروطة بالوقت الذي تستغرقه وحدة المعالجة المركزية (CPU) لتنفيذ الكود المُستدعى داخل حلقة for.
بإلقاء نظرة على الشكل أعلاه الذي يبرز بنية تدفق المفاتيح بعد جولتي التشفير، يتضح أن لدينا وصولًا حرًا فقط إلى قيمة nonce (وإلا لما عرف شركاء Hive كيفية فك تشفير الملفات).
لذا دعونا نركز على قيمة NONCE، التي يبلغ طولها 24 بايت:
NONCE: 40 A4 08 6C D0 D0 34 98 FC 60 C4 28 8C F0 F0 54 B8 1C 80 E4 48 AC AC 10
الفرق بين بايت من قيمة nonce والبايت التالي له (بالقيمة المطلقة) يمثل الوقت المنقضي بين تكرار وآخر. نقدم بهذا التعريف مفهوم البصمة.
بصمة NONCE: 64 9c 64 64 00 9c 64 64 9c 64 9c 64 64 00 9c 64 9c 64 64 9c 64 00 9c
إذا قمنا بتحليل القيم التي تم الحصول عليها، نجد أن زمن تنفيذ الكود شبه متطابق مع اختلافات طفيفة تعود بشكل خاص إلى التقنية المستخدمة في المعالج المستخدم (في اختباراتي استخدمت معالج i7 من الجيل العاشر ومعالج i5 من الجيل الخامس، وعلى أنظمة أخرى قد تختلف هذه البصمة).
هذه النتيجة مهمة جدًا إذا فكرنا في أن قيمة nonce يتم توليدها بواسطة نفس الدالة التي تولد مفتاح النص الواضح، وقبل كل شيء المفتاح الخاص. وبما أن هذه القيم المذكورة ستتبع أيضًا هذا المبدأ، أي أن الفرق بين البايتات الفردية لقيمة nonce قابل للتنبؤ، فإن قيم المفتاح الخاص ومفتاح النص الواضح ستكون أيضًا قابلة للتنبؤ.
ومع ذلك، أظهرت التحليلات أن توليد مصفوفة من 0xA00000 حرفًا على أمل الحصول على نفس البايتات الأصلية لمفتاح النص الواضح الذي حسبه Hive أمر صعب جدًا: فالاختلافات في أحمال وحدة المعالجة المركزية (CPU) والذاكرة تؤثر على سرعة تنفيذ الكود، وغالبًا ما يكون مفتاح النص الواضح الأصلي الذي حسبه ملف Hive القابل للتنفيذ (PE) مختلفًا (حتى ولو لبضعة بايتات فقط) عن المفتاح الذي حسبناه نحن.
نستخدم بصمة nonce هذه لمقارنتها بالبصمة التي تم الحصول عليها من توليد قاموس محتمل بطول 0xA00000 بايت (تم تثبيت هذا الرقم تجريبيًا، وبعد سلسلة من الاختبارات، تبين إحصائيًا أنه في هذا العدد من البايتات يوجد المفتاحان الخاصان، كل منهما بحجم 32 بايت، اللازمان في جولتي التشفير). إذا كانت بصمة nonce مضمنة في بصمة القاموس، فقد وجدنا القاموس الصحيح لبدء هجوم القوة العمياء على كلا المفتاحين الخاصين.
لا ينتهي الأمر هنا، لأنه من خلال التحليلات الديناميكية التي أجريت على توليد قيمة nonce ومفتاح النص الواضح وأيضًا المفتاح الخاص، تم التحقق من أن البايت الأول له مسافة متوسطة مختلفة عن البايت الثاني، مقارنة بجميع البايتات الأخرى التي لها قيم شبه متجانسة. دعونا نرى بالتفصيل:

كما ترى، فإن قيم البصمة التي تلي البايت الأول تخضع لاختلافات طفيفة، أي أن المسافة بالقيمة المطلقة بين البايت الأول والثاني من المفتاح الخاص تكون في معظم الأحيان قيمًا خارج نطاق القيم الموجودة في بقية البصمة.
ربما يعود ذلك إلى بعض خوارزميات التحسين الموجودة في وحدة المعالجة المركزية (CPU) والتي تسرع تنفيذ الكود بعد التكرار الأول في حلقة for.
يقرأ الكود المقترح قيمة nonce لكل جولة من جولات تشفير تدفق المفاتيح، ويحدد بصمتها، ويولد قائمة بقواميس المفاتيح المحتملة التي تحتوي على المفتاح الخاص المحتمل.
لحل المشكلة المتعلقة بالبايت الأول من البصمة الذي يختلف دائمًا عن بقية المفتاح، فكرت في القيام بما يلي:
عندما يتطابق المفتاحان العامان، نكون قد وجدنا المفتاح الخاص الذي تم به تشفير الجولة الثانية (الأخيرة) من التشفير. ومن خلال تكرار العمليات الموصوفة حتى الآن مرة أخرى، سنحصل على المفتاح الخاص لفك تشفير الجولة الأولى من تدفق المفاتيح المشفر، وأخيرًا نستخرج مفتاح النص الواضح الأصلي.
في المجلد HiveRansomwareV5-keystream_decryptor ستجد ملف الحل (sln) الخاص بـ Visual Studio 2017 ومكتبة monocypher مخصصة. يتيح لك البرنامج اختيار العملية التي تريد تنفيذها.

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

أو بدلًا من ذلك، إذا لم يعمل الخيار الأول، فقم بتوليد القاموس الخاص بك عن طريق تشغيل البرمجية الخبيثة في المصحح (على نفس الكمبيوتر المصاب بالفعل) حتى نهاية توليد مفتاح النص الواضح (عند الخروج مباشرة من حلقة for) واحفظ محتويات الذاكرة التي تحتوي على مفتاح النص الواضح. في هذه الحالة يمكنك التحقق من صحة القاموس الخاص بك باستخدام الخيار "3":

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

لتنفيذ الوظيفة الموجودة في الخيار 2 بشكل صحيح، يجب استخراج المفتاح العام. نظرًا لأن عينات Hive ليست جميعها متشابهة، فليس من السهل جدًا إنشاء مستخرج مفتاح عام شامل. ومع ذلك، هناك طريقة معروف أنها تعمل، وهي تعيين نقطة توقف في هذا الجزء من الكود المفكك بعد إنشاء قيمة nonce. في الدليل أدناه، يتم تمرير المفتاح العام إلى الدالة 44E3D8 من أجل اشتقاق المفتاح المشترك باستخدام curve25519. إنه المكان الوحيد الذي يتم فيه كشف المفتاح العام طوال تنفيذ البرمجية الخبيثة.

يرجى الانتباه عند التعامل مع خيارات Visual Studio. قد تتغير مخرجات البرنامج مثل البايتات المُولَّدة للقاموس إذا انتقلت من وضع التصحيح (debug) إلى وضع الإصدار (release) والعكس صحيح.
إذا كنت تريد تسريع إجراء القوة العمياء، يمكنك تعديل قيمة dictionary_dimension في الكود، لكن يرجى الانتباه إلى أن تقليل حجم القاموس قد يقلل أيضًا من فرص العثور على المفاتيح الخاصة.
أيضًا، إذا قررت استخدام مصفوفة بايتات بنص واضح تم توليدها عن طريق تشغيل Hive وتفريغها من الذاكرة، فتذكر ضبط حجم التفريغ في متغير dictionary_dimension.
لاختبار أداة فك التشفير، أتاحت بعض الملفات لاستخدامها في المجلد dummy_data_PoC:
حظًا سعيدًا!
https://github.com/rivitna/Malware/blob/main/Hive/Hive_samples.txt
https://www.virustotal.com/gui/file/335d2e4a743d059955760ecf2ec25ee86d36aa60b096c9180e860c64ef78ee55
https://www.microsoft.com/security/blog/2022/07/05/hive-ransomware-gets-upgrades-in-rust/
https://docs.microsoft.com/en-us/windows/win32/sysinfo/acquiring-high-resolution-time-stamps
https://monocypher.org/manual/x25519
https://monocypher.org/manual/advanced/poly1305