Esempio n. 1
0
static
RU32
    uninstallService
    (

    )
{
    RU32 res = (RU32)-1;

    RNCHAR svcUnload[] = { _SERVICE_UNLOAD };
    RNCHAR svcPath[] = { _SERVICE_FILE };

    if( 0 != system( svcUnload ) )
    {
        rpal_debug_warning( "failed to unload service, already unloaded?" );
    }

    if( !rpal_file_delete( svcPath, FALSE ) )
    {
        rpal_debug_warning( "failed to delete file from disk, not present?" );
    }
    else
    {
        rpal_debug_info( "uninstalled successfully" );
        res = 0;
    }

    return res;
}
RBOOL
    collector_2_init
    (
        HbsState* hbsState,
        rSequence config
    )
{
    RBOOL isSuccess = FALSE;
    UNREFERENCED_PARAMETER( config );

    if( NULL != hbsState )
    {
#ifdef RPAL_PLATFORM_WINDOWS
        RWCHAR apiName[] = _WCH( "dnsapi.dll" );
        RCHAR funcName1[] = "DnsGetCacheDataTable";
        RCHAR funcName2[] = "DnsFree";

        if( NULL != ( hDnsApi = LoadLibraryW( (RPWCHAR)&apiName ) ) )
        {
            // TODO: investigate the DnsQuery API on Windows to get the DNS resolutions.
            if( NULL != ( getCache = (DnsGetCacheDataTable_f)GetProcAddress( hDnsApi, (RPCHAR)&funcName1 ) ) &&
                NULL != ( freeCacheEntry = (DnsFree_f)GetProcAddress( hDnsApi, (RPCHAR)&funcName2 ) ) )
            {
                isSuccess = TRUE;
            }
            else
            {
                rpal_debug_warning( "failed to get dns undocumented function" );
                FreeLibrary( hDnsApi );
            }
        }
        else
        {
            rpal_debug_warning( "failed to load dns api" );
        }
#elif defined( RPAL_PLATFORM_MACOSX )
        isSuccess = TRUE;
#endif
        if( isSuccess )
        {
            isSuccess = FALSE;

            if( rThreadPool_task( hbsState->hThreadPool, dnsDiffThread, NULL ) )
            {
                isSuccess = TRUE;
            }
        }
    }

    return isSuccess;
}
Esempio n. 3
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;
}
static RVOID
    modKernelModeDiff
    (
        rEvent isTimeToStop
    )
{
    RU32 i = 0;
    RU32 nScratch = 0;
    RU32 prev_nScratch = 0;
    KernelAcqModule new_from_kernel[ 200 ] = { 0 };
    KernelAcqModule prev_from_kernel[ 200 ] = { 0 };

    while( !rEvent_wait( isTimeToStop, 1000 ) )
    {
        nScratch = ARRAY_N_ELEM( new_from_kernel );
        rpal_memory_zero( new_from_kernel, sizeof( new_from_kernel ) );
        if( !kAcq_getNewModules( new_from_kernel, &nScratch ) )
        {
            rpal_debug_warning( "kernel acquisition for new modules failed" );
            g_is_kernel_failure = TRUE;
            break;
        }

        for( i = 0; i < prev_nScratch; i++ )
        {
            notifyOfKernelModule( &(prev_from_kernel[ i ]) );
        }

        rpal_memory_memcpy( prev_from_kernel, new_from_kernel, sizeof( prev_from_kernel ) );
        prev_nScratch = nScratch;
    }
}
Esempio n. 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..." );
        }
    }
}
// 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 );
        }
    }
}
Esempio n. 7
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;
}
Esempio n. 8
0
static
RBOOL
    getStoreConf
    (

    )
{
    RBOOL isSuccess = FALSE;

    RPU8 storeFile = NULL;
    RU32 storeFileSize = 0;

    rpHCPIdentStore* storeV2 = NULL;

    OBFUSCATIONLIB_DECLARE( store, RP_HCP_CONFIG_IDENT_STORE );

    OBFUSCATIONLIB_TOGGLE( store );

    if( rpal_file_read( (RPNCHAR)store, (RPVOID)&storeFile, &storeFileSize, FALSE ) )
    {
        if( sizeof( rpHCPIdentStore ) <= storeFileSize )
        {
            storeV2 = (rpHCPIdentStore*)storeFile;
            if( storeV2->enrollmentTokenSize == storeFileSize - sizeof( rpHCPIdentStore ) )
            {
                isSuccess = TRUE;
                rpal_debug_info( "ident store found" );
                if( NULL != ( g_hcpContext.enrollmentToken = rpal_memory_alloc( storeV2->enrollmentTokenSize ) ) )
                {
                    rpal_memory_memcpy( g_hcpContext.enrollmentToken, storeV2->enrollmentToken, storeV2->enrollmentTokenSize );
                    g_hcpContext.enrollmentTokenSize = storeV2->enrollmentTokenSize;
                }
                g_hcpContext.currentId = storeV2->agentId;
            }
            else
            {
                rpal_debug_warning( "inconsistent ident store, reseting" );
                rpal_file_delete( (RPNCHAR)store, FALSE );
            }
        }

        rpal_memory_free( storeFile );
    }

    OBFUSCATIONLIB_TOGGLE( store );

    // Set some always-correct defaults
    g_hcpContext.currentId.id.platformId = RP_HCP_ID_MAKE_PLATFORM( RP_HCP_PLATFORM_CURRENT_CPU, RP_HCP_PLATFORM_CURRENT_MAJOR, RP_HCP_PLATFORM_CURRENT_MINOR );

    return isSuccess;
}
Esempio n. 9
0
static 
RBOOL
    getPrivileges
    (

    )
{
    RBOOL isSuccess = FALSE;

#ifdef RPAL_PLATFORM_WINDOWS
    RCHAR strSeDebug[] = "SeDebugPrivilege";
    RCHAR strSeBackup[] = "SeBackupPrivilege";
    RCHAR strSeRestore[] = "SeRestorePrivilege";
    if( !WindowsGetPrivilege( strSeDebug ) )
    {
        rpal_debug_warning( "error getting SeDebugPrivilege" );
    }
    if( !WindowsGetPrivilege( strSeBackup ) )
    {
        rpal_debug_warning( "error getting SeBackupPrivilege" );
    }
    if( !WindowsGetPrivilege( strSeRestore ) )
    {
        rpal_debug_warning( "error getting SeRestorePrivilege" );
    }
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
    /*cap_t capability_context = 0;
    if( NULL != ( capability_context = cap_get_proc() ) )
    {
        cap_free( capability_context );
    }
    */
#endif

    return isSuccess;
}
Esempio n. 10
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;
}
RPRIVATE
RVOID
    dnsKmDiffThread
    (
        rEvent isTimeToStop
    )
{
    RU8 new_from_kernel[ DNS_KB_PACKET_BUFFER * 1024 ] = { 0 };
    RU8 prev_from_kernel[ DNS_KB_PACKET_BUFFER * 1024 ] = { 0 };

    RU32 sizeInNew = 0;
    RU32 sizeInPrev = 0;

    KernelAcqDnsPacket* pPacket = NULL;

    while( !rEvent_wait( isTimeToStop, 1000 ) )
    {
        rpal_memory_zero( new_from_kernel, sizeof( new_from_kernel ) );
        sizeInNew = sizeof( new_from_kernel );

        if( !kAcq_getNewDnsPackets( (KernelAcqDnsPacket*)new_from_kernel, &sizeInNew ) )
        {
            rpal_debug_warning( "kernel acquisition for new dns packets failed" );
            break;
        }

        pPacket = (KernelAcqDnsPacket*)prev_from_kernel;
        while( IS_WITHIN_BOUNDS( pPacket, sizeof( *pPacket ), prev_from_kernel, sizeInPrev ) &&
               0 != pPacket->ts &&
               IS_WITHIN_BOUNDS( pPacket, sizeof( *pPacket ) + pPacket->packetSize, prev_from_kernel, sizeInPrev ) )
        {
            processDnsPacket( pPacket );

            pPacket = (KernelAcqDnsPacket*)( (RPU8)pPacket + sizeof( *pPacket ) + pPacket->packetSize );
        }

        rpal_memory_memcpy( prev_from_kernel, new_from_kernel, sizeInNew );
        sizeInPrev = sizeInNew;
    }
}
Esempio n. 12
0
static RBOOL
    startCollectors
    (

    )
{
    RBOOL isSuccess = FALSE;
    RU32 i = 0;

    rEvent_unset( g_hbs_state.isTimeToStop );
    if( NULL != ( g_hbs_state.hThreadPool = rThreadPool_create( 1, 
                                                                15,
                                                                MSEC_FROM_SEC( 10 ) ) ) )
    {
        isSuccess = TRUE;

        for( i = 0; i < ARRAY_N_ELEM( g_collectors ); i++ )
        {
            if( g_collectors[ i ].isEnabled )
            {
                if( !g_collectors[ i ].init( &g_hbs_state, g_collectors[ i ].conf ) )
                {
                    isSuccess = FALSE;
                    rpal_debug_warning( "collector %d failed to init.", i );
                }
                else
                {
                    rpal_debug_info( "collector %d started.", i );
                }
            }
            else
            {
                rpal_debug_info( "collector %d disabled.", i );
            }
        }
    }

    return isSuccess;
}
Esempio n. 13
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;
}
Esempio n. 14
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;
            }
        }
    }
}
Esempio n. 15
0
static rList
    beaconHome
    (
        
    )
{
    rList response = NULL;
    rList exfil = NULL;
    rSequence msg = NULL;
    RU32 nExfilMsg = 0;
    rSequence tmpMessage = NULL;

    if( NULL != ( exfil = rList_new( RP_TAGS_MESSAGE, RPCM_SEQUENCE ) ) )
    {
        if( NULL != ( msg = rSequence_new() ) )
        {
            if( rSequence_addBUFFER( msg, RP_TAGS_HASH, g_hbs_state.currentConfigHash, CRYPTOLIB_HASH_SIZE ) )
            {
                if( !rList_addSEQUENCE( exfil, msg ) )
                {
                    rSequence_free( msg );
                    msg = NULL;
                }

                tmpMessage = msg;
            }
            else
            {
                rSequence_free( msg );
                msg = NULL;
            }
        }

        while( rQueue_remove( g_hbs_state.outQueue, &msg, NULL, 0 ) )
        {
            nExfilMsg++;

            if( !rList_addSEQUENCE( exfil, msg ) )
            {
                rSequence_free( msg );
            }
        }

        rpal_debug_info( "%d messages ready for exfil.", nExfilMsg );


        if( rpHcpI_beaconHome( exfil, &response ) )
        {
            rpal_debug_info( "%d messages received from cloud.", rList_getNumElements( response ) );
        }
        else if( g_hbs_state.maxQueueSize > rList_getEstimateSize( exfil ) )
        {
            rpal_debug_info( "beacon failed, re-adding %d messages.", rList_getNumElements( exfil ) );

            // We will attempt to re-add the existing messages back in the queue since this failed
            rList_resetIterator( exfil );
            while( rList_getSEQUENCE( exfil, RP_TAGS_MESSAGE, &msg ) )
            {
                // Ignore message we generate temporarily for the beacon
                if( tmpMessage == msg )
                {
                    rSequence_free( msg );
                    continue;
                }

                if( !rQueue_add( g_hbs_state.outQueue, msg, 0 ) )
                {
                    rSequence_free( msg );
                }
            }
            rList_shallowFree( exfil );
            exfil = NULL;
        }
        else
        {
            rpal_debug_warning( "beacon failed but discarded exfil because of its size." );
        }

        if( NULL != exfil )
        {
            rList_free( exfil );
        }
    }

    return response;
}
Esempio n. 16
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 );
}
Esempio n. 17
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;
}
Esempio n. 18
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." );
        }
    }
}
Esempio n. 19
0
RBOOL
    processMessage
    (
        rSequence seq
    )
{
    RBOOL isSuccess = FALSE;
    RU8 command = 0;
    rSequence idSeq = NULL;
    rpHCPId tmpId = { 0 };
    rpHCPId emptyId = { 0 };
    RU64 tmpTime = 0;
    rThread hQuitThread = 0;

    rpHCPIdentStore identStore = {0};
    RPU8 token = NULL;
    RU32 tokenSize = 0;

    OBFUSCATIONLIB_DECLARE( store, RP_HCP_CONFIG_IDENT_STORE );

    if( NULL != seq )
    {
        if( rSequence_getRU8( seq, RP_TAGS_OPERATION, &command ) )
        {
            rpal_debug_info( "Received command 0x%0X.", command );
            switch( command )
            {
            case RP_HCP_COMMAND_LOAD_MODULE:
                isSuccess = loadModule( &g_hcpContext, seq );
                break;
            case RP_HCP_COMMAND_UNLOAD_MODULE:
                isSuccess = unloadModule( &g_hcpContext, seq );
                break;
            case RP_HCP_COMMAND_SET_HCP_ID:
                if( rSequence_getSEQUENCE( seq, RP_TAGS_HCP_IDENT, &idSeq ) )
                {
                    tmpId = seqToHcpId( idSeq );

                    if( 0 != rpal_memory_memcmp( &emptyId, &tmpId, sizeof( emptyId ) ) )
                    {
                        g_hcpContext.currentId = tmpId;
                        
                        OBFUSCATIONLIB_TOGGLE( store );
                        
                        if( rSequence_getBUFFER( seq, RP_TAGS_HCP_ENROLLMENT_TOKEN, &token, &tokenSize ) )
                        {
                            identStore.agentId = tmpId;

                            if( saveHcpId( (RPNCHAR)store, &identStore, token, tokenSize ) )
                            {
                                isSuccess = TRUE;
                            }

                            if( NULL != g_hcpContext.enrollmentToken )
                            {
                                rpal_memory_free( g_hcpContext.enrollmentToken );
                                g_hcpContext.enrollmentToken = NULL;
                            }

                            if( NULL != ( g_hcpContext.enrollmentToken = rpal_memory_alloc( tokenSize ) ) )
                            {
                                rpal_memory_memcpy( g_hcpContext.enrollmentToken, token, tokenSize );
                                g_hcpContext.enrollmentTokenSize = tokenSize;

                                isSuccess = TRUE;
                            }
                        }
                        else
                        {
                            rpal_debug_warning( "hcp id is missing token" );
                        }

                        OBFUSCATIONLIB_TOGGLE( store );
                    }
                }
                break;
            case RP_HCP_COMMAND_SET_GLOBAL_TIME:
                if( rSequence_getTIMESTAMP( seq, RP_TAGS_TIMESTAMP, &tmpTime ) )
                {
                    rpal_time_setGlobalOffset( tmpTime - rpal_time_getLocal() );
                    isSuccess = TRUE;
                }
                break;
            case RP_HCP_COMMAND_QUIT:
                if( 0 != ( hQuitThread = rpal_thread_new( thread_quitAndCleanup, NULL ) ) )
                {
                    rpal_thread_free( hQuitThread );
                    isSuccess = TRUE;
                }
                break;
            case RP_HCP_COMMAND_UPGRADE:
                isSuccess = upgradeHcp( seq );
                break;
            default:
                break;
            }

            if( isSuccess )
            {
                rpal_debug_info( "Command was successful." );
            }
            else
            {
                rpal_debug_warning( "Command was not successful." );
            }
        }
    }

    return isSuccess;
}
static int
    new_proc_listener
    (
        kauth_cred_t cred,
        struct vnode *vp,
        struct vnode *scriptvp,
        struct label *vnodelabel,
        struct label *scriptlabel,
        struct label *execlabel,
        struct componentname *cnp,
        u_int *csflags,
        void *macpolicyattr,
        size_t macpolicyattrlen
    )
