开源HIDS之Wazuh探究

Wazuh 是一款开源和企业级的安全平台,诞生于OSSEC HIDS,后来与Elastic Stack和OpenSCAP集成,演变成更全面的解决方案,用于威胁检测、完整性监控、事件响应和合规审计,本文记录Wazuh使用体验、探究各项检测能力...

0x01 基础简介

1. 组成架构

架构图

Wazuh 架构基于agent,在受监控的端点上运行,采集数据转发到服务端server,agent 与 server 之间的通信是通过 AES 加密后传输;server对传入的信息进行解码和分析,并将结果传递给 Wazuh 索引器进行索引和存储;Wazuh 索引器集群是一个或多个节点的集合,这些节点相互通信以对索引执行读写操作;当数据被 Wazuh 索引器索引,可使用Wazuh 仪表板挖掘和查看信息。

agent - server通信: 代理与服务器服务建立连接以进行代理连接,默认情况下监听端口 1514(可配置),Wazuh 消息协议默认使用 AES 加密,每个块 128 位和 256 位密钥。

server - index通信: Wazuh 服务器使用 Filebeat 将警报和事件数据发送到 Wazuh 索引器,使用 TLS 加密。Filebeat 读取 Wazuh 服务器输出数据并将其发送到 Wazuh 索引器(默认监听端口 9200/TCP)。Wazuh 仪表板查询 Wazuh RESTful API(默认监听 Wazuh 服务器上的端口 55000/TCP)以显示 Wazuh 服务器和代理的配置和状态相关信息

Agent

Wazuh Agent支持多平台部署,可部署在电脑、台式机、服务器、云实例或虚拟机等端点上。它们提供威胁预防、检测和响应功能。Agent具有模块化架构,其中不同组件负责各自的任务:监视文件系统,读取日志消息,收集清单数据,扫描系统配置,查找恶意软件等,用户可以通过配置启用或禁用代理模块设置。

模块 描述
Log collector 收集系统和应用程序日志及windows事件等日志
Command execution 代理周期性运行命令并将输出结果发送到server端进行分析
File integrity monitoring (FIM) 文件信息监控,在文件修改时将相关信息发送给server端进行分析
Security configuration assessment (SCA) 根据CIS标准来检查现有的安全策略,也可以自定义SCA
System inventory 定期扫描系统信息(比如系统版本,网卡,运行进程,已安装的程序,打开的端口等信息)
Malware detection 恶意软件扫描,基于non-signature检测异常的程序或rootkit的存在,通过监视系统调用,它将查找隐藏的进程,隐藏的文件和隐藏的端口等
Active response 检测到威胁时,此模块将自动执行相关操作,比如阻止网络连接,停止正在运行的进程或删除恶意文件,用户也可以在必要时创建自定义响应
Containers security monitoring 此代理模块与Docker Engine API集成在一起以监视容器化环境中的更改,例如它检测到容器镜像,网络配置或数据量的更改,它还会警告以特权模式运行的容器以及正在运行的容器中执行命令的用户
Cloud security monitoring 云提供商安全检测,它能够检测到云基础架构的更改(例如,创建新用户,修改安全组,停止云实例等),并收集云服务日志数据(AWS Cloudtrail,AWS Macie,AWS GuardDuty,Azure Active Directory等)

Server

Wazuh 服务器分析从代理接收的数据。它通过解码器和规则对其进行处理,使用威胁情报来寻找公开信标 (IOC),在检测到威胁或异常时触发警报, 它还用于远程管理代理配置并监视其状态。

模块 描述
Agents registration service 给每个代理分配一个唯一的预共享身份验证密钥来注册新代理,并支持通过TLS/SSL证书或提供固定密码进行身份验证
Agents connection service 该组件用于接受agent发送来的数据,利用预共享密钥来验证代理身份和加密代理与Wazuh服务器之间的通信及此将配置推送给远程的agent
Analysis engine 进行数据分析,将agent传送过来的数据进行分析,利用解码器来识别正在处理的信息的类型,通过使用规则,它可以识别解码事件中的特定模式,从而触发警报,甚至可能要求采取自动对策(比如防火墙禁止ip等)
Wazuh RESTful API 管理代理和服务器配置设置,监视基础结构状态和整体运行状况,管理和编辑Wazuh解码器和规则等
Wazuh cluster daemon 此服务用于水平扩展Wazuh server,将它们部署为群集,这种配置与网络负载平衡器相结合,可提供高可用性和负载平衡(Wazuh server用来相互通信并保持同步的工具)
Filebeat 用于将事件和警报发送到es,它读取Wazuh分析引擎的输出并实时发送事件,当连接到多节点Elasticsearch集群时,它还提供负载均衡

默认端口列表

2. 安装部署

快速安装

1
2
3
4
5
curl -sO https://packages.wazuh.com/4.3/wazuh-install.sh && sudo bash ./wazuh-install.sh -a

# 重装命令:sudo bash ./wazuh-install.sh -a -i -o

# 卸载命令:sudo bash ./wazuh-install.sh -u

安装完成后,输出会显示访问凭证和一条确认安装成功的消息

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

查找Wazuh 索引器和 Wazuh API 用户的密码

1
sudo tar -O -xvf wazuh-install-files.tar wazuh-install-files/wazuh-passwords.txt

Agent安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
1) Linux安装

rpm -ivh https://packages.wazuh.com/4.x/yum/wazuh-agent-4.3.10-1.x86_64.rpm --nodeps --force

# 修改/var/ossec/etc/ossec.conf,MANAGER_IP修改为server的地址

systemctl daemon-reload
systemctl enable wazuh-agent
systemctl start wazuh-agent

# 默认安装位置:/var/ossec

2)Windows安装

Invoke-WebRequest -Uri https://packages.wazuh.com/4.x/windows/wazuh-agent-4.3.10-1.msi -OutFile ${env:tmp}\wazuh-agent-4.3.10.msi; msiexec.exe /i ${env:tmp}\wazuh-agent-4.3.10.msi /q WAZUH_MANAGER='192.168.10.10' WAZUH_REGISTRATION_SERVER='192.168.10.10'

NET START WazuhSvc

# 默认安装位置:C:\Program Files (x86)\ossec-agent

3)macOS安装

curl -sO https://packages.wazuh.com/4.x/macos/wazuh-agent-4.3.10-1.pkg

launchctl setenv WAZUH_MANAGER "10.0.0.2" && installer -pkg wazuh-agent-4.3.10-1.pkg -target /

/Library/Ossec/bin/wazuh-control start

# 默认安装位置:/Library/Ossec/

0x02 配置管理

1. Server管理

Wazuh 管理器是一个系统,它分析从所有注册代理收到的数据,并在事件符合规则时触发警报。管理器在本地机器上充当代理,它具有代理所具有的所有功能。此外,管理器可以转发它通过系统日志、电子邮件或集成的外部 API 触发的警报。

a. 远程服务配置

远程服务的配置是通过 ossec.conf 文件使用 <remote> XML 标记完成

1
2
3
4
5
<ossec_config>
<remote>
<local_ip>10.0.0.10</local_ip>
</remote>
</ossec_config>

设置管理器监听 IP 地址 10.0.0.10

修改后需重启服务生效

1
systemctl restart wazuh-manager

b. 定义告警等级阈值

管理器将根据事件匹配规则集中的规则为事件分配严重性级别,默认情况下,只会记录严重级别为 3 或更高的警报

警报级别阈值使用 <alerts> XML 标记在 ossec.conf 文件中配置

1
2
3
4
5
<ossec_config>
<alerts>
<log_alert_level>6</log_alert_level>
</alerts>
</ossec_config>

设置存储在 alerts.log 或 alerts.json 文件中的警报的最低严重性级别

修改后需重启服务生效

1
systemctl restart wazuh-manager

c. 集成外部API

Integrator 守护进程允许 Wazuh 连接到外部 API 和警报工具,例如 Slack、PagerDuty 和 VirusTotal等

在/var/ossec/etc/ 目录下 ossec.conf 文件中配置,在 <ossec_config> 部分添加以下配置

1
2
3
4
5
6
7
8
9
10
11
<integration>
<name> </name>
<hook_url> </hook_url> <!-- Required for Slack -->
<api_key> </api_key> <!-- Required for PagerDuty and VirusTotal -->

<!-- Optional filters -->
<rule_id> </rule_id>
<level> </level>
<group> </group>
<event_location> </event_location>
</integration>

修改后需重启服务生效

1
systemctl restart wazuh-manager

d. 配置 syslog 输出

Syslog 输出在 ossec.conf 文件中配置

1
2
3
4
5
6
7
8
9
10
<ossec_config>
<syslog_output>
<level>9</level>
<server>192.168.1.241</server>
</syslog_output>

<syslog_output>
<server>192.168.1.240</server>
</syslog_output>
</ossec_config>

上述配置将向 192.168.1.240 发送警报,如果警报级别高于 9,也会向 192.168.1.241 发送警报

修改后需重启服务生效

1
systemctl restart wazuh-manager

e. 生成自动化报告

可使用 ossec.conf 文件中的 report 选项来配置您自己的自定义报告

将所有 syscheck 警报的每日报告发送到 example@test.com

1
2
3
4
5
6
7
<ossec_config>
<reports>
<category>syscheck</category>
<title>Daily report: File changes</title>
<email_to>[email protected]</email_to>
</reports>
</ossec_config>

规则也可以按级别、来源、用户名、规则 ID 等进行过滤

发送报告,其中包含所有触发级别高于 10 的规则

1
2
3
4
5
6
7
<ossec_config>
<reports>
<level>10</level>
<title>Daily report: Alerts with level higher than 10</title>
<email_to>[email protected]</email_to>
</reports>
</ossec_config>

f. 配置邮件警报

Wazuh 可以配置为在触发某些规则或每日事件报告时向一个或多个电子邮件地址发送电子邮件警报

通用邮件选项

在 ossec.conf 文件 <global> 中配置电子邮件设置

1
2
3
4
5
6
7
8
<ossec_config>
<global>
<email_notification>yes</email_notification>
<email_to>[email protected]</email_to>
<smtp_server>mail.test.com</smtp_server>
<email_from>[email protected]</email_from>
</global>
</ossec_config>

配置完成后,需要将 email_alert_level 设置为将触发电子邮件的最低警报级别。默认情况下,此级别设置为 12

1
2
3
4
5
<ossec_config>
<alerts>
<email_alert_level>10</email_alert_level>
</alerts>
</ossec_config>

精细化邮件配置

基于级别的邮件

当级别大于或等于 4 的规则被触发时,向 you@example.com 发送电子邮件

1
2
3
4
5
<email_alerts>
<email_to>[email protected]</email_to>
<level>4</level>
<do_not_delay />
</email_alerts>

基于级别和agent的邮件

event_location 字段可以配置为监控特定日志、主机名或网络 (IP),当规则在server1机器上触发时发送告警

1
2
3
4
5
<email_alerts>
<email_to>[email protected]</email_to>
<event_location>server1</event_location>
<do_not_delay />
</email_alerts>

基于规则 ID 的邮件

当触发规则 515 或 516 时发送邮件警报

1
2
3
4
5
<email_alerts>
<email_to>[email protected]</email_to>
<rule_id>515, 516</rule_id>
<do_not_delay />
</email_alerts>

基于 group 的邮件

当属于 pci_dss_10.6.1 组的任何规则在任何 Wazuh 监控设备上触发时,将发送警报

1
2
3
4
<email_alerts>
<email_to>[email protected]</email_to>
<group>pci_dss_10.6.1,</group>
</email_alerts>

多选项/多邮件配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<ossec_config>
<email_alerts>
<email_to>[email protected]</email_to>
<event_location>server1|server2</event_location>
</email_alerts>
<email_alerts>
<email_to>[email protected]</email_to>
<event_location>/log/secure$</event_location>
</email_alerts>
<email_alerts>
<email_to>[email protected]</email_to>
<event_location>192.168.</event_location>
</email_alerts>
<email_alerts>
<email_to>[email protected]</email_to>
<level>12</level>
</email_alerts>
</ossec_config>

配置说明:

1
2
3
4
5
6
7
1) 如果server1 或server2 上的任何警报被触发,请发送电子邮件至 [email protected]

2) 如果警报来自 /log/secure/,则发送电子邮件至 [email protected]

3) 如果警报来自 192.168.0.0/24 网络上的任何机器,则发送电子邮件至 [email protected]

4) 如果警报级别等于或高于 12,则发送电子邮件至 [email protected]

2. Agent 管理

a. Agent生命周期

注册agent

注册代理将保留在管理器中,直到被用户删除。代理在任何给定时间可能处于四种不同的状态

agent状态

状态 描述
Never connected 代理已注册但尚未连接到管理器
Pending 身份验证过程尚未完成,管理器收到了来自agent的连接请求,但未收到其他内容,长期此状态可能防火墙导致
Active agent已成功连接,现在可以与管理器通信
Disconnected 如果在 agents_disconnection_time(默认 10m 时间)内没有收到任何keep alive消息,管理器将认为agent已断开连接

删除agent

当agent从管理器中移除时,生命周期结束。可以通过 Wazuh API、命令行或 Authd(如果启用了强制选项)来完成

b. 列出agent

1
2
3
4
5
6
7
8
9
10
11
12
13
1) 使用CLI

/var/ossec/bin/agent_control -l

/var/ossec/bin/manage_agents -l

2) 使用Wazuh API

curl -k -X GET "https://localhost:55000/agents?pretty=true&sort=-ip,name" -H "Authorization: Bearer $TOKEN"

3) 使用Wazuh app

可以转到 Wazuh app中的Agent选项,列出并查看所有注册agent的基本信息

c. 移除agent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1) 使用CLI

/var/ossec/bin/manage_agents

/var/ossec/bin/manage_agents -r 001

2)使用Wazuh API

TOKEN=$(curl -u <user>:<password> -k -X GET "https://localhost:55000/security/user/authenticate?raw=true")

# Removing agents in a list
curl -k -X DELETE "https://localhost:55000/agents?pretty=true&older_than=0s&agents_list=005,006,007&status=all" -H "Authorization: Bearer $TOKEN"

# Removing disconnected agents
curl -k -X DELETE "https://localhost:55000/agents?pretty=true&older_than=21d&agents_list=all&status=never_connected,disconnected" -H "Authorization: Bearer $TOKEN"

d. 检查与Server的连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
1) 通过Wazuh dashboard查看

2)通过agent_control命令查看

/var/ossec/bin/agent_control -l

/var/ossec/bin/agent_control -i <YOUR_AGENT_ID> | grep Status

3)使用Wazuh API

GET /agents/<YOUR_AGENT_ID>/stats/agent

4)读取本地 wazuh-agentd.state 文件

sudo grep ^status /var/ossec/var/run/wazuh-agentd.state # Linux

Select-String -Path C:\Program Files (x86)\ossec-agent\wazuh-agent.state -Pattern "^status" # Windows

sudo grep ^status /Library/Ossec/var/run/wazuh-agentd.state # macOS

5)检查网络通信

netstat -vatunp|grep wazuh-agentd # Linux

Get-NetTCPConnection -RemotePort 1514 # Windows

lsof -i -P | grep ESTABLISHED | grep 1514 # mscOS

Agent日志排查

1
2
3
4
5
Linux/Unix: /var/ossec/logs/ossec.log

Windows: C:\Program Files (x86)\ossec-agent\ossec.log

macOS: /Library/Ossec/logs/ossec.log

