Detection rules › Panther

Panther rules: greynoise

GreyNoise V3 Malicious IP Activity

#
Severity
high
Entities
ip_addresses
Log types
Amazon.EKS.Audit, Asana.Audit, Atlassian.Audit, AWS.ALB, AWS.CloudTrail, AWS.VPCFlow, Azure.Audit, Azure.MonitorActivity, Box.Event, Cloudflare.Firewall, Cloudflare.HttpRequest, Crowdstrike.FDREvent, GCP.AuditLog, GSuite.ActivityEvent, Notion.AuditLogs, Okta.SystemLog, OneLogin.Events, OnePassword.SignInAttempt, Zendesk.Audit, Zoom.Activity
Tags
Reconnaissance:Active Scanning, GreyNoise, Threat Intelligence
Reference
docs.panther.com
Source
github.com/panther-labs/panther-analysis

Detects when an IP address in any log event is classified as malicious or unknown by GreyNoise V3 internet scanner intelligence. Known business services and benign IPs are excluded.

MITRE ATT&CK coverage

TacticTechniques
Reconnaissance

Telemetry coverage

Detection logic

from panther_greynoise_helpers import (
    get_greynoise_v3_business_service_object,
    get_greynoise_v3_object,
    greynoise_severity_decode,
    greynoise_v3_alert_context,
    severity_greater_than,
)

CLASSIFICATIONS_TO_ALERT = {"malicious", "unknown"}

MATCHED_IPS = {}  # {ip: classification}


def _alerting_classification(classification):
    """Collapse a possibly list-shaped classification (multiple LUT hits) to the
    single alertable classification, preferring 'malicious' over 'unknown'."""
    values = classification if isinstance(classification, list) else [classification]
    matches = [value for value in values if value in CLASSIFICATIONS_TO_ALERT]
    if not matches:
        return None
    return "malicious" if "malicious" in matches else matches[0]


def rule(event):
    global MATCHED_IPS  # pylint: disable=global-statement
    MATCHED_IPS = {}

    scanner = get_greynoise_v3_object(event)
    if not scanner:
        return False

    bsi = get_greynoise_v3_business_service_object(event)

    for ip_addr in event.get("p_any_ip_addresses", []):
        if bsi and bsi.found(ip_addr):
            continue

        classification = _alerting_classification(scanner.classification(ip_addr))
        if classification:
            MATCHED_IPS[ip_addr] = classification

    return bool(MATCHED_IPS)


def title(event):
    log_type = event.get("p_log_type", "Unknown")
    if len(MATCHED_IPS) == 1:
        ip_addr, classification = next(iter(MATCHED_IPS.items()))
        return f"GreyNoise: {classification.title()} IP [{ip_addr}] detected in {log_type}"
    return f"GreyNoise: {len(MATCHED_IPS)} suspicious IPs detected in {log_type}"


def severity(event):  # pylint: disable=unused-argument
    highest = None
    for classification in MATCHED_IPS.values():
        sev = greynoise_severity_decode(classification, "DEFAULT")
        if highest is None or severity_greater_than(sev, highest):
            highest = sev
    return highest or "DEFAULT"


def alert_context(event):
    if not MATCHED_IPS:
        return {}
    ctx = {}
    for ip_addr, classification in MATCHED_IPS.items():
        ip_ctx = greynoise_v3_alert_context(event, ip_addr)
        ip_ctx["MatchedClassification"] = classification
        ctx[ip_addr] = ip_ctx
    return ctx

Rule specification

AnalysisType: rule
Filename: greynoise_malicious_ip.py
RuleID: "Standard.GreyNoiseV3.MaliciousIP"
DisplayName: "GreyNoise V3 Malicious IP Activity"
Enabled: true
Severity: High
Description: >-
  Detects when an IP address in any log event is classified as malicious or unknown
  by GreyNoise V3 internet scanner intelligence. Known business services and benign
  IPs are excluded.
Runbook: |
  1. Review the alert context and open the GreyNoise URL to assess the IP's classification,
     associated CVEs, tags, and scanning behavior.
  2. Query the data lake for all events involving this IP to determine what assets or services
     were contacted and whether any connections were successful.
  3. If the IP is confirmed malicious and interaction was successful, block the IP, isolate
     affected hosts, and reset any credentials that may have been exposed.
Reference: https://docs.panther.com/enrichment/greynoise
DedupPeriodMinutes: 60
Reports:
  MITRE ATT&CK:
    - TA0043:T1595.001
Tags:
  - Reconnaissance:Active Scanning
  - GreyNoise
  - Threat Intelligence
SummaryAttributes:
  - p_any_ip_addresses
  - p_source_label
LogTypes:
  - Amazon.EKS.Audit
  - Asana.Audit
  - Atlassian.Audit
  - AWS.ALB
  - AWS.CloudTrail
  - AWS.VPCFlow
  - Azure.Audit
  - Azure.MonitorActivity
  - Box.Event
  - Cloudflare.Firewall
  - Cloudflare.HttpRequest
  - Crowdstrike.FDREvent
  - GCP.AuditLog
  - GSuite.ActivityEvent
  - Notion.AuditLogs
  - Okta.SystemLog
  - OneLogin.Events
  - OnePassword.SignInAttempt
  - Zendesk.Audit
  - Zoom.Activity

Stages and Predicates

Rule logic imperative Python

The parser could not express this rule's Python logic as a structured condition; the complete logic is under Detection logic above.

Output fields

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

Field
p_log_type

Response runbook

1. Review the alert context and open the GreyNoise URL to assess the IP's classification,

associated CVEs, tags, and scanning behavior.

2. Query the data lake for all events involving this IP to determine what assets or services

were contacted and whether any connections were successful.

3. If the IP is confirmed malicious and interaction was successful, block the IP, isolate

affected hosts, and reset any credentials that may have been exposed.

Worked example

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

Sample Test Event
{
  "p_any_ip_addresses": [
    "142.93.204.250"
  ],
  "p_enrichment": {
    "greynoise_noise": {
      "142.93.204.250": {
        "business_service_intelligence": {
          "found": false
        },
        "internet_scanner_intelligence": {
          "actor": "alphastrike",
          "bot": false,
          "classification": "malicious",
          "cves": [
            "CVE-2021-44228"
          ],
          "found": true,
          "metadata": {
            "asn": "AS14061",
            "organization": "DigitalOcean, LLC",
            "os": "Linux",
            "source_country": "United States"
          },
          "spoofable": false,
          "tags": [
            {
              "category": "activity",
              "id": "tag1",
              "intention": "malicious",
              "name": "Log4j Scanner"
            }
          ],
          "tor": false,
          "vpn": false,
          "vpn_service": ""
        },
        "ip": "142.93.204.250"
      }
    }
  },
  "p_log_type": "AWS.CloudTrail"
}