#endif
{
    #ifdef _USE_KAUTH
    vnode_t prog = (vnode_t)arg0;
    const char* file_path = (const char*)arg1;
    #else
    int pathLen = sizeof( g_processes[ 0 ].path );
    #endif
    
    pid_t pid = 0;
    pid_t ppid = 0;
    uid_t uid = 0;
    
    #ifdef _USE_KAUTH
    if( KAUTH_FILEOP_EXEC != action ||
        ( NULL != prog &&
          VREG != vnode_vtype( prog ) ) )
    {
        return KAUTH_RESULT_DEFER;
    }
    #endif
    
    uid = kauth_getuid();
    pid = proc_selfpid();
    ppid = proc_selfppid();
    
    // We skip a known false positive
    if( 0 == ppid && 1 == pid )
    {
        #ifdef _USE_KAUTH
            return KAUTH_RESULT_DEFER;
        #else
            return 0; // Always allow
        #endif
    }
    
    if( NULL != file_path )
    {
        // rpal_debug_info( "!!!!!! process start: %d/%d/%d %s", ppid, pid, uid, file_path );
    }
    
    rpal_mutex_lock( g_collector_1_mutex );
    
#ifdef _USE_KAUTH
    if( NULL != file_path )
    {
        strncpy( g_processes[ g_nextProcess ].path,
                 file_path,
                 sizeof( g_processes[ g_nextProcess ].path ) - 1 );
    }
#else
    vn_getpath( vp, g_processes[ g_nextProcess ].path, &pathLen );
#endif

    g_processes[ g_nextProcess ].pid = pid;
    g_processes[ g_nextProcess ].ppid = ppid;
    g_processes[ g_nextProcess ].uid = uid;
    g_processes[ g_nextProcess ].ts = rpal_time_getLocal();
    
    g_nextProcess++;
    if( g_nextProcess == _NUM_BUFFERED_PROCESSES )
    {
        g_nextProcess = 0;
        rpal_debug_warning( "overflow of the execution buffer" );
    }
    
    // rpal_debug_info( "now %d processes in buffer", g_nextProcess );
    
    rpal_mutex_unlock( g_collector_1_mutex );

#ifdef _USE_KAUTH
    return KAUTH_RESULT_DEFER;
#else
    return 0; // Always allow
#endif
}
Esempio n. 21
0
static
RU32
    _scanProcessWith
    (
        RU32 pid,
        YaraMatchContext* matchContext,
        YR_RULES* rules,
        rEvent isTimeToStop
    )
{
    RU32 scanError = (RU32)(-1);
    rList modules = NULL;
    rSequence module = NULL;
    _MemRange* memRanges = NULL;
    RU32 i = 0;
    rList memoryMap = NULL;
    rSequence memoryRegion = NULL;
    RU8 memAccess = 0;
    RU64 mem = 0;
    RU64 memSize = 0;
    RPU8 buffer = NULL;

    // First pass is to scan known modules
    if( NULL != ( modules = processLib_getProcessModules( pid ) ) )
    {
        rpal_debug_info( "scanning process %d module memory with yara", pid );

        // We also generate an optimized list of module ranges for later
        if( NULL != ( memRanges = rpal_memory_alloc( sizeof( _MemRange ) *
                                                     rList_getNumElements( modules ) ) ) )
        {
            while( ( NULL == isTimeToStop || !rEvent_wait( isTimeToStop, MSEC_FROM_SEC( 5 ) ) ) &&
                   rList_getSEQUENCE( modules, RP_TAGS_DLL, &module ) )
            {
                if( rSequence_getPOINTER64( module, RP_TAGS_BASE_ADDRESS, &mem ) &&
                    rSequence_getRU64( module, RP_TAGS_MEMORY_SIZE, &memSize ) )
                {
                    memRanges[ i ].base = mem;
                    memRanges[ i ].size = memSize;
                    i++;

                    matchContext->regionBase = mem;
                    matchContext->regionSize = memSize;
                    matchContext->moduleInfo = module;

                    if( processLib_getProcessMemory( pid,
                                                     (RPVOID)NUMBER_TO_PTR( mem ),
                                                     memSize,
                                                     (RPVOID*)&buffer,
                                                     TRUE ) )
                    {
                        rpal_debug_info( "yara scanning module region of size 0x%lx", memSize );

                        if( NULL != rules ||
                            rMutex_lock( g_global_rules_mutex ) )
                        {
                            if( ERROR_SUCCESS != ( scanError = yr_rules_scan_mem( NULL == rules ? g_global_rules : rules,
                                                                                  buffer,
                                                                                  (size_t)memSize,
                                                                                  SCAN_FLAGS_FAST_MODE |
                                                                                  SCAN_FLAGS_PROCESS_MEMORY,
                                                                                  _yaraMemMatchCallback,
                                                                                  matchContext,
                                                                                  60 ) ) )
                            {
                                rpal_debug_warning( "Yara module scan error: %d 0x%lx 0x%lx: %d",
                                                    pid,
                                                    mem,
                                                    memSize,
                                                    scanError );
                            }

                            if( NULL == rules )
                            {
                                rMutex_unlock( g_global_rules_mutex );
                            }
                        }

                        rpal_memory_free( buffer );

                        rpal_debug_info( "finished region" );
                    }
                }
            }
        }

        rList_free( modules );
    }

    // Optimize the memory ranges
    if( rpal_memory_isValid( memRanges ) &&
        !rpal_sort_array( memRanges, i, sizeof( _MemRange ), (rpal_ordering_func)rpal_order_RU64 ) )
    {
        rpal_memory_free( memRanges );
        memRanges = NULL;
    }

    // Second pass is to go through executable non-module areas
    if( NULL != ( memoryMap = processLib_getProcessMemoryMap( pid ) ) )
    {
        rpal_debug_info( "scanning process %d non-module memory with yara", pid );

        while( ( NULL == isTimeToStop || !rEvent_wait(isTimeToStop, MSEC_FROM_SEC( 5 ) ) ) &&
               rList_getSEQUENCE( memoryMap, RP_TAGS_MEMORY_REGION, &memoryRegion ) )
        {
            if( rSequence_getPOINTER64( memoryRegion, RP_TAGS_BASE_ADDRESS, &mem ) &&
                rSequence_getRU64( memoryRegion, RP_TAGS_MEMORY_SIZE, &memSize ) &&
                rSequence_getRU8( memoryRegion, RP_TAGS_MEMORY_ACCESS, &memAccess ) &&
                ( PROCESSLIB_MEM_ACCESS_EXECUTE == memAccess ||
                  PROCESSLIB_MEM_ACCESS_EXECUTE_READ == memAccess ||
                  PROCESSLIB_MEM_ACCESS_EXECUTE_READ_WRITE == memAccess ||
                  PROCESSLIB_MEM_ACCESS_EXECUTE_WRITE_COPY  == memAccess ) )
            {
                // If it's in a known module, skip
                if( (RU32)( -1 ) != rpal_binsearch_array_closest( memRanges,
                                                                  i,
                                                                  sizeof( _MemRange ),
                                                                  &mem,
                                                                  (rpal_ordering_func)rpal_order_RU64,
                                                                  TRUE ) )
                {
                    continue;
                }
                matchContext->regionBase = mem;
                matchContext->regionSize = memSize;
                matchContext->moduleInfo = NULL;

                if( processLib_getProcessMemory( pid,
                                                 (RPVOID)NUMBER_TO_PTR(mem),
                                                 memSize,
                                                 (RPVOID*)&buffer,
                                                 TRUE ) )
                {
                    rpal_debug_info( "yara scanning memory region of size 0x%lx", memSize );

                    if( NULL != rules ||
                        rMutex_lock( g_global_rules_mutex ) )
                    {
                        if( ERROR_SUCCESS != ( scanError = yr_rules_scan_mem( NULL == rules ? g_global_rules : rules,
                                                                              buffer,
                                                                              (size_t)memSize,
                                                                              SCAN_FLAGS_FAST_MODE |
                                                                              SCAN_FLAGS_PROCESS_MEMORY,
                                                                              _yaraMemMatchCallback,
                                                                              matchContext,
                                                                              60 ) ) )
                        {
                            rpal_debug_warning( "Yara memory scan error: %d 0x%lx 0x%lx: %d",
                                                pid,
                                                mem,
                                                memSize,
                                                scanError );
                        }

                        if( NULL == rules )
                        {
                            rMutex_unlock( g_global_rules_mutex );
                        }
                    }

                    rpal_memory_free( buffer );
                }
            }
        }

        rList_free( memoryMap );
    }

    if( rpal_memory_isValid( memRanges ) )
    {
        rpal_memory_free( memRanges );
    }

    return scanError;
}
Esempio n. 22
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;
}
Esempio n. 23
0
static
RPVOID
    continuousFileScan
    (
        rEvent isTimeToStop,
        RPVOID ctx
    )
{
    rSequence event = NULL;
    RU32 timeout = 0;
    RPWCHAR strW = NULL;
    RPCHAR strA = NULL;
    YaraMatchContext matchContext = { 0 };
    RU32 scanError = 0;
    rBloom knownFiles = NULL;

    UNREFERENCED_PARAMETER( ctx );

    if( NULL == ( knownFiles = rpal_bloom_create( 100000, 0.00001 ) ) )
    {
        return NULL;
    }

    while( !rEvent_wait( isTimeToStop, timeout ) )
    {
        if( rQueue_remove( g_async_files_to_scan, (RPVOID*)&event, NULL, MSEC_FROM_SEC( 2 ) ) )
        {
            if( rSequence_getSTRINGW( event, RP_TAGS_FILE_PATH, &strW ) )
            {
                strA = rpal_string_wtoa( strW );
            }
            else
            {
                rSequence_getSTRINGA( event, RP_TAGS_FILE_PATH, &strA );
            }

            if( NULL != strA &&
                rpal_bloom_addIfNew( knownFiles, strA, rpal_string_strlen( strA ) ) )
            {
                rpal_debug_info( "yara scanning %s", strA );
                matchContext.fileInfo = event;

                if( rMutex_lock( g_global_rules_mutex ) )
                {
                    if( NULL != g_global_rules )
                    {
                        rpal_debug_info( "scanning continuous file with yara" );
                        if( ERROR_SUCCESS != ( scanError = yr_rules_scan_file( g_global_rules,
                                                                               strA,
                                                                               SCAN_FLAGS_FAST_MODE,
                                                                               _yaraFileMatchCallback,
                                                                               &matchContext,
                                                                               60 ) ) )
                        {
                            rpal_debug_warning( "Yara file scan error: %d", scanError );
                        }
                    }

                    rMutex_unlock( g_global_rules_mutex );
                }
            }

            if( NULL != strA && NULL != strW )
            {
                // If both are allocated it means we got a strW and converted to A
                // so we must free the strA version.
                rpal_memory_free( strA );
            }

            strA = NULL;
            strW = NULL;
            rSequence_free( event );

            timeout = _TIMEOUT_BETWEEN_FILE_SCANS;
        }
        else
        {
            timeout = 0;
        }
    }

    rpal_bloom_destroy( knownFiles );

    yr_finalize_thread();

    return NULL;
}
RPRIVATE
RVOID
    processDnsPacket
    (
        KernelAcqDnsPacket* pDns
    )
{
    rSequence notification = NULL;
    RU32 i = 0;
    DnsLabel* pLabel = NULL;
    DnsHeader* dnsHeader = NULL;
    DnsResponseInfo* pResponseInfo = NULL;
    RCHAR domain[ DNS_LABEL_MAX_SIZE ] = { 0 };
    RU16 recordType = 0;
    RU64 timestamp = 0;
    Atom parentAtom = { 0 };

    if( NULL == pDns )
    {
        return;
    }

    dnsHeader = (DnsHeader*)( (RPU8)pDns + sizeof( *pDns ) );
    pLabel = (DnsLabel*)dnsHeader->data;

    // We are parsing DNS packets coming from the kernel. They may:
    // 1- Be requests and not responses, check there are Answers.
    // 2- Be maliciously crafter packets so we need extra checking for sanity.
    if( 0 == dnsHeader->anCount ||
        0 == dnsHeader->qr ||
        DNS_SANITY_MAX_RECORDS < rpal_ntoh16( dnsHeader->qdCount ) ||
        DNS_SANITY_MAX_RECORDS < rpal_ntoh16( dnsHeader->anCount ) )
    {
        return;
    }

    // We need to walk the Questions first to get to the Answers
    // but we don't really care to record them since they'll be repeated
    // in the Answers.
    for( i = 0; i < rpal_ntoh16( dnsHeader->qdCount ); i++ )
    {
        DnsQuestionInfo* pQInfo = NULL;

        pLabel = dnsReadLabels( pLabel, NULL, (RPU8)dnsHeader, pDns->packetSize, 0, 0 );

        pQInfo = (DnsQuestionInfo*)( pLabel );
        if( !IS_WITHIN_BOUNDS( pQInfo, sizeof( *pQInfo ), dnsHeader, pDns->packetSize ) )
        {
            rpal_debug_warning( "error parsing dns packet" );
            break;
        }

        pLabel = (DnsLabel*)( (RPU8)pQInfo + sizeof( *pQInfo ) );
    }

    if( !IS_WITHIN_BOUNDS( pLabel, sizeof( RU16 ), dnsHeader, pDns->packetSize ) )
    {
        rpal_debug_warning( "error parsing dns packet" );
        return;
    }

    // This is what we care about, the Answers (which also point to each Question).
    // We will emit one event per Answer so as to keep the DNS_REQUEST event flat and atomic.
    for( i = 0; i < rpal_ntoh16( dnsHeader->anCount ); i++ )
    {
        pResponseInfo = NULL;
            
        // This was the Question for this answer.
        rpal_memory_zero( domain, sizeof( domain ) );
        pLabel = dnsReadLabels( pLabel, domain, (RPU8)dnsHeader, pDns->packetSize, 0, 0 );

        pResponseInfo = (DnsResponseInfo*)pLabel;
        pLabel = (DnsLabel*)( (RPU8)pResponseInfo + sizeof( *pResponseInfo ) + rpal_ntoh16( pResponseInfo->rDataLength ) );

        if( !IS_WITHIN_BOUNDS( pResponseInfo, sizeof( *pResponseInfo ), dnsHeader, pDns->packetSize ) )
        {
            rpal_debug_warning( "error parsing dns packet" );
            break;
        }

        if( NULL == ( notification = rSequence_new() ) )
        {
            rpal_debug_warning( "error parsing dns packet" );
            break;
        }

        // This is a timestamp coming from the kernel so it is not globally adjusted.
        // We'll adjust it with the global offset.
        timestamp = pDns->ts;
        timestamp += MSEC_FROM_SEC( rpal_time_getGlobalFromLocal( 0 ) );

        // Try to relate the DNS request to the owner process, this only works on OSX
        // at the moment (since the kernel does not expose the PID at the packet capture
        // stage), and even on OSX it's the DNSResolver process. So it's not super useful
        // but regardless we have the mechanism here as it's better than nothing and when
        // we add better resolving in the kernel it will work transparently.
        parentAtom.key.process.pid = pDns->pid;
        parentAtom.key.category = RP_TAGS_NOTIFICATION_NEW_PROCESS;
        if( atoms_query( &parentAtom, timestamp ) )
        {
            HbsSetParentAtom( notification, parentAtom.id );
        }

        rSequence_addTIMESTAMP( notification, RP_TAGS_TIMESTAMP, timestamp );
        rSequence_addSTRINGA( notification, RP_TAGS_DOMAIN_NAME, domain );
        rSequence_addRU32( notification, RP_TAGS_PROCESS_ID, pDns->pid );

        recordType = rpal_ntoh16( pResponseInfo->recordType );

        rSequence_addRU16( notification, RP_TAGS_MESSAGE_ID, rpal_ntoh16( dnsHeader->msgId ) );
        rSequence_addRU16( notification, RP_TAGS_DNS_TYPE, recordType );

        if( DNS_A_RECORD == recordType )
        {
            rSequence_addIPV4( notification, RP_TAGS_IP_ADDRESS, *(RU32*)pResponseInfo->rData );
        }
        else if( DNS_AAAA_RECORD == recordType )
        {
            rSequence_addIPV6( notification, RP_TAGS_IP_ADDRESS, pResponseInfo->rData );
        }
        else if( DNS_CNAME_RECORD == recordType )
        {
            // CNAME records will have another label as a value and not an IP.
            rpal_memory_zero( domain, sizeof( domain ) );
            dnsReadLabels( (DnsLabel*)pResponseInfo->rData, domain, (RPU8)dnsHeader, pDns->packetSize, 0, 0 );
            rSequence_addSTRINGA( notification, RP_TAGS_CNAME, domain );
        }
        else
        {
            // Right now we only care for A, CNAME and AAAA records.
            rSequence_free( notification );
            notification = NULL;
            continue;
        }

        hbs_publish( RP_TAGS_NOTIFICATION_DNS_REQUEST, notification );
        rSequence_free( notification );
        notification = NULL;
    }
}
// Parses a label from a DNS packet and returns a pointer to the next byte after the label
// or label chain to be used to continue parsing the packet.
// If a human label is specified, will also assemble a human readable version of the labels
// in the buffer.
RPRIVATE
DnsLabel*
    dnsReadLabels
    (
        DnsLabel* pLabel,
        RCHAR humanLabel[ DNS_LABEL_MAX_SIZE ],
        RPU8 packetStart,
        RSIZET packetSize,
        RU32 labelOffset,
        RU32 recursiveDepth
    )
{
    RU32 copied = labelOffset;

    if( 3 < recursiveDepth )
    {
        return NULL;
    }

    if( NULL == pLabel )
    {
        return NULL;
    }

    while( IS_WITHIN_BOUNDS( pLabel, sizeof( *pLabel ), packetStart, packetSize ) &&
            ( DNS_LABEL_IS_OFFSET( pLabel ) ||
                ( IS_WITHIN_BOUNDS( pLabel, sizeof( *pLabel ) + pLabel->nChar, packetStart, packetSize ) &&
                0 != pLabel->nChar ) ) )
    {
        // It's possible for a pointer to be terminating a traditional label
        if( DNS_LABEL_IS_OFFSET( pLabel ) )
        {
            // Pointer to a label
            DnsLabel* tmpLabel = NULL;
            RU16 offset = DNS_LABEL_OFFSET( pLabel );

            if( !IS_WITHIN_BOUNDS( (RPU8)packetStart + offset, sizeof( RU16 ), packetStart, packetSize ) )
            {
                rpal_debug_warning( "error parsing dns packet" );
                return NULL;
            }

            tmpLabel = (DnsLabel*)( (RPU8)packetStart + offset );

            if( NULL == dnsReadLabels( tmpLabel, humanLabel, packetStart, packetSize, copied, recursiveDepth + 1 ) )
            {
                return NULL;
            }

            // Pointers are always terminating the label. So since there is
            // no 0 terminated label we don't need to skip an extra byte, we
            // just skip the current label pointer value.
            pLabel = (DnsLabel*)( (RPU8)pLabel + sizeof( RU16 ) );
            return pLabel;
        }
        else
        {
            if( DNS_LABEL_MAX_SIZE < copied + 1 + pLabel->nChar )
            {
                rpal_debug_warning( "error parsing dns packet" );
                return NULL;
            }

            if( NULL != humanLabel )
            {
                if( 0 != copied )
                {
                    humanLabel[ copied ] = '.';
                    copied++;
                }
                rpal_memory_memcpy( (RPU8)humanLabel + copied, pLabel->label, pLabel->nChar );
                copied += pLabel->nChar;
            }

            pLabel = (DnsLabel*)( (RPU8)pLabel + pLabel->nChar + 1 );
        }
    }

    // We do a last sanity check. A valid label parsing should end in a 0-val nChar within
    // the buffer, so we check it's all valid, otherwise we'll assume an error and will return an error.
    if( !IS_WITHIN_BOUNDS( pLabel, sizeof( *pLabel ), packetStart, packetSize ) ||
        0 != pLabel->nChar )
    {
        rpal_debug_warning( "error parsing dns packet" );
        return NULL;
    }

    // Get to the next valid byte, so we skip the 0-termination.
    pLabel = (DnsLabel*)( (RPU8)pLabel + 1 );

    return pLabel;
}
static
RPVOID
    modUserModeDiff
    (
        rEvent isTimeToStop
    )
{
    rBlob previousSnapshot = NULL;
    rBlob newSnapshot = NULL;
    _moduleHistEntry curModule = { 0 };
    processLibProcEntry* processes = NULL;
    processLibProcEntry* curProc = NULL;
    rList modules = NULL;
    rSequence module = NULL;
    LibOsPerformanceProfile perfProfile = { 0 };
    Atom parentAtom = { 0 };
    RU64 curTime = 0;

    perfProfile.enforceOnceIn = 1;
    perfProfile.lastTimeoutValue = 10;
    perfProfile.sanityCeiling = MSEC_FROM_SEC( 10 );
    perfProfile.targetCpuPerformance = 0;
    perfProfile.globalTargetCpuPerformance = GLOBAL_CPU_USAGE_TARGET;
    perfProfile.timeoutIncrementPerSec = 1;

    while( rpal_memory_isValid( isTimeToStop ) &&
           !rEvent_wait( isTimeToStop, 0 ) &&
           ( !kAcq_isAvailable() ||
             g_is_kernel_failure ) )
    {
        if( NULL != ( processes = processLib_getProcessEntries( FALSE ) ) )
        {
            if( NULL != ( newSnapshot = rpal_blob_create( 1000 * sizeof( _moduleHistEntry ),
                                                          1000 * sizeof( _moduleHistEntry ) ) ) )
            {
                libOs_timeoutWithProfile( &perfProfile, FALSE, isTimeToStop );

                curProc = processes;
                while( rpal_memory_isValid( isTimeToStop ) &&
#ifdef RPAL_PLATFORM_WINDOWS
                       !rEvent_wait( isTimeToStop, 0 ) &&
#else
                       // Module listing outside of 
                       !rEvent_wait( isTimeToStop, MSEC_FROM_SEC( 1 ) ) &&
#endif
                       0 != curProc->pid )
                {
                    if( NULL != ( modules = processLib_getProcessModules( curProc->pid ) ) )
                    {
                        curTime = rpal_time_getGlobalPreciseTime();

                        while( rpal_memory_isValid( isTimeToStop ) &&
                               !rEvent_wait( isTimeToStop, 0 ) &&
                               rList_getSEQUENCE( modules, RP_TAGS_DLL, &module ) )
                        {
                            libOs_timeoutWithProfile( &perfProfile, TRUE, isTimeToStop );

                            if( rSequence_getPOINTER64( module,
                                                        RP_TAGS_BASE_ADDRESS, 
                                                        &( curModule.baseAddr ) ) &&
                                rSequence_getRU64( module, 
                                                   RP_TAGS_MEMORY_SIZE, 
                                                   &(curModule.size) ) )
                            {
                                curModule.procId = curProc->pid;
                                rpal_blob_add( newSnapshot, &curModule, sizeof( curModule ) );
                                if( NULL != previousSnapshot &&
                                    -1 == rpal_binsearch_array( rpal_blob_getBuffer( previousSnapshot ),
                                                                rpal_blob_getSize( previousSnapshot ) /
                                                                    sizeof( _moduleHistEntry ),
                                                                sizeof( _moduleHistEntry ),
                                                                &curModule, 
                                                                (rpal_ordering_func)_cmpModule ) )
                                {
                                    hbs_timestampEvent( module, curTime );
                                    parentAtom.key.category = RP_TAGS_NOTIFICATION_NEW_PROCESS;
                                    parentAtom.key.process.pid = curProc->pid;
                                    if( atoms_query( &parentAtom, curTime ) )
                                    {
                                        HbsSetParentAtom( module, parentAtom.id );
                                    }
                                    rpal_memory_zero( &parentAtom, sizeof( parentAtom ) );
                                    hbs_publish( RP_TAGS_NOTIFICATION_MODULE_LOAD,
                                                 module );
                                }
                            }
                        }

                        rList_free( modules );
                    }

                    curProc++;
                }

                if( !rpal_sort_array( rpal_blob_getBuffer( newSnapshot ),
                                      rpal_blob_getSize( newSnapshot ) / sizeof( _moduleHistEntry ),
                                      sizeof( _moduleHistEntry ),
                                      (rpal_ordering_func)_cmpModule ) )
                {
                    rpal_debug_warning( "error sorting modules" );
                }
            }

            rpal_memory_free( processes );
        }

        if( NULL != previousSnapshot )
        {
            rpal_blob_free( previousSnapshot );
        }
        previousSnapshot = newSnapshot;
        newSnapshot = NULL;
    }

    if( NULL != previousSnapshot )
    {
        rpal_blob_free( previousSnapshot );
    }

    return NULL;
}
static RPVOID
    processDiffThread
    (
        rEvent isTimeToStop,
        RPVOID ctx
    )
{
    processEntry* currentSnapshot = g_snapshot_1;
    processEntry* previousSnapshot = g_snapshot_2;
    processEntry* tmpSnapshot = NULL;
    RBOOL isFirstSnapshots = TRUE;
    RU32 i = 0;
    RU32 j = 0;
    RBOOL isFound = FALSE;
    RU32 nThLoop = 0;
    RU32 currentTimeout = 0;
    UNREFERENCED_PARAMETER( ctx );

    while( !rEvent_wait( isTimeToStop, currentTimeout ) )
    {
        tmpSnapshot = currentSnapshot;
        currentSnapshot = previousSnapshot;
        previousSnapshot = tmpSnapshot;

        if( getSnapshot( currentSnapshot ) )
        {
            if( isFirstSnapshots )
            {
                isFirstSnapshots = FALSE;
                continue;
            }

            // Diff to find new processes
            for( i = 0; i < MAX_SNAPSHOT_SIZE; i++ )
            {
                isFound = FALSE;

                if( 0 == currentSnapshot[ i ].pid )
                {
                    break;
                }

                for( j = 0; j < MAX_SNAPSHOT_SIZE; j++ )
                {
                    if( 0 == previousSnapshot[ j ].pid )
                    {
                        break;
                    }

                    if( previousSnapshot[ j ].pid == currentSnapshot[ i ].pid )
                    {
                        isFound = TRUE;
                        break;
                    }
                }

                if( !isFound )
                {
                    if( !notifyOfProcess( currentSnapshot[ i ].pid, 
                                          currentSnapshot[ i ].ppid,
                                          TRUE ) )
                    {
                        rpal_debug_warning( "error reporting new process: %d", 
                                            currentSnapshot[ i ].pid );
                    }
                }
            }

            // Diff to find terminated processes
            for( i = 0; i < MAX_SNAPSHOT_SIZE; i++ )
            {
                isFound = FALSE;

                if( 0 == previousSnapshot[ i ].pid )
                {
                    break;
                }

                for( j = 0; j < MAX_SNAPSHOT_SIZE; j++ )
                {
                    if( 0 == currentSnapshot[ j ].pid )
                    {
                        break;
                    }

                    if( previousSnapshot[ i ].pid == currentSnapshot[ j ].pid )
                    {
                        isFound = TRUE;
                        break;
                    }
                }

                if( !isFound )
                {
                    if( !notifyOfProcess( previousSnapshot[ i ].pid,
                                          previousSnapshot[ i ].ppid,
                                          FALSE ) )
                    {
                        rpal_debug_warning( "error reporting terminated process: %d",
                                            previousSnapshot[ i ].pid );
                    }
                }
            }
        }

        nThLoop++;
        if( 0 == nThLoop % 20 )
        {
#ifdef RPAL_PLATFORM_WINDOWS
            // The Windows API is much more efficient than on Nix so we can affort
            // going faster between our diffs.
            currentTimeout = libOs_getUsageProportionalTimeout( 500 ) + 100;
#else
            currentTimeout = libOs_getUsageProportionalTimeout( 800 ) + 200;
#endif
        }
    }

    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;
}
Esempio n. 29
0
static
RVOID
    doScan
    (
        rpcm_tag eventType,
        rSequence event
    )
{
    RU32 pid = 0;
    RPWCHAR fileW = NULL;
    RPCHAR fileA = NULL;
    RPWCHAR procW = NULL;
    RPCHAR procA = NULL;
    RPU8 rulesBuffer = NULL;
    RU32 rulesBufferSize = 0;
    YR_RULES* rules = NULL;
    YaraMatchContext matchContext = { 0 };
    processLibProcEntry* processes = NULL;
    processLibProcEntry* curProc = NULL;
    RU32 scanError = 0;
    rSequence processInfo = NULL;
    RPWCHAR tmpW = NULL;
    RPCHAR tmpA = NULL;

    UNREFERENCED_PARAMETER( eventType );

    if( rpal_memory_isValid( event ) )
    {
        rSequence_getRU32( event, RP_TAGS_PROCESS_ID, &pid );
        rSequence_getSTRINGW( event, RP_TAGS_FILE_PATH, &fileW );
        rSequence_getSTRINGA( event, RP_TAGS_FILE_PATH, &fileA );
        rSequence_getSTRINGW( event, RP_TAGS_PROCESS, &procW );
        rSequence_getSTRINGA( event, RP_TAGS_PROCESS, &procA );

        if( rSequence_getBUFFER( event, RP_TAGS_RULES, &rulesBuffer, &rulesBufferSize ) )
        {
            rules = loadYaraRules( rulesBuffer, rulesBufferSize );
        }

        if( NULL != rules )
        {
            if( NULL != fileW )
            {
                fileA = rpal_string_wtoa( fileW );
            }

            if( NULL != procW )
            {
                procA = rpal_string_wtoa( procW );
            }

            if( NULL != fileA )
            {
                rpal_debug_info( "scanning file with yara" );
                matchContext.fileInfo = event;

                // Scan this file
                if( ERROR_SUCCESS != ( scanError = yr_rules_scan_file( rules,
                                                                       fileA,
                                                                       SCAN_FLAGS_FAST_MODE,
                                                                       _yaraFileMatchCallback,
                                                                       &matchContext,
                                                                       60 ) ) )
                {
                    rpal_debug_warning( "Yara file scan error: %d", scanError );
                }
            }
            else if( NULL != procA )
            {
                // Scan processes matching
                if( NULL != ( processes = processLib_getProcessEntries( TRUE ) ) )
                {
                    curProc = processes;
                    while( 0 != curProc->pid )
                    {
                        if( NULL != ( processInfo = processLib_getProcessInfo( curProc->pid, NULL ) ) )
                        {
                            if( rSequence_getSTRINGW( processInfo, RP_TAGS_FILE_PATH, &tmpW ) ||
                                rSequence_getSTRINGA( processInfo, RP_TAGS_FILE_PATH, &tmpA ) )
                            {
                                if( NULL != tmpW )
                                {
                                    tmpA = rpal_string_wtoa( tmpW );
                                }

                                if( NULL != tmpA )
                                {
                                    if( rpal_string_match( procA, tmpA, RPAL_PLATFORM_FS_CASE_SENSITIVITY ) )
                                    {
                                        matchContext.pid = curProc->pid;
                                        matchContext.processInfo = processInfo;

                                        scanError = _scanProcessWith( curProc->pid,
                                                                      &matchContext,
                                                                      rules,
                                                                      NULL );
                                    }
                                }

                                if( NULL != tmpW && NULL != tmpA )
                                {
                                    // If both are allocated it means we got a strW and converted to A
                                    // so we must free the strA version.
                                    rpal_memory_free( tmpA );
                                }
                            }

                            rSequence_free( processInfo );
                        }

                        curProc++;
                    }

                    rpal_memory_free( processes );
                }
            }
            else if( 0 != pid )
            {
                // Scan this process
                matchContext.pid = pid;
                scanError = _scanProcessWith( pid, &matchContext, rules, NULL );
                rSequence_free( matchContext.processInfo );
            }
            else
            {
                // Scan all processes
                if( NULL != ( processes = processLib_getProcessEntries( TRUE ) ) )
                {
                    curProc = processes;
                    while( 0 != curProc->pid )
                    {
                        matchContext.pid = curProc->pid;

                        scanError = _scanProcessWith( curProc->pid, &matchContext, rules, NULL );
                        rSequence_free( matchContext.processInfo );

                        curProc++;
                    }
                        
                    rpal_memory_free( processes );
                }
            }


            if( NULL != fileW && NULL != fileA )
            {
                // If both are allocated it means we got a strW and converted to A
                // so we must free the strA version.
                rpal_memory_free( fileA );
            }

            if( NULL != procW && NULL != procA )
            {
                // If both are allocated it means we got a strW and converted to A
                // so we must free the strA version.
                rpal_memory_free( procA );
            }

            yr_rules_destroy( rules );
        }
        else
        {
            rpal_debug_warning( "no rules in yara scan request" );
            reportError( event, RPAL_ERROR_NOT_SUPPORTED, "yara rules do not parse" );
        }
    }

    rpal_debug_info( "finished on demand yara scan" );
    reportError( event, scanError, "done" );

    yr_finalize_thread();
}
Esempio n. 30
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;
}