Detection rules › Panther

Panther rules: anomalous

Anomalous AccessDenied Requests

#
Source
github.com/panther-labs/panther-analysis

ARNs with a high Access Denied error rate could indicate an error or compromised credentials attempting to perform reconnaissance.

Rule specification

AnalysisType: scheduled_query
Description: ARNs with a high Access Denied error rate could indicate an error or compromised credentials attempting to perform reconnaissance.
Enabled: false
SnowflakeQuery: |
  SELECT
    userIdentity:arn as arn,
    count(DISTINCT eventName) as distinctEventNames
  FROM
    panther_logs.public.aws_cloudtrail
  WHERE
    errorCode = 'AccessDenied'
    and p_occurs_since('1 day')
  GROUP BY userIdentity:arn
  HAVING count(DISTINCT eventName) > 10

DatabricksQuery: |
  SELECT
    userIdentity:arn as arn,
    count(DISTINCT eventName) as distinctEventNames
  FROM
    panther_logs.aws_cloudtrail
  WHERE
    errorCode = 'AccessDenied'
    and p_occurs_since('1 day')
  GROUP BY userIdentity:arn
  HAVING count(DISTINCT eventName) > 10
QueryName: "Anomalous AccessDenied Requests"
Schedule:
  RateMinutes: 1440
  TimeoutMinutes: 5

Stages and Predicates

Stage 1: source

Table
panther_logs.public.aws_cloudtrail

Stage 2: filter

  • errorCode is AccessDenied
Grouped by
userIdentity:arn
Window
1d

Stage 3: having

Threshold
gt 10
Cardinality
eventName

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
arnuserIdentity:arn
distinctEventNamescount ( DISTINCT eventName )

Anomalous VPC Traffic to Destination Port

#
Tags
Anomaly Detection, Example, Statistical Anomaly
Source
github.com/panther-labs/panther-analysis

Look at which VPC hosts have been sending a lot of traffic over the past hour

Rule specification

AnalysisType: saved_query
QueryName: "Anomalous VPC Traffic to Destination Port"
Description: Look at which VPC hosts have been sending a lot of traffic over the past hour
Tags:
  - Anomaly Detection
  - Example
  - Statistical Anomaly
Query: |-
    -- pragma: template

    {% import 'anomalies' statistical_anomaly %}

    with subquery as (
        SELECT *
        FROM panther_logs.public.aws_vpcflow
        WHERE
          p_occurs_since('7 day')
          AND dstAddr not like '10.%'
          AND dstPort < 1024
          AND flowDirection = 'egress'
          AND pktDstAwsService is null
    ),
    {{ statistical_anomaly('subquery', 'srcAddr', 'bytes', 'sum', '1', 'hour', 10) }}

RoleAssumes by Multiple Useragents

#
Source
github.com/panther-labs/panther-analysis

RoleAssumes with multiple Useragents could indicate compromised credentials.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule specification

AnalysisType: scheduled_query
Description: RoleAssumes with multiple Useragents could indicate compromised credentials.
Enabled: false
SnowflakeQuery: |
  SELECT
    requestParameters:roleArn as roleArn,
    userIdentity:principalId as principalId,
    count(DISTINCT userAgent) as distinctUserAgents
  FROM
    panther_logs.public.aws_cloudtrail
  WHERE
    eventSource = 'sts.amazonaws.com'
    and eventName = 'AssumeRole'
    and p_occurs_since('1 days')
    and userIdentity:principalId != 'null'
    and userAgent != 'AWS Internal'
    and requestParameters:roleArn != 'null'
  GROUP BY requestParameters:roleArn, userIdentity:principalId
  HAVING count(DISTINCT userAgent) > 1
  ORDER BY count(DISTINCT userAgent) DESC

DatabricksQuery: |
  SELECT
    requestParameters:roleArn as roleArn,
    userIdentity:principalId as principalId,
    count(DISTINCT userAgent) as distinctUserAgents
  FROM
    panther_logs.aws_cloudtrail
  WHERE
    eventSource = 'sts.amazonaws.com'
    and eventName = 'AssumeRole'
    and p_occurs_since('1 days')
    and userIdentity:principalId != 'null'
    and userAgent != 'AWS Internal'
    and requestParameters:roleArn != 'null'
  GROUP BY requestParameters:roleArn, userIdentity:principalId
  HAVING count(DISTINCT userAgent) > 1
  ORDER BY count(DISTINCT userAgent) DESC
QueryName: "RoleAssumes by Multiple Useragents"
Schedule:
  RateMinutes: 1440
  TimeoutMinutes: 5

