
PoC بسيط لاستدعاء شيلكود مشفر باستخدام استدعاء مخفي
أداة إثبات مفهوم بسيطة لاستدعاء shellcode مشفر باستخدام استدعاء مخفي.
يستخدم هذا الكود خدعة بسيطة لإخفاء التعليمات التي ستقفز فعليًا إلى shellcode الخاص بنا. يجب أن يجعل ذلك التحليل الثابت أو المحاكاة أكثر صعوبة.
كما هو الحال دائمًا، إذا تم شرح هذا المفهوم بالفعل في أوراق أخرى، فقط أرسل لي رسالة وسأضيفه بكل سرور إلى المراجع.
تخطيط الذاكرة لاستخدام هذه التقنية هو التخطيط القياسي كما هو موضح في الشكل 1.
┌───────────────────────────────┐
│ │
│ │
│ │
│ │
│ encrypted shellcode │
│ │
│ │
│ │
│ │
│ │
│ │
├───────────────────────────────┤
│ │
│ │
│ decryption loop │
│ │
│ │
└───────────────────────────────┘
الشكل 1. تخطيط الذاكرة
ستقوم حلقة فك التشفير بفك تشفير shellcode والقفز إليه. كل "السحر" داخل حلقة فك التشفير، حيث بعد الانتهاء من فك تشفير shellcode، ستبدأ حلقة فك التشفير في فك تشفير كودها الخاص. سيؤدي فك تشفير التعليمات الأولى إلى قفزة إلى shellcode الخاص بنا والتي يتم تنفيذها في التكرار التالي للحلقة :)
أدناه الجزء ذو الصلة:
@decryption:
xor word ptr [eax], 06799h ; <jmp esi bytes> XOR <first two bytes of this instruction>
add eax, sizeof word
dec ecx
loop @decryption
كما ترى، لا تحتوي حلقة فك التشفير على أي تعليمة تقفز إلى shellcode الذي تم فك تشفيره. يتم تجميع كود التجميع بالتنسيق الثنائي التالي:
66:8130 9967 | xor word ptr ds:[eax],6799
83C0 02 | add eax,2
49 | dec ecx
E2 F5 | loop 450006
في هذه الحالة، يجب أن يكون مفتاح فك التشفير 06799h، لأن عملية XOR بين 8166h (أول بايتين من أول تعليمة في حلقة فك التشفير) و 6799h (مفتاح XOR) هي e6ffh والتي يتم تجميعها إلى jmp esi. بعبارة أخرى:
0x8166 (xor word ptr ds:[eax],...) XOR 0x6799 (decryption key) == 0x6eff (jmp esi)
من خلال تعيين مسجل ESI إلى بداية shellcode الخاص بنا، يمكننا تحقيق التنفيذ :)
أدناه مثال على التصحيح. في البداية، يتم نسخ shellcode المشفر، يليه الكود المستخدم لفك التشفير واستدعاء shellcode. من الممكن ملاحظة أنه بعد التنفيذ الثالث لحلقة فك التشفير، تتغير التعليمات xor word ptr ds:[eax],6799 إلى jmp esi.

الخطوات لاستخدام هذه التقنية هي:
لجعل كود فك التشفير أقل قابلية للتعرف، من الممكن استخدام طرق بديلة لاستدعاء shellcode. للحصول على مزيد من الحرية، يمكننا التفكير في زيادة حجم القطعة التي يتم تشفيرها خلال كل تكرار. في إثبات المفهوم الخاص بي، استخدمت 2 بايت لأن jmp esi يحتاج إلى بايتين، ولكن يمكننا استخدام حجم قطعة 4 أو 8 بايت، مما يسمح للمشغل بالحصول على المزيد من البدائل التي تتناسب مع قطعة 4 أو 8 بايت. وفقًا للطريقة المختارة لاستدعاء shellcode، سيتغير ثابت التشفير أيضًا.