3. 参考速查

a. 本地配置(ossec.conf)

ossec.conf 文件是Wazuh manager上的主要配置文件,Linux文件位置/var/ossec/etc/ossec.conf, Windows 文件位置 C:\Program Files (x86)\ossec-agent\ossec.conf

ossec.conf 文件为 XML 格式,其所有配置选项都嵌套在文件的相应部分中。在这个文件中,最外层的 XML 标签是<ossec_config>。可以有多个<ossec_config>标签

agent.conf 文件与ossec.conf 相似,但agent.conf 用于将配置信息集中分发给代理

配置项

配置部分 支持安装
active-response manager, agent
agentless manager
agent-upgrade manager, agent
alerts manager
auth manager
client agent
client_buffer agent
cluster manager
command manager
database_output manager
email_alerts manager
fluent-forward manager, agent
global manager
github manager, agent
integration manager
labels manager, agent
localfile manager, agent
logging manager, agent
office365 manager, agent
remote manager
reports manager
rootcheck manager, agent
rule_test manager
ruleset manager
sca manager, agent
socket manager, agent
syscheck manager, agent
syslog_output manager
task-manager manager
vulnerability-detector manager
wodle name=”agent-key-polling” manager
wodle name=”aws-s3” manager, agent
wodle name=”azure-logs” manager
wodle name=”cis-cat” manager, agent
wodle name=”command” manager, agent
wodle name=”docker-listener” manager, agent
wodle name=”open-scap” manager, agent
wodle name=”osquery” manager, agent
wodle name=”syscollector” manager, agent
gcp-pubsub manager, agent
gcp-bucket manager, agent

b. 集中配置(agent.conf)

使用 agent.conf 文件远程配置代理。可以远程配置以下功能:

  • File Integrity monitoring (syscheck)

  • Rootkit detection (rootcheck)

  • Log data collection (localfile)

  • Security policy monitoring (wodle name=”open-scap”, wodle name=”cis-cat”)

  • Remote commands (wodle name=”command”)

  • Labels for agent alerts (labels)

  • Security Configuration Assessment (sca)

  • System inventory (syscollector)

  • Avoid events flooding (client_buffer)

  • Configure osquery wodle (wodle name=”osquery”)

  • force_reconnect_interval setting (client)

在共享代理配置中设置远程命令时,必须为代理模块启用远程命令,在agent中/var/ossec/etc/local_internal_options.conf 文件添加如下行:

1
wazuh_command.remote_commands=1

Agent组

Agent可以组合在一起,以便向他们发送特定于组的唯一集中配置

  • /var/ossec/etc/shared/default 中的所有文件将被推送到所有属于 default 组的代理

  • 文件 ar.conf(活动响应状态)将始终发送给代理

  • agent 会将共享文件存储在/var/ossec/etc/shared 中,而不是组文件夹中

集中配置流程

1)配置 agent.conf 文件

编辑agent组对应的文件。对于默认组,编辑文件 /var/ossec/etc/shared/default/agent.conf。如果文件不存在,则创建

1
2
3
touch /var/ossec/etc/shared/default/agent.conf
chown wazuh:wazuh /var/ossec/etc/shared/default/agent.conf
chmod 640 /var/ossec/etc/shared/default/agent.conf

根据agent的name, OS 或 profile创建多个配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<agent_config name="agent_name">
<localfile>
<location>/var/log/my.log</location>
<log_format>syslog</log_format>
</localfile>
</agent_config>

<agent_config os="Linux">
<localfile>
<location>/var/log/linux.log</location>
<log_format>syslog</log_format>
</localfile>
</agent_config>

<agent_config profile="database">
<localfile>
<location>/var/log/database.log</location>
<log_format>syslog</log_format>
</localfile>
</agent_config>

2)运行 /var/ossec/bin/verify-agent-conf

更改 agent.conf 文件时,需检查配置错误,检查报告任何错误,则必须在下一步之前修复。

3)将配置推送给agent

重新启动管理器将使新的 agent.conf 文件更快地可供agent使用。

4)确认agent收到配置

agent_groups 工具或 Wazuh API 端点 GET /agents/{agent_id}/group/is_sync 可以显示组是否在代理中同步:

1
curl -k -X GET "https://localhost:55000/agents/001/group/is_sync?pretty=true" -H  "Authorization: Bearer $TOKEN"

输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"error": 0,
"data": {
"affected_items": [
{
"id": "001",
"synced": true
}
],
"total_affected_items": 1,
"total_failed_items": 0,
"failed_items": []
},
"message": "Sync info was returned for all selected agents"
}
1
/var/ossec/bin/agent_groups -S -i 001

输出

1
Agent '001' is synchronized.

5)重启agent

默认情况下,agent会在收到新的共享配置时自动重新启动。如果 auto_restart 已被禁用(在本地配置的 <client> 部分),则必须手动重新启动代理:

1
/var/ossec/bin/agent_control -R -u 1032

c. 守护进程表

Daemons进程 描述 安装支持
wazuh-agentd 与服务器通信的客户端守护进程 agent
wazuh-agentlessd 在未安装agent的系统上运行完整性检查 manager
wazuh-analysisd 接收日志消息并将它们与规则进行比较 manager
wazuh-authd 将agent添加到 Wazuh 管理器 manager
wazuh-csyslogd 通过syslog转发 Wazuh 警报 manager
wazuh-dbd 将警报日志插入数据库 manager
wazuh-execd 执行主动响应 manager, agent
wazuh-logcollector 监视配置的文件和命令以获取新的日志消息 manager, agent
wazuh-maild 通过电子邮件发送 Wazuh 警报 manager
wazuh-monitord 监控agent连接并压缩日志文件 manager
wazuh-remoted 与agents通信 manager
wazuh-reportd 从 Wazuh 警报创建报告 manager
wazuh-syscheckd 检查配置文件的安全更改 manager, agent
wazuh-clusterd 管理 Wazuh 集群管理器 manager
wazuh-modulesd 管理 Wazuh 模块 manager, agent
wazuh-db 管理 Wazuh 数据库 manager
wazuh-integratord 允许 Wazuh 连接到外部 API 和警报工具 manager

more: https://documentation.wazuh.com/current/user-manual/reference/daemons/index.html

d. 工具速查表

工具 描述 安装支持
wazuh-control 管理 Wazuh 进程的状态 manager, agent
agent-auth 将agent添加到 Wazuh 管理器 agent
agent_control 允许管理器查询以获取agent相关信息 manager
manage_agents 提供一个接口来处理与agent的认证 manager, agent
wazuh-logtest 允许根据提供的日志记录测试和验证规则 manager
clear_stats 清除事件统计 manager
wazuh-regex 验证正则表达式 manager
update_ruleset 更新解码器、规则和 Rootcheck manager
verify-agent-conf 验证 Wazuh agent.conf 配置 manager
agent_groups 管理和分配组 manager
agent_upgrade 列出过时的agent并升级 manager
cluster_control 管理和检索集群信息 manager
fim_migrate 将旧的 FIM 数据库迁移到 Wazuh-DB manager

more: https://documentation.wazuh.com/current/user-manual/reference/tools/index.html

0x03 规则详解

OSSEC 提供了一组开箱即用的规则,Wazuh基于此规则进行更新和扩展,来检测攻击、入侵、软件滥用、配置问题、应用程序错误、恶意软件、rootkit、系统异常或违反安全策略

1. 目录文件

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

1
2
3
4
5
6
7
8
9
/var/ossec/
├─ etc/
│ ├─ decoders/
| | └─ local_decoder.xml
│ └─ rules/
| └─ local_rules.xml
└─ ruleset/
├─ decoders/
└─ rules/
  • 在 ruleset/ 目录中存放通用规则和解码器。此目录内的所有文件在Wazuh更新过程中都会被覆盖或修改,请勿在此目录内编辑文件或添加自定义文件。

  • 如需执行自定义更改,使用 etc/ 目录。可以在此处添加自己的解码器/规则文件或使用默认的 local_decoder.xmllocal_rules.xml 文件

2. Json解码器

Wazuh 集成了一个用于 JSON 日志的解码器,可以从任何来源提取这种格式的数据,该解码器能够提取以下数据类型:

类型 描述
Numbers 整型、浮点型
Strings 字符类型
Booleans 布尔类型
Null values 空值
Arrays 具有零个或多个值的列表。上述类型组合,不支持对象数组
Objects 键/值对的集合,其中键是字符串

示例一:展示Wazuh 如何解码 JSON 日志并为 Suricata 生成警报

Suricata事件日志:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"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": "21YW5kXBtgdW5zIGRlcHJY2F0QgYWI",
"payload_printable": "this_is_an_example",
"stream": 0,
"host": "suricata.com"
}

JSON 解码器从日志数据中提取每个字段以与规则进行比较,因此不需要特定的 Suricata 解码器。这些规则将用于根据特定于生成 JSON 事件的源的特定字段的存在来识别 JSON 事件的源。

以下示例显示文件 0470-suricata_rules.xml 中包含的规则如何工作,首先有一个父规则检查”timestamp”和”event_type”字段是否存在以确定日志类型 (Suricata),然后子规则使用提取字段的值显示警报。

1
2
3
4
5
6
7
8
9
10
11
12
<rule id="86600" level="0">
<decoded_as>json</decoded_as>
<field name="timestamp">\.+</field>
<field name="event_type">\.+</field>
<description>Suricata messages.</description>
</rule>

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

wazuh-logtest 从上面的 JSON 记录输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Type one log per line

{"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":"21YW5kXBtgdW5zIGRlcHJY2F0QgYWI","payload_printable":"this_is_an_example","stream":0,"host":"suricata.com"}

**Phase 1: Completed pre-decoding.

**Phase 2: Completed decoding.
name: 'json'
alert.action: 'allowed'
alert.category: 'Attempted Administrator Privilege Gain'
alert.gid: '1'
alert.rev: '3'
alert.severity: '1'
alert.signature: 'ET WEB_SERVER Possible CVE-2014-6271 Attempt in HTTP Version Number'
alert.signature_id: '2019236'
dest_ip: '16.10.10.11'
dest_port: '80'
event_type: 'alert'
flow_id: '1234'
host: 'suricata.com'
in_iface: 'eth0'
payload: '21YW5kXBtgdW5zIGRlcHJY2F0QgYWI'
payload_printable: 'this_is_an_example'
proto: 'TCP'
src_ip: '16.10.10.10'
src_port: '5555'
stream: '0'
timestamp: '2016-05-02T17:46:48.515262+0000'

**Phase 3: Completed filtering (rules).
id: '86601'
level: '3'
description: 'Suricata: Alert - ET WEB_SERVER Possible CVE-2014-6271 Attempt in HTTP Version Number'
groups: '['ids', 'suricata']'
firedtimes: '1'
mail: 'False'
**Alert to be generated.

示例二:使用 JSON 解码器提取包含在传入日志中的 JSON

解码器选项中引入的新属性偏移量(offset),它允许丢弃输入字符串的某些部分

输入日志:

1
2018 Apr 04 13:11:52 nba_program: this_is_an_example: " player_information: "{ "name": "Stephen", "surname": "Curry", "team": "Golden State Warriors", "number": 30, "position": "point guard"}

使用该新功能的解码器声明如下:

1
2
3
4
5
<decoder name="raw_json">
<program_name>nba_program</program_name>
<prematch>player_information: "</prematch>
<plugin_decoder offset="after_prematch">JSON_Decoder</plugin_decoder>
</decoder>

JSON 解码器会将 JSON 事件中包含的字段提取为动态字段,并从预匹配文本的末尾开始过滤

wazuh-logtest 的输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Type one log per line

2018 Apr 04 13:11:52 nba_program: this_is_an_example: " player_information: "{ "name": "Stephen", "surname": "Curry", "team": "Golden State Warriors", "number": 30, "position": "point guard"}

**Phase 1: Completed pre-decoding.
full event: '2018 Apr 04 13:11:52 nba_program: this_is_an_example: " player_information: "{ "name": "Stephen", "surname": "Curry", "team": "Golden State Warriors", "number": 30, "position": "point guard"}'
timestamp: '2018 Apr 04 13:11:52'
program_name: 'nba_program'

**Phase 2: Completed decoding.
name: 'raw_json'
name: 'Stephen'
number: '30'
position: 'point guard'
surname: 'Curry'
team: 'Golden State Warriors'

可见,JSON 解码器不再受有效 JSON 对象之后的任何数据影响

3. 自定义规则/解码器

可以修改 Wazuh 规则集中的默认规则和解码器,也可以添加新规则和解码器以提高 Wazuh 的检测能力。

a. 添加新的解码器和规则

  • 使用 local_decoder.xml 和 local_rules.xml 来实现小改动,大规模更改/添加最好创建一个新的解码器和/或规则文件

  • 自定义规则的 <id> 将在 100000 到 120000 的范围内

示例

1
Dec 25 20:45:02 MyHost example[12345]: User 'admin' logged from '192.168.1.100'

首先,需要解码这些信息,将新的解码器添加到/var/ossec/etc/decoders/local_decoder.xml

1
2
3
4
5
6
7
8
9
<decoder name="example">
<program_name>^example</program_name>
</decoder>

<decoder name="example">
<parent>example</parent>
<regex>User '(\w+)' logged from '(\d+.\d+.\d+.\d+)'</regex>
<order>user, srcip</order>
</decoder>

然后,将以下规则添加到/var/ossec/etc/rules/local_rules.xml

1
2
3
4
<rule id="100010" level="0">
<program_name>example</program_name>
<description>User logged</description>
</rule>

使用 /var/ossec/bin/wazuh-logtest 检查它是否有效:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Type one log per line

Dec 25 20:45:02 MyHost example[12345]: User 'admin' logged from '192.168.1.100'

**Phase 1: Completed pre-decoding.
full event: 'Dec 25 20:45:02 MyHost example[12345]: User 'admin' logged from '192.168.1.100''
timestamp: 'Dec 25 20:45:02'
hostname: 'MyHost'
program_name: 'example'

**Phase 2: Completed decoding.
name: 'example'
dstuser: 'admin'
srcip: '192.168.1.100'

**Phase 3: Completed filtering (rules).
id: '100010'
level: '0'
description: 'User logged'
groups: '['local', 'syslog', 'sshd']'
firedtimes: '1'
mail: 'False'

b. 更改现有规则

/var/ossec/ruleset/rules 文件夹中任何规则文件的更改将在更新过程中丢失。使用以下过程来保留更改

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

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

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

1
2
3
4
5
6
7
8
9
<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"表示这条规则覆盖了一个已经定义好的规则

1
2
3
4
5
6
7
8
9
<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>

c. 更改现有解码器

/var/ossec/ruleset/decoders 文件夹中的任何解码器文件的更改都将在更新过程中丢失。使用以下过程来保留您的更改。

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

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

  2. 从 OSSEC 加载列表中排除原始解码器文件 ruleset/decoders/0310-ssh_decoders.xml。为此,请在 ossec.conf 文件中使用标签 <decoder_exclude>,这样就不会从默认的解码器文件夹中加载指定的解码器,而是加载保存在用户文件夹中的解码器文件

1
2
3
4
5
6
7
8
9
10
11
12
<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>
  1. 执行文件 /var/ossec/etc/decoders/0310-ssh_decoders.xml 中的更改

4. 动态字段

a. 传统解码器

