Example #1
0
static
int 
    _yaraMemMatchCallback
    (
        int message,
        void* message_data,
        void* user_data
    )
{
    YR_RULE* rule = (YR_RULE*)message_data;
    YaraMatchContext* context = (YaraMatchContext*)user_data;
    rSequence event = NULL;

    if( CALLBACK_MSG_RULE_MATCHING == message &&
        NULL != message_data &&
        NULL != user_data )
    {
        if( NULL != ( event = rSequence_new() ) )
        {
            rSequence_addRU32( event, RP_TAGS_PROCESS_ID, context->pid );
            rSequence_addPOINTER64( event, RP_TAGS_BASE_ADDRESS, context->regionBase );
            rSequence_addRU64( event, RP_TAGS_MEMORY_SIZE, context->regionSize );

            hbs_markAsRelated( context->fileInfo, event );

            if( NULL == context->processInfo )
            {
                context->processInfo = processLib_getProcessInfo( context->pid, NULL );
            }

            if( NULL != context->processInfo )
            {
                rSequence_addSEQUENCE( event, RP_TAGS_PROCESS, rSequence_duplicate( context->processInfo ) );
            }

            if( NULL != context->moduleInfo )
            {
                rSequence_addSEQUENCE( event, RP_TAGS_DLL, rSequence_duplicate( context->moduleInfo ) );
            }

            rSequence_addSTRINGA( event, RP_TAGS_RULE_NAME, (char*)rule->identifier );

            notifications_publish( RP_TAGS_NOTIFICATION_YARA_DETECTION, event );

            rSequence_free( event );
        }
        else
        {
            rpal_debug_warning( "error creating event from Yara match" );
        }
    }

    return CALLBACK_CONTINUE;
}
Example #2
0
static
int
    _yaraFileMatchCallback
    (
        int message,
        void* message_data,
        void* user_data
    )
{
    YR_RULE* rule = (YR_RULE*)message_data;
    YaraMatchContext* context = (YaraMatchContext*)user_data;
    rSequence event = NULL;
    
    if( CALLBACK_MSG_RULE_MATCHING == message &&
        NULL != message_data &&
        NULL != user_data )
    {
        if( NULL != ( event = rSequence_duplicate( context->fileInfo ) ) )
        {
            rSequence_addSTRINGA( event, RP_TAGS_RULE_NAME, (char*)rule->identifier );

            notifications_publish( RP_TAGS_NOTIFICATION_YARA_DETECTION, event );

            rSequence_free( event );
        }
        else
        {
            rpal_debug_warning( "error creating event from Yara match" );
        }
    }

    return CALLBACK_CONTINUE;
}
Example #3
0
static RBOOL
    updateCollectorConfigs
    (
        rList newConfigs
    )
{
    RBOOL isSuccess = FALSE;
    RU8 unused = 0;
    RU32 i = 0;
    rSequence tmpConf = NULL;
    RU32 confId = 0;

    if( rpal_memory_isValid( newConfigs ) )
    {
        rpal_debug_info( "updating collector configurations." );
        
        for( i = 0; i < ARRAY_N_ELEM( g_collectors ); i++ )
        {
            if( NULL != g_collectors[ i ].conf )
            {
                rpal_debug_info( "freeing collector %d config.", i );
                rSequence_free( g_collectors[ i ].conf );
                g_collectors[ i ].conf = NULL;
            }
        }

        while( rList_getSEQUENCE( newConfigs, RP_TAGS_HBS_CONFIGURATION, &tmpConf ) )
        {
            if( rSequence_getRU32( tmpConf, RP_TAGS_HBS_CONFIGURATION_ID, &confId ) &&
                confId < ARRAY_N_ELEM( g_collectors ) )
            {
                if( rSequence_getRU8( tmpConf, RP_TAGS_IS_DISABLED, &unused ) )
                {
                    g_collectors[ confId ].isEnabled = FALSE;
                }
                else
                {
                    g_collectors[ confId ].isEnabled = TRUE;
                    g_collectors[ confId ].conf = rSequence_duplicate( tmpConf );
                    rpal_debug_info( "set new collector %d config.", confId );
                }
            }
        }
                
        isSuccess = TRUE;
    }

    return isSuccess;
}
static
RBOOL
    _reportEvents
    (
        StatefulMachine* machine
    )
{
    RBOOL isSuccess = FALSE;

    rSequence wrapper = NULL;
    rList events = NULL;
    rSequence event = NULL;
    RU32 i = 0;

    if( NULL != machine )
    {
        if( NULL != ( wrapper = rSequence_new() ) )
        {
            if( NULL != ( events = rList_new( RP_TAGS_EVENT, RPCM_SEQUENCE ) ) )
            {
                for( i = 0; i < machine->history->nElements; i++ )
                {
                    event = ( (StatefulEvent*)machine->history->elements[ i ] )->data;
                    rList_addSEQUENCE( events, rSequence_duplicate( event ) );
                }

                if( !rSequence_addLIST( wrapper, RP_TAGS_EVENTS, events ) )
                {
                    rList_free( events );
                }
                else
                {
                    hbs_timestampEvent( wrapper, 0 );
                    isSuccess = hbs_publish( machine->desc->reportEventType, wrapper );
                }
            }

            rSequence_free( wrapper );
        }
    }

    return isSuccess;
}
static
RVOID
    getDocument
    (
        rpcm_tag notifId,
        rSequence notif
    )
{
    rSequence tmp = NULL;
    DocSearchContext ctx = { 0 };
    RU32 hashSize = 0;
    rList foundDocs = NULL;
    RBOOL isAAlloced = FALSE;
    RBOOL isWAlloced = FALSE;
    UNREFERENCED_PARAMETER( notifId );

    if( NULL != notif )
    {
        if( !rSequence_getSTRINGA( notif, RP_TAGS_STRING_PATTERN, &ctx.exprA ) )
        {
            ctx.exprA = NULL;
        }
        if( !rSequence_getSTRINGW( notif, RP_TAGS_STRING_PATTERN, &ctx.exprW ) )
        {
            ctx.exprW = NULL;
        }
        if( NULL != ctx.exprA && NULL == ctx.exprW )
        {
            ctx.exprW = rpal_string_atow( ctx.exprA );
            isWAlloced = TRUE;
        }
        if( NULL != ctx.exprW && NULL == ctx.exprA )
        {
            ctx.exprA = rpal_string_wtoa( ctx.exprW );
            isAAlloced = TRUE;
        }
        if( !rSequence_getBUFFER( notif, RP_TAGS_HASH, (RPU8*)&ctx.pHash, &hashSize ) ||
            sizeof( *ctx.pHash ) != hashSize )
        {
            // Unexpected hash size, let's not gamble 
            ctx.pHash = NULL;
        }
    }

    if( rMutex_lock( cacheMutex ) )
    {
        if( NULL != ( foundDocs = rList_new( RP_TAGS_FILE_INFO, RPCM_SEQUENCE ) ) )
        {
            while( HbsRingBuffer_find( documentCache, (HbsRingBufferCompareFunc)findDoc, &ctx, &tmp ) )
            {
                // TODO: optimize this since if we're dealing with large files
                // we will be temporarily using large amounts of duplicate memory.
                // We just need to do some shallow free of the datastructures
                // somehow.
                if( NULL != ( tmp = rSequence_duplicate( tmp ) ) )
                {
                    if( !rList_addSEQUENCE( foundDocs, tmp ) )
                    {
                        rSequence_free( tmp );
                    }
                }
            }

            if( !rSequence_addLIST( notif, RP_TAGS_FILES, foundDocs ) )
            {
                rList_free( foundDocs );
            }
        }

        rMutex_unlock( cacheMutex );

        notifications_publish( RP_TAGS_NOTIFICATION_GET_DOCUMENT_REP, notif );
    }

    if( isAAlloced )
    {
        rpal_memory_free( ctx.exprA );
    }
    if( isWAlloced )
    {
        rpal_memory_free( ctx.exprW );
    }
}
Example #6
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;
            }
        }
    }
}
static
rList
    _spotCheckProcess
    (
        rEvent isTimeToStop,
        RU32 pid,
        LibOsPerformanceProfile* perfProfile
    )
{
    rList hollowedModules = NULL;

    rList modules = NULL;
    rSequence module = NULL;
    RPNCHAR modulePath = NULL;
    RU32 fileSize = 0;
    RU64 moduleBase = 0;
    RU64 moduleSize = 0;
    HObs diskSample = NULL;
    rSequence hollowedModule = NULL;
    RU32 lastScratchIndex = 0;
    RU32 nSamplesFound = 0;
    RU32 nSamplesTotal = 0;
    RU32 tmpSamplesFound = 0;
    RU32 tmpSamplesSize = 0;
    RTIME runTime = 0;

    rpal_debug_info( "spot checking process %d", pid );

    if( NULL != ( modules = processLib_getProcessModules( pid ) ) )
    {
        while( !rEvent_wait( isTimeToStop, 0 ) &&
               rList_getSEQUENCE( modules, RP_TAGS_DLL, &module ) )
        {
            libOs_timeoutWithProfile( perfProfile, FALSE, isTimeToStop );
            runTime = rpal_time_getLocal();

            modulePath = NULL;
            lastScratchIndex = 0;

            if( ( rSequence_getSTRINGN( module, 
                                        RP_TAGS_FILE_PATH, 
                                        &modulePath ) ) &&
                rSequence_getPOINTER64( module, RP_TAGS_BASE_ADDRESS, &moduleBase ) &&
                rSequence_getRU64( module, RP_TAGS_MEMORY_SIZE, &moduleSize ) )
            {
                if( 0 != ( fileSize = rpal_file_getSize( modulePath, TRUE ) ) )
                {
                    nSamplesFound = 0;
                    nSamplesTotal = 0;
                    tmpSamplesFound = (RU32)( -1 );

                    while( !rEvent_wait( isTimeToStop, 0 ) &&
                            NULL != ( diskSample = _getModuleDiskStringSample( modulePath,
                                                                                &lastScratchIndex,
                                                                                isTimeToStop,
                                                                                perfProfile ) ) )
                    {
                        libOs_timeoutWithProfile( perfProfile, TRUE, isTimeToStop );

                        tmpSamplesSize = obsLib_getNumPatterns( diskSample );

                        if( 0 != tmpSamplesSize )
                        {
                            tmpSamplesFound = _checkMemoryForStringSample( diskSample,
                                                                            pid,
                                                                            NUMBER_TO_PTR( moduleBase ),
                                                                            moduleSize,
                                                                            isTimeToStop,
                                                                            perfProfile );
                            obsLib_free( diskSample );

                            if( (RU32)( -1 ) == tmpSamplesFound )
                            {
                                break;
                            }

                            nSamplesFound += tmpSamplesFound;
                            nSamplesTotal += tmpSamplesSize;

                            if( _MIN_DISK_SAMPLE_SIZE <= nSamplesTotal &&
                                ( _MIN_SAMPLE_MATCH_PERCENT < ( (RFLOAT)nSamplesFound /
                                                                nSamplesTotal ) * 100 ) &&
                                _MIN_DISK_BIN_COVERAGE_PERCENT <= (RFLOAT)( ( lastScratchIndex *
                                                                                _SCRATCH_SIZE ) /
                                                                            fileSize ) * 100 )
                            {
                                break;
                            }
                        }
                        else
                        {
                            obsLib_free( diskSample );
                        }
                    }
                }
                else
                {
                    rpal_debug_info( "could not get file information, not checking" );
                }

                rpal_debug_info( "process hollowing check found a match in %d ( %d / %d ) from %d passes in %d sec", 
                                    pid,  
                                    nSamplesFound, 
                                    nSamplesTotal,
                                    lastScratchIndex,
                                    rpal_time_getLocal() - runTime );
                    
                if( !rEvent_wait( isTimeToStop, 0 ) &&
                    (RU32)(-1) != tmpSamplesFound &&
                    _MIN_DISK_SAMPLE_SIZE <= nSamplesTotal &&
                    ( ( (RFLOAT)nSamplesFound / nSamplesTotal ) * 100 ) < _MIN_SAMPLE_MATCH_PERCENT )
                {
                    rpal_debug_info( "sign of process hollowing found in process %d", pid );

                    if( NULL != ( hollowedModule = rSequence_duplicate( module ) ) )
                    {
                        if( !rList_addSEQUENCE( hollowedModules, hollowedModule ) )
                        {
                            rSequence_free( hollowedModule );
                        }
                    }
                }
            }
            else
            {
                rpal_debug_info( "module missing characteristic" );
            }
        }

        rList_free( modules );
    }
    else
    {
        rpal_debug_info( "failed to get process modules, might be dead" );
    }

    return hollowedModules;
}