Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
ShellcodeFluctuation — تقنية تهرب متقدمة في الذاكرة تعمل على تذبذب حماية ذاكرة الشيلكود بين RW/NoAccess و RX، ومن ثم تشفير/فك تشفير محتوياته | Kitploit
أدوات/GitHubGitHub/mgeeky/shellcodefluctuation
شيل كودما بعد الاستغلالالفريق الأحمرتطوير الحمولاتالهجوم العدائي
GitHubmgeeky/shellcodefluctuation

ShellcodeFluctuation

تقنية تهرب متقدمة في الذاكرة تعمل على تذبذب حماية ذاكرة الشيلكود بين RW/NoAccess و RX، ومن ثم تشفير/فك تشفير محتوياته

عرض المستودع
1.1k163منذ 4 سنواتتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

Shellcode Fluctuation PoC

تنفيذ PoC لتقنية مراوغة أخرى في الذاكرة تقوم بتشفير وفك تشفير محتويات الشيل كود بشكل دوري لجعله يتأرجح بين حماية الذاكرة RW (أو NoAccess) و RX. عندما تقيم شيل كود الخاص بنا في صفحات ذاكرة RW أو NoAccess، فإن الماسحات الضوئية مثل Moneta أو pe-sieve لن تتمكن من تتبعه وتفريغه لتحليله لاحقًا.

مقدمة

بعد إصدار ThreadStackSpoofer تلقيت بعض الأسئلة حول النقطة التالية من ملف README:

غيّر حماية صفحات ذاكرة الـ Beacon الخاص بك إلى RW (من RX/RWX) وقم بتشفير محتوياتها قبل النوم (قد يؤدي ذلك إلى مراوغة ماسحات ضوئية مثل Moneta أو pe-sieve)

في السابق كنت واثقًا تمامًا من أن المجتمع يعرف بالفعل كيفية تشفير/فك تشفير الحمولات وقلب حمايات الذاكرة الخاصة بها لمجرد مراوغة ماسحات الذاكرة التي تبحث عن مناطق تنفيذ غير طبيعية. لكن الأسئلة أثبتت عكس ذلك، لذا قررت إصدار هذا الـ PoC غير المسلّح لتوثيق استراتيجية مراوغة أخرى وتقديم تنفيذ نموذجي ليعمل معه المجتمع.

هذا الـ PoC هو عرض لتقنية بسيطة نسبيًا، معروفة بالفعل لدى مجتمع الهجوم (لذا لا أحضر أي شيء جديد هنا حقًا) على أمل كشف السر وراء السحر الذي تُظهره بعض الأطر التجارية التي تعرض قدراتها على المراوغة مستهدفةً الماسحين الضوئيين المذكورين أعلاه.

فيما يلي مقارنة عند التأرجح إلى RW (خيار آخر هو التأرجح إلى PAGE_NOACCESS - موصوف أدناه):

  1. Beacon غير مشفّر
  2. Beacon مشفّر (متأرجح)

comparison

هذا التنفيذ إلى جانب ThreadStackSpoofer الخاص بي يقدم للمجتمع الأمني الهجومي تطبيقات نموذجية للحاق بالعروض المقدمة من منتجات C2 التجارية، حتى لا نكون أسوأ حالًا في أدوات Red Team الخاصة بنا. 💪


كيف يعمل؟

يقوم هذا البرنامج بتنفيذ حقن ذاتي للشيل كود (تقريبًا عبر VirtualAlloc الكلاسيكية + memcpy + CreateThread). عند تشغيل الشيل كود (يستهدف هذا التنفيذ تحديدًا حمولات Cobalt Strike Beacon) سيتم ربط دالة ويندوز لاعتراض اللحظة التي ينام فيها الـ Beacon عبر kernel32!Sleep. عندما يتم استدعاء دالة MySleep المربوطة، ستحدد حدود تخصيص الذاكرة الخاص بها، وتقلب حمايتها إلى RW وتقوم بعمل xor32 على جميع البايتات المخزنة هناك. بعد الانتظار للمدة الزمنية المتوقعة، عندما يعود الشيل كود إلى معالج MySleep الخاص بنا، سنقوم بفك تشفير بيانات الشيل كود وقلب الحماية مرة أخرى إلى RX.