检测和处理威胁的一个重要步骤是从收到的每个事件中提取信息。Wazuh 使用解码器来识别事件类型,然后提取最相关的字段,从而丰富事件并允许对它们进行更深入的分析和索引。

OSSEC提供了十三个预定义字段用于存储提取的信息(user、srcip、dstip、srcport、dstport、protocol、action、id、url、data、extra_data、status、system_name),其中只有八个可以同时提取

静态字段:

1
2
3
4
5
6
7
<decoder name="web-accesslog">
<type>web-log</type>
<prematch>^\d+.\d+.\d+.\d+ - </prematch>
<regex>^(\d+.\d+.\d+.\d+) - \S+ [\S+ -\d+] </regex>
<regex>"\w+ (\S+) HTTP\S+ (\d+) </regex>
<order>srcip,url,id</order>
</decoder>

b. 动态解码器

当需要从一个事件中提取八个以上的相关字段,而且提取的实际数据项通常与有限的预定义字段名称列表无关时用到。Wazuh扩展了 OSSEC 以允许解码无限数量的字段,这些字段的字段名称与正在提取的内容明确相关。

动态字段:

1
2
3
4
5
<decoder name="auditd-config_change">
<parent>auditd</parent>
<regex offset="after_regex">^auid=(\S+) ses=(\S+) op="(\.+)"</regex>
<order>audit.auid,audit.session,audit.op</order>
</decoder>

Wazuh 将 <order> 标签中包含的任何字段名称转换为 JSON 字段

示例显示 auditd 解码器如何从警报中提取信息:

1
2
3
4
5
6
7
8
9
10
11
12
** Alert 1486483073.60589: - audit,audit_configuration,
2017 Feb 07 15:57:53 wazuh-example->/var/log/audit/audit.log
Rule: 80705 (level 3) -> 'Auditd: Configuration changed'
type=CONFIG_CHANGE msg=audit(1486483072.194:20): auid=0 ses=6 op="add rule" key="audit-wazuh-a" list=4 res=1
audit.type: CONFIG_CHANGE
audit.id: 20
audit.auid: 0
audit.session: 6
audit.op: add rule
audit.key: audit
audit.list: 4
audit.res: 1

JSON 输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{
"rule": {
"level": 3,
"description": "Auditd: Configuration changed",
"id": 80705,
"firedtimes": 2,
"groups": [
"audit",
"audit_configuration"
]
},
"agent": {
"id": "000",
"name": "wazuh-example"
},
"manager": {
"name": "wazuh-example"
},
"full_log": "type=CONFIG_CHANGE msg=audit(1486483072.194:20): auid=0 ses=6 op=\"add rule\" key=\"audit-wazuh-a\" list=4 res=1",
"audit": {
"type": "CONFIG_CHANGE",
"id": "20",
"auid": "0",
"session": "6",
"op": "add rule",
"key": "audit",
"list": "4",
"res": "1"
},
"decoder": {
"parent": "auditd",
"name": "auditd"
},
"timestamp": "2017 Feb 07 15:57:53",
"location": "/var/log/audit/audit.log"
}

5. XML格式规则集

a. 解码器语法

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

解码器中的配置选项

选项 描述
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

b. 规则语法

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

0x04 安全能力

英文 中文
Log data analysis 日志数据分析
File integrity monitoring 文件完整性监控
Rootkits detection Rootkit检测
Active response 主动防御
Security Configuration Assessment 安全配置评估
System inventory 资产盘点
Vulnerability detection 漏洞检测
Cloud security 云安全
Container security 容器安全
Regulatory compliance 合规检测

1. 日志数据分析

日志数据收集是感知服务器或设备生成的记录的实时过程,该组件可以通过文本文件或 Windows 事件日志接收日志。它还可以通过远程系统日志直接接收日志,适用于防火墙和其他此类设备。

此过程的目的是识别应用程序或系统错误、配置错误、入侵行为、违反策略或安全问题。

a. 日志文件

日志分析引擎可以配置为监控服务器上的特定文件。

Linux:

1
2
3
4
<localfile>
<location>/var/log/example.log</location>
<log_format>syslog</log_format>
</localfile>

Windows:

1
2
3
4
<localfile>
<location>C:\myapp\example.log</location>
<log_format>syslog</log_format>
</localfile>

macOS ULS logs:

1
2
3
4
5
<localfile>
<location>macos</location>
<log_format>macos</log_format>
<query type="log,activity" level="debug">process == "sshd" OR message CONTAINS "invalid"</query>
</localfile>

b. 远程syslog

日志分析组件可以配置为通过 syslog 接收日志事件,有两种方式:

  • 在自定义端口接收 syslog 日志

  • 将 syslog 日志存储在一个纯文本文件中并使用 Wazuh 进行监控

配置 Wazuh 以在给定端口接收日志:

1
2
3
4
5
6
7
8
<ossec_config>
<remote>
<connection>syslog</connection>
<port>513</port>
<protocol>tcp</protocol>
<allowed-ips>192.168.2.0/24</allowed-ips>
</remote>
</ossec_config>
  • <connection>syslog</connection> 表示管理器将接受来自网络传入的系统日志消息
  • <port>513</port> 定义 Wazuh 将监听以检索日志的端口,需未占用
  • <allowed-ips>192.168.2.0/24</allowed-ips> 定义将从中接受系统日志消息的网络或 IP 地址

将 syslog 日志存储在一个纯文本文件中并使用 Wazuh 进行监控:

此方法将日志存储在纯文本文件中并监视该文件, 需先 /etc/rsyslog.conf 配置文件并且定义存储系统日志的位置, 配置一个以 syslog 作为日志格式的 <localfile> 块来监控

1
2
3
4
<localfile>
<log_format>syslog</log_format>
<location>/custom/file/path</location>
</localfile>
  • <log_format>syslog</log_format> 表示源日志格式
  • <location>/custom/file/path</location> 表示存储 syslog 日志的位置

c. 日志分析

预解码

在分析的预解码阶段,从日志头中提取字段的静态信息

1
Feb 14 12:19:04 localhost sshd[25474]: Accepted password for rromero from 192.168.1.133 port 49765 ssh2

提取的信息:

  • hostname: ‘localhost’

  • program_name: ‘sshd’

解码

在解码阶段,判断日志消息以确定它是什么类型的日志,然后提取该特定日志类型的已知字段

1
Feb 14 12:19:04 localhost sshd[25474]: Accepted password for rromero from 192.168.1.133 port 49765 ssh2

提取的信息:

  • program name: sshd

  • dstuser: rromero

  • srcip: 192.168.1.133

规则匹配

在下一阶段,将提取的日志信息与规则集进行比较以寻找匹配项,如下示例匹配ssh登录成功的事件:

1
2
3
4
5
6
<rule id="5715" level="3">
<if_sid>5700</if_sid>
<match>^Accepted|authenticated.$</match>
<description>sshd: authentication success.</description>
<group>authentication_success,pci_dss_10.2.5,</group>
</rule>

告警

匹配规则后,管理器将创建如下警报:

1
2
3
4
5
6
** Alert 1487103546.21448: - syslog,sshd,authentication_success,pci_dss_10.2.5,
2017 Feb 14 12:19:06 localhost->/var/log/secure
Rule: 5715 (level 3) -> 'sshd: authentication success.'
Src IP: 192.168.1.133
User: rromero
Feb 14 12:19:04 localhost sshd[25474]: Accepted password for rromero from 192.168.1.133 port 49765 ssh2

警报将存储在 /var/ossec/logs/alerts/alerts.(json|log) 中,事件存储在 /var/ossec/logs/archives/archives.(json|log)

4. 日志配置

基本用法

日志数据采集配置在ossec.conf文件中,主要用到 localfile、remote和global部分;也可以在 agent.conf 文件中完成配置,以将这些配置集中分发给对应agent

设置要监视的文件的名称和格式:

1
2
3
4
<localfile>
<location>/var/log/messages</location>
<log_format>syslog</log_format>
</localfile>

使用文件名的通配符模式监控日志

Wazuh 支持 posix 通配符模式,例如分析 /var/log 目录中以 .log 结尾的每个文件,使用以下配置:

1
2
3
4
<localfile>
<location>/var/log/*.log</location>
<log_format>syslog</log_format>
</localfile>

监控基于日期的日志

对于根据日期变化的日志文件,还可以指定strftime格式来代替日、月、年等,例如监控C:\Windows\app\log-08-12-15.log 类似日志文件,使用如下配置:

1
2
3
4
<localfile>
<location>C:\Windows\app\log-%y-%m-%d.log</location>
<log_format>syslog</log_format>
</localfile>

使用环境变量

可以在位置模式中使用 %WinDir% 等环境变量。以下是从 IIS 服务器读取日志的示例:

1
2
3
4
<localfile>
<location>%SystemDrive%\inetpub\logs\LogFiles\W3SVC1\u_ex%y%m%d.log</location>
<log_format>iis</log_format>
</localfile>

使用多个输出

默认情况下,日志数据发送到agent socket,但也可以指定其他socket作为输出。 wazuh-logcollector 使用 UNIX 类型socket进行通信,允许 TCP 或 UDP 协议。

要添加一个新的输出socket,我们需要使用标签 <socket> 来指定:

1
2
3
4
5
6
7
8
9
10
11
<socket>
<name>custom_socket</name>
<location>/var/run/custom.sock</location>
<mode>tcp</mode>
<prefix>custom_syslog: </prefix>
</socket>

<socket>
<name>test_socket</name>
<location>/var/run/test.sock</location>
</socket>

当定义了socket,就可以为每个 localfile 添加目标socket:

1
2
3
4
5
6
7
8
9
10
11
<localfile>
<log_format>syslog</log_format>
<location>/var/log/messages</location>
<target>agent,test_socket</target>
</localfile>

<localfile>
<log_format>syslog</log_format>
<location>/var/log/messages</location>
<target>custom_socket,test_socket</target>
</localfile>

2. 文件完整性监控

a. 实现原理

Wazuh 文件完整性监控 (FIM) 系统监视选定的文件并在这些文件被修改时触发警报。负责此任务的组件称为 syscheck

FIM 模块位于 Wazuh agent中,定期扫描并将受监控文件和 Windows 注册表项的校验和与属性存储在本地 FIM 数据库中。该模块通过将新文件的校验和与旧校验和进行比较来查找修改。所有检测到的变化都会报告给 Wazuh agent。

新的 FIM 同步机制确保 Wazuh 管理器中的文件清单始终根据 Wazuh agent进行更新,FIM 同步基于定期计算 Wazuh agent和 Wazuh 管理器数据库之间的完整性,在 Wazuh 管理器中仅更新变化的文件。只要在受监视的文件和/或注册表项中检测到修改,就会生成警报。

FIM 生成的示例警报:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** Alert 1540815355.847397: - ossec,syscheck,pci_dss_11.5,gpg13_4.11,gdpr_II_5.1.f,
2018 Oct 29 13:15:55 (ubuntu) 10.0.0.144->syscheck
Rule: 550 (level 7) -> 'Integrity checksum changed.'
File '/test/hello' checksum changed.
Old md5sum was: '2a4732b1de5db823e94d662d207b8fb2'
New md5sum is : '146c07ef2479cedcd54c7c2af5cf3a80'
Old sha1sum was: 'b89f4786dcf00fb1c4ddc6ad282ca0feb3e18e1b'
New sha1sum is : 'e1efc99729beb17560e02d1f5c15a42a985fe42c'
Old sha256sum was: 'a8a3ea3ddbea6b521e4c0e8f2cca8405e75c042b2a7ed848baaa03e867355bc2'
New sha256sum is : 'a7998f247bd965694ff227fa325c81169a07471a8b6808d3e002a486c4e65975'
Old modification time was: 'Mon Oct 29 13:15:19 2018', now it is 'Mon Oct 29 13:15:54 2018'
(Audit) User: 'root (0)'
(Audit) Login user: 'test (1000)'
(Audit) Effective user: 'root (0)'
(Audit) Group: 'root (0)'
(Audit) Process id: '26089'
(Audit) Process name: '/bin/nano'

Attributes:
- Size: 4
- Permissions: 100644
- Date: Mon Oct 29 13:15:54 2018
- Inode: 537259
- User: root (0)
- Group: root (0)
- MD5: 146c07ef2479cedcd54c7c2af5cf3a80
- SHA1: e1efc99729beb17560e02d1f5c15a42a985fe42c
- SHA256: a7998f247bd965694ff227fa325c81169a07471a8b6808d3e002a486c4e65975

b. FIM 字段-规则映射

FIM - Alerts字段映射

FIM字段 Alert字段 字段描述
file path 当前事件中的文件路径
size size_after 当前事件中的文件大小
hard_links hard_links 文件的硬链接列表
mode mode FIM 事件模式
perm perm_after,win_perm_after 文件权限
uid uid_after 文件所有者的用户 ID
gid gid_after 共享文件所有权的组的组 ID
uname uname_after 文件所有者的用户名
gname gname_after 共享文件所有权的组的组名
md5 md5_after 当前事件中文件的 MD5 哈希(更改后)
sha1 sha1_after 当前事件中文件的 SHA1 哈希(更改后)
sha256 sha256_after 当前事件中文件的 SHA256 哈希(更改后)
mtime mtime_after 文件更改的时间戳
inode inode_after 当前事件中文件的inode
changed_content diff 当前事件文件更改报告
changed_fields changed_attributes 文件中的更改字段(权限、内容等…)
win_attributes attrs_after 文件属性(隐藏、只读等…)
tag tag 添加到一个特定事件的自定义标签
user_id audit.user.id 触发事件的用户的实际ID
user_name audit.user.name 触发事件的用户的实际名称
group_id audit.group.id 触发事件的用户的实际组 ID
group_name audit.group.name 触发事件的用户的实际组名
process_name audit.process.name 触发事件的用户运行的进程的名称
process_id audit.process.id 触发事件的用户运行的进程的 ID
ppid audit.process.ppid 触发事件的父进程 ID
effective_uid audit.effective.user_id 触发事件的进程使用的有效用户 ID
effective_name audit.effective_user.name 触发事件的进程使用的有效用户名
parent_name audit.process.parent_name 触发事件的进程的父进程的进程名称
cwd audit.process.cwd 触发事件的进程的当前工作目录
parent_cwd audit.process.parent_cwd 父进程的当前工作目录
audit_uid audit.login_user.id 触发事件的登录到系统的用户 ID
audit_name audit.login_user.name 触发事件的登录到系统的用户名
arch arch 注册表架构(32 或 64 位)
value_name value_name 注册表值名称
value_type value_type 注册表值类型
entry_type entry_type 注册表项类型

规则映射示例

监控文件从600 到640 的权限更改:

1
2
3
4
5
6
7
8
<rule id="100002" level="0">
<if_sid>550</if_sid>
<field name="file">.log$</field>
<field name="changed_fields">^permission$</field>
<field name="perm">rw-r--r--r--</field>
<match>rw-------</match>
<description>Silence perm changes</description>
</rule>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{
"type": "event",
"data": {
"path": "/specialdir/file.log",
"mode": "whodata",
"type": "modified",
"timestamp": 1623745234,
"attributes": {
"type": "file",
"size": 0,
"perm": "rw-------",
"uid": "0",
"gid": "0",
"user_name": "root",
"group_name": "root",
"inode": 4352002,
"mtime": 1623665041,
"hash_md5": "d41d8cd98f00b204e9800998ecf8427e",
"hash_sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"hash_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"checksum": "25e338d1eca897691bacd33246c38650bdcd5630"
},
"changed_attributes": [
"permission"
],
"old_attributes": {
"type": "file",
"size": 0,
"perm": "rw-r--r--",
"uid": "0",
"gid": "0",
"user_name": "root",
"group_name": "root",
"inode": 4352002,
"mtime": 1623665041,
"hash_md5": "d41d8cd98f00b204e9800998ecf8427e",
"hash_sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"hash_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"checksum": "a1e1975f6f2799cb9f7e25af0b8f0bd1c4e183e4"
},
"audit": {
"user_id": "0",
"user_name": "root",
"process_name": "/usr/bin/chmod",
"process_id": 8866,
"cwd": "/specialdir",
"group_id": "0",
"group_name": "root",
"audit_uid": "1000",
"audit_name": "vagrant",
"effective_uid": "0",
"effective_name": "root",
"parent_name": "/usr/bin/bash",
"parent_cwd": "/specialdir",
"ppid": 3275
}
}
}

当受监控目录下的 .txt 文件被修改并在其中包含关键字关键字时触发规则:

1
2
3
4
5
6
7
<rule id="100010" level="12">
<if_sid>550</if_sid>
<field name="file">.txt$</field>
<field name="changed_content">keyword</field>
<match>modified</match>
<description>Fire alert when .txt file is modified and contains word "keyword"</description>
</rule>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
{
"type": "event",
"data": {
"path": "/test/file.txt",
"mode": "realtime",
"type": "modified",
"timestamp": 1623660202,
"attributes": {
"type": "file",
"size": 26,
"perm": "rw-r--r--",
"uid": "0",
"gid": "0",
"user_name": "root",
"group_name": "root",
"inode": 4096002,
"mtime": 1623660202,
"hash_md5": "126b42ce036035a50516f067aae33418",
"hash_sha1": "5b0c286906ea60075d47b22ceab830681e906365",
"hash_sha256": "d3c558c76a0c62e0917516a3aaf02d0512beb4ef6c1af19ca3c79e913cefcdfe",
"checksum": "6c895291c3c9c20acee3f822c429a0901a77f7b4"
},
"changed_attributes": [
"size",
"mtime",
"md5",
"sha1",
"sha256"
],
"old_attributes": {
"type": "file",
"size": 0,
"perm": "rw-r--r--",
"uid": "0",
"gid": "0",
"user_name": "root",
"group_name": "root",
"inode": 4096002,
"mtime": 1623660184,
"hash_md5": "d41d8cd98f00b204e9800998ecf8427e",
"hash_sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"hash_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"checksum": "eed9691633569779f515786b6eccbdbfd3dc1e1a"
},
"content_changes": "0a1\n> 12313213215681568 keyword\n"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{
"timestamp": "2021-06-14T08:43:22.999+0000",
"rule": {
"level": 12,
"description": "Fire alert when .txt file is modified and contains word \"keyword\"",
"id": "100010",
"firedtimes": 1,
"mail": true,
"groups": [
"local",
"syslog",
"sshd"
]
},
"agent": {
"id": "004",
"name": "ubuntu201",
"ip": "10.0.2.15"
},
"manager": {
"name": "ubuntu20"
},
"id": "1623660202.17987",
"full_log": "File '/test/file.txt' modified\nMode: realtime\nChanged attributes: size,mtime,md5,sha1,sha256\nSize changed from '0' to '26'\nOld modification time was: '1623660184', now it is '1623660202'\nOld md5sum was: 'd41d8cd98f00b204e9800998ecf8427e'\nNew md5sum is : '126b42ce036035a50516f067aae33418'\nOld sha1sum was: 'da39a3ee5e6b4b0d3255bfef95601890afd80709'\nNew sha1sum is : '5b0c286906ea60075d47b22ceab830681e906365'\nOld sha256sum was: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'\nNew sha256sum is : 'd3c558c76a0c62e0917516a3aaf02d0512beb4ef6c1af19ca3c79e913cefcdfe'\n",
"syscheck": {
"path": "/test/file.txt",
"mode": "realtime",
"size_before": "0",
"size_after": "26",
"perm_after": "rw-r--r--",
"uid_after": "0",
"gid_after": "0",
"md5_before": "d41d8cd98f00b204e9800998ecf8427e",
"md5_after": "126b42ce036035a50516f067aae33418",
"sha1_before": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"sha1_after": "5b0c286906ea60075d47b22ceab830681e906365",
"sha256_before": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"sha256_after": "d3c558c76a0c62e0917516a3aaf02d0512beb4ef6c1af19ca3c79e913cefcdfe",
"uname_after": "root",
"gname_after": "root",
"mtime_before": "2021-06-14T08:43:04",
"mtime_after": "2021-06-14T08:43:22",
"inode_after": 4096002,
"diff": "0a1\n> 12313213215681568 keyword\n",
"changed_attributes": [
"size",
"mtime",
"md5",
"sha1",
"sha256"
],
"event": "modified"
},
"decoder": {
"name": "syscheck_integrity_changed"
},
"location": "syscheck"
}

禁止具有管理员权限的 Windows explorer.exe 进程删除文件的规则:

1
2
3
4
5
6
7
<rule id="100011" level="0">
<if_sid>553</if_sid>
<field name="process_name">explorer.exe$</field>
<field name="uname">Administradores$</field>
<match>deleted</match>
<description>Silence delete events triggered by windows explorer with admin privileges</description>
</rule>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
"type": "event",
"data": {
"path": "c:\\test\\adasdasd.txt",
"version": 2,
"mode": "whodata",
"type": "deleted",
"timestamp": 1623666683,
"attributes": {
"type": "file",
"size": 40,
"perm": "Administradores (allowed): delete|read_control|write_dac|write_owner|synchronize|read_data|write_data|append_data|read_ea|write_ea|execute|read_attributes|write_attributes, SYSTEM (allowed): delete|read_control|write_dac|write_owner|synchronize|read_data|write_data|append_data|read_ea|write_ea|execute|read_attributes|write_attributes, Usuarios (allowed): read_control|synchronize|read_data|read_ea|execute|read_attributes, Usuarios autentificados (allowed): delete|read_control|synchronize|read_data|write_data|append_data|read_ea|write_ea|execute|read_attributes|write_attributes",
"uid": "S-1-5-32-544",
"user_name": "Administradores",
"inode": 0,
"mtime": 1623408349,
"hash_md5": "786e0bf0ffc3c466b19d4e68d7c6f155",
"hash_sha1": "99028323b4d6b4b2db9c7fc73d3887163598865c",
"hash_sha256": "c0fc9e1e16ea610b3627af0b91eb623ac74dfde6943e40361de9a3447fed81b4",
"attributes": "ARCHIVE",
"checksum": "9384acf30012c15bd72f5ca435b4b0d41ec55ae2"
},
"audit": {
"user_id": "S-1-5-21-3527455827-79240758-596275861-1001",
"user_name": "jmv74211",
"process_name": "C:\\Windows\\explorer.exe",
"process_id": 2484
}
}
}

监控使用touch命令创建文件,且该文件的父目录为/specialdir,添加该文件的用户组id和有效uid为0,用户audit_uid为1000,审计名称为vagrant:

1
2
3
4
5
6
7
8
9
10
11
12
<rule id="100012" level="0">
<if_sid>554</if_sid>
<field name="parent_cwd">/specialdir</field>
<field name="process_name">/usr/bin/touch</field>
<field name="group_id">0</field>
<field name="effective_uid">0</field>
<field name="audit_name">vagrant</field>
<field name="audit_uid">1000</field>
<match>added</match>
<description>Silence added event created with touch command in parent's current directory /specialdir with group ID 0,
effective user ID 0, audit ID 1000 and audit user name vagrant</description>
</rule>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{
"type": "event",
"data": {
"path": "/specialdir/file.txt",
"mode": "whodata",
"type": "added",
"timestamp": 1623665041,
"attributes": {
"type": "file",
"size": 0,
"perm": "rw-r--r--",
"uid": "0",
"gid": "0",
"user_name": "root",
"group_name": "root",
"inode": 4352002,
"mtime": 1623665041,
"hash_md5": "d41d8cd98f00b204e9800998ecf8427e",
"hash_sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"hash_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"checksum": "a1e1975f6f2799cb9f7e25af0b8f0bd1c4e183e4"
},
"audit": {
"user_id": "0",
"user_name": "root",
"process_name": "/usr/bin/touch",
"process_id": 53794,
"cwd": "/specialdir",
"group_id": "0",
"group_name": "root",
"audit_uid": "1000",
"audit_name": "vagrant",
"effective_uid": "0",
"effective_name": "root",
"parent_name": "/usr/bin/bash",
"parent_cwd": "/specialdir",
"ppid": 44025
}
}
}

c. FIM配置

Syscheck 组件在 Wazuh 管理器和 Wazuh agent 的 ossec.conf 文件中配置,也可以在 agent.conf 文件中配置此功能。所有 syscheck 配置选项的列表在 syscheck 部分中可用。

配置 syscheck - 基本用法

配置 syscheck,必须确定文件和目录列表,directories 选项的 check_all 属性允许检查文件大小、权限、所有者、最后修改日期、索引节点和所有哈希(MD5、SHA1 和 SHA256)

1
2
3
4
<syscheck>
<directories check_all="yes">/etc,/usr/bin,/usr/sbin</directories>
<directories check_all="yes">/root/users.txt,/bsd,/root/db.html</directories>
</syscheck>

Wazuh 4.3.0版本后,FIM 目录可以使用 * 和 ?通配符方式配置:

1
2
3
<syscheck>
<directories check_all="yes">/home/*/Downloads</directories>
</syscheck>

配置定时扫描

syscheck 使用 frequency 选项来配置系统扫描的频率,如下配置为每 10 小时运行一次:

1
2
3
4
5
<syscheck>
<frequency>36000</frequency>
<directories>/etc,/usr/bin,/usr/sbin</directories>
<directories>/bin,/sbin</directories>
</syscheck>

也可以使用 scan_time 和 scan_day 选项配置扫描,如在每周六晚上 10 点进行扫描:

1
2
3
4
5
6
<syscheck>
<scan_time>10pm</scan_time>
<scan_day>saturday</scan_day>
<directories>/etc,/usr/bin,/usr/sbin</directories>
<directories>/bin,/sbin</directories>
</syscheck>

配置实时监控

使用directories 选项的 realtime 属性配置实时监控,此属性仅适用于目录而不适用于单个文件

1
2
3
<syscheck>
<directories check_all="yes" realtime="yes">c:/tmp</directories>
</syscheck>

配置 who-data 监控

配置directories选项的whodata属性进行监控,该属性取代了realtime属性,即whodata隐含实时监控但增加了who-data信息

1
2
3
<syscheck>
<directories check_all="yes" whodata="yes">/etc</directories>
</syscheck>

配置报告新文件

使用 alert_new_files 选项配置 syscheck报告添加到系统的新文件

1
2
3
<syscheck>
<alert_new_files>yes</alert_new_files>
</syscheck>

新文件创建的示例警报:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
** Alert 1585943821.46978: - ossec,syscheck,pci_dss_11.5,gpg13_4.11,gdpr_II_5.1.f,hipaa_164.312.c.1,hipaa_164.312.c.2,nist_800_53_SI.7,
2020 Apr 03 19:57:01 (agent) any->syscheck
Rule: 554 (level 5) -> 'File added to the system.'
File '/etc/new_file' added
Mode: scheduledAttributes:
- Size: 2
- Permissions: rw-r--r--
- Date: Fri Apr 3 19:56:50 2020
- Inode: 23194
- User: root (0)
- Group: root (0)
- MD5: 9a8ad92c50cae39aa2c5604fd0ab6d8c
- SHA1: a9fcd54b25e7e863d72cd47c08af46e61b74b561
- SHA256: 092fcfbbcfca3b5be7ae1b5e58538e92c35ab273ae13664fed0d67484c8e78a6

通过规则配置忽略文件

忽略 syscheck 扫描特定文件的一种方法是使用规则并将规则级别设置为 0:

1
2
3
4
5
<rule id="100345" level="0">
<if_group>syscheck</if_group>
<match>/var/www/htdocs</match>
<description>Ignore changes to /var/www/htdocs</description>
</rule>

配置受监视文件的警报级别

可以在检测到对特定文件或文件模式的更改时更改 syscheck 警报的级别

1
2
3
4
5
<rule id="100345" level="12">
<if_group>syscheck</if_group>
<match>/var/www/htdocs</match>
<description>Changes to /var/www/htdocs - Critical file!</description>
</rule>

配置允许的最大递归级别

使用 directories 选项的 recursion_level 属性配置特定目录允许的最大递归级别,recursion_level 值必须是 0 到 320 之间的整数,要禁用递归并仅为受监视文件夹中的文件生成警报,必须将 recursion_level 值设置为 0:

1
2
3
4
5
<syscheck>
<directories check_all="yes">/etc,/usr/bin,/usr/sbin</directories>
<directories check_all="yes">/root/users.txt,/bsd,/root/db.html</directories>
<directories check_all="yes" recursion_level="3">folder_test</directories>
</syscheck>

配置 syscheck 进程优先级

要调整受监控系统上的 syscheck CPU 使用率,可以使用 process_priority 选项。它为 syscheck 进程设置了 nice 值,默认 process_priority 设置为 10

将 process_priority 值设置为高于默认值,会给 syscheck 较低的优先级、较少的 CPU 资源并使其运行速度变慢,将syscheck 进程的 nice 值设置为最大值:

1
2
3
<syscheck>
<process_priority>19</process_priority>
</syscheck>

将 process_priority 值设置为低于默认值,将为 syscheck 提供更高的优先级、更多的 CPU 资源并使其运行更快,将syscheck 进程的 nice 值设置为最小值:

1
2
3
<syscheck>
<process_priority>-20</process_priority>
</syscheck>

配置数据库的存储位置

当 Wazuh agent启动时,它会执行第一次扫描并生成其数据库。默认情况下,数据库是在磁盘中创建的:

1
2
3
<syscheck>
<database>disk</database>
</syscheck>

Syscheck 可以配置为将数据库存储在内存中:

1
2
3
<syscheck>
<database>memory</database>
</syscheck>

配置同步

Synchronization可以配置同步以更改同步间隔、每秒事件数、队列大小和响应超时:

1
2
3
4
5
6
7
8
9
10
<syscheck>
<synchronization>
<enabled>yes</enabled>
<interval>5m</interval>
<max_interval>1h</max_interval>
<response_timeout>30</response_timeout>
<queue_size>16384</queue_size>
<max_eps>10</max_eps>
</synchronization>
</syscheck>

3. 异常和恶意软件检测

异常检测是指在系统中发现与预期行为不匹配的模式的动作,当系统上安装了恶意软件(例如,rootkit),就会修改系统以对用户隐藏自己。负责此任务的主要组件是 rootcheck,但 Syscheck 也起着重要的作用。

rootkit检测项

a. 文件完整性监控

恶意软件可以替换主机系统上的文件、目录和命令。执行文件完整性监控,用户可以检查系统的指定目录以检测这些操作。

