import expect from '@kbn/expect' ; import { ResolverPaginatedEvents , SafeEndpointEvent , } from '../../../plugins/security_solution/common/endpoint/types' ; import { eventsIndexPattern } from '../../../plugins/security_solution/common/endpoint/constants' ; import { EndpointDocGenerator , Event , } from '../../../plugins/security_solution/common/endpoint/generate_data' ; import { FtrProviderContext } from '../ftr_provider_context' ; import { InsertedEvents , processEventsIndex } from '../services/resolver' ; import { deleteEventsStream } from './data_stream_helper' ; interface EventIngested { event : { ingested : number ; } ; } interface NetworkEvent { source : { geo ? : { country_name : string ; } ; } ; destination : { geo ? : { country_name : string ; } ; } ; } const networkIndex = 'logs-endpoint.events.network-default' ; export default function ( { getService } ) { const esArchiver = getService ( 'esArchiver' ) ; const supertest = getService ( 'supertest' ) ; const resolver = getService ( 'resolverGenerator' ) ; const es = getService ( 'es' ) ; const generator = new EndpointDocGenerator ( 'data' ) ; const searchForID = async < T > ( id ) => { return es . search < T > ( { index : eventsIndexPattern , body : { query : { bool : { filter : [ { ids : { values : [ id ] , } , } , ] , } , } , } , } , { meta : true } ) ; } ; describe . skip ( 'Endpoint package' , ( ) => { describe ( 'network processors' , ( ) => { let networkIndexData ; after ( async ( ) => { await resolver . deleteData ( networkIndexData ) ; } ) ; it ( 'handles events without the `network.protocol` field being defined' , async ( ) => { const eventWithoutNetworkObject = generator . generateEvent ( { eventsDataStream : EndpointDocGenerator . createDataStreamFromIndex ( networkIndex ) , } ) ; delete eventWithoutNetworkObject . network ; networkIndexData = await resolver . insertEvents ( [ eventWithoutNetworkObject ] , networkIndex ) ; const eventWithBothIPs = await searchForID < SafeEndpointEvent > ( networkIndexData . eventsInfo [ 0 ] . _id ) ; expect ( eventWithBothIPs . body . hits . hits [ 0 ] . _source ?. event ?. id ) . to . be ( eventWithoutNetworkObject . event ?. id ) ; } ) ; } ) ; describe ( 'dns processor' , ( ) => { before ( async ( ) => { await esArchiver . load ( 'x-pack/test/functional/es_archives/endpoint/pipeline/dns' , { useCreate : true , } ) ; } ) ; after ( async ( ) => { await deleteEventsStream ( getService ) ; } ) ; it ( 'does not set dns.question.type if it is already populated' , async ( ) => { const id = 'LrLSOVHVsFY94TAi++++++eF' ; const { body } = await supertest . post ( `/api/endpoint/resolver/events` ) . query ( { limit : 1 } ) . set ( 'kbn-xsrf' , 'xxx' ) . send ( { filter : JSON . stringify ( { bool : { filter : [ { term : { 'event.id' : id } } ] , } , } ) , indexPatterns : [ eventsIndexPattern ] , timeRange : { from : '2020-10-01T13:50:15.14364600Z' , to : '2020-10-01T13:50:15.14364600Z' , } , } ) . expect ( 200 ) ; expect ( body . events . length ) . to . eql ( 1 ) ; expect ( ( body . events [ 0 ] as SafeEndpointEvent ) . dns ?. question ?. name ) . to . eql ( 'www.google.com' ) ; expect ( ( body . events [ 0 ] as SafeEndpointEvent ) . dns ?. question ?. type ) . to . eql ( 'INVALID_VALUE' ) ; } ) ; it ( 'sets dns.question.type if it is not populated' , async ( ) => { const id = 'LrLSOVHVsFY94TAi++++++eP' ; const { body } = await supertest . post ( `/api/endpoint/resolver/events` ) . query ( { limit : 1 } ) . set ( 'kbn-xsrf' , 'xxx' ) . send ( { filter : JSON . stringify ( { bool : { filter : [ { term : { 'event.id' : id } } ] , } , } ) , indexPatterns : [ eventsIndexPattern ] , timeRange : { from : '2020-10-01T13:50:15.44516300Z' , to : '2020-10-01T13:50:15.44516300Z' , } , } ) . expect ( 200 ) ; expect ( body . events . length ) . to . eql ( 1 ) ; expect ( ( body . events [ 0 ] as SafeEndpointEvent ) . dns ?. question ?. name ) . to . eql ( 'www.aol.com' ) ; expect ( ( body . events [ 0 ] as SafeEndpointEvent ) . dns ?. question ?. type ) . to . eql ( 'AAAA' ) ; } ) ; } ) ; describe ( 'ingested processor' , ( ) => { let event ; let genData ; before ( async ( ) => { event = generator . generateEvent ( { eventsDataStream : EndpointDocGenerator . createDataStreamFromIndex ( processEventsIndex ) , } ) ; genData = await resolver . insertEvents ( [ event ] , processEventsIndex ) ; } ) ; after ( async ( ) => { await resolver . deleteData ( genData ) ; } ) ; it ( 'sets the event.ingested field' , async ( ) => { const resp = await searchForID < EventIngested > ( genData . eventsInfo [ 0 ] . _id ) ; expect ( resp . body . hits . hits [ 0 ] . _source ?. event . ingested ) . to . not . be ( undefined ) ; } ) ; } ) ; describe ( 'geoip processor' , ( ) => { let processIndexData ; let networkIndexData ; before ( async ( ) => { const eventWithBothIPsNetwork = generator . generateEvent ( { extensions : { source : { ip : '8.8.8.8' } , destination : { ip : '46.239.193.5' } } , eventsDataStream : EndpointDocGenerator . createDataStreamFromIndex ( networkIndex ) , } ) ; const eventWithSourceOnlyNetwork = generator . generateEvent ( { extensions : { source : { ip : '8.8.8.8' } } , eventsDataStream : EndpointDocGenerator . createDataStreamFromIndex ( networkIndex ) , } ) ; networkIndexData = await resolver . insertEvents ( [ eventWithBothIPsNetwork , eventWithSourceOnlyNetwork ] , networkIndex ) ; const eventWithBothIPsProcess = generator . generateEvent ( { extensions : { source : { ip : '8.8.8.8' } , destination : { ip : '46.239.193.5' } } , eventsDataStream : EndpointDocGenerator . createDataStreamFromIndex ( processEventsIndex ) , } ) ; processIndexData = await resolver . insertEvents ( [ eventWithBothIPsProcess ] , processEventsIndex ) ; } ) ; after ( async ( ) => { await resolver . deleteData ( networkIndexData ) ; await resolver . deleteData ( processIndexData ) ; } ) ; it ( 'sets the geoip fields' , async ( ) => { const eventWithBothIPs = await searchForID < NetworkEvent > ( networkIndexData . eventsInfo [ 0 ] . _id ) ; expect ( eventWithBothIPs . body . hits . hits [ 0 ] . _source ?. source . geo ?. country_name ) . to . not . be ( undefined ) ; expect ( eventWithBothIPs . body . hits . hits [ 0 ] . _source ?. destination . geo ?. country_name ) . to . not . be ( undefined ) ; const eventWithSourceOnly = await searchForID < NetworkEvent > ( networkIndexData . eventsInfo [ 1 ] . _id ) ; expect ( eventWithBothIPs . body . hits . hits [ 0 ] . _source ?. source . geo ?. country_name ) . to . not . be ( undefined ) ; expect ( eventWithSourceOnly . body . hits . hits [ 0 ] . _source ?. destination ?. geo ) . to . be ( undefined ) ; } ) ; it ( 'does not set geoip fields for events in indices other than the network index' , async ( ) => { const eventWithBothIPs = await searchForID < NetworkEvent > ( processIndexData . eventsInfo [ 0 ] . _id ) ; expect ( eventWithBothIPs . body . hits . hits [ 0 ] . _source ?. source . geo ) . to . be ( undefined ) ; expect ( eventWithBothIPs . body . hits . hits [ 0 ] . _source ?. destination . geo ) . to . be ( undefined ) ; } ) ; } ) ; } ) ; }