
ShellcodeFluctuation PoC ported to Nim
نسخة Nim المنقولة من المستودع الأصلي: https://github.com/mgeeky/ShellcodeFluctuation تم لصق جميع التعليقات كما هي من المستودع الأصلي لأنها ساعدتني حقًا في فهم التقنية. لمزيد من المعلومات حول التقنية نفسها، أنصح بشدة بمراجعة ملف README الخاص بالمستودع الأصلي!
تثبيت التبعيات:
nimble install winim ptr_math
أنا مدرك تمامًا لحقيقة أن تقنية تشفير الذاكرة هذه ليست الأفضل من حيث OpSec. فهي ستقوم فقط بتشفير تلك المناطق المحددة لها بالضبط. لذا، على سبيل المثال، بالنسبة لـ C2-Implant، لن يتم تشفير عناوين ذاكرة الوحدات المنفذة حديثًا عند Sleep. بالنسبة لعمليات الكشف التي تعتمد على الكومة (مثل تلك الخاصة بإعداد Cobalt-Strike)، ستظل بحاجة إلى إضافة تشفير الكومة هنا.
ولكن مع ذلك، يمكن استخدام تقنية تشفير الذاكرة بشكل مثالي لتجنب اكتشافات ماسح الذاكرة التلقائية أثناء Sleep for the main C2-Implant. لقد اختبرت الـ PoC بنجاح مع Covenant وحمولة Payload مخصصة بدون مراحل مثل هذه.
يجب تعريف مفتاح التشفير/فك التشفير بالإضافة إلى عنوان الـ Shellcode وقيم أخرى مثل الحماية (RW) يدويًا في هذه النسخة المنقولة (Port). في المستودع الأصلي، كان عنوان استدعاء الـ Shellcode يُسترد تلقائيًا.
يحتوي ملف Example.nim على كل ما تحتاجه للبدء. بالطبع، عند استخدام C2-Shellcode، لا تحتاج إلى استدعاء Sleep بنفسك (هذا فقط لتفعيل كل شيء لأغراض الـ PoC)، بل يجب أن يقوم بذلك الـ C2 الخاص بك. في الوقت الحالي، هذا متوافق فقط مع أطر عمل C2 التي تستخدم دالة Win32 Sleep، ولكن إذا قمت بتعديل الـ Hook لدالة أخرى فستعمل بنفس الطريقة.
import winim
import Fluctuation
echo "Trying to hook Sleep"
if (hookSleep()):
echo "Hooked Sleep successfully!"
type
PocArray = array[12, byte]
let names: PocArray = [byte 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA]
g_fluctuationData.shellcodeAddr = unsafeAddr names[0]
echo "Shellcode address:"
echo repr(g_fluctuationData.shellcodeAddr)
g_fluctuationData.shellcodeSize = size_t(len(names))
echo "Shellcode Size:"
echo repr(g_fluctuationData.shellcodeSize)
when defined(amd64):
g_fluctuationData.encodeKey = 0xDEADB33f
when defined(i386):
g_fluctuationData.encodeKey = 0xDEAD
g_fluctuationData.currentlyEncrypted = false
g_fluctuationData.protect = PAGE_READWRITE
g_fluctuate = FluctuateToRW
echo "Calling Sleep"
Sleep(2500)
echo "Everything went fine and as expected"
else:
echo "Failed to hook Sleep"
quit(1)
يمكن اختبار الـ PoC الخاص بالتشفير، على سبيل المثال، على النحو التالي:
nim c --debuginfo --linedir:on Example.nim
ابدأ بمصحح الأخطاء:
gdb Example.exe
عيّن نقاط الإيقاف (Breakpoints) قبل وبعد Sleep:
# Before encryption
break Example.nim:31
# After encryption
break Fluctuation.nim:98
# Original value restored
break Example.nim:33
بعد ذلك، تحقق من قيمة عنوان الـ Shellcode عند كل نقطة إيقاف على النحو التالي:

الانتقال إلى NA في Fluctuation لا يعمل بعد، حيث لم يتم تشغيل معالج الاستثناءات الموجهة (Vectored Exception Handler) في اختباري مطلقًا بل تعطل التطبيق. يجب إجراء المزيد من الاختبارات/استكشاف الأخطاء وإصلاحها في وقت لاحق. لا تتردد في تجربته بنفسك! :-)