1
2
3
4
5
6
7
8
9
** Alert 1460948255.25442: mail  - ossec,syscheck,pci_dss_11.5,
2016 Apr 17 19:57:35 (ubuntu) 10.0.0.144->syscheck
Rule: 550 (level 7) -> 'Integrity checksum changed.'
Integrity checksum changed for: '/bin/bash'
Size changed from '12' to '17'
Old md5sum was: 'e59ff97941044f85df5297e1c302d260'
New md5sum is : '7947eba5d9cc58d440fb06912e302949'
Old sha1sum was: '648a6a6ffffdaa0badb23b8baf90b6168dd16b3a'
New sha1sum is : '379b74ac9b2d2b09ff6ad7fa876c79f914a755e1'

b. 检查运行的进程

恶意进程可以防止自己出现在系统的进程列表中(木马版本的 ps 命令)。 Rootcheck 检查所有进程 ID (PID),寻找与不同系统调用(getsid、getpgid)的差异。

例:Diamorphine 是一种内核模式 rootkit,它能够对 ps 隐藏自身和其他进程

1
2
3
4
** Alert 1460225922.841535: mail  - ossec,rootcheck
2017 Feb 15 10:00:42 (localhost) 192.168.1.240->rootcheck
Rule: 510 (level 7) -> 'Host-based anomaly detection event (rootcheck).'
Process '495' hidden from /proc. Possible kernel level rootkit.

c. 检查隐藏端口

恶意软件可以使用隐藏端口与攻击者通信。 Rootcheck 使用 bind() 检查系统中的每个端口。如果它无法绑定到端口并且该端口不在 netstat 输出中,则可能存在恶意软件。

d. 检查异常文件和权限

Wazuh 扫描整个文件系统以查找异常文件和权限。 检查有root权限的文件以及其他用户帐户可写权限的文件,如 suid 文件、隐藏目录和文件。

e. 使用系统调用检查隐藏文件

Wazuh 扫描整个系统,比较使用 fopen + read 每个目录中的节点数也与opendir + readdir 的输出进行比较。如果任何结果不匹配,则可能存在恶意软件。

告警示例

1
2
3
4
** Alert 1460225922.51190: mail  - ossec,rootcheck
2017 Feb 15 10:30:42 (localhost) 192.168.1.240->rootcheck
Rule: 510 (level 7) -> 'Host-based anomaly detection event (rootcheck).'
Files hidden inside directory '/etc'. Link count does not match number of files (128,129)

监控目录

平台 目录
Unix /bin, /sbin, /usr/bin, /usr/sbin, /dev, /lib, /etc, /root, /var/log, /var/mail, /var/lib, /var/www, /usr/lib, /usr/include, /tmp, /boot, /usr/local, /var/tmp and /sys
Windows C:\WINDOWS and C:\Program Files

f. 扫描 /dev 目录

/dev 目录应该只包含特定设备的文件。应检查任何其他文件,因为恶意软件使用此分区来隐藏文件。

在 /dev 上创建隐藏文件,警报示例:

1
2
3
4
5
6
** Alert 1487182293.37491: - ossec,rootcheck,
2017 Feb 15 10:11:33 localhost->rootcheck
Rule: 510 (level 7) -> 'Host-based anomaly detection event (rootcheck).'
File '/dev/.hiddenfile' present on /dev. Possible hidden file.
title: File present on /dev.
file: /dev/.hiddenfile

g. 检测网卡混杂模式

Wazuh 会在启用混杂模式的情况下扫描系统上的任何网络接口。如果接口处于混杂模式,ifconfig 命令的输出将指示它,这可能表明存在恶意软件。

h. Rootkit 文件检查

Rootcheck 使用其 rootkit 签名数据库执行多项检查:rootkit_files.txt、rootkit_trojans.txt 和 win_malware_rcl.txt。

i. rootkit检测配置

基本示例

在ossec.conf文件中配置 syscheck 和 rootcheck 选项,或使用frequency、rootkit_files 和 rootkit_trojans等选项进行配置

1
2
3
4
<rootcheck>
<rootkit_files>etc/shared/rootkit_files.txt</rootkit_files>
<rootkit_trojans>etc/shared/rootkit_trojans.txt</rootkit_trojans>
</rootcheck>

忽略误报

1
2
3
4
5
<rule id="100100" level="0">
<if_group>rootcheck</if_group>
<match>/dev/.blkid.tab</match>
<description>Ignore false positive for /dev/.blkid.tab</description>
</rule>

4. 监控系统调用

使用linux上的auditd进行审计,修改agent上ossec.conf

1
2
3
4
<localfile>
<log_format>audit</log_format>
<location>/var/log/audit/audit.log</location>
</localfile>

a. Audit规则类型

1
2
3
控制规则:允许修改Audit系统的行为及其某些配置
文件系统规则: 允许Audit对特定文件或目录的访问
系统调用规则: 允许记录指定程序进行的系统调用

b. Audit命令

1
2
3
4
5
auditctl -b :设置内核中现有审计缓冲区的最大数量
auditctl -e :启用/禁用审核系统或锁定其配置
auditctl -s :报告审核系统的状态
auditctl -l :列出所有当前加载的审核规则
auditctl -D :删除所有当前加载的审核规则

c. 定义文件系统规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
语法:

-w <path> -p <permissions> -k <key_name>

说明:

-w :指定需要审核的路径
-p :指定审核的权限,rwxa(r:文件或目录只读,w:文件或目录写入,x: 文件或目录执行,a: 更改文件或目录的属性)
-k :可选字段,用于描述规则生成特定的日志行,wazuh要求使用此选项以便更好的分析日志

定义一个监视/etc/test目录的规则

auditctl -w /etc/test -p w -k audit-wazuh-w
auditctl -w /etc/test -p a -k audit-wazuh-a
auditctl -w /etc/test -p r -k audit-wazuh-r
auditctl -w /etc/test -p x -k audit-wazuh-x

在/etc/test目录下创建一个文件进行测试

目录下文件属性发生任何改变都会进行报警(创建文件,修改属主,写入数据等等)

auditctl -w /etc/test/audit -p wa -k audit_file_change
echo "audit_test" >/etc/test/audit

d. 定义系统调用规则

语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
语法:

-a action,filter -S system_call -F field=value -k key_name

说明:

-a <action> <filter>: 告诉内核的规则匹配引擎在规则列表的末尾附加一个规则,必须指定要附加到哪个规则列表,以及在触发时要执行的操作
<action>: always(文件或目录的读权限),never(文件或目录的写权限)
<filter>: 值指定将哪个内核规则匹配过滤器应用于事件,task(仅审核事件可以fork或clone系统调用),exit(对所有的系统调用或文件系统规则进行评估),user(用于删除一些源自用户空间的事件,默认情况下,允许源于用户空间的任何事件),exclude(用于从记录中排除某些事件),msgtype用于告诉内核要过滤掉哪个消息,要更精细地控制要审核的事件,使用用户过滤器并退出过滤器)

-S <system_call>: 这指定要审核的system_call,可以在单个规则中指定多个系统调用, ausyscall --dump:找到所有系统调用的列表

-F <field=value>: 使用field = value可以指定其他条件来缩小要审核的事件的范围:系统架构,group id, process id等,单个规则可以使用多个-F选项

-k <key_name>: 可选字符串,用于描述规则生成特定的日志行,Wazuh要求使用此参数,以便更准确地分析日志

示例

1
2
3
4
5
6
定义一个监测ID为1000的系统用户,指定系统架构为64位的规则

auditctl -a exit,always -F euid=1000 -F arch=b64 -S execve -k audit-wazuh-c
su - test&&mkdir 1

audit-wazuh-c: 默认的CDB列表,可在cat /var/ossec/etc/lists/audit-keys下查看

5. 监控命令执行

a. 接受来自管理器的远程命令

agent能够运行从管理器推送的命令(通过shared目录中的文件), 可以通过在每个agent的 local_internal_options.conf 文件中设置 logcollector.remote_commands 来完成

1
logcollector.remote_commands=1

b. 配置监控命令

运行和监控的命令可以在各个agent的本地ossec.conf文件中配置,但推荐在管理器上的 agent.conf 文件进行配置

1
2
3
4
5
<localfile>
<log_format>full_command</log_format>
<command>.....</command>
<frequency>120</frequency>
</localfile>

c. 检查输出是否改变

使用Linux netstat命令与 check_diff 选项一起使用来监控监听 tcp 套接字中的变化

1
2
3
4
5
6
<localfile>
<log_format>full_command</log_format>
<command>netstat -tulpn | sed 's/\([[:alnum:]]\+\)\ \+[[:digit:]]\+\ \+[[:digit:]]\+\ \+\(.*\):\([[:digit:]]*\)\ \+\([0-9\.\:\*]\+\).\+\ \([[:digit:]]*\/[[:alnum:]\-]*\).*/\1 \2 == \3 == \4 \5/' | sort -k 4 -g | sed 's/ == \(.*\) ==/:\1/' | sed 1,2d</command>
<alias>netstat listening ports</alias>
<frequency>360</frequency>
</localfile>
1
2
3
4
5
6
7
<rule id="533" level="7">
<if_sid>530</if_sid>
<match>ossec: output: 'netstat listening ports</match>
<check_diff />
<description>Listened ports status (netstat) changed (new port opened or closed).</description>
<group>pci_dss_10.2.7,pci_dss_10.6.1,gpg13_10.1,gdpr_IV_35.7.d,</group>
</rule>

如果输出发生变化,系统将生成警报,指示网络监听器已消失或出现了新的监听器,这表明某些东西已损坏或已安装网络后门

6. 主动防御

主动响应执行各种反制措施来应对威胁,当满足特定条件时阻止从威胁源访问agent。主动响应执行脚本以响应基于警报级别或规则组的特定警报的触发.

a. 工作原理

何时触发

主动响应是配置为在触发特定警报、警报级别或规则组时执行的脚本。主动响应是有状态或无状态响应

  • Stateful(有状态):配置为在指定时间段后撤消操作
  • Stateless(无状态):被配置为一次性操作,没有事件来恢复原始效果

在何处执行

每个活动响应指定将在何处执行其关联命令:在触发警报的agent上、在管理器上、在另一个指定的agent上或在所有agent上。location选项:

  • Local:在生成警报的代理上运行脚本
  • Server:在 Wazuh 管理器上运行脚本
  • Defined agent:指定运行脚本的agent的 ID,而不管在何处观察到事件
  • All:环境中的每个agent都将运行该脚本,谨慎使用

b. 主动响应配置

通过修改ossec.conf文件在管理器中配置主动响应:

创建命令

配置主动响应,必须定义一个命令来启动特定脚本以响应触发器,使用下面的模式定义命令的名称,然后引用要启动的脚本

1
2
3
4
5
<command>
<name>host-deny</name>
<executable>host-deny</executable>
<timeout_allowed>yes</timeout_allowed>
</command>

在此示例中,该命令称为 host-deny 并启动 host-deny 脚本。此命令配置为允许在指定时间段后超时,使其成为有状态响应

定义主动响应

主动响应配置定义命令将在何时何地执行。当具有特定 ID、严重级别或源的特定规则与活动响应标准匹配时,将触发命令,此配置将进一步定义命令的操作将在何处启动

1
2
3
4
5
6
<active-response>
<command>host-deny</command>
<location>local</location>
<level>7</level>
<timeout>600</timeout>
</active-response>

在此示例中,主动响应配置为执行上一步中定义的命令。动作的地点定义为本地主机,时间定义为规则级别高于 6 的任何时间。

可以在 /var/ossec/logs/active-responses.log 查看主动响应日志

c. 默认主动响应脚本

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 地址添加到空路由

d. 配置示例

基本用法

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

restart-wazuh 命令配置为使用没有数据元素的 restart-wazuh 脚本

1
2
3
4
<command>
<name>restart-wazuh</name>
<executable>restart-wazuh</executable>
</command>

主动响应配置为在 ID 为 10005 的规则触发时在本地主机上启动 restart-wazuh 命令。这是一个无状态响应

1
2
3
4
5
<active-response>
<command>restart-wazuh</command>
<location>local</location>
<rules_id>10005</rules_id>
</active-response>

使用 PF 阻止 IP

pf-block 命令配置为使用 pf 脚本

1
2
3
4
<command>
<name>pf-block</name>
<executable>pf</executable>
</command>

当”authentication_failed”或”authentication_failures”规则组中的规则触发时,主动响应配置为在代理 001 上启动 pf-block 命令。这是一个无状态响应

1
2
3
4
5
6
<active-response>
<command>pf-block</command>
<location>defined-agent</location>
<agent_id>001</agent_id>
<rules_group>authentication_failed|authentication_failures</rules_group>
</active-response>

将 IP 添加到 iptables 拒绝列表

firewall-drop 命令配置为使用 firewall-drop 脚本。

1
2
3
4
<command>
<name>firewall-drop</name>
<executable>firewall-drop</executable>
</command>

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

1
2
3
4
5
6
7
<active-response>
<command>firewall-drop</command>
<location>all</location>
<rules_group>authentication_failed|authentication_failures</rules_group>
<timeout>700</timeout>
<repeated_offenders>30,60,120</repeated_offenders>
</active-response>

e. 自定义主动响应

无状态主动响应

无状态主动响应具有两种类型 AR 的最简单配置,并且被配置为一次性操作,没有事件来恢复原始效果。该过程需要通过 JSON 对象中的 STDIN 将完整警报传递给 AR,每个 AR 负责提取其执行所需的信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"version":1,
"origin":{
"name":"worker01",
"module":"wazuh-execd"
},
"command":"add/delete",
"parameters":{
"extra_args":[],
"alert":{},
"program":"program-name"
}
}

Wazuh允许任何语言编写自定义主动响应,但至少需要能够执行如下操作才能正确执行。

  • 读取 STDIN 以获取警报
  • 解析读取的 JSON 对象
  • 分析命令字段以检查它是否必须添加操作或删除它
  • 提取执行所需的信息

有状态的主动响应

有状态 AR 在活动响应中指定的时间段后撤消其原始操作。作为超时行为的一部分,当收到的命令是 add 时,AR 必须执行此操作。需满足以下步骤:

  • 读取STDIN 以获取警报
  • 解析读取的 JSON 对象
  • 分析命令字段以检查它是否必须添加操作或删除它
  • 提取其执行所需的信息
  • 使用从 JSON 格式的警报中提取的密钥构建控制消息
  • 写入 STDOUT 以发送控制消息
  • 等待通过 STDIN 的响应
  • 解析读取的 JSON 对象
  • 分析命令字段以检查它是否必须继续执行或中止执行

控制消息格式如下:

1
2
3
4
5
6
7
8
9
10
11
{
"version":1,
"origin":{
"name":"program-name",
"module":"active-response"
},
"command":"check_keys",
"parameters":{
"keys":["10.0.0.1"]
}
}

响应信息如下:

1
2
3
4
5
6
7
8
9
{
"version":1,
"origin":{
"name":"node01",
"module":"wazuh-execd"
},
"command":"continue/abort",
"parameters":{}
}

7. 系统资产盘点

Wazuh agent能够收集重要的系统信息,并将其存储到管理端每个agent的 SQLite 数据库中。Syscollector 模块负责此任务

agent启动后,Syscollector 会定期扫描定义的目标(硬件、操作系统、程序包等),将新收集的数据转发给管理器,管理器更新数据库的相应表,可通过查询 Wazuh API 从数据库中检索数据

a. 硬件信息

字段 描述 示例 支持平台
scan_id 扫描标识符 573872577 All
scan_time 扫描时间 2018/7/31 15:31 All
board_serial 主板序列号 XDR840TUGM65E03171 All
cpu_name CPU 名称 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz All
cpu_cores CPU核心数 4 All
cpu_mhz 当前处理器频率 900.106 All
ram_total 总内存 (KB) 16374572 All
ram_free 可用内存 (KB) 2111928 All
ram_usage 已使用内存占比 87 All
checksum 完整性同步值 503709147600c8e0023cf2b9995772280eee30 All