التأرجح إلى PAGE_READWRITE يعمل على النحو التالي

  1. قراءة محتويات الشيل كود من ملف.
  2. ربط kernel32!Sleep بحيث يشير إلى دالة الاستدعاء الخاصة بنا.
  3. حقن وتشغيل الشيل كود عبر VirtualAlloc + memcpy + CreateThread. على عكس ما كان لدينا في ThreadStackSpoofer، لا نقوم هنا بربط أي شيء في ntdll لتشغيل الشيل كود الخاص بنا بل نقفز إليه من داخل الدالة الخاصة بنا. تحاول هذه الطريقة تجنب ترك مؤشرات IOC بسيطة في الذاكرة تشير إلى ذاكرة ntdll معدّلة.
  4. بمجرد أن يحاول الـ Beacon النوم، يتم استدعاء دالة الاستدعاء MySleep الخاصة بنا.
  5. يتم تشفير تخصيص الذاكرة الخاص بالـ Beacon وقلب الحماية إلى RW
  6. نقوم بعد ذلك بفك ربط kernel32!Sleep الأصلية لتجنب ترك مؤشر IOC بسيط في الذاكرة يشير إلى أن Sleep قد تم تعديلها بـ trampoline (ربط داخلي inline).
  7. يتم إجراء استدعاء ::Sleep الأصلي للسماح للـ Beacon بالنوم أثناء انتظار التواصل اللاحق.
  8. بعد انتهاء النوم، نقوم بفك تشفير بيانات الشيل كود الخاص بنا، ونقلب حمايات الذاكرة الخاصة به مرة أخرى إلى RX ثم نعيد ربط لضمان اعتراض النوم اللاحق.

التأرجح إلى PAGE_NOACCESS يعمل على النحو التالي

  1. قراءة محتويات الشيل كود من ملف.
  2. ربط kernel32!Sleep بحيث يشير إلى دالة الاستدعاء الخاصة بنا.
  3. حقن وتشغيل الشيل كود عبر VirtualAlloc + memcpy + CreateThread ...
  4. تهيئة معالج استثناءات متجه (VEH) لإعداد المعالج الخاص بنا الذي سيلتقط استثناءات Access Violation.
  5. بمجرد أن يحاول الـ Beacon النوم، يتم استدعاء دالة الاستدعاء MySleep الخاصة بنا.
  6. يتم تشفير تخصيص الذاكرة الخاص بالـ Beacon وقلب الحماية إلى PAGE_NOACCESS
  7. نقوم بعد ذلك بفك ربط kernel32!Sleep الأصلية لتجنب ترك مؤشر IOC بسيط في الذاكرة يشير إلى أن Sleep قد تم تعديلها بـ trampoline (ربط داخلي inline).
  8. يتم إجراء استدعاء ::Sleep الأصلي للسماح للـ Beacon بالنوم أثناء انتظار التواصل اللاحق.
  9. بعد انتهاء النوم، نعيد ربط kernel32!Sleep لضمان اعتراض النوم اللاحق.
  10. يحاول الشيل كود بعد ذلك استئناف تنفيذه مما يؤدي إلى إلقاء استثناء Access Violation نظرًا لأن صفحاته محددة بـ NoAccess.
  11. يلتقط معالج VEH الخاص بنا الاستثناء، ويقوم بفك التشفير وقلب حمايات الذاكرة مرة أخرى إلى RX ويُستأنف الشيل كود.

إنها ليست تقنية جديدة

التقنية ليست جديدة كليًا، وليست شيئًا ابتكرته بنفسي. إنها مجرد تنفيذ يعرض المفهوم واستخدامه العملي للسماح لمجتمعنا الأمني الهجومي باللحاق بالعروض المقدمة من أطر C2 التجارية.

في الواقع، تم تعريفّي بفكرة قلب حماية ذاكرة الشيل كود قبل عدة سنوات من خلال عمل Josh Lospinoso في مشروعه المذهل Gargoyle.

