Skip to content

Commit

Permalink
Updated globals (#49)
Browse files Browse the repository at this point in the history
* updated globals

* updated some things to pass unit tests

* fixed CI issues
  • Loading branch information
nhakmiller authored Apr 23, 2020
1 parent 4356372 commit 3cc53b1
Show file tree
Hide file tree
Showing 13 changed files with 132 additions and 89 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
analysis_directories = aws_policies_cis aws_policies_managed aws_policies_s3 aws_rules_cis aws_rules_cloudtrail aws_rules_guardduty aws_rules_s3_access_logs aws_rules_vpc_flow_logs globals osquery_rules osquery_rules_cis
analysis_directories = aws_policies_cis aws_policies_managed aws_policies_s3 aws_rules_cis aws_rules_cloudtrail aws_rules_guardduty aws_rules_s3_access_logs aws_rules_vpc_flow_logs globals osquery_rules

ci:
pipenv run $(MAKE) lint test
Expand Down
2 changes: 1 addition & 1 deletion aws_policies_s3/aws_s3_bucket_action_restrictions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Tests:
"DisplayName": "user.name",
"ID": "11112223334445556667778899aaabbbcccdddeeee"
},
"Policy": "{ \"Id\": \"Policy1574269747554\", \"Version\": \"2012-10-17\", \"Statement\": [ { \"Sid\": \"Stmt1574269744465\", \"Action\": [ \"s3:AbortMultipartUpload\", \"s3:CreateBucket\", \"s3:CreateJob\", \"s3:DeleteBucket\", \"s3:DeleteBucketPolicy\", \"s3:DeleteBucketWebsite\", \"s3:DeleteObject\", \"s3:DeleteObjectTagging\", \"s3:DeleteObjectVersion\", \"s3:DeleteObjectVersionTagging\", \"s3:DescribeJob\", \"s3:GetAccelerateConfiguration\", \"s3:GetAccountPublicAccessBlock\", \"s3:GetAnalyticsConfiguration\", \"s3:GetBucketAcl\", \"s3:GetBucketCORS\", \"s3:GetBucketLocation\", \"s3:GetBucketLogging\", \"s3:GetBucketNotification\", \"s3:GetBucketObjectLockConfiguration\", \"s3:GetBucketPolicy\", \"s3:GetBucketPolicyStatus\", \"s3:GetBucketPublicAccessBlock\", \"s3:GetBucketRequestPayment\", \"s3:GetBucketTagging\", \"s3:GetBucketVersioning\", \"s3:GetBucketWebsite\", \"s3:GetEncryptionConfiguration\", \"s3:GetInventoryConfiguration\", \"s3:GetLifecycleConfiguration\", \"s3:GetMetricsConfiguration\", \"s3:GetObject\", \"s3:GetObjectAcl\", \"s3:GetObjectLegalHold\", \"s3:GetObjectRetention\", \"s3:GetObjectTagging\", \"s3:GetObjectTorrent\", \"s3:GetObjectVersion\", \"s3:GetObjectVersionAcl\", \"s3:GetObjectVersionForReplication\", \"s3:GetObjectVersionTagging\", \"s3:GetObjectVersionTorrent\", \"s3:GetReplicationConfiguration\", \"s3:HeadBucket\", \"s3:ListAllMyBuckets\", \"s3:ListBucket\", \"s3:ListBucketByTags\", \"s3:ListBucketMultipartUploads\", \"s3:ListBucketVersions\", \"s3:ListJobs\", \"s3:ListMultipartUploadParts\", \"s3:ObjectOwnerOverrideToBucketOwner\", \"s3:PutAccelerateConfiguration\", \"s3:PutAccountPublicAccessBlock\", \"s3:PutAnalyticsConfiguration\", \"s3:PutBucketAcl\", \"s3:PutBucketCORS\", \"s3:PutBucketLogging\", \"s3:PutBucketNotification\", \"s3:PutBucketObjectLockConfiguration\", \"s3:PutBucketPolicy\", \"s3:PutBucketPublicAccessBlock\", \"s3:PutBucketRequestPayment\", \"s3:PutBucketTagging\", \"s3:PutBucketVersioning\", \"s3:PutBucketWebsite\", \"s3:PutEncryptionConfiguration\", \"s3:PutInventoryConfiguration\", \"s3:PutLifecycleConfiguration\", \"s3:PutMetricsConfiguration\", \"s3:PutObject\", \"s3:PutObjectAcl\", \"s3:PutObjectLegalHold\", \"s3:PutObjectRetention\", \"s3:PutObjectTagging\", \"s3:PutObjectVersionAcl\", \"s3:PutObjectVersionTagging\", \"s3:PutReplicationConfiguration\", \"s3:ReplicateDelete\", \"s3:ReplicateObject\", \"s3:ReplicateTags\", \"s3:RestoreObject\", \"s3:UpdateJobPriority\", \"s3:UpdateJobStatus\" ], \"Effect\": \"Allow\", \"Resource\": \"*\", \"Principal\": \"*\" } ]}",
"Policy": "{ \"Id\": \"Policy1574269747554\", \"Version\": \"2012-10-17\", \"Statement\": [{\"Sid\": \"Stmt1574269744465\", \"Action\": [\"s3:PutAnalyticsConfiguration\", \"s3:GetObjectVersionTagging\", \"s3:DeleteAccessPoint\", \"s3:CreateBucket\", \"s3:ReplicateObject\", \"s3:GetObjectAcl\", \"s3:GetBucketObjectLockConfiguration\", \"s3:DeleteBucketWebsite\", \"s3:PutLifecycleConfiguration\", \"s3:GetObjectVersionAcl\", \"s3:PutBucketAcl\", \"s3:PutObjectTagging\", \"s3:DeleteObject\", \"s3:DeleteObjectTagging\", \"s3:GetBucketPolicyStatus\", \"s3:PutAccountPublicAccessBlock\", \"s3:GetObjectRetention\", \"s3:GetBucketWebsite\", \"s3:ListJobs\", \"s3:PutReplicationConfiguration\", \"s3:DeleteObjectVersionTagging\", \"s3:PutObjectLegalHold\", \"s3:GetObjectLegalHold\", \"s3:GetBucketNotification\", \"s3:PutBucketCORS\", \"s3:DeleteBucketPolicy\", \"s3:GetReplicationConfiguration\", \"s3:ListMultipartUploadParts\", \"s3:PutObject\", \"s3:GetObject\", \"s3:PutBucketNotification\", \"s3:DescribeJob\", \"s3:PutBucketLogging\", \"s3:PutObjectVersionAcl\", \"s3:GetAnalyticsConfiguration\", \"s3:PutBucketObjectLockConfiguration\", \"s3:GetObjectVersionForReplication\", \"s3:CreateJob\", \"s3:PutAccessPointPolicy\", \"s3:CreateAccessPoint\", \"s3:GetLifecycleConfiguration\", \"s3:GetAccessPoint\", \"s3:GetInventoryConfiguration\", \"s3:GetBucketTagging\", \"s3:PutAccelerateConfiguration\", \"s3:DeleteObjectVersion\", \"s3:GetBucketLogging\", \"s3:ListBucketVersions\", \"s3:ReplicateTags\", \"s3:RestoreObject\", \"s3:ListBucket\", \"s3:GetAccelerateConfiguration\", \"s3:GetBucketPolicy\", \"s3:PutEncryptionConfiguration\", \"s3:GetEncryptionConfiguration\", \"s3:GetObjectVersionTorrent\", \"s3:AbortMultipartUpload\", \"s3:PutBucketTagging\", \"s3:GetBucketRequestPayment\", \"s3:GetAccessPointPolicyStatus\", \"s3:UpdateJobPriority\", \"s3:GetObjectTagging\", \"s3:GetMetricsConfiguration\", \"s3:DeleteBucket\", \"s3:PutBucketVersioning\", \"s3:PutObjectAcl\", \"s3:GetBucketPublicAccessBlock\", \"s3:ListBucketMultipartUploads\", \"s3:PutBucketPublicAccessBlock\", \"s3:ListAccessPoints\", \"s3:PutMetricsConfiguration\", \"s3:PutObjectVersionTagging\", \"s3:UpdateJobStatus\", \"s3:GetBucketVersioning\", \"s3:GetBucketAcl\", \"s3:BypassGovernanceRetention\", \"s3:PutInventoryConfiguration\", \"s3:GetObjectTorrent\", \"s3:ObjectOwnerOverrideToBucketOwner\", \"s3:GetAccountPublicAccessBlock\", \"s3:PutBucketWebsite\", \"s3:ListAllMyBuckets\", \"s3:PutBucketRequestPayment\", \"s3:PutObjectRetention\", \"s3:GetBucketCORS\", \"s3:PutBucketPolicy\", \"s3:DeleteAccessPointPolicy\", \"s3:GetBucketLocation\", \"s3:GetAccessPointPolicy\", \"s3:ReplicateDelete\", \"s3:GetObjectVersion\", \"s3:HeadBucket\"], \"Effect\": \"Allow\", \"Resource\": \"*\", \"Principal\": \"*\" } ]}",
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": false,
"BlockPublicPolicy": false,
Expand Down
2 changes: 1 addition & 1 deletion aws_policies_s3/aws_s3_bucket_principal_restrictions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Tests:
"Versioning": null
}
-
Name: Bucket Does Not Restrict Principal
Name: Bucket Does Restrict Principal
ResourceType: AWS.S3.Bucket
ExpectedResult: true
Resource:
Expand Down
31 changes: 0 additions & 31 deletions globals/aws_globals.py

