Skip to content

Commit

Permalink
Merge branch 'release_v4.13.0' into obs_fix_25
Browse files Browse the repository at this point in the history
  • Loading branch information
patel-bhavin committed Sep 29, 2023
2 parents b3dc347 + 3d3631f commit 54ce1f7
Show file tree
Hide file tree
Showing 309 changed files with 5,101 additions and 5,869 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class Detection(BaseModel, SecurityContentObject):
nes_fields: str = None
providing_technologies: list = None
runtime: str = None
internalVersion: str = None

# @validator('name')v
# def name_max_length(cls, v, values):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ class DetectionTags(BaseModel):
risk_level: str = None
observable_str: str = None
evidence_str: str = None
analytics_story_str: str = None
kill_chain_phases_id: list = None
kill_chain_phases_str: str = None
research_site_url: str = None
event_schema: str = None
mappings: list = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,37 @@ class FindingReportObject():
@staticmethod
def writeFindingReport(detection : Detection) -> None:

if detection.tags.confidence < 33:
detection.tags.confidence_id = 1
elif detection.tags.confidence < 66:
detection.tags.confidence_id = 2
else:
detection.tags.confidence_id = 3

if detection.tags.impact < 20:
detection.tags.impact_id = 1
elif detection.tags.impact < 40:
detection.tags.impact_id = 2
elif detection.tags.impact < 60:
detection.tags.impact_id = 3
elif detection.tags.impact < 80:
detection.tags.impact_id = 4
else:
detection.tags.impact_id = 5

detection.tags.kill_chain_phases_id = dict()
for kill_chain_phase in detection.tags.kill_chain_phases:
detection.tags.kill_chain_phases_id[kill_chain_phase] = SES_KILL_CHAIN_MAPPINGS[kill_chain_phase]

kill_chain_phase_str = "["
i = 0
for kill_chain_phase in detection.tags.kill_chain_phases_id.keys():
kill_chain_phase_str = kill_chain_phase_str + '{"phase": "' + kill_chain_phase + '", "phase_id": ' + str(detection.tags.kill_chain_phases_id[kill_chain_phase]) + "}"
if not i == (len(detection.tags.kill_chain_phases_id.keys()) - 1):
kill_chain_phase_str = kill_chain_phase_str + ', '
i = i + 1
kill_chain_phase_str = kill_chain_phase_str + ']'
detection.tags.kill_chain_phases_str = kill_chain_phase_str

if detection.tags.risk_score < 20:
detection.tags.risk_level_id = 0
Expand All @@ -27,15 +58,23 @@ def writeFindingReport(detection : Detection) -> None:
detection.tags.risk_level_id = 4
detection.tags.risk_level = "Critical"

evidence_str = "create_map("
evidence_str = "{"
for i in range(len(detection.tags.observable)):
evidence_str = evidence_str + '"' + detection.tags.observable[i]["name"] + '", ' + detection.tags.observable[i]["name"].replace(".", "_")
evidence_str = evidence_str + '"' + detection.tags.observable[i]["name"] + '": ' + detection.tags.observable[i]["name"].replace(".", "_")
if not i == (len(detection.tags.observable) - 1):
evidence_str = evidence_str + ', '
evidence_str = evidence_str + ')'
evidence_str = evidence_str + '}'

detection.tags.evidence_str = evidence_str

analytics_story_str = "["
for i in range(len(detection.tags.analytic_story)):
analytics_story_str = analytics_story_str + '"' + detection.tags.analytic_story[i] + '"'
if not i == (len(detection.tags.analytic_story) - 1):
analytics_story_str = analytics_story_str + ', '
analytics_story_str = analytics_story_str + ']'
detection.tags.analytics_story_str = analytics_story_str

if "actor.user.name" in detection.tags.required_fields:
actor_user_name = "actor_user_name"
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ def writeObjects(self, objects: list, output_path: str, type: SecurityContentTyp
"nist": obj.tags.nist
}

obj.runtime = "SPL-DSP"
obj.runtime = "SPL2"
obj.internalVersion = 2

