Если ты выбрал путь кодера... Небольшое руководство и обзор.
У меня установлена в качестве среды разработки Visual Studio 2017, Visual Assist, VirtualBox
Точка входа
Собраный ехе должен получиться 1,5 кб весом. С двумя секциями, .data и .text.
Как полностью избавиться от создания секции .data в последних редакциях Visual Studio, я не нашел.
Устанавливаем необходимую ОС на виртальную машину, устанавливаем дополнения гостевой ОС, включаем двунаправленный буфер, настраиваем сеть в VirtualBox:
Настройки → Сеть
Тип подключения: Виртуальный адаптер хоста
Имя: VirtualBox Host-Only Enthernet Adapter
Если в дальнейшем будет нужно посмотреть как работает чужая малварь, ставим pafish на виртуалку и гуглим как сделать так, чтобы не было детектов.
Настройка отладчика
Удаленный отладчик находиться здесь
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\Remote Debugger
Папку с нужной архитектурой закидываем на виртуальную машину
Для удобства, я добавил msvsmon.exe в автозагрузку с ключами /noauth /anyuser /nowowwarn /nosecuritywarn
Настройка проекта
Свойства → Отладка
Загружаемый отладчик: Удаленный отладчик Windows
В качестве Имя удаленного сервера устанавливаем IP адрес виртуальной машины(смотрим вывод ipconfig в консоле на виртуалке)
Подключение: Удаленный доступ без аутентификации
В качестве удаленной команды можно указать запуск bat файла, который скопирует exe из расшареной папки и запустит.
Я ограничиваюсь возможностью подключиться к процессу во время выполнения.
Отладка → Присоедениться к процессу...
Забудь про STL и CRT если хочешь чтобы размер ехе был маленьким.
Все функции CRT и STL это обертка вокруг Windows API. Если ты видишь в комерческом разделе малварь, которая использует сторонние библиотеки - автор попросту некомпетентен в этом вопросе. Не повторяй за ним, пиши нормальный код - тебе потом это окупиться сполна.
Если ты привык, что CRT за тебя парсит аргументы командной строки, и делал раньше так
То теперь можно решить ту же задачу таким образом:
Напрмер, если тебе нужно вывести сообщение в консоль при отладке, тебе не нужен printf или std::cout, это можно сделать так:
Подробней под конкретную задачу можно найти в документации
Работа с потоками и процессами: docs.microsoft.com/ru-ru/windows/win32/procthread/process-and-thread-functions
Работа со строками: docs.microsoft.com/ru-ru/windows/win32/menurc/strings
Работа с файлами: docs.microsoft.com/ru-ru/windows/win32/fileio/file-management-functions
Работа с памятью: docs.microsoft.com/ru-ru/windows/win32/memory/memory-management-functions
Автоматизация
Это важный пункт. Если ты пишешь малварь для продажи, то твое время = деньги. Чем быстрее и качественее ты сможешь выполнять свою работу, тем больше сможешь зарабатывать.
Все что тебе приходиться выполнять по несколько раз с какой-либо переодичностью - автоматизируй один раз и забудь. В статье я привел пример, как добавить удаленный отладчик в автозапуск с ключами, чтобы не делать этого каждый раз при запуске виртуалки. Виртуалку лучше всегда держать в актуальном состоянии, с установленными программами и обновлениями. Чтобы не повторять одних и тех же действий, сделай для себя bat файл, который будет делать связное копирование виртуальной машины и ее запуск в один клик. При такой схеме у тебя будет всегда чистая, новая виртуалка.
Если ты регулярно выдаешь новые билды клиентам - сделай сборку проекта, упаковку билда в архив с паролем и загрузку на файлообменник в один клик. Освободившееся время - это твоя возможность сделать малварь более качественной, пока этого не сделал твой конкурент.
Используй современные возможности языка C++ для выполнения рутинных задач. На имена файлов, мьютексов, окон которые ты используешь в своем коде, может быть наложена сигнатура.
Поэтому генерируй их каждый раз в compile-time. В твоем распоряжении макросы docs.microsoft.com/ru-ru/cpp/preprocessor/predefined-macros
Например так можно получать уникальный SEED при каждой сборке проекта
Используй спецификатор constexpr
С его помощью например, можно на этапе компиляции посчитать хеш от строки
или сразу же сделать поиск winapi по хешам
Примеры реализаций можешь найти на гитхабе. Ищи по ключевым запросам compile-time, constexpr, shellcode
Обучение должно быть последовательным и целенаправленным. Разберись со всеми тонкостями студии, виртуализации, почитай о структуре PE файла, посмотри исходники примеров в Windows SDK. Как будешь справляться с написанием простенького загрузчика, переходи дальше - смотри как собрать шеллкод в студии, как писать базонезависимый код.
Скачай себе исходники вирусов с гитхаба. Изучай в свободное время.
Читай книги, из лучших это Рихтер - windows via c++, Руссинович - Внутреннее устройство Microsoft Windows.
Не спеши. Не берись писать HVNC - не напишешь, выгоришь и бросишь вообще учиться. Начинай с малого, постепенно иди дальше.
Обходы и эксплоиты
Будь в теме. Следи за новинками в этой области. Можно неплохо заработать на новом RCE, даже если под него уже выпущен патч. Возможно где-то тебе попадется качественный POC.
Есть форумы, малварь трекеры, независимые иследователи, антивирусные компании - все это, твой источник информации и вдохновения.
Видишь на форуме в комерческом разделе новый LPE, а денег на него нет - можно попробывать найти семпл на трекерах или попросить на форумах для изучения.
Если ты ищешь обход какого-то конкрентого АВ, в подавляющем большинстве случаев тебе не понадобиться отладчик. Просто увидев список импоротов у аналогичной малвари - будет достаточно для того, чтобы понять что происходит под капотом.
У меня установлена в качестве среды разработки Visual Studio 2017, Visual Assist, VirtualBox
Свойства → C++ → Оптимизация
Оптимизация: Максимальная оптимизация (приоритет размера) (/O1)
Развертывание подстовляемых функций: Отключено (/Ob0)
Включить подставляемые функции: Нет
Предпочитать размер или скорость: Предпочитать краткость кода (/Os)
Оптимизация всей программы: Да (/GL)
Свойства → C++ → Создание кода
Включить С++ исключения: Нет
Библиотека времени выполнения: Многопоточная (/MT)
Проверка безопасности: Отключить проверку безопасности (/GS-)
Свойства → C++ → Язык
Включить информацию о типах времени выполнения: Нет (/GR-)
Свойства → C++ → Командная строка
Дополнительные параметры: /Gw
Свойства → Компоновщик → Общее
Включить инкрементную компановку: Нет (/INCREMENTAL:NO)
Свойства → Компоновщик → Ввод
Игнорировать все стандартные библиотеки: Да (/NODEFAULTLIB)
Свойства → Компоновщик → Файл манифеста
Создать манифест: Нет (/MANIFEST:NO)
Свойства → Компоновщик → Отладка
Создать отладочную информацию: Нет
Свойства → Компоновщик → Дополнительно
Точка входа: _EntryPoint
Свойства → Компоновщик → Командная строка
Дополнительные параметры: /EMITPOGOPHASEINFO
Это пример базовой конфигурации, в зависимости от нужд она может быть изменена.
Из интересного здесь: ключ /EMITPOGOPHASEINFO недокументирован, убирает IMAGE_DEBUG_DIRECTORY из .rdata
Ключ /Gw в связке с /GL оставляет пустой секцию .data
Если на выходе нужно получить файл без секции релокаций(.reloc),
то на вкладке Свойства → Компоновщик → Дополнительно
Внесение случайности в базовый адрес: Нет (/DYNAMICBASE:NO)
Фиксированый базовый адрес: Да (/FIXED)
Оптимизация: Максимальная оптимизация (приоритет размера) (/O1)
Развертывание подстовляемых функций: Отключено (/Ob0)
Включить подставляемые функции: Нет
Предпочитать размер или скорость: Предпочитать краткость кода (/Os)
Оптимизация всей программы: Да (/GL)
Свойства → C++ → Создание кода
Включить С++ исключения: Нет
Библиотека времени выполнения: Многопоточная (/MT)
Проверка безопасности: Отключить проверку безопасности (/GS-)
Свойства → C++ → Язык
Включить информацию о типах времени выполнения: Нет (/GR-)
Свойства → C++ → Командная строка
Дополнительные параметры: /Gw
Свойства → Компоновщик → Общее
Включить инкрементную компановку: Нет (/INCREMENTAL:NO)
Свойства → Компоновщик → Ввод
Игнорировать все стандартные библиотеки: Да (/NODEFAULTLIB)
Свойства → Компоновщик → Файл манифеста
Создать манифест: Нет (/MANIFEST:NO)
Свойства → Компоновщик → Отладка
Создать отладочную информацию: Нет
Свойства → Компоновщик → Дополнительно
Точка входа: _EntryPoint
Свойства → Компоновщик → Командная строка
Дополнительные параметры: /EMITPOGOPHASEINFO
Это пример базовой конфигурации, в зависимости от нужд она может быть изменена.
Из интересного здесь: ключ /EMITPOGOPHASEINFO недокументирован, убирает IMAGE_DEBUG_DIRECTORY из .rdata
Ключ /Gw в связке с /GL оставляет пустой секцию .data
Если на выходе нужно получить файл без секции релокаций(.reloc),
то на вкладке Свойства → Компоновщик → Дополнительно
Внесение случайности в базовый адрес: Нет (/DYNAMICBASE:NO)
Фиксированый базовый адрес: Да (/FIXED)
Точка входа
C:
int APIENTRY _EntryPoint()
{
return 0;
}
Собраный ехе должен получиться 1,5 кб весом. С двумя секциями, .data и .text.
Как полностью избавиться от создания секции .data в последних редакциях Visual Studio, я не нашел.
Свойства → Компоновщик → Дополнительно
Объяденить разделы: .data=.text
Объяденить разделы: .data=.text
Отладка
Так как пишем мы малварь, то отладку будем делать под виртуальной машиной удаленно. Устанавливаем необходимую ОС на виртальную машину, устанавливаем дополнения гостевой ОС, включаем двунаправленный буфер, настраиваем сеть в VirtualBox:
Настройки → Сеть
Тип подключения: Виртуальный адаптер хоста
Имя: VirtualBox Host-Only Enthernet Adapter
Если в дальнейшем будет нужно посмотреть как работает чужая малварь, ставим pafish на виртуалку и гуглим как сделать так, чтобы не было детектов.
Настройка отладчика
Удаленный отладчик находиться здесь
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\Remote Debugger
Папку с нужной архитектурой закидываем на виртуальную машину
Для удобства, я добавил msvsmon.exe в автозагрузку с ключами /noauth /anyuser /nowowwarn /nosecuritywarn
| /noauth | Switches the remote debugger from Windows Authentication mode to No Authentication mode. For more information, see Security. |
| /anyuser | In No Authentication mode, Visual Studio sends the current user's username to the remote debugger. The remote debugger uses this username for a safety check to help prevent users from accidentally connecting to a different user's remote debugger. This option disables the safety check so that any user can connect. |
| /nosecuritywarn | When using the '/noauth' or '/allow' command line options, the remote debugger normally displays a warning because both of these options are dangerous unless used with care. The '/nosecuritywarn' disables these warnings. This option should only be used if you understand the security implications of the '/noauth' and '/allow' options. |
| /nowowwarn | 64-bit versions of Windows are capable of running 32-bit applications. This technology is called 'WOW'. When running the remote debugger under WOW, it is not able to attach to 64-bit processes. This option turns off checking for this condition. |
Свойства → Отладка
Загружаемый отладчик: Удаленный отладчик Windows
В качестве Имя удаленного сервера устанавливаем IP адрес виртуальной машины(смотрим вывод ipconfig в консоле на виртуалке)
Подключение: Удаленный доступ без аутентификации
В качестве удаленной команды можно указать запуск bat файла, который скопирует exe из расшареной папки и запустит.
Я ограничиваюсь возможностью подключиться к процессу во время выполнения.
Отладка → Присоедениться к процессу...
Кодинг
Забудь про STL и CRT если хочешь чтобы размер ехе был маленьким.
Все функции CRT и STL это обертка вокруг Windows API. Если ты видишь в комерческом разделе малварь, которая использует сторонние библиотеки - автор попросту некомпетентен в этом вопросе. Не повторяй за ним, пиши нормальный код - тебе потом это окупиться сполна.
Если ты привык, что CRT за тебя парсит аргументы командной строки, и делал раньше так
C:
int main(int argc, char **argv)
{
MessageBox(0, argv[0], "File path", MB_OK);
return 0;
}
C:
int APIENTRY _EntryPoint()
{
int argc = 0;
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
MessageBoxW(0, argv[0], L"File path", MB_OK);
return 0;
}
Напрмер, если тебе нужно вывести сообщение в консоль при отладке, тебе не нужен printf или std::cout, это можно сделать так:
C:
VOID ConsolePrint(PCSTR szFormat, ...)
{
va_list arglist;
va_start(arglist, szFormat);
char Buffer[1024];
DWORD cbBuffer = wvsprintfA(Buffer, szFormat, arglist);
if (cbBuffer) {
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), Buffer, cbBuffer, &cbBuffer, NULL);
}
}
Подробней под конкретную задачу можно найти в документации
Работа с потоками и процессами: docs.microsoft.com/ru-ru/windows/win32/procthread/process-and-thread-functions
Работа со строками: docs.microsoft.com/ru-ru/windows/win32/menurc/strings
Работа с файлами: docs.microsoft.com/ru-ru/windows/win32/fileio/file-management-functions
Работа с памятью: docs.microsoft.com/ru-ru/windows/win32/memory/memory-management-functions
Автоматизация
Это важный пункт. Если ты пишешь малварь для продажи, то твое время = деньги. Чем быстрее и качественее ты сможешь выполнять свою работу, тем больше сможешь зарабатывать.
Все что тебе приходиться выполнять по несколько раз с какой-либо переодичностью - автоматизируй один раз и забудь. В статье я привел пример, как добавить удаленный отладчик в автозапуск с ключами, чтобы не делать этого каждый раз при запуске виртуалки. Виртуалку лучше всегда держать в актуальном состоянии, с установленными программами и обновлениями. Чтобы не повторять одних и тех же действий, сделай для себя bat файл, который будет делать связное копирование виртуальной машины и ее запуск в один клик. При такой схеме у тебя будет всегда чистая, новая виртуалка.
Если ты регулярно выдаешь новые билды клиентам - сделай сборку проекта, упаковку билда в архив с паролем и загрузку на файлообменник в один клик. Освободившееся время - это твоя возможность сделать малварь более качественной, пока этого не сделал твой конкурент.
Используй современные возможности языка C++ для выполнения рутинных задач. На имена файлов, мьютексов, окон которые ты используешь в своем коде, может быть наложена сигнатура.
Поэтому генерируй их каждый раз в compile-time. В твоем распоряжении макросы docs.microsoft.com/ru-ru/cpp/preprocessor/predefined-macros
Например так можно получать уникальный SEED при каждой сборке проекта
C:
#define RNG_SEED ((__TIME__[7] - '0') * 1 + (__TIME__[6] - '0') * 10 + \
(__TIME__[4] - '0') * 60 + (__TIME__[3] - '0') * 600 + \
(__TIME__[1] - '0') * 3600 + (__TIME__[0] - '0') * 36000) + \
(__LINE__ * 100000)
Используй спецификатор constexpr
С его помощью например, можно на этапе компиляции посчитать хеш от строки
C:
constexpr DWORD myhash(const char *str) {
// Add hash algo
return hash;
}
constexpr DWORD dwHash = ct_hash("svchost.exe");
if (dwHash == ct_hash(szFileName)){
// In svchost.exe
}else Inject();
C:
#define LOAD_FUNC(module, function) \
constexpr DWORD hash_##function = hash(module) + hash(#function); \
typedef decltype(function) type_##function; \
static PVOID fn##function = 0;\
if(fn##function == 0)fn##function = _getProcAddress(hash_##function);\
type_##function *##function = (type_##function *)fn##function
LOAD_FUNC("kernel32.dll", Sleep);
Примеры реализаций можешь найти на гитхабе. Ищи по ключевым запросам compile-time, constexpr, shellcode
Обучение должно быть последовательным и целенаправленным. Разберись со всеми тонкостями студии, виртуализации, почитай о структуре PE файла, посмотри исходники примеров в Windows SDK. Как будешь справляться с написанием простенького загрузчика, переходи дальше - смотри как собрать шеллкод в студии, как писать базонезависимый код.
Скачай себе исходники вирусов с гитхаба. Изучай в свободное время.
Читай книги, из лучших это Рихтер - windows via c++, Руссинович - Внутреннее устройство Microsoft Windows.
Не спеши. Не берись писать HVNC - не напишешь, выгоришь и бросишь вообще учиться. Начинай с малого, постепенно иди дальше.
Обходы и эксплоиты
Будь в теме. Следи за новинками в этой области. Можно неплохо заработать на новом RCE, даже если под него уже выпущен патч. Возможно где-то тебе попадется качественный POC.
Есть форумы, малварь трекеры, независимые иследователи, антивирусные компании - все это, твой источник информации и вдохновения.
Видишь на форуме в комерческом разделе новый LPE, а денег на него нет - можно попробывать найти семпл на трекерах или попросить на форумах для изучения.
Если ты ищешь обход какого-то конкрентого АВ, в подавляющем большинстве случаев тебе не понадобиться отладчик. Просто увидев список импоротов у аналогичной малвари - будет достаточно для того, чтобы понять что происходит под капотом.
Последнее редактирование: