def search_alerts(ctx, query, date_range, columns, extend): """Search detection engine alerts with KQL.""" from eql.table import Table from .eswrap import MATCH_ALL, add_range_to_dsl kibana = ctx.obj['kibana'] start_time, end_time = date_range kql_query = kql.to_dsl(query) if query else MATCH_ALL add_range_to_dsl(kql_query['bool'].setdefault('filter', []), start_time, end_time) with kibana: alerts = [ a['_source'] for a in Signal.search({'query': kql_query})['hits']['hits'] ] table_columns = [ 'host.hostname', 'signal.rule.name', 'signal.status', 'signal.original_time' ] if columns: columns = list(columns) table_columns = table_columns + columns if extend else columns click.echo(Table.from_list(table_columns, alerts)) return alerts
def collect_events(ctx, host_id, query, index, rta_name, rule_id, view_events): """Collect events from Elasticsearch.""" client: Elasticsearch = ctx.obj['es'] dsl = kql.to_dsl(query) if query else MATCH_ALL dsl['bool'].setdefault('filter', []).append( {'bool': { 'should': [{ 'match_phrase': { 'host.id': host_id } }] }}) try: collector = CollectRtaEvents(client) start = time.time() click.pause('Press any key once detonation is complete ...') start_time = f'now-{round(time.time() - start) + 5}s' events = collector.run(dsl, index or '*', start_time) events.save(rta_name=rta_name, host_id=host_id) if rta_name and rule_id: events.evaluate_against_rule_and_update_mapping(rule_id, rta_name) if view_events and events.events: events.echo_events(pager=True) return events except AssertionError as e: error_msg = 'No events collected! Verify events are streaming and that the agent-hostname is correct' client_error(error_msg, e, ctx=ctx)
def _prep_query(query, language, index, start_time=None, end_time=None): """Prep a query for search.""" index_str = ','.join(index if isinstance(index, (list, tuple)) else index.split(',')) lucene_query = query if language == 'lucene' else None if language in ('kql', 'kuery'): formatted_dsl = {'query': kql.to_dsl(query)} elif language == 'eql': formatted_dsl = {'query': query, 'filter': MATCH_ALL} elif language == 'lucene': formatted_dsl = {'query': {'bool': {'filter': []}}} elif language == 'dsl': formatted_dsl = {'query': query} else: raise ValueError('Unknown search language') if start_time or end_time: end_time = end_time or 'now' dsl = formatted_dsl['filter']['bool']['filter'] if language == 'eql' else \ formatted_dsl['query']['bool'].setdefault('filter', []) add_range_to_dsl(dsl, start_time, end_time) return index_str, formatted_dsl, lucene_query
def validate(self, kql_source, dsl, **kwargs): actual_dsl = kql.to_dsl(kql_source, **kwargs) self.assertListEqual(list(actual_dsl), ["bool"]) self.assertDictEqual(actual_dsl["bool"], dsl)