D2
Администратор
- Регистрация
- 19 Фев 2025
- Сообщения
- 4,380
- Реакции
- 0
Автор ru_soft
Источник https://xss.is
Доброго времени суток
Сегодня мы напишем быстрый и маленький нерезидентный лоадер вместе с билдером к нему.
Реализуем возможность собирать лоадер в следующих форматах: EXE x86, EXE x64, DLL x86 (rundll32/regsvr), DLL x64 (rundll32/regsvr)? выход из лоу через спам UAC окном, удаление Zone Identifier у скачанного файла и простую защиту от попадания в онлайн сэндбоксы.
Само собой, будет добавлена поддержка разных видов полезной нагрузки, начиная бинарными пейлоадами (EXE, DLL, шеллкоды) и заканчивая скриптами.
Для простоты понимания код будет написан на C с использованием среды разработки VS 2022, написанный мною код будет работать и на более ранних версиях, однако в том случае, если для вас важна поддержка Windows XP - потребуются соответствующие пакеты.
Для начала нам потребуется создать пустой проект и правильно его настроить. Мы уберём из проекта все лишние зависимости, отключим CRT и сохранение отладочной информации.
После создания проекта переходим в его свойства, и ставим следующие настройки по вкладкам:
Прототип точки входа будет выглядеть так:
C: Скопировать в буфер обмена
Как видите, в отличии от приложений использующих CRT она ничего не возвращает, потому что системный загрузчик передаёт управление напрямую на неё.
В случае с CRT управление передаётся на точку входа CRT, внутри которой инициализируется рантайм, а затем происходит прыжок на main, WinMain и аналоги.
Первым делом мы подключим мой менеджер памяти и функционал для удобного вывода отладочных сообщений.
Этот же код использовался и в прошлой статье про написание скрытого майнера и не представляет ничего интересного: удобные аллокация, реаллокация и освобождение памяти, вывод отформатированных отладочных сообщений в DBGOUT и файл.
Код прилагаю ниже:
C: Скопировать в буфер обмена
Далее мы реализуем функционал извлечения информации из конфига. Наш конфиг будет зашифрованным RC4 блобом. В стаб вшита сигнатура, билдер будет искать эту сигнатуру, формировать конфигурацию и вставлять её на место сигнатуры.
RC4 ключ при каждом ребилде уникален, чтобы конфиг не выглядел статично. В памяти данные будут смотреться так:
RC4 ключ (8 байт) - размер зашифрованного конфига (4 байта) - конфиг
После расшифровки конфига мы получим:
Размер ссылки на файл (4 байта) - ссылка на файл - Тип полезной нагрузки (4 байта) - размер экспортируемой функции (4 байта) - экспортируемая функция - нужно ли принудительно повышать уровень привилегий (1 байт)
Про последнюю опцию - мы введём возможность принудительно поднимать integrity level до High тем же методом флуда UAC окном.
Если процесс запущен под Medium IL, но права отсутствуют, условие отработает и привилегии будут повышаться.
Я вынесу конфиг в глобальную переменную, задав ему размер в 5000 байт, или же 5 килобайт. Добавляем сигнатуру, забивая остальное место после неё нулями:
C: Скопировать в буфер обмена
Рассмотрим функционал распаковки конфига. Вышеописанная информация считывается из BLOB'а, дешифруется и распределяется по переменным.
Для дешифровки мы будем использовать алгоритм шифрования ARC4, реализация которого была позаимствована мной из библиотеки mbedtls, Скачать
Источник https://xss.is
Доброго времени суток
Сегодня мы напишем быстрый и маленький нерезидентный лоадер вместе с билдером к нему.
Реализуем возможность собирать лоадер в следующих форматах: EXE x86, EXE x64, DLL x86 (rundll32/regsvr), DLL x64 (rundll32/regsvr)? выход из лоу через спам UAC окном, удаление Zone Identifier у скачанного файла и простую защиту от попадания в онлайн сэндбоксы.
Само собой, будет добавлена поддержка разных видов полезной нагрузки, начиная бинарными пейлоадами (EXE, DLL, шеллкоды) и заканчивая скриптами.
Для простоты понимания код будет написан на C с использованием среды разработки VS 2022, написанный мною код будет работать и на более ранних версиях, однако в том случае, если для вас важна поддержка Windows XP - потребуются соответствующие пакеты.
Для начала нам потребуется создать пустой проект и правильно его настроить. Мы уберём из проекта все лишние зависимости, отключим CRT и сохранение отладочной информации.
После создания проекта переходим в его свойства, и ставим следующие настройки по вкладкам:
Применяем настройки и сохраняем их. Мы отвязали проект от CRT, сделали чтобы он собирался статически и задали кастомную точку входа - начнём написание лоадера с ее оформления.Общие:
Набор инструментов платформы - Visual Studio 2017 - Windows XP (v141_xp)
C/C++:
Оптимизация:
Оптимизация: Максимальная оптимизация (приоритет размера) /O1
Предпочитать размер или скорость: предпочитать краткость кода (/Os)
Оптимизация всей программы: нет
Создание кода:
Включить обьединние строк: Нет (/GF-)
Включить C++ исключения: Нет
Библиотека времени выполнения: Многопоточная (/MT)
Компоновщик:
Файл манифеста:
Создавать манифест: Нет (/MANIFEST:NO)
Отладка:
Создавать отладочную информацию: Нет
Система:
Подсистема: /SUBSYSTEM:WINDOWS
Дополнительно:
Точка входа: Entry
Нажмите, чтобы раскрыть...
Прототип точки входа будет выглядеть так:
C: Скопировать в буфер обмена
Код:
void Entry() {
}
Как видите, в отличии от приложений использующих CRT она ничего не возвращает, потому что системный загрузчик передаёт управление напрямую на неё.
В случае с CRT управление передаётся на точку входа CRT, внутри которой инициализируется рантайм, а затем происходит прыжок на main, WinMain и аналоги.
Первым делом мы подключим мой менеджер памяти и функционал для удобного вывода отладочных сообщений.
Этот же код использовался и в прошлой статье про написание скрытого майнера и не представляет ничего интересного: удобные аллокация, реаллокация и освобождение памяти, вывод отформатированных отладочных сообщений в DBGOUT и файл.
Код прилагаю ниже:
C: Скопировать в буфер обмена
Код:
#include "dbg.h"
#include <Shlwapi.h>
namespace Debug {
OutputTypes output_type;
CRITICAL_SECTION CS = { 0 };
HANDLE dbg_file_handle = 0;
bool Init(OutputTypes type) {
output_type = type;
if (type == OutputTypes::kFile) {
InitializeCriticalSection(&CS);
dbg_file_handle = CreateFileW(L"C:\\ProgramData\\fastldr.log", GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
if (dbg_file_handle == INVALID_HANDLE_VALUE) {
return FALSE;
}
WORD bom = 0xFEFF;
DWORD written = 0;
WriteFile(dbg_file_handle, &bom, sizeof(bom), &written, NULL);
}
return TRUE;
}
void OutToDbg(LPCWSTR message_text, va_list args) {
WCHAR dbg_message[1025] = { 0 };
wvsprintfW(dbg_message, message_text, args);
OutputDebugStringW(dbg_message);
}
void OutToFile(LPCWSTR message_text, va_list args) {
EnterCriticalSection(&CS);
WCHAR dbg_message[1025] = { 0 };
int char_count = wvsprintfW(dbg_message, message_text, args);
DWORD written = 0;
WriteFile(dbg_file_handle, dbg_message, char_count * 2, &written, nullptr);
WriteFile(dbg_file_handle, L"\r\n", 4, &written, nullptr);
LeaveCriticalSection(&CS);
}
void DebugMsg(LPCWSTR message_text, ...) {
va_list args = nullptr;
va_start(args, message_text);
switch (output_type) {
case OutputTypes::kDbgConsole:
OutToDbg(message_text, args);
case OutputTypes::kFile:
OutToFile(message_text, args);
default:
break;
}
va_end(args);
}
}
Далее мы реализуем функционал извлечения информации из конфига. Наш конфиг будет зашифрованным RC4 блобом. В стаб вшита сигнатура, билдер будет искать эту сигнатуру, формировать конфигурацию и вставлять её на место сигнатуры.
RC4 ключ при каждом ребилде уникален, чтобы конфиг не выглядел статично. В памяти данные будут смотреться так:
RC4 ключ (8 байт) - размер зашифрованного конфига (4 байта) - конфиг
После расшифровки конфига мы получим:
Размер ссылки на файл (4 байта) - ссылка на файл - Тип полезной нагрузки (4 байта) - размер экспортируемой функции (4 байта) - экспортируемая функция - нужно ли принудительно повышать уровень привилегий (1 байт)
Про последнюю опцию - мы введём возможность принудительно поднимать integrity level до High тем же методом флуда UAC окном.
Если процесс запущен под Medium IL, но права отсутствуют, условие отработает и привилегии будут повышаться.
Я вынесу конфиг в глобальную переменную, задав ему размер в 5000 байт, или же 5 килобайт. Добавляем сигнатуру, забивая остальное место после неё нулями:
C: Скопировать в буфер обмена
BYTE config[5000] = { "INSERT_CONFIG_HERE" };
Рассмотрим функционал распаковки конфига. Вышеописанная информация считывается из BLOB'а, дешифруется и распределяется по переменным.
Для дешифровки мы будем использовать алгоритм шифрования ARC4, реализация которого была позаимствована мной из библиотеки mbedtls, Скачать
View hidden content is available for registered users!