Cheat sheet — Detecting Host Compromise¶
Companion to Module 10 — Detecting Host Compromise · CC BY 4.0 — print it, pin it, share it.
Last reviewed: 2026-07
sigma-cli — install and inspect¶
pip install sigma-cli # the CLI (module `sigma`, command `sigma`)
sigma plugin list # available backends/pipelines and install state
sigma plugin install splunk # add a backend before you can convert to it
sigma plugin install elasticsearch
sigma list targets # backends you can convert TO (-t)
sigma list pipelines # field-mapping pipelines you can apply (-p)
sigma list formats -t splunk # output formats a backend supports (-f)
Converting a Sigma rule to a backend¶
sigma convert -t splunk rules/credaccess-lsass.yml # → SPL
sigma convert -t elasticsearch -f dsl_lucene rules/*.yml # → Elastic (pick a format)
sigma convert -t splunk -p sysmon rules/persistence-runkey.yml # apply a pipeline (field map)
sigma convert -t splunk --without-pipeline rules/lat-svc.yml # raw fields, no remap (lab proof)
-t= target backend,-p= pipeline (generic field → your SIEM's field),-f= output format.
A Sigma rule skeleton (windows / sysmon)¶
title: LSASS Handle Access (credential dumping)
id: 0e7163d4-... # a UUID, one per rule
status: experimental # experimental | test | stable | deprecated
logsource:
product: windows
category: process_access # or service: sysmon / category: registry_set
detection:
selection:
EventID: 10
TargetImage|endswith: '\lsass.exe'
condition: selection # combine with `and`/`or`/`not`/`1 of ...`
level: high # informational | low | medium | high | critical
tags:
- attack.credential_access
- attack.t1003.001 # LSASS memory — map every rule to ATT&CK
- Lab phases: Run-key persistence
EventID: 13+TargetObject|contains: '\CurrentVersion\Run'(T1547.001); LSASSEventID: 10(T1003.001); remote service installEventID: 7045on theSystemchannel (T1021.002 / T1543.003).
Wazuh custom rules — /var/ossec/etc/rules/local_rules.xml¶
<group name="local,sysmon,">
<rule id="100210" level="12">
<if_sid>61603</if_sid> <!-- chain off a Sysmon base rule for context -->
<field name="win.eventdata.targetImage">lsass\.exe</field>
<match>GrantedAccess</match>
<description>Possible credential dumping: handle opened to LSASS</description>
<mitre>
<id>T1003.001</id>
</mitre>
</rule>
</group>
<match>= substring;<regex>= OSSEC regex;<field name>matches a decoded field.<if_sid>(a specific rule) or<if_group>chains rules so context/severity build up.
Wazuh custom decoders — /var/ossec/etc/decoders/local_decoder.xml¶
<decoder name="myapp">
<prematch>^MyApp: </prematch>
<regex offset="after_prematch">user=(\S+) src=(\S+)</regex>
<order>srcuser, srcip</order> <!-- name the captured fields -->
</decoder>
Test before you deploy¶
/var/ossec/bin/wazuh-logtest # paste a raw log line; shows decoder + rule that fires
# older builds: /var/ossec/bin/ossec-logtest
systemctl restart wazuh-manager # reload rules/decoders after editing
Gotchas worth remembering¶
- Sigma is backend-agnostic; the pipeline does the translation. A rule uses generic field names —
-p sysmon/-p ecs_windowsremaps them to your SIEM's schema. Convert--without-pipelineand the raw field names may not match anything in the target log store. - A rule that converts is not a rule that fires.
sigma convertonly proves the syntax is valid. Run it against real events (the lab'sdetect.py/ your sample JSON): does it match the malicious event and stay quiet on the benign ones? Test data, not the model, tells you the logic is right. - Wazuh custom rules live at id 100000+. IDs below that belong to the shipped ruleset — reuse one
and an upgrade clobbers your rule or yours clobbers a built-in. Higher
level= higher severity. - Always
wazuh-logtesta rule before restarting the manager. A malformedlocal_rules.xmlcan stop the manager from loading its whole ruleset — one bad<field>silences everything. - Rule count is vanity; ATT&CK coverage is the metric. Map every rule to a technique and report the gap ("83% of Credential Access, these named gaps"), not "we have 200 rules."
- Treat detections as code. Version-control the
rules/directory, test each rule against known-bad and known-good telemetry in CI, and review changes — the detection-as-code discipline from Track 02.
Comments
Sign in with GitHub to comment. Choose the type: Feedback (errors or suggestions on this page) · Hints (help for fellow learners — no spoilers) · General (anything else).