Skip to content

Commit 0b04cd3

Browse files
committed
fix: align VMware ESXi filter and rule contracts
1 parent 6c3af7e commit 0b04cd3

17 files changed

Lines changed: 115 additions & 29 deletions

‎filters/audits/vmware.md‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# VMware ESXi normalization and rule review
2+
3+
Use origin.host, canonical authentication failures, and corresponding alert-side grouping names.
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 14 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+
- 1 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/vmware.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.

‎filters/vmware/vmware-esxi.yml‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pipeline:
1919
pattern: '\<{{.data}}\>'
2020
- fieldName: log.deviceTime
2121
pattern: '{{.year}}(-){{.monthNumber}}(-){{.monthDay}}(T){{.time}}(Z)'
22-
- fieldName: origin.hostname
22+
- fieldName: origin.host
2323
pattern: '{{.hostname}}'
2424
- fieldName: log.process
2525
pattern: '{{.hostname}}(\:)'
@@ -40,7 +40,7 @@ pipeline:
4040
pattern: '\<{{.data}}\>'
4141
- fieldName: log.deviceTime
4242
pattern: '{{.year}}(-){{.monthNumber}}(-){{.monthDay}}(T){{.time}}(Z)'
43-
- fieldName: origin.hostname
43+
- fieldName: origin.host
4444
pattern: '{{.hostname}}'
4545
- fieldName: log.process
4646
pattern: '{{.hostname}}'
@@ -55,7 +55,7 @@ pipeline:
5555
pattern: '\<{{.data}}\>'
5656
- fieldName: log.deviceTime
5757
pattern: '{{.year}}-{{.monthNumber}}-{{.monthDay}}T{{.time}}Z'
58-
- fieldName: origin.hostname
58+
- fieldName: origin.host
5959
pattern: '{{.hostname}}'
6060
- fieldName: log.process
6161
pattern: '{{.hostname}}'
@@ -136,14 +136,14 @@ pipeline:
136136
function: string
137137
params:
138138
key: actionResult
139-
value: "failed"
140-
where: 'exists("log.message") && contains("log.message", "authentication failed")'
139+
value: failure
140+
where: exists("log.message") && contains("log.message", "authentication failed")
141141
- add:
142142
function: string
143143
params:
144144
key: actionResult
145-
value: "failed"
146-
where: 'exists("log.message") && contains("log.message", "authentication of user") && contains("log.message", "failed") && !exists("actionResult")'
145+
value: failure
146+
where: exists("log.message") && contains("log.message", "authentication of user") && contains("log.message", "failed") && !exists("actionResult")
147147
- add:
148148
function: string
149149
params:
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"technology": "VMware ESXi",
3+
"filters": [
4+
"filters/vmware/vmware-esxi.yml"
5+
],
6+
"rules": [
7+
"rules/vmware/vmware-esxi/esxi_account_manipulation.yml",
8+
"rules/vmware/vmware-esxi/esxi_disk_theft.yml",
9+
"rules/vmware/vmware-esxi/esxi_firewall_modification.yml",
10+
"rules/vmware/vmware-esxi/esxi_host_compromise.yml",
11+
"rules/vmware/vmware-esxi/esxi_ransomware_detection.yml",
12+
"rules/vmware/vmware-esxi/esxi_ssh_access.yml",
13+
"rules/vmware/vmware-esxi/esxi_syslog_disruption.yml",
14+
"rules/vmware/vmware-esxi/esxi_vib_sideloading.yml",
15+
"rules/vmware/vmware-esxi/hypervisor_escape_attempts.yml",
16+
"rules/vmware/vmware-esxi/powercli_script_execution.yml",
17+
"rules/vmware/vmware-esxi/vcenter_server_attacks.yml",
18+
"rules/vmware/vmware-esxi/vm_escape_detection.yml",
19+
"rules/vmware/vmware-esxi/vmware_tools_vulnerabilities.yml",
20+
"rules/vmware/vmware-esxi/vsphere_api_abuse.yml"
21+
],
22+
"fixtures": [
23+
{
24+
"name": "vmware_auth_failure",
25+
"filter": "vmware/vmware-esxi.yml",
26+
"input": {
27+
"origin": {
28+
"host": "esxi-lab"
29+
},
30+
"log": {
31+
"message": "authentication failed"
32+
}
33+
},
34+
"expected": {
35+
"origin.host": "esxi-lab",
36+
"actionResult": "failure"
37+
},
38+
"absent": [
39+
"origin.hostname"
40+
],
41+
"rules": {}
42+
}
43+
]
44+
}

‎rules/vmware/vmware-esxi/esxi_account_manipulation.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ where: |
4040
))
4141
)
4242
groupBy:
43-
- adversary.hostname
43+
- adversary.host

‎rules/vmware/vmware-esxi/esxi_disk_theft.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,5 @@ where: |
4040
(contains("log.message", "Datastore") && contains("log.message", "browse") && contains("log.message", ".vmdk"))
4141
)
4242
groupBy:
43-
- adversary.hostname
43+
- adversary.host
4444
- adversary.ip

‎rules/vmware/vmware-esxi/esxi_firewall_modification.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ where: |
3434
contains("log.message", "set --allowed-all true") ||
3535
contains("log.message", "set --enabled")
3636
)) ||
37-
(contains("log.message", "iptables") && exists("origin.hostname"))
37+
(contains("log.message", "iptables") && exists("origin.host"))
3838
)
3939
groupBy:
40-
- adversary.hostname
40+
- adversary.host

‎rules/vmware/vmware-esxi/esxi_host_compromise.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ where: |
4242
contains("log.message", "log events removed") ||
4343
(equals("log.process", "vmkernel") && contains("log.message", "SCSI sense")) ||
4444
(contains("log.eventInfo", "ransom") || contains("log.eventInfo", "encrypt"))) &&
45-
exists("origin.hostname")
45+
exists("origin.host")
4646
groupBy:
47-
- adversary.hostname
47+
- adversary.host

‎rules/vmware/vmware-esxi/esxi_ransomware_detection.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,4 @@ where: |
3737
(contains("log.message", "chmod") && contains("log.message", "+x") && contains("log.message", ".sh"))
3838
)
3939
groupBy:
40-
- adversary.hostname
40+
- adversary.host

‎rules/vmware/vmware-esxi/esxi_ssh_access.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,5 @@ where: |
3333
(contains("log.message", "ssh") && contains("log.message", "connection from"))
3434
)
3535
groupBy:
36-
- adversary.hostname
36+
- adversary.host
3737
- adversary.ip

‎rules/vmware/vmware-esxi/esxi_syslog_disruption.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,4 @@ where: |
3737
(contains("log.message", "Syslog.global.logHost") && contains("log.message", "changed"))
3838
)
3939
groupBy:
40-
- adversary.hostname
40+
- adversary.host

0 commit comments

Comments
 (0)