OTX Threat Intelligence Indicator Match


Description

Detects when an IP address in any log event matches a known threat indicator from AlienVault OTX pulse intelligence. Severity is elevated when the pulse includes a named adversary or known malware families.

Query · python

from panther_otx_helpers import (
    get_otx_object,
    otx_alert_context,
    otx_severity,
    severity_greater_than,
)

INDICATOR_FIELDS = (
    "p_any_ip_addresses",
    "p_any_domain_names",
    "p_any_md5_hashes",
    "p_any_sha1_hashes",
    "p_any_sha256_hashes",
    "p_any_emails",
)

MATCHED_INDICATORS = {}  # {indicator: indicator_type}


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

    otx = get_otx_object(event)
    if not otx:
        return False

    for field in INDICATOR_FIELDS:
        for value in event.get(field, []) or []:
            if value in MATCHED_INDICATORS:
                continue
            indicator_type = otx.indicator_type(value)
            if not indicator_type:
                continue
            MATCHED_INDICATORS[value] = indicator_type

    return bool(MATCHED_INDICATORS)


def title(event):
    log_type = event.get("p_log_type", "Unknown")
    if len(MATCHED_INDICATORS) == 1:
        indicator, ioc_type = next(iter(MATCHED_INDICATORS.items()))
        return f"OTX: Known threat {ioc_type} [{indicator}] detected in {log_type}"
    return f"OTX: {len(MATCHED_INDICATORS)} threat indicators detected in {log_type}"


def severity(event):
    highest = None
    for indicator in MATCHED_INDICATORS:
        sev = otx_severity(event, indicator)
        if highest is None or severity_greater_than(sev, highest):
            highest = sev
    return highest or "DEFAULT"


def alert_context(event):
    if not MATCHED_INDICATORS:
        return {}
    ctx = {}
    for indicator, indicator_type in MATCHED_INDICATORS.items():
        indicator_ctx = otx_alert_context(event, indicator)
        indicator_ctx["MatchedIndicatorType"] = indicator_type
        ctx[indicator] = indicator_ctx
    return ctx

Analyst notes

  1. Review the alert context and open the OTX Pulse URL to assess the indicator's threat context, associated adversary, malware families, and MITRE ATT&CK mappings.
  2. Query the data lake for all events involving this indicator to determine what assets or services were contacted and whether any connections were successful.
  3. If the indicator is confirmed malicious and interaction was observed, block the indicator, isolate affected hosts, and reset any credentials that may have been exposed.
Raw source OTX Threat Intelligence Indicator Match · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
Filename: otx_malicious_indicator.py
RuleID: "Standard.OTX.MaliciousIndicator"
DisplayName: "OTX Threat Intelligence Indicator Match"
Enabled: true
Severity: High
Description: >-
  Detects when an IP address in any log event matches a known threat indicator
  from AlienVault OTX pulse intelligence. Severity is elevated when the pulse
  includes a named adversary or known malware families.
Runbook: |
  1. Review the alert context and open the OTX Pulse URL to assess the indicator's
     threat context, associated adversary, malware families, and MITRE ATT&CK mappings.
  2. Query the data lake for all events involving this indicator to determine what assets
     or services were contacted and whether any connections were successful.
  3. If the indicator is confirmed malicious and interaction was observed, block the
     indicator, isolate affected hosts, and reset any credentials that may have been exposed.
Reference: https://otx.alienvault.com
DedupPeriodMinutes: 60
Reports:
  MITRE ATT&CK:
    - TA0043:T1595.001
Tags:
  - Reconnaissance:Active Scanning
  - OTX
  - 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
