单机器搭建

Sever

wazuh的server端安装可以参考官方文档

# 修改开放端口
sudo firewall-cmd --permanent --add-port=1514/tcp
sudo firewall-cmd --permanent --add-port=1515/tcp
sudo firewall-cmd --permanent --add-port=1516/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --permanent --add-port=55000/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
# 安装命令
wget https://packages.wazuh.com/4.9/wazuh-install.sh
chmod +x wazuh-install.sh
./wazuh-install.sh -a
# 重装命令:
./wazuh-install.sh -a -i -o
# 卸载命令:
./wazuh-install.sh -u

需要把防火墙都给打开,端口都开一下,不然安装后dashboard会启动不了,安装完成后,输出会显示访问凭证和一条确认安装成功的消息

INFO: --- Summary ---
INFO: You can access the web interface https://<wazuh-dashboard-ip>
User: admin
Password: <ADMIN_PASSWORD>
INFO: Installation finished.

还有一个更方便的方式直接使用OVA来安装,直接导入就行了

接着使用ip a来查看机器的地址

root@ascotbe:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:47:df:c6 brd ff:ff:ff:ff:ff:ff
altname enp2s1
inet 192.168.180.134/24 brd 192.168.180.255 scope global dynamic noprefixroute ens33
valid_lft 1016sec preferred_lft 1016sec
inet6 fe80::20c:29ff:fe47:dfc6/64 scope link
valid_lft forever preferred_lft forever

切记得使用https://you_ip来访问,切记https://不是http://

image-20241211113137872

然后输入admin/admin就可以了

Agent

关于Agent的安装官方文档也有写,针对Linux可以添加包管理器的安装方式

# 安装curl
apt install curl
# 添加秘钥
curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/wazuh.gpg --import && chmod 644 /usr/share/keyrings/wazuh.gpg
# 写入新的源
echo "deb [signed-by=/usr/share/keyrings/wazuh.gpg] https://packages.wazuh.com/4.x/apt/ stable main" | tee -a /etc/apt/sources.list.d/wazuh.list
# 更新源
apt-get update
# 安装agent
WAZUH_MANAGER="you_ip" apt-get install wazuh-agent
# 启动agent
systemctl daemon-reload
systemctl enable wazuh-agent
systemctl start wazuh-agent

如果是非出网机器可以集中管理安装包,然后使用命令来安装

image-20241211140713369

装好Agent后就可以在控制台中看到相关的数据了

image-20241211140825642

多集群搭建(Kubernetes)

Sever

root@ascotbe:# kubectl get pod -n wazuh
NAME READY STATUS RESTARTS AGE
wazuh-dashboard-66df465b84-25gsf 1/1 Running 0 79s
wazuh-indexer-0 1/1 Running 0 79s
wazuh-manager-master-0 1/1 Running 0 79s
wazuh-manager-worker-0 1/1 Running 0 79s

root@ascotbe:# kubectl get svc -n wazuh
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dashboard LoadBalancer 10.228.199.141 <pending> 443:32056/TCP 84s
indexer LoadBalancer 10.228.148.126 <pending> 9200:32066/TCP 84s
wazuh LoadBalancer 10.228.62.190 <pending> 1515:31122/TCP,55000:32230/TCP 84s
wazuh-cluster ClusterIP None <none> 1516/TCP 84s
wazuh-indexer ClusterIP None <none> 9300/TCP 84s
wazuh-workers LoadBalancer 10.228.149.23 <pending> 1514:30161/TCP 84s

Agent

Agent上线流程:

  • 首先需要请求一次55000端口(通过 Wazuh 服务器 API 注册)和1515端口(通过自动代理请求进行注册)的IP机器一次,用来进行秘钥注册
  • 接着需要长期请求1514端口(代理通信)的IP机器,用来上传数据

Windows

一键安装命令具体参数可以参考官方文档Deployment variables for Windows,如果是集群化的我们修改命令为

Invoke-WebRequest -Uri https://packages.wazuh.com/4.x/windows/wazuh-agent-4.10.0-1.msi -OutFile $env:tmp\wazuh-agent; msiexec.exe /i $env:tmp\wazuh-agent /q WAZUH_MANAGER='10.228.149.23' WAZUH_REGISTRATION_PASSWORD='password' WAZUH_AGENT_GROUP='default' WAZUH_REGISTRATION_SERVER='10.228.62.190' WAZUH_REGISTRATION_PORT='1515'  WAZUH_AGENT_NAME="test11"

接着使用命令来启动服务

NET START WazuhSvc

一键安装命令里面的临时文件夹位置可以这样查看

Write-Output $env:tmp

关于规则/解码器

Wazuh Agent 本身不会存放服务器的规则。Wazuh 的架构中,规则文件和配置主要存储在 Wazuh Manager 中,而不是 Wazuh Agent

目录文件

规则集目录结构如下所示:

/var/ossec/
├─ etc/
│ ├─ decoders/ # 自定义解释器目录
| | └─ local_decoder.xml
│ └─ rules/ # 自定义规则目录
| └─ local_rules.xml
└─ ruleset/
├─ decoders/ # 系统自带解释器目录
└─ rules/ # 系统自带规则目录
  • 在 ruleset/ 目录中存放通用规则和解码器。此目录内的所有文件在Wazuh更新过程中都会被覆盖或修改,请勿在此目录内编辑文件或添加自定义文件。
  • 如需执行自定义更改,使用 etc/ 目录。可以在此处添加自己的解码器/规则文件或使用默认的 local_decoder.xmllocal_rules.xml 文件