This file was deleted.

17 changes: 0 additions & 17 deletions globals/aws_globals.yml

This file was deleted.

87 changes: 87 additions & 0 deletions globals/panther.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""Utility functions provided to policies and rules during execution."""
import os
from typing import Any, Dict
from ipaddress import ip_network
import boto3

# Default to us-east-1 so this doesn't fail during CI (env variable is not always present in CI)
# Used to communicate directly with the Panther resource data store
# pylint: disable=no-member
TABLE = boto3.resource('dynamodb',
os.environ.get('AWS_DEFAULT_REGION',
'us-east-1')).Table('panther-resources')
# pylint: enable=no-member


class BadLookup(Exception):
"""Error returned when a resource lookup fails."""


class PantherBadInput(Exception):
"""Error returned when a Panther helper function is provided bad input."""


def get_s3_arn_by_name(name: str) -> str:
"""This function is used to construct an s3 bucket ARN from its name."""
if name == '':
raise PantherBadInput('s3 name cannot be blank')
return 'arn:aws:s3:::' + name


def s3_lookup_by_name(name: str) -> Dict[str, Any]:
"""This function is used to get an S3 bucket resource from just its name."""
return resource_lookup(get_s3_arn_by_name(name))


def dynamo_lookup(key: str) -> Dict[str, Any]:
"""Make a dynamodb GetItem API call."""
return TABLE.get_item(Key={'id': key})


def resource_lookup(resource_id: str) -> Dict[str, Any]:
"""This function is used to get a resource from the resources-api based on its resourceID."""
# Validate input so we can provide meaningful error messages to users
if resource_id == '':
raise PantherBadInput('resourceId cannot be blank')

# Get the item from dynamo
response = dynamo_lookup(resource_id)

# Check if dynamo failed
status_code = response['ResponseMetadata']['HTTPStatusCode']
if status_code != 200:
raise BadLookup('dynamodb - ' + str(status_code) + ' HTTPStatusCode')

# Check if the item was found
if 'Item' not in response:
raise BadLookup(resource_id + ' not found')

# Return just the attributes of the item
return response['Item']['attributes']


# Expects a string in cidr notation (e.g. '10.0.0.0/24') indicating the ip range being checked
# Returns True if any ip in the range is marked as DMZ space.
DMZ_NETWORKS = [
ip_network('10.1.0.0/24'),
ip_network('100.1.0.0/24'),
]


def is_dmz_cidr(ip_range):
"""This function determines whether a given IP range is within the defined DMZ IP range."""
return any(
ip_network(ip_range).overlaps(dmz_network)
for dmz_network in DMZ_NETWORKS)


DMZ_TAG_KEY = 'environment'
DMZ_TAG_VALUE = 'dmz'


# Defaults to False to assume something is not a DMZ if it is not tagged
def is_dmz_tags(resource):
"""This function determines whether a given resource is tagged as exisitng in a DMZ."""
if resource['Tags'] is None:
return False
return resource['Tags'].get(DMZ_TAG_KEY) == DMZ_TAG_VALUE
4 changes: 4 additions & 0 deletions globals/panther.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
AnalysisType: global
Filename: panther.py
Description: >
Used to define global helpers and variables.
12 changes: 6 additions & 6 deletions osquery_rules/common/osquery_ossec.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
AnalysisType: rule
Filename: osquery_ossec.py
PolicyID: Osquery.OSSECRootkitDetected
RuleID: Osquery.OSSECRootkitDetected
DisplayName: OSSEC Rootkit Detected via Osquery
Enabled: true
ResourceTypes:
LogTypes:
- Osquery.Differential
Tags:
- Osquery
Expand All @@ -20,9 +20,9 @@ Runbook: >
Tests:
-
Name: Rootkit Detected
ResourceType: Osquery.Differential
LogType: Osquery.Differential
ExpectedResult: true
Resource:
Log:
{
"action": "added",
"calendarTime": "Tue Sep 11 16:14:21 2018 UTC",
Expand Down Expand Up @@ -57,9 +57,9 @@ Tests:
}
-
Name: Rootkit Not Detected
ResourceType: Osquery.Differential
LogType: Osquery.Differential
ExpectedResult: false
Resource:
Log:
{
"action": "added",
"calendarTime": "Tue Sep 11 16:14:21 2018 UTC",
Expand Down
24 changes: 12 additions & 12 deletions osquery_rules/common/osquery_suspicious_cron.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
AnalysisType: rule
Filename: osquery_suspicious_cron.py
PolicyID: Osquery.SuspiciousCron
RuleID: Osquery.SuspiciousCron
DisplayName: Suspicious cron detected
Enabled: true
ResourceTypes:
LogTypes:
- Osquery.Differential
Tags:
- Osquery
Expand All @@ -20,9 +20,9 @@ Reference: https://en.wikipedia.org/wiki/Cron
Tests:
-
Name: Netcat Listener
ResourceType: Osquery.Differential
LogType: Osquery.Differential
ExpectedResult: true
Resource:
Log:
{
"name": "pack_incident-response_crontab",
"action": "added",
Expand All @@ -39,9 +39,9 @@ Tests:
}
-
Name: Wget Pipe Bash
ResourceType: Osquery.Differential
LogType: Osquery.Differential
ExpectedResult: true
Resource:
Log:
{
"name": "pack_incident-response_crontab",
"action": "added",
Expand All @@ -58,9 +58,9 @@ Tests:
}
-
Name: Wget Execute
ResourceType: Osquery.Differential
LogType: Osquery.Differential
ExpectedResult: true
Resource:
Log:
{
"name": "pack_incident-response_crontab",
"action": "added",
Expand All @@ -77,9 +77,9 @@ Tests:
}
-
Name: Dig
ResourceType: Osquery.Differential
LogType: Osquery.Differential
ExpectedResult: true
Resource:
Log:
{
"name": "pack_incident-response_crontab",
"action": "added",
Expand All @@ -96,9 +96,9 @@ Tests:
}
-
Name: Built-in Cron
ResourceType: Osquery.Differential
LogType: Osquery.Differential
ExpectedResult: false
Resource:
Log:
{
"name": "pack_incident-response_crontab",
"action": "added",
Expand Down
12 changes: 6 additions & 6 deletions osquery_rules/linux/osquery_linux_aws_commands.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
AnalysisType: rule
Filename: osquery_linux_aws_commands.py
PolicyID: Osquery.Linux.AWSCommandExecuted
RuleID: Osquery.Linux.AWSCommandExecuted
DisplayName: AWS command executed on the command line
Enabled: true
ResourceTypes:
LogTypes:
- Osquery.Differential
Tags:
- Osquery
Expand All @@ -19,9 +19,9 @@ Reference: https://attack.mitre.org/techniques/T1078/
Tests:
-
Name: AWS command executed
ResourceType: Osquery.Differential
LogType: Osquery.Differential
ExpectedResult: true
Resource:
Log:
{
"name": "pack_incident-response_shell_history",
"action": "added",
Expand All @@ -34,9 +34,9 @@ Tests:
}
-
Name: Tail command executed
ResourceType: Osquery.Differential
LogType: Osquery.Differential
ExpectedResult: false
Resource:
Log:
{
"name": "pack_incident-response_shell_history",
"action": "added",
Expand Down
12 changes: 6 additions & 6 deletions osquery_rules/linux/osquery_linux_logins_non_office.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
AnalysisType: rule
Filename: osquery_linux_logins_non_office.py
PolicyID: Osquery.Linux.LoginFromNonOffice
RuleID: Osquery.Linux.LoginFromNonOffice
DisplayName: A Login from Outside the Corporate Office
Enabled: false
ResourceTypes:
LogTypes:
- Osquery.Differential
Tags:
- Configuration Required
Expand All @@ -20,9 +20,9 @@ Reference: https://attack.mitre.org/techniques/T1078/
Tests:
-
Name: Non-office network login
ResourceType: Osquery.Differential
LogType: Osquery.Differential
ExpectedResult: true
Resource:
Log:
{
"name": "pack-logged_in_users",
"action": "added",
Expand All @@ -33,9 +33,9 @@ Tests:
}
-
Name: Office network login
ResourceType: Osquery.Differential
LogType: Osquery.Differential
ExpectedResult: false
Resource:
Log:
{
"name": "pack-logged_in_users",
"action": "added",
Expand Down
12 changes: 6 additions & 6 deletions osquery_rules/mac/osquery_mac_unwanted_chrome_extensions.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
AnalysisType: rule
Filename: osquery_mac_unwanted_chrome_extensions.py
PolicyID: Osquery.Mac.UnwantedChromeExtensions
RuleID: Osquery.Mac.UnwantedChromeExtensions
DisplayName: OSQuery Detected Unwanted Chrome Extensions
Enabled: true
ResourceTypes:
LogTypes:
- Osquery.Differential
Tags:
- Osquery
Expand All @@ -20,9 +20,9 @@ Runbook: Uninstall the unwanted extension
Tests:
-
Name: Unwanted Extension Detected
ResourceType: Osquery.Differential
LogType: Osquery.Differential
ExpectedResult: true
Resource:
Log:
{
"action": "added",
"calendarTime": "Tue Sep 11 16:14:21 2018 UTC",
Expand Down Expand Up @@ -58,9 +58,9 @@ Tests:
}
-
Name: No Unwanted Chrome Extension Detected
ResourceType: Osquery.Differential
LogType: Osquery.Differential
ExpectedResult: false
Resource:
Log:
{
"action": "added",
"calendarTime": "Tue Sep 11 16:14:21 2018 UTC",
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Functional Dependencies
panther-analysis-tool==0.1.11
policyuniverse==1.3.2.1
panther-analysis-tool==0.2.1
policyuniverse==1.3.2.2

# CI Dependencies
bandit==1.6.2
Expand Down

0 comments on commit 3cc53b1

Please sign in to comment.