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

Indicators

These rows show field, operator, and value matches.

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

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