Detection rules › Panther
Panther rules: appomni
| Rule | Severity |
|---|---|
| AppOmni Alert Passthrough | medium |
AppOmni Alert Passthrough
#MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Resource Development | |
| Initial Access | |
| Execution | |
| Persistence | |
| Privilege Escalation | |
| Stealth | |
| Defense Impairment | |
| Credential Access | |
| Discovery | |
| Lateral Movement | |
| Collection | |
| Command & Control | |
| Exfiltration | |
| Impact |
Detection logic
SEV_DICT = {0: "Critical", 1: "High", 2: "Medium", 3: "Low", 4: "Info"}
def rule(event):
# Only alert where event.kind == "alert"
if event.deep_get("event", "kind") == "alert":
return True
return False
def title(event):
# Create title that includes severity and message
sev = SEV_DICT.get(event.deep_get("event", "severity"))
# Use type service in title if only one field, label as 'Multiple Services' if more than one.
if len(event.deep_get("related", "services", "type", default=[])) == 1:
service = event.deep_get("related", "services", "type")[0]
else:
service = "Multiple Services"
return f'[{sev}] - {service} - {event.get("message")}'
def severity(event):
# Update Panther alert severity based on severity from AppOmni Alert
return SEV_DICT[event.deep_get("event", "severity", default=4)]
def dedup(event):
# Dedup by the events alert id, make sure we alert each time a new AppOmni alert is logged
return f'Event ID: {event.deep_get("appomni", "event", "id")}'
def alert_context(event):
# 'Threat' and 'related' data to be included in the alert sent to the alert destination
return {"threat": event.deep_get("rule", "threat"), "related": event.get("related")}
Rule specification
AnalysisType: rule
Filename: appomni_alert_passthrough.py
RuleID: "AppOmni.Alert.Passthrough"
DisplayName: "AppOmni Alert Passthrough"
Enabled: true
LogTypes:
- AppOmni.Alerts
Severity: Medium
Reports:
MITRE ATT&CK:
- TA0001:T1566
- TA0001:T1528
- TA0001:T1190
- TA0001:T1078
- TA0001:T1199
- TA0004:T1548
- TA0005:T1562
- TA0005:T1090
- TA0005:T1564
- TA0005:T1556
- TA0005:T1550
- TA0005:T1078
- TA0006:T1110
- TA0006:T1111
- TA0006:T1550
- TA0006:T1528
- TA0006:T1552
- TA0006:T1539
- TA0040:T1486
- TA0040:T1565
- TA0040:T1485
- TA0040:T1531
- TA0002:T1204
- TA0003:T1114
- TA0003:T1098
- TA0003:T1556
- TA0003:T1078
- TA0003:T1136
- TA0004:T1484
- TA0007:T1518
- TA0007:T1087
- TA0008:T1550
- TA0042:T1608
- TA0009:T1530
- TA0009:T1213
- TA0009:T1114
- TA0004:T1078
- TA0010:T1537
- TA0010:T1567
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on AppOmni.Alerts events when the condition below holds.
Condition
event.kindisalert
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.kind | eq |
| field:"event.kind" kind:eq value:"alert" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
threat | rule.threat |
related | |
message |
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"appomni": {
"alert": {
"channel": "prod"
},
"event": {
"dataset": "appomni_alert",
"id": "2ae1e281-4df1-5d26-81e2-7b75589e5dd4",
"sortable_event_id": "01HQ6JKJ5VE68CAT71JM27Z1D2",
"sortable_ingest_id": "01HQ6KGT23SN874A9ATHZCM1JH"
},
"organization": {
"id": 285
}
},
"event": {
"created": "2024-02-21T19:50:42.499Z",
"kind": "alert",
"severity": 2
},
"message": "Security issue detected in GitHub repository 'appomni/ao_factory_interfaces'",
"related": {
"event": [
"cf8e782f-1657-5a4e-bdc2-cff1d147c912"
],
"services": {
"id": [
12477
],
"type": [
"github"
]
}
},
"rule": {
"name": "Repository Security Issue Detected",
"ruleset": "1423ff39-3250-4d53-aafb-142e740668bd",
"threat": {
"framework": "MITRE ATT&CK",
"tactic": {
"id": [
"TA0001"
],
"name": [
"Initial Access"
]
},
"technique": {
"id": [
"T1195"
],
"name": [
"Supply Chain Compromise"
]
}
},
"uuid": "6d873f19-4847-4412-9b70-6dca598ee64c",
"version": "1"
},
"timestamp": "2024-02-21T19:34:44.155Z",
"version": "2.0.0"
}