Skip to content

Commit

Permalink
Add saved queries for ongoing Snowflake threats (#1248)
Browse files Browse the repository at this point in the history
* Add saved queries for ongoing Snowflake threats

* Add limits

Signed-off-by: egibs <[email protected]>

* snowflake pack

* Add scheduled queries and rules

Signed-off-by: egibs <[email protected]>

* pack update

* ruleID fix

* make fmt

Signed-off-by: egibs <[email protected]>

* Fix merge conflicts

Signed-off-by: egibs <[email protected]>

* Turn off by default

Signed-off-by: egibs <[email protected]>

---------

Signed-off-by: egibs <[email protected]>
Co-authored-by: Ariel Ropek <[email protected]>
  • Loading branch information
egibs and arielkr256 authored May 31, 2024
1 parent f1697c0 commit 791b90d
Show file tree
Hide file tree
Showing 17 changed files with 597 additions and 0 deletions.
41 changes: 41 additions & 0 deletions packs/snowflake.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
AnalysisType: pack
PackID: PantherManaged.Snowflake.Account_Usage
Description: >
Group of all Snowflake account_usage audit log detections and threat hunting queries.
These queries require that Panther's read-only role has access to the snowflake.account_usage audit database
(this may need to be done by the Snowflake admins).
https://docs.panther.com/search/scheduled-searches/examples#database-monitoring-snowflake
DisplayName: "Panther Snowflake Account_Usage Pack"
PackDefinition:
IDs:
# Queries
- Query.Snowflake.AccountAdminGranted
- Query.Snowflake.BruteForceByIp
- Query.Snowflake.BruteForceByUsername
- Query.Snowflake.ClientIp
- Query.Snowflake.ConfigurationDrift
- Query.Snowflake.External.Shares
- Query.Snowflake.KeyUserPasswordLogin
- Query.Snowflake.Multiple.Logins.Followed.By.Success
- Query.Snowflake.SuspectedUserAccess
- Query.Snowflake.SuspectedUserActivity
- Query.Snowflake.UserCreated
- Query.Snowflake.UserEnabled
# Rules
- Snowflake.AccountAdminGranted
- Snowflake.BruteForceByIp
- Snowflake.BruteForceByUsername
- Snowflake.Client.IP
- Snowflake.Configuration.Drift
- Snowflake.External.Shares
- Snowflake.KeyUserPasswordLogin
- Snowflake.Multiple.Failed.Logins.Followed.By.Success
- Snowflake.User.Access
- Snowflake.User.Activity
- Snowflake.UserCreated
- Snowflake.UserEnabled
# Threat Hunting Queries
- Query.Snowflake.ThreatHunting.ConfigurationDrift
- Query.Snowflake.ThreatHunting.ClientIp
- Query.Snowflake.ThreatHunting.SuspectedUserAccess
- Query.Snowflake.ThreatHunting.SuspectedUserActivity
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
def rule(_):
return True


def title(event):
user_name = event.get("user_name", "<NO USERNAME FOUND>")
action = event.get("query_text", "<NO QUERY FOUND>").split(" ")[:2]
target = " ".join(event.get("query_text", "").split(" ")[-2:])
return f"{user_name} performed {action} on {target}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
AnalysisType: scheduled_rule
Filename: snowflake_0108977_configuration_drift.py
RuleID: "Snowflake.Configuration.Drift"
Description: >
Monitor for configuration drift made by malicious actors as part of ongoing cyber threat activity reported May 31st, 2024
DisplayName: "Snowflake Configuration Drift"
Enabled: false
Runbook: Determine if this occurred as a result of a valid business request.
ScheduledQueries:
- Query.Snowflake.ConfigurationDrift
Severity: High
Tests:
- Name: Configuration Drift
ExpectedResult: true
Log:
{
"end_time": "2024-05-31 19:20:08.604Z",
"query_text": "COPY INTO table.name FROM here as test file_format = (type = JSON);",
"role_name": "ADMIN",
"start_time": "2024-05-31 19:20:07.088Z",
"user_name": "USER_NAME",
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
AnalysisType: scheduled_query
Enabled: false
QueryName: "Query.Snowflake.ConfigurationDrift"
Description: >
Monitor for configuration drift made by malicious actors as part of ongoing cyber threat activity reported May 31st, 2024
SnowflakeQuery: >
-- https://community.snowflake.com/s/article/Communication-ID-0108977-Additional-Information
-- adjust query/limit to narrow as necessary
SELECT
query_text,
user_name,
role_name,
start_time,
end_time
FROM snowflake.account_usage.query_history
WHERE execution_status = 'SUCCESS'
AND query_type NOT in ('SELECT')
AND user_name NOT in ('PANTHER_ADMIN', 'PANTHERACCOUNTADMIN')
AND (query_text ILIKE '%create role%'
OR query_text ILIKE '%manage grants%'
OR query_text ILIKE '%create integration%'
OR query_text ILIKE '%alter integration%'
OR query_text ILIKE '%create share%'
OR query_text ILIKE '%create account%'
OR query_text ILIKE '%monitor usage%'
OR query_text ILIKE '%ownership%'
OR query_text ILIKE '%drop table%'
OR query_text ILIKE '%drop database%'
OR query_text ILIKE '%create stage%'
OR query_text ILIKE '%drop stage%'
OR query_text ILIKE '%alter stage%'
OR query_text ILIKE '%create user%'
OR query_text ILIKE '%alter user%'
OR query_text ILIKE '%drop user%'
OR query_text ILIKE '%create_network_policy%'
OR query_text ILIKE '%alter_network_policy%'
OR query_text ILIKE '%drop_network_policy%'
OR query_text ILIKE '%copy%'
)
OR (
query_text ilike '%grant%accountadmin%to%'
AND query_type = 'GRANT'
AND execution_status = 'SUCCESS'
)
ORDER BY end_time desc
LIMIT 100;
Schedule:
RateMinutes: 1440
TimeoutMinutes: 3
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
AnalysisType: saved_query
QueryName: "Query.Snowflake.ThreatHunting.ConfigurationDrift"
Description: >
Monitor for configuration drift made by malicious actors as part of ongoing cyber threat activity reported May 31st, 2024
SnowflakeQuery: >
-- https://community.snowflake.com/s/article/Communication-ID-0108977-Additional-Information
-- adjust query/limit to narrow as necessary
SELECT
query_text,
user_name,
role_name,
start_time,
end_time
FROM snowflake.account_usage.query_history
WHERE execution_status = 'SUCCESS'
AND query_type NOT in ('SELECT')
AND user_name NOT in ('PANTHER_ADMIN', 'PANTHERACCOUNTADMIN')
AND (query_text ILIKE '%create role%'
OR query_text ILIKE '%manage grants%'
OR query_text ILIKE '%create integration%'
OR query_text ILIKE '%alter integration%'
OR query_text ILIKE '%create share%'
OR query_text ILIKE '%create account%'
OR query_text ILIKE '%monitor usage%'
OR query_text ILIKE '%ownership%'
OR query_text ILIKE '%drop table%'
OR query_text ILIKE '%drop database%'
OR query_text ILIKE '%create stage%'
OR query_text ILIKE '%drop stage%'
OR query_text ILIKE '%alter stage%'
OR query_text ILIKE '%create user%'
OR query_text ILIKE '%alter user%'
OR query_text ILIKE '%drop user%'
OR query_text ILIKE '%create_network_policy%'
OR query_text ILIKE '%alter_network_policy%'
OR query_text ILIKE '%drop_network_policy%'
OR query_text ILIKE '%copy%'
)
OR (
query_text ilike '%grant%accountadmin%to%'
AND query_type = 'GRANT'
AND execution_status = 'SUCCESS'
)
ORDER BY end_time desc
LIMIT 100;
8 changes: 8 additions & 0 deletions queries/snowflake_queries/snowflake_0108977_ip.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
def rule(_):
return True


def title(event):
client_ip = event.get("client_ip", "<NO_IP_FOUND>")
user_name = event.get("user_name", "<NO USERNAME FOUND>")
return f"{user_name} accessed Snowflake from {client_ip}"
27 changes: 27 additions & 0 deletions queries/snowflake_queries/snowflake_0108977_ip.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
AnalysisType: scheduled_rule
Filename: snowflake_0108977_ip.py
RuleID: "Snowflake.Client.IP"
Description: >
Monitor for malicious IPs interacting with Snowflake as part of ongoing cyber threat activity reported May 31st, 2024
DisplayName: "Snowflake Client IP"
Enabled: false
Runbook: Determine if this occurred as a result of a valid business request.
ScheduledQueries:
- Query.Snowflake.ClientIp
Severity: High
Tests:
- Name: Client IP Access
ExpectedResult: true
Log:
{
"client_ip": "1.2.3.4",
"event_id": 01234567,
"event_timestamp": "2023-11-08 23:40:08.524Z",
"event_type": "LOGIN",
"first_authentication_factor": "PASSWORD",
"is_success": "YES",
"related_event_id": 0,
"reported_client_type": "OTHER",
"reported_client_version": "1.6.24",
"user_name": "USER_NAME",
}
87 changes: 87 additions & 0 deletions queries/snowflake_queries/snowflake_0108977_ip_query.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
AnalysisType: scheduled_query
Enabled: false
QueryName: "Query.Snowflake.ClientIp"
Description: >
Monitor for malicious IPs interacting with Snowflake as part of ongoing cyber threat activity reported May 31st, 2024
SnowflakeQuery: >
-- https://community.snowflake.com/s/article/Communication-ID-0108977-Additional-Information
SELECT
*
FROM
snowflake.account_usage.login_history
WHERE
client_ip IN (
'104.223.91.28',
'198.54.135.99',
'184.147.100.29',
'146.70.117.210',
'198.54.130.153',
'169.150.203.22',
'185.156.46.163',
'146.70.171.99',
'206.217.206.108',
'45.86.221.146',
'193.32.126.233',
'87.249.134.11',
'66.115.189.247',
'104.129.24.124',
'146.70.171.112',
'198.54.135.67',
'146.70.124.216',
'45.134.142.200',
'206.217.205.49',
'146.70.117.56',
'169.150.201.25',
'66.63.167.147',
'194.230.144.126',
'146.70.165.227',
'154.47.30.137',
'154.47.30.150',
'96.44.191.140',
'146.70.166.176',
'198.44.136.56',
'176.123.6.193',
'192.252.212.60',
'173.44.63.112',
'37.19.210.34',
'37.19.210.21',
'185.213.155.241',
'198.44.136.82',
'93.115.0.49',
'204.152.216.105',
'198.44.129.82',
'185.248.85.59',
'198.54.131.152',
'102.165.16.161',
'185.156.46.144',
'45.134.140.144',
'198.54.135.35',
'176.123.3.132',
'185.248.85.14',
'169.150.223.208',
'162.33.177.32',
'194.230.145.67',
'5.47.87.202',
'194.230.160.5',
'194.230.147.127',
'176.220.186.152',
'194.230.160.237',
'194.230.158.178',
'194.230.145.76',
'45.155.91.99',
'194.230.158.107',
'194.230.148.99',
'194.230.144.50',
'185.204.1.178',
'79.127.217.44',
'104.129.24.115',
'146.70.119.24',
'138.199.34.144'
)
ORDER BY
event_timestamp
LIMIT 100;
Schedule:
RateMinutes: 1440
TimeoutMinutes: 3
83 changes: 83 additions & 0 deletions queries/snowflake_queries/snowflake_0108977_ip_threat_hunting.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
AnalysisType: saved_query
QueryName: "Query.Snowflake.ThreatHunting.ClientIp"
Description: >
Monitor for malicious IPs interacting with Snowflake as part of ongoing cyber threat activity reported May 31st, 2024
SnowflakeQuery: >
-- https://community.snowflake.com/s/article/Communication-ID-0108977-Additional-Information
SELECT
*
FROM
snowflake.account_usage.login_history
WHERE
client_ip IN (
'104.223.91.28',
'198.54.135.99',
'184.147.100.29',
'146.70.117.210',
'198.54.130.153',
'169.150.203.22',
'185.156.46.163',
'146.70.171.99',
'206.217.206.108',
'45.86.221.146',
'193.32.126.233',
'87.249.134.11',
'66.115.189.247',
'104.129.24.124',
'146.70.171.112',
'198.54.135.67',
'146.70.124.216',
'45.134.142.200',
'206.217.205.49',
'146.70.117.56',
'169.150.201.25',
'66.63.167.147',
'194.230.144.126',
'146.70.165.227',
'154.47.30.137',
'154.47.30.150',
'96.44.191.140',
'146.70.166.176',
'198.44.136.56',
'176.123.6.193',
'192.252.212.60',
'173.44.63.112',
'37.19.210.34',
'37.19.210.21',
'185.213.155.241',
'198.44.136.82',
'93.115.0.49',
'204.152.216.105',
'198.44.129.82',
'185.248.85.59',
'198.54.131.152',
'102.165.16.161',
'185.156.46.144',
'45.134.140.144',
'198.54.135.35',
'176.123.3.132',
'185.248.85.14',
'169.150.223.208',
'162.33.177.32',
'194.230.145.67',
'5.47.87.202',
'194.230.160.5',
'194.230.147.127',
'176.220.186.152',
'194.230.160.237',
'194.230.158.178',
'194.230.145.76',
'45.155.91.99',
'194.230.158.107',
'194.230.148.99',
'194.230.144.50',
'185.204.1.178',
'79.127.217.44',
'104.129.24.115',
'146.70.119.24',
'138.199.34.144'
)
ORDER BY
event_timestamp
LIMIT 100;
Loading

0 comments on commit 791b90d

Please sign in to comment.