فيما يلي مزيد من الخلفية:

  • gargoyle, a memory scanning evasion technique
  • Bypassing Memory Scanners with Cobalt Strike and Gargoyle

Gargoyle يأخذ مفهوم الشيل كود الواعي بذاته والمتأرجح بذاته إلى أبعد من ذلك، من خلال الاستفادة من تسلسل ROP الذي يستدعي VirtualProtect. ومع ذلك، التقنية مثيرة للإعجاب، لكن من الصعب بنفس القدر استخدامها مع Cobalt Strike's Beacon دون الحاجة إلى قتل الخيط الخاص به والاستمرار في إعادة تهيئة الـ Beacon أثناء تواجده في الذاكرة.

هذا بعيد عن المثالية، لكن نظرًا لأننا نعمل بالفعل من أرضية عملية تحميل ذاتي خاصة بنا، فنحن قادرون على فعل ما نشاء بالبيئة التي يعمل فيها الشيل كود وإخفائه بالطريقة التي نريدها. تُظهر هذه التقنية (والتقنية السابقة ThreadStackSpoofer) مزايا تشغيل الشيل كود الخاص بنا بهذه الطريقة.

تنفيذ التأرجح إلى PAGE_NOACCESS مستوحى من عمل ORCA666 المعروض في https://github.com/ORCA666/0x41 injector. لقد أظهر أنه:

  1. يمكننا تهيئة معالج استثناءات متجه (VEH)،
  2. قلب صفحات الشيل كود إلى no-access
  3. ثم التقاط استثناءات Access Violation التي ستحدث بمجرد أن يريد الشيل كود استئناف تنفيذه وفك تشفير وقلب صفحات ذاكرته مرة أخرى إلى Read+Execute.

يحتوي هذا التنفيذ على هذه الفكرة مطبقة، وهي متاحة مع الخيار 2 في <fluctuate>. تأكد من الاطلاع على مشاريعه الأخرى أيضًا.


عرض توضيحي

تقبل الأداة ShellcodeFluctuation ثلاثة معاملات: الأول هو المسار إلى الشيل كود والثاني هو معدّل وظيفتنا.``` Usage: ShellcodeFluctuation.exe : -1 - Read shellcode but dont inject it. Run in an infinite loop. 0 - Inject the shellcode but don't hook kernel32!Sleep and don't encrypt anything 1 - Inject shellcode and start fluctuating its memory with standard PAGE_READWRITE. 2 - Inject shellcode and start fluctuating its memory with ORCA666's PAGE_NOACCESS.

root@kitploit:~
### إيجابية كاذبة (على ما يبدو) من Moneta```
C:\> ShellcodeFluctuation.exe beacon64.bin -1

لذا أولاً سنرى ما يراه ماسح Moneta64 حول عملية لا تفعل أي شيء مريب وتكتفي ببساطة بتشغيل حلقة لا نهائية:

moneta إيجابية كاذبة

كما نرى هناك بعض الإيجابيات الكاذبة (على الأقل كما أعتبرها) التي يُزعم أنها تكتشف Mismatching PEB module / Phantom image. حدود الذاكرة تشير إلى وحدة ShellcodeFluctuate.exe نفسها وقد تشير إلى أن هذه الوحدة، رغم كونها من نوع MEM_IMAGE، غير مرتبطة في PEB الخاصة بالعملية - وهو أمر غير معتاد ويبدو غريباً إلى حد ما. سبب هذا الـ IOC غير معروف بالنسبة لي ولم أحاول فهمه بشكل أفضل، لكنه ليس شيئاً يجب أن نقلق بشأنه حقاً.

إذا كان أي شخص يعرف سبب هذا الاكتشاف، فسأكون فضولياً جداً لسماعه! يرجى التواصل معي.