# remove unncessary fields
YmlWriter.writeYmlFile(file_path, obj.dict(
Expand All @@ -84,6 +85,7 @@ def writeObjects(self, objects: list, output_path: str, type: SecurityContentTyp
"known_false_positives": True,
"references": True,
"runtime": True,
"internalVersion": True,
"tags":
{
#"analytic_story": True,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@

| eval body=create_map(
"devices", [
create_map(
"hostname", device_hostname, "type_id", 0, "uuid", ucast(map_get(device,"uuid"), "string", null)
)
],
"time", timestamp,
"evidence", {{ detection.tags.evidence_str }},
"message", concat("{{ detection.name }} has been triggered on ", device_hostname, " by ", {{ actor_user_name }}, "."),
"users", [
create_map(
"name", {{ actor_user_name }}, "uid", ucast(map_get(actor_user,"uid"), "string", null)
)
],
"activity_id", 1,
"category_uid", 2,
"class_uid", 102001,
"risk_level_id", {{ detection.tags.risk_level_id }},
"risk_score", {{ detection.tags.risk_score }},
"severity_id", 0,
"rule", create_map("name", "{{ detection.name }}", "uid", "{{ detection.id }}", "type", "Streaming"),
"metadata", create_map("customer_uid", ucast(map_get(metadata,"customer_uid"), "string", null), "product", create_map("name", "Behavior Analytics", "vendor_name", "Splunk"), "version", "1.0.0-rc.2", "logged_time", time()),
"type_uid", 10200101,
"start_time", timestamp,
"end_time", timestamp
)
| into write_ba_finding_events();
| eval devices = [{"hostname": device_hostname, "type_id": 0, "uuid": device.uuid}],
time = timestamp,
evidence = {{ detection.tags.evidence_str }},
message = "{{ detection.name }} has been triggered on " + device_hostname + " by " + {{ actor_user_name }} + ".",
users = [{"name": {{ actor_user_name }}, "uid": actor_user.uid}],
activity_id = 1,
cis_csc = [{"control": "CIS 10", "version": 8}],
analytic_stories = {{ detection.tags.analytics_story_str }},
class_name = "Detection Report",
confidence = {{ detection.tags.confidence }},
confidence_id = {{ detection.tags.confidence_id }},
duration = 0,
impact = {{ detection.tags.impact }},
impact_id = {{ detection.tags.impact_id }},
kill_chain = {{ detection.tags.kill_chain_phases_str }},
nist = ["DE.AE"],
risk_level = "{{ detection.tags.risk_level }}",
category_uid = 2,
class_uid = 102001,
risk_level_id = {{ detection.tags.risk_level_id }},
risk_score = {{ detection.tags.risk_score }},
severity_id = 0,
rule = {"name": "{{ detection.name }}", "uid": "{{ detection.id }}", "type": "Streaming"},
metadata = {"customer_uid": metadata.customer_uid, "product": {"name": "Behavior Analytics", "vendor_name": "Splunk"}, "version": "1.0.0-rc.2", "logged_time": time()},
type_uid = 10200101,
start_time = timestamp,
end_time = timestamp
| fields metadata, rule, activity_id, analytic_stories, cis_csc, category_uid, class_name, class_uid, confidence, confidence_id, devices, duration, time, evidence, impact, impact_id, kill_chain, message, nist, observables, risk_level, risk_level_id, risk_score, severity_id, type_uid, users, start_time, end_time
| into sink;
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class SplunkBABackend(TextQueryBackend):
wildcard_single : ClassVar[str] = "%"
add_escaped : ClassVar[str] = "\\"

re_expression : ClassVar[str] = "match_regex({field}, /(?i){regex}/)=true"
re_expression : ClassVar[str] = "match({field}, /(?i){regex}/)=true"
re_escape_char : ClassVar[str] = ""
re_escape : ClassVar[Tuple[str]] = ('"',)

Expand Down Expand Up @@ -64,7 +64,7 @@ class SplunkBABackend(TextQueryBackend):
deferred_separator : ClassVar[str] = " OR "
deferred_only_query : ClassVar[str] = "*"

wildcard_match_expression : ClassVar[Optional[str]] = "like({field}, {value})"
wildcard_match_expression : ClassVar[Optional[str]] = "{field} LIKE {value}"


def __init__(self, processing_pipeline: Optional["sigma.processing.pipeline.ProcessingPipeline"] = None, collect_errors: bool = False, min_time : str = "-30d", max_time : str = "now", detection : Detection = None, field_mapping: dict = None, **kwargs):
Expand All @@ -88,41 +88,36 @@ def finalize_query_data_model(self, rule: SigmaRule, query: str, index: int, sta
# fields_input_parsing = fields_input_parsing + ', '

detection_str = """
| from read_ba_enriched_events()
| eval timestamp = ucast(map_get(input_event,"time"),"long", null)
| eval metadata = ucast(map_get(input_event, "metadata"),"map<string, any>", null)
| eval metadata_uid = ucast(map_get(metadata, "uid"),"string", null)
$main = from source
| eval timestamp = time
| eval metadata_uid = metadata.uid
""".replace("\n", " ")

parsed_fields = []

for field in self.field_mapping["mapping"].keys():
mapped_field = self.field_mapping["mapping"][field]
parent = 'input_event'
parent = 'parent'
i = 1
values = mapped_field.split('.')
for val in values:
if parent == "input_event":
new_val = val
if parent == "parent":
parent = val
continue
else:
new_val = parent + '_' + val
if new_val in parsed_fields:
parent = new_val
i = i + 1
continue
if i == len(values):
parser_str = '| eval ' + new_val + '' + '=ucast(map_get(' + parent + ',"' + val + '"), "string", null) '
else:
parser_str = '| eval ' + new_val + '' + '=ucast(map_get(' + parent + ',"' + val + '"), "map<string, any>", null) '
parser_str = '| eval ' + new_val + ' = ' + parent + '.' + val + ' '
detection_str = detection_str + parser_str
parsed_fields.append(new_val)
parent = new_val
i = i + 1

detection_str = detection_str + "| where " + query
detection_str = detection_str.replace("\\\\\\\\", "\\\\")


return detection_str

def finalize_output_data_model(self, queries: List[str]) -> List[str]:
Expand Down
14 changes: 3 additions & 11 deletions detections/application/okta_risk_threshold_exceeded.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ type: Correlation
description:
The following correlation will take risk associated with the content
from "Suspicious Okta Activity" and "Okta MFA Exhaustion" analytic stories and
tally it up. Once it hits the threshold of 100 (may be changed), it will trigger
an anomaly. As needed, reduce or raise the risk scores assocaited with the anomaly
and TTP analytics tagged to these two stories.
tally it up. Once it hits the threshold of 100 (can be changed), it will trigger an a notable. As needed, reduce or raise the risk scores assocaited with the anomaly and TTP analytics tagged to these two analytic stories.
data_source: []
search:
'| tstats `security_content_summariesonly` sum(All_Risk.calculated_risk_score) as risk_score,
Expand Down Expand Up @@ -44,19 +42,13 @@ tags:
asset_type: Infrastructure
confidence: 80
impact: 70
message:
Risk threshold exceeded for $risk_object_type$=$risk_object$ related to
Okta events.
message: Risk score $risk_score$ threshold exceeded for $risk_object$ related to Okta events.
mitre_attack_id:
- T1078
- T1110
observable:
- name: risk_object
type: Other
role:
- Victim
- name: risk_object_type
type: Other
type: Hostname
role:
- Victim
product:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ description: In Splunk Enterprise versions below 8.1.13, 8.2.10, and 9.0.4, a cr
this vulnerability.
data_source: []
search: '`splunkda` uri_path="/en-US/splunkd/__raw/services/ssg/kvstore_client" method="GET"
delete_field_value="spacebridge_server" status="200" | table splunk_server status
delete_field_value="spacebridge_server" status="200" | table splunk_server status
uri delete_field_value method post_data | `splunk_csrf_in_the_ssg_kvstore_client_endpoint_filter`'
how_to_implement: Requires access to internal index.
known_false_positives: This hunting search only applies to the affected versions and
Expand All @@ -31,7 +31,7 @@ tags:
cve:
- CVE-2023-22942
impact: 50
message: Potential CSRF exploitation attempt from $host$
message: Potential CSRF exploitation attempt from $splunk_server$
mitre_attack_id:
- T1189
observable:
Expand Down
8 changes: 3 additions & 5 deletions detections/cloud/aws_excessive_security_scanning.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ description: This search looks for AWS CloudTrail events and analyse the amount
data_source: []
search: '`cloudtrail` eventName=Describe* OR eventName=List* OR eventName=Get* |
stats dc(eventName) as dc_events min(_time) as firstTime max(_time) as lastTime
values(eventName) as eventName values(src) as src values(userAgent) as userAgent
values(eventName) as command values(src) as src values(userAgent) as userAgent
by user userIdentity.arn | where dc_events > 50 | `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`|`aws_excessive_security_scanning_filter`'
how_to_implement: You must install splunk AWS add on and Splunk App for AWS. This
Expand All @@ -25,9 +25,7 @@ tags:
asset_type: AWS Account
confidence: 60
impact: 30
message: user $user$ has excessive number of api calls $dc_events$ from these IP
addresses $src$, violating the threshold of 50, using the following commands
$command$.
message: User $user$ has excessive number of api calls $dc_events$ from these IP addresses $src$, violating the threshold of 50, using the following commands $command$.
mitre_attack_id:
- T1526
observable:
Expand All @@ -38,7 +36,7 @@ tags:
- name: user
type: User
role:
- Attacker
- Victim
product:
- Splunk Enterprise
- Splunk Enterprise Security
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ date: '2021-01-11'
author: Bhavin Patel, Patrick Bareiss, Splunk
status: production
type: TTP
description: The search looks for AWS CloudTrail events to detect if any network ACLs
were created with all the ports open to a specified CIDR.
description: The search looks for AWS CloudTrail events to detect if any network ACLs were created with all the ports open to a specified CIDR.
data_source: []
search: '`cloudtrail` eventName=CreateNetworkAclEntry OR eventName=ReplaceNetworkAclEntry
requestParameters.ruleAction=allow requestParameters.egress=false requestParameters.aclProtocol=-1
| append [search `cloudtrail` eventName=CreateNetworkAclEntry OR eventName=ReplaceNetworkAclEntry
requestParameters.ruleAction=allow requestParameters.egress=false requestParameters.aclProtocol!=-1
| eval port_range=''requestParameters.portRange.to'' - ''requestParameters.portRange.from''
| where port_range>1024] | fillnull | stats count min(_time) as firstTime max(_time)
as lastTime by userName userIdentity.principalId eventName requestParameters.ruleAction
as lastTime by userName user_arn userIdentity.principalId eventName requestParameters.ruleAction
requestParameters.egress requestParameters.aclProtocol requestParameters.portRange.to
requestParameters.portRange.from src userAgent requestParameters.cidrBlock | `security_content_ctime(firstTime)`|
`security_content_ctime(lastTime)` | `aws_network_access_control_list_created_with_all_open_ports_filter`'
Expand All @@ -31,8 +30,7 @@ tags:
asset_type: AWS Instance
confidence: 80
impact: 60
message: User $user_arn$ has created network ACLs with all the ports open to a specified
CIDR $requestParameters.cidrBlock$
message: User $user_arn$ has created network ACLs with all the ports open to a specified CIDR $requestParameters.cidrBlock$
mitre_attack_id:
- T1562.007
- T1562
Expand All @@ -41,14 +39,10 @@ tags:
type: IP Address
role:
- Attacker
- name: userName
- name: user_arn
type: User
role:
- Victim
- name: requestParameters.cidrBlock
type: IP Address
role:
- Victim
product:
- Splunk Enterprise
- Splunk Enterprise Security
Expand Down
2 changes: 1 addition & 1 deletion detections/cloud/aws_setdefaultpolicyversion.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ tags:
asset_type: AWS Account
confidence: 60
impact: 50
message: From IP address $sourceIPAddress$, user agent $userAgent$ has trigged an
message: From IP address $src$, user $user_arn$ has trigged an
event $eventName$ for updating the the default policy version
mitre_attack_id:
- T1078.004
Expand Down
2 changes: 1 addition & 1 deletion detections/cloud/aws_updateloginprofile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ tags:
asset_type: AWS Account
confidence: 60
impact: 50
message: From IP address $sourceIPAddress$, user agent $userAgent$ has trigged an
message: From IP address $src$, user agent $userAgent$ has trigged an
event $eventName$ for updating the existing login profile, potentially giving
user $user_arn$ more access privilleges
mitre_attack_id:
Expand Down
10 changes: 5 additions & 5 deletions detections/cloud/azure_ad_user_enabled_and_password_reset.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ search: ' `azuread` (operationName="Enable account" OR operationName="Reset pass
OR operationName="Update user") | transaction properties.targetResources{}.userPrincipalName
startsWith=(operationName="Enable account") endsWith=(operationName="Reset password (by admin)") maxspan=2m
| rename properties.* as * | rename targetResources{}.userPrincipalName
as userPrincipalName | rename initiatedBy.user.userPrincipalName as initiatedBy
| stats values(operationName) values(initiatedBy) as initiatedBy by _time, userPrincipalName,
as user | rename initiatedBy.user.userPrincipalName as initiatedBy
| stats values(operationName) values(initiatedBy) as initiatedBy by _time, user,
result | `azure_ad_user_enabled_and_password_reset_filter`'
how_to_implement: You must install the latest version of Splunk Add-on for Microsoft
Cloud Services from Splunkbase(https://splunkbase.splunk.com/app/3110/#/details).
Expand All @@ -36,12 +36,12 @@ tags:
mitre_attack_id:
- T1098
observable:
- name: userPrincipalName
type: User Name
- name: user
type: User
role:
- Victim
- name: initiatedBy
type: User Name
type: User
role:
- Attacker
product:
Expand Down
Loading

0 comments on commit 54ce1f7

Please sign in to comment.