b. 操作系统

字段 描述 示例 支持平台
scan_id 扫描标识符 468455719 All
scan_time 扫描时间 2018/7/31 15:31 All
hostname 机器主机名 ag-ubuntu-16 All
architecture 操作系统架构 x86_64 All
os_name 操作系统名称 Ubuntu All
os_version 操作系统版本 16.04.5 LTS (Xenial Xerus) All
os_codename 操作系统版本号 Xenial Xerus All
os_major 主要发行版本 16 All
os_minor 次要发型版本 4 All
os_patch 补丁发行版本 5 macOS
os_build 可选build-specific 14393 Windows
os_release Windwos版本号 SP2 Windows
os_display_version Windows 显示版本 20H2 Windows
os_platform 操作系统平台 ubuntu All
sysname 系统名称 Linux Linux
release 发行名称 4.15.0-29-generic Linux
version 发行版本 #31~16.04.1-Ubuntu SMP Wed Jul 18 08:54:04 UTC 2018 All
checksum 完整性同步值 503709147600c8e0023cf2b9995772280eee30 All
reference 主键 94b6f7b3c1d905aae22a652448df6372da98e5b8 All

c. Packege信息

在 Linux 系统上,检索到的包可以是 deb、pacman 或 rpm 类型

字段 描述 示例 支持平台
scan_id 扫描标识符 1454946158 All
scan_time 扫描时间 2018/7/27 7:27 All
format package格式 deb All
name package名 linux-headers-generic All
priority package优先级 optional deb
section package section kernel deb/rpm/pkg
size 已安装包的大小(以字节为单位) 14 deb/rpm/pacman
vendor 供应商名称 Ubuntu Kernel Team All
install_time 安装包的日期 2018/2/8 18:45 rpm/pacman/win
version package版本 4.4.0.130.136 All
architecture package架构 amd64 All
multiarch 多架构支持 same deb
source package源 linux-meta deb/rpm/pkg
description package描述 Generic Linux kernel headers deb/rpm/pacman/pkg
location package位置 C:\Program Files\VMware\VMware Tools\ win/pkg
checksum 完整性同步值 78503709147600c8e0023cf2b9995772280eee30 All
item_id 主键 4323709147600c8e0023cf2b9995772280eef451 All

d. 网络接口信息

sys_netiface 表

字段 描述 示例 支持平台
id Id 1 All
scan_id 扫描标识符 160615720 All
scan_time 扫描时间 2018/7/31 16:46 All
name Interface名称 eth0 All
adapter 物理适配器名称 Intel(R) PRO/1000 MT Desktop Adapter Windows
type 网络适配器 ethernet All
state 接口状态 up All
mtu 最大传输单元 1500 All
mac MAC地址 08:00:27:C0:14:A5 All
tx_packets 传输的数据包 30279 All
rx_packets 接收的数据包 12754 All
tx_bytes 已传输字节 10034626 All
rx_bytes 已接收字节 1111175 All
tx_errors 传输错误 0 All
rx_errors 接收错误 0 All
tx_dropped 丢弃的传输包 0 All
rx_dropped 丢弃的接收包 0 All
checksum 完整性同步值 8503709147600c8e0023cf2b9995772280eee30 All
item_id 主键 4323709147600c8e0023cf2b9995772280eef41 All

sys_netaddr 表

字段 描述 示例 支持平台
id 来自 sys_netiface 的参考ID 1 All
scan_id 扫描标识符 160615720 All
proto 协议名称 ipv4 All
address IPv4/IPv6 地址 192.168.1.87 All
netmask 网络掩码地址 255.255.255.0 All
broadcast 广播地址 192.168.1.255 All
checksum 完整性同步值 78503709147600c8e0023cf2b9995772280eee30 All
item_id 主键 4323709147600c8e0023cf2b9995772280eef4 All

sys_netproto 表

字段 描述 示例 支持平台
id 来自 sys_netiface 的参考ID 1 All
scan_id 扫描标识符 160615720 All
iface Interface 名称 eth0 All
type 接口数据协议 ipv4 All
gateway 默认网关 192.168.1.1 Linux/Windows/macOS
dhcp DHCP 状态 enabled Linux/Windows
checksum 完整性同步值 78503709147600c8e0023cf2b9995772280eee30 All
item_id 主键 4323709147600c8e0023cf2b9995772280eef4 All

e. 端口信息

字段 描述 示例 支持平台
scan_id 扫描标识符 1618114744 All
scan_time 扫描时间 2018/7/27 7:27 All
protocol 端口协议 tcp All
local_ip 本地IP地址 0.0.0.0 All
local_port 本地端口 22 All
remote_ip 远程IP地址 0.0.0.0 All
remote_port 远程端口 0 All
tx_queue 等待传输的数据包 0 Linux
rx_queue 接收队列中的数据包 0 Linux
inode 端口inode 16974 Linux
state 端口状态 listening All
PID 已开放端口pid 4 Windows/macOS
process 进程名称 System Windows/macOS
checksum 完整性同步值 78503709147600c8e0023cf2b9995772280eee30 All
item_id 主键 4323709147600c8e0023cf2b9995772280eef412 All

f. 进程信息

字段 描述 示例 支持平台
scan_id 扫描标识符 215303769 All
scan_time 扫描时间 2018/8/3 12:57 All
pid 进程PID 603 All
name 进程名称 rsyslogd All
state 进程状态 S Linux/macOS
ppid 进程PPID 1 All
utime 执行用户代码所用时间 157 Linux
stime 执行系统代码所用时间 221 All
cmd 进程执行命令行 /usr/sbin/rsyslogd Linux/Windows
argvs 命令执行参数 -n Linux
euser Effective用户 root Linux/macOS
ruser Real 用户 root Linux/macOS
suser Saved-set 用户 root Linux
egroup Effective 组 root Linux
rgroup Real 组 root Linux/macOS
sgroup Saved-set 组 root Linux
fgroup 文件系统组名 root Linux
priority 内核调度优先级 20 All
nice 进程Nice值 0 Linux/macOS
size 进程大小 53030 All
vm_size VM 总大小 (KB) 212120 All
resident 进程的驻留大小(以字节为单位) 902 Linux
share 共享内存 814 Linux
start_time 进程启动时间 1893 Linux
pgrp 进程组 603 Linux
session 进程会话 603 All
nlwp 轻量级进程数 3 All
tgid 线程组ID 603 Linux
tty 进程TTY数 0 Linux
processor 处理器数 0 Linux
checksum 完整性同步值 78503709147600c8e0023cf2b9995772280eee30 All

g. 配置使用

在规则声明中将 <decoded_as> 字段设置为 syscollector,开启配置

示例:当启用agent的接口 eth0 时将触发此规则,并显示具有该接口的 IPv4

1
2
3
4
5
6
<rule id="100001" level="5">
<if_sid>221</if_sid>
<decoded_as>syscollector</decoded_as>
<field name="netinfo.iface.name">eth0</field>
<description>eth0 interface enabled. IP: $(netinfo.iface.ipv4.address)</description>
</rule>

Syscollector 模块默认在所有兼容系统中启用,包括所有可用的扫描

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- System inventory -->
<wodle name="syscollector">
<disabled>no</disabled>
<interval>1h</interval>
<scan_on_start>yes</scan_on_start>
<hardware>yes</hardware>
<os>yes</os>
<network>yes</network>
<packages>yes</packages>
<ports all="no">yes</ports>
<processes>yes</processes>

<!-- Database synchronization settings -->
<synchronization>
<max_eps>10</max_eps>
</synchronization>
</wodle>

8. 容器安全监控

可使用 Wazuh 监控 Docker 服务器和容器事件

a. 安装依赖项

Docker 监听器模块可以在 Wazuh 管理器(也充当代理)或直接在 Wazuh agent中配置,管理器包括所有已安装的依赖项,agent需安装依赖项

1
2
3
4
5
6
7
yum update && yum install python3

pip3 install --upgrade pip

yum update && yum install python3-pip

pip3 install docker==4.2.0

b. 监控容器活动

Docker wodle 收集 Docker 容器上的事件,例如启动、停止或暂停。

配置

为了使用 Docker 侦听器模块,需要在运行 docker 的服务器的 /var/ossec/etc/ossec.conf 文件中启用 wodle

1
2
3
<wodle name="docker-listener">
<disabled>no</disabled>
</wodle>

配置后重新启动 Wazuh 服务

监控示例

1)启动一个 Docker 容器

命令 docker start apache 启动一个名为 apache 的容器,生成以下警报

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
"timestamp": "2018-10-05T17:15:33.892+0200",
"rule": {
"level": 3,
"description": "Container apache started",
"id": "87903",
"mail": false,
"groups": [
"docker"
]
},
"agent": {
"id": "002",
"name": "agent001",
"ip": "192.168.122.19"
},
"manager": {
"name": "localhost.localdomain"
},
"id": "1538752533.76076",
"cluster": {
"name": "wazuh",
"node": "master"
},
"full_log": "{\"integration\": \"docker\", \"docker\": {\"status\": \"start\", \"id\": \"018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620\", \"from\": \"httpd\", \"Type\": \"container\", \"Action\": \"start\", \"Actor\": {\"ID\": \"018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620\", \"Attributes\": {\"image\": \"httpd\", \"name\": \"apache\"}}, \"time\": 1538752533, \"timeNano\": 1538752533877226210}}",
"decoder": {
"name": "json"
},
"data": {
"integration": "docker",
"docker": {
"status": "start",
"id": "018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620",
"from": "httpd",
"Type": "container",
"Action": "start",
"Actor": {
"ID": "018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620",
"Attributes": {
"image": "httpd",
"name": "apache"
}
},
"time": "1538752533",
"timeNano": "1538752533877226240.000000"
}
},
"location": "Wazuh-Docker"
}
  1. 停止 Docker 容器

使用命令 docker stop apache 生成警报:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
"timestamp": "2018-10-05T17:16:53.412+0200",
"rule": {
"level": 3,
"description": "Container apache stopped",
"id": "87904",
"mail": false,
"groups": [
"docker"
]
},
"agent": {
"id": "002",
"name": "agent001",
"ip": "192.168.122.19"
},
"manager": {
"name": "localhost.localdomain"
},
"id": "1538752613.100231",
"cluster": {
"name": "wazuh",
"node": "master"
},
"full_log": "{\"integration\": \"docker\", \"docker\": {\"status\": \"stop\", \"id\": \"018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620\", \"from\": \"httpd\", \"Type\": \"container\", \"Action\": \"stop\", \"Actor\": {\"ID\": \"018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620\", \"Attributes\": {\"image\": \"httpd\", \"name\": \"apache\"}}, \"time\": 1538752613, \"timeNano\": 1538752613407075872}}",
"decoder": {
"name": "json"
},
"data": {
"integration": "docker",
"docker": {
"status": "stop",
"id": "018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620",
"from": "httpd",
"Type": "container",
"Action": "stop",
"Actor": {
"ID": "018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620",
"Attributes": {
"image": "httpd",
"name": "apache"
}
},
"time": "1538752613",
"timeNano": "1538752613407075840.000000"
}
},
"location": "Wazuh-Docker"
}
  1. 暂停 Docker 容器

使用命令 docker pause apache:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
"timestamp": "2018-10-05T17:17:54.988+0200",
"rule": {
"level": 3,
"description": "Container apache paused",
"id": "87905",
"mail": false,
"groups": [
"docker"
]
},
"agent": {
"id": "002",
"name": "agent001",
"ip": "192.168.122.19"
},
"manager": {
"name": "localhost.localdomain"
},
"id": "1538752674.104889",
"cluster": {
"name": "wazuh",
"node": "master"
},
"full_log": "{\"integration\": \"docker\", \"docker\": {\"status\": \"pause\", \"id\": \"018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620\", \"from\": \"httpd\", \"Type\": \"container\", \"Action\": \"pause\", \"Actor\": {\"ID\": \"018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620\", \"Attributes\": {\"image\": \"httpd\", \"name\": \"apache\"}}, \"time\": 1538752674, \"timeNano\": 1538752674984734790}}",
"decoder": {
"name": "json"
},
"data": {
"integration": "docker",
"docker": {
"status": "pause",
"id": "018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620",
"from": "httpd",
"Type": "container",
"Action": "pause",
"Actor": {
"ID": "018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620",
"Attributes": {
"image": "httpd",
"name": "apache"
}
},
"time": "1538752674",
"timeNano": "1538752674984734720.000000"
}
},
"location": "Wazuh-Docker"
}
  1. 取消暂停 Docker 容器

运行docker unpause apache 命令的警报:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
"timestamp": "2018-10-05T17:18:35.373+0200",
"rule": {
"level": 3,
"description": "Container apache unpaused",
"id": "87906",
"mail": false,
"groups": [
"docker"
]
},
"agent": {
"id": "002",
"name": "agent001",
"ip": "192.168.122.19"
},
"manager": {
"name": "localhost.localdomain"
},
"id": "1538752715.105822",
"cluster": {
"name": "wazuh",
"node": "master"
},
"full_log": "{\"integration\": \"docker\", \"docker\": {\"status\": \"unpause\", \"id\": \"018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620\", \"from\": \"httpd\", \"Type\": \"container\", \"Action\": \"unpause\", \"Actor\": {\"ID\": \"018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620\", \"Attributes\": {\"image\": \"httpd\", \"name\": \"apache\"}}, \"time\": 1538752715, \"timeNano\": 1538752715369717277}}",
"decoder": {
"name": "json"
},
"data": {
"integration": "docker",
"docker": {
"status": "unpause",
"id": "018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620",
"from": "httpd",
"Type": "container",
"Action": "unpause",
"Actor": {
"ID": "018205fa7e170e32578b8487e3b7040aad00b8accedb983bc2ad029238ca3620",
"Attributes": {
"image": "httpd",
"name": "apache"
}
},
"time": "1538752715",
"timeNano": "1538752715369717248.000000"
}
},
"location": "Wazuh-Docker"
}

9. 集成Osquery

Wazuh 管理模块允许从agent集成 Osquery 工具,它允许设置 Osquery 配置并收集 Osquery 生成的信息以将其发送给管理器,并在必要时生成相应的警报。

a. 安装Osquery

1
2
3
4
curl -L https://pkg.osquery.io/rpm/GPG | tee /etc/pki/rpm-gpg/RPM-GPG-KEY-osquery
yum-config-manager --add-repo https://pkg.osquery.io/rpm/osquery-s3-rpm.repo
yum-config-manager --enable osquery-s3-rpm-repo
yum install osquery

安装后,需要 Osquery 的配置文件。如果没有,可使用Osquery 提供的默认配置

1
cp /opt/osquery/share/osquery/osquery.example.conf /etc/osquery/osquery.conf

启动osquery 守护进程

1
2
systemctl enable osqueryd
systemctl start osqueryd

通过添加以下命令为运行 osquery 的agent启用 osquery 模块,配置文件/var/ossec/etc/ossec.conf

1
<wodle name="osquery"/>

b. 配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
"options": {
"config_plugin": "filesystem",
"logger_plugin": "filesystem",
"utc": "true"
},