بيكون غير مشفّر```

C:> ShellcodeFluctuation.exe beacon64.bin 0

root@kitploit:~
الحالة الاستخدامية الثانية تعرض مؤشرات ذاكرة (Memory IOCs) لـ Beacon يعمل داخل عمليتنا، ولا يستخدم أي أنواع من `Artifact Kits` المخصصة، أو `User-Defined Reflective Loaders` (مثل [`ElusiveMice`](https://github.com/mgeeky/ElusiveMice))، ولا أي إجراءات أولية من شأنها أن تفسد نتائجنا.

![moneta not encrypted](https://assets.kitploit.com/production/public/readmes/50718/6a4e3a230a362c25da6f4aa6955b822d2a83215848c1bc09566a27ea9db653c9/dd2e0560a688886c0fe06debe92f153e129daa6654cb17c2976edee8661e3bd3-display-v1.webp)

يمكننا أن نرى أن `Moneta64` يتعرف بشكل صحيح على `Abnormal private executable memory` مشيراً إلى الموقع الذي توجد فيه شيلكود (shellcode) الخاصة بنا. 
هذا مؤشر ذاكرة قوي جداً يكشف الشيلكود الخاصة بنا ليقوم الماسحات الآلية بتفريغها وتحليلها. ليس أمراً جيداً.

### Beacon مشفر مع حمايات RW```
C:\> ShellcodeFluctuation.exe beacon64.bin 1

الآن، حالة الاستخدام الثالثة، والأكثر إثارة للاهتمام من منظور هذا التنفيذ، هي Beacon المتقلب.

moneta encrypted

بصرف النظر عن أول IOC، الذي يُعتبر إلى حد ما إيجابية كاذبة، نرى مؤشرًا جديدًا يشير إلى أن ذاكرة kernel32.dll تم تعديلها. ومع ذلك، لا يوجد مؤشر Abnormal private executable memory هذه المرة. تقلبنا (التشفير/فك التشفير المتكرر وتبديل حمايات الذاكرة) نشط.

وللتسجيل، فإن pe-sieve يكتشف أيضًا الـ PE المزروع عند استخدامه مع خيار /data 3 (ما لم يتم إعطاء هذا الخيار، لن يتم إجراء أي اكتشاف):

pe-sieve

افتراضي الحالي هو أن PE-Sieve يلتقط نفس السمات التي يلتقطها Moneta (الموصوفة أدناه في الكود المعدّل في kernel32.dll) - حقيقة أن الوحدة النمطية المعيّنة من PE تحتوي على Working set غير فارغ، وهي دليل واضح على حقن كود من نوع ما. يُصنَّف هذا على أنه Implanted PE / Implanted. إذا كان الأمر كذلك، فإن الاستنتاج مشابه لملاحظة Moneta. لا أعتقد أننا يجب أن نهتم كثيرًا بذلك المؤشر من ناحية الاكتشاف.

حاليًا، لم أفكر في خيار أفضل لاعتراض تنفيذ الـ shellcode في المنتصف (وأنا الآن أتحدث عن Cobalt Strike) سوى ربط kernel32!Sleep. وبالتالي، نحن مضطرون لترك هذه الأنواع من مؤشرات IOC.

لكن مهلاً، ما زالت البايتات كما هي تمامًا مقارنةً بما هو موجود على نظام الملفات (C:\Windows\System32\kernel32.dll) ولا توجد أي دالة مربوطة، فما الأمر؟ 😉

Beacon مُشفَّر مع حمايات PAGE_NOACCESS```

C:> ShellcodeFluctuation.exe beacon64.bin 2

root@kitploit:~
![no-access](https://assets.kitploit.com/production/public/readmes/50718/03f80df765f37efb3242dce12c613091ab79896e584fbfc2a309a1295c4544c6/327fe5cc3e3ebe6db8277bd091361f7ae42ee4925e21aa87cfa9287b404a1ab5-display-v1.webp)

سيؤدي ذلك إلى جعل الـ shellcode يتأرجح بين صفحات `RX` و `NA` بشكل فعّال.

في الوقت الحالي، لست متأكدًا من فوائد التحويل إلى `PAGE_NOACCESS` بدلاً من `PAGE_READWRITE`.


### الكود المعدَّل في kernel32.dll

إذًا، ما الأمر بالنسبة إلى مؤشر الاختراق (IOC) الخاص بـ `kernel32` المعدَّل؟

الآن، دعونا نحاول الوصول إلى جذور هذا الـ IOC ومعرفة ما هي القصة.

أولاً، سنقوم بتفريغ منطقة الذاكرة المذكورة - وهي قسم `.text` (الكود) في `kernel32.dll`. دعونا نستخدم `ProcessHacker` لهذا الغرض للاستفادة من أدوات معروفة ومستقرة للعموم:

![dump-kernel](https://assets.kitploit.com/production/public/readmes/50718/0b1a4700514b15ec5199ead8f09ccd7c4e5fefc2302a9a9eee0d4e6d77ea48b4/bae9be0ce4bdcede99f235f42431b159bbbf35539f36fe58906fe991e4aacdb4-display-v1.webp)

نقوم بتفريغ قسم الكود من kernel32 الذي يُفترض أنه معدَّل، ثم نقوم بالشيء نفسه بالنسبة إلى kernel32 العامل في عملية لم تعدّل تلك المنطقة.

بعد الحصول على تفريغين، يمكننا مقارنتهما بايتًا ببايت (باستخدام [expdevBadChars](https://github.com/mgeeky/expdevBadChars) الخاص بي) للبحث عن أي تناقضات:

![bindiff](https://assets.kitploit.com/production/public/readmes/50718/4df33e426c7d23554953e2117e3706ee9af1b53b3dd4a60f7b05bcabb988bc85/3db05a8375ded834d576d29083dab9b646cbd83b791a591717fbe0e56ca9a64e-display-v1.webp)

فقط لنرى أنهما متطابقان تمامًا. من الواضح أنه لا يوجد بايت واحد معدَّل في `kernel32.dll`، والسبب في ذلك هو أننا نقوم بإزالة الخطاف من `kernel32!Sleep` قبل استدعائه:

`main.cpp:31:````
    HookTrampolineBuffers buffers = { 0 };
    buffers.originalBytes = g_hookedSleep.sleepStub;
    buffers.originalBytesSize = sizeof(g_hookedSleep.sleepStub);

    //
    // Unhook kernel32!Sleep to evade hooked Sleep IOC. 
    // We leverage the fact that the return address left on the stack will make the thread
    // get back to our handler anyway.
    //
    fastTrampoline(false, (BYTE*)::Sleep, &MySleep, &buffers);

    // Perform sleep emulating originally hooked functionality.
    ::Sleep(dwMilliseconds);

إذًا ما الذي يسبب تفعيل IOC؟ دعونا نفحص Moneta عن كثب:

moneta

عند كسرنا في ملف Ioc.cpp الخاص بـ Moneta قرب السطر 104 حيث يُبلِّغ عن IOC من نوع MODIFIED_CODE، يمكننا تعديل الكود قليلًا لكشف اللحظة الدقيقة التي يحلّل فيها تجمع kernel32 بشكل أفضل. الآن:

  1. يتم إجراء الفحص للتأكد من أن منطقة kernel32 قابلة للتنفيذ. نرى في الواقع أن تلك المنطقة قابلة للتنفيذ a = true
  2. يتم الحصول على مقدار الذاكرة الخاصة (private memory) لتلك الوحدة. هنا نرى أن kernel32 يحتوي على b = 0x1000 بايت خاص. كيف حدث ذلك؟ من المفترض أن يكون العدد 0.
  3. إذا كان التخصيص القابل للتنفيذ يحتوي على أكثر من 0 بايت من الذاكرة الخاصة (a && b) فسيتم الإبلاغ عن IOC
  4. وهذا دليل على أننا كنا نفحص kernel32 في ذلك الوقت.

عندما يقوم مُحمّل الصور في Windows (Windows Image Loader) بتعيين وحدة DLL في مساحة ذاكرة العملية، سيتم تصنيف صفحات الذاكرة الأساسية على أنها MEM_MAPPED أو MEM_IMAGE حسب السيناريو. عندما نعدّل ولو بايتًا واحدًا من تخصيص MEM_MAPPED/MEM_IMAGE، سيفصل النظام صفحة ذاكرة واحدة (بافتراض أننا عدّلنا أقل من PAGE_SIZE بايت ولم نتجاوز حدود الصفحة) للإشارة إلى جزء لا يعود إلى الصورة الأصلية.

