Detection rules › Panther
Panther rules: gti
| Rule | Severity |
|---|---|
| GTI/VirusTotal Threat Intelligence Indicator Match | high |
GTI/VirusTotal Threat Intelligence Indicator Match
#Detects when an IP address, domain, or file hash in any log event matches a known malicious indicator from Google Threat Intelligence (GTI) / VirusTotal enrichment. Severity is elevated based on GTI's threat severity verdict and the number of vendors flagging the indicator as malicious.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Reconnaissance |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| 1Password | any: Sign-in attempt (catch-all) |
Detection logic
from panther_gti_helpers import (
get_gti_object,
gti_alert_context,
gti_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",
)
MATCHED_INDICATORS = {} # {indicator: indicator_type}
def _first(value):
"""Collapse a possibly list-shaped lookup value (multiple LUT hits) to a single value."""
if isinstance(value, list):
return next((entry for entry in value if entry), None)
return value
def rule(event):
global MATCHED_INDICATORS # pylint: disable=global-statement
MATCHED_INDICATORS = {}
gti = get_gti_object(event)
if not gti:
return False
for field in INDICATOR_FIELDS:
for value in event.get(field, []) or []:
if value in MATCHED_INDICATORS:
continue
indicator_type = _first(gti.indicator_type(value))
if not indicator_type:
continue
if not gti.is_malicious(value):
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"GTI: Known malicious {ioc_type} [{indicator}] detected in {log_type}"
return f"GTI: {len(MATCHED_INDICATORS)} threat indicators detected in {log_type}"
def severity(event):
highest = None
for indicator in MATCHED_INDICATORS:
sev = gti_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 = gti_alert_context(event, indicator)
indicator_ctx["MatchedIndicatorType"] = indicator_type
ctx[indicator] = indicator_ctx
return ctx
Rule specification
AnalysisType: rule
Filename: gti_malicious_indicator.py
RuleID: "Standard.GTI.MaliciousIndicator"
DisplayName: "GTI/VirusTotal Threat Intelligence Indicator Match"
Enabled: false
Status: Experimental
Severity: High
Description: >-
Detects when an IP address, domain, or file hash in any log event matches a known
malicious indicator from Google Threat Intelligence (GTI) / VirusTotal enrichment.
Severity is elevated based on GTI's threat severity verdict and the number of
vendors flagging the indicator as malicious.
Runbook: |
1. Review the alert context and open the GTI/VirusTotal URL to assess the indicator's
verdict, detection ratio, and suggested threat label.
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://www.virustotal.com
DedupPeriodMinutes: 60
Reports:
MITRE ATT&CK:
- TA0043:T1595.001
Tags:
- Reconnaissance:Active Scanning
- GTI
- VirusTotal
- 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 GTI/VirusTotal URL to assess the indicator's
verdict, detection ratio, and suggested threat label.
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.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"p_any_sha256_hashes": [
"0000000000000000000000000000000000000000000000000000000000000000"
],
"p_enrichment": {
"vt_iocstream": {
"0000000000000000000000000000000000000000000000000000000000000000": {
"gti_url": "https://www.virustotal.com/gui/file/0000000000000000000000000000000000000000000000000000000000000000",
"id": "0000000000000000000000000000000000000000000000000000000000000000",
"last_analysis_stats": {
"harmless": 0,
"malicious": 57,
"suspicious": 0,
"undetected": 13
},
"md5": "00000000000000000000000000000000",
"meaningful_name": "example-malware.exe",
"names": [
"example-malware.exe",
"svchost32.exe"
],
"popular_threat_classification": {
"popular_threat_category": [
{
"count": 32,
"value": "trojan"
}
],
"popular_threat_name": [
{
"count": 18,
"value": "remcos"
}
],
"suggested_threat_label": "trojan.remcos/rescoms"
},
"reputation": -12,
"sha256": "0000000000000000000000000000000000000000000000000000000000000000",
"tags": [
"peexe",
"payload",
"malware"
],
"threat_severity": {
"level_description": "Severity HIGH because it was considered trojan.",
"threat_severity_level": "SEVERITY_HIGH"
},
"type": "file",
"type_description": "Win32 EXE"
}
}
},
"p_log_type": "Crowdstrike.FDREvent"
}