规则格式

规则示例

下面是Wazuh内置的对网络入侵检测引擎Suricata日志解析的规则示例,该规则示例在/var/ossec/ruleset/rules/0475-suricata_rules.xml文件中。

<group name="ids,suricata,">

<!--
{"timestamp":"2016-05-02T17:46:48.515262+0000","flow_id":1234,"in_iface":"eth0","event_type":"alert","src_ip":"16.10.10.10","src_port":5555,"dest_ip":"16.10.10.11","dest_port":80,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":2019236,"rev":3,"signature":"ET WEB_SERVER Possible CVE-2014-6271 Attempt in HTTP Version Number","category":"Attempted Administrator Privilege Gain","severity":1},"payload":"abcde","payload_printable":"hi test","stream":0,"host":"suricata.com"}
-->
<rule id="86600" level="0">
<decoded_as>json</decoded_as>
<field name="timestamp">\.+</field>
<field name="event_type">\.+</field>
<description>Suricata messages.</description>
<options>no_full_log</options>
</rule>

<rule id="86601" level="3">
<if_sid>86600</if_sid>
<field name="event_type">^alert$</field>
<description>Suricata: Alert - $(alert.signature)</description>
<options>no_full_log</options>
</rule>

<rule id="86602" level="0">
<if_sid>86600</if_sid>
<field name="event_type">^http$</field>
<description>Suricata: HTTP.</description>
<options>no_full_log</options>
</rule>

<rule id="86603" level="0">
<if_sid>86600</if_sid>
<field name="event_type">^dns$</field>
<description>Suricata: DNS.</description>
<options>no_full_log</options>
</rule>

<rule id="86604" level="0">
<if_sid>86600</if_sid>
<field name="event_type">^tls$</field>
<description>Suricata: TLS.</description>
<options>no_full_log</options>
</rule>

</group>

group

该标签用于对警报进行分类。它允许用户在Wazuh仪表板中筛选相关联的警报。每个规则必须至少属于一个组。通过为规则指定一个或多个组,可以将相似的警报归类到一起,从而便于管理和分析。下面规则示例中,规则所属组的名称为limits

<group name="limits">
<rule id="100234" level="3">
<if_sid>230</if_sid>
<field name="alert_type">normal</field>
<description>The file limit set for this agent is $(file_limit). Now, $(file_count) files are being monitored.</description>
</rule>
</group>

如果该规则属于多个组,可以将多个组名以逗号分割,赋值给name属性,下面规则示例中,规则所属组的名称为limits_1limits_2limits_3

<group name="limits_1,limits_2,limits_3">
<rule id="100234" level="3">
<if_sid>230</if_sid>
<field name="alert_type">normal</field>
<description>The file limit set for this agent is $(file_limit). Now, $(file_count) files are being monitored.</description>
</rule>
</group>

除此之外,还可以在规则内容中使用<group>标签定义其所属组名称,示例如下:

<group name="limits_1">
<rule id="100234" level="3">
<if_sid>230</if_sid>
<field name="alert_type">normal</field>
<description>The file limit set for this agent is $(file_limit). Now, $(file_count) files are being monitored.</description>
<group>,limits_2,limits_3</group>
</rule>
</group>

rule

该标签用于定义一个检测规则,它指定了何时以及如何生成安全警报。每个<rule>标签内包含了一系列定义特定规则行为的选项,例如匹配日志事件的条件、规则的严重性级别、描述和其他相关设置。下表为该标签支持的属性:

属性 取值范围 描述
id 1~999999 指定规则的唯一标识符。
level 0~16 指定规则的警报级别,这个级别用于确定警报的严重性。数字越大,表示严重性越高。
maxsize 1~9999 指定事件的最大大小。
frequency 2~9999 指定该规则产生警报前需要达到匹配的次数。
timeframe 1~999999 时间范围 (以秒为单位),此属性和 frequency 配合使用。
ignore 1~999999 触发此规则后忽略此规则的时间 (以秒为单位),一般用于避免警报泛滥。
overwrite yes/no 用于使用当前规则覆盖同名规则。
noalert 0 (警报,默认值) 1 (不警报) 标识当事件命中当前规则时是否产生警报。

下面是规则示例,该规则的标识ID为3151,且此规则在过去120s的时间如果命中了8次,则产生等级为10的警告:

<rule id="3151" level="10" frequency="8" timeframe="120">
<if_matched_sid>3102</if_matched_sid>
<same_source_ip />
<description>sendmail: Sender domain has bogus MX record. </description>
<description>It should not be sending email.</description>
<mitre>
<id>T1114</id>
<id>T1499</id>
</mitre>
<group>multiple_spam,pci_dss_11.4,gdpr_IV_35.7.d,nist_800_53_SI.4,tsc_CC6.1,tsc_CC6.8,tsc_CC7.2,tsc_CC7.3,</group>
</rule>

match

该标签用于定义一个正则表达式,该表达式会在日志事件的内容中进行搜索以查找匹配项。如果日志中的文本与<match>标签中定义的正则表达式相匹配,那么规则就可能会被触发,从而生成一个安全警报。下表为该标签支持的属性:

标签支持的属性:

属性 取值范围 描述
negate yes、no (默认值) 是否反转匹配策略,用来设置命中还是未命中所包含的正则表达式时命中该规则。
type osmatch (默认值)、osregex、pcre2 所包含正则表达式格式。

下面是规则示例,事件信息中如果包含**Queue flood!**语句,则该规则触发等级为 3 的警报。

<rule id="100001" maxsize="300" level="3">
<if_sid>100200</if_sid>
<match>Queue flood!</match>
<description>Flooded events queue.</description>
</rule>

regex

该标签的作用与<match>标签类似,但它专门用于定义一个正则表达式,用于在日志事件中搜索匹配项。<regex>标签提供了更多的灵活性和强大的模式匹配能力,因为它允许使用更复杂的正则表达式语法。下表为该标签支持的属性:

属性 取值范围 描述
negate yes、no (默认值) 是否反转匹配策略,用来设置命中还是未命中所包含的正则表达式时命中该规则。
type osmatch、osregex (默认值)、pcre2 所包含正则表达式格式。

下面是规则示例,事件信息中如果包含 IPv4 地址,则该规则触发等级为 3 的警报。

<rule id="100001" level="3">
<if_sid>100500</if_sid>
<regex>\b(?:\d{1,3}\.){3}\d{1,3}\b</regex>
<description>Matches any valid IP</description>
</rule>

decoded_as

该标签用于指定规则应该触发的解码器。解码器(decoder)是Wazuh中用于解析和提取日志文件中特定信息的组件。当日志事件被特定的解码器解析后,<decoded_as> 标签确保只有那些被特定解码器处理过的日志才会触发相应的规则。下面是规则示例,该规则只有成功经过名为"smtpd"的解码器解码触发此规则:

<rule id="53500" level="0">
<decoded_as>smtpd</decoded_as>
<description>OpenSMTPd grouping.</description>
</rule>

category

标签用于指定规则应该触发的日志类别。这个标签允许规则只对特定类型的日志事件生效,从而提高规则的针对性和减少误报。下面是规则示例,只有日志消息已经被syslog解码器处理过,当前规则才能被触发。

<rule id="1" level="0" noalert="1">
<category>syslog</category>
<description>Generic template for all syslog rules.</description>
</rule>

field

标签用于指定规则应该匹配的特定字段。这个标签通常与解码器结合使用,解码器负责从日志事件中提取信息,并将这些信息存储在字段中。<field>标签允许安全分析师和系统管理员创建更具体和精确的规则,以便在检测到特定字段值时触发警报。下表为该标签支持的属性:

属性 取值范围 描述
name 指定解码器所提取的字段名称。
negate yes no (默认值) 是否反转匹配策略。
type osregex (默认值) osmatch pcre2 所包含正则表达式格式。

下面是规则示例,该规则要求使用json解码器对日志内容进行解码,且检查被解码为integration字段的内容,如果这个字段的内容是virustotal,那么规则就会被触发:

<rule id="87100" level="0">
<decoded_as>json</decoded_as>
<field name="integration">virustotal</field>
<description>VirusTotal integration messages.</description>
<options>no_full_log</options>
</rule>

srcip

srcip标签用于指定规则应该匹配的源IP地址。这个标签通常与解码器结合使用,解码器负责从日志事件中提取信息,并将这些信息存储在字段中。

属性 取值范围 描述
negate yes no(默认值) 是否反转匹配策略

只有经过解码器解码并从日志信息中提取到源IP地址为10.25.23.12时命中此规则:

<rule id="100105" level="8">
<if_sid>100100</if_sid>
<srcip>10.25.23.12</srcip>
<description>Forbidden srcip has been detected.</description>
</rule>

dstip

dstip标签用于指定规则应该匹配的目的IP地址。这个标签通常与解码器结合使用,解码器负责从日志事件中提取信息,并将这些信息存储在字段中。

属性 取值范围 描述
negate yes no(默认值) 是否反转匹配策略

只有经过解码器解码并从日志信息中提取到目的IP地址不为198.168.41.30时命中此规则:

<rule id="100110" level="5">
<if_sid>100100</if_sid>
<dstip negate=”yes”>198.168.41.30</dstip>
<description>A different dstip has been detected.</description>
</rule>

srcport

srcport标签用于指定规则应该匹配的源端口号。这个标签通常与解码器结合使用,解码器负责从日志事件中提取信息,并将这些信息存储在字段中。

属性 取值范围 描述
negate yes no(默认值) 是否反转匹配策略
type osregex osmatch pcre2 所包含正则表达式格式

只有经过解码器解码并从日志信息中提取到源端口号在50000~50007范围时命中此规则:

<rule id="100110" level="5">
<if_sid>100100</if_sid>
<srcport type="pcre2">^5000[0-7]$</srcport>
<description>Source port $(srcport) is detected.</description>
</rule>

dstport

dstport标签用于指定规则应该匹配的目的端口号。这个标签通常与解码器结合使用,解码器负责从日志事件中提取信息,并将这些信息存储在字段中。

属性 取值范围 描述
negate yes no(默认值) 是否反转匹配策略
type osregex osmatch pcre2 所包含正则表达式格式

只有经过解码器解码并从日志信息中提取到目的端口号在50000~50007范围时命中此规则:

<rule id="100110" level="5">
<if_sid>100100</if_sid>
<dstport type="pcre2">^5000[0-7]$</dstport>
<description>Destination port $(dstport) is detected.</description>
</rule>

data

data标签用于定义规则应该匹配的特定数据内容。这个标签通常与解码器结合使用,解码器负责从日志事件中提取信息,并将这些信息存储在字段中。

属性 取值范围 描述
negate yes no(默认值) 是否反转匹配策略
type osregex osmatch pcre2 所包含正则表达式格式

extra_data

extra_data标签用于定义规则应该匹配的额外数据内容。这个标签通常与解码器结合使用,解码器负责从日志事件中提取信息,并将这些信息存储在字段中。

属性 取值情况 描述
negate yes no(默认值) 是否反转匹配策略
type osregex osmatch pcre2 所包含正则表达式格式

当日志文件属于Windows类别,并且解码后的字段extra_data显示为Symantec AntiVirus时,命中当前规则:

<rule id="7301" level="0">
<category>windows</category>
<extra_data>^Symantec AntiVirus</extra_data>
<description>Grouping of Symantec AV rules from eventlog.</description>
</rule>

time

用于指定规则应该触发的时间范围。这个标签允许您定义一个特定的时间窗口,例如,您可以设置规则仅在工作日的特定时间段内触发,或者在夜间不触发,以此来减少误报或针对特定时间段的威胁进行监控。下面是该标签允许的赋值格式:

hh:mm-hh:mm, hh:mm am-hh:mm pm, hh-hh, hh am-hh pm

该规则只有在下午6点到次日8点30命中时才算有效命中:

<rule id="17101" level="9">
<if_group>authentication_success</if_group>
<time>6 pm - 8:30 am</time>
<description>Successful login during non-business hours.</description>
<group>login_time</group>
</rule>

weekday

用于指定规则应该在哪些工作日触发警报。这个标签可以帮助管理员设置在特定日子(例如:工作日或周末)才需要关注的安全规则,从而更有效地管理和响应可能的安全事件。下面是该标签允许的赋值格式:

monday - sunday, weekdays, weekends

下面是规则示例,该规则只有在周六日命中时才算有效命中。

<rule id="17102" level="9">
<if_group>authentication_success</if_group>
<weekday>weekends</weekday>
<description>Successful login during weekend.</description>
<group>login_day,</group>
</rule>

location

用于指定规则应该在哪个数据源或日志文件中触发警报。这个标签可以帮助管理员定义规则的适用范围,例如,只针对来自特定应用程序或服务的日志。

if_sid

该标签用于创建派生规则,它指定当前规则是依赖于另一个规则(父规则)的。如果父规则被触发,并且满足当前规则的其他条件,那么当前规则也会被触发。这允许基于其他规则的结果来创建更具体的过滤和匹配,从而实现更复杂的检测逻辑。如果包含多个父规则则将规则ID以逗号分隔。下面是规则示例,规则ID为100110的父规则时ID为100100和100101的规则。

<rule id="100110" level="5">
<if_sid>100100, 100101</if_sid>
<match>Error</match>
<description>There is an error in the log.</description>
</rule>

if_group

该标签标识当前规则只有在特定组的规则已经匹配的情况下才会生效。下面是规则示例,当前规则命中的条件有两个:
(1)日志信息经过解码器解码提sysmon.image字段后,其值为lsm.exe;
(2)日志信息命中规则组sysmon_event1中的规则;

<rule id="184676" level="12">
<if_group>sysmon_event1</if_group>
<field name="sysmon.image">lsm.exe</field>
<description>Sysmon - Suspicious Process - lsm.exe</description>
<group>pci_dss_10.6.1,pci_dss_11.4,gdpr_IV_35.7.d,hipaa_164.312.b,nist_800_53_AU.6,nist_800_53_SI.4,</group>
</rule>

if_level

该标签用于指定当前规则是否命中取决于在之前是否有规则触发了指定级别的警报时触发。这个标签允许规则之间建立一种基于警报级别的依赖关系。

if_matched_sid

该标签用于指定当前规则是否命中取决于在之前某个指定的规则ID在一定时间范围内被触发了若干次后才触发。这个标签与<frequency><timeframe>标签一起使用,用于创建基于事件频率和时间范围的复合规则。下面是规则示例,当规则30315在120秒内被触发了10次,并且这些请求都是由同一个源IP地址发起的,那么就会触发当前规则。简单来说,就是如果一个IP地址在两分钟内连续触发了某个安全规则10次,那么就会触发另一个规则。这通常用于检测和防御网络攻击,比如DDoS攻击。

<rule id="30316" level="10" frequency="10" timeframe="120">
<if_matched_sid>30315</if_matched_sid>
<same_source_ip />
<description>Apache: Multiple Invalid URI requests from same source.</description>
<mitre>
<id>T1499</id>
</mitre>
<group>gdpr_IV_35.7.d,hipaa_164.312.b,invalid_request,nist_800_53_AU.14,nist_800_53_AC.7,nist_800_53_SI.4,pci_dss_10.2.4,pci_dss_11.4,tsc_CC6.1,tsc_CC6.8,tsc_CC7.2,tsc_CC7.3,</group>
</rule>

if_matched_group

该标签用于指定当前规则是否命中取决于某个指定的组在一定时间范围内被触发了若干次后才触发。这个标签与<frequency><timeframe>标签一起使用,用于创建基于事件频率和时间范围的复合规则。下面是规则示例,当某个被定义为“病毒组”中的规则在过去的360秒内被匹配了8次时,就会触发当前的规则。这通常用于网络安全或数据监控系统中,用来识别和响应潜在的威胁或异常行为。

<rule id="40113" level="12" frequency="8" timeframe="360">
<if_matched_group>virus</if_matched_group>
<description>Multiple viruses detected - Possible outbreak.</description>
<group>virus,pci_dss_5.1,pci_dss_5.2,pci_dss_11.4,gpg13_4.2,gdpr_IV_35.7.d,nist_800_53_SI.3,nist_800_53_SI.4,</group>
</rule>

same_id

该标签用于指定解码器中提取的ID字段值要相同,这个标签与<if_match_id><frequency><timeframe>标签一起使用。下面是规则示例,该规则要求在3800s内,规则ID为20152的规则命中至少5次,并且日志内容经过解码器解码后提取的id字段值要相同。

<rule id="20162" level="11" frequency="5" timeframe="3800">
<if_matched_sid>20152</if_matched_sid>
<same_id />
<ignore>id</ignore>
<description>Multiple IDS alerts for same id </description>
<description>(ignoring now this id).</description>
<group>pci_dss_10.6.1,pci_dss_11.4,gdpr_IV_35.7.d,</group>
</rule>

different_id

<same_id>相反,要求解码器解码提取的id字段值不同。

same_field

该标签用于指定一个动态字段的值必须在一定数量的先前事件中出现,这个标签与<frequency><timeframe>标签一起使用,用于创建基于事件频率和时间范围的复合规则。下面是使用示例。规则100001是规则100002的父规则,规则100002命中的条件是300s内规则100001规则命中至少4次,且经过解码器解码后的key2字段值相同。

<!-- {"key":"value", "key2":"AAAA"} -->
<rule id="100001" level="3">
<decoded_as>json</decoded_as>
<field name="key">value</field>
<description>Testing JSON alert</description>
</rule>

<rule id="100002" level="10" frequency="4" timeframe="300">
<if_matched_sid>100001</if_matched_sid>
<same_field>key2</same_field>
<description>Testing same_field option</description>
</rule>

different_field

<same_field>相反,要求不同字段值。

global_frequency

该标签用于指定当规则使用频率和时间范围选项时,会考虑所有代理的事件。默认情况下,只有由同一个代理生成的事件才会被计算在内,以增加规则的频率计数器。简单来说,就是用户可以选择是否将所有代理的事件都考虑在内,还是只考虑单个代理的事件,来决定某个规则的触发频率。

description

该标签用于给当前规则添加描述信息。示例如下:

<rule id="100005" level="8">
<match>illegal user|invalid user</match>
<description>sshd: Attempt to login using a non-existent user from IP $(attempt_ip)</description>
<options>no_log</options>
</rule>

info

用于为当前规则添加额外的信息。

属性 取值范围 描述
type text link cve ovsdb 文本描述 该规则相关的链接 与该规则相关的CVE编号

options

用于其它规则选项。

属性 描述
alert_by_email 规则命中时邮件提醒
no_email_alert 规则命中时从不邮件提醒
no_log 不记录此规则日志
no_full_log 不包含full_log字段的信息
no_counter 省略JSON格式的告警中rule.firedtimes中的值

下面是使用示例:

<rule id="9800" level="8">
<match>illegal user|invalid user</match>
<description>sshd: Attempt to login using a non-existent user</description>
<options>no_log</options>
</rule>

mitre

该标签用于将特定的安全规则与MITRE ATT&CK框架中的战术和技术关联起来。MITRE ATT&CK是一个知名的网络安全模型,它详细列出了网络攻击者可能使用的战术、技术和程序(TTPs),这些信息被广泛用于安全防御和威胁情报领域。

var

该标签用于定义一个变量,且该变量在当前规则文件中全局可用。下面是使用示例:

<var name="joe_folder">/home/joe/</var>

<group name="local,">

<rule id="100001" level="5">
<if_sid>550</if_sid>
<field name="file">^$joe_folder</field>
<description>A Joe's file was modified.</description>
<group>ossec,pci_dss_10.6.1,gpg13_10.1,gdpr_IV_35.7.d,</group>
</rule>

</group>

如何更改自带规则

将SSH 规则 5710 的级别值从 5 更改为 10

  1. 打开 /var/ossec/ruleset/rules/0095-sshd_rules.xml

  2. 从规则文件中查找并复制以下代码

    <rule id="5710" level="5">
    <if_sid>5700</if_sid>
    <match>illegal user|invalid user</match>
    <description>sshd: Attempt to login using a non-existent user</description>
    <mitre>
    <id>T1110</id>
    </mitre>
    <group>invalid_login,authentication_failed,pci_dss_10.2.4,pci_dss_10.2.5,pci_dss_10.6.1,gpg13_7.1,gdpr_IV_35.7.d,gdpr_IV_32.2,hipaa_164.312.b,nist_800_53_AU.14,nist_800_53_AC.7,nist_800_53_AU.6,tsc_CC6.1,tsc_CC6.8,tsc_CC7.2,tsc_CC7.3,</group>
    </rule>
  3. 将代码粘贴到/var/ossec/etc/rules/local_rules.xml中,修改level值,添加overwrite="yes"表示这条规则覆盖了一个已经定义好的规则

    <rule id="5710" level="10" overwrite="yes">
    <if_sid>5700</if_sid>
    <match>illegal user|invalid user</match>
    <description>sshd: Attempt to login using a non-existent user</description>
    <mitre>
    <id>T1110</id>
    </mitre>
    <group>invalid_login,authentication_failed,pci_dss_10.2.4,pci_dss_10.2.5,pci_dss_10.6.1,gpg13_7.1,gdpr_IV_35.7.d,gdpr_IV_32.2,hipaa_164.312.b,nist_800_53_AU.14,nist_800_53_AC.7,nist_800_53_AU.6,tsc_CC6.1,tsc_CC6.8,tsc_CC7.2,tsc_CC7.3,</group>
    </rule>

如何更改自带解码器

更改解码器文件 0310-ssh_decoders.xml 中的某些内容

  1. 将解码器文件 /var/ossec/ruleset/decoders/0310-ssh_decoders.xml 从默认文件夹复制到用户文件夹 /var/ossec/etc/decoders/0310-ssh_decoders.xml 以保留更改。

  2. 接着修改/var/ossec/etc/decoders/0310-ssh_decoders.xml中的内容,具体怎么改请看官方文档

  3. 修改/var/ossec/etc/ossec.conf中的内容,添加上 <decoder_exclude>,这样就不会从默认的解码器文件夹中加载指定的解码器,而是加载保存在用户文件夹中的解码器文件

    <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>

    <!-- User-defined ruleset -->
    <decoder_dir>etc/decoders</decoder_dir>
    <rule_dir>etc/rules</rule_dir>
    <!-- 下面这条是我们新添加的内容,要使其和路径地址对上,其他内容都是默认自带的 -->
    <decoder_exclude>ruleset/decoders/0310-ssh_decoders.xml</decoder_exclude>
    </ruleset>

解码器语法

解码器从接收到的事件中提取信息。当接收到事件时,解码器将信息分成块,为后续分析做准备。

解码器中的配置选项

选项 描述
decoder Name of the decoder 此属性定义解码器
parent Any decoder’s name 引用父解码器,当前解码器将成为子解码器
accumulate None 允许通过多个日志消息跟踪事件
program_name Any regex, sregex or pcre2 expression. 定义了与解码器关联的程序的名称
prematch Any regex or pcre2 expression. 预匹配,在日志中查找匹配项
regex Any regex or pcre2 expression. 查找所需的字段并提取它们。
order See order table 正则表达式将提取的值将存储在这些组中
fts See fts table 首次出现
ftscomment Any String 为 fts 添加注解
plugin_decoder See below 指定一个将进行解码的插件
use_own_name TRUE 仅适用于子解码器
json_null_field String 添加决定如何存储 JSON 中的空值的选项
json_array_structure String 添加决定如何存储来自 JSON 的数组结构的选项
var Name for the variable. 定义可以在同一个文件中重复使用的变量
type See type table 设置解码器要匹配的日志类型

详细用法: ruleset/ruleset-xml-syntax/decoders.html

规则语法

Wazuh 规则集与任何常用规则相结合,用于分析传入事件并在适当时生成警报。

用于配置规则的 xml 标签

选项 描述
rule See table below. 启动一个新规则及其定义选项
match Any regular expression. 使用 sregex 在日志中查找匹配项,从而决定是否应触发规则
regex Any regular expression. 与match相同,但默认使用正则表达式
decoded_as Any decoder’s name. 与已被特定解码器解码的日志匹配
category Any type. 匹配解码器类型一致的日志
field Name and any regular expression. 将解码器按顺序提取的字段与正则表达式进行比较
srcip Any IP address. 将 IP 地址与解码为 srcip 的 IP 进行比较。利用 !否定它
dstip Any IP address. 它将 IP 地址与解码为 dstip 的 IP 进行比较。利用 !否定它
srcport Any regular expression. 将表示端口的正则表达式与解码为 srcport 的值进行比较
dstport Any regular expression. 将表示端口的正则表达式与解码为 dstport 的值进行比较
data Any regular expression. 将表示数据的正则表达式与解码为data的值进行比较
extra_data Any regular expression. 将表示额外数据的正则表达式与解码为 extra_data 的值进行比较
user Any regular expression. 将表示用户的正则表达式与解码为user的值进行比较
system_name Any regular expression. 将表示系统名称的正则表达式与解码为 system_name 的值进行比较
program_name Any regular expression. 将表示程序名称的正则表达式与预解码为 program_name 的值进行比较
protocol Any regular expression. 将表示协议的正则表达式与解码为协议的值进行比较
hostname Any regular expression. 将表示主机名的正则表达式与预解码为主机名的值进行比较
time Any time range. e.g. (hh:mm-hh:mm) 检查事件是否在该时间范围内生成
weekday monday - sunday, weekdays, weekends 检查事件是否在某些工作日生成
id Any regular expression. 将表示 ID 的正则表达式与解码为 id 的值进行比较
url Any regular expression. 将表示 URL 的正则表达式与解码为 url 的值进行比较
location Any regular expression. 将表示位置的正则表达式与预解码为位置的值进行比较
action Any String or regular expression. 将表示动作的字符串或正则表达式与解码为动作的值进行比较
status Any regular expression. 将表示状态的正则表达式与解码为状态的值进行比较
srcgeoip Any regular expression. 将表示 GeoIP 源的正则表达式与解码为 srcgeoip 的值进行比较
dstgeoip Any regular expression. 将表示 GeoIP 目的地的正则表达式与解码为 dstgeoip 的值进行比较
if_sid A list of rule IDs separated by commas or spaces. 工作原理类似于父解码器。当列表中的规则 ID 先前已匹配时,它将匹配
if_group Any group name. 如果指定的组之前匹配过,它将匹配
if_level Any level from 1 to 16. 如果该级别已经被另一个规则触发,它将匹配
if_matched_sid Any rule ID (Number). 与if_sid类似,但只有在一段时间内触发过ID才会匹配
if_matched_group Any group name. 与 if_group 类似,但它只会在该组在一段时间内被触发时才会匹配
same_id None. 解码后的 id 必须相同
different_id None. 解码后的 id 必须不同
same_srcip None. 解码后的 srcip 必须相同
different_srcip None. 解码后的 srcip 必须不同
same_dstip None. 解码后的 dsrcip 必须相同
different_dstip None. 解码后的 dsrcip 必须不同
same_srcport None. 解码后的 srcport 必须相同
different_srcport None. 解码后的 srcport 必须不同
same_dstport None. 解码后的 dstport 必须相同
different_dstport None. 解码后的 dstport 必须不同
same_location None. location必须相同
different_location None. location必须不同
same_srcuser None. 解码后的 srcuser 必须相同
different_srcuser None. 解码后的 srcuser 必须不同
same_user None. 解码后的user必须相同
different_user None. 解码后的user必须不同
same_field None. 解码field必须与前面的字段相同
different_field None. 解码field必须与之前的字段不同
same_protocol None. 解码后的protocol必须相同
different_protocol None. 解码后的protocol必须不同
same_action None. 解码后的action必须相同
different_action None. 解码后的action必须不同
same_data None. 解码后的data必须相同
different_data None. 解码后的data必须不同
same_extra_data None. 解码后的extra_data必须相同
different_extra_data None. 解码后的extra_data必须不同
same_status None. 解码后的status必须相同
different_status None. 解码后的status必须不同
same_system_name None. 解码后的system_name必须相同
different_system_name None. 解码后的system_name必须不同
same_url None. 解码后的url必须相同
different_url None. 解码后的url必须不同
same_srcgeoip None. 解码后的 srcgeoip 必须相同
different_srcgeoip None. 解码后的 srcgeoip 必须不同
same_dstgeoip None. 解码后的 dstgeoip 必须相同
different_dstgeoip None. 解码后的 dstgeoip 必须不同
description Any String. 规则描述
list Path to the CDB file. 使用 ossec 列表执行 CDB 查找
info Any String. 用某些属性的额外信息
options See the table below. 可以使用的附加规则选项
check_diff None. 确定命令的输出何时更改
group Any String. 向警报添加其他组
mitre See Mitre table below. 包含符合规则的Mitre Technique IDs
var Name for the variable. Most used: BAD_WORDS 定义一个可以在同一文件内的任何地方使用的变量

详细用法:ruleset/ruleset-xml-syntax/rules.html

删除旧的Agent

当 Wazuh Server 已经注册了名为 xiaomi 的 Agent,重复注册时会发生冲突。

方法 1:重新注册

在 Wazuh Server 上删除的 xiaomi Agent的注册,然后重新注册。

  1. 在 Wazuh Server 上删除旧 Agent

    sudo /var/ossec/bin/manage_agents
    • 进入交互式界面后,输入 L 列出所有注册的 Agent。
    • 找到 xiaomi 对应的 ID。
    • 输入 R 然后输入该 Agent 的 ID,删除它。
  2. 在 Agent 上重新注册: 回到 Agent 机器上,运行以下命令:

    sudo /var/ossec/bin/agent-auth -m 192.168.180.134

方法 2:更改 Agent 名称

如果不想删除旧 Agent,可以在当前机器上更改 Agent 名称。

  1. 编辑 Agent 配置文件: 修改 /var/ossec/etc/ossec.conf 中的 <name> 节点,或者直接手动添加 <name>

    <ossec_config>
    <client>
    ...
    <name>new-xiaomi</name>
    </client>
    </ossec_config>
  2. 重新注册: 运行以下命令:

    sudo /var/ossec/bin/agent-auth -m 192.168.180.134

方法 3:重新安装

在 Wazuh Server 上删除 xiaomi Agent的注册,然后在xiaomi这台机器上重新安装。

  1. 在 Wazuh Server 上删除旧 Agent

    sudo /var/ossec/bin/manage_agents
    • 进入交互式界面后,输入 L 列出所有注册的 Agent。
    • 找到 xiaomi 对应的 ID。
    • 输入 R 然后输入该 Agent 的 ID,删除它。
  2. 在Wazuh Agent上卸载旧 Agent:

    一定要卸载干净不然安装各种错误

    # DEB(ubuntu)
    apt-get remove wazuh-agent
    apt-get remove --purge wazuh-agent
    systemctl disable wazuh-agent
    systemctl daemon-reload
    # RPM(CentOS)
    yum remove wazuh-agent
    rm -rf /var/ossec
    systemctl disable wazuh-agent
    systemctl daemon-reload

最后从新安装agent


验证

  1. 注册完成后,重启 Agent:

    sudo systemctl restart wazuh-agent
  2. 检查日志是否正常:

    sudo tail -f /var/ossec/logs/ossec.log

测试与规则封堵

  • Wuzuh Server:192.168.180.134
  • Wuzuh Agent:192.168.180.132
  • 攻击机器:192.168.180.1

直接使用ssh链接工具输入错误几次密码

image-20241212163305831

可以看到日志上面就有告警了,这个默认的规则为0095-sshd_rules.xml,截取其中的一点内容为

<rule id="5758" level="8">
<decoded_as>sshd</decoded_as>
<match>^error: maximum authentication attempts exceeded </match>
<description>Maximum authentication attempts exceeded.</description>
<mitre>
<id>T1110</id>
</mitre>
<group>authentication_failed,gpg13_7.1,</group>
</rule>

主动防御

Wazuh 预配置了以下 Linux 脚本,位于 /var/ossec/active-response/bin

脚本名称 描述
disable-account 通过设置 passwd-l 禁用帐户
firewall-drop 将 IP 添加到 iptables 拒绝列表
firewalld-drop 将 IP 添加到 firewalld drop列表
host-deny 将 IP 添加到 /etc/hosts.deny 文件
ip-customblock 自定义 OSSEC 块,可轻松修改以实现自定义响应
ipfw ipfw 创建的防火墙drop响应脚本
npf npf 创建的防火墙drop响应脚本
wazuh-slack 在 Slack 上发布修改
pf pf 创建的防火墙drop响应脚本
restart-wazuh ossec.conf 更改后自动重启 Wazuh
route-null 将 IP 地址添加到空路由

如果要配置active-response需要在/var/ossec/etc/ossec.conf中进行编辑

ossec.conf文件中的 Active Response 和 Command 部分配置主动响应

将 IP 添加到 iptables 拒绝列表

Command 部分

首先我们需要定义一个要执行的命令脚本,firewall-drop 命令配置为使用 firewall-drop 脚本。

<command>
<name>firewall-drop</name>
<executable>firewall-drop</executable>
</command>

Active Response 部分

当规则ID:5758触发时,主动响应配置为在所有系统上启动 firewall-drop 命令。这是一个超时为 700 秒的有状态响应。 <repeated_offenders> 标记通过特定 IP 地址增加每个后续攻击的超时期限

<active-response>
<command>firewall-drop</command>
<location>all</location>
<rules_id>5758</rules_id>
<timeout>700</timeout>
<repeated_offenders>30,60,120</repeated_offenders>
</active-response>

配置完成保存后重启wazuh-manager

sudo systemctl restart wazuh-manager
sudo systemctl status wazuh-manager

然后进行测试,首先ping一下,然后使用ssh链接疯狂请求使其超时,然后再ping一下,就可以得到下面的效果

PS C:\Users> ping 192.168.180.131

正在 Ping 192.168.180.131 具有 32 字节的数据:
来自 192.168.180.131 的回复: 字节=32 时间=2ms TTL=64
来自 192.168.180.131 的回复: 字节=32 时间=2ms TTL=64
来自 192.168.180.131 的回复: 字节=32 时间=2ms TTL=64
来自 192.168.180.131 的回复: 字节=32 时间=3ms TTL=64

192.168.180.131 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 2ms,最长 = 3ms,平均 = 2ms
PS C:\Users> ping 192.168.180.131

正在 Ping 192.168.180.131 具有 32 字节的数据:
请求超时。
请求超时。
请求超时。
请求超时。

192.168.180.131 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 0,丢失 = 4 (100% 丢失),
PS C:\Users>

image-20241212184159060

自定义主动防御

Wazuh 的 自定义主动响应(Active Response) 配置和脚本通常只需要在 Wazuh Manager 上进行操作,因为 Wazuh Manager 负责管理和处理安全事件,执行相应的响应操作

自定义脚本

首先需要在/var/ossec/active-response/bin/目录存放,自己写好的脚本

#!/bin/bash

# 记录传入的参数
echo "Received IP: $1" >> /var/log/firewall-drop.log
echo "Received Rule ID: $2" >> /var/log/firewall-drop.log

# 防火墙操作
iptables -A INPUT -s $1 -j DROP
echo "Blocked IP: $1" >> /var/log/firewall-drop.log

然后剩下步骤就和主动防御一样了

OSSEC Conf

直接看官方文档

syscollector

现在可以在sever端进行配置了,以前需要手动到agents里面配置的

<wodle name="syscollector">  <!-- 定义syscollector模块,负责收集系统信息 -->
<disabled>no</disabled> <!-- 启用syscollector模块(no表示启用,yes表示禁用) -->
<interval>1h</interval> <!-- 设置收集系统信息的时间间隔,这里设置为每1小时收集一次,例如30m(30分钟)或2h(2小时) -->
<scan_on_start>yes</scan_on_start> <!-- 启动时是否进行扫描(yes表示启动时扫描,no表示不扫描) -->
<hardware>yes</hardware> <!-- 是否收集硬件信息(yes表示启用收集硬件信息,no表示不收集) -->
<os>yes</os> <!-- 是否收集操作系统信息(yes表示启用收集操作系统信息,no表示不收集) -->
<network>yes</network> <!-- 是否收集网络信息(yes表示启用收集网络设备信息,no表示不收集) -->
<packages>yes</packages> <!-- 是否收集已安装的软件包信息(yes表示启用收集软件包信息,no表示不收集) -->
<ports all="no">yes</ports> <!-- 是否收集端口信息(yes表示收集,all="no"表示不会扫描所有端口,只扫描特定端口) -->
<processes>yes</processes> <!-- 是否收集进程信息(yes表示启用收集进程信息,no表示不收集) -->

<!-- 数据库同步设置 -->
<synchronization>
<max_eps>10</max_eps> <!-- 设置每秒最大事件数(EPS)。这里设置为10,表示每秒最多同步10条事件数据 -->
</synchronization>
</wodle>

command

远程命令可以在集中配置中指定,但是,出于安全原因,它们默认处于禁用状态。

在共享代理配置中设置命令时,必须为 Agent 模块启用远程命令

通过将以下行添加到代理中的文件etc/local_internal_options.conf来启用此功能:

wazuh_command.remote_commands=1