"schedule": {
"system_info": {
"query": "SELECT hostname, cpu_brand, physical_memory FROM system_info;",
"interval": 3600
},
"high_load_average": {
"query": "SELECT period, average, '70%' AS 'threshold' FROM load_average WHERE period = '15m' AND average > '0.7';",
"interval": 900,
"description": "Report if load charge is over 70 percent."
},
"low_free_memory": {
"query": "SELECT memory_total, memory_free, CAST(memory_free AS real) / memory_total AS memory_free_perc, '10%' AS threshold FROM memory_info WHERE memory_free_perc < 0.1;",
"interval": 1800,
"description": "Free RAM is under 10%."
}
},

"packs": {
"osquery-monitoring": "/opt/osquery/share/osquery/packs/osquery-monitoring.conf",
"incident-response": "/opt/osquery/share/osquery/packs/incident-response.conf",
"it-compliance": "/opt/osquery/share/osquery/packs/it-compliance.conf",
"vuln-management": "/opt/osquery/share/osquery/packs/vuln-management.conf",
"hardware-monitoring": "/opt/osquery/share/osquery/packs/hardware-monitoring.conf",
"ossec-rootkit": "/opt/osquery/share/osquery/packs/ossec-rootkit.conf"
}
}

c. 告警示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
{
"timestamp": "2018-07-30T13:54:46.476+0000",
"rule": {
"level": 3,
"description": "osquery data grouped",
"id": "24010",
"firedtimes": 207,
"mail": false,
"groups": [
"osquery"
]
},
"agent": {
"id": "000",
"name": "manager"
},
"manager": {
"name": "manager"
},
"id": "1532958886.437707",
"full_log": "{\"name\":\"system_info\",\"hostIdentifier\":\"manager\",\"calendarTime\":\"Mon Jul 30 13:54:45 2018 UTC\",\"unixTime\":1532958885,\"epoch\":0,\"counter\":461,\"columns\":{\"cgroup_namespace\":\"4026531835\",\"cmdline\":\"\",\"cwd\":\"/\",\"disk_bytes_read\":\"0\",\"disk_bytes_written\":\"0\",\"egid\":\"0\",\"euid\":\"0\",\"gid\":\"0\",\"ipc_namespace\":\"4026531839\",\"mnt_namespace\":\"4026531840\",\"name\":\"migration/0\",\"net_namespace\":\"4026531957\",\"nice\":\"0\",\"on_disk\":\"-1\",\"parent\":\"2\",\"path\":\"\",\"pgroup\":\"0\",\"pid\":\"9\",\"pid_namespace\":\"4026531836\",\"resident_size\":\"\",\"root\":\"/\",\"sgid\":\"0\",\"start_time\":\"0\",\"state\":\"S\",\"suid\":\"0\",\"system_time\":\"2\",\"threads\":\"1\",\"total_size\":\"\",\"uid\":\"0\",\"user_namespace\":\"4026531837\",\"user_time\":\"0\",\"uts_namespace\":\"4026531838\",\"wired_size\":\"0\"},\"action\":\"added\"}",
"decoder": {
"name": "json"
},
"data": {
"action": "added",
"name": "system_info",
"hostIdentifier": "manager",
"calendarTime": "Mon Jul 30 13:54:45 2018 UTC",
"unixTime": "1532958885",
"epoch": "0",
"counter": "461",
"columns": {
"cgroup_namespace": "4026531835",
"cmdline": "",
"cwd": "/",
"disk_bytes_read": "0",
"disk_bytes_written": "0",
"egid": "0",
"euid": "0",
"gid": "0",
"ipc_namespace": "4026531839",
"mnt_namespace": "4026531840",
"name": "migration/0",
"net_namespace": "4026531957",
"nice": "0",
"on_disk": "-1",
"parent": "2",
"path": "",
"pgroup": "0",
"pid": "9",
"pid_namespace": "4026531836",
"resident_size": "",
"root": "/",
"sgid": "0",
"start_time": "0",
"state": "S",
"suid": "0",
"system_time": "2",
"threads": "1",
"total_size": "",
"uid": "0",
"user_namespace": "4026531837",
"user_time": "0",
"uts_namespace": "4026531838",
"wired_size": "0"
}
},
"predecoder": {
"hostname": "manager"
},
"location": "osquery"
}

0x05 实战用例

1. 文件完整性监控

配置 Wazuh agent以监视 /root 目录中的文件系统更改,编辑 Wazuh 代理 /var/ossec/etc/ossec.conf 配置文件,在 <syscheck> 块中添加用于监视的目录

1
<directories check_all="yes" report_changes="yes" realtime="yes">/root</directories>

重启 Wazuh agent生效

1
sudo systemctl restart wazuh-agent

2. 检测暴力破解攻击

Linux 端点上的 SSH 和 Windows 端点上的 RDP 等服务通常容易受到暴力攻击,Wazuh 通过关联多个身份验证失败事件来识别暴力攻击。

SSH暴力破解

1
sudo hydra -l user -P <PASSWD_LIST.txt> <RHEL_IP> ssh

RDP暴力破解

1
sudo hydra -l user -P <PASSWD_LIST.txt> rdp://<WINDOWS_IP>

3. 检测异常进程

使用 Wazuh 命令监控功能来检测 Netcat 在 Linux 端点上运行

agent配置

将以下配置块添加到 Wazuh agent /var/ossec/etc/ossec.conf 文件中,允许获取正在运行的进程列表:

1
2
3
4
5
6
7
8
<ossec_config>
<localfile>
<log_format>full_command</log_format>
<alias>process list</alias>
<command>ps -e -o pid,uname,command</command>
<frequency>30</frequency>
</localfile>
</ossec_config>

重启 Wazuh agent生效

1
sudo systemctl restart wazuh-agent

服务端配置

创建每次 Netcat 程序启动时触发的规则,在Wazuh服务器的/var/ossec/etc/rules/local_rules.xml文件创建规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<group name="ossec,">
<rule id="100050" level="0">
<if_sid>530</if_sid>
<match>^ossec: output: 'process list'</match>
<description>List of running processes.</description>
<group>process_monitor,</group>
</rule>

<rule id="100051" level="7" ignore="900">
<if_sid>100050</if_sid>
<match>nc -l</match>
<description>netcat listening for incoming connections.</description>
<group>process_monitor,</group>
</rule>
</group>

重启 Wazuh 管理器生效:

1
sudo systemctl restart wazuh-manager

攻击模拟

1
nc -l 8000

4. 检测 SQL 注入攻击

可以使用 Wazuh 从包含select, union和其他常见 SQL 注入模式等的 Web 服务器日志中检测 SQL 注入攻击

搭建web服务器

1
2
3
4
5
sudo yum -y install apache2

sudo systemctl start apache2

curl http://<LINUX_IP>

日志监控配置

将以下行添加到 Wazuh agent /var/ossec/etc/ossec.conf 文件中。允许 Wazuh agent监控 Apache 服务器的访问日志:

1
2
3
4
5
6
<ossec_config>
<localfile>
<log_format>apache</log_format>
<location>/var/log/apache2/access.log</location>
</localfile>
</ossec_config>

重启 Wazuh agent生效

1
sudo systemctl restart wazuh-agent

攻击模拟

sql注入攻击

1
curl -XGET "http://<HOST_IP>/users/?id=SELECT+*+FROM+users";

Shellshock 攻击

1
sudo curl -H "User-Agent: () { :; }; /bin/cat /etc/passwd" <WEBSERVER-IP>

5. 检测可疑的二进制文件

Wazuh 具有异常和恶意软件检测功能,可以检测端点上的可疑二进制文件。

使用Wazuh rootcheck 模块检测 Linux 端点上的木马系统二进制文件,Wazuh rootcheck 模块还检查隐藏的进程、端口和文件

配置

检查被监控端点的 /var/ossec/etc/ossec.conf 配置文件中的 <rootcheck> 块,确保其具有以下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<rootcheck>
<disabled>no</disabled>
<check_files>yes</check_files>

<!-- Line for trojans detection -->
<check_trojans>yes</check_trojans>

<check_dev>yes</check_dev>
<check_sys>yes</check_sys>
<check_pids>yes</check_pids>
<check_ports>yes</check_ports>
<check_if>yes</check_if>

<!-- Frequency that rootcheck is executed - every 12 hours -->
<frequency>43200</frequency>
<rootkit_files>/var/ossec/etc/shared/rootkit_files.txt</rootkit_files>
<rootkit_trojans>/var/ossec/etc/shared/rootkit_trojans.txt</rootkit_trojans>
<skip_nfs>yes</skip_nfs>
</rootcheck>

攻击模拟

1
2
3
4
5
6
7
8
9
sudo cp -p /usr/bin/w /usr/bin/w.copy

sudo tee /usr/bin/w << EOF
!/bin/bash
echo "`date` this is evil" > /tmp/trojan_created_file
echo 'test for /usr/bin/w trojaned file' >> /tmp/trojan_created_file
Now running original binary
/usr/bin/w.copy
EOF

默认情况下,rootcheck 扫描每 12 小时运行一次。通过重新启动 Wazuh agent来强制扫描以查看相关警报:

1
sudo systemctl restart wazuh-agent

6. 监控恶意命令执行

配置 Auditd 以监视恶意命令的执行,利用 Wazuh CDB 列表查找功能创建可在其上运行的潜在恶意命令列表。

端点配置

  1. 安装、启动并启用 Auditd
1
2
3
sudo yum -y install auditd
sudo systemctl start auditd
sudo systemctl enable auditd

2)root用户执行以下命令将审计规则附加到 /etc/audit/audit.rules 文件

1
2
echo "-a exit,always -F auid=1000 -F egid!=994 -F auid!=-1 -F arch=b32 -S execve -k audit-wazuh-c" >> /etc/audit/audit.rules
echo "-a exit,always -F auid=1000 -F egid!=994 -F auid!=-1 -F arch=b64 -S execve -k audit-wazuh-c" >> /etc/audit/audit.rules

3)重新加载规则并确认启用

1
2
sudo auditctl -R /etc/audit/audit.rules
sudo auditctl -l

4)重启 Wazuh agent生效

1
sudo systemctl restart wazuh-agent

服务端配置

在server创建CDB恶意程序列表和规则来检测列表中程序的执行

1)查看lookup文件 /var/ossec/etc/lists/audit-keys 中的键值对

1
2
3
4
5
audit-wazuh-w:write
audit-wazuh-r:read
audit-wazuh-a:attribute
audit-wazuh-x:execute
audit-wazuh-c:command

此 CDB 列表包含以冒号分隔的键和值,这些被编译成特殊的二进制格式,方便Wazuh 规则中的高性能查找,除了文本文件/var/ossec/etc/lists/audit-keys,还有一个二进制文件/var/ossec/etc/lists/audit-keys.cdb可用于查找

2)创建一个 CDB 列表 /var/ossec/etc/lists/suspicious-programs 并用以下内容填充其内容

1
2
3
ncat:yellow
nc:red
tcpdump:orange

3)将列表添加到 Wazuh 服务器 /var/ossec/etc/ossec.conf 文件的 <ruleset>

1
<list>etc/lists/suspicious-programs</list>

4)创建一个高严重性规则以在执行”red”程序时触发。将此新规则添加到 Wazuh 服务器上的 /var/ossec/etc/rules/local_rules.xml 文件中

1
2
3
4
5
6
7
8
<group name="audit">
<rule id="100210" level="12">
<if_sid>80792</if_sid>
<list field="audit.command" lookup="match_key_value" check_value="red">etc/lists/suspicious-programs</list>
<description>Audit: Highly Suspicious Command executed: $(audit.exe)</description>
<group>audit_command,</group>
</rule>
</group>

5)重启 Wazuh 管理器使配置生效

1
sudo systemctl restart wazuh-manager

攻击模拟

1
2
sudo yum -y install netcat
nc -v

7. 检测隐藏进程

Wazuh 检测 Linux 端点上的 Rootkit 创建的隐藏进程,这个 rootkit 隐藏在内核模块列表中。

它还从 ps 中隐藏选定的进程,但Wazuh 使用 setsid()、getpid() 和 kill() 系统调用来检测

检测配置

1)切换到 root 用户并更新此端点的内核

1
2
sudo su
yum update

2)安装构建 rootkit 所需的包

1
yum -y install gcc git

3)将 Wazuh agent配置为每 2 分钟运行一次 rootcheck 扫描。在 /var/ossec/etc/ossec.conf 文件中,将 <rootcheck> 中的 frequency 选项设置为 120

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<rootcheck>
<disabled>no</disabled>
<check_files>yes</check_files>
<check_trojans>yes</check_trojans>
<check_dev>yes</check_dev>
<check_sys>yes</check_sys>
<check_pids>yes</check_pids>
<check_ports>yes</check_ports>
<check_if>yes</check_if>

<!-- rootcheck execution frequency - every 12 hours by default-->

<frequency>120</frequency>

<rootkit_files>etc/shared/rootkit_files.txt</rootkit_files>
<rootkit_trojans>etc/shared/rootkit_trojans.txt</rootkit_trojans>
<skip_nfs>yes</skip_nfs>
</rootcheck>

4)重启 Wazuh agent生效

1
sudo systemctl restart wazuh-agent

攻击模拟

1)下载、编译并加载Diamorphine rootkit内核模块

1
2
3
4
5
git clone https://github.com/m0nad/Diamorphine

cd Diamorphine && make

insmod diamorphine.ko

2)使用在端点上运行的随机进程的 PID 运行 kill signal 63。这会取消隐藏 Diamorphine rootkit。默认情况下,Diamorphine 会隐藏自身,无法通过运行 lsmod 命令检测到

1
2
3
lsmod | grep diamorphine
kill -63 509
lsmod | grep diamorphine

输出

1
diamorphine            13155  0

使用最后的命令时,会得到一个空输出。在 Diamorphine 的情况下,任何发送到任意进程的 kill 信号 -63(无论是否存在)都会切换 Diamorphine 内核模块以隐藏或取消隐藏

3)运行以下命令以查看 rsyslogd 进程,开始可见然后不再可见。该 rootkit 允许从 ps 命令中隐藏选定的进程,发送终止信号 -31 隐藏/取消隐藏任何进程

1
ps auxw | grep rsyslogd | grep -v grep

输出

1
root       732  0.0  0.7 214452  3572 ?        Ssl  14:53   0:00 /usr/sbin/rsyslogd -n

使用最后一个命令时,会得到一个空输出

1
2
kill -31 <PID_OF_RSYSLOGD>
ps auxw | grep rsyslog | grep -v grep

下一次 rootcheck 扫描将运行并提醒我们有关隐藏在 Diamorphine rootkit 中的 rsyslogd 进程

8. 集成 Yara 检测恶意软件

可以使用 YARA 与 Wazuh 的集成来扫描在端点上添加或修改的文件中是否存在恶意软件,当Wazuh FIM 模块触发警报,YARA 主动响应模块就会扫描新文件或修改过的文件

端点配置

1)下载、编译和安装 YARA

1
2
3
4
5
6
7
8
sudo yum makecache
sudo yum install epel-release
sudo yum update
sudo yum install -y make automake gcc autoconf libtool openssl-devel pkg-config jq
sudo curl -LO https://github.com/VirusTotal/yara/archive/v4.2.3.tar.gz
sudo tar -xvzf v4.2.3.tar.gz -C /usr/local/bin/ && rm -f v4.2.3.tar.gz
cd /usr/local/bin/yara-4.2.3/
sudo ./bootstrap.sh && sudo ./configure && sudo make && sudo make install && sudo make check