تُستخدم هذه الملاحظة بعد ذلك كـ IOC - لا ينبغي أن تحتوي الصورة على تخصيصات MEM_PRIVATE داخل منطقة الذاكرة الخاصة بها (بداخلها) لأن ذلك سيشير إلى أن بعض البايتات قد عُدّلت في يوم من الأيام داخل تلك المنطقة. يعمل Moneta بشكل صحيح على التقاط تعديل الكود حتى وإن كانت البايتات مطابقة لبايتات الوحدة الأصلية في وقت المقارنة.

للحصول على شرح شامل لكيفية عمل Moneta وتنفيذ حقن العملية (process injection) وIOC المرتبط بها تحت الغطاء، اقرأ المقالات التالية عالية الجودة بقلم Forrest Orr:

  1. إخفاء آثار الذاكرة الخبيثة – الجزء الأول: إفراغ DLL الشبح (Phantom DLL Hollowing)
  2. إخفاء آثار الذاكرة الخبيثة – الجزء الثاني: الاندماج عبر الإيجابيات الكاذبة
  3. إخفاء آثار الذاكرة الخبيثة – الجزء الثالث: تجاوز أدوات الفحص الدفاعية

هذا بحث وتوثيق رائع حقًا من Forrest، عمل رائع يا صديقي!

خاصةً المقال الثاني يوضح الأساس المنطقي لهذا الاكتشاف، كما نقرأ ما يعلّمه إيانا Forrest:

في حال كانت الوحدة قد حُمّلت بشكل شرعي وأُضيفت إلى PEB، لكان حِقن الشيلكود (shellcode implant) ما يزال قابِلًا للاكتشاف بسبب الـ 0x1000 بايت (صفحة واحدة) من الذاكرة المُعيَّنة بشكل خاص في مساحة العنوان والتي استرجعها Moneta عبر الاستعلام عن مجموعة العمل (working set) الخاصة به - مما يؤدي إلى IOC لتعديل الكود كما رأينا أعلاه.

باختصار، نترك وراءنا IOC، لكن هل يجب أن نقلق بشأن ذلك؟ حتى لو وُجد IOC، فلا توجد بايتات مسروقة مرئية، لذا لا يوجد مرجع مباشر يعيد إلى الشيلكود الخاص بنا أو يميّز تقنيتنا عن غيرها من التقنيات.

باختصار شديد - لا ينبغي لنا أن نقلق كثيرًا بشأن ذلك الـ IOC. :-)

لكن الأطر التجارية لا تترك أي IOC

يمكن للمرء أن يقول إن هذا التنفيذ بعيد عن الكمال لأنه يترك شيئًا، فما تزال هناك مؤشرات IOC وتُظهر المنتجات التجارية أنها لا تمتلك سمات مشابهة.

عندما يُطرَح هذا الجدال على الطاولة، يجب أن أذكّر بأن الأطر التجارية تمتلك سيطرة كاملة على الكود المصدري لحِقنها (implants) ومحمّلات الشيلكود الخاصة بها، وبالتالي يمكنها دمج أحدهما مع الآخر بشكل جيد لتجنب الحاجة إلى الربط (hooking) والالتفاف حول الشيلكود الخاص بها بنفسها. هنا، نحتاج إلى ربط kernel32!Sleep لاعتراض تنفيذ Beacon من Cobalt Strike قبل أن يدخل في وضع السكون مباشرةً لنتمكن من المتابعة في مهام الصيانة الخاصة بنا. لو وُجدت آلية أفضل لنا للتدخل دون الحاجة إلى ربط دالة sleep لكان ذلك مثاليًا.

ومع ذلك، هناك مفهوم قناع النوم (Sleep Mask) الذي قُدِّم إلى Cobalt Strike، وقيود الحجم كونه مئات البايتات تجعلنا غير قادرين تمامًا على إدخال هذا المنطق في القناع نفسه (وإلا لكنا قادرين على عدم ربط Sleep أيضًا، دون ترك أي IOC تمامًا كما تفعل المنتجات التجارية).

