Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ deployment.yaml
# Held by make proof and the daemon updater while either has the stack down.
.dfe-stack.lock
*.log
# The demo replays these sample events as syslog
# The demo and its packs replay these sample events
!resources/demo/events/**/*.log
!resources/demo-*/events/**/*.log
dist/
dist-bin/
bin/
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -629,8 +629,8 @@ print-ruff-version:

.PHONY: check-python
check-python: ## Lint the helper scripts (config in ruff.toml)
$(RUFF) check scripts/ ops/ resources/demo/
$(RUFF) format --check scripts/ ops/ resources/demo/
$(RUFF) check scripts/ ops/ resources/demo/ resources/demo-*/
$(RUFF) format --check scripts/ ops/ resources/demo/ resources/demo-*/

# Pinned for the same reason RUFF is, and installed the same way in CI
# (PYTEST=pytest). Unit tests over the helper scripts: they
Expand Down
64 changes: 64 additions & 0 deletions resources/demo-cyber/console/dashboards/demo-cyber-denied.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"name": "demo-cyber-denied",
"tags": [
"demo"
],
"tiles": [
{
"config": {
"configType": "sql",
"displayType": "stacked_bar",
"name": "Denied connections per minute, by firewall",
"source": "cisco-asa",
"sqlTemplate": "SELECT $__timeInterval(t) AS ts,\n firewall,\n count() * 60 / $__interval_s AS \"denied/min\"\nFROM (SELECT _timestamp_load AS t, 'Cisco ASA' AS firewall, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, if(coalesce(cisco_asa_rule_name, '') = '', concat('ASA ', coalesce(event_code, '')), cisco_asa_rule_name) AS rule\n FROM dfe.`cisco-asa`\n WHERE $__timeFilter(_timestamp_load) AND event_outcome = 'failure' AND event_action != 'logon-failed'\n UNION ALL\n SELECT _timestamp_load AS t, 'FortiGate' AS firewall, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, concat('policy ', toString(rule_id)) AS rule\n FROM dfe.fortinet\n WHERE $__timeFilter(_timestamp_load) AND event_action = 'deny')\nGROUP BY ts, firewall\nORDER BY ts"
},
"h": 6,
"id": "rate",
"w": 16,
"x": 0,
"y": 0
},
{
"config": {
"configType": "sql",
"displayType": "number",
"name": "Denied connections in the time range",
"source": "cisco-asa",
"sqlTemplate": "SELECT count() AS \"denied\"\nFROM (SELECT _timestamp_load AS t, 'Cisco ASA' AS firewall, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, if(coalesce(cisco_asa_rule_name, '') = '', concat('ASA ', coalesce(event_code, '')), cisco_asa_rule_name) AS rule\n FROM dfe.`cisco-asa`\n WHERE $__timeFilter(_timestamp_load) AND event_outcome = 'failure' AND event_action != 'logon-failed'\n UNION ALL\n SELECT _timestamp_load AS t, 'FortiGate' AS firewall, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, concat('policy ', toString(rule_id)) AS rule\n FROM dfe.fortinet\n WHERE $__timeFilter(_timestamp_load) AND event_action = 'deny')"
},
"h": 6,
"id": "total",
"w": 8,
"x": 16,
"y": 0
},
{
"config": {
"configType": "sql",
"displayType": "table",
"name": "Top denied sources",
"source": "cisco-asa",
"sqlTemplate": "SELECT firewall AS \"Firewall\",\n src AS \"Source\",\n rule AS \"Rule\",\n count() AS \"Denied\"\nFROM (SELECT _timestamp_load AS t, 'Cisco ASA' AS firewall, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, if(coalesce(cisco_asa_rule_name, '') = '', concat('ASA ', coalesce(event_code, '')), cisco_asa_rule_name) AS rule\n FROM dfe.`cisco-asa`\n WHERE $__timeFilter(_timestamp_load) AND event_outcome = 'failure' AND event_action != 'logon-failed'\n UNION ALL\n SELECT _timestamp_load AS t, 'FortiGate' AS firewall, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, concat('policy ', toString(rule_id)) AS rule\n FROM dfe.fortinet\n WHERE $__timeFilter(_timestamp_load) AND event_action = 'deny')\nGROUP BY 1, 2, 3\nORDER BY 4 DESC\nLIMIT 12"
},
"h": 9,
"id": "sources",
"w": 14,
"x": 0,
"y": 6
},
{
"config": {
"configType": "sql",
"displayType": "table",
"name": "Denied by rule",
"source": "cisco-asa",
"sqlTemplate": "SELECT firewall AS \"Firewall\",\n rule AS \"Rule\",\n count() AS \"Denied\",\n uniqExact(src) AS \"Sources\"\nFROM (SELECT _timestamp_load AS t, 'Cisco ASA' AS firewall, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, if(coalesce(cisco_asa_rule_name, '') = '', concat('ASA ', coalesce(event_code, '')), cisco_asa_rule_name) AS rule\n FROM dfe.`cisco-asa`\n WHERE $__timeFilter(_timestamp_load) AND event_outcome = 'failure' AND event_action != 'logon-failed'\n UNION ALL\n SELECT _timestamp_load AS t, 'FortiGate' AS firewall, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, concat('policy ', toString(rule_id)) AS rule\n FROM dfe.fortinet\n WHERE $__timeFilter(_timestamp_load) AND event_action = 'deny')\nGROUP BY 1, 2\nORDER BY 3 DESC\nLIMIT 12"
},
"h": 9,
"id": "rules",
"w": 10,
"x": 14,
"y": 6
}
]
}
64 changes: 64 additions & 0 deletions resources/demo-cyber/console/dashboards/demo-cyber-drop.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"name": "demo-cyber-drop",
"tags": [
"demo"
],
"tiles": [
{
"config": {
"configType": "sql",
"displayType": "stacked_bar",
"name": "Connections to or from DROP-listed networks per minute, allowed and denied",
"source": "cisco-asa",
"sqlTemplate": "WITH ['42.128.0.0/12', '42.160.0.0/12', '42.208.0.0/12', '147.16.0.0/14', '196.16.0.0/14', '101.134.0.0/15', '112.142.0.0/15', '168.80.0.0/15'] AS drop_list\nSELECT $__timeInterval(t) AS ts,\n verdict,\n count() * 60 / $__interval_s AS \"connections/min\"\nFROM (SELECT t, firewall, verdict, if(arrayExists(n -> isIPAddressInRange(src, n), drop_list), src, dst) AS address\n FROM (\n SELECT _timestamp_load AS t, 'Cisco ASA' AS firewall, if(event_outcome = 'failure' AND event_action != 'logon-failed', 'denied', 'allowed') AS verdict, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, replaceOne(IPv6NumToString(assumeNotNull(destination_ip)), '::ffff:', '') AS dst\n FROM dfe.`cisco-asa`\n WHERE $__timeFilter(_timestamp_load)\n UNION ALL\n SELECT _timestamp_load AS t, 'FortiGate' AS firewall, if(event_action = 'deny', 'denied', 'allowed') AS verdict, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, replaceOne(IPv6NumToString(assumeNotNull(destination_ip)), '::ffff:', '') AS dst\n FROM dfe.fortinet\n WHERE $__timeFilter(_timestamp_load)\n )\n WHERE arrayExists(n -> isIPAddressInRange(src, n) OR isIPAddressInRange(dst, n), drop_list))\nGROUP BY ts, verdict\nORDER BY ts"
},
"h": 6,
"id": "rate",
"w": 16,
"x": 0,
"y": 0
},
{
"config": {
"configType": "sql",
"displayType": "number",
"name": "DROP-listed connections the firewalls allowed",
"source": "cisco-asa",
"sqlTemplate": "WITH ['42.128.0.0/12', '42.160.0.0/12', '42.208.0.0/12', '147.16.0.0/14', '196.16.0.0/14', '101.134.0.0/15', '112.142.0.0/15', '168.80.0.0/15'] AS drop_list\nSELECT countIf(verdict = 'allowed') AS \"allowed\"\nFROM (SELECT t, firewall, verdict, if(arrayExists(n -> isIPAddressInRange(src, n), drop_list), src, dst) AS address\n FROM (\n SELECT _timestamp_load AS t, 'Cisco ASA' AS firewall, if(event_outcome = 'failure' AND event_action != 'logon-failed', 'denied', 'allowed') AS verdict, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, replaceOne(IPv6NumToString(assumeNotNull(destination_ip)), '::ffff:', '') AS dst\n FROM dfe.`cisco-asa`\n WHERE $__timeFilter(_timestamp_load)\n UNION ALL\n SELECT _timestamp_load AS t, 'FortiGate' AS firewall, if(event_action = 'deny', 'denied', 'allowed') AS verdict, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, replaceOne(IPv6NumToString(assumeNotNull(destination_ip)), '::ffff:', '') AS dst\n FROM dfe.fortinet\n WHERE $__timeFilter(_timestamp_load)\n )\n WHERE arrayExists(n -> isIPAddressInRange(src, n) OR isIPAddressInRange(dst, n), drop_list))"
},
"h": 6,
"id": "allowed",
"w": 8,
"x": 16,
"y": 0
},
{
"config": {
"configType": "sql",
"displayType": "table",
"name": "Top DROP-listed networks",
"source": "cisco-asa",
"sqlTemplate": "WITH ['42.128.0.0/12', '42.160.0.0/12', '42.208.0.0/12', '147.16.0.0/14', '196.16.0.0/14', '101.134.0.0/15', '112.142.0.0/15', '168.80.0.0/15'] AS drop_list\nSELECT arrayFirst(n -> isIPAddressInRange(address, n), drop_list) AS \"Network\",\n countIf(verdict = 'allowed') AS \"Allowed\",\n countIf(verdict = 'denied') AS \"Denied\",\n uniqExact(address) AS \"Addresses\"\nFROM (SELECT t, firewall, verdict, if(arrayExists(n -> isIPAddressInRange(src, n), drop_list), src, dst) AS address\n FROM (\n SELECT _timestamp_load AS t, 'Cisco ASA' AS firewall, if(event_outcome = 'failure' AND event_action != 'logon-failed', 'denied', 'allowed') AS verdict, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, replaceOne(IPv6NumToString(assumeNotNull(destination_ip)), '::ffff:', '') AS dst\n FROM dfe.`cisco-asa`\n WHERE $__timeFilter(_timestamp_load)\n UNION ALL\n SELECT _timestamp_load AS t, 'FortiGate' AS firewall, if(event_action = 'deny', 'denied', 'allowed') AS verdict, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, replaceOne(IPv6NumToString(assumeNotNull(destination_ip)), '::ffff:', '') AS dst\n FROM dfe.fortinet\n WHERE $__timeFilter(_timestamp_load)\n )\n WHERE arrayExists(n -> isIPAddressInRange(src, n) OR isIPAddressInRange(dst, n), drop_list))\nGROUP BY 1\nORDER BY 2 DESC, 3 DESC\nLIMIT 10"
},
"h": 9,
"id": "networks",
"w": 12,
"x": 0,
"y": 6
},
{
"config": {
"configType": "sql",
"displayType": "table",
"name": "DROP-listed addresses seen",
"source": "cisco-asa",
"sqlTemplate": "WITH ['42.128.0.0/12', '42.160.0.0/12', '42.208.0.0/12', '147.16.0.0/14', '196.16.0.0/14', '101.134.0.0/15', '112.142.0.0/15', '168.80.0.0/15'] AS drop_list\nSELECT address AS \"Address\",\n firewall AS \"Firewall\",\n countIf(verdict = 'allowed') AS \"Allowed\",\n countIf(verdict = 'denied') AS \"Denied\"\nFROM (SELECT t, firewall, verdict, if(arrayExists(n -> isIPAddressInRange(src, n), drop_list), src, dst) AS address\n FROM (\n SELECT _timestamp_load AS t, 'Cisco ASA' AS firewall, if(event_outcome = 'failure' AND event_action != 'logon-failed', 'denied', 'allowed') AS verdict, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, replaceOne(IPv6NumToString(assumeNotNull(destination_ip)), '::ffff:', '') AS dst\n FROM dfe.`cisco-asa`\n WHERE $__timeFilter(_timestamp_load)\n UNION ALL\n SELECT _timestamp_load AS t, 'FortiGate' AS firewall, if(event_action = 'deny', 'denied', 'allowed') AS verdict, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS src, replaceOne(IPv6NumToString(assumeNotNull(destination_ip)), '::ffff:', '') AS dst\n FROM dfe.fortinet\n WHERE $__timeFilter(_timestamp_load)\n )\n WHERE arrayExists(n -> isIPAddressInRange(src, n) OR isIPAddressInRange(dst, n), drop_list))\nGROUP BY 1, 2\nORDER BY 3 DESC, 4 DESC\nLIMIT 16"
},
"h": 9,
"id": "addresses",
"w": 12,
"x": 12,
"y": 6
}
]
}
64 changes: 64 additions & 0 deletions resources/demo-cyber/console/dashboards/demo-cyber-edr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"name": "demo-cyber-edr",
"tags": [
"demo"
],
"tiles": [
{
"config": {
"configType": "sql",
"displayType": "stacked_bar",
"name": "CrowdStrike detections per minute, by severity",
"source": "crowdstrike",
"sqlTemplate": "SELECT $__timeInterval(_timestamp) AS ts,\n multiIf(event_severity >= 99, 'critical', event_severity >= 73, 'high', event_severity >= 47, 'medium', 'low') AS severity,\n count() * 60 / $__interval_s AS \"detections/min\"\nFROM dfe.crowdstrike\nWHERE $__timeFilter(_timestamp) AND event_kind = 'alert'\nGROUP BY ts, severity\nORDER BY ts"
},
"h": 6,
"id": "rate",
"w": 16,
"x": 0,
"y": 0
},
{
"config": {
"configType": "sql",
"displayType": "number",
"name": "Critical and high detections in the time range",
"source": "crowdstrike",
"sqlTemplate": "SELECT count() AS \"critical and high\"\nFROM dfe.crowdstrike\nWHERE $__timeFilter(_timestamp) AND event_kind = 'alert' AND event_severity >= 73"
},
"h": 6,
"id": "critical",
"w": 8,
"x": 16,
"y": 0
},
{
"config": {
"configType": "sql",
"displayType": "table",
"name": "Detections by host and severity",
"source": "crowdstrike",
"sqlTemplate": "SELECT host_name AS \"Host\",\n countIf(event_severity >= 99) AS \"Critical\",\n countIf(event_severity >= 73 AND event_severity < 99) AS \"High\",\n countIf(event_severity >= 47 AND event_severity < 73) AS \"Medium\",\n count() AS \"Total\"\nFROM dfe.crowdstrike\nWHERE $__timeFilter(_timestamp) AND event_kind = 'alert'\nGROUP BY 1\nORDER BY 2 DESC, 3 DESC, 5 DESC\nLIMIT 14"
},
"h": 9,
"id": "hosts",
"w": 13,
"x": 0,
"y": 6
},
{
"config": {
"configType": "sql",
"displayType": "table",
"name": "Detections by rule and tactic",
"source": "crowdstrike",
"sqlTemplate": "SELECT rule_name AS \"Detection\",\n arrayStringConcat(threat_tactic_name, ', ') AS \"Tactic\",\n count() AS \"Detections\"\nFROM dfe.crowdstrike\nWHERE $__timeFilter(_timestamp) AND event_kind = 'alert'\nGROUP BY 1, 2\nORDER BY 3 DESC"
},
"h": 9,
"id": "rules",
"w": 11,
"x": 13,
"y": 6
}
]
}
64 changes: 64 additions & 0 deletions resources/demo-cyber/console/dashboards/demo-cyber-o365-admin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"name": "demo-cyber-o365-admin",
"tags": [
"demo"
],
"tiles": [
{
"config": {
"configType": "sql",
"displayType": "stacked_bar",
"name": "Microsoft 365 admin actions per minute, by actor",
"source": "o365",
"sqlTemplate": "SELECT $__timeInterval(_timestamp) AS ts,\n user_id AS actor,\n count() * 60 / $__interval_s AS \"actions/min\"\nFROM dfe.o365\nWHERE $__timeFilter(_timestamp) AND (event_code = 'ExchangeAdmin' OR event_action IN ('SiteCollectionAdminAdded', 'SiteCollectionAdminRemoved'))\nGROUP BY ts, actor\nORDER BY ts"
},
"h": 6,
"id": "rate",
"w": 16,
"x": 0,
"y": 0
},
{
"config": {
"configType": "sql",
"displayType": "number",
"name": "Admin actions in the time range",
"source": "o365",
"sqlTemplate": "SELECT count() AS \"admin actions\"\nFROM dfe.o365\nWHERE $__timeFilter(_timestamp) AND (event_code = 'ExchangeAdmin' OR event_action IN ('SiteCollectionAdminAdded', 'SiteCollectionAdminRemoved'))"
},
"h": 6,
"id": "total",
"w": 8,
"x": 16,
"y": 0
},
{
"config": {
"configType": "sql",
"displayType": "table",
"name": "Admin actions by actor",
"source": "o365",
"sqlTemplate": "SELECT user_id AS \"Actor\",\n count() AS \"Actions\",\n uniqExact(event_action) AS \"Operations\"\nFROM dfe.o365\nWHERE $__timeFilter(_timestamp) AND (event_code = 'ExchangeAdmin' OR event_action IN ('SiteCollectionAdminAdded', 'SiteCollectionAdminRemoved'))\nGROUP BY 1\nORDER BY 2 DESC"
},
"h": 9,
"id": "actors",
"w": 10,
"x": 0,
"y": 6
},
{
"config": {
"configType": "sql",
"displayType": "table",
"name": "Admin operations by actor",
"source": "o365",
"sqlTemplate": "SELECT user_id AS \"Actor\",\n event_action AS \"Operation\",\n count() AS \"Actions\"\nFROM dfe.o365\nWHERE $__timeFilter(_timestamp) AND (event_code = 'ExchangeAdmin' OR event_action IN ('SiteCollectionAdminAdded', 'SiteCollectionAdminRemoved'))\nGROUP BY 1, 2\nORDER BY 3 DESC\nLIMIT 16"
},
"h": 9,
"id": "operations",
"w": 14,
"x": 10,
"y": 6
}
]
}
64 changes: 64 additions & 0 deletions resources/demo-cyber/console/dashboards/demo-cyber-sign-ins.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"name": "demo-cyber-sign-ins",
"tags": [
"demo"
],
"tiles": [
{
"config": {
"configType": "sql",
"displayType": "stacked_bar",
"name": "Okta sign-ins per minute, by outcome",
"source": "okta",
"sqlTemplate": "SELECT $__timeInterval(_timestamp) AS ts,\n toString(event_outcome) AS outcome,\n count() * 60 / $__interval_s AS \"sign-ins/min\"\nFROM dfe.okta\nWHERE $__timeFilter(_timestamp) AND event_action = 'user.session.start'\nGROUP BY ts, outcome\nORDER BY ts"
},
"h": 6,
"id": "rate",
"w": 16,
"x": 0,
"y": 0
},
{
"config": {
"configType": "sql",
"displayType": "number",
"name": "Failed sign-ins in the time range",
"source": "okta",
"sqlTemplate": "SELECT count() AS \"failed\"\nFROM dfe.okta\nWHERE $__timeFilter(_timestamp) AND event_action = 'user.session.start' AND event_outcome = 'failure'"
},
"h": 6,
"id": "failed",
"w": 8,
"x": 16,
"y": 0
},
{
"config": {
"configType": "sql",
"displayType": "table",
"name": "Sign-ins by country, failures first",
"source": "okta",
"sqlTemplate": "SELECT coalesce(client_geo_country_name, 'unknown') AS \"Country\",\n countIf(event_outcome = 'failure') AS \"Failed\",\n countIf(event_outcome = 'success') AS \"Succeeded\",\n round(100 * countIf(event_outcome = 'failure') / count(), 1) AS \"Failed %\"\nFROM dfe.okta\nWHERE $__timeFilter(_timestamp) AND event_action = 'user.session.start'\nGROUP BY 1\nORDER BY 2 DESC, 3 DESC"
},
"h": 9,
"id": "countries",
"w": 10,
"x": 0,
"y": 6
},
{
"config": {
"configType": "sql",
"displayType": "table",
"name": "Failed sign-ins by user and address",
"source": "okta",
"sqlTemplate": "SELECT user_name AS \"User\",\n replaceOne(IPv6NumToString(assumeNotNull(client_ip)), '::ffff:', '') AS \"Address\",\n client_geo_country_name AS \"Country\",\n count() AS \"Failures\"\nFROM dfe.okta\nWHERE $__timeFilter(_timestamp) AND event_action = 'user.session.start' AND event_outcome = 'failure'\nGROUP BY 1, 2, 3\nORDER BY 4 DESC\nLIMIT 14"
},
"h": 9,
"id": "who",
"w": 14,
"x": 10,
"y": 6
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "demo-cyber-cisco-asa-live",
"orderBy": "_timestamp DESC",
"select": "_timestamp, event_action, event_outcome, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS source, source_port, replaceOne(IPv6NumToString(assumeNotNull(destination_ip)), '::ffff:', '') AS destination, destination_port, network_transport, network_bytes, event_original",
"source": "cisco-asa",
"tags": [
"demo"
],
"where": "",
"whereLanguage": "sql"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "demo-cyber-crowdstrike-live",
"orderBy": "_timestamp DESC",
"select": "_timestamp, event_kind, event_action, event_severity, host_name, user_name, rule_name, threat_tactic_name, replaceOne(IPv6NumToString(assumeNotNull(source_ip)), '::ffff:', '') AS address",
"source": "crowdstrike",
"tags": [
"demo"
],
"where": "",
"whereLanguage": "sql"
}
Loading
Loading