2)下载YARA检测规则

1
2
3
4
5
6
7
8
9
10
sudo mkdir -p /tmp/yara/rules
sudo curl 'https://valhalla.nextron-systems.com/api/v1/get' \
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
-H 'Accept-Language: en-US,en;q=0.5' \
--compressed \
-H 'Referer: https://valhalla.nextron-systems.com/' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'DNT: 1' -H 'Connection: keep-alive' -H 'Upgrade-Insecure-Requests: 1' \
--data 'demo=demo&apikey=1111111111111111111111111111111111111111111111111111111111111111&format=text' \
-o /tmp/yara/rules/yara_rules.yar

3)在/var/ossec/active-response/bin/目录下创建yara.sh脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/bin/bash
# Wazuh - Yara active response
# Copyright (C) 2015-2022, Wazuh Inc.
#
# This program is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public
# License (version 2) as published by the FSF - Free Software
# Foundation.


#------------------------- Gather parameters -------------------------#

# Extra arguments
read INPUT_JSON
YARA_PATH=$(echo $INPUT_JSON | jq -r .parameters.extra_args[1])
YARA_RULES=$(echo $INPUT_JSON | jq -r .parameters.extra_args[3])
FILENAME=$(echo $INPUT_JSON | jq -r .parameters.alert.syscheck.path)

# Set LOG_FILE path
LOG_FILE="logs/active-responses.log"

size=0
actual_size=$(stat -c %s ${FILENAME})
while [ ${size} -ne ${actual_size} ]; do
sleep 1
size=${actual_size}
actual_size=$(stat -c %s ${FILENAME})
done

#----------------------- Analyze parameters -----------------------#

if [[ ! $YARA_PATH ]] || [[ ! $YARA_RULES ]]
then
echo "wazuh-yara: ERROR - Yara active response error. Yara path and rules parameters are mandatory." >> ${LOG_FILE}
exit 1
fi

#------------------------- Main workflow --------------------------#

# Execute Yara scan on the specified filename
yara_output="$("${YARA_PATH}"/yara -w -r "$YARA_RULES" "$FILENAME")"

if [[ $yara_output != "" ]]
then
# Iterate every detected rule and append it to the LOG_FILE
while read -r line; do
echo "wazuh-yara: INFO - Scan result: $line" >> ${LOG_FILE}
done <<< "$yara_output"
fi

exit 0;

4)将 yara.sh 文件所有者更改为 root:wazuh 并将文件权限更改为 0750

1
2
sudo chown root:wazuh /var/ossec/active-response/bin/yara.sh
sudo chmod 750 /var/ossec/active-response/bin/yara.sh

5)在 Wazuh agent /var/ossec/etc/ossec.conf 配置文件的 <syscheck> 块中添加以下内容以监控 /tmp/yara/malware 目录

1
<directories realtime="yes">/tmp/yara/malware</directories>

6)重新启动 Wazuh agent以应用配置更改

1
sudo systemctl restart wazuh-agent

server配置

配置 Wazuh 以提醒端点监控目录中的文件更改,再配置一个主动响应脚本,以便在检测到可疑文件时触发

1)在 /var/ossec/etc/rules/local_rules.xml 文件中添加如下规则,规则检测受监控目录中的 FIM 事件。当 YARA 集成发现恶意软件时,会发出警报

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<group name="syscheck,">
<rule id="100300" level="7">
<if_sid>550</if_sid>
<field name="file">/tmp/yara/malware/</field>
<description>File modified in /tmp/yara/malware/ directory.</description>
</rule>
<rule id="100301" level="7">
<if_sid>554</if_sid>
<field name="file">/tmp/yara/malware/</field>
<description>File added to /tmp/yara/malware/ directory.</description>
</rule>
</group>

<group name="yara,">
<rule id="108000" level="0">
<decoded_as>yara_decoder</decoded_as>
<description>Yara grouping rule</description>
</rule>
<rule id="108001" level="12">
<if_sid>108000</if_sid>
<match>wazuh-yara: INFO - Scan result: </match>
<description>File "$(yara_scanned_file)" is a positive match. Yara rule: $(yara_rule)</description>
</rule>
</group>

2)将以下解码器添加到 Wazuh 服务器 /var/ossec/etc/decoders/local_decoder.xml 文件中。允许从 YARA 扫描结果中提取信息

1
2
3
4
5
6
7
8
9
<decoder name="yara_decoder">
<prematch>wazuh-yara:</prematch>
</decoder>

<decoder name="yara_decoder1">
<parent>yara_decoder</parent>
<regex>wazuh-yara: (\S+) - Scan result: (\S+) (\S+)</regex>
<order>log_type, yara_rule, yara_scanned_file</order>
</decoder>

3)在Wazuh服务器/var/ossec/etc/ossec.conf配置文件中添加如下配置。使主动响应模块配置为在触发规则 100300 和 100301 后触发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<ossec_config>
<command>
<name>yara_linux</name>
<executable>yara.sh</executable>
<extra_args>-yara_path /usr/local/bin -yara_rules /tmp/yara/rules/yara_rules.yar</extra_args>
<timeout_allowed>no</timeout_allowed>
</command>

<active-response>
<command>yara_linux</command>
<location>local</location>
<rules_id>100300,100301</rules_id>
</active-response>
</ossec_config>

4)重启 Wazuh 管理器以应用配置更改

1
sudo systemctl restart wazuh-manager

攻击模拟

1)在受监控端点上创建脚本 /tmp/yara/malware/malware_downloader.sh 以下载恶意软件样本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/bin/bash
# Wazuh - Malware Downloader for test purposes
# Copyright (C) 2015-2022, Wazuh Inc.
#
# This program is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public
# License (version 2) as published by the FSF - Free Software
# Foundation.

function fetch_sample(){

curl -s -XGET "$1" -o "$2"

}

echo "WARNING: Downloading Malware samples, please use this script with caution."
read -p " Do you want to continue? (y/n)" -n 1 -r ANSWER
echo

if [[ $ANSWER =~ ^[Yy]$ ]]
then
echo
# Mirai
echo "# Mirai: https://en.wikipedia.org/wiki/Mirai_(malware)"
echo "Downloading malware sample..."
fetch_sample "https://wazuh-demo.s3-us-west-1.amazonaws.com/mirai" "/tmp/yara/malware/mirai" && echo "Done!" || echo "Error while downloading."
echo

# Xbash
echo "# Xbash: https://unit42.paloaltonetworks.com/unit42-xbash-combines-botnet-ransomware-coinmining-worm-targets-linux-windows/"
echo "Downloading malware sample..."
fetch_sample "https://wazuh-demo.s3-us-west-1.amazonaws.com/xbash" "/tmp/yara/malware/xbash" && echo "Done!" || echo "Error while downloading."
echo

# VPNFilter
echo "# VPNFilter: https://news.sophos.com/en-us/2018/05/24/vpnfilter-botnet-a-sophoslabs-analysis/"
echo "Downloading malware sample..."
fetch_sample "https://wazuh-demo.s3-us-west-1.amazonaws.com/vpn_filter" "/tmp/yara/malware/vpn_filter" && echo "Done!" || echo "Error while downloading."
echo

# Webshell
echo "# WebShell: https://github.com/SecWiki/WebShell-2/blob/master/Php/Worse%20Linux%20Shell.php"
echo "Downloading malware sample..."
fetch_sample "https://wazuh-demo.s3-us-west-1.amazonaws.com/webshell" "/tmp/yara/malware/webshell" && echo "Done!" || echo "Error while downloading."
echo
fi

2)运行 malware_downloader.sh 脚本将恶意软件样本下载到 /tmp/yara/malware 目录:

1
sudo bash /tmp/yara/malware/malware_downloader.sh

9. 集成 Network IDS

Wazuh 与基于网络的入侵检测系统 (NIDS) 集成,通过监控网络流量来增强威胁检测。示例将 Suricata 与 Wazuh 集成。

检测配置

1)在 CentOS 上安装 Suricata

1
2
3
yum -y install epel-release yum-plugin-copr
yum copr enable @oisf/suricata-6.0
yum -y install suricata

2)下载并提取 Suricata 规则集

1
2
3
cd /tmp/ && curl -LO https://rules.emergingthreats.net/open/suricata-6.0.8/emerging.rules.tar.gz
sudo tar -xvzf emerging.rules.tar.gz && sudo mv rules/*.rules /etc/suricata/rules/
sudo chmod 640 /etc/suricata/rules/*.rules

3)修改 /etc/suricata/suricata.yaml 文件中的 Suricata 配置并设置以下变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
HOME_NET: "<UBUNTU_IP>"
EXTERNAL_NET: "any"

default-rule-path: /etc/suricata/rules
rule-files:
- "*.rules"

# Global stats configuration
stats:
enabled: no

# Linux high speed capture support
af-packet:
- interface: eth0

4)重启 Suricata 服务

1
sudo systemctl restart suricata

5)在 Wazuh agent的/var/ossec/etc/ossec.conf文件中添加如下配置。允许 Wazuh agent读取 Suricata 日志文件:

1
2
3
4
5
6
<ossec_config>
<localfile>
<log_format>syslog</log_format>
<location>/var/log/suricata/eve.json</location>
</localfile>
</ossec_config>

6)重新启动 Wazuh agent以应用配置更改

1
sudo systemctl restart wazuh-agent

攻击模拟

Wazuh 自动解析来自 /var/log/suricata/eve.json 的数据,并在 Wazuh 仪表板上生成相关警报

从 Wazuh 服务器 Ping 端点 IP 地址

1
ping -c 20 "<Endpoint_IP>"

Suricata 日志 - /var/log/suricata/suricata.log

Suricata 配置文件:/etc/sysconfig/suricata/etc/suricata/suricata.yaml

10. 漏洞扫描与检测

Wazuh 使用漏洞检测器模块来识别端点上运行的应用程序和操作系统中的漏洞,示例展示Wazuh 检测受监控端点中未修补的常见漏洞 (CVE)

检测配置

1)在 Wazuh 服务器上的 /var/ossec/etc/ossec.conf 文件中启用漏洞检测器模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<ossec_config>
<vulnerability-detector>
<enabled>yes</enabled>
<interval>5m</interval>
<min_full_scan_interval>6h</min_full_scan_interval>
<run_on_start>yes</run_on_start>

<!-- Ubuntu OS vulnerabilities -->
<provider name="canonical">
<enabled>yes</enabled>
<os>trusty</os>
<os>xenial</os>
<os>bionic</os>
<os>focal</os>
<os>jammy</os>
<update_interval>1h</update_interval>
</provider>

<!-- Debian OS vulnerabilities -->
<provider name="debian">
<enabled>yes</enabled>
<os>stretch</os>
<os>buster</os>
<os>bullseye</os>
<update_interval>1h</update_interval>
</provider>

<!-- RedHat OS vulnerabilities -->
<provider name="redhat">
<enabled>yes</enabled>
<os>5</os>
<os>6</os>
<os>7</os>
<os>8</os>
<os allow="CentOS Linux-8">8</os>
<os>9</os>
<update_interval>1h</update_interval>
</provider>

<!-- Windows OS vulnerabilities -->
<provider name="msu">
<enabled>yes</enabled>
<update_interval>1h</update_interval>
</provider>

<!-- Aggregate vulnerabilities -->
<provider name="nvd">
<enabled>yes</enabled>
<update_from_year>2019</update_from_year>
<update_interval>1h</update_interval>
</provider>
</vulnerability-detector>
</ossec_config>

2)重启 Wazuh 管理器以应用配置更改

1
sudo systemctl restart wazuh-manager

测试配置

Wazuh 服务器在 /var/ossec/queue/vulnerabilities/cve.db 中创建一个 CVE 数据库,定期对每个受监控端点上的应用程序和操作系统执行漏洞检测扫描

11. 阻断已知的恶意行为

使用 Wazuh CDB 列表和主动响应功能,演示如何阻止恶意 IP 地址访问 Web 服务器上的 Web 资源

端点配置

1)搭建web服务器

1
2
3
4
5
sudo yum -y install apache2

sudo systemctl start apache2

curl http://<LINUX_IP>

2)将以下内容添加到 /var/ossec/etc/ossec.conf 文件以配置 Wazuh agent并监控 Apache 访问日志

1
2
3
4
<localfile>
<log_format>syslog</log_format>
<location>/var/log/apache2/access.log</location>
</localfile>

3)重新启动 Wazuh agent以应用配置更改

1
sudo systemctl restart wazuh-agent

server配置

在 Wazuh 服务器上执行以下步骤,将 RHEL 端点的 IP 地址添加到 CDB 列表中,然后配置规则和主动响应

1)下载实用程序并配置 CDB 列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 下载 Alienvault IP 信誉数据库

sudo wget https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/alienvault_reputation.ipset -O /var/ossec/etc/lists/alienvault_reputation.ipset

// 将攻击者端点的 IP 地址附加到 IP 信誉数据库。将 <ATTACKER_IP> 替换为以下命令中的 RHEL IP 地址

sudo echo "<ATTACKER_IP>" >> /var/ossec/etc/lists/alienvault_reputation.ipset

// 下载脚本以将 .ipset 格式转换为 .cdb 列表格式

sudo wget https://wazuh.com/resources/iplist-to-cdblist.py -O /tmp/iplist-to-cdblist.py

// 使用之前下载的脚本将 alienvault_reputation.ipset 文件转换为 .cdb 格式

sudo /var/ossec/framework/python/bin/python3 /tmp/iplist-to-cdblist.py /var/ossec/etc/lists/alienvault_reputation.ipset /var/ossec/etc/lists/blacklist-alienvault

// 为生成的文件分配正确的权限和所有权

sudo chown wazuh:wazuh /var/ossec/etc/lists/blacklist-alienvault

2)配置主动响应模块拦截恶意IP地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// 在 Wazuh 服务器 /var/ossec/etc/rules/local_rules.xml 自定义规则集文件中执行此操作

<group name="attack,">
<rule id="100100" level="10">
<if_group>web|attack|attacks</if_group>
<list field="srcip" lookup="address_match_key">etc/lists/blacklist-alienvault</list>
<description>IP address found in AlienVault reputation database.</description>
</rule>
</group>

// 编辑 Wazuh 服务器 /var/ossec/etc/ossec.conf 配置文件,将 etc/lists/blacklist-alienvault 列表添加到 <ruleset> 部分

<ossec_config>
<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/blacklist-alienvault</list>

<!-- User-defined ruleset -->
<decoder_dir>etc/decoders</decoder_dir>
<rule_dir>etc/rules</rule_dir>
</ruleset>
</ossec_config>

// 将主动响应块添加到 Wazuh 服务器 /var/ossec/etc/ossec.conf 文件

<ossec_config>
<active-response>
<command>firewall-drop</command>
<location>local</location>
<rules_id>100100</rules_id>
<timeout>60</timeout>
</active-response>
</ossec_config>

// 重新启动 Wazuh 管理器以应用更改

sudo systemctl restart wazuh-manager

攻击模拟

使用相应的 IP 地址从 RHEL 端点访问 Web 服务器,将 <WEBSERVER_IP> 替换为适当的值并从攻击者端点执行以下命令

1
curl http://<WEBSERVER_IP>

攻击者端点第一次连接到受害者的 Web 服务器。首次连接后,Wazuh 主动响应模块会暂时阻止与 Web 服务器的任何后续连接 60 秒。

0xFF Reference