An overly simple E2E example#
Create rule#
Leverage a user friendly format such as TOML as opposed to JSON
[metadata]
creation_date = "2020/08/18"
integration = ["endpoint", "windows", "system"]
maturity = "production"
min_stack_comments = "New fields added: required_fields, related_integrations, setup"
min_stack_version = "8.3.0"
updated_date = "2024/01/16"
[rule]
author = ["Elastic"]
description = """
Identifies the Internet Information Services (IIS) command-line tool, AppCmd, being used to list passwords. An attacker
with IIS web server access via a web shell can decrypt and dump the IIS AppPool service account password using AppCmd.
"""
from = "now-9m"
index = ["winlogbeat-*", "logs-endpoint.events.*", "logs-windows.*"]
language = "eql"
license = "Elastic License v2"
max_signals = 33
name = "Microsoft IIS Service Account Password Dumped"
references = ["https://blog.netspi.com/decrypting-iis-passwords-to-break-out-of-the-dmz-part-1/"]
risk_score = 73
rule_id = "0564fb9d-90b9-4234-a411-82a546dc1343"
setup = "..."
severity = "high"
tags = ["Domain: Endpoint", "OS: Windows", "Use Case: Threat Detection", "Tactic: Credential Access", "Data Source: Elastic Endgame", "Data Source: Elastic Defend"]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "windows" and event.type == "start" and
(process.name : "appcmd.exe" or ?process.pe.original_file_name == "appcmd.exe") and
process.args : "/list" and process.args : "/text*password"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1003"
name = "OS Credential Dumping"
reference = "https://attack.mitre.org/techniques/T1003/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
Validate format#
Is this valid TOML?
Validate schema#
Load the rule as code and use a schema to validate.

Fig. 49 Example rule schema for validation#
Validate detection logic#
Validate the syntax, semantics, and data schema of the detection logic.

Fig. 50 Example code to validate detection logic#
{'stack': EqlSchemaError('Error at line:4,column:3
Field not recognized for process event
event.type == "start" and process.name == "debugfs" and
process.args : "/dev/sd*" and not process.args == "-R" and
container.security_context.privileged == true
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stack: 8.9.0, beats: 8.9.0,ecs: 8.9.0, endgame: 8.4.0'), 'integrations': EqlSchemaError('Error at line:4,column:3
Field not recognized for process event
event.type == "start" and process.name == "debugfs" and
process.args : "/dev/sd*" and not process.args == "-R" and
container.security_context.privileged == true
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stack: 8.8.0, integration: None,ecs: 8.8.0, package: cloud_defend, package_version: 1.2.2')}
Validate semantics#
Once the rule is fully loaded and mostly validated, with complete context, is there any final validation, such as build time fields.
Unit tests#
Perform additional testing against the rule and entire rule set.

Fig. 51 Example unit tests#
E2E test#
Fully load the rules to the platform and perform functional and efficacy tests.

Fig. 52 End-to-end testing flow#
Merge to dev branch#
Commit and push changes to the development branch.
Deploy to test platform with CI/CD#
CI/CD should trigger on the merge and automatically push to a development platform for testing.
Functional and E2E tests#
Perform the same tests as the previous E2E as part of the CI/CD deployment.
Merge to main#
Once E2E testing is validated and all expectations are met on the development platform testing, merge the changes to the main branch.
Deploy to production platform with CI/CD#
CI/CD should trigger on the merge and automatically push to the production platform.
Receive telemetry on performance#
Telemetry and metrics should be reporting on the deployment and use of the rules.
Tune the rule within the platform#
Based on feedback from the telemetry, modify the rule within the platform to tune it accordingly.
Replicate changes back to VCS#
DaC workflows integrated with the platform should trigger on the rule change to replicate the changes back to the repo with a commit or pull request (this step is only applicable if the dual sync governance strategy is employed).