Detection rules › Panther

Panther rules: vpc

Query.VPC.DNS.Tunneling

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

Detect activity similar to DNS tunneling traffic in AWS VPC Logs

Rule specification

AnalysisType: scheduled_query
QueryName: "Query.VPC.DNS.Tunneling"
Enabled: false
Description: >
  Detect activity similar to DNS tunneling traffic in AWS VPC Logs
SnowflakeQuery: |
  SELECT
    account_id,
    region,
    vpc_id,
    srcAddr, -- outside
    srcIds:instance as instance, -- inside

    COUNT(1) as message_count,
    ARRAY_AGG(DISTINCT query_name) as query_names
  FROM
    panther_logs.public.aws_vpcdns
  WHERE
    p_occurs_since(3600) -- 1 hour in seconds
    AND
    -- simple allowlisting
    query_name NOT LIKE '%amazonaws.com'
  GROUP BY
    1,2,3,4,5
  HAVING
    message_count >= 1000   -- decent amount of activity in an hour
    AND
    ARRAY_SIZE(query_names) <= 2 -- only a small number of distinct domains (not likely a real dns server!)

DatabricksQuery: |
  SELECT
    account_id,
    region,
    vpc_id,
    srcAddr, -- outside
    srcIds:instance as instance, -- inside

    COUNT(1) as message_count,
    COLLECT_SET(query_name) as query_names
  FROM
    panther_logs.aws_vpcdns
  WHERE
    p_occurs_since(3600) -- 1 hour in seconds
    AND
    -- simple allowlisting
    query_name NOT LIKE '%amazonaws.com'
  GROUP BY
    1,2,3,4,5
  HAVING
    message_count >= 1000   -- decent amount of activity in an hour
    AND
    SIZE(query_names) <= 2 -- only a small number of distinct domains (not likely a real dns server!)
Schedule:
  RateMinutes: 60
  TimeoutMinutes: 1

Stages and Predicates

Stage 1: source

Table
panther_logs.public.aws_vpcdns

Stage 2: filter

  • query_name does not match the pattern *amazonaws.com
Grouped by
account_id, region, vpc_id, srcAddr, instance
Window
1h

Stage 3: having

  • message_count is at least 1000

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
query_nameends_withamazonaws.comexcludes:query_name field:"query_name" value:"amazonaws.com"

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
account_id
region
vpc_id
srcAddr
instancesrcIds:instance
message_countCOUNT ( 1 )
query_namesARRAY_AGG ( DISTINCT query_name )

VPC DNS Tunneling

#
Severity
medium
Tags
Defense Evasion:Network Boundary Bridging
Source
github.com/panther-labs/panther-analysis

Detect dns tunneling traffic using a scheduled query

MITRE ATT&CK coverage

TacticTechniques
Defense Impairment

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: vpc_dns_tunneling.py
RuleID: "VPC.DNS.Tunneling"
DisplayName: "VPC DNS Tunneling"
Description: >
  Detect dns tunneling traffic using a scheduled query
Reports:
  MITRE ATT&CK:
    - TA0005:T1599
Tags:
  - Defense Evasion:Network Boundary Bridging
Enabled: false
ScheduledQueries:
  - Query.VPC.DNS.Tunneling
Severity: Medium

Stages and Predicates

Rule logic

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

Worked example

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

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