Stages and Predicates

Stage 1: source

Table
panther_logs.public.aws_cloudtrail

Stage 2: filter

  • eventSource is sts.amazonaws.com
  • eventName is AssumeRole
  • userIdentity:principalId is not null
  • userAgent is not AWS Internal
  • requestParameters:roleArn is not null
Grouped by
requestParameters:roleArn, userIdentity:principalId
Window
1d

Stage 3: having

Threshold
gt 1
Cardinality
userAgent

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
roleArnrequestParameters:roleArn
principalIduserIdentity:principalId
distinctUserAgentscount ( DISTINCT userAgent )

VPC Flow Port Scanning

#
Status
Deprecated
Severity
medium
Tags
Discovery:Network Service Discovery
Source
github.com/panther-labs/panther-analysis

Searches for potential port scanning activity in VPC Flow logs

MITRE ATT&CK coverage

TacticTechniques
Discovery

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: anomalous_vpc_port_activity.py
RuleID: "VPCFlow.Port.Scanning"
DisplayName: "VPC Flow Port Scanning"
Reports:
  MITRE ATT&CK:
    - TA0007:T1046
Tags:
  - Discovery:Network Service Discovery
Description: >
  Searches for potential port scanning activity in VPC Flow logs
Enabled: false
Status: Deprecated
Runbook: >
  Analyze VPC Flow logs of suspicious IPs and see what ports are being accessed. A sequence of ports may be suspicious
ScheduledQueries:
  - VPC Flow Port Scanning
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query VPC Flow Port Scanning; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

Analyze VPC Flow logs of suspicious IPs and see what ports are being accessed. A sequence of ports may be suspicious

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

VPC Flow Port Scanning

#
Source
github.com/panther-labs/panther-analysis

Instances of a srcAddr communicating with multiple ports on a dstAddr could indicate port scanning activity.

Rule specification

AnalysisType: scheduled_query
Description: Instances of a srcAddr communicating with multiple ports on a dstAddr could indicate port scanning activity.
Enabled: false
SnowflakeQuery: |
  SELECT
    srcAddr,
    dstAddr,
    COUNT(DISTINCT dstPort) as distinctDstPorts,
    vpcId,
    region,
    subNetId
  FROM panther_logs.public.aws_vpcflow
  WHERE p_occurs_since('1 hour')
    and srcAddr != 'null'
    and srcPort not in (443, 80, 2049, 123, 445, 53, 853)
    and dstPort not in (443, 80, 2049, 123, 445, 53, 853)
    and flowDirection = 'egress'
  GROUP BY srcAddr, dstAddr, vpcId, region, subNetId
  HAVING COUNT(DISTINCT dstPort) >=  10
  ORDER BY COUNT(DISTINCT dstPort) DESC

DatabricksQuery: |
  SELECT
    srcAddr,
    dstAddr,
    COUNT(DISTINCT dstPort) as distinctDstPorts,
    vpcId,
    region,
    subNetId
  FROM panther_logs.aws_vpcflow
  WHERE p_occurs_since('1 hour')
    and srcAddr != 'null'
    and srcPort not in (443, 80, 2049, 123, 445, 53, 853)
    and dstPort not in (443, 80, 2049, 123, 445, 53, 853)
    and flowDirection = 'egress'
  GROUP BY srcAddr, dstAddr, vpcId, region, subNetId
  HAVING COUNT(DISTINCT dstPort) >=  10
  ORDER BY COUNT(DISTINCT dstPort) DESC
QueryName: "VPC Flow Port Scanning"
Schedule:
  RateMinutes: 60
  TimeoutMinutes: 5

Stages and Predicates

Stage 1: source

Table
panther_logs.public.aws_vpcflow

Stage 2: filter

  • srcAddr is not null
  • srcPort is not one of 443, 80, 2049, 123, 445 (+2 more values, see Indicators below)
  • dstPort is not one of 443, 80, 2049, 123, 445 (+2 more values, see Indicators below)
  • flowDirection is egress
Grouped by
srcAddr, dstAddr, vpcId, region, subNetId
Window
1h

Stage 3: having

Threshold
ge 10
Cardinality
dstPort

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
dstPortin123, 2049, 443, 445, 53, 80, 853excludes:dstPort
srcPortin123, 2049, 443, 445, 53, 80, 853excludes:srcPort

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
srcAddr
dstAddr
distinctDstPortsCOUNT ( DISTINCT dstPort )
vpcId
region
subNetId