haadi@portfolio: ~

haadi@portfolio:~$ cat wazuh-privilege-escalation-rules.md

Security research · Detection engineering

Detecting Linux privilege escalation with custom Wazuhrules

Three rules for sudo abuse the default ruleset doesn't cover, how each was tuned against false positives, tested against a real simulated attack, and mapped to ATT&CK.

Three custom rules covering common ways a Linux account gets escalated sudo access, none of which are meaningfully covered by Wazuh's default ruleset on their own.

All three build on existing default rules using <if_sid> / <if_matched_sid> rather than parsing raw log lines from scratch: see local_rules.xml for the full definitions.

The rules

Rule IDScenarioBuilt onLevelMITRE ATT&CK
100101Multiple failed sudo authentication attemptsDefault rule 5401 + frequency=2, timeframe=6012T1548.003
100102User added to the sudo groupDefault rule 5402 + match on usermod -aG sudo12T1098
100103Unauthorized user attempted to use sudoDefault rule 540511T1548.003

Why these three

A single failed sudo attempt is normal: everyone mistypes a password. A single unauthorized sudo attempt from an account that was never given access is not. The tuning on each rule reflects that difference:

  • 100101 requires the failure to repeat twice within 60 seconds before firing, so it catches a brute-force pattern without alerting on every typo.
  • 100102 is scoped to the exact usermod -aG sudo command rather than any group change, since group modifications happen for all kinds of harmless reasons (docker, www-data, etc.).
  • 100103 has no frequency requirement at all: a denied sudo attempt from an account with no sudo access is inherently suspicious on the first try, so waiting for repetition would only slow detection down.

Installing

# Copy into Wazuh's local rules file (custom rules go here, not the
# default rule files, so they survive a Wazuh update)
sudo cp local_rules.xml /var/ossec/etc/rules/local_rules.xml

# Restart the manager to load the new rules
sudo systemctl restart wazuh-manager

Testing

Each rule was verified against a real simulated attack on a throwaway Linux account. Commands used and expected results:

100101: repeated failed sudo auth

su - testuser
sudo ls        # enter wrong password
sudo ls        # enter wrong password again within 60s

Expect: alert on Rule 100101, Level 12.

100102: user added to sudo group

sudo adduser employee3
sudo usermod -aG sudo employee3

Expect: alert on Rule 100102, Level 12.

100103: unauthorized sudo attempt

sudo adduser guest1
su - guest1
sudo ls        # guest1 is not in sudoers

Expect: alert on Rule 100103, Level 11.

Screenshots of each detection are in ../screenshots/custom-detection-rules/.

Notes · things that tripped me up

  • Rule 100102 didn't fire on the first attempt: the match condition was checking a slightly different field than the one the default decoder actually populates. Pulling the raw decoded event for a manual test and reading the actual field name fixed it.
  • Rule 100101's timing needs the two failed attempts close together: if the gap between them is longer than the timeframe, Wazuh treats them as two unrelated single events instead of one pattern.

Originally published on GitHub

view-source
haadi@portfolio: ~

haadi@portfolio:~$ cat meta

  1. category: security research
  2. event: Detection engineering
  3. topic: Wazuh · MITRE ATT&CK
  4. difficulty: not listed
  5. published: 2026.07.22
  6. read: 2 min

Next writeup

Keepreading