| Level | Title | Examples |
|---|---|---|
| 0 | Ignored | No action taken. Used to avoid false positives. |
| 2 | Low priority notification | System notification with no security relevance. |
| 3 | Authorized events | Successful login attempts, firewall allow events, etc. |
| 4 | System low priority error | Errors related to bad configurations or unused applications. |
| 5 | User generated error | Missed passwords, denied actions, etc. |
| 6 | Low relevance attack | An attack that does not affect the system |
| 7 | “Bad word” matching | Events that have words like “bad”, “error”, etc. |
| 8 | First time seen | First time an IDS event is fired or the first time an user logged in. |
| 9 | Error from invalid source | Attempts to login as an unknown user or from an invalid source. |
| 10 | Multiple user errors | Multiple bad passwords, multiple failed logins, etc. |
| 11 | Integrity checking warning | Modification of binaries or the presence of rootkits. |
| 12 | High relevance event | Error or warning messages from the system, kernel, etc. |
| 13 | Unusual error | Most of the times it matches a common attack pattern. |
| 14 | High security event | Most of the times done with correlation and it indicates an attack. |
| 15 | Severe attack | No chances of false positives. Immediate attention is necessary. |
| Option | Values | Description |
|---|---|---|
| rule | All below | Its starts a new rule and its defining options. |
| match | Sregex regular expression | Matches anywhere on the log using simple SRegex. |
| regex | Any regular expression | Matches with the OS Regex syntax. |
| decoded_as | Any decoder’s name | Matches logs decoded by a specific decoder. |
| field | Any regular expression | Matches a specific decoded field using Regex. |
| srcip | Any IP address | Matches the value decoded as srcip. |
| dstip | Any IP address | Matches the value decoded as dstip. |
| user | Any regular expression | Matches a value decoded as user. |
| program_name | Any regular expression | Matches the value pre-decoded as program_name. |
| hostname | Any regular expression | Matches the value pre-decoded as hostname. |
| time | Any time range | Matches if the event is seen within a specific time range. |
| weekday | Monday - Sunday, weekends | Matches if the event was observed on certain weekdays. |
| list | Path to the CDB file | Performs a CDB lookup using an ossec list. |
| options | alert_by_email, no_full_log, etc | Additional rule options that can be used. |
| check_diff | None | Determines when the output of a command changes. |
| group | Any String | Add additional groups to the alert. |
| Option | Description |
|---|---|
| rule | For composite rules it will specify the frequency, timeframe, ignore properties |
| if_matched_sid | Matches if events with an ID have been triggered in a period of time. |
| if_matched_group | Matches if events within a group have been triggered in a period of time. |
| same_srcip | The decoded srcip must be the same. |
| different_srcip | The decoded srcip must be different. |
| same_dstip | The decoded dstip must be the same. |
| different_dstip | The decoded dstip must be different. |
| same_location | The location must be the same. |
| different_location | The location must be different. |
| same_srcuser | The decoded srcuser must be the same. |
| different_srcuser | The decoded srcuser must be different. |
| not_same_agent | The decoded agent must be different. |
| same_field | The decoded field must be the same as the previous ones. |
| different_field | The decoded field must be different than the previous ones. |
<rule id="100102" level="0">
<decoded_as>fakeinc_custom</decoded_as>
<description>Parent rule for Fakeinc custom</description>
</rule>
Lab Exercise 3A: Modify an existing rule
| Lab Objective: | Modify an existing rule by altering its level. |
|---|
sshd rule:
<rule id="5706" level="6">
<if_sid>5700</if_sid>
<match>Did not receive identification string from</match>
<description>SSH insecure connection attempt (scan).</description>
<group>recon,pci_dss_11.4,</group>
</rule>
Definition
Decoders are designed to extract any relevant data received from events
Wazuh rules commonly use matching criteria that refers to one or more specific fields extracted by decoders, rather that matching for patterns across whole events. This makes them more accurate.
Log Sample: Mar 17 13:00:01 linux_server syslogd: stopped
Predecoded event
Field Description hostname linux_server program_name syslogd time/date Mar 17 13:00:01 log stopped
| Option | Description |
|---|---|
| decoder | This attribute defines the decoder. |
| parent | Decoder will be considered if the decoder specified here is matched. |
| program_name | Decoder will be considered if this is the predecoded value for program_name. |
| prematch | It will look for a match in the log. In case it does, the decoder will be used. |
| regex | The decoder will use this option to find fields of interest and extract them. |
| order | The values that regex will extract will be stored in these groups. |
| fts | Flags a field to keep track of the first time a value is seen. |
| ftscomment | Adds a comment to fts. |
| plugin_decoder | Specifies a built-in plugin to be used |
| use_own_name | Only for child decoders. |
| json_null_field | Adds the option of deciding how a null value from a JSON will be stored. |
| json_array_structure | Adds the option of deciding how an array structure from a JSON will be stored. |
| accumulate | It allows tracking events over multiple log messages. |
| var | Defines variables that can be reused inside the same file. |
\w -> A-Z, a-z, 0-9, '-', '@', '_' characters
\d -> 0-9 characters
\s -> Spaces " "
\t -> Tabs
\p -> ()*+,-.:;<=>?[]!"'#$%&|{}
\W -> Anything not w
\D -> Anything not d
\S -> Anything not s
\. -> Anything
Let’s write a simple decoder for this log event:
Example of a simple log event:
2016-04-29T10:01:04.600374-04:00 manager myprogram[9123]: test connection from 192.168.1.1 via test-protocol1
Example of our new decoder:
<decoder name="myprogram"> <program_name>myprogram</program_name> </decoder>
Example of our Child decoder:
<decoder name="myprogram-test-connection"> <parent>myprogram</parent> <prematch>^test connection </prematch> <regex offset="after_prematch">^from (\S+) via (\S+)$</regex> <order>srcip, protocol</order> </decoder>
We’re referencing the decoder from before “myprogram” and adding new parameters to extract the SRC IP address and the protocol field.
Let’s see how Wazuh picks this up …
- Full_event: '2017-09-02T10:01:04.600374-04:00 manager myprogram[9123]: test connection
from 192.168.1.1 via test-protocol1'
- hostname: 'manager'
- program_name: 'myprogram'
- log: 'test connection from 192.168.1.1 via test-protocol1'
- decoder: 'myprogram'
- srcip: '192.168.1.1'
- protocol: 'test-protocol1'
Lab Exercise 3B: Write a custom decoder
| Lab Objective: | Write a custom decoder that extracts the result, username and source IP address from the following log message. |
|---|
Dec 4 17:07:01 myserver Fakeinc: Accepted password for user test2, IP: 1.2.3.4
Lab Exercise 3C: Write a custom rule family
| Lab Objective: | Write custom rules that classify the following log messages. Assign the appropriate alert levels according to the previously presented “Rule Severity Levels” table. |
|---|
Dec 4 17:07:01 myserver Fakeinc: Accepted password for user test2, IP: 1.2.3.4
Dec 4 17:07:01 myserver Fakeinc: Failed password for user test, IP: 1.2.3.4
Dec 4 17:07:01 myserver Fakeinc: Application is shutting down: Internal error
Dec 4 17:07:01 myserver Fakeinc: DEBUG: Received OK.
Lab Exercise 3D: Write a more advanced custom rule
| Lab Objective: | Write a custom rule that alerts when a specific user logs into a specific server during a specific time window. Base this rule on an existing SSHD rule. |
|---|
Lab Exercise 3E: Integrate Suricata
| Lab Objective: | Deploy Suricata on an agent, configure it to write JSON, and Wazuh to collect the logs so it may dynamically decode them. |
|---|
There are three categories of items that together make up the full ruleset that the Wazuh manager uses to analyse log events.
Decoders:
- Stock decoder files in /var/ossec/ruleset/decoders/
- Local decoder files in /var/ossec/etc/decoders/
- Decoders are grouped in files by family with parent/child relationships, and are identified by decoder name.
Rules:
- Stock rule families are in /var/ossec/ruleset/rules/
- Local rule families are in /var/ossec/etc/rules/
- Rules are grouped in files by family with parent/child relationships, and are uniquely identified by rule id #.
Lists:
- Dynamic lists are referenced by various rules as matching criteria
- Stock and local lists in individual files in /var/ossec/etc/lists/
This section of ossec.conf on the Wazuh manager identifies the various sources making up your full ruleset, with the locations always relative to the /var/ossec/ directory.
<ruleset>
<!-- Default ruleset -->
<decoder_dir>ruleset/decoders</decoder_dir>
<rule_dir>ruleset/rules</rule_dir>
<rule_exclude>0215-policy_rules.xml</rule_exclude>
<list>etc/lists/audit-keys</list>
<list>etc/lists/amazon/aws-eventnames</list>
<list>etc/lists/security-eventchannel</list>
<!-- User-defined ruleset -->
<decoder_dir>etc/decoders</decoder_dir>
<rule_dir>etc/rules</rule_dir>
</ruleset>
Wazuh encourages everyone to contribute new rules & decoders to the Wazuh GitHub repo!
Lab Exercise 4A: Filebeat pipeline enhancement
| Lab Objective: | Make several enhancements to the pipeline controlled by the Wazuh Filebeat module, and explore their impact on Suricata IDS events and other events with extracted IP address fields. |
|---|
What does FIM do?
FIM periodically calculates and records the unique cryptographic checksum and other attributes of specified files, and alerts when such files have been modified.
Wazuh Syscheck options
<syscheck>
<frequency>21600</frequency>
<directories realtime="yes" check_all="yes">/usr/bin,/usr/sbin</directories>
<directories whodata="yes" check_all="yes">/etc,/bin,/sbin</directories>
</syscheck>
Lab Exercise 4B: Set up and test syscheck
| Lab Objective: | Configure syscheck to do periodic scans and realtime monitoring. Generate various file change events and observe the resulting alerts. |
|---|
Lab Exercise 4C: Scan for vulnerable software
| Lab Objective: | Use syscollector and vulnerability-detector to find known vulnerable versions of software on agents and the manager. |
|---|
Definition
A rootkit is a program that can hide itself as well as running processes, file or network connections from the host where it’s running.
It can change access rights of files and directories.
Two kinds of rootkits:
- User-mode (user level) rootkit: covertly replaces common UNIX binaries or libraries with infected versions to hide its existence and to gain root privileges if needed.
- Kernel-mode (system level) rootkit: modifies or replaces the kernel.
The rootcheck module looks for possible intercepted system calls that may be hiding files and processes.
Lab Exercise 4D: Rootkit Detection
| Lab Objective: | Install a rootkit on the linux-agent machine and see how Wazuh detects it. |
|---|