@@ -94,3 +94,4 @@ settings.json
|
||||
|
||||
# VisualStudio
|
||||
.vs/
|
||||
.vscode/launch.json
|
||||
|
||||
@@ -31,6 +31,11 @@ test-sigmac:
|
||||
$(COVERAGE) run -a --include=$(COVSCOPE) tools/sigmac -rvdI -t elastalert -c tools/config/winlogbeat.yml -O alert_methods=http_post,email -O emails=test@test.invalid -O http_post_url=http://test.invalid rules/ > /dev/null
|
||||
$(COVERAGE) run -a --include=$(COVSCOPE) tools/sigmac -rvdI -t elastalert-dsl -c tools/config/winlogbeat.yml -O alert_methods=http_post,email -O emails=test@test.invalid -O http_post_url=http://test.invalid rules/ > /dev/null
|
||||
$(COVERAGE) run -a --include=$(COVSCOPE) tools/sigmac -rvdI -t ee-outliers -c tools/config/winlogbeat.yml rules/ > /dev/null
|
||||
$(COVERAGE) run -a --include=$(COVSCOPE) tools/sigmac -rvdI -t es-qs -c tools/config/ecs-cloudtrail.yml rules/ > /dev/null
|
||||
$(COVERAGE) run -a --include=$(COVSCOPE) tools/sigmac -rvdI -t es-rule -c tools/config/ecs-cloudtrail.yml rules/ > /dev/null
|
||||
$(COVERAGE) run -a --include=$(COVSCOPE) tools/sigmac -rvdI -t kibana -c tools/config/ecs-cloudtrail.yml rules/ > /dev/null
|
||||
$(COVERAGE) run -a --include=$(COVSCOPE) tools/sigmac -rvdI -t xpack-watcher -c tools/config/ecs-cloudtrail.yml rules/ > /dev/null
|
||||
$(COVERAGE) run -a --include=$(COVSCOPE) tools/sigmac -rvdI -t elastalert -c tools/config/ecs-cloudtrail.yml rules/ > /dev/null
|
||||
! $(COVERAGE) run -a --include=$(COVSCOPE) tools/sigmac -rvdI -t splunk rules/ > /dev/null
|
||||
$(COVERAGE) run -a --include=$(COVSCOPE) tools/sigmac -rvdI -t splunk -c tools/config/splunk-windows-index.yml rules/ > /dev/null
|
||||
$(COVERAGE) run -a --include=$(COVSCOPE) tools/sigmac -rvdI -t splunkxml -c tools/config/splunk-windows.yml rules/ > /dev/null
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
title: AWS EC2 VM Export Failure
|
||||
id: 54b9a76a-3c71-4673-b4b3-2edb4566ea7b
|
||||
status: experimental
|
||||
description: An attempt to export an AWS EC2 instance has been detected. A VM Export might indicate an attempt to extract information from an instance.
|
||||
references:
|
||||
- https://docs.aws.amazon.com/vm-import/latest/userguide/vmexport.html#export-instance
|
||||
author: Diogo Braz
|
||||
date: 2020/04/16
|
||||
tags:
|
||||
- attack.collection
|
||||
- attack.t1005
|
||||
- attack.exfiltration
|
||||
- attack.t1537
|
||||
level: low
|
||||
logsource:
|
||||
service: cloudtrail
|
||||
detection:
|
||||
selection:
|
||||
eventName: 'CreateInstanceExportTask'
|
||||
eventSource: 'ec2.amazonaws.com'
|
||||
filter1:
|
||||
errorMessage: '*'
|
||||
filter2:
|
||||
errorCode: '*'
|
||||
filter3:
|
||||
eventName: 'ConsoleLogin'
|
||||
responseElements: '*Failure*'
|
||||
condition: selection and (filter1 or filter2 or filter3)
|
||||
@@ -0,0 +1,60 @@
|
||||
title: Elastic Common Schema And Elastic Exported Fields Mapping For AWS CloudTrail Logs
|
||||
order: 20
|
||||
backends:
|
||||
- es-qs
|
||||
- es-dsl
|
||||
- es-rule
|
||||
- kibana
|
||||
- xpack-watcher
|
||||
- elastalert
|
||||
- elastalert-dsl
|
||||
fieldmappings:
|
||||
additionalEventdata: aws.cloudtrail.additional_eventdata
|
||||
apiVersion: aws.cloudtrail.api_version
|
||||
awsRegion: cloud.region
|
||||
errorCode: aws.cloudtrail.error_code
|
||||
errorMessage: aws.cloudtrail.error_message
|
||||
eventID: event.id
|
||||
eventName: event.action
|
||||
eventSource: event.provider
|
||||
eventTime: '@timestamp'
|
||||
eventType: aws.cloudtrail.event_type
|
||||
eventVersion: aws.cloudtrail.event_version
|
||||
managementEvent: aws.cloudtrail.management_event
|
||||
readOnly: aws.cloudtrail.read_only
|
||||
requestID: aws.cloudtrail.request_id
|
||||
requestParameters: aws.cloudtrail.request_parameters
|
||||
resources.accountId: aws.cloudtrail.resources.account_id
|
||||
resources.ARN: aws.cloudtrail.resources.arn
|
||||
resources.type: aws.cloudtrail.resources.type
|
||||
responseElements: aws.cloudtrail.response_elements
|
||||
serviceEventDetails: aws.cloudtrail.service_event_details
|
||||
sharedEventId: aws.cloudtrail.shared_event_id
|
||||
sourceIPAddress: source.address
|
||||
userAgent: user_agent
|
||||
userIdentity.accessKeyId: aws.cloudtrail.user_identity.access_key_id
|
||||
userIdentity.accountId: cloud.account.id
|
||||
userIdentity.arn: aws.cloudtrail.user_identity.arn
|
||||
userIdentity.invokedBy: aws.cloudtrail.user_identity.invoked_by
|
||||
userIdentity.principalId: user.id
|
||||
userIdentity.sessionContext.attributes.creationDate: aws.cloudtrail.user_identity.session_context.creation_date
|
||||
userIdentity.sessionContext.attributes.mfaAuthenticated: aws.cloudtrail.user_identity.session_context.mfa_authenticated
|
||||
userIdentity.type: aws.cloudtrail.user_identity.type
|
||||
userIdentity.userName: user.name
|
||||
vpcEndpointId: aws.cloudtrail.vpc_endpoint_id
|
||||
overrides:
|
||||
- field: event.outcome
|
||||
value: failure
|
||||
regexes:
|
||||
- (\(\(aws.cloudtrail.error_message.keyword:.* event.action:\"ConsoleLogin\"\)\))
|
||||
- (\(\(aws.cloudtrail.error_code.keyword:.* event.action:\"ConsoleLogin\"\)\))
|
||||
- (\(\(aws.cloudtrail.error_message.keyword:.* aws.cloudtrail.response_elements.keyword:\*Failure\*\)\))
|
||||
- (\(\(aws.cloudtrail.error_code.keyword:.* aws.cloudtrail.response_elements.keyword:\*Failure\*\)\))
|
||||
- (\(\(event.action:\"ConsoleLogin\".* aws.cloudtrail.error_message.keyword:\*\)\))
|
||||
- (\(\(event.action:\"ConsoleLogin\".* aws.cloudtrail.error_code.keyword:\*\)\))
|
||||
- (\(\(aws.cloudtrail.response_elements.keyword:\*Failure\*.* aws.cloudtrail.error_message.keyword:\*\)\))
|
||||
- (\(\(aws.cloudtrail.response_elements.keyword:\*Failure\*.* aws.cloudtrail.error_code.keyword:\*\)\))
|
||||
- field: event.outcome
|
||||
value: success
|
||||
literals:
|
||||
- 'NOT (event.outcome:failure)'
|
||||
@@ -18,6 +18,7 @@ import sys
|
||||
|
||||
import sigma
|
||||
import yaml
|
||||
import re
|
||||
|
||||
from .mixins import RulenameCommentMixin, QuoteCharMixin
|
||||
from sigma.parser.modifiers.base import SigmaTypeModifier
|
||||
@@ -90,6 +91,7 @@ class BaseBackend:
|
||||
options = tuple() # a list of tuples with following elements: option name, default value, help text, target attribute name (option name if None)
|
||||
config_required = True
|
||||
default_config = None
|
||||
mapExpression = ""
|
||||
|
||||
def __init__(self, sigmaconfig, backend_options=dict()):
|
||||
"""
|
||||
@@ -130,29 +132,48 @@ class BaseBackend:
|
||||
result = self.generateNode(parsed.parsedSearch)
|
||||
if parsed.parsedAgg:
|
||||
result += self.generateAggregation(parsed.parsedAgg)
|
||||
#result = self.applyOverrides(result)
|
||||
return result
|
||||
|
||||
def applyOverrides(self, query):
|
||||
try:
|
||||
if 'overrides' in self.sigmaconfig.config and isinstance(query, str):
|
||||
for expression in self.sigmaconfig.config['overrides']:
|
||||
if 'regexes' in expression:
|
||||
for x in expression['regexes']:
|
||||
sub = expression['field']
|
||||
value = expression['value']
|
||||
query = re.sub(x, self.mapExpression % (sub, value), query)
|
||||
if 'literals' in expression:
|
||||
for x in expression['literals']:
|
||||
sub = expression['field']
|
||||
value = expression['value']
|
||||
query = query.replace(x, self.mapExpression % (sub, value))
|
||||
except Exception:
|
||||
pass
|
||||
return query
|
||||
|
||||
def generateNode(self, node):
|
||||
if type(node) == sigma.parser.condition.ConditionAND:
|
||||
return self.generateANDNode(node)
|
||||
return self.applyOverrides(self.generateANDNode(node))
|
||||
elif type(node) == sigma.parser.condition.ConditionOR:
|
||||
return self.generateORNode(node)
|
||||
return self.applyOverrides(self.generateORNode(node))
|
||||
elif type(node) == sigma.parser.condition.ConditionNOT:
|
||||
return self.generateNOTNode(node)
|
||||
return self.applyOverrides(self.generateNOTNode(node))
|
||||
elif type(node) == sigma.parser.condition.ConditionNULLValue:
|
||||
return self.generateNULLValueNode(node)
|
||||
return self.applyOverrides(self.generateNULLValueNode(node))
|
||||
elif type(node) == sigma.parser.condition.ConditionNotNULLValue:
|
||||
return self.generateNotNULLValueNode(node)
|
||||
return self.applyOverrides(self.generateNotNULLValueNode(node))
|
||||
elif type(node) == sigma.parser.condition.NodeSubexpression:
|
||||
return self.generateSubexpressionNode(node)
|
||||
return self.applyOverrides(self.generateSubexpressionNode(node))
|
||||
elif type(node) == tuple:
|
||||
return self.generateMapItemNode(node)
|
||||
return self.applyOverrides(self.generateMapItemNode(node))
|
||||
elif type(node) in (str, int):
|
||||
return self.generateValueNode(node)
|
||||
return self.applyOverrides(self.generateValueNode(node))
|
||||
elif type(node) == list:
|
||||
return self.generateListNode(node)
|
||||
return self.applyOverrides(self.generateListNode(node))
|
||||
elif isinstance(node, SigmaTypeModifier):
|
||||
return self.generateTypedValueNode(node)
|
||||
return self.applyOverrides(self.generateTypedValueNode(node))
|
||||
else:
|
||||
raise TypeError("Node type %s was not expected in Sigma parse tree" % (str(type(node))))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user