Skip to content

Commit d4c625b

Browse files
committed
fix: align Kaspersky filter and rule contracts
1 parent 6c3af7e commit d4c625b

17 files changed

Lines changed: 212 additions & 46 deletions

‎filters/antivirus/kaspersky.yml‎

Lines changed: 71 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,38 +1040,26 @@ pipeline:
10401040

10411041
- rename:
10421042
from:
1043-
- log.agt
1044-
to: origin.ip
1043+
- log.agt
1044+
to: log.agentAddress
10451045

10461046
- rename:
10471047
from:
1048-
- log.ahost
1049-
to: target.host
1048+
- log.ahost
1049+
to: log.agentHost
10501050

10511051
- rename:
10521052
from:
1053-
- log.amac
1054-
to: origin.mac
1053+
- log.amac
1054+
to: log.agentMac
10551055

10561056
- rename:
10571057
from:
10581058
- log.dhost
10591059
to: target.host
10601060

1061-
- rename:
1062-
from:
1063-
- log.originalAgentAddress
1064-
to: origin.ip
10651061

1066-
- rename:
1067-
from:
1068-
- log.syslogHost
1069-
to: origin.host
10701062

1071-
- rename:
1072-
from:
1073-
- log.syslogIpHost
1074-
to: origin.ip
10751063

10761064
# .......................................................................#
10771065
# Removing unnecessary characters of the restData
@@ -1107,15 +1095,15 @@ pipeline:
11071095
function: string
11081096
params:
11091097
key: actionResult
1110-
value: "Allow"
1111-
where: 'oneOf("action", ["Allow", "Allowed"])'
1098+
value: success
1099+
where: oneOf("action", ["Allow", "Allowed"])
11121100

11131101
- add:
11141102
function: string
11151103
params:
11161104
key: actionResult
1117-
value: "blocked"
1118-
where: 'oneOf("action", ["Block", "Blocked", "blocked", "Redirect", "terminate", "delete", "quarantine"])'
1105+
value: denied
1106+
where: oneOf("action", ["Block", "Blocked", "blocked", "Redirect", "terminate", "delete", "quarantine"])
11191107

11201108
# .......................................................................#
11211109
# Removing unused fields
@@ -1126,4 +1114,64 @@ pipeline:
11261114
- log.cefMsgAll
11271115
- log.cefMsg
11281116
- log.irrelevant
1129-
- log.notDefined
1117+
- log.notDefined
1118+
1119+
# Keep addresses in IP fields and retain other source values under log.
1120+
- rename:
1121+
from:
1122+
- origin.ip
1123+
to: log.unparsedOriginIp
1124+
where: exists("origin.ip") && (!(inCIDR("origin.ip","0.0.0.0/0") || inCIDR("origin.ip","::/0")) || oneOf("origin.ip",["0.0.0.0","::"]))
1125+
- rename:
1126+
from:
1127+
- target.ip
1128+
to: log.unparsedTargetIp
1129+
where: exists("target.ip") && (!(inCIDR("target.ip","0.0.0.0/0") || inCIDR("target.ip","::/0")) || oneOf("target.ip",["0.0.0.0","::"]))
1130+
1131+
# Normalize source fields to the standard event schema.
1132+
- rename:
1133+
from:
1134+
- log.shost
1135+
to: origin.host
1136+
- rename:
1137+
from:
1138+
- log.suser
1139+
to: origin.user
1140+
- rename:
1141+
from:
1142+
- log.smac
1143+
to: origin.mac
1144+
- rename:
1145+
from:
1146+
- log.duser
1147+
to: target.user
1148+
- rename:
1149+
from:
1150+
- log.dmac
1151+
to: target.mac
1152+
1153+
# Normalize the source event severity.
1154+
- add:
1155+
function: string
1156+
params:
1157+
key: severity
1158+
value: info
1159+
where: (greaterOrEqual("log.cefDeviceSeverity",0) && lessOrEqual("log.cefDeviceSeverity",3)) || oneOf("log.cefDeviceSeverity",["Low","low","Unknown"])
1160+
- add:
1161+
function: string
1162+
params:
1163+
key: severity
1164+
value: warning
1165+
where: (greaterOrEqual("log.cefDeviceSeverity",4) && lessOrEqual("log.cefDeviceSeverity",6)) || oneOf("log.cefDeviceSeverity",["Medium","medium"])
1166+
- add:
1167+
function: string
1168+
params:
1169+
key: severity
1170+
value: error
1171+
where: (greaterOrEqual("log.cefDeviceSeverity",7) && lessOrEqual("log.cefDeviceSeverity",8)) || oneOf("log.cefDeviceSeverity",["High","high"])
1172+
- add:
1173+
function: string
1174+
params:
1175+
key: severity
1176+
value: critical
1177+
where: (greaterOrEqual("log.cefDeviceSeverity",9) && lessOrEqual("log.cefDeviceSeverity",10)) || oneOf("log.cefDeviceSeverity",["Very-High","Very High","very-high"])

‎filters/audits/kaspersky.md‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Kaspersky normalization and rule review
2+
3+
Keep reporting-agent identity separate from the source; normalize CEF identities, outcomes and severity; correct alert grouping.
4+
5+
This draft targets UTMStack `v11`. It contains 1 filter changes
6+
and 14 rule changes for this technology only. Review covered
7+
1 filter configurations and 19 matching shipped rule files.
8+
Unchanged rules are listed in the regression manifest; they are not duplicated in the diff.
9+
10+
## Contract and validation
11+
12+
- Compared exact standard names/types with go-sdk v1.1.31 and the supplied UTMStack dictionaries.
13+
- Checked documented pipeline ordering, rename/move behavior, open vendor log fields,
14+
event-side versus alert-side fields, and surviving fields used by affected rule predicates/history/grouping.
15+
- Strict SDK configuration decoding and actual CEL compilation pass for this scope.
16+
- 2 synthetic normalization cases pass, including SDK Event conversion and any
17+
trigger predicate assertions recorded in the manifest.
18+
- The scoped alerts module tests and `git diff --check` pass with the shared contract runner applied.
19+
20+
The shared alert-contract PR supplies the reusable Go runner for the manifest in
21+
`plugins/alerts/testdata/filter-contracts/kaspersky.json`. Apply that support before running `go test ./...` in `plugins/alerts`.
22+
23+
The changed rules also require the shared alert-grouping fix to resolve `lastEvent.*` values correctly at runtime.
24+
25+
The model starts from synthetic extraction results. It does not run complex grok,
26+
JSON/KV/XML/CSV extraction, time conversion, dynamic plugins, historical OpenSearch
27+
queries, or the closed EventProcessor. Raw vendor logs and resulting alerts must
28+
still be checked in staging before rollout. No customer false-positive reduction
29+
has been measured and no production rollout is included.
30+
31+
32+
33+
## References
34+
35+
- [SDK schema](https://github.com/threatwinds/go-sdk/blob/v1.1.31/plugins/plugins.proto)
36+
- [Filter steps](https://github.com/threatwinds/go-sdk/wiki/Filter-Steps-Reference)
37+
- [Standard event schema](https://github.com/threatwinds/go-sdk/wiki/Standard-Event-Schema)
38+
- [Rule implementation](https://github.com/threatwinds/go-sdk/wiki/Implementing-Rules)
39+
40+
`afterEvents`, empty noncapturing grok names, supported numeric strings, and custom
41+
`log.*` fields are accepted. Existing textual protocol casing and vendor action names
42+
are preserved unless a concrete consumer mismatch requires correction.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{
2+
"technology": "Kaspersky",
3+
"filters": [
4+
"filters/antivirus/kaspersky.yml"
5+
],
6+
"rules": [
7+
"rules/antivirus/kaspersky/code_injection_attempts.yml",
8+
"rules/antivirus/kaspersky/command_and_control_communication.yml",
9+
"rules/antivirus/kaspersky/critical_object_detected.yml",
10+
"rules/antivirus/kaspersky/data_exfiltration_attempts.yml",
11+
"rules/antivirus/kaspersky/kaspersky_agent_tampering.yml",
12+
"rules/antivirus/kaspersky/kaspersky_ransomware_behavior.yml",
13+
"rules/antivirus/kaspersky/kaspersky_rootkit_detection.yml",
14+
"rules/antivirus/kaspersky/lateral_movement_indicators.yml",
15+
"rules/antivirus/kaspersky/lolbins_abuse.yml",
16+
"rules/antivirus/kaspersky/privilege_escalation_attempts.yml",
17+
"rules/antivirus/kaspersky/process_hollowing_detection.yml",
18+
"rules/antivirus/kaspersky/sandbox_evasion_attempts.yml",
19+
"rules/antivirus/kaspersky/suspicious_network_activity.yml",
20+
"rules/antivirus/kaspersky/suspicious_packed_executables.yml",
21+
"rules/antivirus/kaspersky/suspicious_scheduled_tasks.yml",
22+
"rules/antivirus/kaspersky/suspicious_service_installation.yml",
23+
"rules/antivirus/kaspersky/system_file_tampering_detection.yml",
24+
"rules/antivirus/kaspersky/trusted_application_compromise.yml",
25+
"rules/antivirus/kaspersky/wmi_abuse_detection.yml"
26+
],
27+
"fixtures": [
28+
{
29+
"name": "Kaspersky agent must not overwrite sender",
30+
"filter": "antivirus/kaspersky.yml",
31+
"input": {
32+
"log": {
33+
"src": "198.51.100.10",
34+
"dst": "10.0.0.8",
35+
"agt": "10.0.0.2",
36+
"originalAgentAddress": "10.0.0.3",
37+
"syslogIpHost": "10.0.0.4"
38+
}
39+
},
40+
"expected": {
41+
"origin.ip": "198.51.100.10",
42+
"target.ip": "10.0.0.8",
43+
"log.agentAddress": "10.0.0.2"
44+
},
45+
"absent": [],
46+
"rules": {}
47+
},
48+
{
49+
"name": "Kaspersky CEF side identities",
50+
"filter": "antivirus/kaspersky.yml",
51+
"input": {
52+
"log": {
53+
"shost": "client",
54+
"suser": "alice",
55+
"smac": "00:11:22:33:44:55",
56+
"dhost": "server",
57+
"duser": "bob",
58+
"ahost": "manager",
59+
"agt": "10.0.0.99",
60+
"cefDeviceSeverity": "10"
61+
}
62+
},
63+
"expected": {
64+
"origin.host": "client",
65+
"origin.user": "alice",
66+
"target.host": "server",
67+
"target.user": "bob",
68+
"log.agentHost": "manager",
69+
"severity": "critical"
70+
},
71+
"absent": [
72+
"origin.ip"
73+
]
74+
}
75+
]
76+
}

‎rules/antivirus/kaspersky/code_injection_attempts.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@ where: |
3131
contains("action", ["terminate", "delete", "quarantine"]))) &&
3232
contains("log.msg", ["lsass", "csrss", "winlogon", "services", "svchost", "explorer"])
3333
deduplicateBy:
34-
- origin.host
35-
- log.cs4
34+
- adversary.host
35+
- lastEvent.log.cs4

‎rules/antivirus/kaspersky/command_and_control_communication.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@ where: |
3232
exists("target.ip") &&
3333
action != "blocked" && action != "Blocked"
3434
groupBy:
35-
- origin.host
35+
- adversary.host
3636
- target.ip

‎rules/antivirus/kaspersky/critical_object_detected.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,5 @@ where: |
3434
contains("log.cs4", ["Trojan", "HEUR:", "PDM:", "UDS:"]) ||
3535
contains("log.msg", ["infected", "malicious", "dangerous"]))
3636
groupBy:
37-
- origin.host
38-
- log.signatureID
37+
- adversary.host
38+
- lastEvent.log.signatureID

‎rules/antivirus/kaspersky/data_exfiltration_attempts.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,5 @@ afterEvents:
4848
within: 30m
4949
count: 5
5050
groupBy:
51-
- origin.ip
51+
- adversary.ip
5252
- target.ip

‎rules/antivirus/kaspersky/lolbins_abuse.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@ where: |
3232
(contains("log.msg", ["download", "execute", "bypass", "encoded", "obfuscat", "hidden", "malicious"]) ||
3333
exists("log.actionResult"))
3434
groupBy:
35-
- log.cs4
36-
- origin.host
35+
- lastEvent.log.cs4
36+
- adversary.host

‎rules/antivirus/kaspersky/privilege_escalation_attempts.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@ where: |
3636
contains("log.cs4", "Exploit") ||
3737
contains("log.msg", ["privilege", "elevation"]))
3838
groupBy:
39-
- log.signatureID
40-
- origin.host
41-
- origin.user
39+
- lastEvent.log.signatureID
40+
- adversary.host
41+
- adversary.user

‎rules/antivirus/kaspersky/process_hollowing_detection.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@ where: |
3131
contains("log.msg", ["hollow", "suspended", "unmap"])) &&
3232
greaterOrEqual("log.cefDeviceSeverity", "3")
3333
groupBy:
34-
- log.cs5
35-
- origin.host
34+
- lastEvent.log.cs5
35+
- adversary.host

0 commit comments

Comments
 (0)