قد تكون حجة أخرى أن الأطر التجارية تدمج هذا النوع من المنطق في محمّلات الانعكاس (Reflective Loaders) الخاصة بها، بينما نتركه هنا في أداة الاستضافة EXE بدلًا من ذلك. هذا صحيح، لكن السبب وراء هذا القرار مزدوج:

  1. أحتاج إلى توخي الحذر الشديد عند إصدار هذا النوع من التقنيات لتجنب خطر المساعدة في تسليح مجرمين حقيقيين بتنفيذ سيعود ليطاردنا عبر شيء آخر مثل Petya. وبهذا الأسلوب قررت تخطي بعض التفاصيل المعقدة التي أستخدمها في أدواتي الاحترافية المستخدمة لتقديم تمارين محاكاة الخصم (Adversary Simulation) التجارية المتعاقد عليها. تقديم البذرة آمل أن يُقابَل بمتخصصين من المجتمع قادرين على تنمية المفهوم في أدواتهم الخاصة، بافتراض أنهم يتمتعون بالمهارات المناسبة.

  2. كنت أفضل كثيرًا نقل هذا المنطق بالكامل إلى المحمّل الانعكاسي المعرّف من قبل المستخدم (User-Defined Reflective Loader) الخاص بـ Cobalt Strike، مما يمنح فرق الاختراق (Red Team) فرصًا أعلى في مرحلة التسليم. لكن أولًا، انظر إلى النقطة (1)، وثانيًا هذه التقنية محدودة حاليًا بحجم 5 كيلوبايتات لملفات RDLL الخاصة بها، مما يجعلني غير قادر تمامًا على تنفيذها هناك أيضًا. بالنسبة لمن يبنون C2 وحِقنًا مخصصة لعمليات محاكاة الخصم الداخلية - فقد تلقوا الآن تنفيذًا نموذجيًا سيساعدهم بالتأكيد في تحسين أدواتهم وفقًا لذلك.


كيف أستخدمه؟

انظر إلى الكود وتنفيذه، وافهم المفهوم وأعد تنفيذه داخل محمّلات الشيلكود الخاصة بك التي تستخدمها لتقديم عمليات Red Team. هذه تقنية أخرى من تقنيات المراوغة المتقدمة في الذاكرة تزيد من فرص فريقك في عدم اكتشافه من قبل برامج مكافحة الفيروسات، وأنظمة EDR، ومحللي البرمجيات الخبيثة الذين يفحصون حِقنك.

أثناء تطوير محمّل الشيلكود المتقدم الخاص بك، قد ترغب أيضًا في تنفيذ ما يلي:

  • تشفير كومة العملية (Process Heap Encryption) - استلهم من هذه التدوينة: Hook Heaps and Live Free - والتي يمكن أن تسمح لك بتجنب أدوات استخراج إعدادات Beacon مثل BeaconEye
  • زيّف مكدس استدعاءات الخيط الخاص بك قبل النوم (يمكن أن يتفادى الماسحات الضوئية التي تحاول فحص خيوط العملية ومكدسات الاستدعاءات الخاصة بها في محاولة لاصطياد تخصيصات الذاكرة MEM_PRIVATE التي تشير إليها هذه الخيوط)
  • امسح أي بقايا من المحمّل الانعكاسي (Reflective Loader) لتجنب عمليات الكشف القائمة على التوقيع في الذاكرة
  • أزل الربط (unhook) عن كل ما قد تكون ربطته (مثل AMSI وETW وWLDP) قبل النوم ثم أعد الربط بعد ذلك.

مثال على التشغيل

حالة الاستخدام:``` Usage: ShellcodeFluctuation.exe : -1 - Read shellcode but dont inject it. Run in an infinite loop. 0 - Inject the shellcode but don't hook kernel32!Sleep and don't encrypt anything 1 - Inject shellcode and start fluctuating its memory with standard PAGE_READWRITE. 2 - Inject shellcode and start fluctuating its memory with ORCA666's PAGE_NOACCESS.

root@kitploit:~
حيث:
- `<shellcode>` هو مسار إلى ملف shellcode
- `<fluctuate>` كما هو موضح أعلاه، يأخذ `-1` أو `0` أو `1`


مثال على تشغيل يزيّف مكدس استدعاءات الخيط الخاص بـ beacon:```
C:\> ShellcodeFluctuation.exe ..\..\tests\beacon64.bin 1

