示例#1
0
static RVOID
    sendStartupEvent
    (

    )
{
    rSequence wrapper = NULL;
    rSequence startupEvent = NULL;

    if( NULL != ( wrapper = rSequence_new() ) )
    {
        if( NULL != ( startupEvent = rSequence_new() ) )
        {
            if( rSequence_addSEQUENCE( wrapper, RP_TAGS_NOTIFICATION_STARTING_UP, startupEvent ) )
            {
                if( !rSequence_addTIMESTAMP( startupEvent, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() ) ||
                    !rQueue_add( g_hbs_state.outQueue, wrapper, 0 ) )
                {
                    rSequence_free( wrapper );
                }
            }
            else
            {
                rSequence_free( wrapper );
                rSequence_free( startupEvent );
            }
        }
        else
        {
            rSequence_free( wrapper );
        }
    }
}
static RBOOL
    notifyOfProcess
    (
        RU32 pid,
        RU32 ppid,
        RBOOL isStarting
    )
{
    RBOOL isSuccess = FALSE;
    rSequence info = NULL;
    rSequence parentInfo = NULL;

    if( !isStarting ||
        NULL == ( info = processLib_getProcessInfo( pid ) ) )
    {
        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 );
        rSequence_addTIMESTAMP( info, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() );

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

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

        rSequence_free( info );
    }

    return isSuccess;
}
// Receives new process notifications and check if they're on our
// deny list, if so, kill.
RPRIVATE
RVOID
    denyNewProcesses
    (
        rpcm_tag notifType,
        rSequence event
    )
{
    RPU8 atomId = NULL;
    RU32 pid = 0;

    UNREFERENCED_PARAMETER( notifType );
    
    // We use the lastActivity check here as a cheap way of seeing if there is
    // anything at all in the denied tree.
    if( 0 != g_lastDenyActivity &&
        HbsGetParentAtom( event, &atomId ) &&
        isAtomDenied( atomId ) )
    {
        // This atom is part of a tree that needs to be denied, so we do two things:
        // 1- Add its atom to the list of denied atoms.
        if( HbsGetThisAtom( event, &atomId ) )
        {
            addAtomToDeny( atomId );
        }

        // 2- As this is a process, we deny by killing it.
        if( rSequence_getRU32( event, RP_TAGS_PROCESS_ID, &pid ) )
        {
            if( processLib_killProcess( pid ) )
            {
                rpal_debug_info( "denied process id " RF_U32, pid );
            }
            else
            {
                rpal_debug_warning( "failed to deny process id " RF_U32, pid );
            }
        }
    }
    else if( 0 != g_lastDenyActivity &&
             g_lastDenyActivity + DENY_TREE_CLEANUP_TIMEOUT < rpal_time_getGlobal() )
    {
        // There has not been any positive activity on any denied trees, for the sake
        // of performance we'll reset the denied trees.
        if( rMutex_lock( g_deniedMutex ) )
        {
            g_lastDenyActivity = 0;
            rpal_blob_free( g_denied );
            g_denied = rpal_blob_create( 0, HBS_ATOM_ID_SIZE * 10 );

            rMutex_unlock( g_deniedMutex );
        }
    }
}
static
RVOID
    processCodeIdentA
    (
        RPCHAR name,
        RPU8 pFileHash,
        RU64 codeSize,
        rSequence originalEvent
    )
{
    CodeIdent ident = { 0 };
    rSequence notif = NULL;

    ident.codeSize = codeSize;

    if( NULL != name )
    {
        CryptoLib_hash( name, rpal_string_strlen( name ) * sizeof( RCHAR ), ident.nameHash );
    }

    if( NULL != pFileHash )
    {
        rpal_memory_memcpy( ident.fileHash, pFileHash, CRYPTOLIB_HASH_SIZE );
    }

    if( rpal_bloom_addIfNew( knownCode, &ident, sizeof( ident ) ) )
    {
        if( NULL != ( notif = rSequence_new() ) )
        {
            hbs_markAsRelated( originalEvent, notif );

            if( rSequence_addSTRINGA( notif, RP_TAGS_FILE_NAME, name ) &&
                rSequence_addBUFFER( notif, RP_TAGS_HASH, pFileHash, CRYPTOLIB_HASH_SIZE ) &&
                rSequence_addRU32( notif, RP_TAGS_MEMORY_SIZE, (RU32)codeSize ) &&
                rSequence_addTIMESTAMP( notif, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() ) )
            {
                notifications_publish( RP_TAGS_NOTIFICATION_CODE_IDENTITY, notif );
            }
            rSequence_free( notif );
        }
    }
}
// Add an atom to the deny list, which is just a sortled list
// on which we do binary searches.
RPRIVATE
RVOID
    addAtomToDeny
    (
        RPU8 atomId
    )
{
    if( rMutex_lock( g_deniedMutex ) )
    {
        rpal_blob_add( g_denied, atomId, HBS_ATOM_ID_SIZE );
        rpal_sort_array( rpal_blob_getBuffer( g_denied ), 
                         rpal_blob_getSize( g_denied ) / HBS_ATOM_ID_SIZE, 
                         HBS_ATOM_ID_SIZE, 
                         (rpal_ordering_func)cmpAtoms );

        g_lastDenyActivity = rpal_time_getGlobal();

        rMutex_unlock( g_deniedMutex );
    }
}
示例#6
0
static RVOID
    sendShutdownEvent
    (

    )
{
    rList cloudMessages = NULL;
    rSequence wrapper = NULL;
    rSequence shutdownEvent = NULL;

    if( NULL != ( wrapper = rSequence_new() ) )
    {
        if( NULL != ( shutdownEvent = rSequence_new() ) )
        {
            if( rSequence_addSEQUENCE( wrapper, RP_TAGS_NOTIFICATION_SHUTTING_DOWN, shutdownEvent ) )
            {
                if( rSequence_addTIMESTAMP( shutdownEvent, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() ) &&
                    rQueue_add( g_hbs_state.outQueue, wrapper, 0 ) )
                {
                    if( NULL != ( cloudMessages = beaconHome() ) )
                    {
                        rList_free( cloudMessages );
                    }
                }
                else
                {
                    rSequence_free( wrapper );
                }
            }
            else
            {
                rSequence_free( wrapper );
                rSequence_free( shutdownEvent );
            }
        }
        else
        {
            rSequence_free( wrapper );
        }
    }
}
示例#7
0
//=============================================================================
// YARA Required Shims
//=============================================================================
static
RVOID
    reportError
    (
        rSequence originalRequest,
        RU32 errorCode,
        RPCHAR errorStr
    )
{
    rSequence event = NULL;

    if( NULL != ( event = rSequence_new() ) )
    {
        hbs_markAsRelated( originalRequest, event );
        rSequence_addRU32( event, RP_TAGS_ERROR, errorCode );
        rSequence_addSTRINGA( event, RP_TAGS_ERROR_MESSAGE, errorStr ? errorStr : "" );
        rSequence_addTIMESTAMP( event, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() );
        notifications_publish( RP_TAGS_NOTIFICATION_YARA_DETECTION, event );
        rSequence_free( event );
    }
}
RPRIVATE
RBOOL
    _init_profile_strw_strw
    (
        _Profile* p,
        RPWCHAR key
    )
{
    RBOOL isSuccess = FALSE;

    RTIME now = 0;

    if( NULL != p )
    {
        now = rpal_time_getGlobal();

        p->firstSeen = now;
        p->lastSeen = now;
        p->gensSeen = 0;
        p->gensToStability = _PROFILE_BASE_CHANGE_TICKETS;
        if( NULL != ( p->key = rpal_string_strdupW( key ) ) )
        {
            if( NULL != ( p->relations = rpal_btree_create( sizeof( RPVOID ), 
                                                            (rpal_btree_comp_f)_cmp_stringw, 
                                                            (rpal_btree_free_f)_clean_alloc ) ) )
            {
                isSuccess = TRUE;
            }
            else
            {
                rpal_memory_free( p->key );
            }
        }
    }

    return isSuccess;
}
示例#9
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
RPVOID
    lookForHiddenModulesIn
    (
        rEvent isTimeToStop,
        RU32 processId
    )
{
    rList mods = NULL;
    rList map = NULL;
    rSequence region = NULL;
    RU8 memType = 0;
    RU8 memProtect = 0;
    RU64 memBase = 0;
    RU64 memSize = 0;

    RPU8 pMem = NULL;

    RBOOL isPrefetched = FALSE;
    RBOOL isCurrentExec = FALSE;
    RBOOL isHidden = FALSE;

    rSequence procInfo = NULL;

#ifdef RPAL_PLATFORM_WINDOWS
    PIMAGE_DOS_HEADER pDos = NULL;
    PIMAGE_NT_HEADERS pNt = NULL;
#endif
    if( NULL != ( mods = processLib_getProcessModules( processId ) ) )
    {
        if( NULL != ( map = processLib_getProcessMemoryMap( processId ) ) )
        {
            // Now we got all the info needed for a single process, compare
            while( rpal_memory_isValid( isTimeToStop ) &&
                !rEvent_wait( isTimeToStop, 0 ) &&
                ( isPrefetched || rList_getSEQUENCE( map, RP_TAGS_MEMORY_REGION, &region ) ) )
            {
                if( isPrefetched )
                {
                    isPrefetched = FALSE;
                }

                if( rSequence_getRU8( region, RP_TAGS_MEMORY_TYPE, &memType ) &&
                    rSequence_getRU8( region, RP_TAGS_MEMORY_ACCESS, &memProtect ) &&
                    rSequence_getPOINTER64( region, RP_TAGS_BASE_ADDRESS, &memBase ) &&
                    rSequence_getRU64( region, RP_TAGS_MEMORY_SIZE, &memSize ) )
                {
                    if( PROCESSLIB_MEM_TYPE_PRIVATE == memType ||
                        PROCESSLIB_MEM_TYPE_MAPPED == memType )
                    {
                        if( PROCESSLIB_MEM_ACCESS_EXECUTE == memProtect ||
                            PROCESSLIB_MEM_ACCESS_EXECUTE_READ == memProtect ||
                            PROCESSLIB_MEM_ACCESS_EXECUTE_READ_WRITE == memProtect ||
                            PROCESSLIB_MEM_ACCESS_EXECUTE_WRITE_COPY == memProtect )
                        {
                            isCurrentExec = TRUE;
                        }
                        else
                        {
                            isCurrentExec = FALSE;
                        }

                        if( !isMemInModule( memBase, memSize, mods ) )
                        {
                            // Exec memory found outside of a region marked to belong to
                            // a module, keep looking in for module.
                            if( ( 1024 * 1024 * 10 ) >= memSize &&
                                processLib_getProcessMemory( processId, 
                                                             NUMBER_TO_PTR( memBase ), 
                                                             memSize, 
                                                             (RPVOID*)&pMem ) )
                            {
                                isHidden = FALSE;
#ifdef RPAL_PLATFORM_WINDOWS
                                // Let's just check for MZ and PE for now, we can get fancy later.
                                pDos = (PIMAGE_DOS_HEADER)pMem;
                                if( IS_WITHIN_BOUNDS( (RPU8)pMem, sizeof( IMAGE_DOS_HEADER ), pMem, memSize ) &&
                                    IMAGE_DOS_SIGNATURE == pDos->e_magic )
                                {
                                    pNt = (PIMAGE_NT_HEADERS)( (RPU8)pDos + pDos->e_lfanew );

                                    if( IS_WITHIN_BOUNDS( pNt, sizeof( *pNt ), pMem, memSize ) &&
                                        IMAGE_NT_SIGNATURE == pNt->Signature )
                                    {
                                        if( isCurrentExec )
                                        {
                                            // If the current region is exec, we've got a hidden module.
                                            isHidden = TRUE;
                                        }
                                        else
                                        {
                                            // We need to check if the next section in memory is
                                            // executable and outside of known modules since the PE
                                            // headers may have been marked read-only before the .text.
                                            if( rList_getSEQUENCE( map, RP_TAGS_MEMORY_REGION, &region ) )
                                            {
                                                isPrefetched = TRUE;

                                                if( ( PROCESSLIB_MEM_TYPE_PRIVATE == memType ||
                                                        PROCESSLIB_MEM_TYPE_MAPPED == memType ) &&
                                                    ( PROCESSLIB_MEM_ACCESS_EXECUTE == memProtect ||
                                                        PROCESSLIB_MEM_ACCESS_EXECUTE_READ == memProtect ||
                                                        PROCESSLIB_MEM_ACCESS_EXECUTE_READ_WRITE == memProtect ||
                                                        PROCESSLIB_MEM_ACCESS_EXECUTE_WRITE_COPY == memProtect ) )
                                                {
                                                    isHidden = TRUE;
                                                }
                                            }
                                        }
                                    }
                                }
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
                                if( isCurrentExec &&
                                    0x7F == ( pMem )[ 0 ] &&
                                    'E' == ( pMem )[ 1 ] &&
                                    'L' == ( pMem )[ 2 ] &&
                                    'F' == ( pMem )[ 3 ] )
                                {
                                    isHidden = TRUE;
                                }
#endif

                                rpal_memory_free( pMem );

                                if( isHidden &&
                                    !rEvent_wait( isTimeToStop, 0 ) )
                                {
                                    rpal_debug_info( "found a hidden module in %d.", processId );

                                    if( NULL != ( procInfo = processLib_getProcessInfo( processId ) ) )
                                    {
                                        if( !rSequence_addSEQUENCE( region, RP_TAGS_PROCESS, procInfo ) )
                                        {
                                            rSequence_free( procInfo );
                                        }
                                    }

                                    rSequence_addTIMESTAMP( region, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() );
                                    notifications_publish( RP_TAGS_NOTIFICATION_HIDDEN_MODULE_DETECTED, region );
                                    break;
                                }

                                rpal_thread_sleep( 10 );
                            }
                        }
                    }
                }
            }

            rList_free( map );
        }

        rList_free( mods );
    }

    return NULL;
}
static 
RPVOID
    networkDiffThread
    (
        rEvent isTimeToStop,
        RPVOID ctx
    )
{
    NetLib_Tcp4Table* currentTcp4Table = NULL;
    NetLib_Tcp4Table* oldTcp4Table = NULL;

    NetLib_UdpTable* currentUdpTable = NULL;
    NetLib_UdpTable* oldUdpTable = NULL;

    RU32 i = 0;
    RU32 j = 0;
    RBOOL isFound = FALSE;

    rSequence notif = NULL;
    rSequence comp = NULL;

    RU32 timeout = 100;
    RU32 nThLoop = 0;

    UNREFERENCED_PARAMETER( ctx );

    while( rpal_memory_isValid( isTimeToStop ) &&
           !rEvent_wait( isTimeToStop, 0 ) )
    {
        if( NULL != oldTcp4Table )
        {
            rpal_memory_free( oldTcp4Table );
            oldTcp4Table = NULL;
        }

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

        // Swap the old snapshot for the (prev) new one
        oldTcp4Table = currentTcp4Table;
        oldUdpTable = currentUdpTable;
        currentTcp4Table = NULL;
        currentUdpTable = NULL;

        // Generate new tables
        currentTcp4Table = NetLib_getTcp4Table();
        currentUdpTable = NetLib_getUdpTable();

        // Diff TCP snapshots for new entries
        if( rpal_memory_isValid( currentTcp4Table ) &&
            rpal_memory_isValid( oldTcp4Table ) )
        {
            for( i = 0; i < currentTcp4Table->nRows; i++ )
            {
                isFound = FALSE;

                if( rEvent_wait( isTimeToStop, 0 ) )
                {
                    break;
                }

                for( j = 0; j < oldTcp4Table->nRows; j++ )
                {
                    if( isTcpEqual( &currentTcp4Table->rows[ i ], &oldTcp4Table->rows[ j ] ) )
                    {
                        isFound = TRUE;
                        break;
                    }
                }

                if( !isFound )
                {
                    if( NULL != ( notif = rSequence_new() ) )
                    {
                        if( rSequence_addRU32( notif, 
                                               RP_TAGS_STATE, 
                                               currentTcp4Table->rows[ i ].state ) &&
                            rSequence_addRU32( notif, 
                                               RP_TAGS_PROCESS_ID, 
                                               currentTcp4Table->rows[ i ].pid ) &&
                            rSequence_addTIMESTAMP( notif, 
                                                    RP_TAGS_TIMESTAMP, 
                                                    rpal_time_getGlobal() ) )
                        {
                            if( NULL != ( comp = rSequence_new() ) )
                            {
                                // Add the destination components
                                if( !rSequence_addIPV4( comp, 
                                                        RP_TAGS_IP_ADDRESS, 
                                                        currentTcp4Table->rows[ i ].destIp ) ||
                                    !rSequence_addRU16( comp, 
                                                        RP_TAGS_PORT, 
                                                        rpal_ntoh16( (RU16)currentTcp4Table->rows[ i ].destPort ) ) ||
                                    !rSequence_addSEQUENCE( notif, 
                                                            RP_TAGS_DESTINATION, 
                                                            comp ) )
                                {
                                    rSequence_free( comp );
                                    comp = NULL;
                                }
                            }

                            if( NULL != ( comp = rSequence_new() ) )
                            {
                                // Add the source components
                                if( !rSequence_addIPV4( comp, 
                                                        RP_TAGS_IP_ADDRESS, 
                                                        currentTcp4Table->rows[ i ].sourceIp ) ||
                                    !rSequence_addRU16( comp, 
                                                        RP_TAGS_PORT, 
                                                        rpal_ntoh16( (RU16)currentTcp4Table->rows[ i ].sourcePort ) ) ||
                                    !rSequence_addSEQUENCE( notif, 
                                                            RP_TAGS_SOURCE, 
                                                            comp ) )
                                {
                                    rSequence_free( comp );
                                    comp = NULL;
                                }
                            }

                            rpal_debug_info( "new tcp connection: 0x%08X = 0x%08X:0x%04X ---> 0x%08X:0x%04X -- 0x%08X.",
                                currentTcp4Table->rows[ i ].state,
                                currentTcp4Table->rows[ i ].sourceIp,
                                currentTcp4Table->rows[ i ].sourcePort,
                                currentTcp4Table->rows[ i ].destIp,
                                currentTcp4Table->rows[ i ].destPort,
                                currentTcp4Table->rows[ i ].pid );
                            notifications_publish( RP_TAGS_NOTIFICATION_NEW_TCP4_CONNECTION, notif );
                        }

                        rSequence_free( notif );
                    }
                }
            }
        }
        else if( 0 != nThLoop )
        {
            rpal_debug_warning( "could not get tcp connections table." );
        }


        // Diff TCP snapshots for new entries
        if( NULL != currentUdpTable &&
            NULL != oldUdpTable )
        {
            for( i = 0; i < currentUdpTable->nRows; i++ )
            {
                isFound = FALSE;

                if( rEvent_wait( isTimeToStop, 0 ) )
                {
                    break;
                }

                for( j = 0; j < oldUdpTable->nRows; j++ )
                {
                    if( isUdpEqual( &currentUdpTable->rows[ i ], &oldUdpTable->rows[ j ] ) )
                    {
                        isFound = TRUE;
                        break;
                    }
                }

                if( !isFound )
                {
                    if( NULL != ( notif = rSequence_new() ) )
                    {
                        if( !rSequence_addIPV4( notif, 
                                                RP_TAGS_IP_ADDRESS, 
                                                currentUdpTable->rows[ i ].localIp ) ||
                            !rSequence_addRU16( notif, 
                                                RP_TAGS_PORT, 
                                                rpal_ntoh16( (RU16)currentUdpTable->rows[ i ].localPort ) ) ||
                            !rSequence_addRU32( notif, 
                                                RP_TAGS_PROCESS_ID, 
                                                currentUdpTable->rows[ i ].pid ) ||
                            !rSequence_addTIMESTAMP( notif, 
                                                     RP_TAGS_TIMESTAMP, 
                                                     rpal_time_getGlobal() ) )
                        {
                            notif = NULL;
                        }
                        else
                        {
                            rpal_debug_info( "new udp connection: 0x%08X:0x%04X -- 0x%08X.",
                                currentUdpTable->rows[ i ].localIp,
                                currentUdpTable->rows[ i ].localPort,
                                currentUdpTable->rows[ i ].pid );
                            notifications_publish( RP_TAGS_NOTIFICATION_NEW_UDP4_CONNECTION, notif );
                        }

                        rSequence_free( notif );
                    }
                }
            }
        }
        else if( 0 != nThLoop )
        {
            rpal_debug_warning( "could not get udp connections table." );
        }

        nThLoop++;
        if( 0 == nThLoop % 10 )
        {
            timeout = libOs_getUsageProportionalTimeout( 1000 ) + 500;
        }

        rpal_thread_sleep( timeout );
    }

    rpal_memory_free( currentTcp4Table );
    rpal_memory_free( currentUdpTable );
    rpal_memory_free( oldTcp4Table );
    rpal_memory_free( oldUdpTable );

    return NULL;
}
static 
RPVOID
    dnsDiffThread
    (
        rEvent isTimeToStop,
        RPVOID ctx
    )
{
    RU32 nThLoop = 0;
    RU32 currentTimeout = 0;
    rSequence notif = NULL;
    rBlob snapCur = NULL;
    rBlob snapPrev = NULL;
    _dnsRecord rec = { 0 };
    _dnsRecord* pCurRec = NULL;
    _dnsRecord* pPrevRec = NULL;
    RU32 i = 0;
    RU32 j = 0;
    RBOOL isNew = FALSE;
    
#ifdef RPAL_PLATFORM_WINDOWS
    PDNSCACHEENTRY pDnsEntry = NULL;
    PDNSCACHEENTRY pPrevDnsEntry = NULL;
#endif

    UNREFERENCED_PARAMETER( ctx );

    while( !rEvent_wait( isTimeToStop, currentTimeout ) )
    {
        if( NULL != ( snapCur = rpal_blob_create( 0, 10 * sizeof( rec ) ) ) )
        {
#ifdef RPAL_PLATFORM_WINDOWS
            if( TRUE == getCache( &pDnsEntry ) )
            {
                while( NULL != pDnsEntry )
                {
                    rec.flags = pDnsEntry->dwFlags;
                    rec.type = pDnsEntry->wType;
                    if( NULL != ( rec.name = rpal_string_strdupw( pDnsEntry->pszName ) ) )
                    {
                        rpal_blob_add( snapCur, &rec, sizeof( rec ) );
                    }

                    pPrevDnsEntry = pDnsEntry;
                    pDnsEntry = pDnsEntry->pNext;

                    freeCacheEntry( pPrevDnsEntry->pszName, DnsFreeFlat );
                    freeCacheEntry( pPrevDnsEntry, DnsFreeFlat );
                }
            }
#endif

            // Do a general diff of the snapshots to find new entries.
            if( NULL != snapPrev )
            {
                i = 0;
                while( NULL != ( pCurRec = rpal_blob_arrElem( snapCur, sizeof( rec ), i++ ) ) )
                {
                    isNew = TRUE;
                    j = 0;
                    while( NULL != ( pPrevRec = rpal_blob_arrElem( snapPrev, sizeof( rec ), j++ ) ) )
                    {
                        if( pCurRec->flags == pPrevRec->flags &&
                            pCurRec->type == pPrevRec->type &&
                            0 == rpal_string_strcmpw( pCurRec->name, pPrevRec->name ) )
                        {
                            isNew = FALSE;
                            break;
                        }
                    }

                    if( isNew &&
                        !rEvent_wait( isTimeToStop, 0 ) )
                    {
                        if( NULL != ( notif = rSequence_new() ) )
                        {
                            rSequence_addSTRINGW( notif, RP_TAGS_DOMAIN_NAME, pCurRec->name );
                            rSequence_addRU16( notif, RP_TAGS_DNS_TYPE, pCurRec->type );
                            rSequence_addRU32( notif, RP_TAGS_DNS_FLAGS, pCurRec->flags );
                            rSequence_addTIMESTAMP( notif, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() );

                            notifications_publish( RP_TAGS_NOTIFICATION_DNS_REQUEST, notif );

                            rSequence_free( notif );
                        }
                    }
                }
            }
        }

        if( NULL != snapPrev )
        {
            _freeRecords( snapPrev );
            rpal_blob_free( snapPrev );
            snapPrev = NULL;
        }

        snapPrev = snapCur;
        snapCur = NULL;

        nThLoop++;
        if( 0 == nThLoop % 20 )
        {
            currentTimeout = libOs_getUsageProportionalTimeout( MSEC_FROM_SEC( 10 ) ) + MSEC_FROM_SEC( 5 );
        }

        rpal_thread_sleep( currentTimeout );
    }

    if( NULL != snapPrev )
    {
        _freeRecords( snapPrev );
        rpal_blob_free( snapPrev );
        snapPrev = NULL;
    }

    return NULL;
}
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;
}
示例#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;
}
static
RVOID
    processCodeIdentW
    (
        RPWCHAR name,
        CryptoLib_Hash* pFileHash,
        RU64 codeSize,
        rSequence originalEvent
    )
{
    CodeIdent ident = { 0 };
    rSequence notif = NULL;
    rSequence sig = NULL;
    RBOOL isSigned = FALSE;
    RBOOL isVerifiedLocal = FALSE;
    RBOOL isVerifiedGlobal = FALSE;
    
    ident.codeSize = codeSize;

    if( NULL != name )
    {
        CryptoLib_hash( name, rpal_string_strlenw( name ) * sizeof( RWCHAR ), &ident.nameHash );
    }

    if( NULL != pFileHash )
    {
        rpal_memory_memcpy( &ident.fileHash, pFileHash, sizeof( *pFileHash ) );
    }

    if( rMutex_lock( g_mutex ) )
    {
        if( rpal_bloom_addIfNew( g_knownCode, &ident, sizeof( ident ) ) )
        {
            rMutex_unlock( g_mutex );

            if( NULL != ( notif = rSequence_new() ) )
            {
                hbs_markAsRelated( originalEvent, notif );

                if( ( rSequence_addSTRINGW( notif, RP_TAGS_FILE_PATH, name ) ||
                      rSequence_addSTRINGW( notif, RP_TAGS_DLL, name ) ||
                      rSequence_addSTRINGW( notif, RP_TAGS_EXECUTABLE, name ) ) &&
                    rSequence_addRU32( notif, RP_TAGS_MEMORY_SIZE, (RU32)codeSize ) &&
                    rSequence_addTIMESTAMP( notif, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() ) )
                {
                    if( NULL != pFileHash )
                    {
                        rSequence_addBUFFER( notif, RP_TAGS_HASH, (RPU8)pFileHash, sizeof( *pFileHash ) );
                    }

                    if( libOs_getSignature( name,
                                            &sig,
                                            ( OSLIB_SIGNCHECK_NO_NETWORK | OSLIB_SIGNCHECK_CHAIN_VERIFICATION ),
                                            &isSigned,
                                            &isVerifiedLocal,
                                            &isVerifiedGlobal ) )
                    {
                        if( !rSequence_addSEQUENCE( notif, RP_TAGS_SIGNATURE, sig ) )
                        {
                            rSequence_free( sig );
                        }
                    }

                    notifications_publish( RP_TAGS_NOTIFICATION_CODE_IDENTITY, notif );
                }
                rSequence_free( notif );
            }
        }
        else
        {
            rMutex_unlock( g_mutex );
        }
    }
}