Skip to content

Commit

Permalink
box initial ruleset (#127)
Browse files Browse the repository at this point in the history
* initial set of box rules

* update a few metadata fields

* format updates

* cleaning up test cases

* format yet again...

* remove bad fields from tests; split a rule; added additional rules

* fixing last line
  • Loading branch information
lindsey-w authored Oct 20, 2020
1 parent 0d9498f commit 4a419f8
Show file tree
Hide file tree
Showing 21 changed files with 1,017 additions and 0 deletions.
7 changes: 7 additions & 0 deletions box_rules/box_access_granted.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
def rule(event):
return event.get('event_type') == 'ACCESS_GRANTED'


def title(event):
return 'User [{}] granted access to their account'.format(
event.get('created_by', {}).get('name', '<UNKNOWN_USER>'))
71 changes: 71 additions & 0 deletions box_rules/box_access_granted.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
AnalysisType: rule
Filename: box_access_granted.py
RuleID: Box.Access.Granted
DisplayName: Box Access Granted
Enabled: true
LogTypes:
- Box.Event
Tags:
- Box
Severity: Low
Description: >
A user granted access to their box account to Box technical support from account settings.
Reference: https://developer.box.com/reference/resources/event/
Runbook: >
Investigate whether the user purposefully granted access to their account.
SummaryAttributes:
- p_any_ip_addresses
Tests:
-
Name: Regular Event
ExpectedResult: false
Log:
{
"type": "event",
"additional_details": '{"key": "value"}',
"created_by": {
"id": 12345678,
"type": "user",
"login": "cat@example",
"name": "Bob Cat"
},
"event_type": "DELETE",
"source": {
"item_name": "regular_file.pdf",
"item_type": "file",
"owned_by": {
"id": 12345678,
"type": "user",
"login": "cat@example",
"name": "Bob Cat"
},
"parent": {
"id": 12345,
"type": "folder",
"etag": 1,
"name": "Parent_Folder",
"sequence_id": 2
}
}
}
-
Name: Access Granted
ExpectedResult: true
Log:
{
"type": "event",
"additional_details": '{"key": "value"}',
"created_by": {
"id": 12345678,
"type": "user",
"login": "cat@example",
"name": "Bob Cat"
},
"event_type": "ACCESS_GRANTED",
"source": {
"id": 12345678,
"type": "user",
"login": "user@example",
"name": "Bob Cat",
}
}
22 changes: 22 additions & 0 deletions box_rules/box_anomalous_download.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from panther_base_helpers import box_parse_additional_details # pylint: disable=import-error


def rule(event):
if event.get('event_type') != 'SHIELD_ALERT':
return False
alert_details = box_parse_additional_details(event).get('shield_alert', {})
if alert_details.get('rule_category', '') == 'Anomalous Download':
if alert_details.get('risk_score', 0) > 50:
return True
return False


def title(event):
details = box_parse_additional_details(event)
description = details.get('shield_alert',
{}).get('alert_summary',
{}).get('description', '')
if description:
return description
return 'Anamalous download activity triggered by user [{}].'.format(
event.get('created_by', {}).get('name', '<UNKNOWN_USER>'))
74 changes: 74 additions & 0 deletions box_rules/box_anomalous_download.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
AnalysisType: rule
Filename: box_anomalous_download.py
RuleID: Box.Shield.Anomalous.Download
DisplayName: Box Shield Detected Anomalous Download Activity
Enabled: true
LogTypes:
- Box.Event
Tags:
- Box
Severity: High
Description: >
A user's download activity has altered significantly.
Reference: https://developer.box.com/guides/events/shield-alert-events/
Runbook: >
Investigate whether this was triggered by expected user download activity.
SummaryAttributes:
- event_type
- ip_address
Tests:
-
Name: Regular Event
ExpectedResult: false
Log:
{
"type": "event",
"additional_details": {
'"key": "value"'
},
"created_by": {
"id": 12345678,
"type": "user",
"login": "cat@example",
"name": "Bob Cat"
},
"event_type": "DELETE",
"source": {
"item_id": 123456789012,
"item_name": "regular_file.pdf",
"item_type": "file",
"owned_by": {
"id": 12345678,
"type": "user",
"login": "cat@example",
"name": "Bob Cat"
},
"parent": {
"id": 12345,
"type": "folder",
"etag": 1,
"name": "Parent_Folder",
}
}
}
-
Name: Anomalous Download Event
ExpectedResult: true
Log:
{
"type": "event",
"additional_details": '{"shield_alert":{"rule_category":"Anomalous Download","risk_score":77,"alert_summary":{"description":"Significant increase in download content week over week, 9999% (50.00 MB) more than last week."}}}',
"created_by": {
"id": 12345678,
"type": "user",
"login": "bob@example",
"name": "Bob Cat"
},
"event_type": "SHIELD_ALERT",
"source": {
"id": 12345678,
"type": "user",
"login": "bob@example",
"name": "Bob Cat",
}
}
7 changes: 7 additions & 0 deletions box_rules/box_brute_force_login.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
def rule(event):
return event.get('event_type') == 'FAILED_LOGIN'


def title(event):
return 'User [{}] has exceeded the failed login threshold.'.format(
event.get('source', {}).get('name', "<UNKNOWN_USER>"))
74 changes: 74 additions & 0 deletions box_rules/box_brute_force_login.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
AnalysisType: rule
Filename: box_brute_force_login.py
RuleID: Box.Brute.Force.Login
DisplayName: Box Brute Force Login
Enabled: true
LogTypes:
- Box.Event
Tags:
- Box
Severity: Medium
Description: >
A Box user was denied access more times than the configured threshold.
Threshold: 10
DedupPeriodMinutes: 10
Reference: https://developer.box.com/reference/resources/event/
Runbook: >
Analyze the IP they came from, and other actions taken before/after. Check if this user eventually authenticated successfully.
SummaryAttributes:
- event_type
- ip_address
Tests:
-
Name: Regular Event
ExpectedResult: false
Log:
{
"type": "event",
"additional_details": '{"key": "value"}',
"created_by": {
"id": 12345678,
"type": "user",
"login": "cat@example",
"name": "Bob Cat"
},
"event_type": "DELETE",
"source": {
"item_id": 123456789012,
"item_name": "regular_file.pdf",
"item_type": "file",
"owned_by": {
"id": 12345678,
"type": "user",
"login": "cat@example",
"name": "Bob Cat"
},
"parent": {
"id": 12345,
"type": "folder",
"etag": 1,
"name": "Parent_Folder",
"sequence_id": 2
}
}
}
-
Name: Login Failed
ExpectedResult: true
Log:
{
"type": "event",
"additional_details": '{"key": "value"}',
"created_by": {
"id": 12345678,
"type": "user",
"login": "cat@example",
"name": "Bob Cat"
},
"event_type": "FAILED_LOGIN",
"source": {
"id": 12345678,
"type": "user",
"name": "Bob Cat",
}
}
30 changes: 30 additions & 0 deletions box_rules/box_malicious_content.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from panther_base_helpers import box_parse_additional_details # pylint: disable=import-error


def rule(event):
# enterprise malicious file alert event
if event.get('event_type') == 'FILE_MARKED_MALICIOUS':
return True
# Box Shield will also alert on malicious content
if event.get('event_type') != 'SHIELD_ALERT':
return False
alert_details = box_parse_additional_details(event).get('shield_alert', {})
if alert_details.get('rule_category', '') == 'Malicious Content':
if alert_details.get('risk_score', 0) > 50:
return True
return False


def title(event):
if event.get('event_type') == 'FILE_MARKED_MALICIOUS':
return 'File [{}], owned by [{}], was marked malicious.'.format(
event.get('source', {}).get('item_name', "<UNKNOWN_FILE>"),
event.get('source', {}).get('owned_by',
{}).get('login', '<UNKNOWN_USER>'))

alert_details = box_parse_additional_details(event).get('shield_alert', {})
return 'File [{}], owned by [{}], was marked malicious.'.format(
alert_details.get('alert_summary',
{}).get('upload_activity',
{}).get('item_name', '<UNKNOWN_FILE_NAME>'),
alert_details.get('user', {}).get('email', '<UNKNOWN_USER>'))
Loading

0 comments on commit 4a419f8

Please sign in to comment.