[.] Reading shellcode bytes...
[.] Hooking kernel32!Sleep...
[.] Injecting shellcode...
[+] Shellcode is now running. PID = 9456
[+] Fluctuation initialized.
    Shellcode resides at 0x000002210C091000 and occupies 176128 bytes. XOR32 key: 0x1e602f0d
[>] Flipped to RW. Encoding...

===> MySleep(5000)

[.] Decoding...
[>] Flipped to RX.
[>] Flipped to RW. Encoding...

===> MySleep(5000)

كلمة تحذير

إذا كنت تخطط لإضافة هذه الوظيفة إلى أدوات تحميل الشيل كود / الأدوات الخاصة بك، فتأكد من تجنب إزالة الخطاف (unhook) من kernel32.dll. أي محاولة لإزالة خطاف kernel32 ستؤدي إلى استعادة وظيفة Sleep الأصلية مما يمنع استدعاء الـ callback الخاص بنا. إذا لم يتم استدعاء الـ callback، فلن يتمكن الخيط من تزييف مكدس الاستدعاءات الخاص به بنفسه.

إذا كان هذا ما تريده، فقد تحتاج إلى تشغيل خيط مراقب (watchdog) آخر، للتأكد من أن خيط Beacons يتم تزييف مكدسه كلما نام.

إذا كنت تستخدم Cobalt Strike و BOF unhook-bof من Raphael's Mudge، فتأكد من الاطّلاع على Pull Request الخاص بي الذي يضيف معاملًا اختياريًا إلى BOF يحدد المكتبات التي يجب عدم إزالة خطافاتها.

بهذه الطريقة يمكنك الحفاظ على خطافاتك في kernel32:

---``` beacon> unhook kernel32 [*] Running unhook. Will skip these modules: wmp.dll, kernel32.dll [+] host called home, sent: 9475 bytes [+] received output: ntdll.dll <.text> Unhook is done.

root@kitploit:~
[نسخة معدّلة من `unhook-bof` مع خيار لتجاهل الوحدات المحددة](https://github.com/mgeeky/unhook-bof)

---

## ملاحظة ختامية

صُمم هذا الإثبات المفاهيمي ليعمل مع شيلكودات Beacon الخاصة بـ Cobalt Strike. من المعروف أن الـ Beacon يستدعي `kernel32!Sleep` لانتظار تعليمات أخرى من خادم التحكم (C2). 
يستغل هذا المحمّل هذه الحقيقة من خلال تعليق خطاف على `Sleep` لتنفيذ مهامه الداخلية.

قد لا يعمل هذا التنفيذ مع شيلكودات أخرى في السوق (مثل _Meterpreter_) إذا كانت لا تستخدم `Sleep` لفترات التهدئة. 
وبما أن هذا مجرد _إثبات مفاهيمي_ يعرض التقنية، فإنني لا أنوي إضافة دعم لأي إطار C2 آخر.

عندما تفهم الفكرة، ستحتاج بالتأكيد إلى ترجمتها إلى متطلبات الشيلكود الخاص بك وتكييف الحل لصالحك.

يُرجى عدم فتح مشكلات على GitHub تتعلق بـ "هذا الكود لا يعمل مع شيلكود XYZ"، فسيتم إغلاقها فورًا.

---

### ☕ أظهر دعمك ☕

هذا المشروع وغيره من المشاريع هي ثمرة ليالٍ بلا نوم و**الكثير من العمل الشاق**. إذا أعجبك ما أقدمه وتقدّر أنني دائمًا أعود بالفائدة على المجتمع،
[فكّر في شراء قهوة لي](https://github.com/sponsors/mgeeky) _(أو الأفضل بيرة)_ فقط لقول شكرًا! 💪 

---

## المؤلف```   
   Mariusz Banach / mgeeky, 21
   <mb [at] binary-offensive.com>
   (https://github.com/mgeeky)
تنزيل الأداة
kernel32!Sleep