From e11c55b69bc9899f4165abc2f6a1f64474b28b26 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Wed, 15 Jan 2025 10:39:57 +0100 Subject: [PATCH 01/36] New GitHub Enterprise detections --- data_sources/github.yml | 32 ++++++++ .../cloud/github_disable_dependabot.yml | 75 +++++++++++++++++++ macros/github_enterprise.yml | 4 + 3 files changed, 111 insertions(+) create mode 100644 data_sources/github.yml create mode 100644 detections/cloud/github_disable_dependabot.yml create mode 100644 macros/github_enterprise.yml diff --git a/data_sources/github.yml b/data_sources/github.yml new file mode 100644 index 0000000000..61a065bab2 --- /dev/null +++ b/data_sources/github.yml @@ -0,0 +1,32 @@ +name: GitHub +id: 8a4d656f-8801-4a2c-ae10-553d2696a59f +version: 1 +date: '2025-01-15' +author: Patrick Bareiss, Splunk +description: Data source object for GitHub Enterprise logs +source: github +sourcetype: github:cloud:audit +supported_TA: +- name: Splunk Add-on for Github + url: https://splunkbase.splunk.com/app/6254 + version: 3.1.0 +fields: +- _document_id +- action +- actor +- actor_id +- actor_is_bot +- business +- business_id +- created_at +- operation_type +- org +- org_id +- public_repo +- repo +- repo_id +- request_access_security_header +- user +- user_agent +- user_id +example_log: '{ @timestamp: 1736850926658 _document_id: fHPRFHOMZNXLxTZrk1w2IQ action: repository_vulnerability_alerts.disable actor: P4T12ICK actor_id: 8362376 actor_ip: 84.128.62.13 actor_is_bot: false actor_location: { [+] } business: pb business_id: 273781 created_at: 1736850926658 operation_type: modify org: pbtest2 org_id: 194489467 public_repo: false repo: pbtest2/pbtest5 repo_id: 916529548 request_access_security_header: null user: P4T12ICK user_agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 user_id: 8362376 }' \ No newline at end of file diff --git a/detections/cloud/github_disable_dependabot.yml b/detections/cloud/github_disable_dependabot.yml new file mode 100644 index 0000000000..c671aeba8b --- /dev/null +++ b/detections/cloud/github_disable_dependabot.yml @@ -0,0 +1,75 @@ +name: GitHub Disable Dependabot +id: 787dd1c1-eb3a-4a31-8e8c-2ad24b214bc8 +version: 1 +date: '2025-01-14' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when a user disables Dependabot security features within a GitHub repository. + Dependabot helps automatically identify and fix security vulnerabilities in dependencies. The detection monitors GitHub + Enterprise logs for configuration changes that disable Dependabot functionality. This behavior could indicate an attacker + attempting to prevent the automatic detection of vulnerable dependencies, which would allow them to exploit known vulnerabilities + that would otherwise be patched. For a SOC, identifying the disabling of security features like Dependabot is critical as it may + be a precursor to supply chain attacks where attackers exploit vulnerable dependencies. The impact could be severe if vulnerabilities + remain unpatched, potentially leading to code execution, data theft, or other compromises through the software supply chain. +data_source: +- GitHub +search: '`github_enterprise` action=repository_vulnerability_alerts.disable OR vendor_action=repository_vulnerability_alerts.disable + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user, user_agent, user_id, src, action, vendor_action + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_disable_dependabot_filter`' +how_to_implement: You must ingest GitHub Enterprise logs using the Splunk Add-on for GitHub https://splunkbase.splunk.com/app/6254 . +known_false_positives: unknown +references: +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: Dependabot security features are disabled in repository $repo$ by $user$ + mitre_attack_id: + - T1562.001 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_ip + - actor_is_bot + - actor_location.country_code + - business + - business_id + - org + - org_id + - repo + - repo_id + - user + - user_agent + - user_id + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/disable_dependabot/github.json + source: github + sourcetype: github:cloud:audit diff --git a/macros/github_enterprise.yml b/macros/github_enterprise.yml new file mode 100644 index 0000000000..5028602761 --- /dev/null +++ b/macros/github_enterprise.yml @@ -0,0 +1,4 @@ +definition: sourcetype=github:cloud:audit +description: customer specific splunk configurations(eg- index, source, sourcetype). + Replace the macro definition with configurations for your Splunk Environment. +name: github_enterprise \ No newline at end of file From 7c61973899bd4182de331f92de1951b7eeef260f Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Wed, 15 Jan 2025 10:44:08 +0100 Subject: [PATCH 02/36] bug fix --- detections/cloud/github_template.yml | 55 ---------------------------- 1 file changed, 55 deletions(-) delete mode 100644 detections/cloud/github_template.yml diff --git a/detections/cloud/github_template.yml b/detections/cloud/github_template.yml deleted file mode 100644 index 1ca944b5fd..0000000000 --- a/detections/cloud/github_template.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: GitHub -id: 66d95ea9-c0c5-4aa7-86f2-76e242fcd802 -version: 1 -date: '2025-01-14' -author: Patrick Bareiss, Splunk -status: production -type: Anomaly -description: The following analytic detects -data_source: -- GitHub -search: '`github_enterprise` - | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` - | `github_actions_disable_security_workflow_filter`' -how_to_implement: You must ingest GitHub Enterprise logs using the Splunk Add-on for GitHub https://splunkbase.splunk.com/app/6254 . -known_false_positives: unknown -references: -- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 -drilldown_searches: -- name: View the detection results for - "$user$" - search: '%original_detection_search% | search user = "$user$"' - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -- name: View risk events for the last 7 days for - "$user$" - search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' - earliest_offset: $info_min_time$ - latest_offset: $info_max_time$ -tags: - analytic_story: - - GitHub Malicious Activity - asset_type: GitHub - confidence: 90 - impact: 30 - message: Security Workflow is disabled in branch $branch$ for repository $repository$ - mitre_attack_id: - - T1195.002 - - T1195 - observable: - - name: user - type: User - role: - - Victim - product: - - Splunk Enterprise - - Splunk Enterprise Security - - Splunk Cloud - required_fields: - - user - risk_score: 27 - security_domain: network -tests: -- name: True Positive Test - attack_data: - - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1195.002/github_actions_disable_security_workflow/github_actions_disable_security_workflow.log - source: github - sourcetype: aws:firehose:json From 701a621d3cb17b01b1e9eacba80777616ceb9f34 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Wed, 15 Jan 2025 10:58:13 +0100 Subject: [PATCH 03/36] Deprecated old GItHub detections --- .../github_actions_disable_security_workflow.yml | 6 +++--- .../github_commit_changes_in_master.yml | 6 +++--- .../{cloud => deprecated}/github_commit_in_develop.yml | 6 +++--- .../{cloud => deprecated}/github_dependabot_alert.yml | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) rename detections/{cloud => deprecated}/github_actions_disable_security_workflow.yml (98%) rename detections/{cloud => deprecated}/github_commit_changes_in_master.yml (98%) rename detections/{cloud => deprecated}/github_commit_in_develop.yml (98%) rename detections/{cloud => deprecated}/github_dependabot_alert.yml (98%) diff --git a/detections/cloud/github_actions_disable_security_workflow.yml b/detections/deprecated/github_actions_disable_security_workflow.yml similarity index 98% rename from detections/cloud/github_actions_disable_security_workflow.yml rename to detections/deprecated/github_actions_disable_security_workflow.yml index b5df6c34c6..b0df1c3d63 100644 --- a/detections/cloud/github_actions_disable_security_workflow.yml +++ b/detections/deprecated/github_actions_disable_security_workflow.yml @@ -1,9 +1,9 @@ name: GitHub Actions Disable Security Workflow id: 0459f1a5-c0ac-4987-82d6-65081209f854 -version: 3 -date: '2024-09-30' +version: 4 +date: '2025-01-15' author: Patrick Bareiss, Splunk -status: production +status: deprecated type: Anomaly description: The following analytic detects the disabling of a security workflow in GitHub Actions. It leverages GitHub logs to identify when a workflow, excluding those named *security-testing*, is disabled following a push or pull request event. This activity is significant as it may indicate an attempt by an attacker to conceal malicious code by disabling security checks. If confirmed malicious, this could allow the attacker to introduce and persist undetected malicious code within the repository, potentially compromising the integrity and security of the codebase. data_source: diff --git a/detections/cloud/github_commit_changes_in_master.yml b/detections/deprecated/github_commit_changes_in_master.yml similarity index 98% rename from detections/cloud/github_commit_changes_in_master.yml rename to detections/deprecated/github_commit_changes_in_master.yml index 93a9fb5574..2115a16573 100644 --- a/detections/cloud/github_commit_changes_in_master.yml +++ b/detections/deprecated/github_commit_changes_in_master.yml @@ -1,9 +1,9 @@ name: Github Commit Changes In Master id: c9d2bfe2-019f-11ec-a8eb-acde48001122 -version: 3 -date: '2024-09-30' +version: 4 +date: '2025-01-15' author: Teoderick Contreras, Splunk -status: production +status: deprecated type: Anomaly description: The following analytic detects direct commits or pushes to the master or main branch in a GitHub repository. It leverages GitHub logs to identify events where changes are made directly to these critical branches. This activity is significant because direct modifications to the master or main branch bypass the standard review process, potentially introducing unreviewed and harmful changes. If confirmed malicious, this could lead to unauthorized code execution, security vulnerabilities, or compromised project integrity. data_source: diff --git a/detections/cloud/github_commit_in_develop.yml b/detections/deprecated/github_commit_in_develop.yml similarity index 98% rename from detections/cloud/github_commit_in_develop.yml rename to detections/deprecated/github_commit_in_develop.yml index e0bb7888f2..4493d3d68f 100644 --- a/detections/cloud/github_commit_in_develop.yml +++ b/detections/deprecated/github_commit_in_develop.yml @@ -1,9 +1,9 @@ name: Github Commit In Develop id: f3030cb6-0b02-11ec-8f22-acde48001122 -version: 3 -date: '2024-09-30' +version: 4 +date: '2025-01-15' author: Teoderick Contreras, Splunk -status: production +status: deprecated type: Anomaly description: The following analytic detects commits pushed directly to the 'develop' or 'main' branches in a GitHub repository. It leverages GitHub logs, focusing on commit metadata such as author details, commit messages, and timestamps. This activity is significant as direct commits to these branches can bypass the review process, potentially introducing unvetted changes. If confirmed malicious, this could lead to unauthorized code modifications, introducing vulnerabilities or backdoors into the codebase, and compromising the integrity of the development lifecycle. data_source: diff --git a/detections/cloud/github_dependabot_alert.yml b/detections/deprecated/github_dependabot_alert.yml similarity index 98% rename from detections/cloud/github_dependabot_alert.yml rename to detections/deprecated/github_dependabot_alert.yml index 7d2896bb4f..97eeb5a6fe 100644 --- a/detections/cloud/github_dependabot_alert.yml +++ b/detections/deprecated/github_dependabot_alert.yml @@ -1,9 +1,9 @@ name: GitHub Dependabot Alert id: 05032b04-4469-4034-9df7-05f607d75cba -version: 3 -date: '2024-09-30' +version: 4 +date: '2025-01-15' author: Patrick Bareiss, Splunk -status: production +status: deprecated type: Anomaly description: The following analytic identifies the creation of GitHub Dependabot alerts, which indicate potential vulnerabilities in the codebase. It detects this activity by searching for logs with the "create" action and analyzing fields such as affected package, severity, and fixed version. This detection is significant for a SOC because it helps identify and address security risks in the codebase proactively. If confirmed malicious, these vulnerabilities could be exploited by attackers to gain unauthorized access or cause breaches, leading to potential data loss or system compromise. data_source: From b7298867d33891b6d6d98d31e63d14647fc7bf75 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Wed, 15 Jan 2025 11:01:38 +0100 Subject: [PATCH 04/36] Deprecated old GItHub detections --- .../github_pull_request_from_unknown_user.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename detections/{cloud => deprecated}/github_pull_request_from_unknown_user.yml (98%) diff --git a/detections/cloud/github_pull_request_from_unknown_user.yml b/detections/deprecated/github_pull_request_from_unknown_user.yml similarity index 98% rename from detections/cloud/github_pull_request_from_unknown_user.yml rename to detections/deprecated/github_pull_request_from_unknown_user.yml index 20f76460f5..de613b0a82 100644 --- a/detections/cloud/github_pull_request_from_unknown_user.yml +++ b/detections/deprecated/github_pull_request_from_unknown_user.yml @@ -1,9 +1,9 @@ name: GitHub Pull Request from Unknown User id: 9d7b9100-8878-4404-914e-ca5e551a641e -version: 3 -date: '2024-09-30' +version: 4 +date: '2025-01-15' author: Patrick Bareiss, Splunk -status: production +status: deprecated type: Anomaly description: The following analytic detects pull requests from unknown users on GitHub. It uses a Splunk query to identify pull requests where the user ID is not specified and cross-references these with a known users lookup table. This activity is significant because pull requests from unknown users can introduce malicious code or unauthorized changes to repositories. If confirmed malicious, this could lead to unauthorized code changes, data breaches, or other security incidents. Immediate steps include reviewing the author's name, repository, head reference, and commit message, and investigating any related artifacts and processes. data_source: From 2018be89476749f0947b4b2d4983f61e57d31820 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Wed, 15 Jan 2025 11:07:35 +0100 Subject: [PATCH 05/36] bug fix --- detections/cloud/github_disable_dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/cloud/github_disable_dependabot.yml b/detections/cloud/github_disable_dependabot.yml index c671aeba8b..3fcc9d9389 100644 --- a/detections/cloud/github_disable_dependabot.yml +++ b/detections/cloud/github_disable_dependabot.yml @@ -16,7 +16,7 @@ data_source: - GitHub search: '`github_enterprise` action=repository_vulnerability_alerts.disable OR vendor_action=repository_vulnerability_alerts.disable | fillnull - | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user, user_agent, user_id, src, action, vendor_action + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user, user_agent, user_id, action, vendor_action | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `github_disable_dependabot_filter`' how_to_implement: You must ingest GitHub Enterprise logs using the Splunk Add-on for GitHub https://splunkbase.splunk.com/app/6254 . From a31b2d4ee11c5420da6396e03b01d7499c043015 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Wed, 15 Jan 2025 11:39:58 +0100 Subject: [PATCH 06/36] Improve detection --- detections/cloud/github_disable_dependabot.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/detections/cloud/github_disable_dependabot.yml b/detections/cloud/github_disable_dependabot.yml index 3fcc9d9389..5b27123ed5 100644 --- a/detections/cloud/github_disable_dependabot.yml +++ b/detections/cloud/github_disable_dependabot.yml @@ -14,15 +14,16 @@ description: The following analytic detects when a user disables Dependabot secu remain unpatched, potentially leading to code execution, data theft, or other compromises through the software supply chain. data_source: - GitHub -search: '`github_enterprise` action=repository_vulnerability_alerts.disable OR vendor_action=repository_vulnerability_alerts.disable +search: '`github_enterprise` action=repository_vulnerability_alerts.disable | fillnull - | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user, user_agent, user_id, action, vendor_action + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user, user_agent, user_id, action | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `github_disable_dependabot_filter`' -how_to_implement: You must ingest GitHub Enterprise logs using the Splunk Add-on for GitHub https://splunkbase.splunk.com/app/6254 . +how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk . known_false_positives: unknown references: - https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +- https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk drilldown_searches: - name: View the detection results for - "$user$" search: '%original_detection_search% | search user = "$user$"' @@ -71,5 +72,5 @@ tests: - name: True Positive Test attack_data: - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/disable_dependabot/github.json - source: github - sourcetype: github:cloud:audit + source: http:github + sourcetype: httpevent From e6dae320c3abeadd585e45f420d0d1a9950653fc Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Wed, 15 Jan 2025 11:40:53 +0100 Subject: [PATCH 07/36] github detections --- data_sources/github.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_sources/github.yml b/data_sources/github.yml index 61a065bab2..2d81c6cf0b 100644 --- a/data_sources/github.yml +++ b/data_sources/github.yml @@ -4,8 +4,8 @@ version: 1 date: '2025-01-15' author: Patrick Bareiss, Splunk description: Data source object for GitHub Enterprise logs -source: github -sourcetype: github:cloud:audit +source: http:github +sourcetype: httpevent supported_TA: - name: Splunk Add-on for Github url: https://splunkbase.splunk.com/app/6254 From 2917e241776bf6911d9843fc717be2a11333589b Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Wed, 15 Jan 2025 13:23:49 +0100 Subject: [PATCH 08/36] bug fix --- detections/cloud/github_disable_dependabot.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/detections/cloud/github_disable_dependabot.yml b/detections/cloud/github_disable_dependabot.yml index 5b27123ed5..b4299774c0 100644 --- a/detections/cloud/github_disable_dependabot.yml +++ b/detections/cloud/github_disable_dependabot.yml @@ -74,3 +74,4 @@ tests: - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/disable_dependabot/github.json source: http:github sourcetype: httpevent + From 9d2be764a36b06a52dfd4fe69e4e69f83ef2d807 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Wed, 15 Jan 2025 16:03:42 +0100 Subject: [PATCH 09/36] improvements --- data_sources/{github.yml => github_enterprise_audit_logs.yml} | 2 +- ...ependabot.yml => github_enterprise_disable_dependabot.yml} | 4 ++-- macros/github_enterprise.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename data_sources/{github.yml => github_enterprise_audit_logs.yml} (97%) rename detections/cloud/{github_disable_dependabot.yml => github_enterprise_disable_dependabot.yml} (97%) diff --git a/data_sources/github.yml b/data_sources/github_enterprise_audit_logs.yml similarity index 97% rename from data_sources/github.yml rename to data_sources/github_enterprise_audit_logs.yml index 2d81c6cf0b..73532034df 100644 --- a/data_sources/github.yml +++ b/data_sources/github_enterprise_audit_logs.yml @@ -1,4 +1,4 @@ -name: GitHub +name: GitHub Enterprise Audit Logs id: 8a4d656f-8801-4a2c-ae10-553d2696a59f version: 1 date: '2025-01-15' diff --git a/detections/cloud/github_disable_dependabot.yml b/detections/cloud/github_enterprise_disable_dependabot.yml similarity index 97% rename from detections/cloud/github_disable_dependabot.yml rename to detections/cloud/github_enterprise_disable_dependabot.yml index b4299774c0..b7f4745a20 100644 --- a/detections/cloud/github_disable_dependabot.yml +++ b/detections/cloud/github_enterprise_disable_dependabot.yml @@ -1,4 +1,4 @@ -name: GitHub Disable Dependabot +name: GitHub Enterprise Disable Dependabot id: 787dd1c1-eb3a-4a31-8e8c-2ad24b214bc8 version: 1 date: '2025-01-14' @@ -19,7 +19,7 @@ search: '`github_enterprise` action=repository_vulnerability_alerts.disable | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user, user_agent, user_id, action | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `github_disable_dependabot_filter`' -how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk . +how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. known_false_positives: unknown references: - https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 diff --git a/macros/github_enterprise.yml b/macros/github_enterprise.yml index 5028602761..b605cd7870 100644 --- a/macros/github_enterprise.yml +++ b/macros/github_enterprise.yml @@ -1,4 +1,4 @@ -definition: sourcetype=github:cloud:audit +definition: source=http:github sourcetype=httpevent description: customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environment. name: github_enterprise \ No newline at end of file From 5530d76d68b377c57d15addd4822ab0491d53fb6 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Wed, 15 Jan 2025 16:10:20 +0100 Subject: [PATCH 10/36] improvements --- detections/cloud/github_enterprise_disable_dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/cloud/github_enterprise_disable_dependabot.yml b/detections/cloud/github_enterprise_disable_dependabot.yml index b7f4745a20..5a7a8d89eb 100644 --- a/detections/cloud/github_enterprise_disable_dependabot.yml +++ b/detections/cloud/github_enterprise_disable_dependabot.yml @@ -18,7 +18,7 @@ search: '`github_enterprise` action=repository_vulnerability_alerts.disable | fillnull | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user, user_agent, user_id, action | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` - | `github_disable_dependabot_filter`' + | `github_enterprise_disable_dependabot_filter`' how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. known_false_positives: unknown references: From 616f10df02ae8b45bc34f853fd86920cfc5efcdf Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Wed, 15 Jan 2025 16:29:22 +0100 Subject: [PATCH 11/36] change dataset name --- detections/cloud/github_enterprise_disable_dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/cloud/github_enterprise_disable_dependabot.yml b/detections/cloud/github_enterprise_disable_dependabot.yml index 5a7a8d89eb..58a9916bd1 100644 --- a/detections/cloud/github_enterprise_disable_dependabot.yml +++ b/detections/cloud/github_enterprise_disable_dependabot.yml @@ -71,7 +71,7 @@ tags: tests: - name: True Positive Test attack_data: - - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/disable_dependabot/github.json + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/disable_dependabot/github_enterprise.json source: http:github sourcetype: httpevent From 75549d2e89fb8d000828b5a4e3b174e5887e36f3 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Wed, 15 Jan 2025 16:34:58 +0100 Subject: [PATCH 12/36] change dataset name --- detections/cloud/github_enterprise_disable_dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/cloud/github_enterprise_disable_dependabot.yml b/detections/cloud/github_enterprise_disable_dependabot.yml index 58a9916bd1..5a7a8d89eb 100644 --- a/detections/cloud/github_enterprise_disable_dependabot.yml +++ b/detections/cloud/github_enterprise_disable_dependabot.yml @@ -71,7 +71,7 @@ tags: tests: - name: True Positive Test attack_data: - - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/disable_dependabot/github_enterprise.json + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/disable_dependabot/github.json source: http:github sourcetype: httpevent From 8ed3d573f5582107873e4671d2394a86e6c5c192 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Thu, 16 Jan 2025 10:36:09 +0100 Subject: [PATCH 13/36] new github detections --- data_sources/github_enterprise_audit_logs.yml | 2 +- .../github_organizations_audit_logs.yml | 32 ++++++++ .../github_enterprise_disable_dependabot.yml | 2 +- ...ithub_organizations_disable_dependabot.yml | 77 +++++++++++++++++++ macros/github_organizations.yml | 4 + 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 data_sources/github_organizations_audit_logs.yml create mode 100644 detections/cloud/github_organizations_disable_dependabot.yml create mode 100644 macros/github_organizations.yml diff --git a/data_sources/github_enterprise_audit_logs.yml b/data_sources/github_enterprise_audit_logs.yml index 73532034df..f2f2da3187 100644 --- a/data_sources/github_enterprise_audit_logs.yml +++ b/data_sources/github_enterprise_audit_logs.yml @@ -3,7 +3,7 @@ id: 8a4d656f-8801-4a2c-ae10-553d2696a59f version: 1 date: '2025-01-15' author: Patrick Bareiss, Splunk -description: Data source object for GitHub Enterprise logs +description: Data source object for GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. source: http:github sourcetype: httpevent supported_TA: diff --git a/data_sources/github_organizations_audit_logs.yml b/data_sources/github_organizations_audit_logs.yml new file mode 100644 index 0000000000..faa3002557 --- /dev/null +++ b/data_sources/github_organizations_audit_logs.yml @@ -0,0 +1,32 @@ +name: GitHub Organizations Audit Logs +id: ce520b1c-79fe-48ef-a0f9-71fbbd4837b0 +version: 1 +date: '2025-01-15' +author: Patrick Bareiss, Splunk +description: Data source object for GitHub Organizations logs using the Splunk Add-on for Github using a Personal Access Token. +source: github +sourcetype: github:cloud:audit +supported_TA: +- name: Splunk Add-on for Github + url: https://splunkbase.splunk.com/app/6254 + version: 3.1.0 +fields: +- _document_id +- action +- actor +- actor_id +- actor_is_bot +- business +- business_id +- created_at +- operation_type +- org +- org_id +- public_repo +- repo +- repo_id +- request_access_security_header +- user +- user_agent +- user_id +example_log: '{ @timestamp: 1736850926658 _document_id: fHPRFHOMZNXLxTZrk1w2IQ action: repository_vulnerability_alerts.disable actor: P4T12ICK actor_id: 8362376 actor_ip: 84.128.62.13 actor_is_bot: false actor_location: { [+] } business: pb business_id: 273781 created_at: 1736850926658 operation_type: modify org: pbtest2 org_id: 194489467 public_repo: false repo: pbtest2/pbtest5 repo_id: 916529548 request_access_security_header: null user: P4T12ICK user_agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 user_id: 8362376 }' \ No newline at end of file diff --git a/detections/cloud/github_enterprise_disable_dependabot.yml b/detections/cloud/github_enterprise_disable_dependabot.yml index 5a7a8d89eb..b91556d7d7 100644 --- a/detections/cloud/github_enterprise_disable_dependabot.yml +++ b/detections/cloud/github_enterprise_disable_dependabot.yml @@ -13,7 +13,7 @@ description: The following analytic detects when a user disables Dependabot secu be a precursor to supply chain attacks where attackers exploit vulnerable dependencies. The impact could be severe if vulnerabilities remain unpatched, potentially leading to code execution, data theft, or other compromises through the software supply chain. data_source: -- GitHub +- GitHub Enterprise Audit Logs search: '`github_enterprise` action=repository_vulnerability_alerts.disable | fillnull | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user, user_agent, user_id, action diff --git a/detections/cloud/github_organizations_disable_dependabot.yml b/detections/cloud/github_organizations_disable_dependabot.yml new file mode 100644 index 0000000000..5bcc3d1e7a --- /dev/null +++ b/detections/cloud/github_organizations_disable_dependabot.yml @@ -0,0 +1,77 @@ +name: GitHub Organizations Disable Dependabot +id: 69078d8c-0de6-45de-bb00-14e78e042fd6 +version: 1 +date: '2025-01-14' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when a user disables Dependabot security features within a GitHub repository. + Dependabot helps automatically identify and fix security vulnerabilities in dependencies. The detection monitors GitHub + Enterprise logs for configuration changes that disable Dependabot functionality. This behavior could indicate an attacker + attempting to prevent the automatic detection of vulnerable dependencies, which would allow them to exploit known vulnerabilities + that would otherwise be patched. For a SOC, identifying the disabling of security features like Dependabot is critical as it may + be a precursor to supply chain attacks where attackers exploit vulnerable dependencies. The impact could be severe if vulnerabilities + remain unpatched, potentially leading to code execution, data theft, or other compromises through the software supply chain. +data_source: +- GitHub Organizations Audit Logs +search: '`github_organizations` vendor_action=repository_vulnerability_alerts.disable + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user, user_agent, user_id, vendor_action + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_organizations_disable_dependabot_filter`' +how_to_implement: You must ingest GitHub Organizations logs using Splunk Add-on for Github using a Personal Access Token https://docs.splunk.com/Documentation/AddOns/released/GitHub/Configureinputs . +known_false_positives: unknown +references: +- https://docs.splunk.com/Documentation/AddOns/released/GitHub/Configureinputs +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: Dependabot security features are disabled in repository $repo$ by $user$ + mitre_attack_id: + - T1562.001 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_ip + - actor_is_bot + - actor_location.country_code + - business + - business_id + - org + - org_id + - repo + - repo_id + - user + - user_agent + - user_id + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/disable_dependabot/github.json + source: http:github + sourcetype: httpevent + diff --git a/macros/github_organizations.yml b/macros/github_organizations.yml new file mode 100644 index 0000000000..bf5087b23f --- /dev/null +++ b/macros/github_organizations.yml @@ -0,0 +1,4 @@ +definition: sourcetype=github:cloud:audit +description: customer specific splunk configurations(eg- index, source, sourcetype). + Replace the macro definition with configurations for your Splunk Environment. +name: github_organizations \ No newline at end of file From d2114c216739b5dad67e3863e556349c036c0cae Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Thu, 16 Jan 2025 10:54:17 +0100 Subject: [PATCH 14/36] bug fix --- detections/cloud/github_organizations_disable_dependabot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/detections/cloud/github_organizations_disable_dependabot.yml b/detections/cloud/github_organizations_disable_dependabot.yml index 5bcc3d1e7a..7dd1bfe44e 100644 --- a/detections/cloud/github_organizations_disable_dependabot.yml +++ b/detections/cloud/github_organizations_disable_dependabot.yml @@ -72,6 +72,6 @@ tests: - name: True Positive Test attack_data: - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/disable_dependabot/github.json - source: http:github - sourcetype: httpevent + source: github + sourcetype: github:cloud:audit From 55aefb3c60a2d5c09b21ed69d1d05571490cc7a1 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Thu, 16 Jan 2025 15:35:48 +0100 Subject: [PATCH 15/36] new github detections --- contentctl.yml | 6 ++ ...erprise_disable_audit_log_event_stream.yml | 73 ++++++++++++++++++ ...terprise_modify_audit_log_event_stream.yml | 73 ++++++++++++++++++ ...nterprise_pause_audit_log_event_stream.yml | 74 +++++++++++++++++++ 4 files changed, 226 insertions(+) create mode 100644 detections/cloud/github_enterprise_disable_audit_log_event_stream.yml create mode 100644 detections/cloud/github_enterprise_modify_audit_log_event_stream.yml create mode 100644 detections/cloud/github_enterprise_pause_audit_log_event_stream.yml diff --git a/contentctl.yml b/contentctl.yml index 1608f85298..d53e89eb22 100644 --- a/contentctl.yml +++ b/contentctl.yml @@ -206,4 +206,10 @@ apps: version: 4.2.2 description: PSC for MLTK hardcoded_path: https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/python-for-scientific-computing-for-linux-64-bit_422.tgz +- uid: 6254 + title: Splunk Add-on for Github + appid: Splunk_TA_github + version: 3.1.0 + description: description of app + hardcoded_path: https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/splunk-add-on-for-github_310.tgz githash: d6fac80e6d50ae06b40f91519a98489d4ce3a3fd diff --git a/detections/cloud/github_enterprise_disable_audit_log_event_stream.yml b/detections/cloud/github_enterprise_disable_audit_log_event_stream.yml new file mode 100644 index 0000000000..51d8439c61 --- /dev/null +++ b/detections/cloud/github_enterprise_disable_audit_log_event_stream.yml @@ -0,0 +1,73 @@ +name: GitHub Enterprise Disable Audit Log Event Stream +id: 7bc111cc-7f1b-4be7-99fa-50cf8d2e7564 +version: 1 +date: '2025-01-16' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when a user disables audit log event streaming in GitHub Enterprise. + The detection monitors GitHub Enterprise audit logs for configuration changes that disable the audit log streaming functionality, + which is used to send audit events to security monitoring platforms. This behavior could indicate an attacker attempting to prevent + their malicious activities from being logged and detected by disabling the audit trail. For a SOC, identifying the disabling of + audit logging is critical as it may be a precursor to other attacks where adversaries want to operate undetected. The impact could + be severe as organizations lose visibility into user actions, configuration changes, and security events within their + GitHub Enterprise environment, potentially allowing attackers to perform malicious activities without detection. + This creates a significant blind spot in security monitoring and incident response capabilities. +data_source: +- GitHub Enterprise Audit Logs +search: '`github_enterprise` action=audit_log_streaming.destroy + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, user_agent, action + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_enterprise_disable_audit_log_event_stream_filter`' +how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. +known_false_positives: unknown +references: +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +- https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: Audit log event streaming is disabled by $user$ + mitre_attack_id: + - T1562.008 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_ip + - actor_is_bot + - actor_location.country_code + - business + - business_id + - user_agent + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.008/github_audit_log_stream_disabled/github.json + source: http:github + sourcetype: httpevent + diff --git a/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml b/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml new file mode 100644 index 0000000000..ee9cc157e1 --- /dev/null +++ b/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml @@ -0,0 +1,73 @@ +name: GitHub Enterprise Modify Audit Log Event Stream +id: 99abf2e1-863c-4ec6-82f8-714391590a4c +version: 1 +date: '2025-01-16' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when a user modifies or disables audit log event streaming in GitHub Enterprise. + The detection monitors GitHub Enterprise audit logs for configuration changes that affect the audit log streaming functionality, + which is used to send audit events to security monitoring platforms. This behavior could indicate an attacker attempting to + prevent their malicious activities from being logged and detected by tampering with the audit trail. For a SOC, identifying + modifications to audit logging is critical as it may be a precursor to other attacks where adversaries want to operate undetected. + The impact could be severe as organizations lose visibility into user actions, configuration changes, and security events within + their GitHub Enterprise environment, potentially allowing attackers to perform malicious activities without detection. + This creates a significant blind spot in security monitoring and incident response capabilities. +data_source: +- GitHub Enterprise Audit Logs +search: '`github_enterprise` action=audit_log_streaming.update + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, user_agent, action + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_enterprise_disable_audit_log_event_stream_filter`' +how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. +known_false_positives: unknown +references: +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +- https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: Audit log event streaming is modified by $user$ + mitre_attack_id: + - T1562.008 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_ip + - actor_is_bot + - actor_location.country_code + - business + - business_id + - user_agent + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.008/github_audit_log_stream_modified/github.json + source: http:github + sourcetype: httpevent + diff --git a/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml b/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml new file mode 100644 index 0000000000..b3f90d74b3 --- /dev/null +++ b/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml @@ -0,0 +1,74 @@ +name: GitHub Enterprise Pause Audit Log Event Stream +id: 99abf2e1-863c-4ec6-82f8-714391590a4c +version: 1 +date: '2025-01-16' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when a user pauses audit log event streaming in GitHub Enterprise. + The detection monitors GitHub Enterprise audit logs for configuration changes that temporarily suspend the audit log streaming functionality, + which is used to send audit events to security monitoring platforms. This behavior could indicate an attacker attempting to prevent their + malicious activities from being logged and detected by temporarily disabling the audit trail. For a SOC, identifying the pausing of audit logging + is critical as it may be a precursor to other attacks where adversaries want to operate undetected during the pause window. The impact could be + severe as organizations temporarily lose visibility into user actions, configuration changes, and security events within their GitHub Enterprise + environment, potentially allowing attackers to perform malicious activities without detection during the pause period. + This creates a temporary blind spot in security monitoring and incident response capabilities. +data_source: +- GitHub Enterprise Audit Logs +search: '`github_enterprise` action=audit_log_streaming.update reason="User initiated pause" + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, user_agent, action, reason + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_enterprise_disable_audit_log_event_stream_filter`' +how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. +known_false_positives: unknown +references: +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +- https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: Audit log event streaming is paused by $user$ + mitre_attack_id: + - T1562.008 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_ip + - actor_is_bot + - actor_location.country_code + - business + - business_id + - user_agent + - reason + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.008/github_audit_log_stream_modified/github.json + source: http:github + sourcetype: httpevent + From ae487630d49cbf0a196c3c7fd52e9f36b451b803 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Thu, 16 Jan 2025 15:37:39 +0100 Subject: [PATCH 16/36] bug fix --- .../cloud/github_enterprise_modify_audit_log_event_stream.yml | 2 +- .../cloud/github_enterprise_pause_audit_log_event_stream.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml b/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml index ee9cc157e1..d659f545ee 100644 --- a/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml +++ b/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml @@ -20,7 +20,7 @@ search: '`github_enterprise` action=audit_log_streaming.update | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, user_agent, action | eval user=actor | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` - | `github_enterprise_disable_audit_log_event_stream_filter`' + | `github_enterprise_modify_audit_log_event_stream_filter`' how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. known_false_positives: unknown references: diff --git a/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml b/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml index b3f90d74b3..1023909ed4 100644 --- a/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml +++ b/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml @@ -20,7 +20,7 @@ search: '`github_enterprise` action=audit_log_streaming.update reason="User init | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, user_agent, action, reason | eval user=actor | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` - | `github_enterprise_disable_audit_log_event_stream_filter`' + | `github_enterprise_pause_audit_log_event_stream_filter`' how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. known_false_positives: unknown references: From f488218d56d24d69d5741872321060f329d48aa2 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Thu, 16 Jan 2025 15:39:18 +0100 Subject: [PATCH 17/36] bug fix --- .../cloud/github_enterprise_pause_audit_log_event_stream.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml b/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml index 1023909ed4..386e50b65f 100644 --- a/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml +++ b/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml @@ -1,5 +1,5 @@ name: GitHub Enterprise Pause Audit Log Event Stream -id: 99abf2e1-863c-4ec6-82f8-714391590a4c +id: 21083dcb-276d-4ef9-8f7e-2113ca5e8094 version: 1 date: '2025-01-16' author: Patrick Bareiss, Splunk From 1e203abed026240087437a4ee45e0bf5a9a43bef Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Thu, 16 Jan 2025 16:19:58 +0100 Subject: [PATCH 18/36] new detections --- .../github_enterprise_remove_organization.yml | 73 ++++++++++++++++++ .../github_enterprise_repository_deleted.yml | 76 +++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 detections/cloud/github_enterprise_remove_organization.yml create mode 100644 detections/cloud/github_enterprise_repository_deleted.yml diff --git a/detections/cloud/github_enterprise_remove_organization.yml b/detections/cloud/github_enterprise_remove_organization.yml new file mode 100644 index 0000000000..de5b5d1dda --- /dev/null +++ b/detections/cloud/github_enterprise_remove_organization.yml @@ -0,0 +1,73 @@ +name: GitHub Enterprise Remove Organization +id: 94cb89aa-aec1-4585-91b1-affcdacf357e +version: 1 +date: '2025-01-16' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when a user removes an organization from GitHub Enterprise. + The detection monitors GitHub Enterprise audit logs for organization deletion events, which could indicate unauthorized removal of critical business resources. + For a SOC, identifying organization removals is crucial as it may signal account compromise, insider threats, or malicious attempts to disrupt business operations + by deleting entire organizational structures. The impact could be severe, potentially resulting in loss of source code, repositories, team structures, access controls, + and other critical organizational assets. This disruption could halt development workflows, cause data loss, and require significant effort to restore from backups + if available. Additionally, unauthorized organization removal could be part of a larger attack campaign aimed at destroying or compromising enterprise assets. +data_source: +- GitHub Enterprise Audit Logs +search: '`github_enterprise` action=business.remove_organization + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, user_agent, action + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_enterprise_remove_organization_filter`' +how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. +known_false_positives: unknown +references: +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +- https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: $user$ removed an organization from GitHub Enterprise + mitre_attack_id: + - T1485 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_ip + - actor_is_bot + - actor_location.country_code + - business + - business_id + - org + - org_id + - user_agent + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1485/github_remove_organization/github.json + source: http:github + sourcetype: httpevent + diff --git a/detections/cloud/github_enterprise_repository_deleted.yml b/detections/cloud/github_enterprise_repository_deleted.yml new file mode 100644 index 0000000000..eed55f25a2 --- /dev/null +++ b/detections/cloud/github_enterprise_repository_deleted.yml @@ -0,0 +1,76 @@ +name: GitHub Enterprise Repository Deleted +id: f709e736-3e6c-492f-b865-bc7696cc24a7 +version: 1 +date: '2025-01-16' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when a user deletes a repository in GitHub Enterprise. + The detection monitors GitHub Enterprise audit logs for repository deletion events, which could indicate unauthorized removal of critical source code and project resources. + For a SOC, identifying repository deletions is crucial as it may signal account compromise, insider threats, or malicious attempts to destroy intellectual property and + disrupt development operations. The impact could be severe, potentially resulting in permanent loss of source code, documentation, project history, and other critical assets + if proper backups are not maintained. Repository deletion could halt development workflows, cause significant business disruption, and require substantial effort to restore + from backups if available. Additionally, unauthorized repository removal could be part of a larger attack campaign aimed at destroying or compromising enterprise assets. +data_source: +- GitHub Enterprise Audit Logs +search: '`github_enterprise` action=repo.destroy + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user_agent, visibility, action + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_enterprise_repository_deleted_filter`' +how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. +known_false_positives: unknown +references: +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +- https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: $user$ deleted a repository in GitHub Enterprise + mitre_attack_id: + - T1485 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_ip + - actor_is_bot + - actor_location.country_code + - business + - business_id + - org + - org_id + - repo + - repo_id + - user_agent + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1485/github_delete_repository/github.json + source: http:github + sourcetype: httpevent + + From feaaae4a32bcb46b723e9ce8887d10980a18bf26 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Thu, 16 Jan 2025 17:01:27 +0100 Subject: [PATCH 19/36] improvements --- .../cloud/github_enterprise_modify_audit_log_event_stream.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml b/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml index d659f545ee..0c33fe5476 100644 --- a/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml +++ b/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml @@ -20,7 +20,7 @@ search: '`github_enterprise` action=audit_log_streaming.update | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, user_agent, action | eval user=actor | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` - | `github_enterprise_modify_audit_log_event_stream_filter`' + | `github_enterprise_modify_audit_log_event_stream_filter` ' how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. known_false_positives: unknown references: From aceab149b8197b1fe473301c683782d46f7e7c91 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Fri, 17 Jan 2025 10:03:05 +0100 Subject: [PATCH 20/36] improvements to github detections --- detections/cloud/github_enterprise_remove_organization.yml | 2 +- detections/cloud/github_enterprise_repository_deleted.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/detections/cloud/github_enterprise_remove_organization.yml b/detections/cloud/github_enterprise_remove_organization.yml index de5b5d1dda..34e65f85af 100644 --- a/detections/cloud/github_enterprise_remove_organization.yml +++ b/detections/cloud/github_enterprise_remove_organization.yml @@ -15,7 +15,7 @@ data_source: - GitHub Enterprise Audit Logs search: '`github_enterprise` action=business.remove_organization | fillnull - | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, user_agent, action + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, user_agent, action | eval user=actor | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `github_enterprise_remove_organization_filter`' diff --git a/detections/cloud/github_enterprise_repository_deleted.yml b/detections/cloud/github_enterprise_repository_deleted.yml index eed55f25a2..e01e9f56eb 100644 --- a/detections/cloud/github_enterprise_repository_deleted.yml +++ b/detections/cloud/github_enterprise_repository_deleted.yml @@ -15,7 +15,7 @@ data_source: - GitHub Enterprise Audit Logs search: '`github_enterprise` action=repo.destroy | fillnull - | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user_agent, visibility, action + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user_agent, visibility, action | eval user=actor | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `github_enterprise_repository_deleted_filter`' From ce6a457bfc2e7fa69f4bd0b37caaacad0552d0cd Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Fri, 17 Jan 2025 10:21:55 +0100 Subject: [PATCH 21/36] new github detections --- .../github_enterprise_remove_organization.yml | 1 - .../github_enterprise_repository_archived.yml | 78 ++++++++++++++++++ .../github_enterprise_repository_deleted.yml | 1 - ...thub_organizations_repository_archived.yml | 79 +++++++++++++++++++ ...ithub_organizations_repository_deleted.yml | 79 +++++++++++++++++++ 5 files changed, 236 insertions(+), 2 deletions(-) create mode 100644 detections/cloud/github_enterprise_repository_archived.yml create mode 100644 detections/cloud/github_organizations_repository_archived.yml create mode 100644 detections/cloud/github_organizations_repository_deleted.yml diff --git a/detections/cloud/github_enterprise_remove_organization.yml b/detections/cloud/github_enterprise_remove_organization.yml index 34e65f85af..9feb1a4afc 100644 --- a/detections/cloud/github_enterprise_remove_organization.yml +++ b/detections/cloud/github_enterprise_remove_organization.yml @@ -54,7 +54,6 @@ tags: required_fields: - actor - actor_id - - actor_ip - actor_is_bot - actor_location.country_code - business diff --git a/detections/cloud/github_enterprise_repository_archived.yml b/detections/cloud/github_enterprise_repository_archived.yml new file mode 100644 index 0000000000..c2e5f6da75 --- /dev/null +++ b/detections/cloud/github_enterprise_repository_archived.yml @@ -0,0 +1,78 @@ +name: GitHub Enterprise Repository Archived +id: 8367cb99-bae1-4748-ae3b-0927bb381424 +version: 1 +date: '2025-01-17' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when a repository is archived in GitHub Enterprise. + The detection monitors GitHub Enterprise audit logs for repository archival events by tracking actor details, + repository information, and associated metadata. For a SOC, identifying repository archival is important as it could + indicate attempts to make critical code inaccessible or preparation for repository deletion. While archiving is a legitimate + feature, unauthorized archival of active repositories could signal account compromise, insider threats, or attempts to disrupt + development operations. The impact of unauthorized repository archival includes loss of active development access, disruption + to workflows and CI/CD pipelines, and potential business delays if critical repositories are affected. Additionally, archived + repositories may be targeted for subsequent deletion, potentially resulting in permanent loss of intellectual property if + proper backups are not maintained. +data_source: +- GitHub Enterprise Audit Logs +search: '`github_enterprise` action=repo.archived + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user_agent, visibility, action + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_enterprise_repository_deleted_filter`' +how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. +known_false_positives: unknown +references: +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +- https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: $user$ archived a repository in GitHub Enterprise + mitre_attack_id: + - T1485 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_is_bot + - actor_location.country_code + - business + - business_id + - org + - org_id + - repo + - repo_id + - user_agent + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1485/github_archived_repository/github.json + source: http:github + sourcetype: httpevent + + diff --git a/detections/cloud/github_enterprise_repository_deleted.yml b/detections/cloud/github_enterprise_repository_deleted.yml index e01e9f56eb..3adcec1f0e 100644 --- a/detections/cloud/github_enterprise_repository_deleted.yml +++ b/detections/cloud/github_enterprise_repository_deleted.yml @@ -54,7 +54,6 @@ tags: required_fields: - actor - actor_id - - actor_ip - actor_is_bot - actor_location.country_code - business diff --git a/detections/cloud/github_organizations_repository_archived.yml b/detections/cloud/github_organizations_repository_archived.yml new file mode 100644 index 0000000000..e557c7efd5 --- /dev/null +++ b/detections/cloud/github_organizations_repository_archived.yml @@ -0,0 +1,79 @@ +name: GitHub Organizations Repository Archived +id: 4f568a0e-896f-4d94-a2f7-fa6d82ab1f77 +version: 1 +date: '2025-01-17' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when a repository is archived in GitHub Organizations. + The detection monitors GitHub Organizations audit logs for repository archival events by tracking actor details, + repository information, and associated metadata. For a SOC, identifying repository archival is important as it could + indicate attempts to make critical code inaccessible or preparation for repository deletion. While archiving is a legitimate + feature, unauthorized archival of active repositories could signal account compromise, insider threats, or attempts to disrupt + development operations. The impact of unauthorized repository archival includes loss of active development access, disruption + to workflows and CI/CD pipelines, and potential business delays if critical repositories are affected. Additionally, archived + repositories may be targeted for subsequent deletion, potentially resulting in permanent loss of intellectual property if + proper backups are not maintained. +data_source: +- GitHub Organizations Audit Logs +search: '`github_organizations` vendor_action=repo.archived + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user_agent, visibility, vendor_action + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_organizations_repository_deleted_filter`' +how_to_implement: You must ingest GitHub Organizations logs using Splunk Add-on for Github using a Personal Access Token https://docs.splunk.com/Documentation/AddOns/released/GitHub/Configureinputs . +known_false_positives: unknown +references: +- https://docs.splunk.com/Documentation/AddOns/released/GitHub/Configureinputs +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: $user$ archived a repository in GitHub Organizations + mitre_attack_id: + - T1485 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_is_bot + - actor_location.country_code + - business + - business_id + - org + - org_id + - repo + - repo_id + - user + - user_agent + - user_id + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1485/github_archived_repository/github.json + source: github + sourcetype: github:cloud:audit + diff --git a/detections/cloud/github_organizations_repository_deleted.yml b/detections/cloud/github_organizations_repository_deleted.yml new file mode 100644 index 0000000000..b1502c663d --- /dev/null +++ b/detections/cloud/github_organizations_repository_deleted.yml @@ -0,0 +1,79 @@ +name: GitHub Organizations Repository Deleted +id: 9ff4ca95-fdae-4eea-9ffa-6d8e1c202a71 +version: 1 +date: '2025-01-17' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic identifies when a repository is deleted within a GitHub organization. + The detection monitors GitHub Organizations audit logs for repository deletion events by tracking actor details, + repository information, and associated metadata. This behavior is concerning for SOC teams as malicious actors may + attempt to delete repositories to destroy source code, intellectual property, or evidence of compromise. Repository + deletion can result in permanent loss of code, documentation, and project history if proper backups are not maintained. + Additionally, unauthorized repository deletion could indicate account compromise, insider threats, or attempts to disrupt + business operations. The impact of a repository deletion attack includes loss of intellectual property, disruption to + development workflows, and potential financial losses from lost work. Early detection of unauthorized repository deletions + allows security teams to investigate potential compromises and restore from backups if needed. +data_source: +- GitHub Organizations Audit Logs +search: '`github_organizations` vendor_action=repo.destroy + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user_agent, visibility, vendor_action + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_organizations_repository_deleted_filter`' +how_to_implement: You must ingest GitHub Organizations logs using Splunk Add-on for Github using a Personal Access Token https://docs.splunk.com/Documentation/AddOns/released/GitHub/Configureinputs . +known_false_positives: unknown +references: +- https://docs.splunk.com/Documentation/AddOns/released/GitHub/Configureinputs +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: $user$ deleted a repository in GitHub Organizations + mitre_attack_id: + - T1485 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_is_bot + - actor_location.country_code + - business + - business_id + - org + - org_id + - repo + - repo_id + - user + - user_agent + - user_id + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1485/github_delete_repository/github.json + source: github + sourcetype: github:cloud:audit + From 5552843b31a1b463837cac92b295c80a16ee5afb Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Fri, 17 Jan 2025 10:24:43 +0100 Subject: [PATCH 22/36] bug fix --- detections/cloud/github_enterprise_repository_archived.yml | 2 +- detections/cloud/github_organizations_repository_archived.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/detections/cloud/github_enterprise_repository_archived.yml b/detections/cloud/github_enterprise_repository_archived.yml index c2e5f6da75..460576f5ff 100644 --- a/detections/cloud/github_enterprise_repository_archived.yml +++ b/detections/cloud/github_enterprise_repository_archived.yml @@ -21,7 +21,7 @@ search: '`github_enterprise` action=repo.archived | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user_agent, visibility, action | eval user=actor | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` - | `github_enterprise_repository_deleted_filter`' + | `github_enterprise_repository_archived_filter`' how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. known_false_positives: unknown references: diff --git a/detections/cloud/github_organizations_repository_archived.yml b/detections/cloud/github_organizations_repository_archived.yml index e557c7efd5..e9758e8735 100644 --- a/detections/cloud/github_organizations_repository_archived.yml +++ b/detections/cloud/github_organizations_repository_archived.yml @@ -21,7 +21,7 @@ search: '`github_organizations` vendor_action=repo.archived | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user_agent, visibility, vendor_action | eval user=actor | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` - | `github_organizations_repository_deleted_filter`' + | `github_organizations_repository_archived_filter`' how_to_implement: You must ingest GitHub Organizations logs using Splunk Add-on for Github using a Personal Access Token https://docs.splunk.com/Documentation/AddOns/released/GitHub/Configureinputs . known_false_positives: unknown references: From c1c45958e3ba0da0492f5d49d115e78831cdacc8 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Fri, 17 Jan 2025 11:23:36 +0100 Subject: [PATCH 23/36] new detections --- ...ithub_enterprise_delete_branch_ruleset.yml | 78 ++++++++++++++++++ ...disable_classic_branch_protection_rule.yml | 78 ++++++++++++++++++ ...ub_organizations_delete_branch_ruleset.yml | 80 +++++++++++++++++++ ...isable_classic_branch_protection_rule..yml | 80 +++++++++++++++++++ 4 files changed, 316 insertions(+) create mode 100644 detections/cloud/github_enterprise_delete_branch_ruleset.yml create mode 100644 detections/cloud/github_enterprise_disable_classic_branch_protection_rule.yml create mode 100644 detections/cloud/github_organizations_delete_branch_ruleset.yml create mode 100644 detections/cloud/github_organizations_disable_classic_branch_protection_rule..yml diff --git a/detections/cloud/github_enterprise_delete_branch_ruleset.yml b/detections/cloud/github_enterprise_delete_branch_ruleset.yml new file mode 100644 index 0000000000..f0d5d00652 --- /dev/null +++ b/detections/cloud/github_enterprise_delete_branch_ruleset.yml @@ -0,0 +1,78 @@ +name: GitHub Enterprise Delete Branch Ruleset +id: 6169ea23-3719-439f-957a-0ea5174b70e2 +version: 1 +date: '2025-01-17' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when branch rules are deleted in GitHub Enterprise. + The detection monitors GitHub Enterprise audit logs for branch rule deletion events by tracking actor details, repository information, + and associated metadata. For a SOC, identifying deleted branch rules is critical as it could indicate attempts to bypass code review requirements + and security controls. Branch deletion rules are essential security controls that enforce code review, prevent force pushes, and maintain code quality. + Disabling these protections could allow malicious actors to directly push unauthorized code changes or backdoors to protected branches. The impact of + disabled branch protection includes potential code tampering, bypass of security reviews, introduction of vulnerabilities or malicious code, and compromise + of software supply chain integrity. This activity could be part of a larger attack chain where an adversary first disables security controls before attempting + to inject malicious code. +data_source: +- GitHub Enterprise Audit Logs +search: '`github_enterprise` action=repository_ruleset.destroy + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user_agent, action, ruleset_name + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_enterprise_delete_branch_ruleset_filter`' +how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. +known_false_positives: unknown +references: +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +- https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: $user$ deleted a branch ruleset in repo $repo$ + mitre_attack_id: + - T1562.001 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_is_bot + - actor_location.country_code + - business + - business_id + - org + - org_id + - repo + - repo_id + - user_agent + - ruleset_name + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/github_delete_branch_ruleset/github.json + source: http:github + sourcetype: httpevent + + diff --git a/detections/cloud/github_enterprise_disable_classic_branch_protection_rule.yml b/detections/cloud/github_enterprise_disable_classic_branch_protection_rule.yml new file mode 100644 index 0000000000..842e563852 --- /dev/null +++ b/detections/cloud/github_enterprise_disable_classic_branch_protection_rule.yml @@ -0,0 +1,78 @@ +name: GitHub Enterprise Disable Classic Branch Protection Rule +id: 372176ba-450c-4abd-9b86-419bb44c1b76 +version: 1 +date: '2025-01-17' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when classic branch protection rules are disabled in GitHub Enterprise. + The detection monitors GitHub Enterprise audit logs for branch protection removal events by tracking actor details, repository information, + and associated metadata. For a SOC, identifying disabled branch protection is critical as it could indicate attempts to bypass code review requirements + and security controls. Branch protection rules are essential security controls that enforce code review, prevent force pushes, and maintain code quality. + Disabling these protections could allow malicious actors to directly push unauthorized code changes or backdoors to protected branches. The impact of + disabled branch protection includes potential code tampering, bypass of security reviews, introduction of vulnerabilities or malicious code, and compromise + of software supply chain integrity. This activity could be part of a larger attack chain where an adversary first disables security controls before attempting + to inject malicious code. +data_source: +- GitHub Enterprise Audit Logs +search: '`github_enterprise` action=protected_branch.destroy + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user_agent, action, name + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_enterprise_disable_classic_branch_protection_rule_filter`' +how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. +known_false_positives: unknown +references: +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +- https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: $user$ disabled a classic branch protection rule in repo $repo$ + mitre_attack_id: + - T1562.001 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_is_bot + - actor_location.country_code + - business + - business_id + - org + - org_id + - repo + - repo_id + - user_agent + - name + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/github_disable_classic_branch_protection/github.json + source: http:github + sourcetype: httpevent + + diff --git a/detections/cloud/github_organizations_delete_branch_ruleset.yml b/detections/cloud/github_organizations_delete_branch_ruleset.yml new file mode 100644 index 0000000000..cfd7fbba77 --- /dev/null +++ b/detections/cloud/github_organizations_delete_branch_ruleset.yml @@ -0,0 +1,80 @@ +name: GitHub Organizations Delete Branch Ruleset +id: 8e454f64-4bd6-45e6-8a94-1b482593d721 +version: 1 +date: '2025-01-17' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when branch rulesets are deleted in GitHub Organizations. + The detection monitors GitHub Organizations audit logs for branch ruleset deletion events by tracking actor details, repository information, + and associated metadata. For a SOC, identifying deleted branch rulesets is critical as it could indicate attempts to bypass code review requirements + and security controls. Branch rulesets are essential security controls that enforce code review, prevent force pushes, and maintain code quality. + Disabling these protections could allow malicious actors to directly push unauthorized code changes or backdoors to protected branches. + The impact of disabled branch protection includes potential code tampering, bypass of security reviews, introduction of vulnerabilities or malicious code, + and compromise of software supply chain integrity. This activity could be part of a larger attack chain where an adversary first disables security controls + before attempting to inject malicious code. +data_source: +- GitHub Organizations Audit Logs +search: '`github_organizations` vendor_action=repository_ruleset.destroy + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user_agent, vendor_action, ruleset_name + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_organizations_delete_branch_ruleset_filter`' +how_to_implement: You must ingest GitHub Organizations logs using Splunk Add-on for Github using a Personal Access Token https://docs.splunk.com/Documentation/AddOns/released/GitHub/Configureinputs . +known_false_positives: unknown +references: +- https://docs.splunk.com/Documentation/AddOns/released/GitHub/Configureinputs +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: $user$ deleted a branch ruleset in repo $repo$ + mitre_attack_id: + - T1562.001 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_ip + - actor_is_bot + - actor_location.country_code + - business + - business_id + - org + - org_id + - repo + - repo_id + - user + - user_agent + - user_id + - name + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/github_delete_branch_ruleset/github.json + source: github + sourcetype: github:cloud:audit + diff --git a/detections/cloud/github_organizations_disable_classic_branch_protection_rule..yml b/detections/cloud/github_organizations_disable_classic_branch_protection_rule..yml new file mode 100644 index 0000000000..d03416df50 --- /dev/null +++ b/detections/cloud/github_organizations_disable_classic_branch_protection_rule..yml @@ -0,0 +1,80 @@ +name: GitHub Organizations Disable Classic Branch Protection Rule +id: 33cffee0-41ee-402e-a238-d37825f2d788 +version: 1 +date: '2025-01-17' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when classic branch protection rules are disabled in GitHub Organizations. + The detection monitors GitHub Organizations audit logs for branch protection removal events by tracking actor details, repository information, + and associated metadata. For a SOC, identifying disabled branch protection is critical as it could indicate attempts to bypass code review requirements + and security controls. Branch protection rules are essential security controls that enforce code review, prevent force pushes, and maintain code quality. + Disabling these protections could allow malicious actors to directly push unauthorized code changes or backdoors to protected branches. + The impact of disabled branch protection includes potential code tampering, bypass of security reviews, introduction of vulnerabilities + or malicious code, and compromise of software supply chain integrity. This activity could be part of a larger attack chain where an adversary + first disables security controls before attempting to inject malicious code. +data_source: +- GitHub Organizations Audit Logs +search: '`github_organizations` vendor_action=protected_branch.destroy + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, repo, repo_id, user_agent, vendor_action, name + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_organizations_disable_classic_branch_protection_rule_filter`' +how_to_implement: You must ingest GitHub Organizations logs using Splunk Add-on for Github using a Personal Access Token https://docs.splunk.com/Documentation/AddOns/released/GitHub/Configureinputs . +known_false_positives: unknown +references: +- https://docs.splunk.com/Documentation/AddOns/released/GitHub/Configureinputs +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: $user$ disabled a classic branch protection rule in repo $repo$ + mitre_attack_id: + - T1562.001 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_ip + - actor_is_bot + - actor_location.country_code + - business + - business_id + - org + - org_id + - repo + - repo_id + - user + - user_agent + - user_id + - name + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/github_disable_classic_branch_protection/github.json + source: github + sourcetype: github:cloud:audit + From bdf5fb6948594fc038379fcaa148ad5a56c9963d Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Fri, 17 Jan 2025 11:26:31 +0100 Subject: [PATCH 24/36] bug fix --- ...thub_organizations_disable_classic_branch_protection_rule.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename detections/cloud/{github_organizations_disable_classic_branch_protection_rule..yml => github_organizations_disable_classic_branch_protection_rule.yml} (100%) diff --git a/detections/cloud/github_organizations_disable_classic_branch_protection_rule..yml b/detections/cloud/github_organizations_disable_classic_branch_protection_rule.yml similarity index 100% rename from detections/cloud/github_organizations_disable_classic_branch_protection_rule..yml rename to detections/cloud/github_organizations_disable_classic_branch_protection_rule.yml From 647f8043f7b458d81eab4aa05b90b532072b18a6 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Fri, 17 Jan 2025 12:07:23 +0100 Subject: [PATCH 25/36] new detection --- ...hub_enterprise_disable_2FA_requirement.yml | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 detections/cloud/github_enterprise_disable_2FA_requirement.yml diff --git a/detections/cloud/github_enterprise_disable_2FA_requirement.yml b/detections/cloud/github_enterprise_disable_2FA_requirement.yml new file mode 100644 index 0000000000..dc1ec13ecf --- /dev/null +++ b/detections/cloud/github_enterprise_disable_2FA_requirement.yml @@ -0,0 +1,73 @@ +name: GitHub Enterprise Disable 2FA Requirement +id: 5a773226-ebd7-480c-a819-fccacfeddcd9 +version: 1 +date: '2025-01-17' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when two-factor authentication (2FA) requirements are disabled in GitHub Enterprise. + The detection monitors GitHub Enterprise audit logs for 2FA requirement changes by tracking actor details, organization information, + and associated metadata. For a SOC, identifying disabled 2FA requirements is critical as it could indicate attempts to weaken + account security controls. Two-factor authentication is a fundamental security control that helps prevent unauthorized access even if + passwords are compromised. Disabling 2FA requirements could allow attackers to more easily compromise accounts through password-based attacks. + The impact of disabled 2FA includes increased risk of account takeover, potential access to sensitive code and intellectual property, and + compromise of the software supply chain. This activity could be part of a larger attack chain where an adversary first disables + security controls before attempting broader account compromises. +data_source: +- GitHub Enterprise Audit Logs +search: '`github_enterprise` action=org.disable_two_factor_requirement OR action=business.disable_two_factor_requirement + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_is_bot, actor_location.country_code, business, business_id, user_agent, action + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_enterprise_disable_2FA_requirement_filter`' +how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. +known_false_positives: unknown +references: +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +- https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: $user$ disabled 2FA requirement + mitre_attack_id: + - T1562.001 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_is_bot + - actor_location.country_code + - business + - business_id + - user_agent + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/github_disable_two_factor_requirement/github.json + source: http:github + sourcetype: httpevent + + From 526468af81d806c7e89b0aeced7a04df60d16fc6 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Fri, 17 Jan 2025 12:11:50 +0100 Subject: [PATCH 26/36] new detection --- ..._organizations_disable_2FA_requirement.yml | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 detections/cloud/github_organizations_disable_2FA_requirement.yml diff --git a/detections/cloud/github_organizations_disable_2FA_requirement.yml b/detections/cloud/github_organizations_disable_2FA_requirement.yml new file mode 100644 index 0000000000..9286156438 --- /dev/null +++ b/detections/cloud/github_organizations_disable_2FA_requirement.yml @@ -0,0 +1,75 @@ +name: GitHub Organizations Disable 2FA Requirement +id: 3ed0d6ba-4791-4fa8-a1ef-403e438c7033 +version: 1 +date: '2025-01-17' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic detects when two-factor authentication (2FA) requirements are disabled in GitHub Organizations. + The detection monitors GitHub Organizations audit logs for 2FA requirement changes by tracking actor details, organization information, + and associated metadata. For a SOC, identifying disabled 2FA requirements is critical as it could indicate attempts to weaken account security + controls. Two-factor authentication is a fundamental security control that helps prevent unauthorized access even if passwords are compromised. + Disabling 2FA requirements could allow attackers to more easily compromise accounts through password-based attacks. The impact of disabled 2FA + includes increased risk of account takeover, potential access to sensitive code and intellectual property, and compromise of the software supply chain. + This activity could be part of a larger attack chain where an adversary first disables security controls before attempting broader account compromises. +data_source: +- GitHub Organizations Audit Logs +search: '`github_organizations` vendor_action=org.disable_two_factor_requirement + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, user_agent, vendor_action + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_organizations_disable_2FA_requirement_filter`' +how_to_implement: You must ingest GitHub Organizations logs using Splunk Add-on for Github using a Personal Access Token https://docs.splunk.com/Documentation/AddOns/released/GitHub/Configureinputs . +known_false_positives: unknown +references: +- https://docs.splunk.com/Documentation/AddOns/released/GitHub/Configureinputs +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: $user$ disabled 2FA requirement in GitHub Organizations + mitre_attack_id: + - T1562.001 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_ip + - actor_is_bot + - actor_location.country_code + - business + - business_id + - org + - org_id + - user + - user_agent + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/github_disable_two_factor_requirement/github.json + source: github + sourcetype: github:cloud:audit + From 421b11d7484efe71ceb58605134dd6c77d1c912e Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Fri, 17 Jan 2025 12:13:49 +0100 Subject: [PATCH 27/36] bug fix --- detections/cloud/github_enterprise_disable_2FA_requirement.yml | 2 +- .../cloud/github_organizations_disable_2FA_requirement.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/detections/cloud/github_enterprise_disable_2FA_requirement.yml b/detections/cloud/github_enterprise_disable_2FA_requirement.yml index dc1ec13ecf..85dce6b460 100644 --- a/detections/cloud/github_enterprise_disable_2FA_requirement.yml +++ b/detections/cloud/github_enterprise_disable_2FA_requirement.yml @@ -20,7 +20,7 @@ search: '`github_enterprise` action=org.disable_two_factor_requirement OR action | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_is_bot, actor_location.country_code, business, business_id, user_agent, action | eval user=actor | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` - | `github_enterprise_disable_2FA_requirement_filter`' + | `github_enterprise_disable_2fa_requirement_filter`' how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. known_false_positives: unknown references: diff --git a/detections/cloud/github_organizations_disable_2FA_requirement.yml b/detections/cloud/github_organizations_disable_2FA_requirement.yml index 9286156438..1b9cdf4c3d 100644 --- a/detections/cloud/github_organizations_disable_2FA_requirement.yml +++ b/detections/cloud/github_organizations_disable_2FA_requirement.yml @@ -19,7 +19,7 @@ search: '`github_organizations` vendor_action=org.disable_two_factor_requirement | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_ip, actor_is_bot, actor_location.country_code, business, business_id, org, org_id, user_agent, vendor_action | eval user=actor | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` - | `github_organizations_disable_2FA_requirement_filter`' + | `github_organizations_disable_2fa_requirement_filter`' how_to_implement: You must ingest GitHub Organizations logs using Splunk Add-on for Github using a Personal Access Token https://docs.splunk.com/Documentation/AddOns/released/GitHub/Configureinputs . known_false_positives: unknown references: From c03a2dc0b4474dab909b5c2cfdc15c84ba03051d Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Fri, 17 Jan 2025 13:17:26 +0100 Subject: [PATCH 28/36] rename detection --- detections/cloud/github_enterprise_disable_2FA_requirement.yml | 2 -- .../cloud/github_organizations_disable_2FA_requirement.yml | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/detections/cloud/github_enterprise_disable_2FA_requirement.yml b/detections/cloud/github_enterprise_disable_2FA_requirement.yml index 85dce6b460..1030a44b79 100644 --- a/detections/cloud/github_enterprise_disable_2FA_requirement.yml +++ b/detections/cloud/github_enterprise_disable_2FA_requirement.yml @@ -69,5 +69,3 @@ tests: - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/github_disable_two_factor_requirement/github.json source: http:github sourcetype: httpevent - - diff --git a/detections/cloud/github_organizations_disable_2FA_requirement.yml b/detections/cloud/github_organizations_disable_2FA_requirement.yml index 1b9cdf4c3d..de7c509c56 100644 --- a/detections/cloud/github_organizations_disable_2FA_requirement.yml +++ b/detections/cloud/github_organizations_disable_2FA_requirement.yml @@ -73,3 +73,4 @@ tests: source: github sourcetype: github:cloud:audit + From 28d73383bc2ddaac56e64aa33d468405617a3e39 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Fri, 17 Jan 2025 13:19:02 +0100 Subject: [PATCH 29/36] change --- ...irement.yml => github_enterprise_disable_2fa_requirements.yml} | 0 ...ment.yml => github_organizations_disable_2fa_requirements.yml} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename detections/cloud/{github_enterprise_disable_2FA_requirement.yml => github_enterprise_disable_2fa_requirements.yml} (100%) rename detections/cloud/{github_organizations_disable_2FA_requirement.yml => github_organizations_disable_2fa_requirements.yml} (100%) diff --git a/detections/cloud/github_enterprise_disable_2FA_requirement.yml b/detections/cloud/github_enterprise_disable_2fa_requirements.yml similarity index 100% rename from detections/cloud/github_enterprise_disable_2FA_requirement.yml rename to detections/cloud/github_enterprise_disable_2fa_requirements.yml diff --git a/detections/cloud/github_organizations_disable_2FA_requirement.yml b/detections/cloud/github_organizations_disable_2fa_requirements.yml similarity index 100% rename from detections/cloud/github_organizations_disable_2FA_requirement.yml rename to detections/cloud/github_organizations_disable_2fa_requirements.yml From 71efc6ad162a4a0c28ec6bfc8a5a0ebf48592294 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Fri, 17 Jan 2025 13:19:20 +0100 Subject: [PATCH 30/36] change --- ...irements.yml => github_enterprise_disable_2fa_requirement.yml} | 0 ...ments.yml => github_organizations_disable_2fa_requirement.yml} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename detections/cloud/{github_enterprise_disable_2fa_requirements.yml => github_enterprise_disable_2fa_requirement.yml} (100%) rename detections/cloud/{github_organizations_disable_2fa_requirements.yml => github_organizations_disable_2fa_requirement.yml} (100%) diff --git a/detections/cloud/github_enterprise_disable_2fa_requirements.yml b/detections/cloud/github_enterprise_disable_2fa_requirement.yml similarity index 100% rename from detections/cloud/github_enterprise_disable_2fa_requirements.yml rename to detections/cloud/github_enterprise_disable_2fa_requirement.yml diff --git a/detections/cloud/github_organizations_disable_2fa_requirements.yml b/detections/cloud/github_organizations_disable_2fa_requirement.yml similarity index 100% rename from detections/cloud/github_organizations_disable_2fa_requirements.yml rename to detections/cloud/github_organizations_disable_2fa_requirement.yml From 8ef62a239b22196aebe460330df2f5b4e7687083 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Mon, 20 Jan 2025 11:48:11 +0100 Subject: [PATCH 31/36] new detections --- ..._enterprise_created_self_hosted_runner.yml | 72 +++++++++++++++++++ ...thub_enterprise_disabled_ip_allow_list.yml | 72 +++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 detections/cloud/github_enterprise_created_self_hosted_runner.yml create mode 100644 detections/cloud/github_enterprise_disabled_ip_allow_list.yml diff --git a/detections/cloud/github_enterprise_created_self_hosted_runner.yml b/detections/cloud/github_enterprise_created_self_hosted_runner.yml new file mode 100644 index 0000000000..066320e8f1 --- /dev/null +++ b/detections/cloud/github_enterprise_created_self_hosted_runner.yml @@ -0,0 +1,72 @@ +name: GitHub Enterprise Created Self Hosted Runner +id: b27685a2-8826-4123-ab78-2d9d0d419ed0 +version: 1 +date: '2025-01-20' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic identifies when a self-hosted runner is created in GitHub Enterprise. + The detection monitors GitHub Enterprise audit logs for actions related to creating new self-hosted runners at the organization or enterprise level. + his behavior warrants monitoring because self-hosted runners execute workflow jobs on customer-controlled infrastructure, which could be exploited by attackers to + execute malicious code, access sensitive data, or pivot to other systems. While self-hosted runners are a legitimate feature, their creation should be carefully + controlled as compromised runners pose significant security risks. The impact includes potential remote code execution, data exfiltration, and lateral movement + within the environment if a runner is compromised. SOC teams should investigate unexpected runner creation events to verify they are authorized and properly secured, + especially if created by unfamiliar users or in unusual contexts. +data_source: +- GitHub Enterprise Audit Logs +search: '`github_enterprise` action=enterprise.register_self_hosted_runner + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_is_bot, actor_location.country_code, business, business_id, user_agent, action + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_enterprise_disabled_ip_allow_list_filter`' +how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. +known_false_positives: unknown +references: +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +- https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: $user$ created a self-hosted runner in GitHub Enterprise + mitre_attack_id: + - T1562.001 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_is_bot + - actor_location.country_code + - business + - business_id + - user_agent + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/github_created_self_hosted_runner/github.json + source: http:github + sourcetype: httpevent + + diff --git a/detections/cloud/github_enterprise_disabled_ip_allow_list.yml b/detections/cloud/github_enterprise_disabled_ip_allow_list.yml new file mode 100644 index 0000000000..7d953d2833 --- /dev/null +++ b/detections/cloud/github_enterprise_disabled_ip_allow_list.yml @@ -0,0 +1,72 @@ +name: GitHub Enterprise Disable IP Allow List +id: afed020e-edcd-4913-a675-cebedf81d4fb +version: 1 +date: '2025-01-20' +author: Patrick Bareiss, Splunk +status: production +type: Anomaly +description: The following analytic identifies when an IP allow list is disabled in GitHub Enterprise. + The detection monitors GitHub Enterprise audit logs for actions related to disabling IP allow lists at the organization or enterprise level. + This behavior is concerning because IP allow lists are a critical security control that restricts access to GitHub Enterprise resources to only + trusted IP addresses. When disabled, it could indicate an attacker attempting to bypass access controls to gain unauthorized access from untrusted + networks. The impact includes potential exposure of sensitive code repositories and GitHub Enterprise resources to access from any IP address. + SOC teams should investigate such events, especially if they were not pre-approved changes, as they may indicate compromise of admin credentials + or malicious insider activity. +data_source: +- GitHub Enterprise Audit Logs +search: '`github_enterprise` action=ip_allow_list.disable + | fillnull + | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_is_bot, actor_location.country_code, business, business_id, user_agent, user_id, action + | eval user=actor + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | `github_enterprise_disabled_ip_allow_list_filter`' +how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. +known_false_positives: unknown +references: +- https://www.googlecloudcommunity.com/gc/Community-Blog/Monitoring-for-Suspicious-GitHub-Activity-with-Google-Security/ba-p/763610 +- https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk +drilldown_searches: +- name: View the detection results for - "$user$" + search: '%original_detection_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +tags: + analytic_story: + - GitHub Malicious Activity + asset_type: GitHub + confidence: 90 + impact: 30 + message: $user$ disabled an IP allow list in GitHub Enterprise + mitre_attack_id: + - T1562.001 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - actor + - actor_id + - actor_is_bot + - actor_location.country_code + - business + - business_id + - user_agent + risk_score: 27 + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1562.001/github_disable_ip_allow_list/github.json + source: http:github + sourcetype: httpevent + + From 920fc699e51e566394fd8f5be569b07a975b77f0 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Mon, 20 Jan 2025 11:54:12 +0100 Subject: [PATCH 32/36] bug fix --- .../cloud/github_enterprise_created_self_hosted_runner.yml | 2 +- ...low_list.yml => github_enterprise_disable_ip_allow_list.yml} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename detections/cloud/{github_enterprise_disabled_ip_allow_list.yml => github_enterprise_disable_ip_allow_list.yml} (98%) diff --git a/detections/cloud/github_enterprise_created_self_hosted_runner.yml b/detections/cloud/github_enterprise_created_self_hosted_runner.yml index 066320e8f1..963f853d77 100644 --- a/detections/cloud/github_enterprise_created_self_hosted_runner.yml +++ b/detections/cloud/github_enterprise_created_self_hosted_runner.yml @@ -19,7 +19,7 @@ search: '`github_enterprise` action=enterprise.register_self_hosted_runner | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_is_bot, actor_location.country_code, business, business_id, user_agent, action | eval user=actor | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` - | `github_enterprise_disabled_ip_allow_list_filter`' + | `github_enterprise_created_self_hosted_runner_filter`' how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. known_false_positives: unknown references: diff --git a/detections/cloud/github_enterprise_disabled_ip_allow_list.yml b/detections/cloud/github_enterprise_disable_ip_allow_list.yml similarity index 98% rename from detections/cloud/github_enterprise_disabled_ip_allow_list.yml rename to detections/cloud/github_enterprise_disable_ip_allow_list.yml index 7d953d2833..e1b9805edb 100644 --- a/detections/cloud/github_enterprise_disabled_ip_allow_list.yml +++ b/detections/cloud/github_enterprise_disable_ip_allow_list.yml @@ -19,7 +19,7 @@ search: '`github_enterprise` action=ip_allow_list.disable | stats count min(_time) as firstTime max(_time) as lastTime by actor, actor_id, actor_is_bot, actor_location.country_code, business, business_id, user_agent, user_id, action | eval user=actor | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` - | `github_enterprise_disabled_ip_allow_list_filter`' + | `github_enterprise_disable_ip_allow_list_filter`' how_to_implement: You must ingest GitHub Enterprise logs using Audit log streaming as described in this documentation https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#setting-up-streaming-to-splunk using a Splunk HTTP Event Collector. known_false_positives: unknown references: From eead81fa656d3368d39e60c18cdf60af6f4a2e0e Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Thu, 6 Feb 2025 15:52:12 +0100 Subject: [PATCH 33/36] new detection yml schema --- ..._enterprise_created_self_hosted_runner.yml | 24 ++++---------- ...ithub_enterprise_delete_branch_ruleset.yml | 29 ++++------------- ...hub_enterprise_disable_2fa_requirement.yml | 24 ++++---------- ...erprise_disable_audit_log_event_stream.yml | 25 ++++----------- ...disable_classic_branch_protection_rule.yml | 29 ++++------------- .../github_enterprise_disable_dependabot.yml | 31 ++++-------------- ...ithub_enterprise_disable_ip_allow_list.yml | 24 ++++---------- ...terprise_modify_audit_log_event_stream.yml | 25 ++++----------- ...nterprise_pause_audit_log_event_stream.yml | 26 ++++----------- .../github_enterprise_remove_organization.yml | 26 ++++----------- .../github_enterprise_repository_archived.yml | 28 ++++------------ .../github_enterprise_repository_deleted.yml | 28 ++++------------ ...ub_organizations_delete_branch_ruleset.yml | 32 ++++--------------- ..._organizations_disable_2fa_requirement.yml | 28 ++++------------ ...disable_classic_branch_protection_rule.yml | 32 ++++--------------- ...ithub_organizations_disable_dependabot.yml | 31 ++++-------------- ...thub_organizations_repository_archived.yml | 30 ++++------------- ...ithub_organizations_repository_deleted.yml | 30 ++++------------- 18 files changed, 126 insertions(+), 376 deletions(-) diff --git a/detections/cloud/github_enterprise_created_self_hosted_runner.yml b/detections/cloud/github_enterprise_created_self_hosted_runner.yml index 963f853d77..bf4aefc735 100644 --- a/detections/cloud/github_enterprise_created_self_hosted_runner.yml +++ b/detections/cloud/github_enterprise_created_self_hosted_runner.yml @@ -34,33 +34,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: $user$ created a self-hosted runner in GitHub Enterprise + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: $user$ created a self-hosted runner in GitHub Enterprise mitre_attack_id: - T1562.001 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_is_bot - - actor_location.country_code - - business - - business_id - - user_agent - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_enterprise_delete_branch_ruleset.yml b/detections/cloud/github_enterprise_delete_branch_ruleset.yml index f0d5d00652..dd186cc579 100644 --- a/detections/cloud/github_enterprise_delete_branch_ruleset.yml +++ b/detections/cloud/github_enterprise_delete_branch_ruleset.yml @@ -35,38 +35,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: $user$ deleted a branch ruleset in repo $repo$ + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: $user$ deleted a branch ruleset in repo $repo$ mitre_attack_id: - T1562.001 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_is_bot - - actor_location.country_code - - business - - business_id - - org - - org_id - - repo - - repo_id - - user_agent - - ruleset_name - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_enterprise_disable_2fa_requirement.yml b/detections/cloud/github_enterprise_disable_2fa_requirement.yml index 1030a44b79..2295bf2dbb 100644 --- a/detections/cloud/github_enterprise_disable_2fa_requirement.yml +++ b/detections/cloud/github_enterprise_disable_2fa_requirement.yml @@ -35,33 +35,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: $user$ disabled 2FA requirement + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: $user$ disabled 2FA requirement mitre_attack_id: - T1562.001 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_is_bot - - actor_location.country_code - - business - - business_id - - user_agent - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_enterprise_disable_audit_log_event_stream.yml b/detections/cloud/github_enterprise_disable_audit_log_event_stream.yml index 51d8439c61..4489e8c45d 100644 --- a/detections/cloud/github_enterprise_disable_audit_log_event_stream.yml +++ b/detections/cloud/github_enterprise_disable_audit_log_event_stream.yml @@ -35,34 +35,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: Audit log event streaming is disabled by $user$ + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: Audit log event streaming is disabled by $user$ mitre_attack_id: - T1562.008 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_ip - - actor_is_bot - - actor_location.country_code - - business - - business_id - - user_agent - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_enterprise_disable_classic_branch_protection_rule.yml b/detections/cloud/github_enterprise_disable_classic_branch_protection_rule.yml index 842e563852..c048624fa1 100644 --- a/detections/cloud/github_enterprise_disable_classic_branch_protection_rule.yml +++ b/detections/cloud/github_enterprise_disable_classic_branch_protection_rule.yml @@ -35,38 +35,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: $user$ disabled a classic branch protection rule in repo $repo$ + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: $user$ disabled a classic branch protection rule in repo $repo$ mitre_attack_id: - T1562.001 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_is_bot - - actor_location.country_code - - business - - business_id - - org - - org_id - - repo - - repo_id - - user_agent - - name - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_enterprise_disable_dependabot.yml b/detections/cloud/github_enterprise_disable_dependabot.yml index b91556d7d7..5b2196a7a0 100644 --- a/detections/cloud/github_enterprise_disable_dependabot.yml +++ b/detections/cloud/github_enterprise_disable_dependabot.yml @@ -33,40 +33,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: Dependabot security features are disabled in repository $repo$ by $user$ + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: Dependabot security features are disabled in repository $repo$ by $user$ mitre_attack_id: - T1562.001 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_ip - - actor_is_bot - - actor_location.country_code - - business - - business_id - - org - - org_id - - repo - - repo_id - - user - - user_agent - - user_id - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_enterprise_disable_ip_allow_list.yml b/detections/cloud/github_enterprise_disable_ip_allow_list.yml index e1b9805edb..dc60ccfd63 100644 --- a/detections/cloud/github_enterprise_disable_ip_allow_list.yml +++ b/detections/cloud/github_enterprise_disable_ip_allow_list.yml @@ -34,33 +34,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: $user$ disabled an IP allow list in GitHub Enterprise + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: $user$ disabled an IP allow list in GitHub Enterprise mitre_attack_id: - T1562.001 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_is_bot - - actor_location.country_code - - business - - business_id - - user_agent - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml b/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml index 0c33fe5476..f1f55421fa 100644 --- a/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml +++ b/detections/cloud/github_enterprise_modify_audit_log_event_stream.yml @@ -35,34 +35,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: Audit log event streaming is modified by $user$ + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: Audit log event streaming is modified by $user$ mitre_attack_id: - T1562.008 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_ip - - actor_is_bot - - actor_location.country_code - - business - - business_id - - user_agent - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml b/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml index 386e50b65f..f71bac6e2a 100644 --- a/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml +++ b/detections/cloud/github_enterprise_pause_audit_log_event_stream.yml @@ -35,35 +35,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: Audit log event streaming is paused by $user$ + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: Audit log event streaming is paused by $user$ mitre_attack_id: - T1562.008 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_ip - - actor_is_bot - - actor_location.country_code - - business - - business_id - - user_agent - - reason - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_enterprise_remove_organization.yml b/detections/cloud/github_enterprise_remove_organization.yml index 9feb1a4afc..e9f04b22c5 100644 --- a/detections/cloud/github_enterprise_remove_organization.yml +++ b/detections/cloud/github_enterprise_remove_organization.yml @@ -33,35 +33,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: $user$ removed an organization from GitHub Enterprise + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: $user$ removed an organization from GitHub Enterprise mitre_attack_id: - T1485 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_is_bot - - actor_location.country_code - - business - - business_id - - org - - org_id - - user_agent - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_enterprise_repository_archived.yml b/detections/cloud/github_enterprise_repository_archived.yml index 460576f5ff..f4b1f57ed2 100644 --- a/detections/cloud/github_enterprise_repository_archived.yml +++ b/detections/cloud/github_enterprise_repository_archived.yml @@ -36,37 +36,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: $user$ archived a repository in GitHub Enterprise + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: $user$ archived a repository in GitHub Enterprise mitre_attack_id: - T1485 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_is_bot - - actor_location.country_code - - business - - business_id - - org - - org_id - - repo - - repo_id - - user_agent - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_enterprise_repository_deleted.yml b/detections/cloud/github_enterprise_repository_deleted.yml index 3adcec1f0e..d295127aa4 100644 --- a/detections/cloud/github_enterprise_repository_deleted.yml +++ b/detections/cloud/github_enterprise_repository_deleted.yml @@ -33,37 +33,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: $user$ deleted a repository in GitHub Enterprise + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: $user$ deleted a repository in GitHub Enterprise mitre_attack_id: - T1485 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_is_bot - - actor_location.country_code - - business - - business_id - - org - - org_id - - repo - - repo_id - - user_agent - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_organizations_delete_branch_ruleset.yml b/detections/cloud/github_organizations_delete_branch_ruleset.yml index cfd7fbba77..01e4a24064 100644 --- a/detections/cloud/github_organizations_delete_branch_ruleset.yml +++ b/detections/cloud/github_organizations_delete_branch_ruleset.yml @@ -35,41 +35,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: $user$ deleted a branch ruleset in repo $repo$ + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: $user$ deleted a branch ruleset in repo $repo$ mitre_attack_id: - T1562.001 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_ip - - actor_is_bot - - actor_location.country_code - - business - - business_id - - org - - org_id - - repo - - repo_id - - user - - user_agent - - user_id - - name - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_organizations_disable_2fa_requirement.yml b/detections/cloud/github_organizations_disable_2fa_requirement.yml index de7c509c56..a2fcda1822 100644 --- a/detections/cloud/github_organizations_disable_2fa_requirement.yml +++ b/detections/cloud/github_organizations_disable_2fa_requirement.yml @@ -34,37 +34,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: $user$ disabled 2FA requirement in GitHub Organizations + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: $user$ disabled 2FA requirement in GitHub Organizations mitre_attack_id: - T1562.001 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_ip - - actor_is_bot - - actor_location.country_code - - business - - business_id - - org - - org_id - - user - - user_agent - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_organizations_disable_classic_branch_protection_rule.yml b/detections/cloud/github_organizations_disable_classic_branch_protection_rule.yml index d03416df50..0847afd389 100644 --- a/detections/cloud/github_organizations_disable_classic_branch_protection_rule.yml +++ b/detections/cloud/github_organizations_disable_classic_branch_protection_rule.yml @@ -35,41 +35,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: $user$ disabled a classic branch protection rule in repo $repo$ + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: $user$ disabled a classic branch protection rule in repo $repo$ mitre_attack_id: - T1562.001 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_ip - - actor_is_bot - - actor_location.country_code - - business - - business_id - - org - - org_id - - repo - - repo_id - - user - - user_agent - - user_id - - name - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_organizations_disable_dependabot.yml b/detections/cloud/github_organizations_disable_dependabot.yml index 7dd1bfe44e..b222d94020 100644 --- a/detections/cloud/github_organizations_disable_dependabot.yml +++ b/detections/cloud/github_organizations_disable_dependabot.yml @@ -33,40 +33,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: Dependabot security features are disabled in repository $repo$ by $user$ + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: Dependabot security features are disabled in repository $repo$ by $user$ mitre_attack_id: - T1562.001 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_ip - - actor_is_bot - - actor_location.country_code - - business - - business_id - - org - - org_id - - repo - - repo_id - - user - - user_agent - - user_id - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_organizations_repository_archived.yml b/detections/cloud/github_organizations_repository_archived.yml index e9758e8735..143b8274db 100644 --- a/detections/cloud/github_organizations_repository_archived.yml +++ b/detections/cloud/github_organizations_repository_archived.yml @@ -36,39 +36,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: $user$ archived a repository in GitHub Organizations + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: $user$ archived a repository in GitHub Organizations mitre_attack_id: - T1485 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_is_bot - - actor_location.country_code - - business - - business_id - - org - - org_id - - repo - - repo_id - - user - - user_agent - - user_id - risk_score: 27 security_domain: network tests: - name: True Positive Test diff --git a/detections/cloud/github_organizations_repository_deleted.yml b/detections/cloud/github_organizations_repository_deleted.yml index b1502c663d..1074119a3e 100644 --- a/detections/cloud/github_organizations_repository_deleted.yml +++ b/detections/cloud/github_organizations_repository_deleted.yml @@ -36,39 +36,23 @@ drilldown_searches: search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ +rba: + message: $user$ deleted a repository in GitHub Organizations + risk_objects: + - field: user + type: user + score: 25 + threat_objects: [] tags: analytic_story: - GitHub Malicious Activity asset_type: GitHub - confidence: 90 - impact: 30 - message: $user$ deleted a repository in GitHub Organizations mitre_attack_id: - T1485 - observable: - - name: user - type: User - role: - - Victim product: - Splunk Enterprise - Splunk Enterprise Security - Splunk Cloud - required_fields: - - actor - - actor_id - - actor_is_bot - - actor_location.country_code - - business - - business_id - - org - - org_id - - repo - - repo_id - - user - - user_agent - - user_id - risk_score: 27 security_domain: network tests: - name: True Positive Test From dfe5b0a0baa9388b3723d39ce44b1ca2a5b3f7f2 Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Thu, 6 Feb 2025 15:56:30 +0100 Subject: [PATCH 34/36] missing status field --- stories/github_malicious_activity.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/stories/github_malicious_activity.yml b/stories/github_malicious_activity.yml index 780f988652..621fae9d65 100644 --- a/stories/github_malicious_activity.yml +++ b/stories/github_malicious_activity.yml @@ -3,6 +3,7 @@ id: 9abdd884-909d-46a8-bf11-9fbcd076fac2 version: 1 date: '2025-01-14' author: Patrick Bareiss, Splunk +status: production description: Leverage searches that allow you to detect and investigate suspicious GitHub activities that might indicate malicious behavior, including pull requests from unknown users, disabled security workflows, and other potentially harmful repository modifications. These detections help identify From d7171f0d6efd2f766327428389299c81d16627ee Mon Sep 17 00:00:00 2001 From: Patrick Bareiss Date: Thu, 6 Feb 2025 15:59:50 +0100 Subject: [PATCH 35/36] version bump --- .../deprecated/github_actions_disable_security_workflow.yml | 2 +- detections/deprecated/github_commit_changes_in_master.yml | 2 +- detections/deprecated/github_commit_in_develop.yml | 2 +- detections/deprecated/github_dependabot_alert.yml | 2 +- detections/deprecated/github_pull_request_from_unknown_user.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/detections/deprecated/github_actions_disable_security_workflow.yml b/detections/deprecated/github_actions_disable_security_workflow.yml index 44b8612e51..cb6343cdfe 100644 --- a/detections/deprecated/github_actions_disable_security_workflow.yml +++ b/detections/deprecated/github_actions_disable_security_workflow.yml @@ -1,6 +1,6 @@ name: GitHub Actions Disable Security Workflow id: 0459f1a5-c0ac-4987-82d6-65081209f854 -version: 4 +version: 5 date: '2024-11-14' author: Patrick Bareiss, Splunk status: deprecated diff --git a/detections/deprecated/github_commit_changes_in_master.yml b/detections/deprecated/github_commit_changes_in_master.yml index 95b4253e92..7506c8aee4 100644 --- a/detections/deprecated/github_commit_changes_in_master.yml +++ b/detections/deprecated/github_commit_changes_in_master.yml @@ -1,6 +1,6 @@ name: Github Commit Changes In Master id: c9d2bfe2-019f-11ec-a8eb-acde48001122 -version: 4 +version: 5 date: '2024-11-14' author: Teoderick Contreras, Splunk status: deprecated diff --git a/detections/deprecated/github_commit_in_develop.yml b/detections/deprecated/github_commit_in_develop.yml index a7cb32540f..87ec79e318 100644 --- a/detections/deprecated/github_commit_in_develop.yml +++ b/detections/deprecated/github_commit_in_develop.yml @@ -1,6 +1,6 @@ name: Github Commit In Develop id: f3030cb6-0b02-11ec-8f22-acde48001122 -version: 4 +version: 5 date: '2024-11-14' author: Teoderick Contreras, Splunk status: deprecated diff --git a/detections/deprecated/github_dependabot_alert.yml b/detections/deprecated/github_dependabot_alert.yml index 958bbfe3aa..57b8e2904c 100644 --- a/detections/deprecated/github_dependabot_alert.yml +++ b/detections/deprecated/github_dependabot_alert.yml @@ -1,6 +1,6 @@ name: GitHub Dependabot Alert id: 05032b04-4469-4034-9df7-05f607d75cba -version: 4 +version: 5 date: '2024-11-14' author: Patrick Bareiss, Splunk status: deprecated diff --git a/detections/deprecated/github_pull_request_from_unknown_user.yml b/detections/deprecated/github_pull_request_from_unknown_user.yml index f30ac86038..5dc412350a 100644 --- a/detections/deprecated/github_pull_request_from_unknown_user.yml +++ b/detections/deprecated/github_pull_request_from_unknown_user.yml @@ -1,6 +1,6 @@ name: GitHub Pull Request from Unknown User id: 9d7b9100-8878-4404-914e-ca5e551a641e -version: 4 +version: 5 date: '2024-11-14' author: Patrick Bareiss, Splunk status: deprecated From a33eccd84607af2a00926dde08bb19d679ca36af Mon Sep 17 00:00:00 2001 From: Bhavin Patel Date: Tue, 18 Feb 2025 15:34:23 -0800 Subject: [PATCH 36/36] wrong space --- detections/endpoint/bits_job_persistence.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/bits_job_persistence.yml b/detections/endpoint/bits_job_persistence.yml index 458d8f5584..eee12eeb44 100644 --- a/detections/endpoint/bits_job_persistence.yml +++ b/detections/endpoint/bits_job_persistence.yml @@ -66,7 +66,7 @@ rba: type: system score: 56 threat_objects: - - field: parent_process_name + - field: parent_process_name type: parent_process_name - field: process_name type: process_name