Tests:
  - Name: "Known Threat IP Detected - With Adversary and Malware"
    ExpectedResult: true
    Log:
      p_any_ip_addresses:
        - "198.51.100.23"
      p_log_type: "AWS.CloudTrail"
      p_enrichment:
        pulses_otx:
          "198.51.100.23":
            id: "6141bd9b4e9aaa4bdd26b2a8"
            name: "APT28 Infrastructure"
            description: "Known command and control infrastructure used by APT28."
            created: "2024-01-15T10:30:00"
            modified: "2024-06-01T08:00:00"
            tags:
              - "apt28"
              - "c2"
              - "russia"
            industries:
              - "government"
              - "defense"
            malware_families:
              - "X-Agent"
              - "Sofacy"
            references:
              - "https://example.com/apt28-report"
            tlp: "white"
            adversary: "APT28"
            target_countries:
              - "US"
              - "DE"
            attack_ids:
              - "T1071"
              - "T1059"
            indicator: "198.51.100.23"
            indicator_type: "IPv4"
            indicator_created: "2024-01-15T10:30:00"
            indicator_expiration: "2025-01-15T10:30:00"
  - Name: "Threat IP - No Adversary"
    ExpectedResult: true
    Log:
      p_any_ip_addresses:
        - "203.0.113.99"
      p_log_type: "Okta.SystemLog"
      p_enrichment:
        pulses_otx:
          "203.0.113.99":
            id: "abc123"
            name: "Scanning Activity"
            description: "IP observed performing widespread port scanning."
            created: "2024-03-01T12:00:00"
            tags:
              - "scanner"
            industries: []
            malware_families: []
            references: []
            tlp: "green"
            adversary: ""
            target_countries: []
            attack_ids:
              - "T1595"
            indicator: "203.0.113.99"
            indicator_type: "IPv4"
            indicator_created: "2024-03-01T12:00:00"
  - Name: "Benign IP - No Enrichment"
    ExpectedResult: false
    Log:
      p_any_ip_addresses:
        - "10.0.0.1"
      p_log_type: "AWS.VPCFlow"
  - Name: "IP Not in OTX"
    ExpectedResult: false
    Log:
      p_any_ip_addresses:
        - "192.168.1.1"
      p_log_type: "Cloudflare.HttpRequest"
      p_enrichment:
        pulses_otx:
          "192.168.1.1":
            id: ""
            name: ""
            indicator: ""
            indicator_type: ""
  - Name: "Multiple Threat IPs Detected"
    ExpectedResult: true
    Log:
      p_any_ip_addresses:
        - "198.51.100.10"
        - "198.51.100.20"
      p_log_type: "AWS.ALB"
      p_enrichment:
        pulses_otx:
          "198.51.100.10":
            id: "pulse001"
            name: "Botnet C2"
            description: "Known botnet command and control node."
            created: "2024-02-01T00:00:00"
            tags:
              - "botnet"
            industries: []
            malware_families:
              - "Mirai"
            references: []
            tlp: "white"
            adversary: ""
            target_countries: []
            attack_ids: []
            indicator: "198.51.100.10"
            indicator_type: "IPv4"
            indicator_created: "2024-02-01T00:00:00"
          "198.51.100.20":
            id: "pulse002"
            name: "Phishing Infrastructure"
            description: "Hosting phishing pages targeting financial institutions."
            created: "2024-04-10T00:00:00"
            tags:
              - "phishing"
            industries:
              - "finance"
            malware_families: []
            references: []
            tlp: "amber"
            adversary: "FIN7"
            target_countries:
              - "US"
            attack_ids:
              - "T1566"
            indicator: "198.51.100.20"
            indicator_type: "IPv4"
            indicator_created: "2024-04-10T00:00:00"
  - Name: "Malicious Domain Detected"
    ExpectedResult: true
    Log:
      p_any_domain_names:
        - "evil.example.com"
      p_log_type: "Cloudflare.HttpRequest"
      p_enrichment:
        pulses_otx:
          "evil.example.com":
            id: "pulse-domain-001"
            name: "Phishing Domain"
            description: "Domain hosting credential phishing pages."
            created: "2024-05-01T00:00:00"
            tags:
              - "phishing"
            malware_families: []
            adversary: "FIN7"
            attack_ids:
              - "T1566.002"
            indicator: "evil.example.com"
            indicator_type: "domain"
            indicator_created: "2024-05-01T00:00:00"
  - Name: "Malicious File Hash Detected"
    ExpectedResult: true
    Log:
      p_any_sha256_hashes:
        - "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
      p_log_type: "Crowdstrike.FDREvent"
      p_enrichment:
        pulses_otx:
          "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855":
            id: "pulse-hash-001"
            name: "Emotet Loader"
            description: "Known Emotet loader binary."
            created: "2024-06-01T00:00:00"
            malware_families:
              - "Emotet"
            adversary: ""
            indicator: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
            indicator_type: "FileHash-SHA256"
            indicator_created: "2024-06-01T00:00:00"
  - Name: "Malicious Email Detected"
    ExpectedResult: true
    Log:
      p_any_emails:
        - "attacker@evil.example.com"
      p_log_type: "GSuite.ActivityEvent"
      p_enrichment:
        pulses_otx:
          "attacker@evil.example.com":
            id: "pulse-email-001"
            name: "Phishing Sender"
            description: "Email address used in widespread phishing campaign."
            created: "2024-07-01T00:00:00"
            malware_families: []
            adversary: ""
            indicator: "attacker@evil.example.com"
            indicator_type: "email"
            indicator_created: "2024-07-01T00:00:00"


# ------ paired body: otx_malicious_indicator.py ------

from panther_otx_helpers import (
    get_otx_object,
    otx_alert_context,
    otx_severity,
    severity_greater_than,
)

INDICATOR_FIELDS = (
    "p_any_ip_addresses",
    "p_any_domain_names",
    "p_any_md5_hashes",
    "p_any_sha1_hashes",
    "p_any_sha256_hashes",
    "p_any_emails",
)

MATCHED_INDICATORS = {}  # {indicator: indicator_type}


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

    otx = get_otx_object(event)
    if not otx:
        return False

    for field in INDICATOR_FIELDS:
        for value in event.get(field, []) or []:
            if value in MATCHED_INDICATORS:
                continue
            indicator_type = otx.indicator_type(value)
            if not indicator_type:
                continue
            MATCHED_INDICATORS[value] = indicator_type

    return bool(MATCHED_INDICATORS)


def title(event):
    log_type = event.get("p_log_type", "Unknown")
    if len(MATCHED_INDICATORS) == 1:
        indicator, ioc_type = next(iter(MATCHED_INDICATORS.items()))
        return f"OTX: Known threat {ioc_type} [{indicator}] detected in {log_type}"
    return f"OTX: {len(MATCHED_INDICATORS)} threat indicators detected in {log_type}"


def severity(event):
    highest = None
    for indicator in MATCHED_INDICATORS:
        sev = otx_severity(event, indicator)
        if highest is None or severity_greater_than(sev, highest):
            highest = sev
    return highest or "DEFAULT"


def alert_context(event):
    if not MATCHED_INDICATORS:
        return {}
    ctx = {}
    for indicator, indicator_type in MATCHED_INDICATORS.items():
        indicator_ctx = otx_alert_context(event, indicator)
        indicator_ctx["MatchedIndicatorType"] = indicator_type
        ctx[indicator] = indicator_ctx
    return ctx

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.