Detection rules › Panther

Signal - VPC Flow Logs Allowed SSH

Severity
informational
Log types
AWS.VPCFlow
Tags
AWS, Signal
Source
github.com/panther-labs/panther-analysis

VPC Flow Logs observed inbound traffic on SSH port. This rule is a signal to be used in correlation rules.

MITRE ATT&CK coverage

TacticTechniques
Lateral MovementT1021.004 Remote Services: SSH

Rule body yaml

AnalysisType: rule
Filename: aws_vpc_ssh_allowed_signal.py
RuleID: "AWS.VPC.SSHAllowedSignal"
DisplayName: "Signal - VPC Flow Logs Allowed SSH"
Enabled: true
CreateAlert: false
LogTypes:
  - AWS.VPCFlow
Tags:
  - AWS
  - Signal
Reports:
  MITRE ATT&CK:
    - TA0008:T1021.004 # Lateral Movement: Remote Services: SSH
Severity: Info
Description: >
  VPC Flow Logs observed inbound traffic on SSH port.
  This rule is a signal to be used in correlation rules.
Tests:
  - Name: Public to Private IP on SSH Allowed
    ExpectedResult: true
    Log:
      {
        "dstPort": 22,
        "dstAddr": "10.0.0.1",
        "srcAddr": "1.1.1.1",
        "instanceId": "i-0d4c7318592c6a2c7",
        "action": "ACCEPT",
        "p_log_type": "AWS.VPCFlow",
      }
  - Name: Public to Private IP on non-SSH
    ExpectedResult: false
    Log:
      {
        "dstPort": 443,
        "dstAddr": "10.0.0.1",
        "srcAddr": "1.1.1.1",
        "instanceId": "i-0d4c7318592c6a2c7",
        "action": "ACCEPT",
        "p_log_type": "AWS.VPCFlow",
      }
  - Name: Private to Private IP on SSH
    ExpectedResult: false
    Log:
      {
        "dstPort": 22,
        "dstAddr": "10.0.0.1",
        "srcAddr": "10.10.10.1",
        "instanceId": "i-0d4c7318592c6a2c7",
        "action": "ACCEPT",
        "p_log_type": "AWS.VPCFlow",
      }
  - Name: Public to Private IP on SSH Denied
    ExpectedResult: false
    Log:
      {
        "dstPort": 22,
        "dstAddr": "10.0.0.1",
        "srcAddr": "1.1.1.1",
        "instanceId": "i-0d4c7318592c6a2c7",
        "action": "REJECT",
        "p_log_type": "AWS.VPCFlow",
      }

Detection logic

Condition

not (destination_port ne "22" or action ne "ACCEPT")

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

Exclusions

Top-level NOT(...) conjuncts: predicates this rule actively suppresses.

FieldKindExcluded values
actionneACCEPT
destination_portne22

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

Field
eventName
eventSource
awsRegion
recipientAccountId
sourceIPAddress
userAgent
userIdentity